rpms/gdb/devel gdb-6.6-buildid-locate.patch, NONE, 1.1 gdb-6.6-buildid-verify.patch, NONE, 1.1 gdb-6.6-upstream.patch, 1.6, 1.7 gdb.spec, 1.242, 1.243

Jan Kratochvil (jkratoch) fedora-extras-commits at redhat.com
Tue Aug 28 14:47:11 UTC 2007


Author: jkratoch

Update of /cvs/pkgs/rpms/gdb/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv28770

Modified Files:
	gdb-6.6-upstream.patch gdb.spec 
Added Files:
	gdb-6.6-buildid-locate.patch gdb-6.6-buildid-verify.patch 
Log Message:
* Tue Aug 28 2007 Jan Kratochvil <jan.kratochvil at redhat.com> - 6.6-26
- New fast verification whether the .debug file matches its peer (build-id).
- New locating of the matching binaries from the pure core file (build-id).


gdb-6.6-buildid-locate.patch:

--- NEW FILE gdb-6.6-buildid-locate.patch ---
diff -u -rup gdb-6.6-orig/gdb/Makefile.in gdb-6.6/gdb/Makefile.in
--- gdb-6.6-orig/gdb/Makefile.in	2007-08-28 15:31:19.000000000 +0200
+++ gdb-6.6/gdb/Makefile.in	2007-08-28 15:32:40.000000000 +0200
@@ -1917,7 +1917,8 @@ corelow.o: corelow.c $(defs_h) $(arch_ut
 	$(inferior_h) $(symtab_h) $(command_h) $(bfd_h) $(target_h) \
 	$(gdbcore_h) $(gdbthread_h) $(regcache_h) $(regset_h) $(symfile_h) \
 	$(exec_h) $(readline_h) $(gdb_assert_h) \
-	$(exceptions_h) $(solib_h)
+	$(exceptions_h) $(solib_h) $(auxv_h) $(elf_common_h) $(objfiles_h) \
+	$(gdbcmd_h)
 core-regset.o: core-regset.c $(defs_h) $(command_h) $(gdbcore_h) \
 	$(inferior_h) $(target_h) $(gdb_string_h) $(gregset_h)
 cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) $(gdbcmd_h) \
