[COMMITTED] readelf: Fix advance_pc to use op_addr_advance, not just op_advance.

2018-04-16 Thread Mark Wielaard
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 068c87b..2d525e6 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 8c0ef6c..45fc826 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;
-- 
1.8.3.1



[COMMITTED] tests: Test readelf --debug-dump=[decoded]line with min_inst_len > 1.

2018-04-16 Thread Mark Wielaard
This testcase tests the fix for the readelf --debug-dump=line bug fixed
in commit 40b1f18 "readelf: Fix advance_pc to use op_addr_advance, not
just op_advance."

This tests both the --debug-dump=line (readelf) implementation and the
--debug-dump=decodedline (libdw) implementation. The first fails without
the bug fix. The second was already correct.

Signed-off-by: Mark Wielaard 
---
 tests/ChangeLog|   6 +++
 tests/Makefile.am  |   1 +
 tests/run-readelf-line.sh  |  89 +
 tests/testfile-ppc64-min-instr.bz2 | Bin 0 -> 3106 bytes
 4 files changed, 96 insertions(+)
 create mode 100755 tests/testfile-ppc64-min-instr.bz2

diff --git a/tests/ChangeLog b/tests/ChangeLog
index c9403fb..27e5bd8 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2018-04-16  Mark Wielaard  
+
+   * testfile-ppc64-min-instr.bz2: New testfile.
+   * run-readelf-line.sh: Run against testfile-ppc64-min-instr.bz2.
+   * Makefile.am (EXTRA_DIST): Add testfile-ppc64-min-instr.bz2.
+
 2018-04-11  Mark Wielaard  
 
* run-addrcfi.sh: Adjust expected rule for aarch64 sp.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a8cc2df..16abfb0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -230,6 +230,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
 run-readelf-macro.sh testfilemacro.bz2 \
 run-readelf-loc.sh testfileloc.bz2 \
 run-readelf-aranges.sh run-readelf-line.sh testfilefoobarbaz.bz2 \
+testfile-ppc64-min-instr.bz2 \
 run-readelf-z.sh \
 run-readelf-dwz-multi.sh libtestfile_multi_shared.so.bz2 \
 testfile_multi.dwz.bz2 testfile_multi_main.bz2 \
diff --git a/tests/run-readelf-line.sh b/tests/run-readelf-line.sh
index 32bcf9d..f93bf47 100755
--- a/tests/run-readelf-line.sh
+++ b/tests/run-readelf-line.sh
@@ -256,4 +256,93 @@ DWARF section [30] '.debug_line' at offset 0x15f6:
 
 EOF
 
+# A .debug_line table with mininum instruction length > 1.
+#
+# = hello.c
+# #include 
+#
+# int
+# main (int argc, char **argv)
+# {
+#   printf ("Hello, %s\n", (argc > 0
+#? argv[1]: "World"));
+#   return 0;
+# }
+#
+# clang version 5.0.1 (tags/RELEASE_501/final)
+# Target: powerpc64-unknown-linux-gnu
+# clang -g -O2 -o testfile-ppc64-min-instr hello.c
+testfiles testfile-ppc64-min-instr
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=line 
testfile-ppc64-min-instr <<\EOF
+
+DWARF section [29] '.debug_line' at offset 0xdf6:
+
+Table at offset 0:
+
+ Length: 69
+ DWARF version:  2
+ Prologue length:30
+ Minimum instruction length: 4
+ Maximum operations per instruction: 1
+ Initial value if 'is_stmt': 1
+ Line base:  -5
+ Line range: 14
+ Opcode base:13
+
+Opcodes:
+  [ 1]  0 arguments
+  [ 2]  1 argument
+  [ 3]  1 argument
+  [ 4]  1 argument
+  [ 5]  1 argument
+  [ 6]  0 arguments
+  [ 7]  0 arguments
+  [ 8]  0 arguments
+  [ 9]  1 argument
+  [10]  0 arguments
+  [11]  0 arguments
+  [12]  1 argument
+
+Directory table:
+
+File name table:
+ Entry Dir   Time  Size  Name
+ 1 0 0 0 hello.c
+
+Line number statements:
+ [28] extended opcode 2:  set address to 0x15a4 
+ [33] special opcode 22: address+0 = 0x15a4 , line+4 = 5
+ [34] set column to 27
+ [36] set prologue end flag
+ [37] special opcode 19: address+0 = 0x15a4 , line+1 = 6
+ [38] set column to 8
+ [3a] special opcode 47: address+8 = 0x15ac , line+1 = 7
+ [3b] set 'is_stmt' to 0
+ [3c] advance line by constant -7 to 0
+ [3e] special opcode 32: address+4 = 0x15b0 , line+0 = 0
+ [3f] set column to 3
+ [41] set 'is_stmt' to 1
+ [42] special opcode 108: address+24 = 0x15c8 , line+6 = 6
+ [43] special opcode 76: address+16 = 0x15d8 , line+2 = 8
+ [44] advance address by 32 to 0x15f8
+ [46] extended opcode 1:  end of sequence
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=decodedline 
testfile-ppc64-min-instr <<\EOF
+
+DWARF section [29] '.debug_line' at offset 0xdf6:
+
+ CU [b] hello.c
+  line:col SBPE* disc isa op address (Statement Block Prologue Epilogue *End)
+  /home/fedora/mjw/hello.c (mtime: 0, length: 0)
+ 5:0   S0   0  0 0x15a4 
+ 6:27  S P  0   0  0 0x15a4 
+ 7:8   S0   0  0 0x15ac 
+ 0:80   0  0 0x15b0 
+ 6:3   S0   0  0 0x15c8 
+ 8:3   S0   0  0 0x15d8 
+ 8:3   S   *0   0  0 0x15f7 
+
+EOF
 exit 0
diff --git a/tests/testfile-ppc64-min-instr.bz2 
b/tests/testfile-ppc64-min-instr.bz2
new file mode 100755
index 
..85bef57be5819daecec07592b3e5044c4ef4953f
GIT binary patch
literal 3106
zcmV+-