print_cfa_program might call print_ops with zero offset size. We don't need (and don't know) the DWARF offset size in that case. DW_OP_call_ref and DW_OP_GNU_implicit_pointer need to know the offset size because they reference a DIE. But they are invalid when used from CFA.
Signed-off-by: Mark Wielaard <m...@redhat.com> --- src/ChangeLog | 5 +++++ src/readelf.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index c149a9c..ccbd6e8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2014-12-07 Mark Wielaard <m...@redhat.com> + + * readelf.c (print_ops): Handle zero ref_size for DW_OP_call_ref + and DW_OP_GNU_implicit_pointer. + 2014-12-04 Mark Wielaard <m...@redhat.com> * objdump.c (show_relocs_x): Make sure destshdr exists. diff --git a/src/readelf.c b/src/readelf.c index 89b1754..881bb45 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -3999,6 +3999,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, case DW_OP_call_ref: /* Offset operand. */ + if (ref_size == 0) + goto invalid; /* Cannot be used in CFA. */ NEED (ref_size); if (ref_size == 4) addr = read_4ubyte_unaligned (dbg, data); @@ -4203,6 +4205,8 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest, /* DIE offset operand. */ start = data; NEED (ref_size + 1); + if (ref_size == 0) + goto invalid; /* Cannot be used in CFA. */ if (ref_size == 4) addr = read_4ubyte_unaligned (dbg, data); else -- 1.9.3