From: Mark Wielaard Date: Mon, 29 Jun 2026 20:43:39 +0000 (+0200) Subject: readelf: Fix interpretation of offset_size_flag in print_cu_index_section X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bdd83a9102c0bc92b4e043417f0d3d0b3351d3a3;p=thirdparty%2Felfutils.git readelf: Fix interpretation of offset_size_flag in print_cu_index_section The offset_size_flag is an DWARF 6 extension described in https://dwarfstd.org/issues/220708.2.html While writing tests for eu-dwp some issues with the eu-readelf display of the .debug_cu_index were found. The offset_size_flag was only used for the offsets table, not the size (lengths) table. And if the flag was set only 4 bytes of the offset were read (instead of 8 bytes). * src/readelf.c (print_cu_index_section): Calculate lengths_end using off_bytes, use read_8ubyte_unaligned to read offsets when offset_size_flag is set, calculate prow using off_bytes, read and print sizes based on off_bytes. Signed-off-by: Mark Wielaard --- diff --git a/src/readelf.c b/src/readelf.c index 8d7950d3..9d3bbbf6 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -12290,6 +12290,7 @@ print_cu_index_section (Dwfl_Module *dwflmod __attribute__ ((unused)), readp++; } + /* Both offsets and sizes are either 32 or 64 bits (4 or 8 bytes). */ const unsigned char off_bytes = offset_size_flag == 0 ? 4 : 8; if (unlikely (readp > dataend - 4)) @@ -12325,17 +12326,17 @@ print_cu_index_section (Dwfl_Module *dwflmod __attribute__ ((unused)), the hash table (ids of 8 bytes). */ const unsigned char *indices = hash_table + slot_count * 8; /* Sections used starts after the indices, indices and hash table - have the same number of slots, indeces are 4 bytes each, */ + have the same number of slots, indices are 4 bytes each, */ const unsigned char *sections = indices + slot_count * 4; /* Offset slots for each section follow the one row of sections. */ const unsigned char *offsets = sections + section_count * 4; /* Size slots for each section follow the offsets (used rows). */ const unsigned char *lengths = (offsets + unit_count * section_count * off_bytes); - /* The size table has one row of section_count 4-byte slots per unit, + /* The size table has one row of section_count slots per unit, just like the offset table, so it spans unit_count rows (not one). */ const unsigned char *lengths_end = (lengths + - unit_count * section_count * 4); + unit_count * section_count * off_bytes); /* Sanity check the above against dataend. */ if ((slot_count > UINT32_MAX / 8) @@ -12395,7 +12396,7 @@ print_cu_index_section (Dwfl_Module *dwflmod __attribute__ ((unused)), else for (size_t j = 0; j < section_count; j++) { - uint64_t off = read_4ubyte_unaligned (dbg, prow + j * 8); + uint64_t off = read_8ubyte_unaligned (dbg, prow + j * 8); fprintf (out, " %6" PRIu64, off); } fprintf (out, "\n"); @@ -12433,12 +12434,20 @@ print_cu_index_section (Dwfl_Module *dwflmod __attribute__ ((unused)), continue; } /* Note row is one based, not zero based. */ - const unsigned char *prow = lengths + (row - 1) * section_count * 4; - for (size_t j = 0; j < section_count; j++) - { - uint32_t off = read_4ubyte_unaligned (dbg, prow + j * 4); - fprintf (out, " %6" PRIu32, off); - } + const unsigned char *prow = (lengths + + (row - 1) * section_count * off_bytes); + if (off_bytes == 4) + for (size_t j = 0; j < section_count; j++) + { + uint32_t sz = read_4ubyte_unaligned (dbg, prow + j * 4); + fprintf (out, " %6" PRIu32, sz); + } + else + for (size_t j = 0; j < section_count; j++) + { + uint64_t sz = read_8ubyte_unaligned (dbg, prow + j * 8); + fprintf (out, " %6" PRIu64, sz); + } fprintf (out, "\n"); } }