dwarf-aux.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  1. /*
  2. * dwarf-aux.c : libdw auxiliary interfaces
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. *
  18. */
  19. #include <errno.h>
  20. #include <inttypes.h>
  21. #include <stdbool.h>
  22. #include "util.h"
  23. #include "debug.h"
  24. #include "dwarf-aux.h"
  25. #include "string2.h"
  26. /**
  27. * cu_find_realpath - Find the realpath of the target file
  28. * @cu_die: A DIE(dwarf information entry) of CU(compilation Unit)
  29. * @fname: The tail filename of the target file
  30. *
  31. * Find the real(long) path of @fname in @cu_die.
  32. */
  33. const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
  34. {
  35. Dwarf_Files *files;
  36. size_t nfiles, i;
  37. const char *src = NULL;
  38. int ret;
  39. if (!fname)
  40. return NULL;
  41. ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
  42. if (ret != 0)
  43. return NULL;
  44. for (i = 0; i < nfiles; i++) {
  45. src = dwarf_filesrc(files, i, NULL, NULL);
  46. if (strtailcmp(src, fname) == 0)
  47. break;
  48. }
  49. if (i == nfiles)
  50. return NULL;
  51. return src;
  52. }
  53. /**
  54. * cu_get_comp_dir - Get the path of compilation directory
  55. * @cu_die: a CU DIE
  56. *
  57. * Get the path of compilation directory of given @cu_die.
  58. * Since this depends on DW_AT_comp_dir, older gcc will not
  59. * embedded it. In that case, this returns NULL.
  60. */
  61. const char *cu_get_comp_dir(Dwarf_Die *cu_die)
  62. {
  63. Dwarf_Attribute attr;
  64. if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
  65. return NULL;
  66. return dwarf_formstring(&attr);
  67. }
  68. /**
  69. * cu_find_lineinfo - Get a line number and file name for given address
  70. * @cu_die: a CU DIE
  71. * @addr: An address
  72. * @fname: a pointer which returns the file name string
  73. * @lineno: a pointer which returns the line number
  74. *
  75. * Find a line number and file name for @addr in @cu_die.
  76. */
  77. int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
  78. const char **fname, int *lineno)
  79. {
  80. Dwarf_Line *line;
  81. Dwarf_Addr laddr;
  82. line = dwarf_getsrc_die(cu_die, (Dwarf_Addr)addr);
  83. if (line && dwarf_lineaddr(line, &laddr) == 0 &&
  84. addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
  85. *fname = dwarf_linesrc(line, NULL, NULL);
  86. if (!*fname)
  87. /* line number is useless without filename */
  88. *lineno = 0;
  89. }
  90. return *lineno ?: -ENOENT;
  91. }
  92. static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data);
  93. /**
  94. * cu_walk_functions_at - Walk on function DIEs at given address
  95. * @cu_die: A CU DIE
  96. * @addr: An address
  97. * @callback: A callback which called with found DIEs
  98. * @data: A user data
  99. *
  100. * Walk on function DIEs at given @addr in @cu_die. Passed DIEs
  101. * should be subprogram or inlined-subroutines.
  102. */
  103. int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
  104. int (*callback)(Dwarf_Die *, void *), void *data)
  105. {
  106. Dwarf_Die die_mem;
  107. Dwarf_Die *sc_die;
  108. int ret = -ENOENT;
  109. /* Inlined function could be recursive. Trace it until fail */
  110. for (sc_die = die_find_realfunc(cu_die, addr, &die_mem);
  111. sc_die != NULL;
  112. sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr,
  113. &die_mem)) {
  114. ret = callback(sc_die, data);
  115. if (ret)
  116. break;
  117. }
  118. return ret;
  119. }
  120. /**
  121. * die_get_linkage_name - Get the linkage name of the object
  122. * @dw_die: A DIE of the object
  123. *
  124. * Get the linkage name attiribute of given @dw_die.
  125. * For C++ binary, the linkage name will be the mangled symbol.
  126. */
  127. const char *die_get_linkage_name(Dwarf_Die *dw_die)
  128. {
  129. Dwarf_Attribute attr;
  130. if (dwarf_attr_integrate(dw_die, DW_AT_linkage_name, &attr) == NULL)
  131. return NULL;
  132. return dwarf_formstring(&attr);
  133. }
  134. /**
  135. * die_compare_name - Compare diename and tname
  136. * @dw_die: a DIE
  137. * @tname: a string of target name
  138. *
  139. * Compare the name of @dw_die and @tname. Return false if @dw_die has no name.
  140. */
  141. bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
  142. {
  143. const char *name;
  144. name = dwarf_diename(dw_die);
  145. return name ? (strcmp(tname, name) == 0) : false;
  146. }
  147. /**
  148. * die_match_name - Match diename/linkage name and glob
  149. * @dw_die: a DIE
  150. * @glob: a string of target glob pattern
  151. *
  152. * Glob matching the name of @dw_die and @glob. Return false if matching fail.
  153. * This also match linkage name.
  154. */
  155. bool die_match_name(Dwarf_Die *dw_die, const char *glob)
  156. {
  157. const char *name;
  158. name = dwarf_diename(dw_die);
  159. if (name && strglobmatch(name, glob))
  160. return true;
  161. /* fall back to check linkage name */
  162. name = die_get_linkage_name(dw_die);
  163. if (name && strglobmatch(name, glob))
  164. return true;
  165. return false;
  166. }
  167. /**
  168. * die_get_call_lineno - Get callsite line number of inline-function instance
  169. * @in_die: a DIE of an inlined function instance
  170. *
  171. * Get call-site line number of @in_die. This means from where the inline
  172. * function is called.
  173. */
  174. int die_get_call_lineno(Dwarf_Die *in_die)
  175. {
  176. Dwarf_Attribute attr;
  177. Dwarf_Word ret;
  178. if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
  179. return -ENOENT;
  180. dwarf_formudata(&attr, &ret);
  181. return (int)ret;
  182. }
  183. /**
  184. * die_get_type - Get type DIE
  185. * @vr_die: a DIE of a variable
  186. * @die_mem: where to store a type DIE
  187. *
  188. * Get a DIE of the type of given variable (@vr_die), and store
  189. * it to die_mem. Return NULL if fails to get a type DIE.
  190. */
  191. Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
  192. {
  193. Dwarf_Attribute attr;
  194. if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
  195. dwarf_formref_die(&attr, die_mem))
  196. return die_mem;
  197. else
  198. return NULL;
  199. }
  200. /* Get a type die, but skip qualifiers */
  201. static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
  202. {
  203. int tag;
  204. do {
  205. vr_die = die_get_type(vr_die, die_mem);
  206. if (!vr_die)
  207. break;
  208. tag = dwarf_tag(vr_die);
  209. } while (tag == DW_TAG_const_type ||
  210. tag == DW_TAG_restrict_type ||
  211. tag == DW_TAG_volatile_type ||
  212. tag == DW_TAG_shared_type);
  213. return vr_die;
  214. }
  215. /**
  216. * die_get_real_type - Get a type die, but skip qualifiers and typedef
  217. * @vr_die: a DIE of a variable
  218. * @die_mem: where to store a type DIE
  219. *
  220. * Get a DIE of the type of given variable (@vr_die), and store
  221. * it to die_mem. Return NULL if fails to get a type DIE.
  222. * If the type is qualifiers (e.g. const) or typedef, this skips it
  223. * and tries to find real type (structure or basic types, e.g. int).
  224. */
  225. Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
  226. {
  227. do {
  228. vr_die = __die_get_real_type(vr_die, die_mem);
  229. } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
  230. return vr_die;
  231. }
  232. /* Get attribute and translate it as a udata */
  233. static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
  234. Dwarf_Word *result)
  235. {
  236. Dwarf_Attribute attr;
  237. if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
  238. dwarf_formudata(&attr, result) != 0)
  239. return -ENOENT;
  240. return 0;
  241. }
  242. /* Get attribute and translate it as a sdata */
  243. static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
  244. Dwarf_Sword *result)
  245. {
  246. Dwarf_Attribute attr;
  247. if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
  248. dwarf_formsdata(&attr, result) != 0)
  249. return -ENOENT;
  250. return 0;
  251. }
  252. /**
  253. * die_is_signed_type - Check whether a type DIE is signed or not
  254. * @tp_die: a DIE of a type
  255. *
  256. * Get the encoding of @tp_die and return true if the encoding
  257. * is signed.
  258. */
  259. bool die_is_signed_type(Dwarf_Die *tp_die)
  260. {
  261. Dwarf_Word ret;
  262. if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
  263. return false;
  264. return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
  265. ret == DW_ATE_signed_fixed);
  266. }
  267. /**
  268. * die_is_func_def - Ensure that this DIE is a subprogram and definition
  269. * @dw_die: a DIE
  270. *
  271. * Ensure that this DIE is a subprogram and NOT a declaration. This
  272. * returns true if @dw_die is a function definition.
  273. **/
  274. bool die_is_func_def(Dwarf_Die *dw_die)
  275. {
  276. Dwarf_Attribute attr;
  277. return (dwarf_tag(dw_die) == DW_TAG_subprogram &&
  278. dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL);
  279. }
  280. /**
  281. * die_entrypc - Returns entry PC (the lowest address) of a DIE
  282. * @dw_die: a DIE
  283. * @addr: where to store entry PC
  284. *
  285. * Since dwarf_entrypc() does not return entry PC if the DIE has only address
  286. * range, we have to use this to retrieve the lowest address from the address
  287. * range attribute.
  288. */
  289. int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr)
  290. {
  291. Dwarf_Addr base, end;
  292. if (!addr)
  293. return -EINVAL;
  294. if (dwarf_entrypc(dw_die, addr) == 0)
  295. return 0;
  296. return dwarf_ranges(dw_die, 0, &base, addr, &end) < 0 ? -ENOENT : 0;
  297. }
  298. /**
  299. * die_is_func_instance - Ensure that this DIE is an instance of a subprogram
  300. * @dw_die: a DIE
  301. *
  302. * Ensure that this DIE is an instance (which has an entry address).
  303. * This returns true if @dw_die is a function instance. If not, the @dw_die
  304. * must be a prototype. You can use die_walk_instances() to find actual
  305. * instances.
  306. **/
  307. bool die_is_func_instance(Dwarf_Die *dw_die)
  308. {
  309. Dwarf_Addr tmp;
  310. Dwarf_Attribute attr_mem;
  311. int tag = dwarf_tag(dw_die);
  312. if (tag != DW_TAG_subprogram &&
  313. tag != DW_TAG_inlined_subroutine)
  314. return false;
  315. return dwarf_entrypc(dw_die, &tmp) == 0 ||
  316. dwarf_attr(dw_die, DW_AT_ranges, &attr_mem) != NULL;
  317. }
  318. /**
  319. * die_get_data_member_location - Get the data-member offset
  320. * @mb_die: a DIE of a member of a data structure
  321. * @offs: The offset of the member in the data structure
  322. *
  323. * Get the offset of @mb_die in the data structure including @mb_die, and
  324. * stores result offset to @offs. If any error occurs this returns errno.
  325. */
  326. int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
  327. {
  328. Dwarf_Attribute attr;
  329. Dwarf_Op *expr;
  330. size_t nexpr;
  331. int ret;
  332. if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
  333. return -ENOENT;
  334. if (dwarf_formudata(&attr, offs) != 0) {
  335. /* DW_AT_data_member_location should be DW_OP_plus_uconst */
  336. ret = dwarf_getlocation(&attr, &expr, &nexpr);
  337. if (ret < 0 || nexpr == 0)
  338. return -ENOENT;
  339. if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
  340. pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
  341. expr[0].atom, nexpr);
  342. return -ENOTSUP;
  343. }
  344. *offs = (Dwarf_Word)expr[0].number;
  345. }
  346. return 0;
  347. }
  348. /* Get the call file index number in CU DIE */
  349. static int die_get_call_fileno(Dwarf_Die *in_die)
  350. {
  351. Dwarf_Sword idx;
  352. if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
  353. return (int)idx;
  354. else
  355. return -ENOENT;
  356. }
  357. /* Get the declared file index number in CU DIE */
  358. static int die_get_decl_fileno(Dwarf_Die *pdie)
  359. {
  360. Dwarf_Sword idx;
  361. if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
  362. return (int)idx;
  363. else
  364. return -ENOENT;
  365. }
  366. /**
  367. * die_get_call_file - Get callsite file name of inlined function instance
  368. * @in_die: a DIE of an inlined function instance
  369. *
  370. * Get call-site file name of @in_die. This means from which file the inline
  371. * function is called.
  372. */
  373. const char *die_get_call_file(Dwarf_Die *in_die)
  374. {
  375. Dwarf_Die cu_die;
  376. Dwarf_Files *files;
  377. int idx;
  378. idx = die_get_call_fileno(in_die);
  379. if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) ||
  380. dwarf_getsrcfiles(&cu_die, &files, NULL) != 0)
  381. return NULL;
  382. return dwarf_filesrc(files, idx, NULL, NULL);
  383. }
  384. /**
  385. * die_find_child - Generic DIE search function in DIE tree
  386. * @rt_die: a root DIE
  387. * @callback: a callback function
  388. * @data: a user data passed to the callback function
  389. * @die_mem: a buffer for result DIE
  390. *
  391. * Trace DIE tree from @rt_die and call @callback for each child DIE.
  392. * If @callback returns DIE_FIND_CB_END, this stores the DIE into
  393. * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE,
  394. * this continues to trace the tree. Optionally, @callback can return
  395. * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only
  396. * the children and trace only the siblings respectively.
  397. * Returns NULL if @callback can't find any appropriate DIE.
  398. */
  399. Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
  400. int (*callback)(Dwarf_Die *, void *),
  401. void *data, Dwarf_Die *die_mem)
  402. {
  403. Dwarf_Die child_die;
  404. int ret;
  405. ret = dwarf_child(rt_die, die_mem);
  406. if (ret != 0)
  407. return NULL;
  408. do {
  409. ret = callback(die_mem, data);
  410. if (ret == DIE_FIND_CB_END)
  411. return die_mem;
  412. if ((ret & DIE_FIND_CB_CHILD) &&
  413. die_find_child(die_mem, callback, data, &child_die)) {
  414. memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
  415. return die_mem;
  416. }
  417. } while ((ret & DIE_FIND_CB_SIBLING) &&
  418. dwarf_siblingof(die_mem, die_mem) == 0);
  419. return NULL;
  420. }
  421. struct __addr_die_search_param {
  422. Dwarf_Addr addr;
  423. Dwarf_Die *die_mem;
  424. };
  425. static int __die_search_func_tail_cb(Dwarf_Die *fn_die, void *data)
  426. {
  427. struct __addr_die_search_param *ad = data;
  428. Dwarf_Addr addr = 0;
  429. if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
  430. !dwarf_highpc(fn_die, &addr) &&
  431. addr == ad->addr) {
  432. memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
  433. return DWARF_CB_ABORT;
  434. }
  435. return DWARF_CB_OK;
  436. }
  437. /**
  438. * die_find_tailfunc - Search for a non-inlined function with tail call at
  439. * given address
  440. * @cu_die: a CU DIE which including @addr
  441. * @addr: target address
  442. * @die_mem: a buffer for result DIE
  443. *
  444. * Search for a non-inlined function DIE with tail call at @addr. Stores the
  445. * DIE to @die_mem and returns it if found. Returns NULL if failed.
  446. */
  447. Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
  448. Dwarf_Die *die_mem)
  449. {
  450. struct __addr_die_search_param ad;
  451. ad.addr = addr;
  452. ad.die_mem = die_mem;
  453. /* dwarf_getscopes can't find subprogram. */
  454. if (!dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0))
  455. return NULL;
  456. else
  457. return die_mem;
  458. }
  459. /* die_find callback for non-inlined function search */
  460. static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
  461. {
  462. struct __addr_die_search_param *ad = data;
  463. /*
  464. * Since a declaration entry doesn't has given pc, this always returns
  465. * function definition entry.
  466. */
  467. if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
  468. dwarf_haspc(fn_die, ad->addr)) {
  469. memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
  470. return DWARF_CB_ABORT;
  471. }
  472. return DWARF_CB_OK;
  473. }
  474. /**
  475. * die_find_realfunc - Search a non-inlined function at given address
  476. * @cu_die: a CU DIE which including @addr
  477. * @addr: target address
  478. * @die_mem: a buffer for result DIE
  479. *
  480. * Search a non-inlined function DIE which includes @addr. Stores the
  481. * DIE to @die_mem and returns it if found. Returns NULL if failed.
  482. */
  483. Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
  484. Dwarf_Die *die_mem)
  485. {
  486. struct __addr_die_search_param ad;
  487. ad.addr = addr;
  488. ad.die_mem = die_mem;
  489. /* dwarf_getscopes can't find subprogram. */
  490. if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
  491. return NULL;
  492. else
  493. return die_mem;
  494. }
  495. /* die_find callback for inline function search */
  496. static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
  497. {
  498. Dwarf_Addr *addr = data;
  499. if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
  500. dwarf_haspc(die_mem, *addr))
  501. return DIE_FIND_CB_END;
  502. return DIE_FIND_CB_CONTINUE;
  503. }
  504. /**
  505. * die_find_top_inlinefunc - Search the top inlined function at given address
  506. * @sp_die: a subprogram DIE which including @addr
  507. * @addr: target address
  508. * @die_mem: a buffer for result DIE
  509. *
  510. * Search an inlined function DIE which includes @addr. Stores the
  511. * DIE to @die_mem and returns it if found. Returns NULL if failed.
  512. * Even if several inlined functions are expanded recursively, this
  513. * doesn't trace it down, and returns the topmost one.
  514. */
  515. Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
  516. Dwarf_Die *die_mem)
  517. {
  518. return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
  519. }
  520. /**
  521. * die_find_inlinefunc - Search an inlined function at given address
  522. * @sp_die: a subprogram DIE which including @addr
  523. * @addr: target address
  524. * @die_mem: a buffer for result DIE
  525. *
  526. * Search an inlined function DIE which includes @addr. Stores the
  527. * DIE to @die_mem and returns it if found. Returns NULL if failed.
  528. * If several inlined functions are expanded recursively, this trace
  529. * it down and returns deepest one.
  530. */
  531. Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
  532. Dwarf_Die *die_mem)
  533. {
  534. Dwarf_Die tmp_die;
  535. sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
  536. if (!sp_die)
  537. return NULL;
  538. /* Inlined function could be recursive. Trace it until fail */
  539. while (sp_die) {
  540. memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
  541. sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
  542. &tmp_die);
  543. }
  544. return die_mem;
  545. }
  546. struct __instance_walk_param {
  547. void *addr;
  548. int (*callback)(Dwarf_Die *, void *);
  549. void *data;
  550. int retval;
  551. };
  552. static int __die_walk_instances_cb(Dwarf_Die *inst, void *data)
  553. {
  554. struct __instance_walk_param *iwp = data;
  555. Dwarf_Attribute attr_mem;
  556. Dwarf_Die origin_mem;
  557. Dwarf_Attribute *attr;
  558. Dwarf_Die *origin;
  559. int tmp;
  560. if (!die_is_func_instance(inst))
  561. return DIE_FIND_CB_CONTINUE;
  562. attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem);
  563. if (attr == NULL)
  564. return DIE_FIND_CB_CONTINUE;
  565. origin = dwarf_formref_die(attr, &origin_mem);
  566. if (origin == NULL || origin->addr != iwp->addr)
  567. return DIE_FIND_CB_CONTINUE;
  568. /* Ignore redundant instances */
  569. if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) {
  570. dwarf_decl_line(origin, &tmp);
  571. if (die_get_call_lineno(inst) == tmp) {
  572. tmp = die_get_decl_fileno(origin);
  573. if (die_get_call_fileno(inst) == tmp)
  574. return DIE_FIND_CB_CONTINUE;
  575. }
  576. }
  577. iwp->retval = iwp->callback(inst, iwp->data);
  578. return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE;
  579. }
  580. /**
  581. * die_walk_instances - Walk on instances of given DIE
  582. * @or_die: an abstract original DIE
  583. * @callback: a callback function which is called with instance DIE
  584. * @data: user data
  585. *
  586. * Walk on the instances of give @in_die. @in_die must be an inlined function
  587. * declartion. This returns the return value of @callback if it returns
  588. * non-zero value, or -ENOENT if there is no instance.
  589. */
  590. int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *),
  591. void *data)
  592. {
  593. Dwarf_Die cu_die;
  594. Dwarf_Die die_mem;
  595. struct __instance_walk_param iwp = {
  596. .addr = or_die->addr,
  597. .callback = callback,
  598. .data = data,
  599. .retval = -ENOENT,
  600. };
  601. if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL)
  602. return -ENOENT;
  603. die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem);
  604. return iwp.retval;
  605. }
  606. /* Line walker internal parameters */
  607. struct __line_walk_param {
  608. bool recursive;
  609. line_walk_callback_t callback;
  610. void *data;
  611. int retval;
  612. };
  613. static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
  614. {
  615. struct __line_walk_param *lw = data;
  616. Dwarf_Addr addr = 0;
  617. const char *fname;
  618. int lineno;
  619. if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
  620. fname = die_get_call_file(in_die);
  621. lineno = die_get_call_lineno(in_die);
  622. if (fname && lineno > 0 && die_entrypc(in_die, &addr) == 0) {
  623. lw->retval = lw->callback(fname, lineno, addr, lw->data);
  624. if (lw->retval != 0)
  625. return DIE_FIND_CB_END;
  626. }
  627. if (!lw->recursive)
  628. return DIE_FIND_CB_SIBLING;
  629. }
  630. if (addr) {
  631. fname = dwarf_decl_file(in_die);
  632. if (fname && dwarf_decl_line(in_die, &lineno) == 0) {
  633. lw->retval = lw->callback(fname, lineno, addr, lw->data);
  634. if (lw->retval != 0)
  635. return DIE_FIND_CB_END;
  636. }
  637. }
  638. /* Continue to search nested inlined function call-sites */
  639. return DIE_FIND_CB_CONTINUE;
  640. }
  641. /* Walk on lines of blocks included in given DIE */
  642. static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive,
  643. line_walk_callback_t callback, void *data)
  644. {
  645. struct __line_walk_param lw = {
  646. .recursive = recursive,
  647. .callback = callback,
  648. .data = data,
  649. .retval = 0,
  650. };
  651. Dwarf_Die die_mem;
  652. Dwarf_Addr addr;
  653. const char *fname;
  654. int lineno;
  655. /* Handle function declaration line */
  656. fname = dwarf_decl_file(sp_die);
  657. if (fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
  658. die_entrypc(sp_die, &addr) == 0) {
  659. lw.retval = callback(fname, lineno, addr, data);
  660. if (lw.retval != 0)
  661. goto done;
  662. }
  663. die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
  664. done:
  665. return lw.retval;
  666. }
  667. static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
  668. {
  669. struct __line_walk_param *lw = data;
  670. /*
  671. * Since inlined function can include another inlined function in
  672. * the same file, we need to walk in it recursively.
  673. */
  674. lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data);
  675. if (lw->retval != 0)
  676. return DWARF_CB_ABORT;
  677. return DWARF_CB_OK;
  678. }
  679. /**
  680. * die_walk_lines - Walk on lines inside given DIE
  681. * @rt_die: a root DIE (CU, subprogram or inlined_subroutine)
  682. * @callback: callback routine
  683. * @data: user data
  684. *
  685. * Walk on all lines inside given @rt_die and call @callback on each line.
  686. * If the @rt_die is a function, walk only on the lines inside the function,
  687. * otherwise @rt_die must be a CU DIE.
  688. * Note that this walks not only dwarf line list, but also function entries
  689. * and inline call-site.
  690. */
  691. int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
  692. {
  693. Dwarf_Lines *lines;
  694. Dwarf_Line *line;
  695. Dwarf_Addr addr;
  696. const char *fname, *decf = NULL, *inf = NULL;
  697. int lineno, ret = 0;
  698. int decl = 0, inl;
  699. Dwarf_Die die_mem, *cu_die;
  700. size_t nlines, i;
  701. bool flag;
  702. /* Get the CU die */
  703. if (dwarf_tag(rt_die) != DW_TAG_compile_unit) {
  704. cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL);
  705. dwarf_decl_line(rt_die, &decl);
  706. decf = dwarf_decl_file(rt_die);
  707. } else
  708. cu_die = rt_die;
  709. if (!cu_die) {
  710. pr_debug2("Failed to get CU from given DIE.\n");
  711. return -EINVAL;
  712. }
  713. /* Get lines list in the CU */
  714. if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
  715. pr_debug2("Failed to get source lines on this CU.\n");
  716. return -ENOENT;
  717. }
  718. pr_debug2("Get %zd lines from this CU\n", nlines);
  719. /* Walk on the lines on lines list */
  720. for (i = 0; i < nlines; i++) {
  721. line = dwarf_onesrcline(lines, i);
  722. if (line == NULL ||
  723. dwarf_lineno(line, &lineno) != 0 ||
  724. dwarf_lineaddr(line, &addr) != 0) {
  725. pr_debug2("Failed to get line info. "
  726. "Possible error in debuginfo.\n");
  727. continue;
  728. }
  729. /* Skip end-of-sequence */
  730. if (dwarf_lineendsequence(line, &flag) != 0 || flag)
  731. continue;
  732. /* Skip Non statement line-info */
  733. if (dwarf_linebeginstatement(line, &flag) != 0 || !flag)
  734. continue;
  735. /* Filter lines based on address */
  736. if (rt_die != cu_die) {
  737. /*
  738. * Address filtering
  739. * The line is included in given function, and
  740. * no inline block includes it.
  741. */
  742. if (!dwarf_haspc(rt_die, addr))
  743. continue;
  744. if (die_find_inlinefunc(rt_die, addr, &die_mem)) {
  745. /* Call-site check */
  746. inf = die_get_call_file(&die_mem);
  747. if ((inf && !strcmp(inf, decf)) &&
  748. die_get_call_lineno(&die_mem) == lineno)
  749. goto found;
  750. dwarf_decl_line(&die_mem, &inl);
  751. if (inl != decl ||
  752. decf != dwarf_decl_file(&die_mem))
  753. continue;
  754. }
  755. }
  756. found:
  757. /* Get source line */
  758. fname = dwarf_linesrc(line, NULL, NULL);
  759. ret = callback(fname, lineno, addr, data);
  760. if (ret != 0)
  761. return ret;
  762. }
  763. /*
  764. * Dwarf lines doesn't include function declarations and inlined
  765. * subroutines. We have to check functions list or given function.
  766. */
  767. if (rt_die != cu_die)
  768. /*
  769. * Don't need walk inlined functions recursively, because
  770. * inner inlined functions don't have the lines of the
  771. * specified function.
  772. */
  773. ret = __die_walk_funclines(rt_die, false, callback, data);
  774. else {
  775. struct __line_walk_param param = {
  776. .callback = callback,
  777. .data = data,
  778. .retval = 0,
  779. };
  780. dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
  781. ret = param.retval;
  782. }
  783. return ret;
  784. }
  785. struct __find_variable_param {
  786. const char *name;
  787. Dwarf_Addr addr;
  788. };
  789. static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
  790. {
  791. struct __find_variable_param *fvp = data;
  792. Dwarf_Attribute attr;
  793. int tag;
  794. tag = dwarf_tag(die_mem);
  795. if ((tag == DW_TAG_formal_parameter ||
  796. tag == DW_TAG_variable) &&
  797. die_compare_name(die_mem, fvp->name) &&
  798. /* Does the DIE have location information or external instance? */
  799. (dwarf_attr(die_mem, DW_AT_external, &attr) ||
  800. dwarf_attr(die_mem, DW_AT_location, &attr)))
  801. return DIE_FIND_CB_END;
  802. if (dwarf_haspc(die_mem, fvp->addr))
  803. return DIE_FIND_CB_CONTINUE;
  804. else
  805. return DIE_FIND_CB_SIBLING;
  806. }
  807. /**
  808. * die_find_variable_at - Find a given name variable at given address
  809. * @sp_die: a function DIE
  810. * @name: variable name
  811. * @addr: address
  812. * @die_mem: a buffer for result DIE
  813. *
  814. * Find a variable DIE called @name at @addr in @sp_die.
  815. */
  816. Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
  817. Dwarf_Addr addr, Dwarf_Die *die_mem)
  818. {
  819. struct __find_variable_param fvp = { .name = name, .addr = addr};
  820. return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
  821. die_mem);
  822. }
  823. static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
  824. {
  825. const char *name = data;
  826. if (dwarf_tag(die_mem) == DW_TAG_member) {
  827. if (die_compare_name(die_mem, name))
  828. return DIE_FIND_CB_END;
  829. else if (!dwarf_diename(die_mem)) { /* Unnamed structure */
  830. Dwarf_Die type_die, tmp_die;
  831. if (die_get_type(die_mem, &type_die) &&
  832. die_find_member(&type_die, name, &tmp_die))
  833. return DIE_FIND_CB_END;
  834. }
  835. }
  836. return DIE_FIND_CB_SIBLING;
  837. }
  838. /**
  839. * die_find_member - Find a given name member in a data structure
  840. * @st_die: a data structure type DIE
  841. * @name: member name
  842. * @die_mem: a buffer for result DIE
  843. *
  844. * Find a member DIE called @name in @st_die.
  845. */
  846. Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
  847. Dwarf_Die *die_mem)
  848. {
  849. return die_find_child(st_die, __die_find_member_cb, (void *)name,
  850. die_mem);
  851. }
  852. /**
  853. * die_get_typename - Get the name of given variable DIE
  854. * @vr_die: a variable DIE
  855. * @buf: a strbuf for result type name
  856. *
  857. * Get the name of @vr_die and stores it to @buf. Return 0 if succeeded.
  858. * and Return -ENOENT if failed to find type name.
  859. * Note that the result will stores typedef name if possible, and stores
  860. * "*(function_type)" if the type is a function pointer.
  861. */
  862. int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
  863. {
  864. Dwarf_Die type;
  865. int tag, ret;
  866. const char *tmp = "";
  867. if (__die_get_real_type(vr_die, &type) == NULL)
  868. return -ENOENT;
  869. tag = dwarf_tag(&type);
  870. if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
  871. tmp = "*";
  872. else if (tag == DW_TAG_subroutine_type) {
  873. /* Function pointer */
  874. return strbuf_add(buf, "(function_type)", 15);
  875. } else {
  876. if (!dwarf_diename(&type))
  877. return -ENOENT;
  878. if (tag == DW_TAG_union_type)
  879. tmp = "union ";
  880. else if (tag == DW_TAG_structure_type)
  881. tmp = "struct ";
  882. else if (tag == DW_TAG_enumeration_type)
  883. tmp = "enum ";
  884. /* Write a base name */
  885. return strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type));
  886. }
  887. ret = die_get_typename(&type, buf);
  888. return ret ? ret : strbuf_addstr(buf, tmp);
  889. }
  890. /**
  891. * die_get_varname - Get the name and type of given variable DIE
  892. * @vr_die: a variable DIE
  893. * @buf: a strbuf for type and variable name
  894. *
  895. * Get the name and type of @vr_die and stores it in @buf as "type\tname".
  896. */
  897. int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
  898. {
  899. int ret;
  900. ret = die_get_typename(vr_die, buf);
  901. if (ret < 0) {
  902. pr_debug("Failed to get type, make it unknown.\n");
  903. ret = strbuf_add(buf, " (unknown_type)", 14);
  904. }
  905. return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
  906. }
  907. #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT
  908. /**
  909. * die_get_var_innermost_scope - Get innermost scope range of given variable DIE
  910. * @sp_die: a subprogram DIE
  911. * @vr_die: a variable DIE
  912. * @buf: a strbuf for variable byte offset range
  913. *
  914. * Get the innermost scope range of @vr_die and stores it in @buf as
  915. * "@<function_name+[NN-NN,NN-NN]>".
  916. */
  917. static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
  918. struct strbuf *buf)
  919. {
  920. Dwarf_Die *scopes;
  921. int count;
  922. size_t offset = 0;
  923. Dwarf_Addr base;
  924. Dwarf_Addr start, end;
  925. Dwarf_Addr entry;
  926. int ret;
  927. bool first = true;
  928. const char *name;
  929. ret = die_entrypc(sp_die, &entry);
  930. if (ret)
  931. return ret;
  932. name = dwarf_diename(sp_die);
  933. if (!name)
  934. return -ENOENT;
  935. count = dwarf_getscopes_die(vr_die, &scopes);
  936. /* (*SCOPES)[1] is the DIE for the scope containing that scope */
  937. if (count <= 1) {
  938. ret = -EINVAL;
  939. goto out;
  940. }
  941. while ((offset = dwarf_ranges(&scopes[1], offset, &base,
  942. &start, &end)) > 0) {
  943. start -= entry;
  944. end -= entry;
  945. if (first) {
  946. ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
  947. name, start, end);
  948. first = false;
  949. } else {
  950. ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
  951. start, end);
  952. }
  953. if (ret < 0)
  954. goto out;
  955. }
  956. if (!first)
  957. ret = strbuf_add(buf, "]>", 2);
  958. out:
  959. free(scopes);
  960. return ret;
  961. }
  962. /**
  963. * die_get_var_range - Get byte offset range of given variable DIE
  964. * @sp_die: a subprogram DIE
  965. * @vr_die: a variable DIE
  966. * @buf: a strbuf for type and variable name and byte offset range
  967. *
  968. * Get the byte offset range of @vr_die and stores it in @buf as
  969. * "@<function_name+[NN-NN,NN-NN]>".
  970. */
  971. int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
  972. {
  973. int ret = 0;
  974. Dwarf_Addr base;
  975. Dwarf_Addr start, end;
  976. Dwarf_Addr entry;
  977. Dwarf_Op *op;
  978. size_t nops;
  979. size_t offset = 0;
  980. Dwarf_Attribute attr;
  981. bool first = true;
  982. const char *name;
  983. ret = die_entrypc(sp_die, &entry);
  984. if (ret)
  985. return ret;
  986. name = dwarf_diename(sp_die);
  987. if (!name)
  988. return -ENOENT;
  989. if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
  990. return -EINVAL;
  991. while ((offset = dwarf_getlocations(&attr, offset, &base,
  992. &start, &end, &op, &nops)) > 0) {
  993. if (start == 0) {
  994. /* Single Location Descriptions */
  995. ret = die_get_var_innermost_scope(sp_die, vr_die, buf);
  996. goto out;
  997. }
  998. /* Location Lists */
  999. start -= entry;
  1000. end -= entry;
  1001. if (first) {
  1002. ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
  1003. name, start, end);
  1004. first = false;
  1005. } else {
  1006. ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
  1007. start, end);
  1008. }
  1009. if (ret < 0)
  1010. goto out;
  1011. }
  1012. if (!first)
  1013. ret = strbuf_add(buf, "]>", 2);
  1014. out:
  1015. return ret;
  1016. }
  1017. #else
  1018. int die_get_var_range(Dwarf_Die *sp_die __maybe_unused,
  1019. Dwarf_Die *vr_die __maybe_unused,
  1020. struct strbuf *buf __maybe_unused)
  1021. {
  1022. return -ENOTSUP;
  1023. }
  1024. #endif
  1025. /*
  1026. * die_has_loclist - Check if DW_AT_location of @vr_die is a location list
  1027. * @vr_die: a variable DIE
  1028. */
  1029. static bool die_has_loclist(Dwarf_Die *vr_die)
  1030. {
  1031. Dwarf_Attribute loc;
  1032. int tag = dwarf_tag(vr_die);
  1033. if (tag != DW_TAG_formal_parameter &&
  1034. tag != DW_TAG_variable)
  1035. return false;
  1036. return (dwarf_attr_integrate(vr_die, DW_AT_location, &loc) &&
  1037. dwarf_whatform(&loc) == DW_FORM_sec_offset);
  1038. }
  1039. /*
  1040. * die_is_optimized_target - Check if target program is compiled with
  1041. * optimization
  1042. * @cu_die: a CU DIE
  1043. *
  1044. * For any object in given CU whose DW_AT_location is a location list,
  1045. * target program is compiled with optimization. This is applicable to
  1046. * clang as well.
  1047. */
  1048. bool die_is_optimized_target(Dwarf_Die *cu_die)
  1049. {
  1050. Dwarf_Die tmp_die;
  1051. if (die_has_loclist(cu_die))
  1052. return true;
  1053. if (!dwarf_child(cu_die, &tmp_die) &&
  1054. die_is_optimized_target(&tmp_die))
  1055. return true;
  1056. if (!dwarf_siblingof(cu_die, &tmp_die) &&
  1057. die_is_optimized_target(&tmp_die))
  1058. return true;
  1059. return false;
  1060. }
  1061. /*
  1062. * die_search_idx - Search index of given line address
  1063. * @lines: Line records of single CU
  1064. * @nr_lines: Number of @lines
  1065. * @addr: address we are looking for
  1066. * @idx: index to be set by this function (return value)
  1067. *
  1068. * Search for @addr by looping over every lines of CU. If address
  1069. * matches, set index of that line in @idx. Note that single source
  1070. * line can have multiple line records. i.e. single source line can
  1071. * have multiple index.
  1072. */
  1073. static bool die_search_idx(Dwarf_Lines *lines, unsigned long nr_lines,
  1074. Dwarf_Addr addr, unsigned long *idx)
  1075. {
  1076. unsigned long i;
  1077. Dwarf_Addr tmp;
  1078. for (i = 0; i < nr_lines; i++) {
  1079. if (dwarf_lineaddr(dwarf_onesrcline(lines, i), &tmp))
  1080. return false;
  1081. if (tmp == addr) {
  1082. *idx = i;
  1083. return true;
  1084. }
  1085. }
  1086. return false;
  1087. }
  1088. /*
  1089. * die_get_postprologue_addr - Search next address after function prologue
  1090. * @entrypc_idx: entrypc index
  1091. * @lines: Line records of single CU
  1092. * @nr_lines: Number of @lines
  1093. * @hignpc: high PC address of function
  1094. * @postprologue_addr: Next address after function prologue (return value)
  1095. *
  1096. * Look for prologue-end marker. If there is no explicit marker, return
  1097. * address of next line record or next source line.
  1098. */
  1099. static bool die_get_postprologue_addr(unsigned long entrypc_idx,
  1100. Dwarf_Lines *lines,
  1101. unsigned long nr_lines,
  1102. Dwarf_Addr highpc,
  1103. Dwarf_Addr *postprologue_addr)
  1104. {
  1105. unsigned long i;
  1106. int entrypc_lno, lno;
  1107. Dwarf_Line *line;
  1108. Dwarf_Addr addr;
  1109. bool p_end;
  1110. /* entrypc_lno is actual source line number */
  1111. line = dwarf_onesrcline(lines, entrypc_idx);
  1112. if (dwarf_lineno(line, &entrypc_lno))
  1113. return false;
  1114. for (i = entrypc_idx; i < nr_lines; i++) {
  1115. line = dwarf_onesrcline(lines, i);
  1116. if (dwarf_lineaddr(line, &addr) ||
  1117. dwarf_lineno(line, &lno) ||
  1118. dwarf_lineprologueend(line, &p_end))
  1119. return false;
  1120. /* highpc is exclusive. [entrypc,highpc) */
  1121. if (addr >= highpc)
  1122. break;
  1123. /* clang supports prologue-end marker */
  1124. if (p_end)
  1125. break;
  1126. /* Actual next line in source */
  1127. if (lno != entrypc_lno)
  1128. break;
  1129. /*
  1130. * Single source line can have multiple line records.
  1131. * For Example,
  1132. * void foo() { printf("hello\n"); }
  1133. * contains two line records. One points to declaration and
  1134. * other points to printf() line. Variable 'lno' won't get
  1135. * incremented in this case but 'i' will.
  1136. */
  1137. if (i != entrypc_idx)
  1138. break;
  1139. }
  1140. dwarf_lineaddr(line, postprologue_addr);
  1141. if (*postprologue_addr >= highpc)
  1142. dwarf_lineaddr(dwarf_onesrcline(lines, i - 1),
  1143. postprologue_addr);
  1144. return true;
  1145. }
  1146. /*
  1147. * die_skip_prologue - Use next address after prologue as probe location
  1148. * @sp_die: a subprogram DIE
  1149. * @cu_die: a CU DIE
  1150. * @entrypc: entrypc of the function
  1151. *
  1152. * Function prologue prepares stack and registers before executing function
  1153. * logic. When target program is compiled without optimization, function
  1154. * parameter information is only valid after prologue. When we probe entrypc
  1155. * of the function, and try to record function parameter, it contains
  1156. * garbage value.
  1157. */
  1158. void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die,
  1159. Dwarf_Addr *entrypc)
  1160. {
  1161. size_t nr_lines = 0;
  1162. unsigned long entrypc_idx = 0;
  1163. Dwarf_Lines *lines = NULL;
  1164. Dwarf_Addr postprologue_addr;
  1165. Dwarf_Addr highpc;
  1166. if (dwarf_highpc(sp_die, &highpc))
  1167. return;
  1168. if (dwarf_getsrclines(cu_die, &lines, &nr_lines))
  1169. return;
  1170. if (!die_search_idx(lines, nr_lines, *entrypc, &entrypc_idx))
  1171. return;
  1172. if (!die_get_postprologue_addr(entrypc_idx, lines, nr_lines,
  1173. highpc, &postprologue_addr))
  1174. return;
  1175. *entrypc = postprologue_addr;
  1176. }