Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* External debug symbols
@ 2002-08-20 12:50 Alexander Larsson
  2002-08-21  6:39 ` Alexander Larsson
  2002-08-21 10:46 ` Jim Blandy
  0 siblings, 2 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-08-20 12:50 UTC (permalink / raw)
  To: gdb

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2023 bytes --]

Hi

I've been experimenting some with removing debug information from binaries 
and placing it in a separate file, and then having gdb automatically load 
these if availible. (The goal here is to package debug information in 
separate packages that can be on-demand downloaded and installed.)

I have written a libelf based application that takes an elf file, splits 
out debug information to a separate file, strips the original file and 
adds a ".debuglink" section to the stripped file. This section contains 
the basename of the filename of the debug file and a crc32 checksum of it.

I've also written an "unstrip" application that puts together the original 
ELF file from the stripped one and the debug file (and some extra 
information I put in a section of the debug file). This produces a bitwise 
identical file to the original.

My next step is to make gdb automatically follow ".debuglink" sections so 
that i don't have to use the unstrip application. Attached to this mail is 
a patch that implements a "badhack" which seems to almost work. In order 
for it to work I had to add all the original section headers to the debug 
file (but SHT_NOBITS, so they take no space). It seems to work for the 
main binary, but setting breakpoints in libraries doesn't work. I think it 
gets the base address wrong or something.

What are your opinions about this solution? Has anything like this been 
done or tought of before? I'm pretty scared of the gdb codebase (looked at 
it for the first time today), so my solution is probably both buggy and 
generally wrong, tips of other ways to do this are appreciated.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a benighted Jewish romance novelist plagued by the memory of his family's 
brutal murder. She's a time-travelling Bolivian traffic cop with only herself 
to blame. They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 2735 bytes --]

diff -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Tue Aug 20 15:32:15 2002
@@ -397,6 +397,11 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
Only in gdb-5.2.1.separate_debug_symbols/gdb: objfiles.c~
diff -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Tue Aug 20 15:15:56 2002
@@ -409,6 +409,8 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    struct objfile *separate_debug_objfile;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
diff -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Tue Aug 20 16:15:33 2002
@@ -837,6 +837,7 @@
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   bfd *abfd;
+  asection *sect = NULL;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +927,42 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  
+  sect = bfd_get_section_by_name (objfile->obfd, ".debuglink");
+  if (sect)
+    {
+      bfd_size_type size = bfd_section_size (objfile->obfd, sect);
+      char *debuglink;
+      char *dir;
+      char *debugfile;
+      char *name_copy;
+      char *p;
+      
+      debuglink = alloca (size);
+      bfd_get_section_contents (objfile->obfd, sect, debuglink,
+				(file_ptr)0, (bfd_size_type)size);
+
+      dir = xstrdup (name);
+      p = strrchr (dir, '/');
+      if (p != NULL)
+	{
+	  *(p+1) = 0;
+	  
+	  debugfile = alloca ( strlen (dir) + strlen (debuglink) + 1);
+	  strcpy (debugfile, dir);
+	  strcat (debugfile, debuglink);
+	}
+      else
+	{
+	  debugfile = alloca ( strlen (debuglink) + 1);
+	  strcpy (debugfile, debuglink);
+	}
+      xfree (dir);
+      
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, addrs, 0, flags);
+    }
+  
   return (objfile);
 }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-08-20 12:50 External debug symbols Alexander Larsson
@ 2002-08-21  6:39 ` Alexander Larsson
  2002-08-21 10:46 ` Jim Blandy
  1 sibling, 0 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-08-21  6:39 UTC (permalink / raw)
  To: gdb

[-- Attachment #1: Type: TEXT/PLAIN, Size: 607 bytes --]

On Tue, 20 Aug 2002, Alexander Larsson wrote:

> It seems to work for
> the main binary, but setting breakpoints in libraries doesn't work. I
> think it gets the base address wrong or something.

The new patch attached seems to fix this.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's an otherworldly vegetarian librarian looking for 'the Big One.' She's a 
hard-bitten renegade pearl diver with a flame-thrower. They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 2799 bytes --]

diff -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Tue Aug 20 15:32:15 2002
@@ -397,6 +397,11 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
diff -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Tue Aug 20 15:15:56 2002
@@ -409,6 +409,8 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    struct objfile *separate_debug_objfile;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
diff -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Wed Aug 21 14:47:49 2002
@@ -837,6 +837,11 @@
   struct objfile *objfile;
   struct partial_symtab *psymtab;
   bfd *abfd;
+  asection *sect = NULL;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +931,43 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  
+  sect = bfd_get_section_by_name (objfile->obfd, ".debuglink");
+  if (sect)
+    {
+      bfd_size_type size = bfd_section_size (objfile->obfd, sect);
+      char *debuglink;
+      char *dir;
+      char *debugfile;
+      char *name_copy;
+      char *p;
+      
+      debuglink = alloca (size);
+      bfd_get_section_contents (objfile->obfd, sect, debuglink,
+				(file_ptr)0, (bfd_size_type)size);
+
+      dir = xstrdup (name);
+      p = strrchr (dir, '/');
+      if (p != NULL)
+	{
+	  *(p+1) = 0;
+	  
+	  debugfile = alloca ( strlen (dir) + strlen (debuglink) + 1);
+	  strcpy (debugfile, dir);
+	  strcat (debugfile, debuglink);
+	}
+      else
+	{
+	  debugfile = alloca ( strlen (debuglink) + 1);
+	  strcpy (debugfile, debuglink);
+	}
+      xfree (dir);
+      
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+
+      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, (addrs != NULL) ? &orig_addrs : NULL, 0, flags);
+    }
+  
   return (objfile);
 }
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-08-20 12:50 External debug symbols Alexander Larsson
  2002-08-21  6:39 ` Alexander Larsson
@ 2002-08-21 10:46 ` Jim Blandy
  2002-08-21 23:51   ` Alexander Larsson
  2002-08-27  3:59   ` Alexander Larsson
  1 sibling, 2 replies; 20+ messages in thread
From: Jim Blandy @ 2002-08-21 10:46 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: gdb


Wow, that's a lot less work than I expected it to be.  It doesn't look
especially wrong to me.  Basically, the presence of a .debuglink
section tells GDB that, whenever it loads one objfile, it should also
load the other.  When the stripped objfile is freed, the other one is
freed, too.

Sun's toolchain, I'm told, has the ability to simply leave the debug
info in the .o files, and just put what amounts to an index in the
executable file.  The debugger is responsible for figuring out which
.o file has the data it needs, and applying any relocs to the debug
info based on the symbol values in the linked executable.  This makes
linking a lot faster, and keeps executables small.  This would also
address your distribution size problem, but it would also be helpful
to developers in their everyday work as well.

But since the .debuglink change is so simple, it seems a shame to put
that on hold in favor of an alternative solution which I expect will
take a lot more work, and may never get done.

.debuglink looks like a Dwarf 2 section name.  How about .gnu_debuglink?

I'm also concerned about the deallocation policy.  I think your change
will break the ALL_OBJFILES_SAFE macro, since the `nxt' pointer the
macro carefully caches before evaluating the `for' body will become
invalid if the body goes and frees the objfile it points to.

Along similar lines --- what would happen if the debug objfile gets
unloaded before the stripped objfile?  Wouldn't the stripped objfile
still have a dangling pointer to the now-gone debug objfile?  I can't
think of a situation where this would happen, but it would be nice to
be confident that it didn't matter.

Alexander Larsson <alexl@redhat.com> writes:

