aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2024-11-18 16:19:43 +0000
committerAndrew Burgess <aburgess@redhat.com>2024-11-21 19:38:39 +0000
commit978324718990b6b371d4eeeba02cfe13a0ebf120 (patch)
tree59fa8fda18cf50a64ff2470ab0020420fee26640 /gdb/testsuite/lib
parenttestsuite: skip confirmation in 'gdb_reinitialize_dir' (diff)
downloadbinutils-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.exp13
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.