@@ -2785,7 +2786,8 @@ symfile.o: symfile.c $(defs_h) $(bfdlink
 	$(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \
 	$(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
 	$(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h) \
-	$(parser_defs_h) $(elf_bfd_h)
+	$(parser_defs_h) $(elf_bfd_h) $(gdb_stdint_h) $(libbfd_h) $(elf_bfd_h) \
+	$(elf_external_h)
 symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
 	$(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \
 	$(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h)
diff -u -rup gdb-6.6-orig/gdb/corelow.c gdb-6.6/gdb/corelow.c
--- gdb-6.6-orig/gdb/corelow.c	2006-04-18 21:20:06.000000000 +0200
+++ gdb-6.6/gdb/corelow.c	2007-08-28 15:31:56.000000000 +0200
@@ -46,6 +46,10 @@
 #include "gdb_assert.h"
 #include "exceptions.h"
 #include "solib.h"
+#include "auxv.h"
+#include "elf/common.h"
+#include "objfiles.h"
+#include "gdbcmd.h"
 
 
 #ifndef O_LARGEFILE
@@ -253,6 +257,70 @@ add_to_thread_list (bfd *abfd, asection 
     inferior_ptid = pid_to_ptid (thread_id);	/* Yes, make it current */
 }
 
+static int build_id_core_loads = 1;
+static void
+show_build_id_core_loads (struct ui_file *file, int from_tty,
+			  struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Automatic loading of the matching binaries "
+			    "for core files is %s.\n"), value);
+}
+
+static void 
+build_id_locate_exec (int from_tty)
+{
+  CORE_ADDR at_entry;
+  struct build_id *build_id;
+  char *exec_filename, *debug_filename;
+  char *build_id_filename;
+
+  if (exec_bfd != NULL)
+    return;
+
+  if (target_auxv_search (&current_target, AT_ENTRY, &at_entry) <= 0)
+    return;
+
+  build_id = build_id_addr_get (at_entry);
+  if (build_id == NULL)
+    return;
+
+  exec_filename = build_id_to_filename (build_id, &build_id_filename, 0);
+  if (exec_filename != NULL)
+    exec_file_attach (exec_filename, from_tty);
+  else
+    warning (_("Missing the matching executable file: %s"), build_id_filename);
+  xfree (build_id_filename);
+
+  /* `.note.gnu.build-id' section exists even for files without a separate
+     debuginfo.  */
+  debug_filename = build_id_to_filename (build_id, &build_id_filename, 1);
+  if (debug_filename != NULL)
+    {
+      symbol_file_add_main (debug_filename, from_tty);
+      xfree (debug_filename);
+    }
+  else
+    {
+      if (exec_filename != NULL)
+	symbol_file_add_main (exec_filename, from_tty);
+      if (symfile_objfile == NULL)
+	warning (_("Missing the matching executable's debug info file: %s"),
+		 build_id_filename);
+    }
+  xfree (build_id_filename);
+
+  xfree (exec_filename);
+
+  if (exec_filename != NULL)
+    {
+#ifdef SOLIB_ADD
+      SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
+#else
+      solib_add (NULL, 0, &current_target, auto_solib_add);
+#endif
+    }
+}
+
 /* This routine opens and sets up the core file bfd.  */
 
 static void
@@ -377,6 +445,10 @@ core_open (char *filename, int from_tty)
       /* Fetch all registers from core file.  */
       target_fetch_registers (-1);
 
+      /* Find build_id identifiers.  */
+      if (build_id_core_loads != 0)
+        build_id_locate_exec (from_tty);
+
       /* Now, set up the frame cache, and print the top of stack.  */
       flush_cached_frames ();
       select_frame (get_current_frame ());
@@ -662,4 +734,13 @@ _initialize_corelow (void)
 
   if (!coreops_suppress_target)
     add_target (&core_ops);
+
+  add_setshow_zinteger_cmd ("build-id-core-loads", class_files,
+			    &build_id_core_loads, _("\
+Set debugging of the build-id locator."), _("\
+Show debugging of the build-id locator."), _("\
+Enables printf debugging output."),
+			    NULL,
+			    show_build_id_core_loads,
+			    &setlist, &showlist);
 }
diff -u -rup gdb-6.6-orig/gdb/solib-svr4.c gdb-6.6/gdb/solib-svr4.c
--- gdb-6.6-orig/gdb/solib-svr4.c	2007-08-28 15:31:19.000000000 +0200
+++ gdb-6.6/gdb/solib-svr4.c	2007-08-28 15:34:02.000000000 +0200
@@ -943,10 +943,34 @@ svr4_current_sos (void)
 		}
               else
                 {
-		  strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
-		  new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-		  xfree (buffer);
-		  strcpy (new->so_original_name, new->so_name);
+		  struct build_id *build_id;
+
+		  strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
+		  new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+		  /* May get overwritten below.  */
+		  strcpy (new->so_name, new->so_original_name);
+
+		  build_id = build_id_addr_get (LM_DYNAMIC_FROM_LINK_MAP (new));
+		  if (build_id != NULL)
+		    {
+		      char *name, *build_id_filename;
+
+		      /* Missing the build-id matching separate debug info file
+			 would be handled while SO_NAME gets loaded.  */
+		      name = build_id_to_filename (build_id, &build_id_filename, 0);
+		      if (name != NULL)
+			{
+			  strncpy (new->so_name, name, SO_NAME_MAX_PATH_SIZE - 1);
+			  new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+			  xfree (name);
+			}
+		      else
+			warning (_("Missing the matching library file: %s"),
+				 build_id_filename);
+		      xfree (build_id_filename);
+		      xfree (build_id);
+		    }
+
 		  if (debug_solib)
 		    {
 		      fprintf_unfiltered (gdb_stdlog, 
diff -u -rup gdb-6.6-orig/gdb/symfile.c gdb-6.6/gdb/symfile.c
--- gdb-6.6-orig/gdb/symfile.c	2007-08-28 15:31:19.000000000 +0200
+++ gdb-6.6/gdb/symfile.c	2007-08-28 15:36:22.000000000 +0200
@@ -54,6 +54,9 @@
 #include "exec.h"
 #include "parser-defs.h"
 #include "elf-bfd.h"
+#include "gdb_stdint.h"
+#include "libbfd.h"
+#include "elf/external.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -62,6 +65,7 @@
 #include <ctype.h>
 #include <time.h>
 #include <sys/time.h>
+#include <sys/param.h>
 
 
 int (*deprecated_ui_load_progress_hook) (const char *section, unsigned long num);
@@ -1120,16 +1124,62 @@ symbol_file_clear (int from_tty)
       printf_unfiltered (_("No symbol file now.\n"));
 }
 
+/* Locate NT_GNU_BUILD_ID and return its matching debug filename.
+   FIXME: NOTE decoding should be unified with the BFD core notes decoding.  */
+
+static int build_id_debug;
+static void
+show_build_id_debug (struct ui_file *file, int from_tty,
+		     struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Debugging of the build-id locator is %s.\n"),
+		    value);
+}
+
 struct build_id
   {
     size_t size;
     gdb_byte data[1];
   };
 
-/* Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
+struct build_id *
+build_id_buf_get (bfd *templ, gdb_byte *buf, bfd_size_type size)
+{
+  bfd_byte *p;
+
+  p = buf;
+  while (p < buf + size)
+    {
+      /* FIXME: bad alignment assumption.  */
+      Elf_External_Note *xnp = (Elf_External_Note *) p;
+      size_t namesz = H_GET_32 (templ, xnp->namesz);
+      size_t descsz = H_GET_32 (templ, xnp->descsz);
+      bfd_byte *descdata = xnp->name + BFD_ALIGN (namesz, 4);
+
+      if (H_GET_32 (templ, xnp->type) == NT_GNU_BUILD_ID
+	  && namesz == sizeof "GNU"
+	  && memcmp (xnp->name, "GNU", sizeof "GNU") == 0)
+	{
+	  size_t size = descsz;
+	  gdb_byte *data = (void *) descdata;
+	  struct build_id *retval;
+
+	  retval = xmalloc (sizeof *retval - 1 + size);
+	  retval->size = size;
+	  memcpy (retval->data, data, size);
+
+	  return retval;
+	}
+      p = descdata + BFD_ALIGN (descsz, 4);
+    }
+  return NULL;
+}
+
+/* Separate debuginfo files have corrupted PHDR but SHDR is correct there.
+   Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
 
 static struct build_id *
-build_id_bfd_get (bfd *abfd)
+build_id_bfd_shdr_get (bfd *abfd)
 {
   struct build_id *retval;
 
@@ -1145,6 +1195,348 @@ build_id_bfd_get (bfd *abfd)
   return retval;
 }
 
+/* Core files may have missing (corrupt) SHDR but PDHR is correct there.
+   bfd_elf_bfd_from_remote_memory () has too much overhead by
+   allocating/reading all the available ELF PT_LOADs.  */
+
+static struct build_id *
+build_id_phdr_get (bfd *templ, bfd_vma loadbase, unsigned e_phnum,
+		   Elf_Internal_Phdr *i_phdr)
+{
+  int i;
+  struct build_id *retval = NULL;
+
+  for (i = 0; i < e_phnum; i++)
+    if (i_phdr[i].p_type == PT_NOTE && i_phdr[i].p_filesz > 0)
+      {
+	Elf_Internal_Phdr *hdr = &i_phdr[i];
+	gdb_byte *buf;
+	int err;
+
+	buf = xmalloc (hdr->p_filesz);
+	err = target_read_memory (loadbase + i_phdr[i].p_vaddr, buf,
+				  hdr->p_filesz);
+	if (err == 0)
+	  retval = build_id_buf_get (templ, buf, hdr->p_filesz);
+	else
+	  retval = NULL;
+	xfree (buf);
+	if (retval != NULL)
+	  break;
+      }
+  return retval;
+}
+
+/* First we validate the file by reading in the ELF header and checking
+   the magic number.  */
+
+static inline bfd_boolean
+elf_file_p (Elf64_External_Ehdr *x_ehdrp64)
+{
+  gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr));
+  gdb_assert (offsetof (Elf64_External_Ehdr, e_ident)
+	      == offsetof (Elf32_External_Ehdr, e_ident));
+  gdb_assert (sizeof (((Elf64_External_Ehdr *) 0)->e_ident)
+	      == sizeof (((Elf32_External_Ehdr *) 0)->e_ident));
+
+  return ((x_ehdrp64->e_ident[EI_MAG0] == ELFMAG0)
+	  && (x_ehdrp64->e_ident[EI_MAG1] == ELFMAG1)
+	  && (x_ehdrp64->e_ident[EI_MAG2] == ELFMAG2)
+	  && (x_ehdrp64->e_ident[EI_MAG3] == ELFMAG3));
+}
+
+/* Translate an ELF file header in external format into an ELF file header in
+   internal format.  */
+
+#define H_GET_WORD(bfd, ptr) (is64 ? H_GET_64 (bfd, (ptr))		\
+				   : H_GET_32 (bfd, (ptr)))
+#define H_GET_SIGNED_WORD(bfd, ptr) (is64 ? H_GET_S64 (bfd, (ptr))	\
+					  : H_GET_S32 (bfd, (ptr)))
+
+static void
+elf_swap_ehdr_in (bfd *abfd,
+		  const Elf64_External_Ehdr *src64,
+		  Elf_Internal_Ehdr *dst)
+{
+  int is64 = bfd_get_arch_size (abfd) == 64;
+#define SRC(field) (is64 ? src64->field \
+			 : ((const Elf32_External_Ehdr *) src64)->field)
+
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+  memcpy (dst->e_ident, SRC (e_ident), EI_NIDENT);
+  dst->e_type = H_GET_16 (abfd, SRC (e_type));
+  dst->e_machine = H_GET_16 (abfd, SRC (e_machine));
+  dst->e_version = H_GET_32 (abfd, SRC (e_version));
+  if (signed_vma)
+    dst->e_entry = H_GET_SIGNED_WORD (abfd, SRC (e_entry));
+  else
+    dst->e_entry = H_GET_WORD (abfd, SRC (e_entry));
+  dst->e_phoff = H_GET_WORD (abfd, SRC (e_phoff));
+  dst->e_shoff = H_GET_WORD (abfd, SRC (e_shoff));
+  dst->e_flags = H_GET_32 (abfd, SRC (e_flags));
+  dst->e_ehsize = H_GET_16 (abfd, SRC (e_ehsize));
+  dst->e_phentsize = H_GET_16 (abfd, SRC (e_phentsize));
+  dst->e_phnum = H_GET_16 (abfd, SRC (e_phnum));
+  dst->e_shentsize = H_GET_16 (abfd, SRC (e_shentsize));
+  dst->e_shnum = H_GET_16 (abfd, SRC (e_shnum));
+  dst->e_shstrndx = H_GET_16 (abfd, SRC (e_shstrndx));
+
+#undef SRC
+}
+
+/* Translate an ELF program header table entry in external format into an
+   ELF program header table entry in internal format.  */
+
+void
+elf_swap_phdr_in (bfd *abfd,
+		  const Elf64_External_Phdr *src64,
+		  Elf_Internal_Phdr *dst)
+{
+  int is64 = bfd_get_arch_size (abfd) == 64;
+#define SRC(field) (is64 ? src64->field					\
+			 : ((const Elf32_External_Phdr *) src64)->field)
+
+  int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+
+  dst->p_type = H_GET_32 (abfd, SRC (p_type));
+  dst->p_flags = H_GET_32 (abfd, SRC (p_flags));
+  dst->p_offset = H_GET_WORD (abfd, SRC (p_offset));
+  if (signed_vma)
+    {
+      dst->p_vaddr = H_GET_SIGNED_WORD (abfd, SRC (p_vaddr));
+      dst->p_paddr = H_GET_SIGNED_WORD (abfd, SRC (p_paddr));
+    }
+  else
+    {
+      dst->p_vaddr = H_GET_WORD (abfd, SRC (p_vaddr));
+      dst->p_paddr = H_GET_WORD (abfd, SRC (p_paddr));
+    }
+  dst->p_filesz = H_GET_WORD (abfd, SRC (p_filesz));
+  dst->p_memsz = H_GET_WORD (abfd, SRC (p_memsz));
+  dst->p_align = H_GET_WORD (abfd, SRC (p_align));
+
+#undef SRC
+}
+
+#undef H_GET_SIGNED_WORD
+#undef H_GET_WORD
+
+static Elf_Internal_Phdr *
+elf_get_phdr (bfd *templ, bfd_vma ehdr_vma, unsigned *e_phnum_pointer,
+              bfd_vma *loadbase_pointer)
+{
+  /* sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)  */
+  Elf64_External_Ehdr x_ehdr64;	/* Elf file header, external form */
+  Elf_Internal_Ehdr i_ehdr;	/* Elf file header, internal form */
+  bfd_size_type x_phdrs_size;
+  gdb_byte *x_phdrs_ptr;
+  Elf_Internal_Phdr *i_phdrs;
+  int err;
+  unsigned int i;
+  bfd_vma loadbase;
+  int loadbase_set;
+
+  gdb_assert (templ != NULL);
+  gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr));
+
+  /* Read in the ELF header in external format.  */
+  err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr64, sizeof x_ehdr64);
+  if (err)
+    {
+      if (build_id_debug)
+        warning (_("build-id: Error reading ELF header at address 0x%lx"),
+		 (unsigned long) ehdr_vma);
+      return NULL;
+    }
+
+  /* Now check to see if we have a valid ELF file, and one that BFD can
+     make use of.  The magic number must match, the address size ('class')
+     and byte-swapping must match our XVEC entry.  */
+
+  if (! elf_file_p (&x_ehdr64)
+      || x_ehdr64.e_ident[EI_VERSION] != EV_CURRENT
+      || !((bfd_get_arch_size (templ) == 64
+            && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS64)
+           || (bfd_get_arch_size (templ) == 32
+	       && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS32)))
+    {
+      if (build_id_debug)
+        warning (_("build-id: Unrecognized ELF header at address 0x%lx"),
+		 (unsigned long) ehdr_vma);
+      return NULL;
+    }
+
+  /* Check that file's byte order matches xvec's */
+  switch (x_ehdr64.e_ident[EI_DATA])
+    {
+    case ELFDATA2MSB:		/* Big-endian */
+      if (! bfd_header_big_endian (templ))
+	{
+	  if (build_id_debug)
+	    warning (_("build-id: Unrecognized "
+		       "big-endian ELF header at address 0x%lx"),
+		     (unsigned long) ehdr_vma);
+	  return NULL;
+	}
+      break;
+    case ELFDATA2LSB:		/* Little-endian */
+      if (! bfd_header_little_endian (templ))
+	{
+	  if (build_id_debug)
+	    warning (_("build-id: Unrecognized "
+		       "little-endian ELF header at address 0x%lx"),
+		     (unsigned long) ehdr_vma);
+	  return NULL;
+	}
+      break;
+    case ELFDATANONE:		/* No data encoding specified */
+    default:			/* Unknown data encoding specified */
+      if (build_id_debug)
+	warning (_("build-id: Unrecognized "
+		   "ELF header endianity at address 0x%lx"),
+		 (unsigned long) ehdr_vma);
+      return NULL;
+    }
+
+  elf_swap_ehdr_in (templ, &x_ehdr64, &i_ehdr);
+
+  /* The file header tells where to find the program headers.
+     These are what we use to actually choose what to read.  */
+
+  if (i_ehdr.e_phentsize != (bfd_get_arch_size (templ) == 64
+                             ? sizeof (Elf64_External_Phdr)
+			     : sizeof (Elf32_External_Phdr))
+      || i_ehdr.e_phnum == 0)
+    {
+      if (build_id_debug)
+	warning (_("build-id: Invalid ELF program headers from the ELF header "
+		   "at address 0x%lx"), (unsigned long) ehdr_vma);
+      return NULL;
+    }
+
+  x_phdrs_size = (bfd_get_arch_size (templ) == 64 ? sizeof (Elf64_External_Phdr)
+						: sizeof (Elf32_External_Phdr));
+
+  i_phdrs = xmalloc (i_ehdr.e_phnum * (sizeof *i_phdrs + x_phdrs_size));
+  x_phdrs_ptr = (void *) &i_phdrs[i_ehdr.e_phnum];
+  err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs_ptr,
+			    i_ehdr.e_phnum * x_phdrs_size);
+  if (err)
+    {
+      free (i_phdrs);
+      if (build_id_debug)
+        warning (_("build-id: Error reading "
+		   "ELF program headers at address 0x%lx"),
+		 (unsigned long) ehdr_vma + i_ehdr.e_phoff);
+      return NULL;
+    }
+
+  loadbase = ehdr_vma;
+  loadbase_set = 0;
+  for (i = 0; i < i_ehdr.e_phnum; ++i)
+    {
+      elf_swap_phdr_in (templ, (Elf64_External_Phdr *)
+			       (x_phdrs_ptr + i * x_phdrs_size), &i_phdrs[i]);
+      /* IA-64 vDSO may have two mappings for one segment, where one mapping
+	 is executable only, and one is read only.  We must not use the
+	 executable one (PF_R is the first one, PF_X the second one).  */
+      if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R))
+	{
+	  /* Only the first PT_LOAD segment indicates the file bias.
+	     Next segments may have P_VADDR arbitrarily higher.
+	     If the first segment has P_VADDR zero any next segment must not
+	     confuse us, the first one sets LOADBASE certainly enough.  */
+	  if (!loadbase_set && i_phdrs[i].p_offset == 0)
+	    {
+	      loadbase = ehdr_vma - i_phdrs[i].p_vaddr;
+	      loadbase_set = 1;
+	    }
+	}
+    }
+
+  if (build_id_debug)
+    warning (_("build-id: Found ELF header at address 0x%lx, loadbase 0x%lx"),
+	     (unsigned long) ehdr_vma, (unsigned long) loadbase);
+
+  *e_phnum_pointer = i_ehdr.e_phnum;
+  *loadbase_pointer = loadbase;
+  return i_phdrs;
+}
+
+/* BUILD_ID_ADDR_GET gets ADDR located somewhere in the object.
+   Find the first section before ADDR containing an ELF header.
+   We rely on the fact the sections from multiple files do not mix.
+   FIXME: We should check ADDR is contained _inside_ the section with possibly
+   missing content (P_FILESZ < P_MEMSZ).  These omitted sections are currently
+   hidden by _BFD_ELF_MAKE_SECTION_FROM_PHDR.  */
+
+static CORE_ADDR build_id_addr;
+struct build_id_addr_sect
+  {
+    struct build_id_addr_sect *next;
+    asection *sect;
+  };
+static struct build_id_addr_sect *build_id_addr_sect;
+
+static void build_id_addr_candidate (bfd *abfd, asection *sect, void *obj)
+{
+  if (build_id_addr >= bfd_section_vma (abfd, sect))
+    {
+      struct build_id_addr_sect *candidate;
+
+      candidate = xmalloc (sizeof *candidate);
+      candidate->next = build_id_addr_sect;
+      build_id_addr_sect = candidate;
+      candidate->sect = sect;
+    }
+}
+
+struct build_id *
+build_id_addr_get (CORE_ADDR addr)
+{
+  struct build_id_addr_sect *candidate;
+  struct build_id *retval = NULL;
+  Elf_Internal_Phdr *i_phdr = NULL;
+  bfd_vma loadbase = 0;
+  unsigned e_phnum = 0;
+
+  if (core_bfd == NULL)
+    return NULL;
+
+  build_id_addr = addr;
+  gdb_assert (build_id_addr_sect == NULL);
+  bfd_map_over_sections (core_bfd, build_id_addr_candidate, NULL);
+
+  /* Sections are sorted in the high-to-low VMAs order.
+     Stop the search on the first ELF header we find.
+     Do not continue the search even if it does not contain NT_GNU_BUILD_ID.  */
+
+  for (candidate = build_id_addr_sect; candidate != NULL;
+       candidate = candidate->next)
+    {
+      i_phdr = elf_get_phdr (core_bfd,
+			     bfd_section_vma (core_bfd, candidate->sect),
+			     &e_phnum, &loadbase);
+      if (i_phdr != NULL)
+	break;
+    }
+
+  if (i_phdr != NULL)
+    {
+      retval = build_id_phdr_get (core_bfd, loadbase, e_phnum, i_phdr);
+      xfree (i_phdr);
+    }
+
+  while (build_id_addr_sect != NULL)
+    {
+      candidate = build_id_addr_sect;
+      build_id_addr_sect = candidate->next;
+      xfree (candidate);
+    }
+
+  return retval;
+}
+
 /* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value.  */
 
 static int