> Hi
> 
> I've been experimenting some with removing debug information from binaries 
> and placing it in a separate file, and then having gdb automatically load 
> these if availible. (The goal here is to package debug information in 
> separate packages that can be on-demand downloaded and installed.)
> 
> I have written a libelf based application that takes an elf file, splits 
> out debug information to a separate file, strips the original file and 
> adds a ".debuglink" section to the stripped file. This section contains 
> the basename of the filename of the debug file and a crc32 checksum of it.
> 
> I've also written an "unstrip" application that puts together the original 
> ELF file from the stripped one and the debug file (and some extra 
> information I put in a section of the debug file). This produces a bitwise 
> identical file to the original.
> 
> My next step is to make gdb automatically follow ".debuglink" sections so 
> that i don't have to use the unstrip application. Attached to this mail is 
> a patch that implements a "badhack" which seems to almost work. In order 
> for it to work I had to add all the original section headers to the debug 
> file (but SHT_NOBITS, so they take no space). It seems to work for the 
> main binary, but setting breakpoints in libraries doesn't work. I think it 
> gets the base address wrong or something.
> 
> What are your opinions about this solution? Has anything like this been 
> done or tought of before? I'm pretty scared of the gdb codebase (looked at 
> it for the first time today), so my solution is probably both buggy and 
> generally wrong, tips of other ways to do this are appreciated.
> 
> -- 
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>  Alexander Larsson                                            Red Hat, Inc 
>                    alexl@redhat.com    alla@lysator.liu.se 
> He's a benighted Jewish romance novelist plagued by the memory of his family's 
> brutal murder. She's a time-travelling Bolivian traffic cop with only herself 
> to blame. They fight crime! 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-08-21 10:46 ` Jim Blandy
@ 2002-08-21 23:51   ` Alexander Larsson
  2002-08-27  3:59   ` Alexander Larsson
  1 sibling, 0 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-08-21 23:51 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb

On 21 Aug 2002, Jim Blandy wrote:

> Wow, that's a lot less work than I expected it to be.  It doesn't look
> especially wrong to me.  Basically, the presence of a .debuglink
> section tells GDB that, whenever it loads one objfile, it should also
> load the other.  When the stripped objfile is freed, the other one is
> freed, too.

Since I don't know much about the gdb codebase I tried to look for the 
solution that required the smallest amount of changes. But yeah, I was 
also a bit amazed how easy it was.
 
> Sun's toolchain, I'm told, has the ability to simply leave the debug
> info in the .o files, and just put what amounts to an index in the
> executable file.  The debugger is responsible for figuring out which
> .o file has the data it needs, and applying any relocs to the debug
> info based on the symbol values in the linked executable.  This makes
> linking a lot faster, and keeps executables small.  This would also
> address your distribution size problem, but it would also be helpful
> to developers in their everyday work as well.

It does sound nice, but it also sounds like an load of work. And for us 
having just one file with debug information per lib/executable is actually 
preferable, from a packagaging perspective.
 
> But since the .debuglink change is so simple, it seems a shame to put
> that on hold in favor of an alternative solution which I expect will
> take a lot more work, and may never get done.
> 
> .debuglink looks like a Dwarf 2 section name.  How about .gnu_debuglink?

I will change that.
 
> I'm also concerned about the deallocation policy.  I think your change
> will break the ALL_OBJFILES_SAFE macro, since the `nxt' pointer the
> macro carefully caches before evaluating the `for' body will become
> invalid if the body goes and frees the objfile it points to.
> 
> Along similar lines --- what would happen if the debug objfile gets
> unloaded before the stripped objfile?  Wouldn't the stripped objfile
> still have a dangling pointer to the now-gone debug objfile?  I can't
> think of a situation where this would happen, but it would be nice to
> be confident that it didn't matter.

The later problem could be fixed by having a back-pointer from the debug 
objfile to the original one, and NULLing out the other pointer when the 
debug objfile is freed.

The first issue sounds harder. It could be handled by making sure the 
debug file is always in front of the original file in the object_files 
list. But that sounds somewhat fragile.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a notorious chivalrous cowboy on his last day in the job. She's a 
disco-crazy paranoid vampire looking for love in all the wrong places. They 
fight crime! 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-08-21 10:46 ` Jim Blandy
  2002-08-21 23:51   ` Alexander Larsson
@ 2002-08-27  3:59   ` Alexander Larsson
  2002-09-16  6:59     ` Alexander Larsson
  1 sibling, 1 reply; 20+ messages in thread
From: Alexander Larsson @ 2002-08-27  3:59 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1455 bytes --]

On 21 Aug 2002, Jim Blandy wrote:
 
> Wow, that's a lot less work than I expected it to be.  It doesn't look
> especially wrong to me.  Basically, the presence of a .debuglink
> section tells GDB that, whenever it loads one objfile, it should also
> load the other.  When the stripped objfile is freed, the other one is
> freed, too.

Ok. Here is a new, more "productized" patch. It is slightly larger, since 
it does a bit more. New in this patch is:
* Some more memory handling code to handle the cases Jim mentioned.
* Verify the crc32 checksum of the debug symbol file
* look for separate debug files in several places:
  1 - In the same directory as the original file
  2 - In a .debug subdirectory
  3 - In a gloal directory, with the full pathname appended.
      So if the global path is /usr/lib/debug it would look for 
      debug info for /usr/bin/ls in /usr/lib/debug/usr/bin/ls.
      (global directory is settable in gdb, defaults to $libdir/debug)

  The last place is what we want to use for the Red Hat distribution. It 
  makes it very nice from a packaging standpoint.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a sword-wielding crooked astronaut haunted by memories of 'Nam. She's an 
elegant winged vampire with only herself to blame. They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 14267 bytes --]

diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acconfig.h gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h
--- gdb-5.2.1/gdb/acconfig.h	Sat Jan  5 19:36:32 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h	Mon Aug 26 16:44:14 2002
@@ -173,3 +173,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* libdir */
+#undef DEBUGDIR
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acinclude.m4 gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4
--- gdb-5.2.1/gdb/acinclude.m4	Mon Apr 15 06:28:49 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4	Mon Aug 26 11:16:40 2002
@@ -976,3 +976,18 @@
   *) CC="$CC $am_cv_prog_cc_stdc" ;;
 esac
 ])
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo [$]$2`
+  ac_define_dir=`eval echo [$]ac_define_dir`
+  ifelse($3, ,
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
--- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
@@ -234,6 +234,14 @@
 AC_CHECK_LIB(socket, socketpair)
 AC_CHECK_FUNCS(socketpair)
 
+debugdir=${libdir}/debug
+	 
+AC_ARG_WITH(separate-debug-dir,
+[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+	
+AC_DEFINE_DIR(DEBUGDIR, debugdir)
+#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
 BFD_NEED_DECLARATION(malloc)
 BFD_NEED_DECLARATION(realloc)
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Mon Aug 26 10:21:12 2002
@@ -325,6 +325,27 @@
   return (objfile);
 }
 
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+  struct objfile **objp;
+
+  unlink_objfile (objfile);
+  
+  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+    {
+      if (*objp == before_this)
+	{
+	  objfile->next = *objp;
+	  *objp = objfile;
+	  return;
+	}
+    }
+  
+  internal_error (__FILE__, __LINE__,
+		  "put_objfile_before: before objfile not in list");
+}
+
 /* Put OBJFILE at the front of the list.  */
 
 void
@@ -397,6 +418,18 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
+  if (objfile->separate_debug_objfile_backlink)
+    {
+      /* We freed the separate debug file, make sure the base objfile
+	 doesn't reference it.  */
+      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Aug 26 14:57:15 2002
@@ -409,6 +409,9 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    struct objfile *separate_debug_objfile;
+    struct objfile *separate_debug_objfile_backlink;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
@@ -500,6 +503,8 @@
 
 extern int build_objfile_section_table (struct objfile *);
 
+extern void put_objfile_before (struct objfile *, struct objfile *);
+
 extern void objfile_to_front (struct objfile *);
 
 extern void unlink_objfile (struct objfile *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Mon Aug 26 17:16:40 2002
@@ -160,6 +160,8 @@
 
 static void info_ext_lang_command (char *args, int from_tty);
 
+static char *find_separate_debug_file (struct objfile *objfile, const char *name);
+
 static void init_filename_language_table (void);
 
 void _initialize_symfile (void);
@@ -836,7 +839,12 @@
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
+  char *debugfile;
   bfd *abfd;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +934,20 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  debugfile = find_separate_debug_file (objfile, name);
+  if (debugfile)
+    {
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+
+      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, (addrs != NULL) ? &orig_addrs : NULL, 0, flags);
+
+      /* Put the separate debug object before the normal one, this is so that
+         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+      put_objfile_before (objfile->separate_debug_objfile, objfile);
+      
+      xfree (debugfile);
+    }
+  
   return (objfile);
 }
 
@@ -985,6 +1007,188 @@
 #endif
 }
 
+static unsigned long crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
+}
+
+int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+  unsigned long file_crc = 0;
+  int fd;
+  char buffer[8*1024];
+  int count;
+
+  fd = open (name, O_RDONLY);
+  if (fd < 0)
+    return 0;
+
+  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+    file_crc = crc32 (file_crc, buffer, count);
+
+  close (fd);
+
+  return crc == file_crc;
+}
+
+static char *debug_file_search_path = NULL;
+
+static char *
+find_separate_debug_file (struct objfile *objfile, const char *name)
+{
+  asection *sect;
+  char *basename;
+  char *dir;
+  char *debugfile;
+  char *name_copy;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  int crc_offset;
+  unsigned char *crc_data;
+  unsigned char *p;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+  if (sect == NULL)
+    return NULL;
+
+  debuglink_size = bfd_section_size (objfile->obfd, sect);
+  
+  basename = alloca (debuglink_size);
+  bfd_get_section_contents (objfile->obfd, sect, basename,
+			    (file_ptr)0, (bfd_size_type)debuglink_size);
+
+  /* Crc value is stored after the filename, aligned up to 4 bytes. */
+  crc_offset = strlen (basename) + 1;
+  if (crc_offset & 3)
+    crc_offset += 4 - (crc_offset & 3);
+  crc_data = basename + crc_offset;
+
+  crc32 = 0;
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      for (p = crc_data; p < crc_data + 4; ++p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  else
+    {
+      for (p = crc_data + 4 - 1; p >= crc_data; --p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  
+  dir = xstrdup (name);
+  p = strrchr (dir, '/');
+  if (p != NULL)
+    {
+      *(p+1) = 0;
+    }
+  else
+    {
+      *dir = 0;
+    }
+
+  debugfile = alloca (strlen (debug_file_search_path) + 1 +
+		      strlen (dir) + strlen (".debug/") + strlen (basename) + 1);
+
+  /* First try in the same directory as the original file: */
+  strcpy (debugfile, dir);
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in a subdirectory called .debug */
+  strcpy (debugfile, dir);
+  strcat (debugfile, ".debug/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in the global debugfile directory */
+  strcpy (debugfile, debug_file_search_path);
+  strcat (debugfile, "/");
+  strcat (debugfile, dir);
+  strcat (debugfile, "/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  return NULL;
+}
+
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -3336,4 +3540,17 @@
 		  "cache.\n",
 		  &setlist),
      &showlist);
+
+  debug_file_search_path = xstrdup (DEBUGDIR);
+  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
+		   (char *) &debug_file_search_path,
+		   "Set the search path for loading separate debug symbols.\n"
+		   "Separate debug symbols are first searched for in the same\n"
+		   "directory as the binary, then in the .debug subdirectory,\n"
+		   "and lastly at the path of the directory of the binary with\n"
+		   "the global debug-file search path prepended\n",
+		   &setlist);
+  add_show_from_set (c, &showlist);
+  c->completer = filename_completer;
+
 }

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-08-27  3:59   ` Alexander Larsson
@ 2002-09-16  6:59     ` Alexander Larsson
  2002-09-20  8:13       ` Elena Zannoni
  0 siblings, 1 reply; 20+ messages in thread
From: Alexander Larsson @ 2002-09-16  6:59 UTC (permalink / raw)
  To: gdb, Jim Blandy

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1733 bytes --]

On Tue, 27 Aug 2002, Alexander Larsson wrote:

> On 21 Aug 2002, Jim Blandy wrote:
>  
> > Wow, that's a lot less work than I expected it to be.  It doesn't look
> > especially wrong to me.  Basically, the presence of a .debuglink
> > section tells GDB that, whenever it loads one objfile, it should also
> > load the other.  When the stripped objfile is freed, the other one is
> > freed, too.
> 
> Ok. Here is a new, more "productized" patch. It is slightly larger, since 
> it does a bit more. New in this patch is:
> * Some more memory handling code to handle the cases Jim mentioned.
> * Verify the crc32 checksum of the debug symbol file
> * look for separate debug files in several places:
>   1 - In the same directory as the original file
>   2 - In a .debug subdirectory
>   3 - In a gloal directory, with the full pathname appended.
>       So if the global path is /usr/lib/debug it would look for 
>       debug info for /usr/bin/ls in /usr/lib/debug/usr/bin/ls.
>       (global directory is settable in gdb, defaults to $libdir/debug)
> 
>   The last place is what we want to use for the Red Hat distribution. It 
>   makes it very nice from a packaging standpoint.

There was a slight bug in the old patch regarding the ALL_OBJFILES_SAFE 
macro, but here is an updated one that should work.

I'd like to hear some comments on this patch.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a globe-trotting neurotic grifter with acid for blood. She's a 
mistrustful antique-collecting snake charmer with the power to see death. They 
fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 14359 bytes --]

diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acconfig.h gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h
--- gdb-5.2.1/gdb/acconfig.h	Sat Jan  5 19:36:32 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h	Mon Aug 26 16:44:14 2002
@@ -173,3 +173,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* debugdir */
+#undef DEBUGDIR
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acinclude.m4 gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4
--- gdb-5.2.1/gdb/acinclude.m4	Mon Apr 15 06:28:49 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4	Mon Aug 26 11:16:40 2002
@@ -976,3 +976,18 @@
   *) CC="$CC $am_cv_prog_cc_stdc" ;;
 esac
 ])
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo [$]$2`
+  ac_define_dir=`eval echo [$]ac_define_dir`
+  ifelse($3, ,
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
--- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
@@ -234,6 +234,14 @@
 AC_CHECK_LIB(socket, socketpair)
 AC_CHECK_FUNCS(socketpair)
 
+debugdir=${libdir}/debug
+	 
+AC_ARG_WITH(separate-debug-dir,
+[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+	
+AC_DEFINE_DIR(DEBUGDIR, debugdir)
+#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
 BFD_NEED_DECLARATION(malloc)
 BFD_NEED_DECLARATION(realloc)
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Mon Sep 16 14:01:45 2002
@@ -325,6 +325,27 @@
   return (objfile);
 }
 
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+  struct objfile **objp;
+
+  unlink_objfile (objfile);
+  
+  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+    {
+      if (*objp == before_this)
+	{
+	  objfile->next = *objp;
+	  *objp = objfile;
+	  return;
+	}
+    }
+  
+  internal_error (__FILE__, __LINE__,
+		  "put_objfile_before: before objfile not in list");
+}
+
 /* Put OBJFILE at the front of the list.  */
 
 void
@@ -397,6 +418,18 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
+  if (objfile->separate_debug_objfile_backlink)
+    {
+      /* We freed the separate debug file, make sure the base objfile
+	 doesn't reference it.  */
+      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Sep 16 13:15:15 2002
@@ -409,6 +409,9 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    struct objfile *separate_debug_objfile;
+    struct objfile *separate_debug_objfile_backlink;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
@@ -500,6 +503,8 @@
 
 extern int build_objfile_section_table (struct objfile *);
 
+extern void put_objfile_before (struct objfile *, struct objfile *);
+
 extern void objfile_to_front (struct objfile *);
 
 extern void unlink_objfile (struct objfile *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Mon Sep 16 15:07:17 2002
@@ -160,6 +160,8 @@
 
 static void info_ext_lang_command (char *args, int from_tty);
 
+static char *find_separate_debug_file (struct objfile *objfile, const char *name);
+
 static void init_filename_language_table (void);
 
 void _initialize_symfile (void);
@@ -836,7 +838,12 @@
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
+  char *debugfile;
   bfd *abfd;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +933,21 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  debugfile = find_separate_debug_file (objfile, name);
+  if (debugfile)
+    {
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+
+      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, (addrs != NULL) ? &orig_addrs : NULL, 0, flags);
+      objfile->separate_debug_objfile->separate_debug_objfile_backlink = objfile;
+      
+      /* Put the separate debug object before the normal one, this is so that
+         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+      put_objfile_before (objfile->separate_debug_objfile, objfile);
+      
+      xfree (debugfile);
+    }
+  
   return (objfile);
 }
 
@@ -985,6 +1007,188 @@
 #endif
 }
 
+static unsigned long crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
+}
+
+int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+  unsigned long file_crc = 0;
+  int fd;
+  char buffer[8*1024];
+  int count;
+
+  fd = open (name, O_RDONLY);
+  if (fd < 0)
+    return 0;
+
+  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+    file_crc = crc32 (file_crc, buffer, count);
+
+  close (fd);
+
+  return crc == file_crc;
+}
+
+static char *debug_file_search_path = NULL;
+
+static char *
+find_separate_debug_file (struct objfile *objfile, const char *name)
+{
+  asection *sect;
+  char *basename;
+  char *dir;
+  char *debugfile;
+  char *name_copy;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  int crc_offset;
+  unsigned char *crc_data;
+  unsigned char *p;
+
+  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+  if (sect == NULL)
+    return NULL;
+
+  debuglink_size = bfd_section_size (objfile->obfd, sect);
+  
+  basename = alloca (debuglink_size);
+  bfd_get_section_contents (objfile->obfd, sect, basename,
+			    (file_ptr)0, (bfd_size_type)debuglink_size);
+
+  /* Crc value is stored after the filename, aligned up to 4 bytes. */
+  crc_offset = strlen (basename) + 1;
+  if (crc_offset & 3)
+    crc_offset += 4 - (crc_offset & 3);
+  crc_data = basename + crc_offset;
+
+  crc32 = 0;
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      for (p = crc_data; p < crc_data + 4; ++p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  else
+    {
+      for (p = crc_data + 4 - 1; p >= crc_data; --p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  
+  dir = xstrdup (name);
+  p = strrchr (dir, '/');
+  if (p != NULL)
+    {
+      *(p+1) = 0;
+    }
+  else
+    {
+      *dir = 0;
+    }
+
+  debugfile = alloca (strlen (debug_file_search_path) + 1 +
+		      strlen (dir) + strlen (".debug/") + strlen (basename) + 1);
+
+  /* First try in the same directory as the original file: */
+  strcpy (debugfile, dir);
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in a subdirectory called .debug */
+  strcpy (debugfile, dir);
+  strcat (debugfile, ".debug/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in the global debugfile directory */
+  strcpy (debugfile, debug_file_search_path);
+  strcat (debugfile, "/");
+  strcat (debugfile, dir);
+  strcat (debugfile, "/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  return NULL;
+}
+
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -3336,4 +3540,17 @@
 		  "cache.\n",
 		  &setlist),
      &showlist);
+
+  debug_file_search_path = xstrdup (DEBUGDIR);
+  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
+		   (char *) &debug_file_search_path,
+		   "Set the search path for loading separate debug symbols.\n"
+		   "Separate debug symbols are first searched for in the same\n"
+		   "directory as the binary, then in the .debug subdirectory,\n"
+		   "and lastly at the path of the directory of the binary with\n"
+		   "the global debug-file search path prepended\n",
+		   &setlist);
+  add_show_from_set (c, &showlist);
+  c->completer = filename_completer;
+
 }

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-16  6:59     ` Alexander Larsson
@ 2002-09-20  8:13       ` Elena Zannoni
  2002-09-20  8:22         ` Daniel Jacobowitz
                           ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Elena Zannoni @ 2002-09-20  8:13 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: gdb, Jim Blandy


I have looked at this. I think it's a valuable thing to have.  I have
a few questions about the approach, and a few more specific comments
about the code. I haven't followed all the implications of this patch.
What do other folks think?

See below.

Alexander Larsson writes:
 > On Tue, 27 Aug 2002, Alexander Larsson wrote:
 > 
 > > On 21 Aug 2002, Jim Blandy wrote:
 > >  
 > > > Wow, that's a lot less work than I expected it to be.  It doesn't look
 > > > especially wrong to me.  Basically, the presence of a .debuglink
 > > > section tells GDB that, whenever it loads one objfile, it should also
 > > > load the other.  When the stripped objfile is freed, the other one is
 > > > freed, too.
 > > 
 > > Ok. Here is a new, more "productized" patch. It is slightly larger, since 
 > > it does a bit more. New in this patch is:
 > > * Some more memory handling code to handle the cases Jim mentioned.
 > > * Verify the crc32 checksum of the debug symbol file
 > > * look for separate debug files in several places:
 > >   1 - In the same directory as the original file
 > >   2 - In a .debug subdirectory
 > >   3 - In a gloal directory, with the full pathname appended.
 > >       So if the global path is /usr/lib/debug it would look for 
 > >       debug info for /usr/bin/ls in /usr/lib/debug/usr/bin/ls.
 > >       (global directory is settable in gdb, defaults to $libdir/debug)
 > > 
 > >   The last place is what we want to use for the Red Hat distribution. It 
 > >   makes it very nice from a packaging standpoint.
 > 
 > There was a slight bug in the old patch regarding the ALL_OBJFILES_SAFE 
 > macro, but here is an updated one that should work.
 > 
 > I'd like to hear some comments on this patch.
 > 
 > -- 
 > =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 >  Alexander Larsson                                            Red Hat, Inc 
 >                    alexl@redhat.com    alla@lysator.liu.se 
 > He's a globe-trotting neurotic grifter with acid for blood. She's a 
 > mistrustful antique-collecting snake charmer with the power to see death. They 
 > fight crime! 
 > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acconfig.h gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h
 > --- gdb-5.2.1/gdb/acconfig.h	Sat Jan  5 19:36:32 2002
 > +++ gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h	Mon Aug 26 16:44:14 2002
 > @@ -173,3 +173,7 @@
 >  
 >  /* nativefile */
 >  #undef GDB_NM_FILE
 > +
 > +/* debugdir */
 > +#undef DEBUGDIR
 > +
 > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acinclude.m4 gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4
 > --- gdb-5.2.1/gdb/acinclude.m4	Mon Apr 15 06:28:49 2002
 > +++ gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4	Mon Aug 26 11:16:40 2002
 > @@ -976,3 +976,18 @@
 >    *) CC="$CC $am_cv_prog_cc_stdc" ;;
 >  esac
 >  ])
 > +
 > +dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
 > +dnl Version 1.3 (2001/03/02)
 > +dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
 > +
 > +AC_DEFUN([AC_DEFINE_DIR], [
 > +  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
 > +  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 > +  ac_define_dir=`eval echo [$]$2`
 > +  ac_define_dir=`eval echo [$]ac_define_dir`
 > +  ifelse($3, ,
 > +    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
 > +    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
 > +])
 > +
 > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
 > --- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
 > +++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
 > @@ -234,6 +234,14 @@
 >  AC_CHECK_LIB(socket, socketpair)
 >  AC_CHECK_FUNCS(socketpair)
 >  
 > +debugdir=${libdir}/debug
 > +	 
 > +AC_ARG_WITH(separate-debug-dir,
 > +[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
 > +[debugdir="${withval}"])
 > +	
 > +AC_DEFINE_DIR(DEBUGDIR, debugdir)
 > +#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 >  

Could this be done alternatively using an environment variable,
instead of being set at configure time? something like
DEBUG_INFO_PATH, or similar.  I don't have a strong preference, but
seems to me that an environment variable is more flexible. 


 >  BFD_NEED_DECLARATION(malloc)
 >  BFD_NEED_DECLARATION(realloc)
 > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
 > --- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
 > +++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Mon Sep 16 14:01:45 2002
 > @@ -325,6 +325,27 @@
 >    return (objfile);
 >  }
 >  
 > +void
 > +put_objfile_before (struct objfile *objfile, struct objfile *before_this)
 > +{
 > +  struct objfile **objp;
 > +
 > +  unlink_objfile (objfile);
 > +  
 > +  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
 > +    {
 > +      if (*objp == before_this)
 > +	{
 > +	  objfile->next = *objp;
 > +	  *objp = objfile;
 > +	  return;
 > +	}
 > +    }
 > +  
 > +  internal_error (__FILE__, __LINE__,
 > +		  "put_objfile_before: before objfile not in list");
 > +}
 > +

Thinking out loud...

I wonder if it wouldn't be more intuitive to add the debug info to the
objfile, instead of creating another objfile.  So that in the end we
would have just a new field added to the objfile, indicating the name
of the debug info file.

It would definitely require more work. There are a few function you
can look at to see how to do this: add_symbol_file itself, of course,
and syms_from_objfile() (which is used in rs6000-tdep.c, in
objfile_symbol_add) (btw, would objfile_symbol_add still work with
your changes?).

Does the reread_symbols() function still work?  To see this you need
to run the inferior, then w/o quitting from gdb, modify the
executable/recompile and then issue a 'run' command.  That would cause
the excutable and symbols to be reread.  It walks the list of existing
objfiles and updates those that need it, but it doesn't call
symbol_file_add, so the crc check would not be done and the 2 files
could get out of sync.

What does the global variable symfile_objfile point to now?
I wonder if lookups of this type would still work:
  sym = lookup_minimal_symbol ("_Prelude", NULL, symfile_objfile);

If I understand correctly, we would have the minimal symbols hanging
off the exec objfile, but the symbol tables would hang off the symbol
objfile? (I haven't looked at this closely, maybe this is not the
case). No, wait, I think we would have 2 copies of the minimal symbols?


 >  /* Put OBJFILE at the front of the list.  */
 >  
 >  void
 > @@ -397,6 +418,18 @@
 >  void
 >  free_objfile (struct objfile *objfile)
 >  {
 > +  if (objfile->separate_debug_objfile)
 > +    {
 > +      free_objfile (objfile->separate_debug_objfile);
 > +    }
 > +  
 > +  if (objfile->separate_debug_objfile_backlink)
 > +    {
 > +      /* We freed the separate debug file, make sure the base objfile
 > +	 doesn't reference it.  */
 > +      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
 > +    }
 > +  
 >    /* First do any symbol file specific actions required when we are
 >       finished with a particular symbol file.  Note that if the objfile
 >       is using reusable symbol information (via mmalloc) then each of
 > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
 > --- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
 > +++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Sep 16 13:15:15 2002
 > @@ -409,6 +409,9 @@
 >      ExportEntry *export_list;
 >      int export_list_size;
 >  
 > +    struct objfile *separate_debug_objfile;
 > +    struct objfile *separate_debug_objfile_backlink;
 > +    

Could you add some comments, here and elsewhere?


 >      /* Place to stash various statistics about this objfile */
 >        OBJSTATS;
 >    };
 > @@ -500,6 +503,8 @@
 >  
 >  extern int build_objfile_section_table (struct objfile *);
 >  
 > +extern void put_objfile_before (struct objfile *, struct objfile *);
 > +
 >  extern void objfile_to_front (struct objfile *);
 >  
 >  extern void unlink_objfile (struct objfile *);
 > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
 > --- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
 > +++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Mon Sep 16 15:07:17 2002
 > @@ -160,6 +160,8 @@
 >  
 >  static void info_ext_lang_command (char *args, int from_tty);
 >  
 > +static char *find_separate_debug_file (struct objfile *objfile, const char *name);
 > +
 >  static void init_filename_language_table (void);
 >  
 >  void _initialize_symfile (void);
 > @@ -836,7 +838,12 @@
 >  {
 >    struct objfile *objfile;
 >    struct partial_symtab *psymtab;
 > +  char *debugfile;
 >    bfd *abfd;
 > +  struct section_addr_info orig_addrs;
 > +  
 > +  if (addrs)
 > +    orig_addrs = *addrs;
 >  
 >    /* Open a bfd for the file, and give user a chance to burp if we'd be
 >       interactively wiping out any existing symbols.  */
 > @@ -926,6 +933,21 @@
 >    if (target_new_objfile_hook)
 >      target_new_objfile_hook (objfile);
 >  
 > +  debugfile = find_separate_debug_file (objfile, name);
 > +  if (debugfile)
 > +    {
 > +      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
 > +
 > +      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, (addrs != NULL) ? &orig_addrs : NULL, 0, flags);


Suggest using a simple conditional instead of a conditional expression.



 > +      objfile->separate_debug_objfile->separate_debug_objfile_backlink = objfile;
 > +      
 > +      /* Put the separate debug object before the normal one, this is so that
 > +         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
 > +      put_objfile_before (objfile->separate_debug_objfile, objfile);
 > +      
 > +      xfree (debugfile);
 > +    }
 > +  
 >    return (objfile);
 >  }
 >  
 > @@ -985,6 +1007,188 @@
 >  #endif
 >  }
 >  
 > +static unsigned long crc32 (unsigned long crc, unsigned char *buf, size_t len)
 > +{
 > +  static const unsigned long crc32_table[256] =
 > +    {
 > +      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
 > +      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
 > +      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
 > +      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
 > +      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
 > +      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
 > +      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
 > +      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
 > +      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
 > +      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
 > +      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
 > +      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
 > +      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
 > +      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
 > +      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
 > +      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
 > +      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
 > +      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
 > +      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
 > +      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
 > +      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
 > +      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
 > +      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
 > +      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
 > +      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
 > +      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
 > +      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
 > +      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
 > +      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
 > +      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
 > +      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
 > +      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
 > +      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
 > +      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
 > +      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
 > +      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
 > +      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
 > +      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
 > +      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
 > +      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
 > +      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
 > +      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
 > +      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
 > +      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
 > +      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
 > +      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
 > +      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
 > +      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
 > +      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
 > +      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
 > +      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
 > +      0x2d02ef8d
 > +    };
 > +  unsigned char *end;
 > +
 > +  crc = ~crc & 0xffffffff;
 > +  for (end = buf + len; buf < end; ++buf)
 > +    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
 > +  return ~crc & 0xffffffff;;
 > +}
 > +

I don't think this function belongs in this file. It is general enough
that it could be pushed into utils.c. Maybe even into some directory
outside of gdb? It could be useful to other tools as well.


For the below, in theory is Ok, but I would suggest looking at the
function openp() (in source.c) and how it is used in the solib_open()
function in solib.c.  The tricky part is going to be assuring that the
filename is portable, i.e. working on windows/dos systems where the
directory separator is '\'. Look at IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH
in the libiberty directory.

Once this is done, this change would need to be documented in the gdb
manual, and a testcase added to the testsuite.


Elena



 > +int
 > +separate_debug_file_exists (const char *name, unsigned long crc)
 > +{
 > +  unsigned long file_crc = 0;
 > +  int fd;
 > +  char buffer[8*1024];
 > +  int count;
 > +
 > +  fd = open (name, O_RDONLY);
 > +  if (fd < 0)
 > +    return 0;
 > +
 > +  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
 > +    file_crc = crc32 (file_crc, buffer, count);
 > +
 > +  close (fd);
 > +
 > +  return crc == file_crc;
 > +}
 > +
 > +static char *debug_file_search_path = NULL;
 > +
 > +static char *
 > +find_separate_debug_file (struct objfile *objfile, const char *name)
 > +{
 > +  asection *sect;
 > +  char *basename;
 > +  char *dir;
 > +  char *debugfile;
 > +  char *name_copy;
 > +  bfd_size_type debuglink_size;
 > +  unsigned long crc32;
 > +  int crc_offset;
 > +  unsigned char *crc_data;
 > +  unsigned char *p;
 > +
 > +  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
 > +
 > +  if (sect == NULL)
 > +    return NULL;
 > +
 > +  debuglink_size = bfd_section_size (objfile->obfd, sect);
 > +  
 > +  basename = alloca (debuglink_size);
 > +  bfd_get_section_contents (objfile->obfd, sect, basename,
 > +			    (file_ptr)0, (bfd_size_type)debuglink_size);
 > +
 > +  /* Crc value is stored after the filename, aligned up to 4 bytes. */
 > +  crc_offset = strlen (basename) + 1;
 > +  if (crc_offset & 3)
 > +    crc_offset += 4 - (crc_offset & 3);
 > +  crc_data = basename + crc_offset;
 > +
 > +  crc32 = 0;
 > +  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
 > +    {
 > +      for (p = crc_data; p < crc_data + 4; ++p)
 > +	crc32 = (crc32 << 8) | *p;
 > +    }
 > +  else
 > +    {
 > +      for (p = crc_data + 4 - 1; p >= crc_data; --p)
 > +	crc32 = (crc32 << 8) | *p;
 > +    }
 > +  
 > +  dir = xstrdup (name);
 > +  p = strrchr (dir, '/');
 > +  if (p != NULL)
 > +    {
 > +      *(p+1) = 0;
 > +    }
 > +  else
 > +    {
 > +      *dir = 0;
 > +    }
 > +
 > +  debugfile = alloca (strlen (debug_file_search_path) + 1 +
 > +		      strlen (dir) + strlen (".debug/") + strlen (basename) + 1);
 > +
 > +  /* First try in the same directory as the original file: */
 > +  strcpy (debugfile, dir);
 > +  strcat (debugfile, basename);
 > +
 > +  if (separate_debug_file_exists (debugfile, crc32))
 > +    {
 > +      xfree (dir);
 > +      return xstrdup (debugfile);
 > +    }
 > +  
 > +  /* Then try in a subdirectory called .debug */
 > +  strcpy (debugfile, dir);
 > +  strcat (debugfile, ".debug/");
 > +  strcat (debugfile, basename);
 > +
 > +  if (separate_debug_file_exists (debugfile, crc32))
 > +    {
 > +      xfree (dir);
 > +      return xstrdup (debugfile);
 > +    }
 > +  
 > +  /* Then try in the global debugfile directory */
 > +  strcpy (debugfile, debug_file_search_path);
 > +  strcat (debugfile, "/");
 > +  strcat (debugfile, dir);
 > +  strcat (debugfile, "/");
 > +  strcat (debugfile, basename);
 > +
 > +  if (separate_debug_file_exists (debugfile, crc32))
 > +    {
 > +      xfree (dir);
 > +      return xstrdup (debugfile);
 > +    }
 > +  
 > +  return NULL;
 > +}
 > +
 > +
 >  /* This is the symbol-file command.  Read the file, analyze its
 >     symbols, and add a struct symtab to a symtab list.  The syntax of
 >     the command is rather bizarre--(1) buildargv implements various
 > @@ -3336,4 +3540,17 @@
 >  		  "cache.\n",
 >  		  &setlist),
 >       &showlist);
 > +
 > +  debug_file_search_path = xstrdup (DEBUGDIR);
 > +  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
 > +		   (char *) &debug_file_search_path,
 > +		   "Set the search path for loading separate debug symbols.\n"
 > +		   "Separate debug symbols are first searched for in the same\n"
 > +		   "directory as the binary, then in the .debug subdirectory,\n"
 > +		   "and lastly at the path of the directory of the binary with\n"
 > +		   "the global debug-file search path prepended\n",
 > +		   &setlist);
 > +  add_show_from_set (c, &showlist);
 > +  c->completer = filename_completer;
 > +
 >  }


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-20  8:13       ` Elena Zannoni
@ 2002-09-20  8:22         ` Daniel Jacobowitz
  2002-09-23  0:46           ` Alexander Larsson
  2002-09-23  0:43         ` Alexander Larsson
  2002-09-23  8:21         ` Alexander Larsson
  2 siblings, 1 reply; 20+ messages in thread
From: Daniel Jacobowitz @ 2002-09-20  8:22 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: Alexander Larsson, gdb, Jim Blandy

On Fri, Sep 20, 2002 at 11:11:09AM -0400, Elena Zannoni wrote:
> 
> I have looked at this. I think it's a valuable thing to have.  I have
> a few questions about the approach, and a few more specific comments
> about the code. I haven't followed all the implications of this patch.
> What do other folks think?

In general, I'm in love with it.

>  > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
>  > --- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
>  > +++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
>  > @@ -234,6 +234,14 @@
>  >  AC_CHECK_LIB(socket, socketpair)
>  >  AC_CHECK_FUNCS(socketpair)
>  >  
>  > +debugdir=${libdir}/debug
>  > +	 
>  > +AC_ARG_WITH(separate-debug-dir,
>  > +[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
>  > +[debugdir="${withval}"])
>  > +	
>  > +AC_DEFINE_DIR(DEBUGDIR, debugdir)
>  > +#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
>  >  
> 
> Could this be done alternatively using an environment variable,
> instead of being set at configure time? something like
> DEBUG_INFO_PATH, or similar.  I don't have a strong preference, but
> seems to me that an environment variable is more flexible. 

I'd have to change this for local GDB packages anyway.  Full
relocatable installs are a must for me, so I'd have to make this path
follow the current location of the GDB binary.  I'm hoping to put the
necessary support code in libiberty eventually...
 
> Thinking out loud...
> 
> I wonder if it wouldn't be more intuitive to add the debug info to the
> objfile, instead of creating another objfile.  So that in the end we
> would have just a new field added to the objfile, indicating the name
> of the debug info file.

I like this idea; it seems a lot less fragile.


-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-20  8:13       ` Elena Zannoni
  2002-09-20  8:22         ` Daniel Jacobowitz
@ 2002-09-23  0:43         ` Alexander Larsson
  2002-09-23  8:21         ` Alexander Larsson
  2 siblings, 0 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-09-23  0:43 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb, Jim Blandy

On Fri, 20 Sep 2002, Elena Zannoni wrote:

>  > +++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
>  > @@ -234,6 +234,14 @@
>  >  AC_CHECK_LIB(socket, socketpair)
>  >  AC_CHECK_FUNCS(socketpair)
>  >  
>  > +debugdir=${libdir}/debug
>  > +	 
>  > +AC_ARG_WITH(separate-debug-dir,
>  > +[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
>  > +[debugdir="${withval}"])
>  > +	
>  > +AC_DEFINE_DIR(DEBUGDIR, debugdir)
>  > +#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
>  >  
> 
> Could this be done alternatively using an environment variable,
> instead of being set at configure time? something like
> DEBUG_INFO_PATH, or similar.  I don't have a strong preference, but
> seems to me that an environment variable is more flexible. 

It's currently a gdb variable "debug-file-search-path", and you can set
the default value at configure time. I can change the gdb variable
into an enviroment variable if you want. The only thing I need is to be
able to set the default path to /usr/lib/debug, without any
environment variable needed, because that is how we want to ship it by 
default in Red Hat.
 
>  > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
>  > --- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
>  > +++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Mon Sep 16 14:01:45 2002
>  > @@ -325,6 +325,27 @@
>  >    return (objfile);
>  >  }
>  >  
>  > +void
>  > +put_objfile_before (struct objfile *objfile, struct objfile *before_this)
>  > +{
>  > +  struct objfile **objp;
>  > +
>  > +  unlink_objfile (objfile);
>  > +  
>  > +  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
>  > +    {
>  > +      if (*objp == before_this)
>  > +	{
>  > +	  objfile->next = *objp;
>  > +	  *objp = objfile;
>  > +	  return;
>  > +	}
>  > +    }
>  > +  
>  > +  internal_error (__FILE__, __LINE__,
>  > +		  "put_objfile_before: before objfile not in list");
>  > +}
>  > +
> 
> Thinking out loud...
> 
> I wonder if it wouldn't be more intuitive to add the debug info to the
> objfile, instead of creating another objfile.  So that in the end we
> would have just a new field added to the objfile, indicating the name
> of the debug info file.
> 
> It would definitely require more work. There are a few function you
> can look at to see how to do this: add_symbol_file itself, of course,
> and syms_from_objfile() (which is used in rs6000-tdep.c, in
> objfile_symbol_add) (btw, would objfile_symbol_add still work with
> your changes?).

They really are different object files though. I've for instance tested 
prelinking the main binary after stripping out the debug info (this is 
something we need to support). This works fine, but means that the exec 
lib will be relocated to another address, and the debug lib won't. So 
things like section_offsets in the two objfiles will differ.
 
> Does the reread_symbols() function still work?  To see this you need
> to run the inferior, then w/o quitting from gdb, modify the
> executable/recompile and then issue a 'run' command.  That would cause
> the excutable and symbols to be reread.  It walks the list of existing
> objfiles and updates those that need it, but it doesn't call
> symbol_file_add, so the crc check would not be done and the 2 files
> could get out of sync.

It looks like it would "work", but yeah, it can get out of sync. I'll look 
into this.
 
> What does the global variable symfile_objfile point to now?
> I wonder if lookups of this type would still work:
>   sym = lookup_minimal_symbol ("_Prelude", NULL, symfile_objfile);
> 
> If I understand correctly, we would have the minimal symbols hanging
> off the exec objfile, but the symbol tables would hang off the symbol
> objfile? (I haven't looked at this closely, maybe this is not the
> case). No, wait, I think we would have 2 copies of the minimal symbols?

I think there are two copies of the minimal symbols, yes.

>  > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
>  > --- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
>  > +++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Sep 16 13:15:15 2002
>  > @@ -409,6 +409,9 @@
>  >      ExportEntry *export_list;
>  >      int export_list_size;
>  >  
>  > +    struct objfile *separate_debug_objfile;
>  > +    struct objfile *separate_debug_objfile_backlink;
>  > +    
> 
> Could you add some comments, here and elsewhere?
 
Sure.
 
>  > +  debugfile = find_separate_debug_file (objfile, name);
>  > +  if (debugfile)
>  > +    {
>  > +      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
>  > +
>  > +      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, (addrs != NULL) ? &orig_addrs : NULL, 0, flags);
> 
> 
> Suggest using a simple conditional instead of a conditional expression.

Ok.
 
>  > +  unsigned char *end;
>  > +
>  > +  crc = ~crc & 0xffffffff;
>  > +  for (end = buf + len; buf < end; ++buf)
>  > +    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
>  > +  return ~crc & 0xffffffff;;
>  > +}
>  > +
> 
> I don't think this function belongs in this file. It is general enough
> that it could be pushed into utils.c. Maybe even into some directory
> outside of gdb? It could be useful to other tools as well.

ok. 
 
> For the below, in theory is Ok, but I would suggest looking at the
> function openp() (in source.c) and how it is used in the solib_open()
> function in solib.c.  The tricky part is going to be assuring that the
> filename is portable, i.e. working on windows/dos systems where the
> directory separator is '\'. Look at IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH
> in the libiberty directory.

I'll look into it.
 
> Once this is done, this change would need to be documented in the gdb
> manual, and a testcase added to the testsuite.

ok.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a lounge-singing sweet-toothed gentleman spy on the edge. She's a foxy 
nymphomaniac bodyguard from a family of eight older brothers. They fight 
crime! 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-20  8:22         ` Daniel Jacobowitz
@ 2002-09-23  0:46           ` Alexander Larsson
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-09-23  0:46 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Elena Zannoni, gdb, Jim Blandy

On Fri, 20 Sep 2002, Daniel Jacobowitz wrote:

> On Fri, Sep 20, 2002 at 11:11:09AM -0400, Elena Zannoni wrote:
> > 
> > I have looked at this. I think it's a valuable thing to have.  I have
> > a few questions about the approach, and a few more specific comments
> > about the code. I haven't followed all the implications of this patch.
> > What do other folks think?
> 
> In general, I'm in love with it.
> 
> >  > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
> >  > --- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
> >  > +++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
> >  > @@ -234,6 +234,14 @@
> >  >  AC_CHECK_LIB(socket, socketpair)
> >  >  AC_CHECK_FUNCS(socketpair)
> >  >  
> >  > +debugdir=${libdir}/debug
> >  > +	 
> >  > +AC_ARG_WITH(separate-debug-dir,
> >  > +[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
> >  > +[debugdir="${withval}"])
> >  > +	
> >  > +AC_DEFINE_DIR(DEBUGDIR, debugdir)
> >  > +#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
> >  >  
> > 
> > Could this be done alternatively using an environment variable,
> > instead of being set at configure time? something like
> > DEBUG_INFO_PATH, or similar.  I don't have a strong preference, but
> > seems to me that an environment variable is more flexible. 
> 
> I'd have to change this for local GDB packages anyway.  Full
> relocatable installs are a must for me, so I'd have to make this path
> follow the current location of the GDB binary.  I'm hoping to put the
> necessary support code in libiberty eventually...

That's only the default value, you can change it as a gdb variable too. 
Although having it relocate correctly would be really nice.
  
> > Thinking out loud...
> > 
> > I wonder if it wouldn't be more intuitive to add the debug info to the
> > objfile, instead of creating another objfile.  So that in the end we
> > would have just a new field added to the objfile, indicating the name
> > of the debug info file.
> 
> I like this idea; it seems a lot less fragile.

I'm not sure exactly what is meant by it though. But I'm not really a gdb 
hacker. :)

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a scarfaced soccer-playing photographer from the 'hood. She's a pregnant 
bisexual angel who don't take no shit from nobody. They fight crime! 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-20  8:13       ` Elena Zannoni
  2002-09-20  8:22         ` Daniel Jacobowitz
  2002-09-23  0:43         ` Alexander Larsson
@ 2002-09-23  8:21         ` Alexander Larsson
  2002-09-23  8:25           ` Daniel Jacobowitz
  2002-09-23 21:45           ` Eli Zaretskii
  2 siblings, 2 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-09-23  8:21 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb, Jim Blandy

[-- Attachment #1: Type: TEXT/PLAIN, Size: 3975 bytes --]

Here comes a new patch that fixes some issues.

On Fri, 20 Sep 2002, Elena Zannoni wrote:

> Does the reread_symbols() function still work?  To see this you need
> to run the inferior, then w/o quitting from gdb, modify the
> executable/recompile and then issue a 'run' command.  That would cause
> the excutable and symbols to be reread.  It walks the list of existing
> objfiles and updates those that need it, but it doesn't call
> symbol_file_add, so the crc check would not be done and the 2 files
> could get out of sync.

I fixed reread_symbols so that it won't ever use an incorrect debug file. 
It doesn't do a full search though, so if you change the file and keep 
using separate debug files you better leave the debug file in the same 
place.
 
reread_symbols is pretty ugly in general though. For instance, what if the 
new file is relocated to a different place? It copies the old 
section_offsets, so that would break i think.

>  > diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
>  > --- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
>  > +++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Sep 16 13:15:15 2002
>  > @@ -409,6 +409,9 @@
>  >      ExportEntry *export_list;
>  >      int export_list_size;
>  >  
>  > +    struct objfile *separate_debug_objfile;
>  > +    struct objfile *separate_debug_objfile_backlink;
>  > +    
> 
> Could you add some comments, here and elsewhere?

I added some.

>  > +  debugfile = find_separate_debug_file (objfile, name);
>  > +  if (debugfile)
>  > +    {
>  > +      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
>  > +
>  > +      objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, (addrs != NULL) ? &orig_addrs : NULL, 0, flags);
> 
> 
> Suggest using a simple conditional instead of a conditional expression.

Done.

>  > +    };
>  > +  unsigned char *end;
>  > +
>  > +  crc = ~crc & 0xffffffff;
>  > +  for (end = buf + len; buf < end; ++buf)
>  > +    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
>  > +  return ~crc & 0xffffffff;;
>  > +}
>  > +
> 
> I don't think this function belongs in this file. It is general enough
> that it could be pushed into utils.c. Maybe even into some directory
> outside of gdb? It could be useful to other tools as well.

Put it in utils.c
 
> For the below, in theory is Ok, but I would suggest looking at the
> function openp() (in source.c) and how it is used in the solib_open()
> function in solib.c.  The tricky part is going to be assuring that the
> filename is portable, i.e. working on windows/dos systems where the
> directory separator is '\'. Look at IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH
> in the libiberty directory.

I don't want to use openp() because i don't want the first availible file. 
I want the first one that matches the checksum. I can't see how i can use 
openp() to accomplish that.
 
> Once this is done, this change would need to be documented in the gdb
> manual, and a testcase added to the testsuite.

I really tried to make a testcase. I promise. I was just completely 
crushed by expect/dejagnu and the testsuite setup. I have a small piece of 
code that can be used with objcopy --add-section to generate a 
.gnu_debuglink section to test this. I tried it manually, and it works 
well. If anyone is willing to do the testsuite work I promise to help as 
much as I can.

--
--------------------------------------------------------------------------
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's an otherworldly drug-addicted firefighter trapped in a world he never 
made. She's a cynical Buddhist museum curator with the power to see death. 
They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 17818 bytes --]

diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acconfig.h gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h
--- gdb-5.2.1/gdb/acconfig.h	Sat Jan  5 19:36:32 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h	Mon Sep 16 15:28:37 2002
@@ -173,3 +173,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* debugdir */
+#undef DEBUGDIR
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acinclude.m4 gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4
--- gdb-5.2.1/gdb/acinclude.m4	Mon Apr 15 06:28:49 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4	Mon Aug 26 11:16:40 2002
@@ -976,3 +976,18 @@
   *) CC="$CC $am_cv_prog_cc_stdc" ;;
 esac
 ])
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo [$]$2`
+  ac_define_dir=`eval echo [$]ac_define_dir`
+  ifelse($3, ,
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
--- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
@@ -234,6 +234,14 @@
 AC_CHECK_LIB(socket, socketpair)
 AC_CHECK_FUNCS(socketpair)
 
+debugdir=${libdir}/debug
+	 
+AC_ARG_WITH(separate-debug-dir,
+[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+	
+AC_DEFINE_DIR(DEBUGDIR, debugdir)
+#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
 BFD_NEED_DECLARATION(malloc)
 BFD_NEED_DECLARATION(realloc)
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/defs.h gdb-5.2.1.separate_debug_symbols/gdb/defs.h
--- gdb-5.2.1/gdb/defs.h	Mon Mar 25 17:50:20 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/defs.h	Mon Sep 23 12:37:23 2002
@@ -577,6 +577,8 @@
 
 extern char *gdb_realpath (const char *);
 
+extern unsigned long calc_crc32 (unsigned long crc, unsigned char *buf, size_t len);
+
 /* From demangle.c */
 
 extern void set_demangling_style (char *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Mon Sep 23 13:07:24 2002
@@ -325,6 +325,30 @@
   return (objfile);
 }
 
+/* Put one object file before a specified on in the global list.
+   This can be used to make sure an object file is destroyed before
+   another when using ALL_OBJFILES_SAFE to free all objfiles. */
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+  struct objfile **objp;
+
+  unlink_objfile (objfile);
+  
+  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+    {
+      if (*objp == before_this)
+	{
+	  objfile->next = *objp;
+	  *objp = objfile;
+	  return;
+	}
+    }
+  
+  internal_error (__FILE__, __LINE__,
+		  "put_objfile_before: before objfile not in list");
+}
+
 /* Put OBJFILE at the front of the list.  */
 
 void
@@ -397,6 +421,18 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
+  if (objfile->separate_debug_objfile_backlink)
+    {
+      /* We freed the separate debug file, make sure the base objfile
+	 doesn't reference it.  */
+      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Sep 23 13:02:53 2002
@@ -409,6 +409,15 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    /* Link to objfile that contains the debug symbols for this one.
+       One is loaded if this file has an debug link to an existing
+       debug file with the right checksum */
+    struct objfile *separate_debug_objfile;
+
+    /* If this is a separate debug object, this is used as a link to the
+       actual executable objfile. */
+    struct objfile *separate_debug_objfile_backlink;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
@@ -500,6 +509,8 @@
 
 extern int build_objfile_section_table (struct objfile *);
 
+extern void put_objfile_before (struct objfile *, struct objfile *);
+
 extern void objfile_to_front (struct objfile *);
 
 extern void unlink_objfile (struct objfile *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Mon Sep 23 14:49:05 2002
@@ -160,6 +160,8 @@
 
 static void info_ext_lang_command (char *args, int from_tty);
 
+static char *find_separate_debug_file (struct objfile *objfile, const char *name);
+
 static void init_filename_language_table (void);
 
 void _initialize_symfile (void);
@@ -836,7 +838,12 @@
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
+  char *debugfile;
   bfd *abfd;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +933,28 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  debugfile = find_separate_debug_file (objfile, name);
+  if (debugfile)
+    {
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+
+      if (addrs != NULL)
+	{
+	  objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, &orig_addrs, 0, flags);
+	}
+      else
+	{
+	  objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+	}
+      objfile->separate_debug_objfile->separate_debug_objfile_backlink = objfile;
+      
+      /* Put the separate debug object before the normal one, this is so that
+         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+      put_objfile_before (objfile->separate_debug_objfile, objfile);
+      
+      xfree (debugfile);
+    }
+  
   return (objfile);
 }
 
@@ -985,6 +1014,146 @@
 #endif
 }
 
+static char *
+get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+{
+  asection *sect;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  char *contents;
+  int crc_offset;
+  unsigned char *crc_data;
+  unsigned char *p;
+  
+  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+  if (sect == NULL)
+    return NULL;
+
+  debuglink_size = bfd_section_size (objfile->obfd, sect);
+  
+  contents = xmalloc (debuglink_size);
+  bfd_get_section_contents (objfile->obfd, sect, contents,
+			    (file_ptr)0, (bfd_size_type)debuglink_size);
+
+  /* Crc value is stored after the filename, aligned up to 4 bytes. */
+  crc_offset = strlen (contents) + 1;
+  if (crc_offset & 3)
+    crc_offset += 4 - (crc_offset & 3);
+  crc_data = contents + crc_offset;
+
+  crc32 = 0;
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      for (p = crc_data; p < crc_data + 4; ++p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  else
+    {
+      for (p = crc_data + 4 - 1; p >= crc_data; --p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  
+  *crc32_out = crc32;
+  return contents;
+}
+
+static int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+  unsigned long file_crc = 0;
+  int fd;
+  char buffer[8*1024];
+  int count;
+
+  fd = open (name, O_RDONLY);
+  if (fd < 0)
+    return 0;
+
+  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+    file_crc = calc_crc32 (file_crc, buffer, count);
+
+  close (fd);
+
+  return crc == file_crc;
+}
+
+static char *debug_file_search_path = NULL;
+
+static char *
+find_separate_debug_file (struct objfile *objfile, const char *name)
+{
+  asection *sect;
+  char *basename;
+  char *dir;
+  char *debugfile;
+  char *name_copy;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  unsigned char *p;
+
+  basename = get_debug_link_info (objfile, &crc32);
+
+  if (basename == NULL)
+    return NULL;
+  
+  dir = xstrdup (name);
+  p = strrchr (dir, '/');
+  if (p != NULL)
+    {
+      *(p+1) = 0;
+    }
+  else
+    {
+      *dir = 0;
+    }
+
+  debugfile = alloca (strlen (debug_file_search_path) + 1 +
+		      strlen (dir) + strlen (".debug/") + strlen (basename) + 1);
+
+  /* First try in the same directory as the original file: */
+  strcpy (debugfile, dir);
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in a subdirectory called .debug */
+  strcpy (debugfile, dir);
+  strcat (debugfile, ".debug/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in the global debugfile directory */
+  strcpy (debugfile, debug_file_search_path);
+  strcat (debugfile, "/");
+  strcat (debugfile, dir);
+  strcat (debugfile, "/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  xfree (basename);
+  xfree (dir);
+  return NULL;
+}
+
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -1639,6 +1808,8 @@
   long new_modtime;
   int reread_one = 0;
   struct stat new_statbuf;
+  char *debug_file;
+  unsigned long crc32;
   int res;
 
   /* With the addition of shared libraries, this should be modified,
@@ -1822,6 +1993,30 @@
 	         needs to keep track of (such as _sigtramp, or whatever).  */
 
 	      TARGET_SYMFILE_POSTREAD (objfile);
+
+	      /* Verify the checksum of a previously loaded separate debug file. */
+	      if (objfile->separate_debug_objfile)
+		{
+		  printf ("reread sep debug objfile\n");
+		  debug_file = get_debug_link_info (objfile, &crc32);
+		  if (debug_file)
+		    {
+		      if (!separate_debug_file_exists (objfile->separate_debug_objfile->name, crc32))
+			{
+			  printf ("removing invalid separate debug symbols\n");
+			  /* The old separate debug symbols file is invalid */
+			  free_objfile (objfile->separate_debug_objfile);
+			}
+		      xfree (debug_file);
+		    }
+		  else
+		    {
+		      printf ("removing debug symbols, since i found no debug link\n");
+		      /* No more debug link, kill old separate debug symbols */
+		      free_objfile (objfile->separate_debug_objfile);
+		    }
+		}
+	      
 	    }
 	}
     }
@@ -3336,4 +3531,17 @@
 		  "cache.\n",
 		  &setlist),
      &showlist);
+
+  debug_file_search_path = xstrdup (DEBUGDIR);
+  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
+		   (char *) &debug_file_search_path,
+		   "Set the search path for loading separate debug symbols.\n"
+		   "Separate debug symbols are first searched for in the same\n"
+		   "directory as the binary, then in the .debug subdirectory,\n"
+		   "and lastly at the path of the directory of the binary with\n"
+		   "the global debug-file search path prepended\n",
+		   &setlist);
+  add_show_from_set (c, &showlist);
+  c->completer = filename_completer;
+
 }
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/utils.c gdb-5.2.1.separate_debug_symbols/gdb/utils.c
--- gdb-5.2.1/gdb/utils.c	Thu Mar 28 05:28:01 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/utils.c	Mon Sep 23 12:37:05 2002
@@ -2563,3 +2563,69 @@
   return xstrdup (filename);
 #endif
 }
+
+unsigned long
+calc_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
+}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-23  8:21         ` Alexander Larsson
@ 2002-09-23  8:25           ` Daniel Jacobowitz
  2002-09-23 10:03             ` Alexander Larsson
  2002-09-23 21:45           ` Eli Zaretskii
  1 sibling, 1 reply; 20+ messages in thread
From: Daniel Jacobowitz @ 2002-09-23  8:25 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: Elena Zannoni, gdb, Jim Blandy

On Mon, Sep 23, 2002 at 11:21:51AM -0400, Alexander Larsson wrote:
> > Once this is done, this change would need to be documented in the gdb
> > manual, and a testcase added to the testsuite.
> 
> I really tried to make a testcase. I promise. I was just completely 
> crushed by expect/dejagnu and the testsuite setup. I have a small piece of 
> code that can be used with objcopy --add-section to generate a 
> .gnu_debuglink section to test this. I tried it manually, and it works 
> well. If anyone is willing to do the testsuite work I promise to help as 
> much as I can.

If you'll send me that, when this code has settled and been committed
I'll try to handle the testsuite.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-23  8:25           ` Daniel Jacobowitz
@ 2002-09-23 10:03             ` Alexander Larsson
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Larsson @ 2002-09-23 10:03 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Elena Zannoni, gdb, Jim Blandy

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1582 bytes --]

On Mon, 23 Sep 2002, Daniel Jacobowitz wrote:

> On Mon, Sep 23, 2002 at 11:21:51AM -0400, Alexander Larsson wrote:
> > > Once this is done, this change would need to be documented in the gdb
> > > manual, and a testcase added to the testsuite.
> > 
> > I really tried to make a testcase. I promise. I was just completely 
> > crushed by expect/dejagnu and the testsuite setup. I have a small piece of 
> > code that can be used with objcopy --add-section to generate a 
> > .gnu_debuglink section to test this. I tried it manually, and it works 
> > well. If anyone is willing to do the testsuite work I promise to help as 
> > much as I can.
> 
> If you'll send me that, when this code has settled and been committed
> I'll try to handle the testsuite.
> 

Thanks. I attached the code.

A simple test is:
cp binary binary.debug
debug-link < binary.debug > binary.debugling
objcopy --add-section .gnu_debuglink=binary.debuglink binary binary.stripped
strip binary.stripped

After that you should be able to do gdb binary.stripped and still get 
debug info.

I also have some libelf based code to do the stripping which is much more 
production oriented. This is what we'll use later.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's an underprivileged dishevelled grifter with a winning smile and a way 
with the ladies. She's a disco-crazy motormouth queen of the dead from out of 
town. They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 5469 bytes --]

/* Copyright (C) 2001 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   Please email any bugs, comments, and/or additions to this file to:
   bug-gdb@prep.ai.mit.edu  */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>

unsigned long
calc_crc32 (unsigned long crc, unsigned char *buf, size_t len)
{
  static const unsigned long crc32_table[256] =
    {
      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
      0x2d02ef8d
    };
  unsigned char *end;

  crc = ~crc & 0xffffffff;
  for (end = buf + len; buf < end; ++buf)
    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
  return ~crc & 0xffffffff;;
}

int
main (int argc, char *argv[])
{
  unsigned long crc;
  int fd;
  char buffer[8*1024];
  int count;
  uint32_t x;
  
  if (argc < 2)
    return 1;

  crc = 0;
  while ((count = read (0, buffer, sizeof (buffer))) > 0)
    crc = calc_crc32 (crc, buffer, count);

  /* Write the filename */
  write (1, argv[1], strlen (argv[1])+1);

  /* align to 4 byte  */
  count = strlen (argv[1])+1;
  while (count % 4 != 0)
    {
      char c = 0;
      write (1, &c, 1);
      count++;
    }

  /* Optionally write the wrong checksum */
  if (argc > 2 && *argv[2] == 'w')
    crc += 0x1234;
  
  /* Write out the crc in native byte order */
  x = crc;
  write (1, &x, 4);
}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-23  8:21         ` Alexander Larsson
  2002-09-23  8:25           ` Daniel Jacobowitz
@ 2002-09-23 21:45           ` Eli Zaretskii
  2002-09-25  1:51             ` Alexander Larsson
  1 sibling, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2002-09-23 21:45 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: Elena Zannoni, gdb, Jim Blandy


On Mon, 23 Sep 2002, Alexander Larsson wrote:

> > For the below, in theory is Ok, but I would suggest looking at the
> > function openp() (in source.c) and how it is used in the solib_open()
> > function in solib.c.  The tricky part is going to be assuring that the
> > filename is portable, i.e. working on windows/dos systems where the
> > directory separator is '\'. Look at IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH
> > in the libiberty directory.
> 
> I don't want to use openp() because i don't want the first availible file. 
> I want the first one that matches the checksum. I can't see how i can use 
> openp() to accomplish that.

Nevertheless, the code that analizes file names must be portable, so it 
has to use IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH, and the like instead of a 
literal '/' etc.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-23 21:45           ` Eli Zaretskii
@ 2002-09-25  1:51             ` Alexander Larsson
  2002-09-25 22:00               ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Alexander Larsson @ 2002-09-25  1:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Elena Zannoni, gdb, Jim Blandy

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1470 bytes --]

On Tue, 24 Sep 2002, Eli Zaretskii wrote:

> 
> On Mon, 23 Sep 2002, Alexander Larsson wrote:
> 
> > > For the below, in theory is Ok, but I would suggest looking at the
> > > function openp() (in source.c) and how it is used in the solib_open()
> > > function in solib.c.  The tricky part is going to be assuring that the
> > > filename is portable, i.e. working on windows/dos systems where the
> > > directory separator is '\'. Look at IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH
> > > in the libiberty directory.
> > 
> > I don't want to use openp() because i don't want the first availible file. 
> > I want the first one that matches the checksum. I can't see how i can use 
> > openp() to accomplish that.
> 
> Nevertheless, the code that analizes file names must be portable, so it 
> has to use IS_DIR_SEPARATOR, IS_ABSOLUTE_PATH, and the like instead of a 
> literal '/' etc.

Oh, I missed a place where I should be using IS_DIR_SEPARATOR, new patch 
attached. Still, I just hardcode / when i want to add directory 
separators, but this seems to be common in gdb.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a fast talking alcoholic vampire hunter who hides his scarred face behind 
a mask. She's a strong-willed tempestuous barmaid living homeless in New 
York's sewers. They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 17907 bytes --]

diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acconfig.h gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h
--- gdb-5.2.1/gdb/acconfig.h	Sat Jan  5 19:36:32 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h	Mon Sep 16 15:28:37 2002
@@ -173,3 +173,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* debugdir */
+#undef DEBUGDIR
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acinclude.m4 gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4
--- gdb-5.2.1/gdb/acinclude.m4	Mon Apr 15 06:28:49 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4	Mon Aug 26 11:16:40 2002
@@ -976,3 +976,18 @@
   *) CC="$CC $am_cv_prog_cc_stdc" ;;
 esac
 ])
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo [$]$2`
+  ac_define_dir=`eval echo [$]ac_define_dir`
+  ifelse($3, ,
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
--- gdb-5.2.1/gdb/configure.in	Thu Mar 28 05:28:00 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	Mon Aug 26 17:02:48 2002
@@ -234,6 +234,14 @@
 AC_CHECK_LIB(socket, socketpair)
 AC_CHECK_FUNCS(socketpair)
 
+debugdir=${libdir}/debug
+	 
+AC_ARG_WITH(separate-debug-dir,
+[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+	
+AC_DEFINE_DIR(DEBUGDIR, debugdir)
+#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
 BFD_NEED_DECLARATION(malloc)
 BFD_NEED_DECLARATION(realloc)
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/defs.h gdb-5.2.1.separate_debug_symbols/gdb/defs.h
--- gdb-5.2.1/gdb/defs.h	Mon Mar 25 17:50:20 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/defs.h	Mon Sep 23 12:37:23 2002
@@ -577,6 +577,8 @@
 
 extern char *gdb_realpath (const char *);
 
+extern unsigned long calc_crc32 (unsigned long crc, unsigned char *buf, size_t len);
+
 /* From demangle.c */
 
 extern void set_demangling_style (char *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	Thu Dec  6 21:59:11 2001
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	Mon Sep 23 13:07:24 2002
@@ -325,6 +325,30 @@
   return (objfile);
 }
 
+/* Put one object file before a specified on in the global list.
+   This can be used to make sure an object file is destroyed before
+   another when using ALL_OBJFILES_SAFE to free all objfiles. */
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+  struct objfile **objp;
+
+  unlink_objfile (objfile);
+  
+  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+    {
+      if (*objp == before_this)
+	{
+	  objfile->next = *objp;
+	  *objp = objfile;
+	  return;
+	}
+    }
+  
+  internal_error (__FILE__, __LINE__,
+		  "put_objfile_before: before objfile not in list");
+}
+
 /* Put OBJFILE at the front of the list.  */
 
 void
@@ -397,6 +421,18 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
+  if (objfile->separate_debug_objfile_backlink)
+    {
+      /* We freed the separate debug file, make sure the base objfile
+	 doesn't reference it.  */
+      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	Sat Jun 29 00:05:47 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	Mon Sep 23 13:02:53 2002
@@ -409,6 +409,15 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    /* Link to objfile that contains the debug symbols for this one.
+       One is loaded if this file has an debug link to an existing
+       debug file with the right checksum */
+    struct objfile *separate_debug_objfile;
+
+    /* If this is a separate debug object, this is used as a link to the
+       actual executable objfile. */
+    struct objfile *separate_debug_objfile_backlink;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
@@ -500,6 +509,8 @@
 
 extern int build_objfile_section_table (struct objfile *);
 
+extern void put_objfile_before (struct objfile *, struct objfile *);
+
 extern void objfile_to_front (struct objfile *);
 
 extern void unlink_objfile (struct objfile *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	Sat Jun 22 18:49:33 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	Wed Sep 25 09:37:03 2002
@@ -37,6 +37,7 @@
 #include "complaints.h"
 #include "demangle.h"
 #include "inferior.h"		/* for write_pc */
+#include "filenames.h"		/* for DOSish file names */
 #include "gdb-stabs.h"
 #include "obstack.h"
 #include "completer.h"
@@ -160,6 +161,8 @@
 
 static void info_ext_lang_command (char *args, int from_tty);
 
+static char *find_separate_debug_file (struct objfile *objfile, const char *name);
+
 static void init_filename_language_table (void);
 
 void _initialize_symfile (void);
@@ -836,7 +839,12 @@
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
+  char *debugfile;
   bfd *abfd;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +934,28 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  debugfile = find_separate_debug_file (objfile, name);
+  if (debugfile)
+    {
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+
+      if (addrs != NULL)
+	{
+	  objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, &orig_addrs, 0, flags);
+	}
+      else
+	{
+	  objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+	}
+      objfile->separate_debug_objfile->separate_debug_objfile_backlink = objfile;
+      
+      /* Put the separate debug object before the normal one, this is so that
+         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+      put_objfile_before (objfile->separate_debug_objfile, objfile);
+      
+      xfree (debugfile);
+    }
+  
   return (objfile);
 }
 
@@ -985,6 +1015,145 @@
 #endif
 }
 
+static char *
+get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+{
+  asection *sect;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  char *contents;
+  int crc_offset;
+  unsigned char *crc_data;
+  unsigned char *p;
+  
+  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+  if (sect == NULL)
+    return NULL;
+
+  debuglink_size = bfd_section_size (objfile->obfd, sect);
+  
+  contents = xmalloc (debuglink_size);
+  bfd_get_section_contents (objfile->obfd, sect, contents,
+			    (file_ptr)0, (bfd_size_type)debuglink_size);
+
+  /* Crc value is stored after the filename, aligned up to 4 bytes. */
+  crc_offset = strlen (contents) + 1;
+  if (crc_offset & 3)
+    crc_offset += 4 - (crc_offset & 3);
+  crc_data = contents + crc_offset;
+
+  crc32 = 0;
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      for (p = crc_data; p < crc_data + 4; ++p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  else
+    {
+      for (p = crc_data + 4 - 1; p >= crc_data; --p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  
+  *crc32_out = crc32;
+  return contents;
+}
+
+static int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+  unsigned long file_crc = 0;
+  int fd;
+  char buffer[8*1024];
+  int count;
+
+  fd = open (name, O_RDONLY);
+  if (fd < 0)
+    return 0;
+
+  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+    file_crc = calc_crc32 (file_crc, buffer, count);
+
+  close (fd);
+
+  return crc == file_crc;
+}
+
+static char *debug_file_search_path = NULL;
+
+static char *
+find_separate_debug_file (struct objfile *objfile, const char *name)
+{
+  asection *sect;
+  char *basename;
+  char *dir;
+  char *debugfile;
+  char *name_copy;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  int i;
+
+  basename = get_debug_link_info (objfile, &crc32);
+
+  if (basename == NULL)
+    return NULL;
+  
+  dir = xstrdup (name);
+
+  /* Strip off filename part */
+  for (i = strlen(dir) - 1; i >= 0; i--)
+    {
+      if (IS_DIR_SEPARATOR (dir[i]))
+	break;
+    }
+  dir[i+1] = '\0';
+  
+  debugfile = alloca (strlen (debug_file_search_path) + 1 +
+		      strlen (dir) + strlen (".debug/") + strlen (basename) + 1);
+
+  /* First try in the same directory as the original file: */
+  strcpy (debugfile, dir);
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in a subdirectory called .debug */
+  strcpy (debugfile, dir);
+  strcat (debugfile, ".debug/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in the global debugfile directory */
+  strcpy (debugfile, debug_file_search_path);
+  strcat (debugfile, "/");
+  strcat (debugfile, dir);
+  strcat (debugfile, "/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  xfree (basename);
+  xfree (dir);
+  return NULL;
+}
+
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -1639,6 +1808,8 @@
   long new_modtime;
   int reread_one = 0;
   struct stat new_statbuf;
+  char *debug_file;
+  unsigned long crc32;
   int res;
 
   /* With the addition of shared libraries, this should be modified,
@@ -1822,6 +1993,27 @@
 	         needs to keep track of (such as _sigtramp, or whatever).  */
 
 	      TARGET_SYMFILE_POSTREAD (objfile);
+
+	      /* Verify the checksum of a previously loaded separate debug file. */
+	      if (objfile->separate_debug_objfile)
+		{
+		  debug_file = get_debug_link_info (objfile, &crc32);
+		  if (debug_file)
+		    {
+		      if (!separate_debug_file_exists (objfile->separate_debug_objfile->name, crc32))
+			{
+			  /* The old separate debug symbols file is invalid */
+			  free_objfile (objfile->separate_debug_objfile);
+			}
+		      xfree (debug_file);
+		    }
+		  else
+		    {
+		      /* No more debug link, kill old separate debug symbols */
+		      free_objfile (objfile->separate_debug_objfile);
+		    }
+		}
+	      
 	    }
 	}
     }
@@ -3336,4 +3528,17 @@
 		  "cache.\n",
 		  &setlist),
      &showlist);
+
+  debug_file_search_path = xstrdup (DEBUGDIR);
+  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
+		   (char *) &debug_file_search_path,
+		   "Set the search path for loading separate debug symbols.\n"
+		   "Separate debug symbols are first searched for in the same\n"
+		   "directory as the binary, then in the .debug subdirectory,\n"
+		   "and lastly at the path of the directory of the binary with\n"
+		   "the global debug-file search path prepended\n",
+		   &setlist);
+  add_show_from_set (c, &showlist);
+  c->completer = filename_completer;
+
 }
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/utils.c gdb-5.2.1.separate_debug_symbols/gdb/utils.c
--- gdb-5.2.1/gdb/utils.c	Thu Mar 28 05:28:01 2002
+++ gdb-5.2.1.separate_debug_symbols/gdb/utils.c	Mon Sep 23 12:37:05 2002
@@ -2563,3 +2563,69 @@
   return xstrdup (filename);
 #endif
 }
+
+unsigned long
+calc_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
+}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-25  1:51             ` Alexander Larsson
@ 2002-09-25 22:00               ` Eli Zaretskii
  2002-10-02  7:42                 ` Alexander Larsson
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2002-09-25 22:00 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: Elena Zannoni, gdb, Jim Blandy


On Wed, 25 Sep 2002, Alexander Larsson wrote:

> Oh, I missed a place where I should be using IS_DIR_SEPARATOR, new patch 
> attached.

See a couple of comments below.

> Still, I just hardcode / when i want to add directory 
> separators, but this seems to be common in gdb.

That's okay in general, since DOS/Windows filesystems support forward 
slashes as well as backslashes.


+  fd = open (name, O_RDONLY);
+  if (fd < 0)
+    return 0;

This `open' call should use a binary mode (O_BINARY or'ed with O_RDONLY).

+  /* Strip off filename part */
+  for (i = strlen(dir) - 1; i >= 0; i--)
+    {
+      if (IS_DIR_SEPARATOR (dir[i]))
+	break;
+    }
+  dir[i+1] = '\0';

This will fail for file names such as "d:foo.c", but I'm not sure this 
case is worth pursuing.

+  debug_file_search_path = xstrdup (DEBUGDIR);
+  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
+		   (char *) &debug_file_search_path,
+		   "Set the search path for loading separate debug symbols.\n"
+		   "Separate debug symbols are first searched for in the same\n"
+		   "directory as the binary, then in the .debug subdirectory,\n"
+		   "and lastly at the path of the directory of the binary with\n"
+		   "the global debug-file search path prepended\n",
+		   &setlist);

