View | Details | Raw Unified | Return to bug 20876 | Differences between
and this patch

Collapse All | Expand All

(-)a/bfd/bfd-in2.h (+2 lines)
Lines 1121-1126 struct bfd_section *bfd_create_gnu_debuglink_section Link Here
1121
bfd_boolean bfd_fill_in_gnu_debuglink_section
1121
bfd_boolean bfd_fill_in_gnu_debuglink_section
1122
   (bfd *abfd, struct bfd_section *sect, const char *filename);
1122
   (bfd *abfd, struct bfd_section *sect, const char *filename);
1123
1123
1124
char *bfd_follow_build_id_debuglink (bfd *abfd, const char *dir);
1125
1124
/* Extracted from libbfd.c.  */
1126
/* Extracted from libbfd.c.  */
1125
1127
1126
/* Byte swapping macros for user section data.  */
1128
/* Byte swapping macros for user section data.  */
(-)a/bfd/dwarf2.c (-1 / +5 lines)
Lines 3921-3927 _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd, Link Here
3921
  msec = find_debug_info (debug_bfd, debug_sections, NULL);
3921
  msec = find_debug_info (debug_bfd, debug_sections, NULL);
3922
  if (msec == NULL && abfd == debug_bfd)
3922
  if (msec == NULL && abfd == debug_bfd)
