455
516
static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
456
517
Dwarf_Die *die_mem)
458
return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
521
sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
525
/* Inlined function could be recursive. Trace it until fail */
527
memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
528
sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
535
/* Walker on lines (Note: line number will not be sorted) */
536
typedef int (* line_walk_handler_t) (const char *fname, int lineno,
537
Dwarf_Addr addr, void *data);
539
struct __line_walk_param {
541
line_walk_handler_t handler;
546
static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
548
struct __line_walk_param *lw = data;
552
if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
553
lineno = die_get_call_lineno(in_die);
554
if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
555
lw->retval = lw->handler(lw->fname, lineno, addr,
558
return DIE_FIND_CB_FOUND;
561
return DIE_FIND_CB_SIBLING;
564
/* Walk on lines of blocks included in given DIE */
565
static int __die_walk_funclines(Dwarf_Die *sp_die,
566
line_walk_handler_t handler, void *data)
568
struct __line_walk_param lw = {
577
/* Handle function declaration line */
578
lw.fname = dwarf_decl_file(sp_die);
579
if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
580
dwarf_entrypc(sp_die, &addr) == 0) {
581
lw.retval = handler(lw.fname, lineno, addr, data);
585
die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
590
static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
592
struct __line_walk_param *lw = data;
594
lw->retval = __die_walk_funclines(sp_die, lw->handler, lw->data);
596
return DWARF_CB_ABORT;
602
* Walk on lines inside given PDIE. If the PDIE is subprogram, walk only on
603
* the lines inside the subprogram, otherwise PDIE must be a CU DIE.
605
static int die_walk_lines(Dwarf_Die *pdie, line_walk_handler_t handler,
613
Dwarf_Die die_mem, *cu_die;
617
if (dwarf_tag(pdie) == DW_TAG_subprogram)
618
cu_die = dwarf_diecu(pdie, &die_mem, NULL, NULL);
622
pr_debug2("Failed to get CU from subprogram\n");
626
/* Get lines list in the CU */
627
if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
628
pr_debug2("Failed to get source lines on this CU.\n");
631
pr_debug2("Get %zd lines from this CU\n", nlines);
633
/* Walk on the lines on lines list */
634
for (i = 0; i < nlines; i++) {
635
line = dwarf_onesrcline(lines, i);
637
dwarf_lineno(line, &lineno) != 0 ||
638
dwarf_lineaddr(line, &addr) != 0) {
639
pr_debug2("Failed to get line info. "
640
"Possible error in debuginfo.\n");
643
/* Filter lines based on address */
647
* The line is included in given function, and
648
* no inline block includes it.
650
if (!dwarf_haspc(pdie, addr) ||
651
die_find_inlinefunc(pdie, addr, &die_mem))
653
/* Get source line */
654
fname = dwarf_linesrc(line, NULL, NULL);
656
ret = handler(fname, lineno, addr, data);
662
* Dwarf lines doesn't include function declarations and inlined
663
* subroutines. We have to check functions list or given function.
666
ret = __die_walk_funclines(pdie, handler, data);
668
struct __line_walk_param param = {
673
dwarf_getfuncs(cu_die, __die_walk_culines_cb, ¶m, 0);
461
680
struct __find_variable_param {
729
958
return (tvar->type == NULL) ? -ENOMEM : 0;
732
ret = die_get_byte_size(&type) * 8;
734
/* Check the bitwidth */
735
if (ret > MAX_BASIC_TYPE_BITS) {
736
pr_info("%s exceeds max-bitwidth."
737
" Cut down to %d bits.\n",
738
dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
739
ret = MAX_BASIC_TYPE_BITS;
742
ret = snprintf(buf, 16, "%c%d",
743
die_is_signed_type(&type) ? 's' : 'u', ret);
744
if (ret < 0 || ret >= 16) {
747
pr_warning("Failed to convert variable type: %s\n",
751
tvar->type = strdup(buf);
752
if (tvar->type == NULL)
961
ret = BYTES_TO_BITS(die_get_byte_size(&type));
963
/* No size ... try to use default type */
966
/* Check the bitwidth */
967
if (ret > MAX_BASIC_TYPE_BITS) {
968
pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
969
dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
970
ret = MAX_BASIC_TYPE_BITS;
972
ret = snprintf(buf, 16, "%c%d",
973
die_is_signed_type(&type) ? 's' : 'u', ret);
976
if (ret < 0 || ret >= 16) {
979
pr_warning("Failed to convert variable type: %s\n",
983
tvar->type = strdup(buf);
984
if (tvar->type == NULL)
1284
static int probe_point_line_walker(const char *fname, int lineno,
1285
Dwarf_Addr addr, void *data)
1287
struct probe_finder *pf = data;
1290
if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
1294
ret = call_probe_finder(NULL, pf);
1296
/* Continue if no error, because the line will be in inline function */
1297
return ret < 0 ? ret : 0;
1053
1300
/* Find probe point from its line number */
1054
1301
static int find_probe_point_by_line(struct probe_finder *pf)
1063
if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
1064
pr_warning("No source lines found.\n");
1068
for (i = 0; i < nlines && ret == 0; i++) {
1069
line = dwarf_onesrcline(lines, i);
1070
if (dwarf_lineno(line, &lineno) != 0 ||
1074
/* TODO: Get fileno from line, but how? */
1075
if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
1078
if (dwarf_lineaddr(line, &addr) != 0) {
1079
pr_warning("Failed to get the address of the line.\n");
1082
pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n",
1083
(int)i, lineno, (uintmax_t)addr);
1086
ret = call_probe_finder(NULL, pf);
1087
/* Continuing, because target line might be inlined. */
1303
return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
1092
1306
/* Find lines which match lazy pattern */
1093
1307
static int find_lazy_match_lines(struct list_head *head,
1094
1308
const char *fname, const char *pat)
1096
char *fbuf, *p1, *p2;
1097
int fd, line, nlines = -1;
1314
int count = 0, linenum = 1;
1100
fd = open(fname, O_RDONLY);
1102
pr_warning("Failed to open %s: %s\n", fname, strerror(-fd));
1316
fp = fopen(fname, "r");
1318
pr_warning("Failed to open %s: %s\n", fname, strerror(errno));
1106
if (fstat(fd, &st) < 0) {
1107
pr_warning("Failed to get the size of %s: %s\n",
1108
fname, strerror(errno));
1114
fbuf = malloc(st.st_size + 2);
1117
if (read(fd, fbuf, st.st_size) < 0) {
1118
pr_warning("Failed to read %s: %s\n", fname, strerror(errno));
1122
fbuf[st.st_size] = '\n'; /* Dummy line */
1123
fbuf[st.st_size + 1] = '\0';
1127
while ((p2 = strchr(p1, '\n')) != NULL) {
1129
if (strlazymatch(p1, pat)) {
1130
line_list__add_line(head, line);
1322
while ((len = getline(&line, &line_len, fp)) > 0) {
1324
if (line[len - 1] == '\n')
1325
line[len - 1] = '\0';
1327
if (strlazymatch(line, pat)) {
1328
line_list__add_line(head, linenum);
1340
pr_debug("No matched lines found in %s.\n", fname);
1344
static int probe_point_lazy_walker(const char *fname, int lineno,
1345
Dwarf_Addr addr, void *data)
1347
struct probe_finder *pf = data;
1350
if (!line_list__has_line(&pf->lcache, lineno) ||
1351
strtailcmp(fname, pf->fname) != 0)
1354
pr_debug("Probe line found: line:%d addr:0x%llx\n",
1355
lineno, (unsigned long long)addr);
1357
ret = call_probe_finder(NULL, pf);
1360
* Continue if no error, because the lazy pattern will match
1363
return ret < 0 ? ret : 0;
1143
1366
/* Find probe points from lazy pattern */
1144
1367
static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
1154
1371
if (list_empty(&pf->lcache)) {
1155
1372
/* Matching lazy line pattern */
1156
1373
ret = find_lazy_match_lines(&pf->lcache, pf->fname,
1157
1374
pf->pev->point.lazy_line);
1159
pr_debug("No matched lines found in %s.\n", pf->fname);
1165
if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
1166
pr_warning("No source lines found.\n");
1170
for (i = 0; i < nlines && ret >= 0; i++) {
1171
line = dwarf_onesrcline(lines, i);
1173
if (dwarf_lineno(line, &lineno) != 0 ||
1174
!line_list__has_line(&pf->lcache, lineno))
1177
/* TODO: Get fileno from line, but how? */
1178
if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
1181
if (dwarf_lineaddr(line, &addr) != 0) {
1182
pr_debug("Failed to get the address of line %d.\n",
1187
/* Address filtering 1: does sp_die include addr? */
1188
if (!dwarf_haspc(sp_die, addr))
1190
/* Address filtering 2: No child include addr? */
1191
if (die_find_inlinefunc(sp_die, addr, &die_mem))
1195
pr_debug("Probe line found: line[%d]:%d addr:0x%llx\n",
1196
(int)i, lineno, (unsigned long long)addr);
1199
ret = call_probe_finder(sp_die, pf);
1200
/* Continuing, because target line might be inlined. */
1202
/* TODO: deallocate lines, but how? */
1379
return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
1206
1382
/* Callback parameter with return value */
1319
1532
line_list__init(&pf->lcache);
1534
/* Fastpath: lookup by function name from .debug_pubnames section */
1536
struct pubname_callback_param pubname_param = {
1537
.function = pp->function,
1539
.cu_die = &pf->cu_die,
1540
.sp_die = &pf->sp_die,
1543
struct dwarf_callback_param probe_param = {
1547
dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
1548
if (pubname_param.found) {
1549
ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1320
1555
/* Loop on CUs (Compilation Unit) */
1321
while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) &&
1556
while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1323
1557
/* Get the DIE(Debugging Information Entry) of this CU */
1324
1558
diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die);
1569
/* Find a corresponding line */
1570
line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr);
1572
if (dwarf_lineaddr(line, &laddr) == 0 &&
1573
(Dwarf_Addr)addr == laddr &&
1574
dwarf_lineno(line, &lineno) == 0) {
1575
tmp = dwarf_linesrc(line, NULL, NULL);
1578
ppt->file = strdup(tmp);
1579
if (ppt->file == NULL) {
1805
/* Find a corresponding line (filename and lineno) */
1806
cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1807
/* Don't care whether it failed or not */
1588
/* Find a corresponding function */
1809
/* Find a corresponding function (name, baseline and baseaddr) */
1589
1810
if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1811
/* Get function entry information */
1590
1812
tmp = dwarf_diename(&spdie);
1591
if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0)
1814
dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1815
dwarf_decl_line(&spdie, &baseline) != 0)
1595
if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1597
/* addr in an inline function */
1819
if (addr == (unsigned long)baseaddr)
1820
/* Function entry - Relative line number is 0 */
1822
else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1824
if (dwarf_entrypc(&indie, &_addr) == 0 &&
1827
* addr is at an inline function entry.
1828
* In this case, lineno should be the call-site
1831
lineno = die_get_call_lineno(&indie);
1834
* addr is in an inline function body.
1835
* Since lineno points one of the lines
1836
* of the inline function, baseline should
1837
* be the entry line of the inline function.
1598
1839
tmp = dwarf_diename(&indie);
1601
ret = dwarf_decl_line(&indie, &lineno);
1603
if (eaddr == addr) { /* Function entry */
1607
ret = dwarf_decl_line(&spdie, &lineno);
1610
/* Make a relative line number */
1611
ppt->line -= lineno;
1841
dwarf_decl_line(&spdie, &baseline) == 0)
1615
/* We don't have a line number, let's use offset */
1616
ppt->offset = addr - (unsigned long)eaddr;
1618
ppt->function = strdup(tmp);
1848
/* Make a relative line number or an offset */
1850
ppt->line = lineno - baseline;
1852
ppt->offset = addr - (unsigned long)baseaddr;
1854
/* Duplicate strings */
1856
ppt->function = strdup(func);
1619
1857
if (ppt->function == NULL) {
1863
ppt->file = strdup(fname);
1864
if (ppt->file == NULL) {
1865
if (ppt->function) {
1866
free(ppt->function);
1867
ppt->function = NULL;
1628
1875
dwfl_end(dwfl);
1630
ret = found ? 1 : 0;
1876
if (ret == 0 && (fname || func))
1877
ret = 1; /* Found a point */
1644
1891
return line_list__add_line(&lr->line_list, lineno);
1647
/* Search function declaration lines */
1648
static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data)
1894
static int line_range_walk_cb(const char *fname, int lineno,
1895
Dwarf_Addr addr __used,
1650
struct dwarf_callback_param *param = data;
1651
struct line_finder *lf = param->data;
1655
src = dwarf_decl_file(sp_die);
1656
if (src && strtailcmp(src, lf->fname) != 0)
1659
if (dwarf_decl_line(sp_die, &lineno) != 0 ||
1898
struct line_finder *lf = data;
1900
if ((strtailcmp(fname, lf->fname) != 0) ||
1660
1901
(lf->lno_s > lineno || lf->lno_e < lineno))
1663
param->retval = line_range_add_line(src, lineno, lf->lr);
1664
if (param->retval < 0)
1665
return DWARF_CB_ABORT;
1669
static int find_line_range_func_decl_lines(struct line_finder *lf)
1671
struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1672
dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, ¶m, 0);
1673
return param.retval;
1904
if (line_range_add_line(fname, lineno, lf->lr) < 0)
1676
1910
/* Find line range from its line number */
1677
1911
static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1683
int lineno, ret = 0;
1687
line_list__init(&lf->lr->line_list);
1688
if (dwarf_getsrclines(&lf->cu_die, &lines, &nlines) != 0) {
1689
pr_warning("No source lines found.\n");
1693
/* Search probable lines on lines list */
1694
for (i = 0; i < nlines; i++) {
1695
line = dwarf_onesrcline(lines, i);
1696
if (dwarf_lineno(line, &lineno) != 0 ||
1697
(lf->lno_s > lineno || lf->lno_e < lineno))
1701
/* Address filtering 1: does sp_die include addr? */
1702
if (dwarf_lineaddr(line, &addr) != 0 ||
1703
!dwarf_haspc(sp_die, addr))
1706
/* Address filtering 2: No child include addr? */
1707
if (die_find_inlinefunc(sp_die, addr, &die_mem))
1711
/* TODO: Get fileno from line, but how? */
1712
src = dwarf_linesrc(line, NULL, NULL);
1713
if (strtailcmp(src, lf->fname) != 0)
1716
ret = line_range_add_line(src, lineno, lf->lr);
1722
* Dwarf lines doesn't include function declarations. We have to
1723
* check functions list or given function.
1726
src = dwarf_decl_file(sp_die);
1727
if (src && dwarf_decl_line(sp_die, &lineno) == 0 &&
1728
(lf->lno_s <= lineno && lf->lno_e >= lineno))
1729
ret = line_range_add_line(src, lineno, lf->lr);
1731
ret = find_line_range_func_decl_lines(lf);
1915
ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);
1733
1917
/* Update status */
1814
1999
pr_warning("No debug information found in the vmlinux - "
1815
2000
"please rebuild with CONFIG_DEBUG_INFO=y.\n");
2001
close(fd); /* Without dwfl_end(), fd isn't closed. */
2005
/* Fastpath: lookup by function name from .debug_pubnames section */
2007
struct pubname_callback_param pubname_param = {
2008
.function = lr->function, .file = lr->file,
2009
.cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
2010
struct dwarf_callback_param line_range_param = {
2011
.data = (void *)&lf, .retval = 0};
2013
dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
2014
if (pubname_param.found) {
2015
line_range_search_cb(&lf.sp_die, &line_range_param);
1819
2021
/* Loop on CUs (Compilation Unit) */
1820
2022
while (!lf.found && ret >= 0) {
1821
2023
if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)