@@ -1159,7 +1551,7 @@ build_id_verify (const char *filename, s
   if (abfd == NULL)
     return 0;
 
-  found = build_id_bfd_get (abfd);
+  found = build_id_bfd_shdr_get (abfd);
 
   if (found == NULL)
     warning (_("File \"%s\" has no build-id, file skipped"), filename);
@@ -1177,8 +1569,9 @@ build_id_verify (const char *filename, s
 
 static char *debug_file_directory = NULL;
 
-static char *
-build_id_to_debug_filename (struct build_id *build_id)
+char *
+build_id_to_filename (struct build_id *build_id, char **link_return,
+		      int add_debug_suffix)
 {
   char *link, *s, *retval = NULL;
   gdb_byte *data = build_id->data;
@@ -1186,7 +1579,9 @@ build_id_to_debug_filename (struct build
 
   /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
   link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
-		  + 2 * size + (sizeof ".debug" - 1) + 1);
+		  + 2 * size
+		  + (add_debug_suffix ? sizeof ".debug" - 1 : 0)
+		  + 1);
   s = link + sprintf (link, "%s/.build-id/", debug_file_directory);
   if (size > 0)
     {
@@ -1197,12 +1592,14 @@ build_id_to_debug_filename (struct build
     *s++ = '/';
   while (size-- > 0)
     s += sprintf (s, "%02x", (unsigned) *data++);
-  strcpy (s, ".debug");
+  if (add_debug_suffix)
+    strcpy (s, ".debug");
+  else
+    *s = 0;
 
   /* lrealpath() is expensive even for the usually non-existent files.  */
   if (access (link, F_OK) == 0)
     retval = lrealpath (link);
-  xfree (link);
 
   if (retval != NULL && !build_id_verify (retval, build_id))
     {
@@ -1210,6 +1607,11 @@ build_id_to_debug_filename (struct build
       retval = NULL;
     }
 
+  if (link_return != NULL)
+    *link_return = link;
+  else
+    xfree (link);
+
   return retval;
 }
 
@@ -1305,23 +1707,27 @@ find_separate_debug_file (struct objfile
   unsigned long crc32;
   int i;
   struct build_id *build_id;
+  char *build_id_filename = NULL;
 
-  build_id = build_id_bfd_get (objfile->obfd);
+  build_id = build_id_bfd_shdr_get (objfile->obfd);
   if (build_id != NULL)
     {
       char *build_id_name;
 
-      build_id_name = build_id_to_debug_filename (build_id);
-      free (build_id);
+      build_id_name = build_id_to_filename (build_id, &build_id_filename, 1);
+      xfree (build_id);
       /* Prevent looping on a stripped .debug file.  */
       if (build_id_name != NULL && strcmp (build_id_name, objfile->name) == 0)
         {
-	  warning (_("\"%s\": separate debug info file has no debug info"),
+	  warning (_("\"%s\": The separate debug info file has no debug info"),
 		   build_id_name);
 	  xfree (build_id_name);
 	}
       else if (build_id_name != NULL)
-        return build_id_name;
+        {
+	  xfree (build_id_filename);
+	  return build_id_name;
+	}
     }
 
   basename = get_debug_link_info (objfile, &crc32);
@@ -1329,7 +1735,10 @@ find_separate_debug_file (struct objfile
   if (basename == NULL)
     /* There's no separate debug info, hence there's no way we could
        load it => no warning.  */
-    return NULL;
+    {
+      xfree (build_id_filename);
+      return NULL;
+    }
 
   dir = xstrdup (objfile->name);
 
@@ -1358,6 +1767,7 @@ find_separate_debug_file (struct objfile
 
   if (separate_debug_file_exists (debugfile, crc32, objfile->name))
     {
+      xfree (build_id_filename);
       xfree (basename);
       xfree (dir);
       return xstrdup (debugfile);
@@ -1371,6 +1781,7 @@ find_separate_debug_file (struct objfile
 
   if (separate_debug_file_exists (debugfile, crc32, objfile->name))
     {
+      xfree (build_id_filename);
       xfree (basename);
       xfree (dir);
       return xstrdup (debugfile);
@@ -1384,11 +1795,19 @@ find_separate_debug_file (struct objfile
 
   if (separate_debug_file_exists (debugfile, crc32, objfile->name))
     {
+      xfree (build_id_filename);
       xfree (basename);
       xfree (dir);
       return xstrdup (debugfile);
     }
 
+  if (build_id_filename != NULL)
+    {
+      warning (_("Missing the separate debug info file: %s"),
+	       build_id_filename);
+      xfree (build_id_filename);
+    }
+
   xfree (basename);
   xfree (dir);
   return NULL;
@@ -4024,4 +4443,12 @@ the global debug-file directory prepende
 				     NULL,
 				     show_debug_file_directory,
 				     &setlist, &showlist);
+
+  add_setshow_zinteger_cmd ("build-id", no_class, &build_id_debug, _("\
+Set debugging of the build-id locator."), _("\
+Show debugging of the build-id locator."), _("\
+Enables printf debugging output."),
+			    NULL,
+			    show_build_id_debug,
+			    &setdebuglist, &showdebuglist);
 }
diff -u -rup gdb-6.6-orig/gdb/symfile.h gdb-6.6/gdb/symfile.h
--- gdb-6.6-orig/gdb/symfile.h	2005-12-17 23:34:03.000000000 +0100
+++ gdb-6.6/gdb/symfile.h	2007-08-28 15:31:56.000000000 +0200
@@ -322,6 +322,12 @@ extern bfd_byte *symfile_relocate_debug_
 extern void dwarf_build_psymtabs (struct objfile *, int, file_ptr,
 				  unsigned int, file_ptr, unsigned int);
 
+/* build-id support.  */
+struct build_id;
+extern struct build_id *build_id_addr_get (CORE_ADDR addr);
+extern char *build_id_to_filename (struct build_id *build_id,
+				   char **link_return, int add_debug_suffix);
+
 /* From dwarf2read.c */
 
 extern int dwarf2_has_info (struct objfile *);

gdb-6.6-buildid-verify.patch:

--- NEW FILE gdb-6.6-buildid-verify.patch ---
http://sources.redhat.com/ml/gdb-patches/2007-08/msg00478.html
v2
[ Backported for GDB-6.6. ]

2007-08-26  Jan Kratochvil  <jan.kratochvil at redhat.com>

	* Makefile.in (symfile.o): Update dependencies.
	* symfile.c (symbol_file_add_with_addrs_or_offsets): Initialize the
	DEBUGFILE variable.  FIND_SEPARATE_DEBUG_FILE called only if !PSYMTABS.
	(struct build_id): New structure.
	(build_id_bfd_get, build_id_verify, build_id_to_debug_filename): New.
	(find_separate_debug_file): New variable BUILD_ID.
	Call BUILD_ID_BFD_GET with BUILD_ID_TO_DEBUG_FILENAME as the first try.

2007-08-26  Jan Kratochvil  <jan.kratochvil at redhat.com>

	* lib/gdb.exp (build_id_debug_filename_get): New function.
	* gdb.base/sepdebug.exp: Reflect the changes in the heading comment.
	Remove the generate DEBUG file for the future testcase runs.
	New testcase for the NT_GNU_BUILD_ID retrieval.
	Move the final testing step to ...
	(test_different_dir): ... a new function.
	New parameter XFAIL to XFAIL all the tests performed.
	New parameter TEST_DIFFERENT_DIR parametrizing the directory.
	New parameter TYPE to PF_PREFIX all the tests performed.

2007-08-26  Jan Kratochvil  <jan.kratochvil at redhat.com>

	* gdb.texinfo (Separate Debug Files): Included a BUILD ID description.
	Enlisted BUILD ID to the debug file searching example.
	Included a BUILD ID `.note.gnu.build-id' section description.
	Updated/added the debug files splitting instructions for OBJCOPY.

diff -u -rup gdb-6.6-orig/gdb/Makefile.in gdb-6.6/gdb/Makefile.in
--- gdb-6.6-orig/gdb/Makefile.in	2007-08-28 14:32:18.000000000 +0200
+++ gdb-6.6/gdb/Makefile.in	2007-08-28 14:33:56.000000000 +0200
@@ -2785,7 +2785,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink
 	$(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \
 	$(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
 	$(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h) \
-	$(parser_defs_h)
+	$(parser_defs_h) $(elf_bfd_h)
 symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
 	$(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \
 	$(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h)
diff -u -rup gdb-6.6-orig/gdb/doc/gdb.texinfo gdb-6.6/gdb/doc/gdb.texinfo
--- gdb-6.6-orig/gdb/doc/gdb.texinfo	2007-08-28 14:32:18.000000000 +0200
+++ gdb-6.6/gdb/doc/gdb.texinfo	2007-08-28 14:33:03.000000000 +0200
@@ -11857,18 +11857,32 @@ than the executable code itself --- some
 information for their executables in separate files, which users can
 install only when they need to debug a problem.
 
-If an executable's debugging information has been extracted to a
-separate file, the executable should contain a @dfn{debug link} giving
-the name of the debugging information file (with no directory
-components), and a checksum of its contents.  (The exact form of a
-debug link is described below.)  If the full name of the directory
-containing the executable is @var{execdir}, and the executable has a
-debug link that specifies the name @var{debugfile}, then @value{GDBN}
-will automatically search for the debugging information file in three
-places:
+There are two identificators how the separate debug file may be found:
 
 @itemize @bullet
 @item
+ at dfn{debug link} is present only in the executable if its debug information has
+been split out.  It is not present in the separate debug file.  It provides the
+separate debug file filename, usually as @file{executable.debug}.
+ at item
+ at dfn{build id} is present in all the files (if the operating system supports
+it).  The executable file and its separate debug file have the same unique
+ at dfn{build id} content.
+ at end itemize
+
+If the full name of the directory containing the executable is @var{execdir},
+the executable has a debug link that specifies the name @var{debugfile},
+ at var{bu} is the first byte (two hexadecimal characters) of the build id
+content, @var{ild-id} are the remaining bytes / hexadecimal characters and
+ at var{globaldebugdir} is the global debug file directory then @value{GDBN} will
+automatically search for the debugging information file in four places:
+
+ at itemize @bullet
+ at item
+a specific file in the subdirectory of the global debug file directory
+according to the @dfn{build id} content (if present), the file tried is
+ at file{@var{globaldebugdir}/.debug-id/@var{bu}/@var{ild-id}.debug}.
+ at item
 the directory containing the executable file (that is, it will look
 for a file named @file{@var{execdir}/@var{debugfile}},
 @item
@@ -11883,15 +11897,17 @@ executable's full path, and the name fro
 @end itemize
 @noindent
 @value{GDBN} checks under each of these names for a debugging
-information file whose checksum matches that given in the link, and
-reads the debugging information from the first one it finds.
-
-So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls},
-which has a link containing the name @file{ls.debug}, and the global
-debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look
-for debug information in @file{/usr/bin/ls.debug},
- at file{/usr/bin/.debug/ls.debug}, and
- at file{/usr/lib/debug/usr/bin/ls.debug}.
+information file with build id content matching the build id content of the
+executable file - or - whose checksum matches the one given in the link in the
+debug link case.  In each case @value{GDBN} reads the debugging information
+from the first debug file it finds.
+
+So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, which has
+a @dfn{debug link} containing the name @file{ls.debug}, its @dfn{build id}
+value in hexadecimal is @code{abcdef} and the global debug directory is
+ at file{/usr/lib/debug}, then @value{GDBN} will look for debug information in
+ at file{/usr/lib/debug/.build-id/ab/cdef.debug}, @file{/usr/bin/ls.debug},
+ at file{/usr/bin/.debug/ls.debug}, and @file{/usr/lib/debug/usr/bin/ls.debug}.
 
 You can set the global debugging info directory's name, and view the
 name @value{GDBN} is currently using.
@@ -11933,6 +11949,16 @@ Any executable file format can carry a d
 contain a section named @code{.gnu_debuglink} with the contents
 described above.
 
+ at cindex @code{.note.gnu.build-id} sections
+ at cindex build id
+Build id is a special section of the executable file named
+ at code{.note.gnu.build-id}.  The section contains unique identification hash
+derived from the built files - it remains the same across multiple builds of
+the same build tree.  The default algorithm SHA1 produces 160 bits (40
+hexadecimal characters) of the content.  The same section and value is present
+in the original built binary with symbols, in its stripped variant and in the
+separate debug information file.
+
 The debugging information file itself should be an ordinary
 executable, containing a full set of linker symbols, sections, and
 debugging information.  The sections of the debugging information file
@@ -11940,18 +11966,21 @@ should have the same names, addresses an
 but they need not contain any data --- much like a @code{.bss} section
 in an ordinary executable.
 
-As of December 2002, there is no standard GNU utility to produce
-separated executable / debugging information file pairs.  Ulrich
-Drepper's @file{elfutils} package, starting with version 0.53,
-contains a version of the @code{strip} command such that the command
- at kbd{strip foo -f foo.debug} removes the debugging information from
-the executable file @file{foo}, places it in the file
- at file{foo.debug}, and leaves behind a debug link in @file{foo}.
-
-Since there are many different ways to compute CRC's (different
-polynomials, reversals, byte ordering, etc.), the simplest way to
-describe the CRC used in @code{.gnu_debuglink} sections is to give the
-complete code for a function that computes it:
+ at sc{gnu} binary utilities contain the @samp{objcopy} utility able to produce
+the separated executable / debugging information file pairs by commands
+ at kbd{objcopy --only-keep-debug foo foo.debug; strip -g foo; objcopy
+--add-gnu-debuglink="foo.debug" "foo"}.  These commands remove the debugging
+information from the executable file @file{foo}, place it in the file
+ at file{foo.debug}, and leave behind a debug link in @file{foo}.  Ulrich
+Drepper's @file{elfutils} package, starting with version 0.53, contains
+a version of the @code{strip} command such that the command @kbd{strip foo -f
+foo.debug} has the same functionality as the three commands above.
+
+Since there are many different ways to compute CRC's for the debug link
+(different polynomials, reversals, byte ordering, etc.).  This computation does
+not apply to the build id section.  The simplest way to describe the CRC used
+in @code{.gnu_debuglink} sections is to give the complete code for a function
+that computes it:
 
 @kindex gnu_debuglink_crc32
 @smallexample
diff -u -rup gdb-6.6-orig/gdb/symfile.c gdb-6.6/gdb/symfile.c
--- gdb-6.6-orig/gdb/symfile.c	2007-08-28 14:32:17.000000000 +0200
+++ gdb-6.6/gdb/symfile.c	2007-08-28 14:34:12.000000000 +0200
@@ -53,6 +53,7 @@
 #include "observer.h"
 #include "exec.h"
 #include "parser-defs.h"
+#include "elf-bfd.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -904,7 +905,7 @@ symbol_file_add_with_addrs_or_offsets (b
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
-  char *debugfile;
+  char *debugfile = NULL;
   struct section_addr_info *orig_addrs = NULL;
   struct cleanup *my_cleanups;
   const char *name = bfd_get_filename (abfd);
@@ -968,7 +969,11 @@ symbol_file_add_with_addrs_or_offsets (b
 	}
     }
 
-  debugfile = find_separate_debug_file (objfile);
+  /* If the file has its own symbol tables it has no separate debug info.
+     `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS.
+     `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'.  */
+  if (objfile->psymtabs == NULL)
+    debugfile = find_separate_debug_file (objfile);
   if (debugfile)
     {
       if (addrs != NULL)
@@ -1115,6 +1120,99 @@ symbol_file_clear (int from_tty)
       printf_unfiltered (_("No symbol file now.\n"));
 }
 
+struct build_id
+  {
+    size_t size;
+    gdb_byte data[1];
+  };
+
+/* Locate NT_GNU_BUILD_ID from ABFD and return its content.  */
+
+static struct build_id *
+build_id_bfd_get (bfd *abfd)
+{
+  struct build_id *retval;
+
+  if (!bfd_check_format (abfd, bfd_object)
+      || bfd_get_flavour (abfd) != bfd_target_elf_flavour
+      || elf_tdata (abfd)->build_id == NULL)
+    return NULL;
+
+  retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size);
+  retval->size = elf_tdata (abfd)->build_id_size;
+  memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size);
+
+  return retval;
+}
+
+/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value.  */
+
+static int
+build_id_verify (const char *filename, struct build_id *check)
+{
+  bfd *abfd;
+  struct build_id *found = NULL;
+  int retval = 0;
+
+  /* We expect to be silent on the non-existing files.  */
+  abfd = bfd_openr (filename, gnutarget);
+  if (abfd == NULL)
+    return 0;
+
+  found = build_id_bfd_get (abfd);
+
+  if (found == NULL)
+    warning (_("File \"%s\" has no build-id, file skipped"), filename);
+  else if (found->size != check->size
+           || memcmp (found->data, check->data, found->size) != 0)
+    warning (_("File \"%s\" has a different build-id, file skipped"), filename);
+  else
+    retval = 1;
+
+  if (!bfd_close (abfd))
+    warning (_("cannot close \"%s\": %s"), filename,
+	     bfd_errmsg (bfd_get_error ()));
+  return retval;
+}
+
+static char *debug_file_directory = NULL;
+
+static char *
+build_id_to_debug_filename (struct build_id *build_id)
+{
+  char *link, *s, *retval = NULL;
+  gdb_byte *data = build_id->data;
+  size_t size = build_id->size;
+
+  /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
+  link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
+		  + 2 * size + (sizeof ".debug" - 1) + 1);
+  s = link + sprintf (link, "%s/.build-id/", debug_file_directory);
+  if (size > 0)
+    {
+      size--;
+      s += sprintf (s, "%02x", (unsigned) *data++);
+    }
+  if (size > 0)
+    *s++ = '/';
+  while (size-- > 0)
+    s += sprintf (s, "%02x", (unsigned) *data++);
+  strcpy (s, ".debug");
+
+  /* lrealpath() is expensive even for the usually non-existent files.  */
+  if (access (link, F_OK) == 0)
+    retval = lrealpath (link);
+  xfree (link);
+
+  if (retval != NULL && !build_id_verify (retval, build_id))
+    {
+      xfree (retval);
+      retval = NULL;
+    }
+
+  return retval;
+}
+
 static char *
 get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
 {
@@ -1278,7 +1280,6 @@ separate_debug_file_exists (const char *
   return 1;
 }
 
-static char *debug_file_directory = NULL;
 static void
 show_debug_file_directory (struct ui_file *file, int from_tty,
 			   struct cmd_list_element *c, const char *value)
@@ -1207,6 +1303,25 @@ find_separate_debug_file (struct objfile
   bfd_size_type debuglink_size;
   unsigned long crc32;
   int i;
+  struct build_id *build_id;
+
+  build_id = build_id_bfd_get (objfile->obfd);
+  if (build_id != NULL)
+    {
+      char *build_id_name;
+
+      build_id_name = build_id_to_debug_filename (build_id);
+      free (build_id);
+      /* Prevent looping on a stripped .debug file.  */
+      if (build_id_name != NULL && strcmp (build_id_name, objfile->name) == 0)
+        {
+	  warning (_("\"%s\": separate debug info file has no debug info"),
+		   build_id_name);
+	  xfree (build_id_name);
+	}
+      else if (build_id_name != NULL)
+        return build_id_name;
+    }
 
   basename = get_debug_link_info (objfile, &crc32);
 
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.base/sepdebug.exp gdb-6.6/gdb/testsuite/gdb.base/sepdebug.exp
--- gdb-6.6-orig/gdb/testsuite/gdb.base/sepdebug.exp	2007-08-28 14:32:17.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.base/sepdebug.exp	2007-08-28 14:46:38.000000000 +0200
@@ -21,11 +21,14 @@
 
 # Based on break.exp, written by Rob Savoye. (rob at cygnus.com)
 # Modified to test gdb's handling of separate debug info files.
+# Modified to test gdb's handling of a debug-id retrieval.
 
 # This file has two parts. The first is testing that gdb behaves
 # normally after reading in an executable and its corresponding
 # separate debug file. The second moves the .debug file to a different
 # location and tests the "set debug-file-directory" command.
+# The third is for testing build-id retrievel by finding the separate
+# ".debug-id/ab/cdef.debug" file.
 
 
 if $tracelevel then {
@@ -851,110 +854,6 @@ proc test_next_with_recursion {} { 
 test_next_with_recursion
 
 
-#********
-
-# now move the .debug file to a different location so that we can test
-# the "set debug-file-directory" command.
-  
-remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}"
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_test "set debug-file-directory ${objdir}/${subdir}" ".*" "set separate debug location"
-gdb_load ${binfile}
-
-if [target_info exists gdb_stub] {
-    gdb_step_for_stub;
-}
-
-#
-# test break at function
-#
-gdb_test "break main" \
-    "Breakpoint.*at.* file .*$srcfile, line.*" \
-    "breakpoint function, optimized file"
-
-#
-# test break at function
-#
-gdb_test "break marker4" \
-    "Breakpoint.*at.* file .*$srcfile, line.*" \
-    "breakpoint small function, optimized file"
-
-#
-# run until the breakpoint at main is hit. For non-stubs-using targets.
-#
-if ![target_info exists use_gdb_stub] {
-  if [istarget "*-*-vxworks*"] then {
-    send_gdb "run vxmain \"2\"\n"
-    set timeout 120
-    verbose "Timeout is now $timeout seconds" 2
-  } else {
-	send_gdb "run\n"
-  }
-  gdb_expect {
-    -re "The program .* has been started already.*y or n. $" {
-	send_gdb "y\n"
-	exp_continue
-    }
-    -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $"\
-	                    { pass "run until function breakpoint, optimized file" }
-    -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $"\
-	                    { pass "run until function breakpoint, optimized file (code motion)" }
-    -re ".*$gdb_prompt $"       { fail "run until function breakpoint, optimized file" }
-    timeout	            { fail "run until function breakpoint, optimized file (timeout)" }
-  }
-} else {
-    if ![target_info exists gdb_stub] {
-	gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.*\{.*" "stub continue, optimized file"
-    }
-}
-
-#
-# run until the breakpoint at a small function
-#
-
-#
-# Add a second pass pattern.  The behavior differs here between stabs
-# and dwarf for one-line functions.  Stabs preserves two line symbols
-# (one before the prologue and one after) with the same line number, 
-# but dwarf regards these as duplicates and discards one of them.
-# Therefore the address after the prologue (where the breakpoint is)
-# has no exactly matching line symbol, and GDB reports the breakpoint
-# as if it were in the middle of a line rather than at the beginning.
-
-set bp_location13 [gdb_get_line_number "set breakpoint 13 here"]
-set bp_location14 [gdb_get_line_number "set breakpoint 14 here"]
-send_gdb "continue\n"
-gdb_expect {
-    -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
-	pass "run until breakpoint set at small function, optimized file"
-    }
-    -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
-	pass "run until breakpoint set at small function, optimized file"
-    }
-    -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
-        # marker4() is defined at line 46 when compiled with -DPROTOTYPES
-	pass "run until breakpoint set at small function, optimized file (line bp_location14)"
-    }
-    -re ".*$gdb_prompt " {
-	fail "run until breakpoint set at small function, optimized file"
-    }
-    timeout {
-	fail "run until breakpoint set at small function, optimized file (timeout)"
-    }
-}
-
-
-# Reset the default arguments for VxWorks
-if [istarget "*-*-vxworks*"] {
-    set timeout 10
-    verbose "Timeout is now $timeout seconds" 2
-    send_gdb "set args main\n"
-    gdb_expect -re ".*$gdb_prompt $" {}
-}
-
-
 # Compile up a second, different, object file.  Copy its debug info
 # over the top of the new debug info.  Note that somewhere in the
 # above the "set debug-file-directory" variable is set to
@@ -973,6 +872,7 @@ if [gdb_gnu_strip_debug $binfile] {
     unsupported "cannot produce separate debug info files"
     return -1
 }
+remote_exec build "cp ${existing_binfile}.debug ${existing_binfile}.debug-backup"
 remote_exec build "cp $corrupt_debug_file ${existing_binfile}.debug"
 
 gdb_exit
@@ -990,3 +890,188 @@ gdb_test_multiple "file $existing_binfil
 	exp_continue
     }
 }
+
+remote_exec build "cp ${existing_binfile}.debug-backup ${existing_binfile}.debug"
+
+#********
+
+proc test_different_dir {type test_different_dir xfail} {
+    global srcdir subdir objdir binfile srcfile timeout gdb_prompt
+    global pf_prefix
+    global bp_location6 decimal hex
+
+    set pf_prefix "$type:"
+
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_test "set debug-file-directory ${test_different_dir}" ".*" "set separate debug location"
+    gdb_load ${binfile}
+
+    if [target_info exists gdb_stub] {
+        gdb_step_for_stub;
+    }
+
+    #
+    # test break at function
+    #
+    if {$xfail} {
+        setup_xfail "*-*-*"
+    }
+    gdb_test "break main" \
+        "Breakpoint.*at.* file .*$srcfile, line.*" \
+        "breakpoint function, optimized file"
+
+    #
+    # test break at function
+    #
+    if {$xfail} {
+        setup_xfail "*-*-*"
+    }
+    gdb_test "break marker4" \
+        "Breakpoint.*at.* file .*$srcfile, line.*" \
+        "breakpoint small function, optimized file"
+
+    #
+    # run until the breakpoint at main is hit. For non-stubs-using targets.
+    #
+    gdb_run_cmd
+    if {$xfail} {
+        setup_xfail "*-*-*"
+    }
+    gdb_expect {
+        -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" {
+            pass "run until function breakpoint, optimized file"
+        }
+        -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" {
+            pass "run until function breakpoint, optimized file (code motion)"
+        }
+        -re "$gdb_prompt $" {
+            fail "run until function breakpoint, optimized file"
+        }
+        timeout {
+            fail "run until function breakpoint, optimized file (timeout)"
+        }
+    }
+
+    if ![target_info exists use_gdb_stub] {
+      if [istarget "*-*-vxworks*"] then {
+        send_gdb "run vxmain \"2\"\n"
+        set timeout 120
+        verbose "Timeout is now $timeout seconds" 2
+      } else {
+            send_gdb "run\n"
+      }
+      if {$xfail} {
+        setup_xfail "*-*-*"
+      }
+      gdb_expect {
+        -re "The program .* has been started already.*y or n. $" {
+            send_gdb "y\n"
+            exp_continue
+        }
+        -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $"\
+                                { pass "run until function breakpoint, optimized file" }
+        -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $"\
+                                { pass "run until function breakpoint, optimized file (code motion)" }
+        -re ".*$gdb_prompt $"       { fail "run until function breakpoint, optimized file" }
+        timeout                    { fail "run until function breakpoint, optimized file (timeout)" }
+      }
+    } else {
+        if ![target_info exists gdb_stub] {
+            gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.*\{.*" "stub continue, optimized file"
+        }
+    }
+
+
+
+    #
+    # run until the breakpoint at a small function
+    #
+
+    #
+    # Add a second pass pattern.  The behavior differs here between stabs
+    # and dwarf for one-line functions.  Stabs preserves two line symbols
+    # (one before the prologue and one after) with the same line number, 
+    # but dwarf regards these as duplicates and discards one of them.
+    # Therefore the address after the prologue (where the breakpoint is)
+    # has no exactly matching line symbol, and GDB reports the breakpoint
+    # as if it were in the middle of a line rather than at the beginning.
+
+    set bp_location13 [gdb_get_line_number "set breakpoint 13 here"]
+    set bp_location14 [gdb_get_line_number "set breakpoint 14 here"]
+    send_gdb "continue\n"
+    if {$xfail} {
+        setup_xfail "*-*-*"
+    }
+    gdb_expect {
+        -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
+            pass "run until breakpoint set at small function, optimized file"
+        }
+        -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
+            pass "run until breakpoint set at small function, optimized file"
+        }
+        -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
+            # marker4() is defined at line 46 when compiled with -DPROTOTYPES
+            pass "run until breakpoint set at small function, optimized file (line bp_location14)"
+        }
+        -re ".*$gdb_prompt " {
+            fail "run until breakpoint set at small function, optimized file"
+        }
+        timeout {
+            fail "run until breakpoint set at small function, optimized file (timeout)"
+        }
+    }
+
+
+    # Reset the default arguments for VxWorks
+    if [istarget "*-*-vxworks*"] {
+        set timeout 10
+        verbose "Timeout is now $timeout seconds" 2
+        send_gdb "set args main\n"
+        gdb_expect -re ".*$gdb_prompt $" {}
+    }
+
+    unset pf_prefix
+# proc test_different_dir
+}
+
+
+# now move the .debug file to a different location so that we can test
+# the "set debug-file-directory" command.
+  
+remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}"
+set debugfile "${objdir}/${subdir}/${testfile}.debug"
+
+test_different_dir debuglink "${objdir}/${subdir}" 0
+
+
+# NT_GNU_BUILD_ID / .note.gnu.build-id test:
+
+set build_id_debug_filename [build_id_debug_filename_get $binfile]
+if {$build_id_debug_filename eq ""} {
+    unsupported "build-id is not supported by the compiler"
+
+    # Spare debug files may confuse testsuite runs in the future.
+    remote_exec build "rm -f $debugfile"
+} else {
+    set build_id_debugself_filename [build_id_debug_filename_get $debugfile]
+    set test "build-id support by binutils"
+    set xfail 0
+    if {$build_id_debugself_filename eq ""} {
+        unsupported $test
+        set xfail 1
+    } elseif {$build_id_debugself_filename ne $build_id_debug_filename} {
+        fail $test
+    } else {
+        pass $test
+    }
+
+    file mkdir [file dirname ${objdir}/${subdir}/${build_id_debug_filename}]
+    remote_exec build "mv $debugfile ${objdir}/${subdir}/${build_id_debug_filename}"
+
+    test_different_dir build-id "${objdir}/${subdir}" $xfail
+
+    # Spare debug files may confuse testsuite runs in the future.
+    remote_exec build "rm -f ${objdir}/${subdir}/${build_id_debug_filename}"
+}
diff -u -rup gdb-6.6-orig/gdb/testsuite/lib/gdb.exp gdb-6.6/gdb/testsuite/lib/gdb.exp
--- gdb-6.6-orig/gdb/testsuite/lib/gdb.exp	2007-08-28 14:32:18.000000000 +0200
+++ gdb-6.6/gdb/testsuite/lib/gdb.exp	2007-08-28 14:33:03.000000000 +0200
@@ -2323,6 +2323,27 @@ proc separate_debug_filename { exec } {
     return $debug_file
 }
 
+# Return the build-id hex string (usually 160 bits as 40 hex characters)
+# converted to the form: .build-id/ab/cdef1234...89.debug
+# Return "" if no build-id found.
+proc build_id_debug_filename_get { exec } {
+    set tmp "${exec}-tmp"
+    exec objcopy -j .note.gnu.build-id -O binary $exec $tmp
+    set fi [open $tmp]
+    # Skip the NOTE header.
+    read $fi 16
+    set data [read $fi]
+    close $fi
+    file delete $tmp
+    if {$data eq ""} {
+	return ""
+    }
+    # Convert it to hex.
+    binary scan $data H* data
+    set data [regsub {^..} $data {\0/}]
+    return ".build-id/${data}.debug";
+}
+
 # Create stripped files for DEST, replacing it.  If ARGS is passed, it is a
 # list of optional flags.  The only currently supported flag is no-main,
 # which removes the symbol entry for main from the separate debug file.
--- gdb-6.6/gdb/testsuite/gdb.base/sepdebug.exp	2007-08-28 15:27:36.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.base/sepdebug.exp	2007-08-28 15:25:23.000000000 +0200
@@ -860,14 +860,14 @@ test_next_with_recursion
 # ${objdir}/${subdir} so need to move things there.
 
 set existing_binfile $binfile
-set testfile "sepdebug2"
-set srcfile ${testfile}.c
-set binfile ${objdir}/${subdir}/${testfile}
-set corrupt_debug_file [separate_debug_filename $binfile]
-if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-w}] != "" } {
+set testfile2 "sepdebug2"
+set srcfile2 ${testfile2}.c
+set binfile2 ${objdir}/${subdir}/${testfile2}
+set corrupt_debug_file [separate_debug_filename $binfile2]
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug additional_flags=-w}] != "" } {
     return -1
 }
-if [gdb_gnu_strip_debug $binfile] {
+if [gdb_gnu_strip_debug $binfile2] {
     # check that you have a recent version of strip and objcopy installed
     unsupported "cannot produce separate debug info files"
     return -1

gdb-6.6-upstream.patch:

Index: gdb-6.6-upstream.patch
===================================================================
RCS file: /cvs/pkgs/rpms/gdb/devel/gdb-6.6-upstream.patch,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- gdb-6.6-upstream.patch	7 Jun 2007 18:31:29 -0000	1.6
+++ gdb-6.6-upstream.patch	28 Aug 2007 14:46:38 -0000	1.7
@@ -882,3 +882,254 @@
                }
  	      break;
  	    case DW_LNS_set_column:
+
+
+
+http://sourceware.org/ml/binutils/2007-08/msg00296.html
+
+[ Backported for GDB-6.6. ]
+
+2007-08-19  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* bfd/elf-bfd.h (struct elf_obj_tdata): New build_id_size, build_id.
+	* bfd/elf.c (elfcore_read_notes): Split to ...
+	(elf_read_notes) ... here ...
+	(elf_parse_notes): ... and here.  Check `bfd_get_format (abfd)' with
+	the former subfunctions called only for BFD_CORE.
+	Call ELFOBJ_GROK_GNU_NOTE for BFD_OBJECT files with the owner "GNU".
+	(_bfd_elf_make_section_from_shdr): Call ELF_PARSE_NOTES for SHT_NOTEs.
+	(bfd_section_from_phdr): Update the call for renamed ELFCORE_READ_NOTES.
+	(elfobj_grok_gnu_build_id, elfobj_grok_gnu_note): New functions.
+	Code advisory: Roland McGrath
+
+--- gdb-6.6/bfd/elf-bfd.h.orig	2006-11-02 16:20:31.000000000 +0100
++++ gdb-6.6/bfd/elf-bfd.h	2007-08-28 15:00:42.000000000 +0200
+@@ -1408,6 +1408,10 @@ struct elf_obj_tdata
+ 
+   /* Symbol buffer.  */
+   Elf_Internal_Sym *symbuf;
++
++  /* NT_GNU_BUILD_ID note type.  */
++  bfd_size_type build_id_size;
++  bfd_byte *build_id;
+ };
+ 
+ #define elf_tdata(bfd)		((bfd) -> tdata.elf_obj_data)
+--- ./bfd/elf.c	16 Aug 2007 18:49:42 -0000	1.410
++++ ./bfd/elf.c	19 Aug 2007 20:12:16 -0000
+@@ -48,7 +48,9 @@ static int elf_sort_sections (const void
+ static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
+ static bfd_boolean prep_headers (bfd *);
+ static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
+-static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ;
++static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
++static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
++				    file_ptr offset);
+ 
+ /* Swap version information in and out.  The version information is
+    currently size independent.  If that ever changes, this code will
+@@ -899,6 +901,28 @@ _bfd_elf_make_section_from_shdr (bfd *ab
+   if (! bfd_set_section_flags (abfd, newsect, flags))
+     return FALSE;
+ 
++  /* We do not parse the PT_NOTE segments as we are interested even in the
++     separate debug info files which may have the segments offsets corrupted.
++     PT_NOTEs from the core files are currently not parsed using BFD.  */
++  if (hdr->sh_type == SHT_NOTE)
++    {
++      char *contents;
++
++      contents = bfd_malloc (hdr->sh_size);
++      if (!contents)
++	return FALSE;
++
++      if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
++				     hdr->sh_size)
++	  || !elf_parse_notes (abfd, contents, hdr->sh_size, -1))
++	{
++	  free (contents);
++	  return FALSE;
++	}
++      
++      free (contents);
++    }
++
+   if ((flags & SEC_ALLOC) != 0)
+     {
+       Elf_Internal_Phdr *phdr;
+@@ -2341,7 +2365,7 @@ bfd_section_from_phdr (bfd *abfd, Elf_In
+     case PT_NOTE:
+       if (! _bfd_elf_make_section_from_phdr (abfd, hdr, index, "note"))
+ 	return FALSE;
+-      if (! elfcore_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
++      if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
+ 	return FALSE;
+       return TRUE;
+ 
+@@ -7713,6 +7737,32 @@ elfcore_grok_note (bfd *abfd, Elf_Intern
+ }
+ 
+ static bfd_boolean
++elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
++{
++  elf_tdata (abfd)->build_id_size = note->descsz;
++  elf_tdata (abfd)->build_id = bfd_alloc (abfd, note->descsz);
++  if (elf_tdata (abfd)->build_id == NULL)
++    return FALSE;
++
++  memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz);
++
++  return TRUE;
++}
++
++static bfd_boolean
++elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
++{
++  switch (note->type)
++    {
++    default:
++      return TRUE;
++
++    case NT_GNU_BUILD_ID:
++      return elfobj_grok_gnu_build_id (abfd, note);
++    }
++}
++
++static bfd_boolean
+ elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
+ {
+   char *cp;
+@@ -8186,28 +8236,10 @@ elfcore_write_prxfpreg (bfd *abfd,
+ }
+ 
+ static bfd_boolean
+-elfcore_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
++elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
+ {
+-  char *buf;
+   char *p;
+ 
+-  if (size <= 0)
+-    return TRUE;
+-
+-  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
+-    return FALSE;
+-
+-  buf = bfd_malloc (size);
+-  if (buf == NULL)
+-    return FALSE;
+-
+-  if (bfd_bread (buf, size, abfd) != size)
+-    {
+-    error:
+-      free (buf);
+-      return FALSE;
+-    }
+-
+   p = buf;
+   while (p < buf + size)
+     {
+@@ -8312,25 +8344,66 @@ elfcore_read_notes (bfd *abfd, file_ptr 
+       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
+       in.descpos = offset + (in.descdata - buf);
+ 
+-      if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
++      switch (bfd_get_format (abfd))
+         {
+-          if (! elfcore_grok_netbsd_note (abfd, &in))
+-            goto error;
+-        }
+-      else if (CONST_STRNEQ (in.namedata, "QNX"))
+-	{
+-	  if (! elfcore_grok_nto_note (abfd, &in))
+-	    goto error;
++	default:
++	  return TRUE;
++
++	case bfd_core:
++	  if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
++	    {
++	      if (! elfcore_grok_netbsd_note (abfd, &in))
++		return FALSE;
++	    }
++	  else if (CONST_STRNEQ (in.namedata, "QNX"))
++	    {
++	      if (! elfcore_grok_nto_note (abfd, &in))
++		return FALSE;
++	    }
++	  else
++	    {
++	      if (! elfcore_grok_note (abfd, &in))
++		return FALSE;
++	    }
++	  break;
++
++	case bfd_object:
++	  if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
++	    {
++	      if (! elfobj_grok_gnu_note (abfd, &in))
++		return FALSE;
++	    }
++	  break;
+ 	}
+-      else
+-        {
+-          if (! elfcore_grok_note (abfd, &in))
+-            goto error;
+-        }
+ 
+       p = in.descdata + BFD_ALIGN (in.descsz, 4);
+     }
+ 
++  return TRUE;
++}
++
++static bfd_boolean
++elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
++{
++  char *buf;
++
++  if (size <= 0)
++    return TRUE;
++
++  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
++    return FALSE;
++
++  buf = bfd_malloc (size);
++  if (buf == NULL)
++    return FALSE;
++
++  if (bfd_bread (buf, size, abfd) != size
++      || !elf_parse_notes (abfd, buf, size, offset))
++    {
++      free (buf);
++      return FALSE;
++    }
++
+   free (buf);
+   return TRUE;
+ }
+
+
+
+2007-07-09  Roland McGrath  <roland at redhat.com>
+
+	* common.h (NT_GNU_HWCAP, NT_GNU_BUILD_ID): New macros.
+
+--- ./include/elf/common.h	29 Jun 2007 16:29:16 -0000	1.85
++++ ./include/elf/common.h	9 Jul 2007 21:17:42 -0000	1.86
+@@ -413,9 +413,13 @@
+ #define NT_VERSION	1		/* Contains a version string.  */
+ #define NT_ARCH		2		/* Contains an architecture string.  */
+ 
+-/* Values for GNU .note.ABI-tag notes.  Note name is "GNU".  */
++/* Values for notes in non-core files using name "GNU".  */
+ 
+ #define NT_GNU_ABI_TAG		1
++#define NT_GNU_HWCAP		2	/* Used by ld.so and kernel vDSO.  */
++#define NT_GNU_BUILD_ID		3	/* Generated by ld --build-id.  */
++
++/* Values used in GNU .note.ABI-tag notes (NT_GNU_ABI_TAG).  */
+ #define GNU_ABI_TAG_LINUX	0
+ #define GNU_ABI_TAG_HURD	1
+ #define GNU_ABI_TAG_SOLARIS	2


Index: gdb.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gdb/devel/gdb.spec,v
retrieving revision 1.242
retrieving revision 1.243
diff -u -r1.242 -r1.243
--- gdb.spec	17 Aug 2007 14:37:20 -0000	1.242
+++ gdb.spec	28 Aug 2007 14:46:38 -0000	1.243
@@ -11,7 +11,7 @@
 Version: 6.6
 
 # The release always contains a leading reserved number, start it at 1.
-Release: 25%{?dist}
+Release: 26%{?dist}
 
 License: GPL
 Group: Development/Debuggers
@@ -369,6 +369,11 @@
 # Fixed compatibility with the Rawhide glibc open(2) syscall sanity checking.
 Patch272: gdb-6.6-glibc-open-fcntl2-compat.patch
 
+# New fast verification whether the .debug file matches its peer (build-id).
+# New locating of the matching binaries from the pure core file (build-id).
+Patch273: gdb-6.6-buildid-verify.patch
+Patch274: gdb-6.6-buildid-locate.patch
+
 BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext
 BuildRequires: flex bison sharutils expat-devel
 Requires: readline
@@ -522,6 +527,8 @@
 %patch266 -p1
 %patch269 -p1
 %patch272 -p1
+%patch273 -p1
+%patch274 -p1
 
 # Change the version that gets printed at GDB startup, so it is RedHat
 # specific.
@@ -676,6 +683,10 @@
 # don't include the files in include, they are part of binutils
 
 %changelog
+* Tue Aug 28 2007 Jan Kratochvil <jan.kratochvil at redhat.com> - 6.6-26
+- New fast verification whether the .debug file matches its peer (build-id).
+- New locating of the matching binaries from the pure core file (build-id).
+
 * Fri Aug 17 2007 Jan Kratochvil <jan.kratochvil at redhat.com> - 6.6-25
 - Fixed excessive RPATH (related to BZ 228891).
 




More information about the fedora-extras-commits mailing list