3923
    {
3923
    {
3924
      char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
3924
      char * debug_filename;
3925
3926
      debug_filename = bfd_follow_build_id_debuglink (abfd, DEBUGDIR);
3927
      if (debug_filename == NULL)
3928
	debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
3925
3929
3926
      if (debug_filename == NULL)
3930
      if (debug_filename == NULL)
3927
	/* No dwarf2 info, and no gnu_debuglink to follow.
3931
	/* No dwarf2 info, and no gnu_debuglink to follow.
(-)a/bfd/opncls.c (-16 / +174 lines)
Lines 25-30 Link Here
25
#include "objalloc.h"
25
#include "objalloc.h"
26
#include "libbfd.h"
26
#include "libbfd.h"
27
#include "libiberty.h"
27
#include "libiberty.h"
28
#include "elf-bfd.h"
28
29
29
#ifndef S_IXUSR
30
#ifndef S_IXUSR
30
#define S_IXUSR 0100	/* Execute by owner.  */
31
#define S_IXUSR 0100	/* Execute by owner.  */
Lines 1336-1352 INTERNAL_FUNCTION Link Here
1336
	find_separate_debug_file
1337
	find_separate_debug_file
1337
1338
1338
SYNOPSIS
1339
SYNOPSIS
1339
	char *find_separate_debug_file (bfd *abfd);
1340
	char *find_separate_debug_file
1341
	  (bfd *abfd, const char *dir, get_func_type get, check_func_type check);
1340
1342
1341
DESCRIPTION
1343
DESCRIPTION
1342
	Searches @var{abfd} for a section called @var{section_name} which
1344
	Searches for a debug information file corresponding to @var{abfd},
1343
	is expected to contain a reference to a file containing separate
1345
	using a link method abstracted into the @var{get} function.
1344
	debugging information.  The function scans various locations in
1346
	This function scans various locations in the filesystem, including
1345
	the filesystem, including the file tree rooted at
1347
	the file tree rooted at	@var{dir}, and returns the filename of the
1346
	@var{debug_file_directory}, and returns the first matching
1348
	first file to successfully match.  Matching files must have a TRUE
1347
	filename that it finds.  If @var{check_crc} is TRUE then the
1349
	result returned by the @var{check} function.
1348
	contents of the file must also match the CRC value contained in
1350
	Returns NULL if no valid file could be found.
1349
	@var{section_name}.  Returns NULL if no valid file could be found.
1350
*/
1351
*/
1351
1352
1352
typedef char *      (* get_func_type) (bfd *, unsigned long *);
1353
typedef char *      (* get_func_type) (bfd *, unsigned long *);
Lines 1475-1483 DESCRIPTION Link Here
1475
	locations, including the directory tree rooted at @var{dir}, and if
1476
	locations, including the directory tree rooted at @var{dir}, and if
1476
	found returns the full filename.
1477
	found returns the full filename.
1477
1478
1478
	If @var{dir} is NULL, it will search a default path configured into
1479
	If @var{dir} is NULL, the search will take place starting at
1479
	libbfd at build time.  [XXX this feature is not currently
1480
	the current directory.
1480
	implemented].
1481
1481
1482
RETURNS
1482
RETURNS
1483
	<<NULL>> on any errors or failure to locate the .debug file,
1483
	<<NULL>> on any errors or failure to locate the .debug file,
Lines 1522-1535 DESCRIPTION Link Here
1522
1522
1523
	Takes a BFD and searches it for a .gnu_debugaltlink section.  If this
1523
	Takes a BFD and searches it for a .gnu_debugaltlink section.  If this
1524
	section is found, it examines the section for the name of a file
1524
	section is found, it examines the section for the name of a file
1525
	containing auxiliary debugging information.  It	then searches the
1525
	containing auxiliary debugging information.  It then searches the
1526
	filesystem for this file in a set of standard locations, including
1526
	filesystem for this file in a set of standard locations, including
1527
	the directory tree rooted at @var{dir}, and if found returns the
1527
	the directory tree rooted at @var{dir}, and if found returns the
1528
	full filename.
1528
	full filename.
1529
1529
1530
	If @var{dir} is NULL, it will search a default path configured into
1530
	If @var{dir} is NULL, the search will take place starting at
1531
	libbfd at build time.  [FIXME: This feature is not currently
1531
	the current directory.
1532
	implemented].
1533
1532
1534
RETURNS
1533
RETURNS
1535
	<<NULL>> on any errors or failure to locate the debug file,
1534
	<<NULL>> on any errors or failure to locate the debug file,
Lines 1695-1697 bfd_fill_in_gnu_debuglink_section (bfd *abfd, Link Here
1695
1694
1696
  return TRUE;
1695
  return TRUE;
1697
}
1696
}
1697
1698
1699
static char *
1700
get_build_id_name (bfd *abfd, unsigned long *build_id_out)
1701
{
1702
  struct bfd_build_id *build_id;
1703
  char *name;
1704
  char *n;
1705
  bfd_size_type s;
1706
  bfd_byte *d;
1707
1708
  if (abfd == NULL || abfd->filename == NULL || build_id_out == NULL)
1709
    {
1710
      bfd_set_error (bfd_error_invalid_operation);
1711
      return NULL;
1712
    }
1713
1714
  if (abfd->build_id && abfd->build_id->size > 0)
1715
    {
1716
      /* Save some time by using the already computed build-id.
1717
	 FIXME: Is this safe/reliable ?  */
1718
      build_id = (struct bfd_build_id *) abfd->build_id;
1719
    }
1720
  else
1721
    {
1722
      Elf_Internal_Note inote;
1723
      Elf_External_Note *enote;
1724
      bfd_byte *contents;
1725
      asection *sect;
1726
1727
      sect = bfd_get_section_by_name (abfd, ".note.gnu.build-id");
1728
      if (sect == NULL)
1729
	{
1730
	  bfd_set_error (bfd_error_no_debug_section);
1731
	  return NULL;
1732
	}
1733
1734
      /* FIXME: Can we get smaller build-id notes ?  */
1735
      if (bfd_get_section_size (sect) < 0x24)
1736
	{
1737
	  bfd_set_error (bfd_error_invalid_operation);
1738
	  return NULL;
1739
	}
1740
1741
      if (!bfd_malloc_and_get_section (abfd, sect, & contents))
1742
	{
1743
	  if (contents != NULL)
1744
	    free (contents);
1745
	  bfd_set_error (bfd_error_invalid_operation);
1746
	  return NULL;
1747
	}
1748
1749
      enote = (Elf_External_Note *) contents;
1750
      inote.type = H_GET_32 (abfd, enote->type);
1751
      inote.namesz = H_GET_32 (abfd, enote->namesz);
1752
      inote.namedata = enote->name;
1753
      inote.descsz = H_GET_32 (abfd, enote->descsz);
1754
      inote.descdata = inote.namedata + BFD_ALIGN (inote.namesz, 4);
1755
      /* FIXME: Should we check for extra notes in this section ?  */
1756
	  
1757
      if (inote.descsz == 0
1758
	  || inote.type != NT_GNU_BUILD_ID
1759
	  || inote.namesz != 4 /* sizeof "GNU"  */
1760
	  || strcmp (inote.namedata, "GNU") != 0)
1761
	{
1762
	  free (contents);
1763
	  bfd_set_error (bfd_error_invalid_operation);
1764
	  return NULL;
1765
	}
1766
1767
      build_id = bfd_alloc (abfd, sizeof (struct bfd_build_id) + inote.descsz);
1768
      if (build_id == NULL)
1769
	{
1770
	  free (contents);
1771
	  bfd_set_error (bfd_error_no_memory);
1772
	  return NULL;
1773
	}
1774
1775
      build_id->size = inote.descsz;
1776
      memcpy (build_id->data, inote.descdata, inote.descsz);
1777
      abfd->build_id = build_id;
1778
      free (contents);
1779
    }
1780
1781
  /* Compute the debug pathname corresponding to the build-id.  */
1782
  name = bfd_malloc (strlen (".build-id/") + build_id->size * 2 + 2 + strlen (".debug"));
1783
  if (name == NULL)
1784
    {
1785
      bfd_set_error (bfd_error_no_memory);
1786
      return NULL;
1787
    }
1788
  n = name;
1789
  d = build_id->data;
1790
  s = build_id->size;
1791
1792
  n += sprintf (n, ".build-id/");
1793
  n += sprintf (n, "%02x", (unsigned) *d++); s--;
1794
  n += sprintf (n, "/");
1795
  while (s--)
1796
    n += sprintf (n, "%02x", (unsigned) *d++);
1797
  n += sprintf (n, ".debug");
1798
1799
  * build_id_out = (unsigned long) build_id;
1800
  return name;
1801
}
1802
1803
static bfd_boolean
1804
check_build_id_match (const char *name, const unsigned long builid ATTRIBUTE_UNUSED)
1805
{
1806
  FILE *f;
1807
1808
  BFD_ASSERT (name);
1809
1810
  f = real_fopen (name, FOPEN_RB);
1811
  if (f == NULL)
1812
    return FALSE;
1813
1814
  /* FIXME: Add code to check buildid.  */
1815
1816
  fclose (f);
1817
1818
  return TRUE;
1819
}
1820
1821
/*
1822
FUNCTION
1823
	bfd_follow_build_id_debuglink
1824
1825
SYNOPSIS
1826
	char *bfd_follow_build_id_debuglink (bfd *abfd, const char *dir);
1827
1828
DESCRIPTION
1829
1830
	Takes @var{abfd} and searches it for a .note.gnu.build-id section.
1831
	If this section is found, it extracts the value of the NT_GNU_BUILD_ID
1832
	note, which should be a hexadecimal value @var{NNNN+NN} (for
1833
	32+ hex digits).  It then searches the filesystem for a file named
1834
	@var{.build-id/NN/NN+NN.debug} in a set of standard locations,
1835
	including the directory tree rooted at @var{dir}.  The filename
1836
	of the first matching file to be found is returned.  A matching
1837
	file must contain a .note.gnu.build-id section with the same
1838
	@var{NNNN+NN} note as @var{abfd}.
1839
1840
	If @var{dir} is NULL, the search will take place starting at
1841
	the current directory.
1842
1843
RETURNS
1844
	<<NULL>> on any errors or failure to locate the debug file,
1845
	otherwise a pointer to a heap-allocated string containing the
1846
	filename.  The caller is responsible for freeing this string.
1847
*/
1848
1849
char *
1850
bfd_follow_build_id_debuglink (bfd *abfd, const char *dir ATTRIBUTE_UNUSED)
1851
{
1852
  return find_separate_debug_file (abfd, dir,
1853
				   get_build_id_name,
1854
				   check_build_id_match);
1855
}
(-)a/binutils/testsuite/binutils-all/compress.exp (+75 lines)
Lines 762-767 proc test_gnu_debuglink {} { Link Here
762
    }
762
    }
