GCC11 will warn about a mismatch in the declaration of dwarf_frame_register:
dwarf_frame_register.c:37:61: error: argument 3 of type ‘Dwarf_Op *’ declared as a pointer [-Werror=array-parameter=] 37 | dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem, | ~~~~~~~~~~^~~~~~~ libdw.h:1068:43: note: previously declared as an array ‘Dwarf_Op[3]’ 1068 | Dwarf_Op ops_mem[3], | ~~~~~~~~~^~~~~~~~~~ When fixing that it will show an actual bug in the addrcfi testcase: addrcfi.c:98:16: error: ‘dwarf_frame_register’ accessing 96 bytes in a region of size 64 [-Werror=stringop-overflow=] 98 | int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ addrcfi.c:98:16: note: referencing argument 3 of type ‘Dwarf_Op *’ 1069 | extern int dwarf_frame_register (Dwarf_Frame *frame, int regno, | ^~~~~~~~~~~~~~~~~~~~ Fix the declaration, fix the bug and add an extra comment to the description in libdw.h. Signed-off-by: Mark Wielaard <m...@klomp.org> --- libdw/dwarf_frame_register.c | 2 +- libdw/libdw.h | 8 +++++--- tests/addrcfi.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libdw/dwarf_frame_register.c b/libdw/dwarf_frame_register.c index d0159fb8..bcf3fa03 100644 --- a/libdw/dwarf_frame_register.c +++ b/libdw/dwarf_frame_register.c @@ -34,7 +34,7 @@ #include <dwarf.h> int -dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem, +dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op ops_mem[3], Dwarf_Op **ops, size_t *nops) { /* Maybe there was a previous error. */ diff --git a/libdw/libdw.h b/libdw/libdw.h index 1a4e15a1..ad4fa6ea 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -1061,9 +1061,11 @@ extern int dwarf_frame_cfa (Dwarf_Frame *frame, Dwarf_Op **ops, size_t *nops) caller's REGNO is "same_value", i.e. this frame did not change it; ask the caller frame where to find it. - For common simple expressions *OPS is OPS_MEM. For arbitrary DWARF - expressions in the CFI, *OPS is an internal pointer that can be used as - long as the Dwarf_CFI used to create FRAME remains alive. */ + For common simple expressions *OPS is OPS_MEM (which is a caller + owned array for for at least 3 Dwarf_Ops). For arbitrary DWARF + expressions in the CFI, *OPS is an internal pointer that can be + used as long as the Dwarf_CFI used to create FRAME remains + alive. */ extern int dwarf_frame_register (Dwarf_Frame *frame, int regno, Dwarf_Op ops_mem[3], Dwarf_Op **ops, size_t *nops) diff --git a/tests/addrcfi.c b/tests/addrcfi.c index 589b8513..2b7d7bd0 100644 --- a/tests/addrcfi.c +++ b/tests/addrcfi.c @@ -92,7 +92,7 @@ print_register (void *arg, printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname); - Dwarf_Op ops_mem[2]; + Dwarf_Op ops_mem[3]; Dwarf_Op *ops; size_t nops; int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops); -- 2.18.4