238 lines
8.2 KiB
Diff
238 lines
8.2 KiB
Diff
|
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@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)
|
||
|
{
|