763
}
763
}
764
764
765
# Strictly speaking this test does not belong here as it does not
766
# test compressed debug sections.  But since the test is so similar
767
# to proc test_gnu_debuglink above, this location was convenient.
768
proc test_build_id_debuglink {} {
769
    global srcdir
770
    global subdir
771
    global env
772
    global CC_FOR_TARGET
773
    global STRIP
774
    global OBJCOPY
775
    global OBJDUMP
776
    global CFLAGS_FOR_TARGET
777
    
778
    set test "build-id-debuglink"
779
    if {![info exists CC_FOR_TARGET]} {
780
	set CC_FOR_TARGET $env(CC)
781
    }
782
    if { $CC_FOR_TARGET == "" } {
783
	unsupported $test
784
	return
785
    }
786
787
    # Use a fixed build-id.
788
    set CFLAGS_FOR_TARGET "-g -Wl,--build-id=0x12345678abcdef01"
789
790
    if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog exectuable debug] != "" } {
791
	fail "$test (build)"
792
	return
793
    }
794
795
    # FIXME: Do we need to restore CFLAGS_FOR_TARGET to its old value ?
796
797
    if { [binutils_run $STRIP "--strip-debug --remove-section=.comment tmpdir/testprog -o tmpdir/testprog.strip"] != "" } {
798
	fail "$test (strip debug info)"
799
	return
800
    }
