This is the mail archive of the binutils@sources.redhat.com 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: separated debuginfo patch


Philippe Elie wrote:
Nick Clifton wrote:

Hi Philippe,



sorry, the missing patch ...

regards,
Phil
Index: bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.226
diff -c -3 -p -r1.226 bfd-in2.h
*** bfd-in2.h	1 Jul 2003 14:44:59 -0000	1.226
--- bfd-in2.h	4 Jul 2003 21:18:00 -0000
*************** bfd_boolean bfd_make_readable (bfd *abfd
*** 853,865 ****
  unsigned long bfd_calc_gnu_debuglink_crc32
     (unsigned long crc, const unsigned char *buf, bfd_size_type len);
  
  char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
  
  struct sec *bfd_create_gnu_debuglink_section
     (bfd *abfd, const char *filename);
  
  bfd_boolean bfd_fill_in_gnu_debuglink_section
!    (bfd *abfd, struct sec *sect, const char *filename);
  
  /* Extracted from libbfd.c.  */
  
--- 853,874 ----
  unsigned long bfd_calc_gnu_debuglink_crc32
     (unsigned long crc, const unsigned char *buf, bfd_size_type len);
  
+ char *bfd_get_debug_link_info 
+    (bfd *abfd, unsigned long *crc32_out, unsigned long *timestamp);
+ 
  char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir);
  
  struct sec *bfd_create_gnu_debuglink_section
     (bfd *abfd, const char *filename);
  
  bfd_boolean bfd_fill_in_gnu_debuglink_section
!    (bfd *abfd, struct sec *sect, const char *filename,
!     unsigned long timestamp);
! 
! struct sec *bfd_create_gnu_debuglink_timestamp_section (bfd *abfd);
! 
! bfd_boolean bfd_fill_in_gnu_debuglink_timestamp_section
!    (bfd *abfd, struct sec *sect, unsigned long timestamp);
  
  /* Extracted from libbfd.c.  */
  
Index: opncls.c
===================================================================
RCS file: /cvs/src/src/bfd/opncls.c,v
retrieving revision 1.18
diff -c -3 -p -r1.18 opncls.c
*** opncls.c	29 Jun 2003 10:06:39 -0000	1.18
--- opncls.c	4 Jul 2003 21:18:02 -0000
*************** bfd_release (bfd *abfd, void *block)
*** 692,697 ****
--- 692,698 ----
  */
  
  #define GNU_DEBUGLINK	".gnu_debuglink"
+ #define GNU_DEBUGLINK_TIMESTAMP ".gnu_debuglink_timestamp"
  /*
  FUNCTION
  	bfd_calc_gnu_debuglink_crc32
*************** bfd_calc_gnu_debuglink_crc32 (unsigned l
*** 779,798 ****
  
  
  /*
! INTERNAL_FUNCTION
! 	get_debug_link_info
  
  SYNOPSIS
! 	char *get_debug_link_info (bfd *abfd, unsigned long *crc32_out);
  
  DESCRIPTION
! 	fetch the filename and CRC32 value for any separate debuginfo
! 	associated with @var{abfd}. Return NULL if no such info found,
! 	otherwise return filename and update @var{crc32_out}.
  */
  