Isn't the use of ``search-path'' here confusing?  The variable holds a 
name of a single directory, not a colon-separated list of directories, 
right?  If so, shouldn't we call it ``debug-file-directory'' or some such?

Finally, this new feature should be documented in the manual.  (Sorry if 
you already posted the patch for that and I forgot.)


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-09-25 22:00               ` Eli Zaretskii
@ 2002-10-02  7:42                 ` Alexander Larsson
  2002-10-02 21:40                   ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Alexander Larsson @ 2002-10-02  7:42 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Elena Zannoni, gdb, Jim Blandy

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1486 bytes --]

On Thu, 26 Sep 2002, Eli Zaretskii wrote:

> +  fd = open (name, O_RDONLY);
> +  if (fd < 0)
> +    return 0;
> 
> This `open' call should use a binary mode (O_BINARY or'ed with O_RDONLY).
> 
> +  debug_file_search_path = xstrdup (DEBUGDIR);
> +  c = add_set_cmd ("debug-file-search-path", class_support, var_string,
> +		   (char *) &debug_file_search_path,
> +		   "Set the search path for loading separate debug symbols.\n"
> +		   "Separate debug symbols are first searched for in the same\n"
> +		   "directory as the binary, then in the .debug subdirectory,\n"
> +		   "and lastly at the path of the directory of the binary with\n"
> +		   "the global debug-file search path prepended\n",
> +		   &setlist);
> 
> Isn't the use of ``search-path'' here confusing?  The variable holds a 
> name of a single directory, not a colon-separated list of directories, 
> right?  If so, shouldn't we call it ``debug-file-directory'' or some such?
> 
> Finally, this new feature should be documented in the manual.  (Sorry if 
> you already posted the patch for that and I forgot.)

Ok. Fixed these in the attached patch.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a fiendish misogynist gangster who dotes on his loving old ma. She's a 
ditzy cigar-chomping mercenary with a knack for trouble. They fight crime! 

[-- Attachment #2: Type: TEXT/PLAIN, Size: 19737 bytes --]

diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acconfig.h gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h
--- gdb-5.2.1/gdb/acconfig.h	2002-01-05 19:36:32.000000000 +0100
+++ gdb-5.2.1.separate_debug_symbols/gdb/acconfig.h	2002-09-16 15:28:37.000000000 +0200
@@ -173,3 +173,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* debugdir */
+#undef DEBUGDIR
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/acinclude.m4 gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4
--- gdb-5.2.1/gdb/acinclude.m4	2002-04-15 06:28:49.000000000 +0200
+++ gdb-5.2.1.separate_debug_symbols/gdb/acinclude.m4	2002-08-26 11:16:40.000000000 +0200
@@ -976,3 +976,18 @@
   *) CC="$CC $am_cv_prog_cc_stdc" ;;
 esac
 ])
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo [$]$2`
+  ac_define_dir=`eval echo [$]ac_define_dir`
+  ifelse($3, ,
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/configure.in gdb-5.2.1.separate_debug_symbols/gdb/configure.in
--- gdb-5.2.1/gdb/configure.in	2002-03-28 05:28:00.000000000 +0100
+++ gdb-5.2.1.separate_debug_symbols/gdb/configure.in	2002-08-26 17:02:48.000000000 +0200
@@ -234,6 +234,14 @@
 AC_CHECK_LIB(socket, socketpair)
 AC_CHECK_FUNCS(socketpair)
 
+debugdir=${libdir}/debug
+	 
+AC_ARG_WITH(separate-debug-dir,
+[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+	
+AC_DEFINE_DIR(DEBUGDIR, debugdir)
+#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
 BFD_NEED_DECLARATION(malloc)
 BFD_NEED_DECLARATION(realloc)
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/defs.h gdb-5.2.1.separate_debug_symbols/gdb/defs.h
--- gdb-5.2.1/gdb/defs.h	2002-03-25 17:50:20.000000000 +0100
+++ gdb-5.2.1.separate_debug_symbols/gdb/defs.h	2002-09-23 12:37:23.000000000 +0200
@@ -577,6 +577,8 @@
 
 extern char *gdb_realpath (const char *);
 
+extern unsigned long calc_crc32 (unsigned long crc, unsigned char *buf, size_t len);
+
 /* From demangle.c */
 
 extern void set_demangling_style (char *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/doc/gdb.texinfo gdb-5.2.1.separate_debug_symbols/gdb/doc/gdb.texinfo
--- gdb-5.2.1/gdb/doc/gdb.texinfo	2002-04-07 20:59:15.000000000 +0200
+++ gdb-5.2.1.separate_debug_symbols/gdb/doc/gdb.texinfo	2002-10-02 16:13:21.000000000 +0200
@@ -9537,6 +9537,29 @@
 Display the current autoloading size threshold, in megabytes.
 @end table
 
+On @sc{elf} based systems, @value{GDBN} supports automatically loading
+symbol tables and debug information from a file separate from the
+executable. This works by putting information in the executable about
+the name and checksum of the file with debug information. When
+@value{GDBN} reads such an executable it automatically tries to locate
+the debug file and load it. 
+
+@value{GDBN} searchs for the file first in the same directory as the
+executable, and then in a subdirectory called @file{.debug}.
+If both these fail @value{GDBN} looks in the global debug directory, with the
+full pathname of the executable. So if you are loading
+@file{/usr/bin/ls} and it references the debug file @file{ls.debug}
+@value{GDBN} will look for @file{usr/bin/ls.debug} in the global debug
+directory.
+
+@table @code
+@kindex set debug-file-directory
+@item set debug-file-directory @var{directory}
+Set the global directory where @value{GDBN} searches for separate
+debug files to @var{directory}.
+@end table
+
+
 @node Symbol Errors
 @section Errors reading symbol files
 
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.c gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c
--- gdb-5.2.1/gdb/objfiles.c	2001-12-06 21:59:11.000000000 +0100
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.c	2002-09-23 13:07:24.000000000 +0200
@@ -325,6 +325,30 @@
   return (objfile);
 }
 
+/* Put one object file before a specified on in the global list.
+   This can be used to make sure an object file is destroyed before
+   another when using ALL_OBJFILES_SAFE to free all objfiles. */
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+  struct objfile **objp;
+
+  unlink_objfile (objfile);
+  
+  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+    {
+      if (*objp == before_this)
+	{
+	  objfile->next = *objp;
+	  *objp = objfile;
+	  return;
+	}
+    }
+  
+  internal_error (__FILE__, __LINE__,
+		  "put_objfile_before: before objfile not in list");
+}
+
 /* Put OBJFILE at the front of the list.  */
 
 void
@@ -397,6 +421,18 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
+  if (objfile->separate_debug_objfile_backlink)
+    {
+      /* We freed the separate debug file, make sure the base objfile
+	 doesn't reference it.  */
+      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/objfiles.h gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h
--- gdb-5.2.1/gdb/objfiles.h	2002-06-29 00:05:47.000000000 +0200
+++ gdb-5.2.1.separate_debug_symbols/gdb/objfiles.h	2002-09-23 13:02:53.000000000 +0200
@@ -409,6 +409,15 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    /* Link to objfile that contains the debug symbols for this one.
+       One is loaded if this file has an debug link to an existing
+       debug file with the right checksum */
+    struct objfile *separate_debug_objfile;
+
+    /* If this is a separate debug object, this is used as a link to the
+       actual executable objfile. */
+    struct objfile *separate_debug_objfile_backlink;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
@@ -500,6 +509,8 @@
 
 extern int build_objfile_section_table (struct objfile *);
 
+extern void put_objfile_before (struct objfile *, struct objfile *);
+
 extern void objfile_to_front (struct objfile *);
 
 extern void unlink_objfile (struct objfile *);
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/symfile.c gdb-5.2.1.separate_debug_symbols/gdb/symfile.c
--- gdb-5.2.1/gdb/symfile.c	2002-06-22 18:49:33.000000000 +0200
+++ gdb-5.2.1.separate_debug_symbols/gdb/symfile.c	2002-10-02 14:43:30.000000000 +0200
@@ -37,6 +37,7 @@
 #include "complaints.h"
 #include "demangle.h"
 #include "inferior.h"		/* for write_pc */
+#include "filenames.h"		/* for DOSish file names */
 #include "gdb-stabs.h"
 #include "obstack.h"
 #include "completer.h"
@@ -160,6 +161,8 @@
 
 static void info_ext_lang_command (char *args, int from_tty);
 
+static char *find_separate_debug_file (struct objfile *objfile, const char *name);
+
 static void init_filename_language_table (void);
 
 void _initialize_symfile (void);
@@ -836,7 +839,12 @@
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
+  char *debugfile;
   bfd *abfd;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -926,6 +934,28 @@
   if (target_new_objfile_hook)
     target_new_objfile_hook (objfile);
 
+  debugfile = find_separate_debug_file (objfile, name);
+  if (debugfile)
+    {
+      printf_filtered ("loading separate debug info from '%s'\n", debugfile);
+
+      if (addrs != NULL)
+	{
+	  objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, &orig_addrs, 0, flags);
+	}
+      else
+	{
+	  objfile->separate_debug_objfile = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+	}
+      objfile->separate_debug_objfile->separate_debug_objfile_backlink = objfile;
+      
+      /* Put the separate debug object before the normal one, this is so that
+         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+      put_objfile_before (objfile->separate_debug_objfile, objfile);
+      
+      xfree (debugfile);
+    }
+  
   return (objfile);
 }
 
@@ -985,6 +1015,145 @@
 #endif
 }
 
+static char *
+get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+{
+  asection *sect;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  char *contents;
+  int crc_offset;
+  unsigned char *crc_data;
+  unsigned char *p;
+  
+  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+  if (sect == NULL)
+    return NULL;
+
+  debuglink_size = bfd_section_size (objfile->obfd, sect);
+  
+  contents = xmalloc (debuglink_size);
+  bfd_get_section_contents (objfile->obfd, sect, contents,
+			    (file_ptr)0, (bfd_size_type)debuglink_size);
+
+  /* Crc value is stored after the filename, aligned up to 4 bytes. */
+  crc_offset = strlen (contents) + 1;
+  if (crc_offset & 3)
+    crc_offset += 4 - (crc_offset & 3);
+  crc_data = contents + crc_offset;
+
+  crc32 = 0;
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      for (p = crc_data; p < crc_data + 4; ++p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  else
+    {
+      for (p = crc_data + 4 - 1; p >= crc_data; --p)
+	crc32 = (crc32 << 8) | *p;
+    }
+  
+  *crc32_out = crc32;
+  return contents;
+}
+
+static int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+  unsigned long file_crc = 0;
+  int fd;
+  char buffer[8*1024];
+  int count;
+
+  fd = open (name, O_RDONLY | O_BINARY);
+  if (fd < 0)
+    return 0;
+
+  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+    file_crc = calc_crc32 (file_crc, buffer, count);
+
+  close (fd);
+
+  return crc == file_crc;
+}
+
+static char *debug_file_directory = NULL;
+
+static char *
+find_separate_debug_file (struct objfile *objfile, const char *name)
+{
+  asection *sect;
+  char *basename;
+  char *dir;
+  char *debugfile;
+  char *name_copy;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  int i;
+
+  basename = get_debug_link_info (objfile, &crc32);
+
+  if (basename == NULL)
+    return NULL;
+  
+  dir = xstrdup (name);
+
+  /* Strip off filename part */
+  for (i = strlen(dir) - 1; i >= 0; i--)
+    {
+      if (IS_DIR_SEPARATOR (dir[i]))
+	break;
+    }
+  dir[i+1] = '\0';
+  
+  debugfile = alloca (strlen (debug_file_directory) + 1 +
+		      strlen (dir) + strlen (".debug/") + strlen (basename) + 1);
+
+  /* First try in the same directory as the original file: */
+  strcpy (debugfile, dir);
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in a subdirectory called .debug */
+  strcpy (debugfile, dir);
+  strcat (debugfile, ".debug/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in the global debugfile directory */
+  strcpy (debugfile, debug_file_directory);
+  strcat (debugfile, "/");
+  strcat (debugfile, dir);
+  strcat (debugfile, "/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  xfree (basename);
+  xfree (dir);
+  return NULL;
+}
+
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -1639,6 +1808,8 @@
   long new_modtime;
   int reread_one = 0;
   struct stat new_statbuf;
+  char *debug_file;
+  unsigned long crc32;
   int res;
 
   /* With the addition of shared libraries, this should be modified,
@@ -1822,6 +1993,27 @@
 	         needs to keep track of (such as _sigtramp, or whatever).  */
 
 	      TARGET_SYMFILE_POSTREAD (objfile);
+
+	      /* Verify the checksum of a previously loaded separate debug file. */
+	      if (objfile->separate_debug_objfile)
+		{
+		  debug_file = get_debug_link_info (objfile, &crc32);
+		  if (debug_file)
+		    {
+		      if (!separate_debug_file_exists (objfile->separate_debug_objfile->name, crc32))
+			{
+			  /* The old separate debug symbols file is invalid */
+			  free_objfile (objfile->separate_debug_objfile);
+			}
+		      xfree (debug_file);
+		    }
+		  else
+		    {
+		      /* No more debug link, kill old separate debug symbols */
+		      free_objfile (objfile->separate_debug_objfile);
+		    }
+		}
+	      
 	    }
 	}
     }
@@ -3336,4 +3528,17 @@
 		  "cache.\n",
 		  &setlist),
      &showlist);
