Hi Mark,

On Mon, Jun 29, 2026 at 4:45 PM Mark Wielaard <[email protected]> wrote:
>
> 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 <[email protected]>

LGTM.

Aaron

> ---
>  src/readelf.c | 29 +++++++++++++++++++----------
>  1 file changed, 19 insertions(+), 10 deletions(-)
>
> diff --git a/src/readelf.c b/src/readelf.c
> index 8d7950d3a6c8..9d3bbbf6f240 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");
>         }
>      }
> --
> 2.54.0
>

Reply via email to