! static char *
! get_debug_link_info (bfd *abfd, unsigned long *crc32_out)
  {
    asection * sect;
    bfd_size_type debuglink_size;
--- 780,803 ----
  
  
  /*
! FUNCTION
! 	bfd_get_debug_link_info
  
  SYNOPSIS
! 	char *bfd_get_debug_link_info 
! 	  (bfd *abfd, unsigned long *crc32_out, unsigned long *timestamp);
  
  DESCRIPTION
! 	fetch the filename, CRC32 value and 32 bits timestamp for any
! 	separate debuginfo associated with @var{abfd}. Return NULL if no such
! 	info found, otherwise return filename, update @var{crc32_out} and
! 	@var{timestamp}. If timestamp is not available return 0 in
! 	@var{timestamp}
  */
  
! char *
! bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out, 
! 			 unsigned long *timestamp)
  {
    asection * sect;
    bfd_size_type debuglink_size;
*************** get_debug_link_info (bfd *abfd, unsigned
*** 803,808 ****
--- 808,814 ----
  
    BFD_ASSERT (abfd);
    BFD_ASSERT (crc32_out);
+   BFD_ASSERT (timestamp);
  
    sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK);
  
*************** get_debug_link_info (bfd *abfd, unsigned
*** 828,852 ****
  
    crc32 = bfd_get_32 (abfd, contents + crc_offset);
  
    *crc32_out = crc32;
    return contents;
  }
  
  /*
  INTERNAL_FUNCTION
  	separate_debug_file_exists
  
  SYNOPSIS
  	bfd_boolean separate_debug_file_exists
! 	  (char *name, unsigned long crc32);
  
  DESCRIPTION
  	Checks to see if @var{name} is a file and if its contents
! 	match @var{crc32}.
  */
  
  static bfd_boolean
! separate_debug_file_exists (const char *name, const unsigned long crc)
  {
    static char buffer [8 * 1024];
    unsigned long file_crc = 0;
--- 834,920 ----
  
    crc32 = bfd_get_32 (abfd, contents + crc_offset);
  
+   /* .gnu_debuglink format changed by adding a timestamp value after the
+    * the crc, we must support the old format */
+   *timestamp = 0;
+   if (debuglink_size - (crc_offset + 4) >= 4)
+     *timestamp = bfd_get_32 (abfd, contents + crc_offset + 4);
+ 
    *crc32_out = crc32;
    return contents;
  }
  
  /*
  INTERNAL_FUNCTION
+ 	bfd_get_debug_timestamp_info
+ 
+ SYNOPSIS
+ 	bfd_boolean bfd_get_debug_timestamp_info
+ 	  (bfd *abfd, unsigned long *timestamp);
+ 
+ DESCRIPTION
+ 	fetch the timestamp for any separate debuginfo associated with
+ 	@var{abfd}.
+ 
+ RETURNS
+ 	<<TRUE>> is returned if all is ok, otherwise <<FALSE>>.
+ */
+ 
+ static bfd_boolean
+ bfd_get_debug_timestamp_info (bfd *abfd,  unsigned long *timestamp)
+ {
+   asection * sect;
+   bfd_size_type timestamp_size;
+   bfd_boolean ret;
+   char * contents;
+ 
+   BFD_ASSERT (abfd);
+   BFD_ASSERT (timestamp);
+ 
+   sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK_TIMESTAMP);
+ 
+   if (sect == NULL)
+     return FALSE;
+ 
+   timestamp_size = bfd_section_size (abfd, sect);  
+ 
+   if (timestamp_size != 4)
+     return FALSE;
+ 
+   contents = malloc (timestamp_size);
+   if (contents == NULL)
+     return FALSE;
+ 
+   ret = bfd_get_section_contents (abfd, sect, contents, 0, timestamp_size);
+   if (! ret)
+     {
+       free (contents);
+       return FALSE;
+     }
+ 
+   *timestamp = bfd_get_32 (abfd, contents);
+ 
+   free (contents);
+ 
+   return TRUE;
+ }
+ 
+ /*
+ INTERNAL_FUNCTION
  	separate_debug_file_exists
  
  SYNOPSIS
  	bfd_boolean separate_debug_file_exists
! 	  (char *name, unsigned long crc32, unsigned long timestamp);
  
  DESCRIPTION
  	Checks to see if @var{name} is a file and if its contents
! 	match @var{timestamp} or if the @var{crc32} match.
  */
  
  static bfd_boolean
