From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17082 invoked by alias); 4 Jul 2003 23:40:55 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 17068 invoked from network); 4 Jul 2003 23:40:52 -0000 Received: from unknown (HELO mwinf0104.wanadoo.fr) (193.252.22.30) by sources.redhat.com with SMTP; 4 Jul 2003 23:40:52 -0000 Received: from wanadoo.fr (AToulouse-206-1-3-24.w81-50.abo.wanadoo.fr [81.50.192.24]) by mwinf0104.wanadoo.fr (SMTP Server) with ESMTP id 8EA961BFFFD2; Sat, 5 Jul 2003 01:40:50 +0200 (CEST) Message-ID: <3F062F6C.7050106@wanadoo.fr> Date: Fri, 04 Jul 2003 23:40:00 -0000 From: Philippe Elie User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020605 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Philippe Elie Cc: Nick Clifton , graydon@redhat.com, oprofile-list@sourceforge.net, binutils@sources.redhat.com, gdb@sources.redhat.com Subject: Re: separated debuginfo patch References: <87wuf3s4q3.fsf@dub.venge.net> <3F02B1A5.5000102@wanadoo.fr> <87adbwpkhj.fsf@dub.venge.net> <3F03EB19.4090801@wanadoo.fr> <3F062EDF.4060801@wanadoo.fr> Content-Type: multipart/mixed; boundary="------------090707080001000808000508" X-SW-Source: 2003-07/txt/msg00079.txt.bz2 This is a multi-part message in MIME format. --------------090707080001000808000508 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 111 Philippe Elie wrote: > Nick Clifton wrote: > >> Hi Philippe, > sorry, the missing patch ... regards, Phil --------------090707080001000808000508 Content-Type: text/plain; name="bfd.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="bfd.diff" Content-length: 14208 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 + <> is returned if all is ok, otherwise <>. + */ + + 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, ×tamp); 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 <> 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 + <> is returned if all is ok. Otherwise <> 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); --------------090707080001000808000508 Content-Type: text/plain; name="binutils.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="binutils.diff" Content-length: 3871 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': --------------090707080001000808000508 Content-Type: text/plain; name="gdb.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="gdb.diff" Content-length: 665 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 } --------------090707080001000808000508--