801
802
    if { [binutils_run $OBJCOPY "--only-keep-debug tmpdir/testprog tmpdir/testprog.debug"] != "" } {
803
	fail "$test (create separate debug info file)"
804
	return
805
    }
806
807
    set got [remote_exec host "mkdir -p tmpdir/.build-id/12" ]
808
    if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
809
	fail "$test (make debug directory)"
810
	return
811
    }
812
813
    set got [remote_exec host "cp tmpdir/testprog.debug tmpdir/.build-id/12/345678abcdef01.debug"]
814
    if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
815
	fail "$test (copy debug info into debug directory)"
816
	return
817
    }
818
    
819
    set got [remote_exec host "$OBJDUMP -Sl tmpdir/testprog.strip" "" "/dev/null" "tmpdir/testprog.strip.dump"]
820
    if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
821
	fail "$test (post strip dump)"
822
	return
823
    }
824
825
    set src2 tmpdir/testprog.strip.dump
826
    verbose " grep -e testprog.c ${src2}"
827
    set status [remote_exec build grep "-e testprog.c ${src2}"]
828
    set exec_output [lindex $status 1]
829
    set exec_output [prune_warnings $exec_output]
830
    if [string match "" $exec_output] then {
831
	send_log "$exec_output\n"
832
	verbose "$exec_output" 1
833
	fail "$test (grepping for source file name in disassembly output)"
834
    } else {
835
	pass "$test"
836
    }
837
}
838
765
if {[isnative] && [is_elf_format]} then {
839
if {[isnative] && [is_elf_format]} then {
766
    test_gnu_debuglink
840
    test_gnu_debuglink
841
    test_build_id_debuglink
767
}
842
}

Return to bug 20876