diff options
author | Andrew Burgess <aburgess@redhat.com> | 2024-11-18 16:19:43 +0000 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2024-11-21 19:38:39 +0000 |
commit | 978324718990b6b371d4eeeba02cfe13a0ebf120 (patch) | |
tree | 59fa8fda18cf50a64ff2470ab0020420fee26640 /gdb/testsuite/lib | |
parent | testsuite: skip confirmation in 'gdb_reinitialize_dir' (diff) | |
download | binutils-gdb-978324718990b6b371d4eeeba02cfe13a0ebf120.tar.gz binutils-gdb-978324718990b6b371d4eeeba02cfe13a0ebf120.tar.bz2 binutils-gdb-978324718990b6b371d4eeeba02cfe13a0ebf120.zip |
gdb/build-id: protect against weirdly short build-ids
While looking at build_id_to_bfd_suffix (in gdb/build-id.c) I realised
that GDB would likely not do what we wanted if a build-id was ever a
single byte.
Right now, build-ids generated by the GNU linker are 32 bytes, but
there's nothing that forces this to be the case, it's pretty easy to
create a fake, single byte, build-id. Given that the build-id is an
external input (read from the objfile), GDB should protect itself
against these edge cases.
The problem with build_id_to_bfd_suffix is that this function creates
the path used to lookup either the debug information, or an
executable, based on its build-id. So a 3-byte build-id 0xaabbcc will
look in the path: `$DEBUG_FILE_DIRECTORY/.build-id/aa/bbcc.debug`.
However, a single byte build-id 0xaa, will look in the file:
`$DEBUG_FILE_DIRECTORY/.build-id/aa/.debug` which doesn't seem right.
Worse, when looking for an objfile given a build-id GDB will look for
a file called `$DEBUG_FILE_DIRECTORY/.build-id/aa/` with a trailing
'/' character.
I propose that, in build_id_to_bfd_suffix we just return early if the
build-id is 1 byte (or less) with a return value that indicates no
separate file was found.
For testing I made use of the DWARF assembler. I needed to update the
build-id creation proc, the existing code assumes that the build-id is
a multiple of 4 bytes, so I added some additional padding to ensure
that the generated note was a multiple of 4 bytes, even if the
build-id was not.
I added a test with a 1 byte build-id, and also for the case where the
build-id has zero length. The zero length case already does what
you'd expect (no debug is loaded) as the bfd library rejects the
build-id when loading it from the objfile, but adding this additional
test is pretty cheap.
Approved-By: Kevin Buettner <kevinb@redhat.com>
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r-- | gdb/testsuite/lib/dwarf.exp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 1002c75dd09..f6348972968 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -3008,25 +3008,32 @@ namespace eval Dwarf { proc _note {type name hexdata} { set namelen [expr [string length $name] + 1] + set datalen [expr [string length $hexdata] / 2] # Name size. _op .4byte $namelen # Data size. - _op .4byte [expr [string length $hexdata] / 2] + _op .4byte $datalen # Type. _op .4byte $type # The name. _op .ascii [_quote $name] - # Alignment. + # Alignment (to 4-byte boundary). set align 2 set total [expr {($namelen + (1 << $align) - 1) & -(1 << $align)}] for {set i $namelen} {$i < $total} {incr i} { - _op .byte 0 + _op .byte 0 padding } # The data. foreach {a b} [split $hexdata {}] { _op .byte 0x$a$b } + # Alignment (to 4-byte boundary). + set align 2 + set total [expr {($datalen + (1 << $align) - 1) & -(1 << $align)}] + for {set i $datalen} {$i < $total} {incr i} { + _op .byte 0 padding + } } # Emit a note section holding the given build-id. |