This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: objdump -S omits source when input uses .gnu_debuglink


Hi Noah,

When an object's debugging information resides in a separate file, linked via a
.gnu_debuglink section, `objdump -S' does not show source code; the output is
rigorously identical to that of `objdump -d'.

Hmm, this was not quite as straightforward as I would have hoped, but I think there is a way to do it. Please could you try out the attached patch and let me know if it works for you.


Cheers
  Nick

Index: bfd/dwarf2.c
===================================================================
RCS file: /cvs/src/src/bfd/dwarf2.c,v
retrieving revision 1.93
diff -c -3 -p -r1.93 dwarf2.c
*** bfd/dwarf2.c	26 Apr 2007 14:46:56 -0000	1.93
--- bfd/dwarf2.c	19 Jun 2007 15:00:26 -0000
*************** struct dwarf2_debug
*** 93,100 ****
    /* Pointer to the end of the .debug_info section memory buffer.  */
    bfd_byte *info_ptr_end;
  
!   /* Pointer to the section and address of the beginning of the
!      section.  */
    asection *sec;
    bfd_byte *sec_info_ptr;
  
--- 93,102 ----
    /* Pointer to the end of the .debug_info section memory buffer.  */
    bfd_byte *info_ptr_end;
  
!   /* Pointer to the bfd, section and address of the beginning of the
!      section.  The bfd might be different than expected because of
!      gnu_debuglink sections.  */
!   bfd * bfd;
    asection *sec;
    bfd_byte *sec_info_ptr;
  
