From 40b1f188a3b3194c7f62db9760d81f07db229b33 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 16 Apr 2018 10:25:35 +0200 Subject: [PATCH] readelf: Fix advance_pc to use op_addr_advance, not just op_advance. Found by John Mellor-Crummey. The reason this bug wasn't found earlier is because gcc fixes minimum_instr_len and max_ops_per_instr to 1 for all architectures (in theory max_ops_per_instr could be overridden, but I didn't find any architecture that does). And op_index always seems zero (it looks like it is really only for special VLWI architectures). So in all cases I saw it means that: op_addr_advance = minimum_instr_len * ((op_index + op_advance) / max_ops_per_instr) = 1 * ((0 + op_advance) / 1) = op_advance Completely masking the bug. The libdw dwarf_getsrclines.c implementation does get this right. Because it doesn't care about the data representation and so does the calculation directly. Signed-off-by: Mark Wielaard --- src/ChangeLog | 5 +++++ src/readelf.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 068c87b94..2d525e6d6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2018-04-16 Mark Wielaard + + * readelf.c (print_debug_line_section). In advance_pc, advance + using op_addr_advance, not op_advance. + 2018-04-14 Mark Wielaard * readelf.c (attr_callback): Only show errors when not silent. diff --git a/src/readelf.c b/src/readelf.c index 8c0ef6ca8..45fc82657 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -6971,7 +6971,7 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr, { op_addr_advance = minimum_instr_len * ((op_index + op_advance) / max_ops_per_instr); - address += op_advance; + address += op_addr_advance; show_op_index = (op_index > 0 || (op_index + op_advance) % max_ops_per_instr > 0); op_index = (op_index + op_advance) % max_ops_per_instr; -- 2.39.5