We now require callers to pass DWARF_GETMACROS_START to start the iteration. 0 is still accepted, but signals to libdw that the iteration request comes from an old-style caller, and that opcode 0xff should be rejected when iterating .debug_macro, to avoid confusion.
Signed-off-by: Petr Machata pmachata@redhat.com --- NEWS | 2 - libdw/ChangeLog | 8 ++ libdw/dwarf_getmacros.c | 176 +++++++++++++++++++++++++---------------- libdw/libdw.h | 40 ++++++---- tests/ChangeLog | 10 +++ tests/dwarf-getmacros.c | 27 +++++-- tests/run-dwarf-getmacros.sh | 11 +++ tests/testfile-macros-0xff.bz2 | Bin 0 -> 2844 bytes tests/testfile-macros-0xff.s | 153 +++++++++++++++++++++++++++++++++++ 9 files changed, 334 insertions(+), 93 deletions(-) create mode 100755 tests/testfile-macros-0xff.bz2 create mode 100644 tests/testfile-macros-0xff.s
diff --git a/NEWS b/NEWS index 8f0780b..a7ead0a 100644 --- a/NEWS +++ b/NEWS @@ -8,8 +8,6 @@ libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses dwarf_macro_getparamcnt, and dwarf_macro_param are available for more generalized inspection of macros and their parameters.
-XXX: Fix serving of 0xff based on what ends up in Dwarf 5. - Version 0.160
libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 37f94df..37e8bda 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,11 @@ +2014-12-02 Petr Machata pmachata@redhat.com + + * dwarf_getmacros.c (token_from_offset, offset_from_token): New + helper functions. + (DWARF_GETMACROS_DMACRO): New macro. + (do_dwarf_getmacros_die): Merge into dwarf_getmacros. + * libdw.h (DWARF_GETMACROS_START): New macro. + 2014-11-24 Mark Wielaard mjw@redhat.com
* dwarf_getsrclines.c (read_srclines): Check line_range is not zero diff --git a/libdw/dwarf_getmacros.c b/libdw/dwarf_getmacros.c index 8d9d78b..08928c3 100644 --- a/libdw/dwarf_getmacros.c +++ b/libdw/dwarf_getmacros.c @@ -384,13 +384,65 @@ read_macros (Dwarf *dbg, int sec_index, return 0; }
+#define DWARF_GETMACROS_DMACRO PTRDIFF_MIN + +/* Token layout: + + - sign bit is used for distinguishing between .debug_macinfo + iteration (when unset) and .debug_macro iteration (when set, + i.e. negative values). The mask is DWARF_GETMACROS_DMACRO. + + - the next highest bit is used for distinguishing between callers + that know that opcode 0xff may have one of two incompatible + meanings. The mask that we use for selecting this bit is + DWARF_GETMACROS_START. + + Besides, token value of 0 signals end of iteration and -1 is + reserved for signaling errors. + + That means that on a 32-bit machine, 30 bits are allowed for + offset, and therefore the maximum macro unit size is 1GB. Also, + because -1 is reserved, it's impossible to represent maximum offset + of a .debug_macro unit to new-style callers (which in practice + decreases the permissible macro unit size by another 1 byte). */ + +static ptrdiff_t +token_from_offset (ptrdiff_t offset, bool accept_0xff, bool debug_macro) +{ + if (offset == -1 || offset == 0) + return offset; + + /* Make sure the offset didn't overflow into the flag bits. */ + assert ((offset & DWARF_GETMACROS_START) == 0); + assert ((offset & DWARF_GETMACROS_DMACRO) == 0); + + if (accept_0xff) + offset |= DWARF_GETMACROS_START; + if (debug_macro) + offset |= DWARF_GETMACROS_DMACRO; + + return offset; +} + +static ptrdiff_t +offset_from_token (ptrdiff_t token, bool *accept_0xffp, bool *debug_macrop) +{ + *accept_0xffp = (token & DWARF_GETMACROS_START) != 0; + token &= ~DWARF_GETMACROS_START; + + *debug_macrop = (token & DWARF_GETMACROS_DMACRO) != 0; + token &= ~DWARF_GETMACROS_DMACRO; + + return token; +} + static ptrdiff_t gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *), - void *arg, ptrdiff_t token, bool accept_0xff, + void *arg, ptrdiff_t offset, bool accept_0xff, Dwarf_Die *cudie) { - assert (token <= 0); + assert (offset >= 0);
if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size) { @@ -398,23 +450,19 @@ gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, return -1; }
- ptrdiff_t ret = read_macros (dbg, IDX_debug_macro, macoff, - callback, arg, -token, accept_0xff, cudie); - if (ret == -1) - return -1; - else - return -ret; + return read_macros (dbg, IDX_debug_macro, macoff, + callback, arg, offset, accept_0xff, cudie); }
static ptrdiff_t macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *), - void *arg, ptrdiff_t token, Dwarf_Die *cudie) + void *arg, ptrdiff_t offset, Dwarf_Die *cudie) { - assert (token >= 0); + assert (offset >= 0);
return read_macros (dbg, IDX_debug_macinfo, macoff, - callback, arg, token, true, cudie); + callback, arg, offset, true, cudie); }
ptrdiff_t @@ -428,21 +476,25 @@ dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, return -1; }
- /* We use token values > 0 for iteration through .debug_macinfo and - values < 0 for iteration through .debug_macro. Return value of - -1 also signifies an error, but that's fine, because .debug_macro - always contains at least three bytes of headers and after - iterating one opcode, we should never see anything above -4. */ - assert (token <= 0); + bool accept_0xff; + bool debug_macro; + ptrdiff_t offset = offset_from_token (token, &accept_0xff, &debug_macro); + + assert (accept_0xff); + assert (debug_macro || offset == 0); + + offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset, + accept_0xff, NULL);
- return gnu_macros_getmacros_off (dbg, macoff, callback, arg, token, true, - NULL); + return token_from_offset (offset, accept_0xff, true); }
-static ptrdiff_t -do_dwarf_getmacros_die (Dwarf_Die *cudie, Dwarf_Off *macoffp, - int (*callback) (Dwarf_Macro *, void *), - void *arg, ptrdiff_t token, bool accept_0xff) +ptrdiff_t +dwarf_getmacros (cudie, callback, arg, token) + Dwarf_Die *cudie; + int (*callback) (Dwarf_Macro *, void *); + void *arg; + ptrdiff_t token; { if (cudie == NULL) { @@ -450,50 +502,6 @@ do_dwarf_getmacros_die (Dwarf_Die *cudie, Dwarf_Off *macoffp, return -1; }
- if (token > 0 && macoffp != NULL) - /* A continuation call from DW_AT_macro_info iteration, meaning - *MACOFF contains previously-cached offset. */ - return macro_info_getmacros_off (cudie->cu->dbg, *macoffp, - callback, arg, token, cudie); - - /* A fresh start of DW_AT_macro_info iteration, or a continuation - thereof without a cache. */ - if (token > 0 - || (token == 0 && dwarf_hasattr (cudie, DW_AT_macro_info))) - { - Dwarf_Word macoff; - if (macoffp == NULL) - macoffp = &macoff; - if (get_offset_from (cudie, DW_AT_macro_info, macoffp) != 0) - return -1; - return macro_info_getmacros_off (cudie->cu->dbg, *macoffp, - callback, arg, token, cudie); - } - - if (token < 0 && macoffp != NULL) - /* A continuation call from DW_AT_GNU_macros iteration. */ - return gnu_macros_getmacros_off (cudie->cu->dbg, *macoffp, - callback, arg, token, accept_0xff, - cudie); - - /* Likewise without cache, or iteration start. */ - Dwarf_Word macoff; - if (macoffp == NULL) - macoffp = &macoff; - if (get_offset_from (cudie, DW_AT_GNU_macros, macoffp) != 0) - return -1; - return gnu_macros_getmacros_off (cudie->cu->dbg, *macoffp, - callback, arg, token, accept_0xff, - cudie); -} - -ptrdiff_t -dwarf_getmacros (die, callback, arg, offset) - Dwarf_Die *die; - int (*callback) (Dwarf_Macro *, void *); - void *arg; - ptrdiff_t offset; -{ /* This function might be called from a code that expects to see DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones. It is fine to serve most DW_MACRO_{GNU_,}* opcodes to such code, because those @@ -511,7 +519,37 @@ dwarf_getmacros (die, callback, arg, offset) some small probability that the two opcodes would look superficially similar enough that a client would be confused and misbehave as a result. For this reason, we refuse to serve - through this interface 0xff's originating from .debug_macro. */ + through this interface 0xff's originating from .debug_macro + unless the TOKEN that we obtained indicates the call originates + from a new-style caller. See above for details on what + information is encoded into tokens. */ + + bool accept_0xff; + bool debug_macro; + ptrdiff_t offset = offset_from_token (token, &accept_0xff, &debug_macro); + + if (offset == 0) + debug_macro = dwarf_hasattr (cudie, DW_AT_GNU_macros); + + /* DW_AT_macro_info */ + if (! debug_macro) + { + Dwarf_Word macoff; + if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0) + return -1; + offset = macro_info_getmacros_off (cudie->cu->dbg, macoff, + callback, arg, offset, cudie); + } + else + { + /* DW_AT_GNU_macros, DW_AT_macros */ + Dwarf_Word macoff; + if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0) + return -1; + offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff, + callback, arg, offset, accept_0xff, + cudie); + }
- return do_dwarf_getmacros_die (die, NULL, callback, arg, offset, false); + return token_from_offset (offset, accept_0xff, debug_macro); } diff --git a/libdw/libdw.h b/libdw/libdw.h index c0baa21..6c488de 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -32,6 +32,7 @@ #include <gelf.h> #include <stdbool.h> #include <stddef.h> +#include <stdint.h>
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) @@ -845,22 +846,24 @@ extern int dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts);
/* Iterate through the macro unit referenced by CUDIE and call - CALLBACK for each macro information entry. Keeps iterating while - CALLBACK returns DWARF_CB_OK. If the callback returns - DWARF_CB_ABORT, it stops iterating and returns a continuation - token, which can be used to restart the iteration at the point - where it ended. A TOKEN of 0 starts the iteration. Returns -1 for - errors or 0 if there are no more macro entries. + CALLBACK for each macro information entry. To start the iteration, + one would pass DWARF_GETMACROS_START for TOKEN. + + The iteration continues while CALLBACK returns DWARF_CB_OK. If the + callback returns DWARF_CB_ABORT, the iteration stops and a + continuation token is returned, which can be used to restart the + iteration at the point where it ended. Returns -1 for errors or 0 + if there are no more macro entries.
Note that the Dwarf_Macro pointer passed to the callback is only valid for the duration of the callback invocation.
- Note that this interface will refuse to serve opcode 0xff from - .debug_macro sections. Such opcode is considered invalid and will - cause dwarf_getmacros to return with error. Note that this should - be no limitation as of now, as DW_MACRO_GNU_* domain doesn't - allocate 0xff. It is however a theoretical possibility with future - Dwarf standards. */ + For backward compatibility, a token of 0 is accepted for starting + the iteration as well, but in that case this interface will refuse + to serve opcode 0xff from .debug_macro sections. Such opcode would + be considered invalid and would cause dwarf_getmacros to return + with error. */ +#define DWARF_GETMACROS_START ((ptrdiff_t) (((uintptr_t) PTRDIFF_MIN) >> 1)) extern ptrdiff_t dwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *), void *arg, ptrdiff_t token) @@ -871,13 +874,16 @@ extern ptrdiff_t dwarf_getmacros (Dwarf_Die *cudie, iterates .debug_macro. This can be used for handling DW_MACRO_GNU_transparent_include's or similar opcodes.
+ TOKEN value of DWARF_GETMACROS_START can be used to start the + iteration. + It is not appropriate to obtain macro unit offset by hand from a CU DIE and then request iteration through this interface. The reason for this is that if a dwarf_macro_getsrcfiles is later called, there would be no way to figure out what DW_AT_comp_dir was present on the CU DIE, and file names referenced in either the macro unit itself, or the .debug_line unit that it references, might be wrong. - Use dwarf_getmacro. */ + Use dwarf_getmacros. */ extern ptrdiff_t dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *), void *arg, ptrdiff_t token) @@ -895,9 +901,11 @@ extern int dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro, /* Return macro opcode. That's a constant that can be either from DW_MACINFO_* domain or DW_MACRO_GNU_* domain. The two domains have compatible values, so it's OK to use either of them for - comparisons. The only differences is 0xff, which currently is - never served from .debug_macro, and can thus be safely assumed to - mean DW_MACINFO_vendor_ext. */ + comparisons. The only differences is 0xff, which could be either + DW_MACINFO_vendor_ext or a vendor-defined DW_MACRO_* constant. One + would need to look if the CU DIE which the iteration was requested + for has attribute DW_AT_macro_info, or either of DW_AT_GNU_macros + or DW_AT_macros to differentiate the two interpretations. */ extern int dwarf_macro_opcode (Dwarf_Macro *macro, unsigned int *opcodep) __nonnull_attribute__ (2);
diff --git a/tests/ChangeLog b/tests/ChangeLog index 909a61e..eb77673 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,13 @@ +2014-12-02 Petr Machata pmachata@redhat.com + + * dwarf-getmacros.c (mac): Skip over DW_MACINFO_undef, + DW_MACRO_GNU_undef_indirect opcodes. Add a default branch. + (main): Initialize off to DWARF_GETMACROS_START when an extra + command line argument is passed. + * testfile-macros-0xff.bz2: New test case. + * testfile-macros-0xff.s: New file (source for the above). + * run-dwarf-getmacros.sh: Add two tests. + 2014-11-21 Mark Wielaard mjw@redhat.com
* run-readelf-A.sh: New test. diff --git a/tests/dwarf-getmacros.c b/tests/dwarf-getmacros.c index f203d5b..92e093c 100644 --- a/tests/dwarf-getmacros.c +++ b/tests/dwarf-getmacros.c @@ -34,9 +34,9 @@ mac (Dwarf_Macro *macro, void *dbg) { static int level = 0;
- switch (({ unsigned int opcode; - dwarf_macro_opcode (macro, &opcode); - opcode; })) + unsigned int opcode; + dwarf_macro_opcode (macro, &opcode); + switch (opcode) { case DW_MACRO_GNU_transparent_include: { @@ -50,7 +50,7 @@ mac (Dwarf_Macro *macro, void *dbg)
printf ("%*sinclude %#" PRIx64 "\n", level, "", w); ++level; - include (dbg, w, 0); + include (dbg, w, DWARF_GETMACROS_START); --level; printf ("%*s/include\n", level, ""); break; @@ -88,6 +88,19 @@ mac (Dwarf_Macro *macro, void *dbg) printf ("%*s%s\n", level, "", value); break; } + + case DW_MACINFO_undef: + case DW_MACRO_GNU_undef_indirect: + break; + + default: + { + size_t paramcnt; + dwarf_macro_getparamcnt (macro, ¶mcnt); + printf ("%*sopcode %u with %zd arguments\n", + level, "", opcode, paramcnt); + break; + } }
return DWARF_CB_ABORT; @@ -105,17 +118,19 @@ include (Dwarf *dbg, Dwarf_Off macoff, ptrdiff_t token) }
int -main (int argc __attribute__ ((unused)), char *argv[]) +main (int argc, char *argv[]) { + assert (argc >= 3); const char *name = argv[1]; ptrdiff_t cuoff = strtol (argv[2], NULL, 0); + bool new_style = argc > 3;
int fd = open (name, O_RDONLY); Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
Dwarf_Die cudie_mem, *cudie = dwarf_offdie (dbg, cuoff, &cudie_mem);
- for (ptrdiff_t off = 0; + for (ptrdiff_t off = new_style ? DWARF_GETMACROS_START : 0; (off = dwarf_getmacros (cudie, mac, dbg, off)); ) if (off == -1) { diff --git a/tests/run-dwarf-getmacros.sh b/tests/run-dwarf-getmacros.sh index 8f7c4a8..0a488fa 100755 --- a/tests/run-dwarf-getmacros.sh +++ b/tests/run-dwarf-getmacros.sh @@ -696,4 +696,15 @@ file /home/mark/src/tests/macro.c /file EOF
+testfiles testfile-macros-0xff +testrun_compare ${abs_builddir}/dwarf-getmacros testfile-macros-0xff 0xb <<\EOF +invalid opcode +EOF +testrun_compare ${abs_builddir}/dwarf-getmacros testfile-macros-0xff 0xb '' <<\EOF +opcode 255 with 0 arguments +file /home/petr/proj/elfutils/master/elfutils/x.c + FOO 0 +/file +EOF + exit 0 diff --git a/tests/testfile-macros-0xff.bz2 b/tests/testfile-macros-0xff.bz2 new file mode 100755 index 0000000000000000000000000000000000000000..a19662a3d43170f7200c50f2984693450fda79e4 GIT binary patch literal 2844 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
literal 0 HcmV?d00001
diff --git a/tests/testfile-macros-0xff.s b/tests/testfile-macros-0xff.s new file mode 100644 index 0000000..7fdd35c --- /dev/null +++ b/tests/testfile-macros-0xff.s @@ -0,0 +1,153 @@ + .file "x.c" + .text +.Ltext0: + .globl main + .type main, @function +main: +.LFB0: + .file 1 "x.c" + .loc 1 3 0 + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + .loc 1 3 0 + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0x52 + .value 0x4 + .long .Ldebug_abbrev0 + .byte 0x8 + .uleb128 0x1 + .long .LASF244 + .byte 0x4 + .string "x.c" + .long .LASF245 + .quad .Ltext0 + .quad .Letext0-.Ltext0 + .long .Ldebug_line0 + .long .Ldebug_macro0 + .uleb128 0x2 + .long .LASF246 + .byte 0x1 + .byte 0x3 + .long 0x4e + .quad .LFB0 + .quad .LFE0-.LFB0 + .uleb128 0x1 + .byte 0x9c + .uleb128 0x3 + .byte 0x4 + .byte 0x5 + .string "int" + .byte 0 + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x25 + .uleb128 0xe + .uleb128 0x13 + .uleb128 0xb + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x1b + .uleb128 0xe + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x7 + .uleb128 0x10 + .uleb128 0x17 + .uleb128 0x2119 + .uleb128 0x17 + .byte 0 + .byte 0 + .uleb128 0x2 + .uleb128 0x2e + .byte 0 + .uleb128 0x3f + .uleb128 0x19 + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x7 + .uleb128 0x40 + .uleb128 0x18 + .uleb128 0x2117 + .uleb128 0x19 + .byte 0 + .byte 0 + .uleb128 0x3 + .uleb128 0x24 + .byte 0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0x8 + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .long 0x2c + .value 0x2 + .long .Ldebug_info0 + .byte 0x8 + .byte 0 + .value 0 + .value 0 + .quad .Ltext0 + .quad .Letext0-.Ltext0 + .quad 0 + .quad 0 + .section .debug_macro,"",@progbits +.Ldebug_macro0: + .value 0x4 + .byte 0x6 + .long .Ldebug_line0 + .byte 0x1 + .byte 0xff + .uleb128 0 + .byte 0xff + .byte 0x3 + .uleb128 0 + .uleb128 0x1 + .byte 0x5 + .uleb128 0x1 + .long .LASF243 + .byte 0x4 + .byte 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF245: + .string "/home/petr/proj/elfutils/master/elfutils" +.LASF244: + .string "GNU C++ 4.9.0 20140422 (Red Hat 4.9.0-1) -mtune=generic -march=x86-64 -g3" +.LASF243: + .string "FOO 0" +.LASF246: + .string "main" + .ident "GCC: (GNU) 4.9.0 20140422 (Red Hat 4.9.0-1)" + .section .note.GNU-stack,"",@progbits
Hi Petr,
On Tue, 2014-12-02 at 21:42 +0100, Petr Machata wrote:
We now require callers to pass DWARF_GETMACROS_START to start the iteration. 0 is still accepted, but signals to libdw that the iteration request comes from an old-style caller, and that opcode 0xff should be rejected when iterating .debug_macro, to avoid confusion. [...] +/* Token layout:
- sign bit is used for distinguishing between .debug_macinfo
- iteration (when unset) and .debug_macro iteration (when set,
- i.e. negative values). The mask is DWARF_GETMACROS_DMACRO.
- the next highest bit is used for distinguishing between callers
- that know that opcode 0xff may have one of two incompatible
- meanings. The mask that we use for selecting this bit is
- DWARF_GETMACROS_START.
- Besides, token value of 0 signals end of iteration and -1 is
- reserved for signaling errors.
- That means that on a 32-bit machine, 30 bits are allowed for
- offset, and therefore the maximum macro unit size is 1GB. Also,
- because -1 is reserved, it's impossible to represent maximum offset
- of a .debug_macro unit to new-style callers (which in practice
- decreases the permissible macro unit size by another 1 byte). */
I am wondering whether we really need to track both issues with the toke/offset. It looks like we only need to track old-vs-new caller (0xff allowed). Whether we are using macinfo or macro seems to be discoverable from the call made.
If the user calls dwarf_getmacros they provide the CU DIE. From that we can determine whether we are using macinfo or macro by looking for the DW_AT_macro_info or DW_AT_macros attribute.
If the user calls dwarf_getmacros_off then they are a new style caller by default because that function didn't exist previously. And it only works for macro because it is meant for the transparent_include style macro which doesn't exist with macinfo.
Sorry to bring this up after you have written all this code. But if we can use a simpler token encoding then I think we should.
Thanks,
Mark
elfutils-devel@lists.fedorahosted.org