*************** scan_unit_for_symbols (struct comp_unit 
*** 1888,1895 ****
     to get to the line number information for the compilation unit.  */
  
  static struct comp_unit *
! parse_comp_unit (bfd *abfd,
! 		 struct dwarf2_debug *stash,
  		 bfd_vma unit_length,
  		 bfd_byte *info_ptr_unit,
  		 unsigned int offset_size)
--- 1890,1896 ----
     to get to the line number information for the compilation unit.  */
  
  static struct comp_unit *
! parse_comp_unit (struct dwarf2_debug *stash,
  		 bfd_vma unit_length,
  		 bfd_byte *info_ptr_unit,
  		 unsigned int offset_size)
*************** parse_comp_unit (bfd *abfd,
*** 1907,1912 ****
--- 1908,1914 ----
    bfd_size_type amt;
    bfd_vma low_pc = 0;
    bfd_vma high_pc = 0;
+   bfd *abfd = stash->bfd;
  
    version = read_2_bytes (abfd, info_ptr);
    info_ptr += 2;
*************** find_debug_info (bfd *abfd, asection *af
*** 2192,2201 ****
  {
    asection * msec;
  
!   if (after_sec)
!     msec = after_sec->next;
!   else
!     msec = abfd->sections;
  
    while (msec)
      {
--- 2194,2200 ----
  {
    asection * msec;
  
!   msec = after_sec != NULL ? after_sec->next : abfd->sections;
  
    while (msec)
      {
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2328,2339 ****
       a pointer to the next un-read compilation unit.  Check the
       previously read units before reading more.  */
    struct dwarf2_debug *stash;
- 
    /* What address are we looking for?  */
    bfd_vma addr;
- 
    struct comp_unit* each;
- 
    bfd_vma found = FALSE;
  
    stash = *pinfo;
--- 2327,2335 ----
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2373,2407 ****
  
    if (! *pinfo)
      {
        bfd_size_type total_size;
        asection *msec;
  
        *pinfo = stash;
  
        msec = find_debug_info (abfd, NULL);
!       if (! msec)
! 	/* No dwarf2 info.  Note that at this point the stash
! 	   has been allocated, but contains zeros, this lets
! 	   future calls to this function fail quicker.  */
! 	goto done;
  
        /* There can be more than one DWARF2 info section in a BFD these days.
  	 Read them all in and produce one large stash.  We do this in two
  	 passes - in the first pass we just accumulate the section sizes.
  	 In the second pass we read in the section's contents.  The allows
  	 us to avoid reallocing the data as we add sections to the stash.  */
!       for (total_size = 0; msec; msec = find_debug_info (abfd, msec))
  	total_size += msec->size;
  
!       stash->info_ptr = bfd_alloc (abfd, total_size);
        if (stash->info_ptr == NULL)
  	goto done;
  
        stash->info_ptr_end = stash->info_ptr;
  
!       for (msec = find_debug_info (abfd, NULL);
  	   msec;
! 	   msec = find_debug_info (abfd, msec))
  	{
  	  bfd_size_type size;
  	  bfd_size_type start;
--- 2369,2423 ----
  
    if (! *pinfo)
      {
+       bfd *debug_bfd;
        bfd_size_type total_size;
        asection *msec;
  
        *pinfo = stash;
  
        msec = find_debug_info (abfd, NULL);
!       if (msec == NULL)
! 	{
! 	  char * debug_filename = bfd_follow_gnu_debuglink (abfd, NULL);
! 
! 	  if (debug_filename == NULL)
! 	    /* No dwarf2 info, and no gnu_debuglink to follow.
! 	       Note that at this point the stash has been allocated, but
! 	       contains zeros.  This lets future calls to this function
! 	       fail more quickly.  */
! 	    goto done;
! 
! 	  if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
! 	      || ! bfd_check_format (debug_bfd, bfd_object)
! 	      || (msec = find_debug_info (debug_bfd, NULL)) == NULL)
! 	    {
! 	      if (debug_bfd)
! 		bfd_close (debug_bfd);
! 	      /* FIXME: Should we report our failure to follow the debuglink ?  */
! 	      free (debug_filename);
! 	      goto done;
! 	    }
! 	}
!       else
! 	debug_bfd = abfd;
  
        /* There can be more than one DWARF2 info section in a BFD these days.
  	 Read them all in and produce one large stash.  We do this in two
  	 passes - in the first pass we just accumulate the section sizes.
  	 In the second pass we read in the section's contents.  The allows
  	 us to avoid reallocing the data as we add sections to the stash.  */
!       for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec))
  	total_size += msec->size;
  
!       stash->info_ptr = bfd_alloc (debug_bfd, total_size);
        if (stash->info_ptr == NULL)
  	goto done;
  
        stash->info_ptr_end = stash->info_ptr;
  
!       for (msec = find_debug_info (debug_bfd, NULL);
  	   msec;
! 	   msec = find_debug_info (debug_bfd, msec))
  	{
  	  bfd_size_type size;
  	  bfd_size_type start;
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2413,2419 ****
  	  start = stash->info_ptr_end - stash->info_ptr;
  
  	  if ((bfd_simple_get_relocated_section_contents
! 	       (abfd, msec, stash->info_ptr + start, symbols)) == NULL)
  	    continue;
  
  	  stash->info_ptr_end = stash->info_ptr + start + size;
--- 2429,2435 ----
  	  start = stash->info_ptr_end - stash->info_ptr;
  
  	  if ((bfd_simple_get_relocated_section_contents
! 	       (debug_bfd, msec, stash->info_ptr + start, symbols)) == NULL)
  	    continue;
  
  	  stash->info_ptr_end = stash->info_ptr + start + size;
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2421,2429 ****
  
        BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
  
!       stash->sec = find_debug_info (abfd, NULL);
        stash->sec_info_ptr = stash->info_ptr;
        stash->syms = symbols;
      }
  
    /* A null info_ptr indicates that there is no dwarf2 info
--- 2437,2446 ----
  
        BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
  
!       stash->sec = find_debug_info (debug_bfd, NULL);
        stash->sec_info_ptr = stash->info_ptr;
        stash->syms = symbols;
+       stash->bfd = debug_bfd;
      }
  
    /* A null info_ptr indicates that there is no dwarf2 info
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2451,2463 ****
        unsigned int offset_size = addr_size;
        bfd_byte *info_ptr_unit = stash->info_ptr;
  
!       length = read_4_bytes (abfd, stash->info_ptr);
        /* A 0xffffff length is the DWARF3 way of indicating we use
  	 64-bit offsets, instead of 32-bit offsets.  */
        if (length == 0xffffffff)
  	{
  	  offset_size = 8;
! 	  length = read_8_bytes (abfd, stash->info_ptr + 4);
  	  stash->info_ptr += 12;
  	}
        /* A zero length is the IRIX way of indicating 64-bit offsets,
--- 2468,2480 ----
        unsigned int offset_size = addr_size;
        bfd_byte *info_ptr_unit = stash->info_ptr;
  
!       length = read_4_bytes (stash->bfd, stash->info_ptr);
        /* A 0xffffff length is the DWARF3 way of indicating we use
  	 64-bit offsets, instead of 32-bit offsets.  */
        if (length == 0xffffffff)
  	{
  	  offset_size = 8;
! 	  length = read_8_bytes (stash->bfd, stash->info_ptr + 4);
  	  stash->info_ptr += 12;
  	}
        /* A zero length is the IRIX way of indicating 64-bit offsets,
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2466,2472 ****
        else if (length == 0)
  	{
  	  offset_size = 8;
! 	  length = read_4_bytes (abfd, stash->info_ptr + 4);
  	  stash->info_ptr += 8;
  	}
        /* In the absence of the hints above, we assume 32-bit DWARF2
--- 2483,2489 ----
        else if (length == 0)
  	{
  	  offset_size = 8;
! 	  length = read_4_bytes (stash->bfd, stash->info_ptr + 4);
  	  stash->info_ptr += 8;
  	}
        /* In the absence of the hints above, we assume 32-bit DWARF2
*************** _bfd_dwarf2_find_nearest_line (bfd *abfd
*** 2488,2501 ****
  
        if (length > 0)
  	{
! 	  each = parse_comp_unit (abfd, stash, length, info_ptr_unit,
  				  offset_size);
  	  stash->info_ptr += length;
  
  	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
  	      == stash->sec->size)
  	    {
! 	      stash->sec = find_debug_info (abfd, stash->sec);
  	      stash->sec_info_ptr = stash->info_ptr;
  	    }
  
--- 2505,2518 ----
  
        if (length > 0)
  	{
! 	  each = parse_comp_unit (stash, length, info_ptr_unit,
  				  offset_size);
  	  stash->info_ptr += length;
  
  	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
  	      == stash->sec->size)
  	    {
! 	      stash->sec = find_debug_info (stash->bfd, stash->sec);
  	      stash->sec_info_ptr = stash->info_ptr;
  	    }
  
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2552,2565 ****
       a pointer to the next un-read compilation unit.  Check the
       previously read units before reading more.  */
    struct dwarf2_debug *stash;
- 
    /* What address are we looking for?  */
    bfd_vma addr;
- 
    struct comp_unit* each;
- 
    asection *section;
- 
    bfd_boolean found = FALSE;
  
    section = bfd_get_section (symbol);
--- 2569,2578 ----
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2595,2629 ****
  
    if (! *pinfo)
      {
        bfd_size_type total_size;
        asection *msec;
  
        *pinfo = stash;
  
        msec = find_debug_info (abfd, NULL);
!       if (! msec)
! 	/* No dwarf2 info.  Note that at this point the stash
! 	   has been allocated, but contains zeros, this lets
! 	   future calls to this function fail quicker.  */
! 	goto done;
  
        /* There can be more than one DWARF2 info section in a BFD these days.
  	 Read them all in and produce one large stash.  We do this in two
  	 passes - in the first pass we just accumulate the section sizes.
  	 In the second pass we read in the section's contents.  The allows
  	 us to avoid reallocing the data as we add sections to the stash.  */
!       for (total_size = 0; msec; msec = find_debug_info (abfd, msec))
  	total_size += msec->size;
  
!       stash->info_ptr = bfd_alloc (abfd, total_size);
        if (stash->info_ptr == NULL)
  	goto done;
  
        stash->info_ptr_end = stash->info_ptr;
  
!       for (msec = find_debug_info (abfd, NULL);
  	   msec;
! 	   msec = find_debug_info (abfd, msec))
  	{
  	  bfd_size_type size;
  	  bfd_size_type start;
--- 2608,2662 ----
  
    if (! *pinfo)
      {
+       bfd *debug_bfd;
        bfd_size_type total_size;
        asection *msec;
  
        *pinfo = stash;
  
        msec = find_debug_info (abfd, NULL);
!       if (msec == NULL)
! 	{
! 	  char * debug_filename = bfd_follow_gnu_debuglink (abfd, NULL);
! 
! 	  if (debug_filename == NULL)
! 	    /* No dwarf2 info, and no gnu_debuglink to follow.
! 	       Note that at this point the stash has been allocated, but
! 	       contains zeros.  This lets future calls to this function
! 	       fail more quickly.  */
! 	    goto done;
! 
! 	  if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
! 	      || ! bfd_check_format (debug_bfd, bfd_object)
! 	      || (msec = find_debug_info (debug_bfd, NULL)) == NULL)
! 	    {
! 	      if (debug_bfd)
! 		bfd_close (debug_bfd);
! 	      /* FIXME: Should we report our failure to follow the debuglink ?  */
! 	      free (debug_filename);
! 	      goto done;
! 	    }
! 	}
!       else
! 	debug_bfd = abfd;
  
        /* There can be more than one DWARF2 info section in a BFD these days.
  	 Read them all in and produce one large stash.  We do this in two
  	 passes - in the first pass we just accumulate the section sizes.
  	 In the second pass we read in the section's contents.  The allows
  	 us to avoid reallocing the data as we add sections to the stash.  */
!       for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec))
  	total_size += msec->size;
  
!       stash->info_ptr = bfd_alloc (debug_bfd, total_size);
        if (stash->info_ptr == NULL)
  	goto done;
  
        stash->info_ptr_end = stash->info_ptr;
  
!       for (msec = find_debug_info (debug_bfd, NULL);
  	   msec;
! 	   msec = find_debug_info (debug_bfd, msec))
  	{
  	  bfd_size_type size;
  	  bfd_size_type start;
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2635,2641 ****
  	  start = stash->info_ptr_end - stash->info_ptr;
  
  	  if ((bfd_simple_get_relocated_section_contents
! 	       (abfd, msec, stash->info_ptr + start, symbols)) == NULL)
  	    continue;
  
  	  stash->info_ptr_end = stash->info_ptr + start + size;
--- 2668,2674 ----
  	  start = stash->info_ptr_end - stash->info_ptr;
  
  	  if ((bfd_simple_get_relocated_section_contents
! 	       (debug_bfd, msec, stash->info_ptr + start, symbols)) == NULL)
  	    continue;
  
  	  stash->info_ptr_end = stash->info_ptr + start + size;
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2643,2651 ****
  
        BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
  
!       stash->sec = find_debug_info (abfd, NULL);
        stash->sec_info_ptr = stash->info_ptr;
        stash->syms = symbols;
      }
  
    /* A null info_ptr indicates that there is no dwarf2 info
--- 2676,2685 ----
  
        BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
  
!       stash->sec = find_debug_info (debug_bfd, NULL);
        stash->sec_info_ptr = stash->info_ptr;
        stash->syms = symbols;
+       stash->bfd = debug_bfd;
      }
  
    /* A null info_ptr indicates that there is no dwarf2 info
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2680,2692 ****
        unsigned int offset_size = addr_size;
        bfd_byte *info_ptr_unit = stash->info_ptr;
  
!       length = read_4_bytes (abfd, stash->info_ptr);
        /* A 0xffffff length is the DWARF3 way of indicating we use
  	 64-bit offsets, instead of 32-bit offsets.  */
        if (length == 0xffffffff)
  	{
  	  offset_size = 8;
! 	  length = read_8_bytes (abfd, stash->info_ptr + 4);
  	  stash->info_ptr += 12;
  	}
        /* A zero length is the IRIX way of indicating 64-bit offsets,
--- 2714,2726 ----
        unsigned int offset_size = addr_size;
        bfd_byte *info_ptr_unit = stash->info_ptr;
  
!       length = read_4_bytes (stash->bfd, stash->info_ptr);
        /* A 0xffffff length is the DWARF3 way of indicating we use
  	 64-bit offsets, instead of 32-bit offsets.  */
        if (length == 0xffffffff)
  	{
  	  offset_size = 8;
! 	  length = read_8_bytes (stash->bfd, stash->info_ptr + 4);
  	  stash->info_ptr += 12;
  	}
        /* A zero length is the IRIX way of indicating 64-bit offsets,
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2695,2701 ****
        else if (length == 0)
  	{
  	  offset_size = 8;
! 	  length = read_4_bytes (abfd, stash->info_ptr + 4);
  	  stash->info_ptr += 8;
  	}
        /* In the absence of the hints above, we assume 32-bit DWARF2
--- 2729,2735 ----
        else if (length == 0)
  	{
  	  offset_size = 8;
! 	  length = read_4_bytes (stash->bfd, stash->info_ptr + 4);
  	  stash->info_ptr += 8;
  	}
        /* In the absence of the hints above, we assume 32-bit DWARF2
*************** _bfd_dwarf2_find_line (bfd *abfd,
*** 2717,2730 ****
  
        if (length > 0)
  	{
! 	  each = parse_comp_unit (abfd, stash, length, info_ptr_unit,
  				  offset_size);
  	  stash->info_ptr += length;
  
  	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
  	      == stash->sec->size)
  	    {
! 	      stash->sec = find_debug_info (abfd, stash->sec);
  	      stash->sec_info_ptr = stash->info_ptr;
  	    }
  
--- 2751,2764 ----
  
        if (length > 0)
  	{
! 	  each = parse_comp_unit (stash, length, info_ptr_unit,
  				  offset_size);
  	  stash->info_ptr += length;
  
  	  if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
  	      == stash->sec->size)
  	    {
! 	      stash->sec = find_debug_info (stash->bfd, stash->sec);
  	      stash->sec_info_ptr = stash->info_ptr;
  	    }
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]