+
+  debug_file_directory = xstrdup (DEBUGDIR);
+  c = add_set_cmd ("debug-file-directory", class_support, var_string,
+		   (char *) &debug_file_directory,
+		   "Set the directory where separate debug symbols are searched for.\n"
+		   "Separate debug symbols are first searched for in the same\n"
+		   "directory as the binary, then in the .debug subdirectory,\n"
+		   "and lastly at the path of the directory of the binary with\n"
+		   "the global debug-file directory prepended\n",
+		   &setlist);
+  add_show_from_set (c, &showlist);
+  c->completer = filename_completer;
+
 }
diff --exclude '*~' --exclude '*.orig' --exclude '*.rej' --exclude '.#*' --exclude '*.o' --exclude CVS --exclude SCCS --exclude RCS --exclude '.*.flags' --exclude .cvsignore --exclude .depend -ur gdb-5.2.1/gdb/utils.c gdb-5.2.1.separate_debug_symbols/gdb/utils.c
--- gdb-5.2.1/gdb/utils.c	2002-03-28 05:28:01.000000000 +0100
+++ gdb-5.2.1.separate_debug_symbols/gdb/utils.c	2002-09-23 12:37:05.000000000 +0200
@@ -2563,3 +2563,69 @@
   return xstrdup (filename);
 #endif
 }
