Handle unaligned mapping of .gdb_index
The .gdb_index was designed such that all data would be aligned. Unfortunately, we neglected to require this alignment in the objcopy instructions in the manual. As a result, in many cases, a .gdb_index in the wild will not be properly aligned by mmap. This yields undefined behavior, which is PR gdb/23743. This patch fixes the bug by always assuming that the mapping is unaligned, and using extract_unsigned_integer when needed. A new helper class is introduced to make this less painful. gdb/ChangeLog 2021-04-17 Tom Tromey <tom@tromey.com> PR gdb/23743: * dwarf2/read.c (class offset_view): New. (struct symbol_table_slot): Remove. (struct mapped_index) <symbol_table, constant_pool>: Change type. <symbol_name_index, symbol_vec_index>: New methods. <symbol_name_slot_invalid, symbol_name_at, symbol_name_count>: Rewrite. (read_gdb_index_from_buffer): Update. (struct dw2_symtab_iterator) <vec>: Change type. (dw2_symtab_iter_init_common, dw2_symtab_iter_init) (dw2_symtab_iter_next, dw2_expand_marked_cus): Update. * dwarf2/index-write.c (class data_buf) <append_data>: Remove. <append_array, append_offset>: New methods. (write_hash_table, add_address_entry, write_gdbindex_1) (write_debug_names): Update. * dwarf2/index-common.h (byte_swap, MAYBE_SWAP): Remove.
This commit is contained in:
parent
da314dd397
commit
42c2c69462
4 changed files with 132 additions and 81 deletions
|
@ -29,28 +29,15 @@
|
|||
architecture-independent. */
|
||||
typedef uint32_t offset_type;
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
|
||||
/* Convert VALUE between big- and little-endian. */
|
||||
/* Unpack a 32-bit little-endian value. */
|
||||
|
||||
static inline offset_type
|
||||
byte_swap (offset_type value)
|
||||
gdb_index_unpack (const gdb_byte *value)
|
||||
{
|
||||
offset_type result;
|
||||
|
||||
result = (value & 0xff) << 24;
|
||||
result |= (value & 0xff00) << 8;
|
||||
result |= (value & 0xff0000) >> 8;
|
||||
result |= (value & 0xff000000) >> 24;
|
||||
return result;
|
||||
return (offset_type) extract_unsigned_integer (value, sizeof (offset_type),
|
||||
BFD_ENDIAN_LITTLE);
|
||||
}
|
||||
|
||||
#define MAYBE_SWAP(V) byte_swap (V)
|
||||
|
||||
#else
|
||||
#define MAYBE_SWAP(V) static_cast<offset_type> (V)
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
/* The hash function for strings in the mapped index. This is the same as
|
||||
SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
|
||||
implementation. This is necessary because the hash function is tied to the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue