probe-finder.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. /*
  2. * probe-finder.c : C expression to kprobe event converter
  3. *
  4. * Written by Masami Hiramatsu <mhiramat@redhat.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. *
  20. */
  21. #include <sys/utsname.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. #include <stdio.h>
  27. #include <unistd.h>
  28. #include <getopt.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <stdarg.h>
  32. #include <ctype.h>
  33. #include "event.h"
  34. #include "debug.h"
  35. #include "util.h"
  36. #include "probe-finder.h"
  37. /* Dwarf_Die Linkage to parent Die */
  38. struct die_link {
  39. struct die_link *parent; /* Parent die */
  40. Dwarf_Die die; /* Current die */
  41. };
  42. static Dwarf_Debug __dw_debug;
  43. static Dwarf_Error __dw_error;
  44. /*
  45. * Generic dwarf analysis helpers
  46. */
  47. #define X86_32_MAX_REGS 8
  48. const char *x86_32_regs_table[X86_32_MAX_REGS] = {
  49. "%ax",
  50. "%cx",
  51. "%dx",
  52. "%bx",
  53. "$stack", /* Stack address instead of %sp */
  54. "%bp",
  55. "%si",
  56. "%di",
  57. };
  58. #define X86_64_MAX_REGS 16
  59. const char *x86_64_regs_table[X86_64_MAX_REGS] = {
  60. "%ax",
  61. "%dx",
  62. "%cx",
  63. "%bx",
  64. "%si",
  65. "%di",
  66. "%bp",
  67. "%sp",
  68. "%r8",
  69. "%r9",
  70. "%r10",
  71. "%r11",
  72. "%r12",
  73. "%r13",
  74. "%r14",
  75. "%r15",
  76. };
  77. /* TODO: switching by dwarf address size */
  78. #ifdef __x86_64__
  79. #define ARCH_MAX_REGS X86_64_MAX_REGS
  80. #define arch_regs_table x86_64_regs_table
  81. #else
  82. #define ARCH_MAX_REGS X86_32_MAX_REGS
  83. #define arch_regs_table x86_32_regs_table
  84. #endif
  85. /* Return architecture dependent register string (for kprobe-tracer) */
  86. static const char *get_arch_regstr(unsigned int n)
  87. {
  88. return (n <= ARCH_MAX_REGS) ? arch_regs_table[n] : NULL;
  89. }
  90. /*
  91. * Compare the tail of two strings.
  92. * Return 0 if whole of either string is same as another's tail part.
  93. */
  94. static int strtailcmp(const char *s1, const char *s2)
  95. {
  96. int i1 = strlen(s1);
  97. int i2 = strlen(s2);
  98. while (--i1 > 0 && --i2 > 0) {
  99. if (s1[i1] != s2[i2])
  100. return s1[i1] - s2[i2];
  101. }
  102. return 0;
  103. }
  104. /* Find the fileno of the target file. */
  105. static Dwarf_Unsigned cu_find_fileno(Dwarf_Die cu_die, const char *fname)
  106. {
  107. Dwarf_Signed cnt, i;
  108. Dwarf_Unsigned found = 0;
  109. char **srcs;
  110. int ret;
  111. if (!fname)
  112. return 0;
  113. ret = dwarf_srcfiles(cu_die, &srcs, &cnt, &__dw_error);
  114. if (ret == DW_DLV_OK) {
  115. for (i = 0; i < cnt && !found; i++) {
  116. if (strtailcmp(srcs[i], fname) == 0)
  117. found = i + 1;
  118. dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
  119. }
  120. for (; i < cnt; i++)
  121. dwarf_dealloc(__dw_debug, srcs[i], DW_DLA_STRING);
  122. dwarf_dealloc(__dw_debug, srcs, DW_DLA_LIST);
  123. }
  124. if (found)
  125. pr_debug("found fno: %d\n", (int)found);
  126. return found;
  127. }
  128. /* Compare diename and tname */
  129. static int die_compare_name(Dwarf_Die dw_die, const char *tname)
  130. {
  131. char *name;
  132. int ret;
  133. ret = dwarf_diename(dw_die, &name, &__dw_error);
  134. DIE_IF(ret == DW_DLV_ERROR);
  135. if (ret == DW_DLV_OK) {
  136. ret = strcmp(tname, name);
  137. dwarf_dealloc(__dw_debug, name, DW_DLA_STRING);
  138. } else
  139. ret = -1;
  140. return ret;
  141. }
  142. /* Check the address is in the subprogram(function). */
  143. static int die_within_subprogram(Dwarf_Die sp_die, Dwarf_Addr addr,
  144. Dwarf_Signed *offs)
  145. {
  146. Dwarf_Addr lopc, hipc;
  147. int ret;
  148. /* TODO: check ranges */
  149. ret = dwarf_lowpc(sp_die, &lopc, &__dw_error);
  150. DIE_IF(ret == DW_DLV_ERROR);
  151. if (ret == DW_DLV_NO_ENTRY)
  152. return 0;
  153. ret = dwarf_highpc(sp_die, &hipc, &__dw_error);
  154. DIE_IF(ret != DW_DLV_OK);
  155. if (lopc <= addr && addr < hipc) {
  156. *offs = addr - lopc;
  157. return 1;
  158. } else
  159. return 0;
  160. }
  161. /* Check the die is inlined function */
  162. static Dwarf_Bool die_inlined_subprogram(Dwarf_Die dw_die)
  163. {
  164. /* TODO: check strictly */
  165. Dwarf_Bool inl;
  166. int ret;
  167. ret = dwarf_hasattr(dw_die, DW_AT_inline, &inl, &__dw_error);
  168. DIE_IF(ret == DW_DLV_ERROR);
  169. return inl;
  170. }
  171. /* Get the offset of abstruct_origin */
  172. static Dwarf_Off die_get_abstract_origin(Dwarf_Die dw_die)
  173. {
  174. Dwarf_Attribute attr;
  175. Dwarf_Off cu_offs;
  176. int ret;
  177. ret = dwarf_attr(dw_die, DW_AT_abstract_origin, &attr, &__dw_error);
  178. DIE_IF(ret != DW_DLV_OK);
  179. ret = dwarf_formref(attr, &cu_offs, &__dw_error);
  180. DIE_IF(ret != DW_DLV_OK);
  181. dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
  182. return cu_offs;
  183. }
  184. /* Get entry pc(or low pc, 1st entry of ranges) of the die */
  185. static Dwarf_Addr die_get_entrypc(Dwarf_Die dw_die)
  186. {
  187. Dwarf_Attribute attr;
  188. Dwarf_Addr addr;
  189. Dwarf_Off offs;
  190. Dwarf_Ranges *ranges;
  191. Dwarf_Signed cnt;
  192. int ret;
  193. /* Try to get entry pc */
  194. ret = dwarf_attr(dw_die, DW_AT_entry_pc, &attr, &__dw_error);
  195. DIE_IF(ret == DW_DLV_ERROR);
  196. if (ret == DW_DLV_OK) {
  197. ret = dwarf_formaddr(attr, &addr, &__dw_error);
  198. DIE_IF(ret != DW_DLV_OK);
  199. dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
  200. return addr;
  201. }
  202. /* Try to get low pc */
  203. ret = dwarf_lowpc(dw_die, &addr, &__dw_error);
  204. DIE_IF(ret == DW_DLV_ERROR);
  205. if (ret == DW_DLV_OK)
  206. return addr;
  207. /* Try to get ranges */
  208. ret = dwarf_attr(dw_die, DW_AT_ranges, &attr, &__dw_error);
  209. DIE_IF(ret != DW_DLV_OK);
  210. ret = dwarf_formref(attr, &offs, &__dw_error);
  211. DIE_IF(ret != DW_DLV_OK);
  212. ret = dwarf_get_ranges(__dw_debug, offs, &ranges, &cnt, NULL,
  213. &__dw_error);
  214. DIE_IF(ret != DW_DLV_OK);
  215. addr = ranges[0].dwr_addr1;
  216. dwarf_ranges_dealloc(__dw_debug, ranges, cnt);
  217. return addr;
  218. }
  219. /*
  220. * Search a Die from Die tree.
  221. * Note: cur_link->die should be deallocated in this function.
  222. */
  223. static int __search_die_tree(struct die_link *cur_link,
  224. int (*die_cb)(struct die_link *, void *),
  225. void *data)
  226. {
  227. Dwarf_Die new_die;
  228. struct die_link new_link;
  229. int ret;
  230. if (!die_cb)
  231. return 0;
  232. /* Check current die */
  233. while (!(ret = die_cb(cur_link, data))) {
  234. /* Check child die */
  235. ret = dwarf_child(cur_link->die, &new_die, &__dw_error);
  236. DIE_IF(ret == DW_DLV_ERROR);
  237. if (ret == DW_DLV_OK) {
  238. new_link.parent = cur_link;
  239. new_link.die = new_die;
  240. ret = __search_die_tree(&new_link, die_cb, data);
  241. if (ret)
  242. break;
  243. }
  244. /* Move to next sibling */
  245. ret = dwarf_siblingof(__dw_debug, cur_link->die, &new_die,
  246. &__dw_error);
  247. DIE_IF(ret == DW_DLV_ERROR);
  248. dwarf_dealloc(__dw_debug, cur_link->die, DW_DLA_DIE);
  249. cur_link->die = new_die;
  250. if (ret == DW_DLV_NO_ENTRY)
  251. return 0;
  252. }
  253. dwarf_dealloc(__dw_debug, cur_link->die, DW_DLA_DIE);
  254. return ret;
  255. }
  256. /* Search a die in its children's die tree */
  257. static int search_die_from_children(Dwarf_Die parent_die,
  258. int (*die_cb)(struct die_link *, void *),
  259. void *data)
  260. {
  261. struct die_link new_link;
  262. int ret;
  263. new_link.parent = NULL;
  264. ret = dwarf_child(parent_die, &new_link.die, &__dw_error);
  265. DIE_IF(ret == DW_DLV_ERROR);
  266. if (ret == DW_DLV_OK)
  267. return __search_die_tree(&new_link, die_cb, data);
  268. else
  269. return 0;
  270. }
  271. /* Find a locdesc corresponding to the address */
  272. static int attr_get_locdesc(Dwarf_Attribute attr, Dwarf_Locdesc *desc,
  273. Dwarf_Addr addr)
  274. {
  275. Dwarf_Signed lcnt;
  276. Dwarf_Locdesc **llbuf;
  277. int ret, i;
  278. ret = dwarf_loclist_n(attr, &llbuf, &lcnt, &__dw_error);
  279. DIE_IF(ret != DW_DLV_OK);
  280. ret = DW_DLV_NO_ENTRY;
  281. for (i = 0; i < lcnt; ++i) {
  282. if (llbuf[i]->ld_lopc <= addr &&
  283. llbuf[i]->ld_hipc > addr) {
  284. memcpy(desc, llbuf[i], sizeof(Dwarf_Locdesc));
  285. desc->ld_s =
  286. malloc(sizeof(Dwarf_Loc) * llbuf[i]->ld_cents);
  287. DIE_IF(desc->ld_s == NULL);
  288. memcpy(desc->ld_s, llbuf[i]->ld_s,
  289. sizeof(Dwarf_Loc) * llbuf[i]->ld_cents);
  290. ret = DW_DLV_OK;
  291. break;
  292. }
  293. dwarf_dealloc(__dw_debug, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
  294. dwarf_dealloc(__dw_debug, llbuf[i], DW_DLA_LOCDESC);
  295. }
  296. /* Releasing loop */
  297. for (; i < lcnt; ++i) {
  298. dwarf_dealloc(__dw_debug, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
  299. dwarf_dealloc(__dw_debug, llbuf[i], DW_DLA_LOCDESC);
  300. }
  301. dwarf_dealloc(__dw_debug, llbuf, DW_DLA_LIST);
  302. return ret;
  303. }
  304. /* Get decl_file attribute value (file number) */
  305. static Dwarf_Unsigned die_get_decl_file(Dwarf_Die sp_die)
  306. {
  307. Dwarf_Attribute attr;
  308. Dwarf_Unsigned fno;
  309. int ret;
  310. ret = dwarf_attr(sp_die, DW_AT_decl_file, &attr, &__dw_error);
  311. DIE_IF(ret != DW_DLV_OK);
  312. dwarf_formudata(attr, &fno, &__dw_error);
  313. DIE_IF(ret != DW_DLV_OK);
  314. dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
  315. return fno;
  316. }
  317. /* Get decl_line attribute value (line number) */
  318. static Dwarf_Unsigned die_get_decl_line(Dwarf_Die sp_die)
  319. {
  320. Dwarf_Attribute attr;
  321. Dwarf_Unsigned lno;
  322. int ret;
  323. ret = dwarf_attr(sp_die, DW_AT_decl_line, &attr, &__dw_error);
  324. DIE_IF(ret != DW_DLV_OK);
  325. dwarf_formudata(attr, &lno, &__dw_error);
  326. DIE_IF(ret != DW_DLV_OK);
  327. dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
  328. return lno;
  329. }
  330. /*
  331. * Probe finder related functions
  332. */
  333. /* Show a location */
  334. static void show_location(Dwarf_Loc *loc, struct probe_finder *pf)
  335. {
  336. Dwarf_Small op;
  337. Dwarf_Unsigned regn;
  338. Dwarf_Signed offs;
  339. int deref = 0, ret;
  340. const char *regs;
  341. op = loc->lr_atom;
  342. /* If this is based on frame buffer, set the offset */
  343. if (op == DW_OP_fbreg) {
  344. deref = 1;
  345. offs = (Dwarf_Signed)loc->lr_number;
  346. op = pf->fbloc.ld_s[0].lr_atom;
  347. loc = &pf->fbloc.ld_s[0];
  348. } else
  349. offs = 0;
  350. if (op >= DW_OP_breg0 && op <= DW_OP_breg31) {
  351. regn = op - DW_OP_breg0;
  352. offs += (Dwarf_Signed)loc->lr_number;
  353. deref = 1;
  354. } else if (op >= DW_OP_reg0 && op <= DW_OP_reg31) {
  355. regn = op - DW_OP_reg0;
  356. } else if (op == DW_OP_bregx) {
  357. regn = loc->lr_number;
  358. offs += (Dwarf_Signed)loc->lr_number2;
  359. deref = 1;
  360. } else if (op == DW_OP_regx) {
  361. regn = loc->lr_number;
  362. } else
  363. die("Dwarf_OP %d is not supported.\n", op);
  364. regs = get_arch_regstr(regn);
  365. if (!regs)
  366. die("%lld exceeds max register number.\n", regn);
  367. if (deref)
  368. ret = snprintf(pf->buf, pf->len,
  369. " %s=%+lld(%s)", pf->var, offs, regs);
  370. else
  371. ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs);
  372. DIE_IF(ret < 0);
  373. DIE_IF(ret >= pf->len);
  374. }
  375. /* Show a variables in kprobe event format */
  376. static void show_variable(Dwarf_Die vr_die, struct probe_finder *pf)
  377. {
  378. Dwarf_Attribute attr;
  379. Dwarf_Locdesc ld;
  380. int ret;
  381. ret = dwarf_attr(vr_die, DW_AT_location, &attr, &__dw_error);
  382. if (ret != DW_DLV_OK)
  383. goto error;
  384. ret = attr_get_locdesc(attr, &ld, (pf->addr - pf->cu_base));
  385. if (ret != DW_DLV_OK)
  386. goto error;
  387. /* TODO? */
  388. DIE_IF(ld.ld_cents != 1);
  389. show_location(&ld.ld_s[0], pf);
  390. free(ld.ld_s);
  391. dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
  392. return ;
  393. error:
  394. die("Failed to find the location of %s at this address.\n"
  395. " Perhaps, it has been optimized out.\n", pf->var);
  396. }
  397. static int variable_callback(struct die_link *dlink, void *data)
  398. {
  399. struct probe_finder *pf = (struct probe_finder *)data;
  400. Dwarf_Half tag;
  401. int ret;
  402. ret = dwarf_tag(dlink->die, &tag, &__dw_error);
  403. DIE_IF(ret == DW_DLV_ERROR);
  404. if ((tag == DW_TAG_formal_parameter ||
  405. tag == DW_TAG_variable) &&
  406. (die_compare_name(dlink->die, pf->var) == 0)) {
  407. show_variable(dlink->die, pf);
  408. return 1;
  409. }
  410. /* TODO: Support struct members and arrays */
  411. return 0;
  412. }
  413. /* Find a variable in a subprogram die */
  414. static void find_variable(Dwarf_Die sp_die, struct probe_finder *pf)
  415. {
  416. int ret;
  417. if (!is_c_varname(pf->var)) {
  418. /* Output raw parameters */
  419. ret = snprintf(pf->buf, pf->len, " %s", pf->var);
  420. DIE_IF(ret < 0);
  421. DIE_IF(ret >= pf->len);
  422. return ;
  423. }
  424. pr_debug("Searching '%s' variable in context.\n", pf->var);
  425. /* Search child die for local variables and parameters. */
  426. ret = search_die_from_children(sp_die, variable_callback, pf);
  427. if (!ret)
  428. die("Failed to find '%s' in this function.\n", pf->var);
  429. }
  430. /* Get a frame base on the address */
  431. static void get_current_frame_base(Dwarf_Die sp_die, struct probe_finder *pf)
  432. {
  433. Dwarf_Attribute attr;
  434. int ret;
  435. ret = dwarf_attr(sp_die, DW_AT_frame_base, &attr, &__dw_error);
  436. DIE_IF(ret != DW_DLV_OK);
  437. ret = attr_get_locdesc(attr, &pf->fbloc, (pf->addr - pf->cu_base));
  438. DIE_IF(ret != DW_DLV_OK);
  439. dwarf_dealloc(__dw_debug, attr, DW_DLA_ATTR);
  440. }
  441. static void free_current_frame_base(struct probe_finder *pf)
  442. {
  443. free(pf->fbloc.ld_s);
  444. memset(&pf->fbloc, 0, sizeof(Dwarf_Locdesc));
  445. }
  446. /* Show a probe point to output buffer */
  447. static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
  448. struct probe_finder *pf)
  449. {
  450. struct probe_point *pp = pf->pp;
  451. char *name;
  452. char tmp[MAX_PROBE_BUFFER];
  453. int ret, i, len;
  454. /* Output name of probe point */
  455. ret = dwarf_diename(sp_die, &name, &__dw_error);
  456. DIE_IF(ret == DW_DLV_ERROR);
  457. if (ret == DW_DLV_OK) {
  458. ret = snprintf(tmp, MAX_PROBE_BUFFER, "%s+%u", name,
  459. (unsigned int)offs);
  460. /* Copy the function name if possible */
  461. if (!pp->function) {
  462. pp->function = strdup(name);
  463. pp->offset = offs;
  464. }
  465. dwarf_dealloc(__dw_debug, name, DW_DLA_STRING);
  466. } else {
  467. /* This function has no name. */
  468. ret = snprintf(tmp, MAX_PROBE_BUFFER, "0x%llx", pf->addr);
  469. if (!pp->function) {
  470. /* TODO: Use _stext */
  471. pp->function = strdup("");
  472. pp->offset = (int)pf->addr;
  473. }
  474. }
  475. DIE_IF(ret < 0);
  476. DIE_IF(ret >= MAX_PROBE_BUFFER);
  477. len = ret;
  478. pr_debug("Probe point found: %s\n", tmp);
  479. /* Find each argument */
  480. get_current_frame_base(sp_die, pf);
  481. for (i = 0; i < pp->nr_args; i++) {
  482. pf->var = pp->args[i];
  483. pf->buf = &tmp[len];
  484. pf->len = MAX_PROBE_BUFFER - len;
  485. find_variable(sp_die, pf);
  486. len += strlen(pf->buf);
  487. }
  488. free_current_frame_base(pf);
  489. pp->probes[pp->found] = strdup(tmp);
  490. pp->found++;
  491. }
  492. static int probeaddr_callback(struct die_link *dlink, void *data)
  493. {
  494. struct probe_finder *pf = (struct probe_finder *)data;
  495. Dwarf_Half tag;
  496. Dwarf_Signed offs;
  497. int ret;
  498. ret = dwarf_tag(dlink->die, &tag, &__dw_error);
  499. DIE_IF(ret == DW_DLV_ERROR);
  500. /* Check the address is in this subprogram */
  501. if (tag == DW_TAG_subprogram &&
  502. die_within_subprogram(dlink->die, pf->addr, &offs)) {
  503. show_probepoint(dlink->die, offs, pf);
  504. return 1;
  505. }
  506. return 0;
  507. }
  508. /* Find probe point from its line number */
  509. static void find_by_line(struct probe_finder *pf)
  510. {
  511. Dwarf_Signed cnt, i, clm;
  512. Dwarf_Line *lines;
  513. Dwarf_Unsigned lineno = 0;
  514. Dwarf_Addr addr;
  515. Dwarf_Unsigned fno;
  516. int ret;
  517. ret = dwarf_srclines(pf->cu_die, &lines, &cnt, &__dw_error);
  518. DIE_IF(ret != DW_DLV_OK);
  519. for (i = 0; i < cnt; i++) {
  520. ret = dwarf_line_srcfileno(lines[i], &fno, &__dw_error);
  521. DIE_IF(ret != DW_DLV_OK);
  522. if (fno != pf->fno)
  523. continue;
  524. ret = dwarf_lineno(lines[i], &lineno, &__dw_error);
  525. DIE_IF(ret != DW_DLV_OK);
  526. if (lineno != pf->lno)
  527. continue;
  528. ret = dwarf_lineoff(lines[i], &clm, &__dw_error);
  529. DIE_IF(ret != DW_DLV_OK);
  530. ret = dwarf_lineaddr(lines[i], &addr, &__dw_error);
  531. DIE_IF(ret != DW_DLV_OK);
  532. pr_debug("Probe line found: line[%d]:%u,%d addr:0x%llx\n",
  533. (int)i, (unsigned)lineno, (int)clm, addr);
  534. pf->addr = addr;
  535. /* Search a real subprogram including this line, */
  536. ret = search_die_from_children(pf->cu_die,
  537. probeaddr_callback, pf);
  538. if (ret == 0)
  539. die("Probe point is not found in subprograms.\n");
  540. /* Continuing, because target line might be inlined. */
  541. }
  542. dwarf_srclines_dealloc(__dw_debug, lines, cnt);
  543. }
  544. /* Search function from function name */
  545. static int probefunc_callback(struct die_link *dlink, void *data)
  546. {
  547. struct probe_finder *pf = (struct probe_finder *)data;
  548. struct probe_point *pp = pf->pp;
  549. struct die_link *lk;
  550. Dwarf_Signed offs;
  551. Dwarf_Half tag;
  552. int ret;
  553. ret = dwarf_tag(dlink->die, &tag, &__dw_error);
  554. DIE_IF(ret == DW_DLV_ERROR);
  555. if (tag == DW_TAG_subprogram) {
  556. if (die_compare_name(dlink->die, pp->function) == 0) {
  557. if (pp->line) { /* Function relative line */
  558. pf->fno = die_get_decl_file(dlink->die);
  559. pf->lno = die_get_decl_line(dlink->die)
  560. + pp->line;
  561. find_by_line(pf);
  562. return 1;
  563. }
  564. if (die_inlined_subprogram(dlink->die)) {
  565. /* Inlined function, save it. */
  566. ret = dwarf_die_CU_offset(dlink->die,
  567. &pf->inl_offs,
  568. &__dw_error);
  569. DIE_IF(ret != DW_DLV_OK);
  570. pr_debug("inline definition offset %lld\n",
  571. pf->inl_offs);
  572. return 0; /* Continue to search */
  573. }
  574. /* Get probe address */
  575. pf->addr = die_get_entrypc(dlink->die);
  576. pf->addr += pp->offset;
  577. /* TODO: Check the address in this function */
  578. show_probepoint(dlink->die, pp->offset, pf);
  579. return 1; /* Exit; no same symbol in this CU. */
  580. }
  581. } else if (tag == DW_TAG_inlined_subroutine && pf->inl_offs) {
  582. if (die_get_abstract_origin(dlink->die) == pf->inl_offs) {
  583. /* Get probe address */
  584. pf->addr = die_get_entrypc(dlink->die);
  585. pf->addr += pp->offset;
  586. pr_debug("found inline addr: 0x%llx\n", pf->addr);
  587. /* Inlined function. Get a real subprogram */
  588. for (lk = dlink->parent; lk != NULL; lk = lk->parent) {
  589. tag = 0;
  590. dwarf_tag(lk->die, &tag, &__dw_error);
  591. DIE_IF(ret == DW_DLV_ERROR);
  592. if (tag == DW_TAG_subprogram &&
  593. !die_inlined_subprogram(lk->die))
  594. goto found;
  595. }
  596. die("Failed to find real subprogram.\n");
  597. found:
  598. /* Get offset from subprogram */
  599. ret = die_within_subprogram(lk->die, pf->addr, &offs);
  600. DIE_IF(!ret);
  601. show_probepoint(lk->die, offs, pf);
  602. /* Continue to search */
  603. }
  604. }
  605. return 0;
  606. }
  607. static void find_by_func(struct probe_finder *pf)
  608. {
  609. search_die_from_children(pf->cu_die, probefunc_callback, pf);
  610. }
  611. /* Find a probe point */
  612. int find_probepoint(int fd, struct probe_point *pp)
  613. {
  614. Dwarf_Half addr_size = 0;
  615. Dwarf_Unsigned next_cuh = 0;
  616. int cu_number = 0, ret;
  617. struct probe_finder pf = {.pp = pp};
  618. ret = dwarf_init(fd, DW_DLC_READ, 0, 0, &__dw_debug, &__dw_error);
  619. if (ret != DW_DLV_OK) {
  620. pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO.\n");
  621. return -ENOENT;
  622. }
  623. pp->found = 0;
  624. while (++cu_number) {
  625. /* Search CU (Compilation Unit) */
  626. ret = dwarf_next_cu_header(__dw_debug, NULL, NULL, NULL,
  627. &addr_size, &next_cuh, &__dw_error);
  628. DIE_IF(ret == DW_DLV_ERROR);
  629. if (ret == DW_DLV_NO_ENTRY)
  630. break;
  631. /* Get the DIE(Debugging Information Entry) of this CU */
  632. ret = dwarf_siblingof(__dw_debug, 0, &pf.cu_die, &__dw_error);
  633. DIE_IF(ret != DW_DLV_OK);
  634. /* Check if target file is included. */
  635. if (pp->file)
  636. pf.fno = cu_find_fileno(pf.cu_die, pp->file);
  637. if (!pp->file || pf.fno) {
  638. /* Save CU base address (for frame_base) */
  639. ret = dwarf_lowpc(pf.cu_die, &pf.cu_base, &__dw_error);
  640. DIE_IF(ret == DW_DLV_ERROR);
  641. if (ret == DW_DLV_NO_ENTRY)
  642. pf.cu_base = 0;
  643. if (pp->function)
  644. find_by_func(&pf);
  645. else {
  646. pf.lno = pp->line;
  647. find_by_line(&pf);
  648. }
  649. }
  650. dwarf_dealloc(__dw_debug, pf.cu_die, DW_DLA_DIE);
  651. }
  652. ret = dwarf_finish(__dw_debug, &__dw_error);
  653. DIE_IF(ret != DW_DLV_OK);
  654. return pp->found;
  655. }