+
+unsigned long
+calc_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
+}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-10-02  7:42                 ` Alexander Larsson
@ 2002-10-02 21:40                   ` Eli Zaretskii
  2002-10-08  8:21                     ` Alexander Larsson
  0 siblings, 1 reply; 20+ messages in thread
From: Eli Zaretskii @ 2002-10-02 21:40 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: Elena Zannoni, gdb, Jim Blandy


On Wed, 2 Oct 2002, Alexander Larsson wrote:

> > Finally, this new feature should be documented in the manual.  (Sorry if 
> > you already posted the patch for that and I forgot.)
> 
> Ok. Fixed these in the attached patch.

Thanks.  The code changes take care of my concerns, and the documentation 
patch is approved (but please make sure there are two blank characters 
after a period that ends a sentence).


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-10-02 21:40                   ` Eli Zaretskii
@ 2002-10-08  8:21                     ` Alexander Larsson
  2002-10-08  9:33                       ` Eli Zaretskii
  0 siblings, 1 reply; 20+ messages in thread
From: Alexander Larsson @ 2002-10-08  8:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Elena Zannoni, gdb, Jim Blandy

On Thu, 3 Oct 2002, Eli Zaretskii wrote:

> 
> On Wed, 2 Oct 2002, Alexander Larsson wrote:
> 
> > > Finally, this new feature should be documented in the manual.  (Sorry if 
> > > you already posted the patch for that and I forgot.)
> > 
> > Ok. Fixed these in the attached patch.
> 
> Thanks.  The code changes take care of my concerns, and the documentation 
> patch is approved (but please make sure there are two blank characters 
> after a period that ends a sentence).

