[gdb/f14/master] - Fix discontiguous address ranges in .gdb_index - v3->v4 (BZ 672281).

Jan Kratochvil jankratochvil at fedoraproject.org
Tue Jan 25 18:20:50 UTC 2011


commit 310918247eea65242e9ffce45ef132d7d70c7e8c
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Tue Jan 25 19:20:34 2011 +0100

    - Fix discontiguous address ranges in .gdb_index - v3->v4 (BZ 672281).

 gdb-gdbindex-v4-1of3.patch |  237 ++++++++++++++++++++++++++++++++++++++++++++
 gdb-gdbindex-v4-2of3.patch |   53 ++++++++++
 gdb-gdbindex-v4-3of3.patch |  145 +++++++++++++++++++++++++++
 gdb.spec                   |   17 +++-
 4 files changed, 451 insertions(+), 1 deletions(-)
---
diff --git a/gdb-gdbindex-v4-1of3.patch b/gdb-gdbindex-v4-1of3.patch
new file mode 100644
index 0000000..e46cb73
--- /dev/null
+++ b/gdb-gdbindex-v4-1of3.patch
@@ -0,0 +1,237 @@
+http://sourceware.org/ml/gdb-cvs/2010-12/msg00031.html
+
+### src/gdb/ChangeLog	2010/12/08 18:26:40	1.12364
+### src/gdb/ChangeLog	2010/12/08 19:03:34	1.12365
+## -1,5 +1,15 @@
+ 2010-12-08  Doug Evans  <dje at google.com>
+ 
++	PR symtab/12302
++	* dwarf2read.c (struct psymtab_cu_index_map): New struct.
++	(hash_psymtab_cu_index, eq_psymtab_cu_index): New functions.
++	(struct addrmap_index_data): New struct.
++	(add_address_entry): Remove arg `pst', new args `start', `end'.
++	(add_address_entry_worker, write_address_map): New functions.
++	(write_psymtabs_to_index): Address table generation moved to
++	write_address_map.  Build a table mapping psymtab to CU index
++	to pass to it.
++
+ 	* dwarf2read.c (write_psymtabs_to_index): When stat fails, pass file
+ 	name to perror.
+ 
+Index: gdb-7.2/gdb/dwarf2read.c
+===================================================================
+--- gdb-7.2.orig/gdb/dwarf2read.c	2011-01-25 18:48:52.000000000 +0100
++++ gdb-7.2/gdb/dwarf2read.c	2011-01-25 18:56:43.000000000 +0100
+@@ -14662,30 +14662,129 @@ write_hash_table (struct mapped_symtab *
+   htab_delete (index_table);
+ }
+ 
+-/* Write an address entry to ADDR_OBSTACK.  The addresses are taken
+-   from PST; CU_INDEX is the index of the CU in the vector of all
+-   CUs.  */
++/* Struct to map psymtab to CU index in the index file.  */
++struct psymtab_cu_index_map
++{
++  struct partial_symtab *psymtab;
++  unsigned int cu_index;
++};
++
++static hashval_t
++hash_psymtab_cu_index (const void *item)
++{
++  const struct psymtab_cu_index_map *map = item;
++
++  return htab_hash_pointer (map->psymtab);
++}
++
++static int
++eq_psymtab_cu_index (const void *item_lhs, const void *item_rhs)
++{
++  const struct psymtab_cu_index_map *lhs = item_lhs;
++  const struct psymtab_cu_index_map *rhs = item_rhs;
++
++  return lhs->psymtab == rhs->psymtab;
++}
++
++/* Helper struct for building the address table.  */
++struct addrmap_index_data
++{
++  struct objfile *objfile;
++  struct obstack *addr_obstack;
++  htab_t cu_index_htab;
++
++  /* Non-zero if the previous_* fields are valid.
++     We can't write an entry until we see the next entry (since it is only then
++     that we know the end of the entry).  */
++  int previous_valid;
++  /* Index of the CU in the table of all CUs in the index file.  */
++  unsigned int previous_cu_index;
++  /* Start address of the CU. */
++  CORE_ADDR previous_cu_start;
++};
++
++/* Write an address entry to OBSTACK.  */
++
+ static void
+-add_address_entry (struct objfile *objfile,
+-		   struct obstack *addr_obstack, struct partial_symtab *pst,
+-		   unsigned int cu_index)
++add_address_entry (struct objfile *objfile, struct obstack *obstack,
++		   CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
+ {
+-  offset_type offset;
++  offset_type cu_index_to_write;
+   char addr[8];
+   CORE_ADDR baseaddr;
+ 
+-  /* Don't bother recording empty ranges.  */
+-  if (pst->textlow == pst->texthigh)
+-    return;
+-
+   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ 
+-  store_unsigned_integer (addr, 8, BFD_ENDIAN_LITTLE, pst->textlow - baseaddr);
+-  obstack_grow (addr_obstack, addr, 8);
+-  store_unsigned_integer (addr, 8, BFD_ENDIAN_LITTLE, pst->texthigh - baseaddr);
+-  obstack_grow (addr_obstack, addr, 8);
+-  offset = MAYBE_SWAP (cu_index);
+-  obstack_grow (addr_obstack, &offset, sizeof (offset_type));
++  store_unsigned_integer (addr, 8, BFD_ENDIAN_LITTLE, start - baseaddr);
++  obstack_grow (obstack, addr, 8);
++  store_unsigned_integer (addr, 8, BFD_ENDIAN_LITTLE, end - baseaddr);
++  obstack_grow (obstack, addr, 8);
++  cu_index_to_write = MAYBE_SWAP (cu_index);
++  obstack_grow (obstack, &cu_index_to_write, sizeof (offset_type));
++}
++
++/* Worker function for traversing an addrmap to build the address table.  */
++
++static int
++add_address_entry_worker (void *datap, CORE_ADDR start_addr, void *obj)
++{
++  struct addrmap_index_data *data = datap;
++  struct partial_symtab *pst = obj;
++  offset_type cu_index;
++  void **slot;
++
++  if (data->previous_valid)
++    add_address_entry (data->objfile, data->addr_obstack,
++		       data->previous_cu_start, start_addr,
++		       data->previous_cu_index);
++
++  data->previous_cu_start = start_addr;
++  if (pst != NULL)
++    {
++      struct psymtab_cu_index_map find_map, *map;
++      find_map.psymtab = pst;
++      map = htab_find (data->cu_index_htab, &find_map);
++      gdb_assert (map != NULL);
++      data->previous_cu_index = map->cu_index;
++      data->previous_valid = 1;
++    }
++  else
++      data->previous_valid = 0;
++
++  return 0;
++}
++
++/* Write OBJFILE's address map to OBSTACK.
++   CU_INDEX_HTAB is used to map addrmap entries to their CU indices
++   in the index file.  */
++
++static void
++write_address_map (struct objfile *objfile, struct obstack *obstack,
++		   htab_t cu_index_htab)
++{
++  struct addrmap_index_data addrmap_index_data;
++
++  /* When writing the address table, we have to cope with the fact that
++     the addrmap iterator only provides the start of a region; we have to
++     wait until the next invocation to get the start of the next region.  */
++
++  addrmap_index_data.objfile = objfile;
++  addrmap_index_data.addr_obstack = obstack;
++  addrmap_index_data.cu_index_htab = cu_index_htab;
++  addrmap_index_data.previous_valid = 0;
++
++  addrmap_foreach (objfile->psymtabs_addrmap, add_address_entry_worker,
++		   &addrmap_index_data);
++
++  /* It's highly unlikely the last entry (end address = 0xff...ff)
++     is valid, but we should still handle it.
++     The end address is recorded as the start of the next region, but that
++     doesn't work here.  To cope we pass 0xff...ff, this is a rare situation
++     anyway.  */
++  if (addrmap_index_data.previous_valid)
++    add_address_entry (objfile, obstack,
++		       addrmap_index_data.previous_cu_start, (CORE_ADDR) -1,
++		       addrmap_index_data.previous_cu_index);
+ }
+ 
+ /* Add a list of partial symbols to SYMTAB.  */
+@@ -14813,6 +14912,8 @@ write_psymtabs_to_index (struct objfile 
+   struct stat st;
+   char buf[8];
+   htab_t psyms_seen;
++  htab_t cu_index_htab;
++  struct psymtab_cu_index_map *psymtab_cu_index_map;
+ 
+   if (!objfile->psymtabs)
+     return;
+@@ -14849,7 +14950,21 @@ write_psymtabs_to_index (struct objfile 
+ 				  NULL, xcalloc, xfree);
+   make_cleanup (cleanup_htab, psyms_seen);
+ 
+-  /* The list is already sorted, so we don't need to do additional
++  /* While we're scanning CU's create a table that maps a psymtab pointer
++     (which is what addrmap records) to its index (which is what is recorded
++     in the index file).  This will later be needed to write the address
++     table.  */
++  cu_index_htab = htab_create_alloc (100,
++				     hash_psymtab_cu_index,
++				     eq_psymtab_cu_index,
++				     NULL, xcalloc, xfree);
++  make_cleanup (cleanup_htab, cu_index_htab);
++  psymtab_cu_index_map = (struct psymtab_cu_index_map *)
++    xmalloc (sizeof (struct psymtab_cu_index_map)
++	     * dwarf2_per_objfile->n_comp_units);
++  make_cleanup (xfree, psymtab_cu_index_map);
++
++  /* The CU list is already sorted, so we don't need to do additional
+      work here.  Also, the debug_types entries do not appear in
+      all_comp_units, but only in their own hash table.  */
+   for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+@@ -14857,6 +14972,8 @@ write_psymtabs_to_index (struct objfile 
+       struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+       struct partial_symtab *psymtab = cu->v.psymtab;
+       gdb_byte val[8];
++      struct psymtab_cu_index_map *map;
++      void **slot;
+ 
+       write_psymbols (symtab,
+ 		      psyms_seen,
+@@ -14869,7 +14986,13 @@ write_psymtabs_to_index (struct objfile 
+ 		      psymtab->n_static_syms, i,
+ 		      1);
+ 
+-      add_address_entry (objfile, &addr_obstack, psymtab, i);
++      map = &psymtab_cu_index_map[i];
++      map->psymtab = psymtab;
++      map->cu_index = i;
++      slot = htab_find_slot (cu_index_htab, map, INSERT);
++      gdb_assert (slot != NULL);
++      gdb_assert (*slot == NULL);
++      *slot = map;
+ 
+       store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, cu->offset);
+       obstack_grow (&cu_list, val, 8);
+@@ -14877,6 +15000,9 @@ write_psymtabs_to_index (struct objfile 
+       obstack_grow (&cu_list, val, 8);
+     }
+ 
++  /* Dump the address map.  */
++  write_address_map (objfile, &addr_obstack, cu_index_htab);
++
+   /* Write out the .debug_type entries, if any.  */
+   if (dwarf2_per_objfile->signatured_types)
+     {
diff --git a/gdb-gdbindex-v4-2of3.patch b/gdb-gdbindex-v4-2of3.patch
new file mode 100644
index 0000000..57a072f
--- /dev/null
+++ b/gdb-gdbindex-v4-2of3.patch
@@ -0,0 +1,53 @@
+http://sourceware.org/ml/gdb-cvs/2011-01/msg00169.html
+
+### src/gdb/ChangeLog	2011/01/25 17:00:23	1.12503
+### src/gdb/ChangeLog	2011/01/25 17:25:10	1.12504
+## -1,3 +1,8 @@
++2011-01-25  Jan Kratochvil  <jan.kratochvil at redhat.com>
++
++	* dwarf2read.c (dwarf2_read_index, write_psymtabs_to_index)
++	(save_gdb_index_command): Switch to .gdb_index version 4.
++
+ 2011-01-25  Pedro Alves  <pedro at codesourcery.com>
+ 
+ 	* mi/mi-main.c (get_register): Use get_frame_register_value rather
+Index: gdb-7.2/gdb/dwarf2read.c
+===================================================================
+--- gdb-7.2.orig/gdb/dwarf2read.c	2011-01-25 18:56:43.000000000 +0100
++++ gdb-7.2/gdb/dwarf2read.c	2011-01-25 18:57:45.000000000 +0100
+@@ -1905,9 +1905,14 @@ dwarf2_read_index (struct objfile *objfi
+   /* Version check.  */
+   version = MAYBE_SWAP (*(offset_type *) addr);
+   /* Versions earlier than 3 emitted every copy of a psymbol.  This
+-     causes the index to behave very poorly for certain requests.  So,
+-     it seems better to just ignore such indices.  */
+-  if (version < 3)
++     causes the index to behave very poorly for certain requests.  Version 4
++     contained incomplete addrmap.  So, it seems better to just ignore such
++     indices.  */
++  if (version < 4)
++    return 0;
++  /* Indexes with higher version than the one supported by GDB may be no
++     longer backward compatible.  */
++  if (version > 4)
+     return 0;
+ 
+   map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+@@ -15029,7 +15034,7 @@ write_psymtabs_to_index (struct objfile 
+   total_len = size_of_contents;
+ 
+   /* The version number.  */
+-  val = MAYBE_SWAP (3);
++  val = MAYBE_SWAP (4);
+   obstack_grow (&contents, &val, sizeof (val));
+ 
+   /* The offset of the CU list from the start of the file.  */
+@@ -15087,7 +15092,7 @@ write_psymtabs_to_index (struct objfile 
+    1. The file header.  This is a sequence of values, of offset_type
+    unless otherwise noted:
+ 
+-   [0] The version number, currently 3.  Versions 1 and 2 are
++   [0] The version number, currently 4.  Versions 1, 2 and 3 are
+    obsolete.
+    [1] The offset, from the start of the file, of the CU list.
+    [2] The offset, from the start of the file, of the types CU list.
diff --git a/gdb-gdbindex-v4-3of3.patch b/gdb-gdbindex-v4-3of3.patch
new file mode 100644
index 0000000..39060c6
--- /dev/null
+++ b/gdb-gdbindex-v4-3of3.patch
@@ -0,0 +1,145 @@
+http://sourceware.org/ml/gdb-cvs/2010-10/msg00048.html
+
+### src/gdb/ChangeLog	2010/10/07 08:32:36	1.12241
+### src/gdb/ChangeLog	2010/10/07 17:02:06	1.12242
+## -1,3 +1,16 @@
++2010-10-07  Doug Evans  <dje at google.com>
++
++	* addrmap.h (addrmap_foreach_fn): New typedef.
++	(addrmap_foreach): Declare.
++	* addrmap.c (struct addrmap_funcs): New member foreach.
++	(addrmap_foreach): New function.
++	(addrmap_fixed_foreach): New function.
++	(addrmap_fixed_funcs): Update.
++	(struct mutable_foreach_data): New struct.
++	(addrmap_mutable_foreach_worker): New function.
++	(addrmap_mutable_foreach): New function.
++	(addrmap_mutable_funcs): Update.
++
+ 2010-10-07  Paul Hilfinger  <hilfinger at adacore.com>
+ 
+ 	* dictionary.c (dict_hash): Revert to msymbol_hash_iw in
+--- src/gdb/addrmap.c	2010/05/18 19:23:37	1.8
++++ src/gdb/addrmap.c	2010/10/07 17:02:14	1.9
+@@ -41,6 +41,7 @@
+   struct addrmap *(*create_fixed) (struct addrmap *this,
+                                    struct obstack *obstack);
+   void (*relocate) (struct addrmap *this, CORE_ADDR offset);
++  int (*foreach) (struct addrmap *this, addrmap_foreach_fn fn, void *data);
+ };
+ 
+ 
+@@ -82,6 +83,11 @@
+ }
+ 
+ 
++int
++addrmap_foreach (struct addrmap *map, addrmap_foreach_fn fn, void *data)
++{
++  return map->funcs->foreach (map, fn, data);
++}
+ 
+ /* Fixed address maps.  */
+ 
+@@ -175,12 +181,32 @@
+ }
+ 
+ 
++static int
++addrmap_fixed_foreach (struct addrmap *this, addrmap_foreach_fn fn,
++		       void *data)
++{
++  struct addrmap_fixed *map = (struct addrmap_fixed *) this;
++  size_t i;
++
++  for (i = 0; i < map->num_transitions; i++)
++    {
++      int res = fn (data, map->transitions[i].addr, map->transitions[i].value);
++
++      if (res != 0)
++	return res;
++    }
++
++  return 0;
++}
++
++
+ static const struct addrmap_funcs addrmap_fixed_funcs =
+ {
+   addrmap_fixed_set_empty,
+   addrmap_fixed_find,
+   addrmap_fixed_create_fixed,
+-  addrmap_fixed_relocate
++  addrmap_fixed_relocate,
++  addrmap_fixed_foreach
+ };
+ 
+ 
+@@ -444,12 +470,48 @@
+ }
+ 
+ 
++/* Struct to map addrmap's foreach function to splay_tree's version.  */
++struct mutable_foreach_data
++{
++  addrmap_foreach_fn fn;
++  void *data;
++};
++
++
++/* This is a splay_tree_foreach_fn.  */
++
++static int
++addrmap_mutable_foreach_worker (splay_tree_node node, void *data)
++{
++  struct mutable_foreach_data *foreach_data = data;
++
++  return foreach_data->fn (foreach_data->data,
++			   addrmap_node_key (node),
++			   addrmap_node_value (node));
++}
++
++
++static int
++addrmap_mutable_foreach (struct addrmap *this, addrmap_foreach_fn fn,
++			 void *data)
++{
++  struct addrmap_mutable *mutable = (struct addrmap_mutable *) this;
++  struct mutable_foreach_data foreach_data;
++
++  foreach_data.fn = fn;
++  foreach_data.data = data;
++  return splay_tree_foreach (mutable->tree, addrmap_mutable_foreach_worker,
++			     &foreach_data);
++}
++
++
+ static const struct addrmap_funcs addrmap_mutable_funcs =
+ {
+   addrmap_mutable_set_empty,
+   addrmap_mutable_find,
+   addrmap_mutable_create_fixed,
+-  addrmap_mutable_relocate
++  addrmap_mutable_relocate,
++  addrmap_mutable_foreach
+ };
+ 
+ 
+--- src/gdb/addrmap.h	2010/01/01 07:31:29	1.5
++++ src/gdb/addrmap.h	2010/10/07 17:02:14	1.6
+@@ -91,4 +91,15 @@
+    to either mutable or immutable maps.)  */
+ void addrmap_relocate (struct addrmap *map, CORE_ADDR offset);
+ 
++/* The type of a function used to iterate over the map.
++   OBJ is NULL for unmapped regions.  */
++typedef int (*addrmap_foreach_fn) (void *data, CORE_ADDR start_addr,
++				   void *obj);
++
++/* Call FN, passing it DATA, for every address in MAP, following an
++   in-order traversal.  If FN ever returns a non-zero value, the
++   iteration ceases immediately, and the value is returned.
++   Otherwise, this function returns 0.  */
++int addrmap_foreach (struct addrmap *map, addrmap_foreach_fn fn, void *data);
++
+ #endif /* ADDRMAP_H */
diff --git a/gdb.spec b/gdb.spec
index 1495e8f..0225b78 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -27,7 +27,7 @@ Version: 7.2
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 36%{?_with_upstream:.upstream}%{dist}
+Release: 37%{?_with_upstream:.upstream}%{dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and GFDL and BSD and Public Domain
 Group: Development/Debuggers
@@ -702,8 +702,17 @@ Patch548: gdb-test-expr-cumulative-archer.patch
 # [vla] Support Fortran vector slices and subsets (BZ 609782).
 # =drop
 Patch549: gdb-archer-vla-misc.patch
+# =drop
 Patch550: gdb-archer-vla-subarray.patch
 
+# Fix discontiguous address ranges in .gdb_index - v3->v4 (BZ 672281).
+# =drop
+Patch551: gdb-gdbindex-v4-1of3.patch
+# =drop
+Patch552: gdb-gdbindex-v4-2of3.patch
+# =drop
+Patch553: gdb-gdbindex-v4-3of3.patch
+
 BuildRequires: ncurses-devel%{?_isa} texinfo gettext flex bison expat-devel%{?_isa}
 Requires: readline%{?_isa}
 BuildRequires: readline-devel%{?_isa}
@@ -1004,6 +1013,9 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
 %patch548 -p1
 %patch549 -p1
 %patch550 -p1
+%patch551 -p1
+%patch552 -p1
+%patch553 -p1
 
 %patch390 -p1
 %patch393 -p1
@@ -1401,6 +1413,9 @@ fi
 %endif
 
 %changelog
+* Tue Jan 25 2011 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.2-37.fc14
+- Fix discontiguous address ranges in .gdb_index - v3->v4 (BZ 672281).
+
 * Sun Jan 16 2011 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.2-36.fc14
 - Fix occasional NULL dereference of the readline-6.0 workaround (BZ 575516).
 


More information about the scm-commits mailing list