! separate_debug_file_exists (const char *name, const unsigned long crc,
! 			    unsigned long timestamp)
  {
    static char buffer [8 * 1024];
    unsigned long file_crc = 0;
*************** separate_debug_file_exists (const char *
*** 855,860 ****
--- 923,954 ----
  
    BFD_ASSERT (name);
  
+   printf("try %s %ld\n", name, timestamp);
+ 
+   if (timestamp)
+     {
+       bfd *abfd = bfd_openr(name, NULL);
+ 
+       if (abfd)
+ 	{
+ 	  char ** matching;
+ 
+ 	  if (bfd_check_format_matches(abfd, bfd_object, &matching))
+ 	    {
+ 	      unsigned long temp_timestamp;
+ 
+ 	      if (bfd_get_debug_timestamp_info (abfd, &temp_timestamp))
+ 		{
+ 		  bfd_close(abfd);
+ 		  return temp_timestamp == timestamp;
+ 		}
+ 	      bfd_close (abfd);
+ 	    }
+ 	}
+     }
+ 
+   printf("doing full crc\n");
+ 
    fd = open (name, O_RDONLY);
    if (fd < 0)
      return FALSE;
*************** find_separate_debug_file (bfd *abfd, con
*** 891,896 ****
--- 985,991 ----
    char *dir;
    char *debugfile;
    unsigned long crc32;
+   unsigned long timestamp;
    int i;
  
    BFD_ASSERT (abfd);
*************** find_separate_debug_file (bfd *abfd, con
*** 901,907 ****
    if (! abfd->filename)
      return NULL;
  
!   basename = get_debug_link_info (abfd, & crc32);
    if (basename == NULL)
      return NULL;
  
--- 996,1002 ----
    if (! abfd->filename)
      return NULL;
  
!   basename = bfd_get_debug_link_info (abfd, &crc32, &timestamp);
    if (basename == NULL)
      return NULL;
  
*************** find_separate_debug_file (bfd *abfd, con
*** 943,949 ****
    strcpy (debugfile, dir);
    strcat (debugfile, basename);
  
!   if (separate_debug_file_exists (debugfile, crc32))
      {
        free (basename);
        free (dir);
--- 1038,1044 ----
    strcpy (debugfile, dir);
    strcat (debugfile, basename);
  
!   if (separate_debug_file_exists (debugfile, crc32, timestamp))
      {
        free (basename);
        free (dir);
*************** find_separate_debug_file (bfd *abfd, con
*** 955,961 ****
    strcat (debugfile, ".debug/");
    strcat (debugfile, basename);
  
!   if (separate_debug_file_exists (debugfile, crc32))
      {
        free (basename);
        free (dir);
--- 1050,1056 ----
    strcat (debugfile, ".debug/");
    strcat (debugfile, basename);
  
!   if (separate_debug_file_exists (debugfile, crc32, timestamp))
      {
        free (basename);
        free (dir);
*************** find_separate_debug_file (bfd *abfd, con
*** 972,978 ****
    strcat (debugfile, dir);
    strcat (debugfile, basename);
  
!   if (separate_debug_file_exists (debugfile, crc32))
      {
        free (basename);
        free (dir);
--- 1067,1073 ----
    strcat (debugfile, dir);
    strcat (debugfile, basename);
  
!   if (separate_debug_file_exists (debugfile, crc32, timestamp))
      {
        free (basename);
        free (dir);
*************** bfd_create_gnu_debuglink_section (bfd *a
*** 1073,1079 ****
    debuglink_size = strlen (filename) + 1;
    debuglink_size += 3;
    debuglink_size &= ~3;
!   debuglink_size += 4;
  
    if (! bfd_set_section_size (abfd, sect, debuglink_size))
      /* XXX Should we delete the section from the bfd ?  */
--- 1168,1174 ----
    debuglink_size = strlen (filename) + 1;
    debuglink_size += 3;
    debuglink_size &= ~3;
!   debuglink_size += 8;
  
    if (! bfd_set_section_size (abfd, sect, debuglink_size))
      /* XXX Should we delete the section from the bfd ?  */
*************** FUNCTION
*** 1089,1095 ****
  
  SYNOPSIS
  	bfd_boolean bfd_fill_in_gnu_debuglink_section
! 	  (bfd *abfd, struct sec *sect, const char *filename);
  
  DESCRIPTION
  
--- 1184,1191 ----
  
  SYNOPSIS
  	bfd_boolean bfd_fill_in_gnu_debuglink_section
! 	  (bfd *abfd, struct sec *sect, const char *filename,
! 	   unsigned long timestamp);
  
  DESCRIPTION
  
*************** RETURNS
*** 1106,1112 ****
  bfd_boolean
  bfd_fill_in_gnu_debuglink_section (bfd *abfd,
  				   struct sec *sect,
! 				   const char *filename)
  {
    bfd_size_type debuglink_size;
    unsigned long crc32;
--- 1202,1209 ----
  bfd_boolean
  bfd_fill_in_gnu_debuglink_section (bfd *abfd,
  				   struct sec *sect,
! 				   const char *filename,
! 				   unsigned long timestamp)
  {
    bfd_size_type debuglink_size;
    unsigned long crc32;
*************** bfd_fill_in_gnu_debuglink_section (bfd *
*** 1147,1153 ****
    debuglink_size = strlen (filename) + 1;
    debuglink_size += 3;
    debuglink_size &= ~3;
!   debuglink_size += 4;
  
    contents = malloc (debuglink_size);
    if (contents == NULL)
--- 1244,1250 ----
    debuglink_size = strlen (filename) + 1;
    debuglink_size += 3;
    debuglink_size &= ~3;
!   debuglink_size += 8;
  
    contents = malloc (debuglink_size);
    if (contents == NULL)
*************** bfd_fill_in_gnu_debuglink_section (bfd *
*** 1158,1168 ****
      }
  
    strcpy (contents, filename);
!   crc_offset = debuglink_size - 4;
  
    bfd_put_32 (abfd, crc32, contents + crc_offset);
  
    if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
      {
        /* XXX Should we delete the section from the bfd ?  */
        free (contents);
--- 1255,1373 ----
      }
  
    strcpy (contents, filename);
!   crc_offset = debuglink_size - 8;
  
    bfd_put_32 (abfd, crc32, contents + crc_offset);
+   bfd_put_32 (abfd, timestamp, contents + crc_offset + 4);
  
    if (! bfd_set_section_contents (abfd, sect, contents, 0, debuglink_size))
+     {
+       /* XXX Should we delete the section from the bfd ?  */
+       free (contents);
+       return FALSE;
+     }
+ 
+   return TRUE;
+ }
+ 
+ /*
+ FUNCTION
+ 	bfd_create_gnu_debuglink_timestamp_section
+ 
+ SYNOPSIS
+ 	struct sec *bfd_create_gnu_debuglink_timestamp_section (bfd *abfd);
+ 
+ DESCRIPTION
+ 
+ 	Takes a @var{BFD} and adds a .gnu_debuglink_time_stamp section to it.
+ 	The section is sized to be big enough to contain a 32 bits timestamp
+ 	value.
+ 
+ RETURNS
+ 	A pointer to the new section is returned if all is ok.  Otherwise <<NULL>> is
+ 	returned and bfd_error is set.  
+ */
+ 
+ asection *
+ bfd_create_gnu_debuglink_timestamp_section (bfd *abfd)
+ {
+   asection *sect;
+ 
+   if (abfd == NULL)
+     {
+       bfd_set_error (bfd_error_invalid_operation);
+       return NULL;
+     }
+ 
+   sect = bfd_get_section_by_name (abfd, GNU_DEBUGLINK_TIMESTAMP);
+   if (sect)
+     {
+       /* Section already exists.  */
+       bfd_set_error (bfd_error_invalid_operation);
+       return NULL;
+     }
+ 
+   sect = bfd_make_section (abfd, GNU_DEBUGLINK_TIMESTAMP);
+   if (sect == NULL)
+     return NULL;
+ 
+   if (! bfd_set_section_flags (abfd, sect,
+ 			       SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING))
+     /* XXX Should we delete the section from the bfd ?  */
+     return NULL;
+ 
+   
+   if (! bfd_set_section_size (abfd, sect, 4))
+     /* XXX Should we delete the section from the bfd ?  */
+     return NULL;
+   
+   return sect;
+ }
+ 
+ 
+ /*
+ FUNCTION
+ 	bfd_fill_in_gnu_debuglink_timestamp_section
+ 
+ SYNOPSIS
+ 	bfd_boolean bfd_fill_in_gnu_debuglink_timestamp_section
+ 	  (bfd *abfd, struct sec *sect, unsigned long timestamp);
+ 
+ DESCRIPTION
+ 
+ 	Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT}
+ 	and fills in the contents of the section to contain a link to the
+ 	specified @var{filename}.  The filename should be relative to the
+ 	current directory.
+ 
+ RETURNS
+ 	<<TRUE>> is returned if all is ok.  Otherwise <<FALSE>> is returned
+ 	and bfd_error is set.  
+ */
+ 
+ bfd_boolean
+ bfd_fill_in_gnu_debuglink_timestamp_section (bfd *abfd, struct sec *sect,
+ 					     unsigned long timestamp)
+ {
+   char * contents;
+ 
+   if (abfd == NULL || sect == NULL)
+     {
+       bfd_set_error (bfd_error_invalid_operation);
+       return FALSE;
+     }
+ 
+   contents = malloc (4);
+   if (contents == NULL)
+     {
+       /* XXX Should we delete the section from the bfd ?  */
+       bfd_set_error (bfd_error_no_memory);
+       return FALSE;
+     }
+ 
+   bfd_put_32 (abfd, timestamp, contents);
+ 
+   if (! bfd_set_section_contents (abfd, sect, contents, 0, 4))
      {
        /* XXX Should we delete the section from the bfd ?  */
        free (contents);
Index: objcopy.c
===================================================================
RCS file: /cvs/src/src/binutils/objcopy.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 objcopy.c
*** objcopy.c	27 Jun 2003 08:01:28 -0000	1.51
--- objcopy.c	4 Jul 2003 21:18:19 -0000
*************** static struct section_add *add_sections;
*** 224,229 ****
--- 224,233 ----
     This should be the filename to store in the .gnu_debuglink section.  */
  static const char * gnu_debuglink_filename = NULL;
  
+ /* If non zero the argument to --set-debuglink-timestamp.
+    This should be the value to store in the .gnu_debuglink_timestamp */
+ static unsigned long int gnu_debuglink_timestamp;
+ 
  /* Whether to convert debugging information.  */
  static bfd_boolean convert_debugging = FALSE;
  
*************** static char *prefix_alloc_sections_strin
*** 286,291 ****
--- 290,296 ----
  #define OPTION_FORMATS_INFO (OPTION_PREFIX_ALLOC_SECTIONS + 1)
  #define OPTION_ADD_GNU_DEBUGLINK (OPTION_FORMATS_INFO + 1)
  #define OPTION_ONLY_KEEP_DEBUG (OPTION_ADD_GNU_DEBUGLINK + 1)
+ #define OPTION_SET_DEBUGLINK_TIMESTAMP  (OPTION_ONLY_KEEP_DEBUG + 1)
  
  /* Options to handle if running as "strip".  */
  
*************** static struct option copy_options[] =
*** 371,376 ****
--- 376,382 ----
    {"set-start", required_argument, 0, OPTION_SET_START},
    {"srec-len", required_argument, 0, OPTION_SREC_LEN},
    {"srec-forceS3", no_argument, 0, OPTION_SREC_FORCES3},
+   {"set-debuglink-timestamp", required_argument, 0, OPTION_SET_DEBUGLINK_TIMESTAMP},
    {"strip-all", no_argument, 0, 'S'},
    {"strip-debug", no_argument, 0, 'g'},
    {"strip-unneeded", no_argument, 0, OPTION_STRIP_UNNEEDED},
*************** copy_object (ibfd, obfd)
*** 1133,1138 ****
--- 1139,1145 ----
    long symcount;
    asection **osections = NULL;
    asection * gnu_debuglink_section = NULL;
+   asection * gnu_debuglink_timestamp_section = NULL;
    bfd_size_type *gaps = NULL;
    bfd_size_type max_gap = 0;
    long symsize;
*************** copy_object (ibfd, obfd)
*** 1258,1263 ****
--- 1265,1280 ----
  	RETURN_NONFATAL (gnu_debuglink_filename);
  	}
      }
+   else if (gnu_debuglink_timestamp) {
+       gnu_debuglink_timestamp_section =
+ 	bfd_create_gnu_debuglink_timestamp_section (obfd);
+ 
+       if (gnu_debuglink_timestamp_section == NULL)
+ 	{
+ 	  fprintf (stderr, "UGG A\n");
+ 	  RETURN_NONFATAL ("Unable to create gnu_debuglink_timestamp section");
+ 	}
+   }
  
    if (gap_fill_set || pad_to_set)
      {
*************** copy_object (ibfd, obfd)
*** 1421,1434 ****
  
    if (gnu_debuglink_filename != NULL)
      {
!       if (! bfd_fill_in_gnu_debuglink_section
! 	  (obfd, gnu_debuglink_section, gnu_debuglink_filename))
  	{
  	  fprintf (stderr, "UGG 2\n");
  	  RETURN_NONFATAL (gnu_debuglink_filename);
  	}
      }
  
    if (gap_fill_set || pad_to_set)
      {
        bfd_byte *buf;
--- 1438,1462 ----
  
    if (gnu_debuglink_filename != NULL)
      {
!       if (! bfd_fill_in_gnu_debuglink_section (obfd, gnu_debuglink_section,
! 					       gnu_debuglink_filename,
! 					       gnu_debuglink_timestamp))
  	{
  	  fprintf (stderr, "UGG 2\n");
  	  RETURN_NONFATAL (gnu_debuglink_filename);
  	}
      }
  
+   if (gnu_debuglink_timestamp_section)
+     {
+       if (! bfd_fill_in_gnu_debuglink_timestamp_section
+ 	  (obfd, gnu_debuglink_timestamp_section, gnu_debuglink_timestamp))
+ 	{
+ 	  fprintf (stderr, "UGG 3\n");
+ 	  RETURN_NONFATAL ("Unable to fill gnu_debuglink_timestamp section");
+ 	}
+     }
+ 
    if (gap_fill_set || pad_to_set)
      {
        bfd_byte *buf;
*************** copy_main (argc, argv)
*** 2458,2463 ****
--- 2486,2495 ----
  
  	case OPTION_ADD_GNU_DEBUGLINK:
  	  gnu_debuglink_filename = optarg;
+ 	  break;
+ 
+ 	case OPTION_SET_DEBUGLINK_TIMESTAMP:
+ 	  gnu_debuglink_timestamp = atoi(optarg);
  	  break;
  
  	case 'K':
Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.101
diff -u -r1.101 symfile.c
--- symfile.c	27 Jun 2003 13:11:17 -0000	1.101
+++ symfile.c	3 Jul 2003 13:54:51 -0000
@@ -1103,6 +1103,7 @@
 static char *
 find_separate_debug_file (struct objfile *objfile)
 {
+#if 0
   asection *sect;
   char *basename;
   char *dir;
@@ -1178,6 +1179,12 @@
   xfree (basename);
   xfree (dir);
   return NULL;
+#else
+  char *debug_file = NULL;
+  if (objfile->obfd)
+    debug_file = bfd_follow_gnu_debuglink(objfile->obfd, debug_file_directory);
+  return debug_file;
+#endif
 }
 
 

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