So, how do i proceed from here?

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 Alexander Larsson                                            Red Hat, Inc 
                   alexl@redhat.com    alla@lysator.liu.se 
He's a lounge-singing flyboy messiah looking for 'the Big One.' She's a 
cynical winged mercenary who hides her beauty behind a pair of thick-framed 
spectacles. They fight crime! 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: External debug symbols
  2002-10-08  8:21                     ` Alexander Larsson
@ 2002-10-08  9:33                       ` Eli Zaretskii
  0 siblings, 0 replies; 20+ messages in thread
From: Eli Zaretskii @ 2002-10-08  9:33 UTC (permalink / raw)
  To: Alexander Larsson; +Cc: Elena Zannoni, gdb, Jim Blandy


On Tue, 8 Oct 2002, Alexander Larsson wrote:

> > Thanks.  The code changes take care of my concerns, and the documentation 
> > patch is approved (but please make sure there are two blank characters 
> > after a period that ends a sentence).
> 
> So, how do i proceed from here?

As far as the doco patch is concerned, add the missing blanks where they 
are needed, and you can commit the patch.

As for the code patch, I have no further objections, but I cannot approve 
the patch, either (it's not my responsibility).

Andrew?


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2002-10-08 16:33 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-20 12:50 External debug symbols Alexander Larsson
2002-08-21  6:39 ` Alexander Larsson
2002-08-21 10:46 ` Jim Blandy
2002-08-21 23:51   ` Alexander Larsson
2002-08-27  3:59   ` Alexander Larsson
2002-09-16  6:59     ` Alexander Larsson
2002-09-20  8:13       ` Elena Zannoni
2002-09-20  8:22         ` Daniel Jacobowitz
2002-09-23  0:46           ` Alexander Larsson
2002-09-23  0:43         ` Alexander Larsson
2002-09-23  8:21         ` Alexander Larsson
2002-09-23  8:25           ` Daniel Jacobowitz
2002-09-23 10:03             ` Alexander Larsson
2002-09-23 21:45           ` Eli Zaretskii
2002-09-25  1:51             ` Alexander Larsson
2002-09-25 22:00               ` Eli Zaretskii
2002-10-02  7:42                 ` Alexander Larsson
2002-10-02 21:40                   ` Eli Zaretskii
2002-10-08  8:21                     ` Alexander Larsson
2002-10-08  9:33                       ` Eli Zaretskii

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox