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