diff options
author | Mark Wielaard <mark@klomp.org> | 2018-06-28 17:53:12 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2018-06-29 19:43:28 +0200 |
commit | 6dd08dc77dfde80efb349bfab4df67b375f47293 (patch) | |
tree | a8c122b109e0b4f394ad2bb6d40b630751b65b93 /libdw | |
parent | c7a83bf05734e2c20d621678d0f3214475404c55 (diff) |
libdw: Recognize zero terminator to end frame table in dwarf_next_cfi.
When the length is zero this is a the zero terminator that ends the
frame table. Return 1 (end of table) instead of -1 (error) in that case.
We cannot update next_off and don't want to caller to try again.
Add testcase for dwarf_next_cfi to show both .eh_frame and .debug_frame
tables and check consistency (FDEs should point to existing CIEs).
Also add a self check to make sure we can read the table from the just
build elfutils binaries.
Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdw')
-rw-r--r-- | libdw/ChangeLog | 4 | ||||
-rw-r--r-- | libdw/dwarf_next_cfi.c | 8 |
2 files changed, 12 insertions, 0 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 1e86e682..da7ed9d0 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,7 @@ +2018-06-28 Mark Wielaard <mark@klomp.org> + + * dwarf_next_cfi.c (dwarf_next_cfi): Check whether length is zero. + 2018-06-27 Mark Wielaard <mark@klomp.org> * dwarf_begin_elf.c (check_section): Allow a single .debug_frame diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c index 53fc3697..fa28d99b 100644 --- a/libdw/dwarf_next_cfi.c +++ b/libdw/dwarf_next_cfi.c @@ -54,6 +54,7 @@ dwarf_next_cfi (const unsigned char e_ident[], we don't know yet whether this is a 64-bit object or not. */ || unlikely (off + 4 >= data->d_size)) { + done: *next_off = (Dwarf_Off) -1l; return 1; } @@ -79,6 +80,13 @@ dwarf_next_cfi (const unsigned char e_ident[], } length = read_8ubyte_unaligned_inc (&dw, bytes); } + + /* Not explicitly in the DWARF spec, but mentioned in the LSB exception + frames (.eh_frame) spec. If Length contains the value 0, then this + CIE shall be considered a terminator and processing shall end. */ + if (length == 0) + goto done; + if (unlikely ((uint64_t) (limit - bytes) < length) || unlikely (length < offset_size + 1)) goto invalid; |