aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/index-write.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2021-04-17 13:56:36 -0600
committerTom Tromey <tom@tromey.com>2021-04-17 13:56:36 -0600
commit42c2c69462fd83db2e0532ee57c44091bc1032f9 (patch)
tree13355973b52c4ffc51df5db1838a4907138e6270 /gdb/dwarf2/index-write.c
parentda314dd397ab967af558f2929a79349aa5f96ac8 (diff)
downloadbinutils-42c2c69462fd83db2e0532ee57c44091bc1032f9.zip
binutils-42c2c69462fd83db2e0532ee57c44091bc1032f9.tar.gz
binutils-42c2c69462fd83db2e0532ee57c44091bc1032f9.tar.bz2
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.
Diffstat (limited to 'gdb/dwarf2/index-write.c')
-rw-r--r--gdb/dwarf2/index-write.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c
index 6cfe415..e27e1e8 100644
--- a/gdb/dwarf2/index-write.c
+++ b/gdb/dwarf2/index-write.c
@@ -94,13 +94,10 @@ file_write (FILE *file, const std::vector<Elem, Alloc> &vec)
class data_buf
{
public:
- /* Copy DATA to the end of the buffer. */
- template<typename T>
- void append_data (const T &data)
+ /* Copy ARRAY to the end of the buffer. */
+ void append_array (gdb::array_view<const gdb_byte> array)
{
- std::copy (reinterpret_cast<const gdb_byte *> (&data),
- reinterpret_cast<const gdb_byte *> (&data + 1),
- grow (sizeof (data)));
+ std::copy (array.begin (), array.end (), grow (array.size ()));
}
/* Copy CSTR (a zero-terminated string) to the end of buffer. The
@@ -120,7 +117,7 @@ public:
input >>= 7;
if (input)
output |= 0x80;
- append_data (output);
+ m_vec.push_back (output);
if (input == 0)
break;
}
@@ -133,6 +130,12 @@ public:
::store_unsigned_integer (grow (len), len, byte_order, val);
}
+ /* Copy VALUE to the end of the buffer, little-endian. */
+ void append_offset (offset_type value)
+ {
+ append_uint (sizeof (value), BFD_ENDIAN_LITTLE, value);
+ }
+
/* Return the size of the buffer. */
size_t size () const
{
@@ -371,9 +374,9 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
symbol_hash_table.emplace (entry.cu_indices, cpool.size ());
entry.index_offset = cpool.size ();
- cpool.append_data (MAYBE_SWAP (entry.cu_indices.size ()));
+ cpool.append_offset (entry.cu_indices.size ());
for (const auto index : entry.cu_indices)
- cpool.append_data (MAYBE_SWAP (index));
+ cpool.append_offset (index);
}
}
@@ -399,8 +402,8 @@ write_hash_table (mapped_symtab *symtab, data_buf &output, data_buf &cpool)
vec_off = 0;
}
- output.append_data (MAYBE_SWAP (str_off));
- output.append_data (MAYBE_SWAP (vec_off));
+ output.append_offset (str_off);
+ output.append_offset (vec_off);
}
}
@@ -434,7 +437,7 @@ add_address_entry (data_buf &addr_vec,
{
addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, start);
addr_vec.append_uint (8, BFD_ENDIAN_LITTLE, end);
- addr_vec.append_data (MAYBE_SWAP (cu_index));
+ addr_vec.append_offset (cu_index);
}
/* Worker function for traversing an addrmap to build the address table. */
@@ -1374,26 +1377,26 @@ write_gdbindex_1 (FILE *out_file,
offset_type total_len = size_of_header;
/* The version number. */
- contents.append_data (MAYBE_SWAP (8));
+ contents.append_offset (8);
/* The offset of the CU list from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
+ contents.append_offset (total_len);
total_len += cu_list.size ();
/* The offset of the types CU list from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
+ contents.append_offset (total_len);
total_len += types_cu_list.size ();
/* The offset of the address table from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
+ contents.append_offset (total_len);
total_len += addr_vec.size ();
/* The offset of the symbol table from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
+ contents.append_offset (total_len);
total_len += symtab_vec.size ();
/* The offset of the constant pool from the start of the file. */
- contents.append_data (MAYBE_SWAP (total_len));
+ contents.append_offset (total_len);
total_len += constant_pool.size ();
gdb_assert (contents.size () == size_of_header);
@@ -1611,7 +1614,7 @@ write_debug_names (dwarf2_per_objfile *per_objfile,
string. This value is rounded up to a multiple of 4. */
static_assert (sizeof (dwarf5_gdb_augmentation) % 4 == 0, "");
header.append_uint (4, dwarf5_byte_order, sizeof (dwarf5_gdb_augmentation));
- header.append_data (dwarf5_gdb_augmentation);
+ header.append_array (dwarf5_gdb_augmentation);
gdb_assert (header.size () == bytes_of_header);