@@ -114,7 +114,7 @@ static int strtailcmp(const char *s1, const char *s2)
114114}
115115
116116/* Find the fileno of the target file. */
117- static Dwarf_Unsigned die_get_fileno (Dwarf_Die cu_die , const char * fname )
117+ static Dwarf_Unsigned cu_find_fileno (Dwarf_Die cu_die , const char * fname )
118118{
119119 Dwarf_Signed cnt , i ;
120120 Dwarf_Unsigned found = 0 ;
@@ -335,6 +335,36 @@ static int attr_get_locdesc(Dwarf_Attribute attr, Dwarf_Locdesc *desc,
335335 return ret ;
336336}
337337
338+ /* Get decl_file attribute value (file number) */
339+ static Dwarf_Unsigned die_get_decl_file (Dwarf_Die sp_die )
340+ {
341+ Dwarf_Attribute attr ;
342+ Dwarf_Unsigned fno ;
343+ int ret ;
344+
345+ ret = dwarf_attr (sp_die , DW_AT_decl_file , & attr , & __dw_error );
346+ DIE_IF (ret != DW_DLV_OK );
347+ dwarf_formudata (attr , & fno , & __dw_error );
348+ DIE_IF (ret != DW_DLV_OK );
349+ dwarf_dealloc (__dw_debug , attr , DW_DLA_ATTR );
350+ return fno ;
351+ }
352+
353+ /* Get decl_line attribute value (line number) */
354+ static Dwarf_Unsigned die_get_decl_line (Dwarf_Die sp_die )
355+ {
356+ Dwarf_Attribute attr ;
357+ Dwarf_Unsigned lno ;
358+ int ret ;
359+
360+ ret = dwarf_attr (sp_die , DW_AT_decl_line , & attr , & __dw_error );
361+ DIE_IF (ret != DW_DLV_OK );
362+ dwarf_formudata (attr , & lno , & __dw_error );
363+ DIE_IF (ret != DW_DLV_OK );
364+ dwarf_dealloc (__dw_debug , attr , DW_DLA_ATTR );
365+ return lno ;
366+ }
367+
338368/*
339369 * Probe finder related functions
340370 */
@@ -501,6 +531,7 @@ static void show_probepoint(Dwarf_Die sp_die, Dwarf_Signed offs,
501531 DIE_IF (ret < 0 );
502532 DIE_IF (ret >= MAX_PROBE_BUFFER );
503533 len = ret ;
534+ pr_debug ("Probe point found: %s\n" , tmp );
504535
505536 /* Find each argument */
506537 get_current_frame_base (sp_die , pf );
@@ -536,17 +567,16 @@ static int probeaddr_callback(struct die_link *dlink, void *data)
536567}
537568
538569/* Find probe point from its line number */
539- static void find_by_line (Dwarf_Die cu_die , struct probe_finder * pf )
570+ static void find_by_line (struct probe_finder * pf )
540571{
541- struct probe_point * pp = pf -> pp ;
542- Dwarf_Signed cnt , i ;
572+ Dwarf_Signed cnt , i , clm ;
543573 Dwarf_Line * lines ;
544574 Dwarf_Unsigned lineno = 0 ;
545575 Dwarf_Addr addr ;
546576 Dwarf_Unsigned fno ;
547577 int ret ;
548578
549- ret = dwarf_srclines (cu_die , & lines , & cnt , & __dw_error );
579+ ret = dwarf_srclines (pf -> cu_die , & lines , & cnt , & __dw_error );
550580 DIE_IF (ret != DW_DLV_OK );
551581
552582 for (i = 0 ; i < cnt ; i ++ ) {
@@ -557,15 +587,20 @@ static void find_by_line(Dwarf_Die cu_die, struct probe_finder *pf)
557587
558588 ret = dwarf_lineno (lines [i ], & lineno , & __dw_error );
559589 DIE_IF (ret != DW_DLV_OK );
560- if (lineno != ( Dwarf_Unsigned ) pp -> line )
590+ if (lineno != pf -> lno )
561591 continue ;
562592
593+ ret = dwarf_lineoff (lines [i ], & clm , & __dw_error );
594+ DIE_IF (ret != DW_DLV_OK );
595+
563596 ret = dwarf_lineaddr (lines [i ], & addr , & __dw_error );
564597 DIE_IF (ret != DW_DLV_OK );
565- pr_debug ("Probe point found: 0x%llx\n" , addr );
598+ pr_debug ("Probe line found: line[%d]:%u,%d addr:0x%llx\n" ,
599+ (int )i , (unsigned )lineno , (int )clm , addr );
566600 pf -> addr = addr ;
567601 /* Search a real subprogram including this line, */
568- ret = search_die_from_children (cu_die , probeaddr_callback , pf );
602+ ret = search_die_from_children (pf -> cu_die ,
603+ probeaddr_callback , pf );
569604 if (ret == 0 )
570605 die ("Probe point is not found in subprograms.\n" );
571606 /* Continuing, because target line might be inlined. */
@@ -587,6 +622,13 @@ static int probefunc_callback(struct die_link *dlink, void *data)
587622 DIE_IF (ret == DW_DLV_ERROR );
588623 if (tag == DW_TAG_subprogram ) {
589624 if (die_compare_name (dlink -> die , pp -> function ) == 0 ) {
625+ if (pp -> line ) { /* Function relative line */
626+ pf -> fno = die_get_decl_file (dlink -> die );
627+ pf -> lno = die_get_decl_line (dlink -> die )
628+ + pp -> line ;
629+ find_by_line (pf );
630+ return 1 ;
631+ }
590632 if (die_inlined_subprogram (dlink -> die )) {
591633 /* Inlined function, save it. */
592634 ret = dwarf_die_CU_offset (dlink -> die ,
@@ -631,17 +673,16 @@ static int probefunc_callback(struct die_link *dlink, void *data)
631673 return 0 ;
632674}
633675
634- static void find_by_func (Dwarf_Die cu_die , struct probe_finder * pf )
676+ static void find_by_func (struct probe_finder * pf )
635677{
636- search_die_from_children (cu_die , probefunc_callback , pf );
678+ search_die_from_children (pf -> cu_die , probefunc_callback , pf );
637679}
638680
639681/* Find a probe point */
640682int find_probepoint (int fd , struct probe_point * pp )
641683{
642684 Dwarf_Half addr_size = 0 ;
643685 Dwarf_Unsigned next_cuh = 0 ;
644- Dwarf_Die cu_die = 0 ;
645686 int cu_number = 0 , ret ;
646687 struct probe_finder pf = {.pp = pp };
647688
@@ -659,25 +700,27 @@ int find_probepoint(int fd, struct probe_point *pp)
659700 break ;
660701
661702 /* Get the DIE(Debugging Information Entry) of this CU */
662- ret = dwarf_siblingof (__dw_debug , 0 , & cu_die , & __dw_error );
703+ ret = dwarf_siblingof (__dw_debug , 0 , & pf . cu_die , & __dw_error );
663704 DIE_IF (ret != DW_DLV_OK );
664705
665706 /* Check if target file is included. */
666707 if (pp -> file )
667- pf .fno = die_get_fileno ( cu_die , pp -> file );
708+ pf .fno = cu_find_fileno ( pf . cu_die , pp -> file );
668709
669710 if (!pp -> file || pf .fno ) {
670711 /* Save CU base address (for frame_base) */
671- ret = dwarf_lowpc (cu_die , & pf .cu_base , & __dw_error );
712+ ret = dwarf_lowpc (pf . cu_die , & pf .cu_base , & __dw_error );
672713 DIE_IF (ret == DW_DLV_ERROR );
673714 if (ret == DW_DLV_NO_ENTRY )
674715 pf .cu_base = 0 ;
675- if (pp -> line )
676- find_by_line (cu_die , & pf );
677716 if (pp -> function )
678- find_by_func (cu_die , & pf );
717+ find_by_func (& pf );
718+ else {
719+ pf .lno = pp -> line ;
720+ find_by_line (& pf );
721+ }
679722 }
680- dwarf_dealloc (__dw_debug , cu_die , DW_DLA_DIE );
723+ dwarf_dealloc (__dw_debug , pf . cu_die , DW_DLA_DIE );
681724 }
682725 ret = dwarf_finish (__dw_debug , & __dw_error );
683726 DIE_IF (ret != DW_DLV_OK );
0 commit comments