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