print_form_data didn't take the offset_len (4 or 8 bytes) into account
causing the wrong entry to be read from .debug_str_offsets.
print_debug_macro_section did sanity checking before calling
print_form_data, which does sanity checking itself. The sanity check
for DW_FORM_strx was wrong in print_debug_macro_section (but correct
in print_form_data).
Add a new testfile for run-readelf-macro.sh, this one compiled with
clang -gdwarf-5 -fdebug-macro.
* src/readelf.c (print_form_data): Multiply by offset_len for
strx_val.
(print_debug_macro_section): Remove sanity checks before calling
print_form_data.
* tests/testfileclangmacro.bz2: New testfile.
* tests/Makefile.am (EXTRA_DIST): Add testfileclangmacro.bz2.
* tests/run-readelf-macro.sh: Add testfileclangmacro output.
Signed-off-by: Mark Wielaard
---
src/readelf.c| 13 +-
tests/Makefile.am| 2 +-
tests/run-readelf-macro.sh | 817 ++-
tests/testfileclangmacro.bz2 | Bin 0 -> 7985 bytes
4 files changed, 820 insertions(+), 12 deletions(-)
create mode 100755 tests/testfileclangmacro.bz2
diff --git a/src/readelf.c b/src/readelf.c
index 0e931184ed38..c945b371966f 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -8869,11 +8869,12 @@ print_form_data (Dwarf *dbg, int form, const unsigned
char *readp,
strx_val:
data = dbg->sectiondata[IDX_debug_str_offsets];
if (data == NULL
- || data->d_size - str_offsets_base < val)
+ || data->d_size - str_offsets_base < val * offset_len)
str = "???";
else
{
- const unsigned char *strreadp = data->d_buf + str_offsets_base + val;
+ const unsigned char *strreadp = (data->d_buf + str_offsets_base
+ + val * offset_len);
const unsigned char *strreadendp = data->d_buf + data->d_size;
if ((size_t) (strreadendp - strreadp) < offset_len)
str = "???";
@@ -10853,8 +10854,6 @@ print_debug_macro_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
case DW_MACRO_define_sup:
get_uleb128 (u128, readp, readendp);
- if (readp + offset_len > readendp)
- goto invalid_data;
printf ("%*s#define ", level, "");
readp = print_form_data (dbg, DW_FORM_strp_sup,
readp, readendp, offset_len,
@@ -10864,8 +10863,6 @@ print_debug_macro_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
case DW_MACRO_undef_sup:
get_uleb128 (u128, readp, readendp);
- if (readp + offset_len > readendp)
- goto invalid_data;
printf ("%*s#undef ", level, "");
readp = print_form_data (dbg, DW_FORM_strp_sup,
readp, readendp, offset_len,
@@ -10887,8 +10884,6 @@ print_debug_macro_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
case DW_MACRO_define_strx:
get_uleb128 (u128, readp, readendp);
- if (readp + offset_len > readendp)
- goto invalid_data;
printf ("%*s#define ", level, "");
readp = print_form_data (dbg, DW_FORM_strx,
readp, readendp, offset_len,
@@ -10898,8 +10893,6 @@ print_debug_macro_section (Dwfl_Module *dwflmod
__attribute__ ((unused)),
case DW_MACRO_undef_strx:
get_uleb128 (u128, readp, readendp);
- if (readp + offset_len > readendp)
- goto invalid_data;
printf ("%*s#undef ", level, "");
readp = print_form_data (dbg, DW_FORM_strx,
readp, readendp, offset_len,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b7fb72384f32..46f553a9b991 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -378,7 +378,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \
testfile49.bz2 testfile50.bz2 testfile51.bz2 \
testfile-macros-0xff.bz2 \
-run-readelf-macro.sh testfilemacro.bz2 \
+run-readelf-macro.sh testfilemacro.bz2 testfileclangmacro.bz2 \
run-readelf-loc.sh testfileloc.bz2 \
splitdwarf4-not-split4.dwo.bz2 \
testfile-splitdwarf4-not-split4.debug.bz2 \
diff --git a/tests/run-readelf-macro.sh b/tests/run-readelf-macro.sh
index 8b17f7da6e05..92401b59ff35 100755
--- a/tests/run-readelf-macro.sh
+++ b/tests/run-readelf-macro.sh
@@ -342,4 +342,819 @@ DWARF section [32] '.debug_macro' at offset 0x2480:
EOF
-exit 0
+# Same sources as above, but now using clang
+# gcc -g3 -c hello.c
+# gcc -g3 -c world.c
+# gcc -g3 -o testfilemacro hello.o world.o
+
+# clang -gdwarf-5 -fdebug-macro -c hello.c
+# clang -gdwarf-5 -fdebug-macro -c world.c
+# clang