Fix lost line info for symbol at addr zero
authorOmair Javaid <omair.javaid@linaro.org>
Tue, 15 May 2018 14:04:21 +0000 (19:04 +0500)
committerOmair Javaid <omair.javaid@linaro.org>
Wed, 27 Jun 2018 15:12:49 +0000 (20:12 +0500)
This patch fixes a unique condition where GDB fails to provide line
information of symbol at address zero when code is compiled with text
address zero but loaded at an offset > 0.

For example lets compile following code snippet:

int main() {
  return 0;
}

gcc -O0 -g3 -nostdlib -emain -Wl,-Ttext=0x00 -o file.out file.c

Start gdb and run:

add-symbol-file file.out 0xffff0000
info line main

GDB will return error saying no line info is available for the symbol.

This is a direct consequence of the fix for PR 12528 where GDB tries to ignore
line table for a function which has been garbage collected by the linker.

As the garbage collected symbols are sent to address zero GDB assumes a symbol
actually placed at address zero as garbage collected.

This was fixed with an additional check address < lowpc. But when symbol is
loaded at an offset lowpc becomes lowpc + offset while no offset is added to
address rather final symbol address is calculated based on baseaddr and address
added together. So in case where symbols are loaded at an offset the condition
address < lowpc will always return true.

This patch fixes this by comparing address against a non offset lowpc.

This patch also adds a GDB test case to replicate this behavior.

gdb:

2018-06-27  Omair Javaid  <omair.javaid@linaro.org>

PR gdb/21695
* dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.
(dwarf_decode_lines_1): Adjust.

gdb/testsuite:

2018-06-27  Omair Javaid  <omair.javaid@linaro.org>

PR gdb/21695
* gdb.base/infoline-reloc-main-from-zero.exp: New test.
* gdb.base/infoline-reloc-main-from-zero.c: New file.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c [new file with mode: 0644]
gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp [new file with mode: 0644]

index c315246c8900fe9a53a22998d3ced498a905635d..a3882f52a31b2d198c0fbe230e13d63bfa182437 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-27  Omair Javaid  <omair.javaid@linaro.org>
+
+       PR gdb/21695
+       * dwarf2read.c (lnp_state_machine::check_line_address): Update declaration.
+       (dwarf_decode_lines_1): Adjust.
+
 2018-06-27  Simon Marchi  <simon.marchi@ericsson.com>
 
        * fbsd-nat.h (class fbsd_nat_target) <find_memory_regions>: Add
index 4ad05274064d8f33d8bfe9fec4ed315b98decbcd..083ec91df8f45687fabd8e97508a45be02571360 100644 (file)
@@ -20305,11 +20305,11 @@ public:
      we're processing the end of a sequence.  */
   void record_line (bool end_sequence);
 
-  /* Check address and if invalid nop-out the rest of the lines in this
-     sequence.  */
+  /* Check ADDRESS is zero and less than UNRELOCATED_LOWPC and if true
+     nop-out rest of the lines in this sequence.  */
   void check_line_address (struct dwarf2_cu *cu,
                           const gdb_byte *line_ptr,
-                          CORE_ADDR lowpc, CORE_ADDR address);
+                          CORE_ADDR unrelocated_lowpc, CORE_ADDR address);
 
   void handle_set_discriminator (unsigned int discriminator)
   {
@@ -20653,14 +20653,14 @@ lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,
 void
 lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
                                       const gdb_byte *line_ptr,
-                                      CORE_ADDR lowpc, CORE_ADDR address)
+                                      CORE_ADDR unrelocated_lowpc, CORE_ADDR address)
 {
-  /* If address < lowpc then it's not a usable value, it's outside the
-     pc range of the CU.  However, we restrict the test to only address
-     values of zero to preserve GDB's previous behaviour which is to
-     handle the specific case of a function being GC'd by the linker.  */
+  /* If ADDRESS < UNRELOCATED_LOWPC then it's not a usable value, it's outside
+     the pc range of the CU.  However, we restrict the test to only ADDRESS
+     values of zero to preserve GDB's previous behaviour which is to handle
+     the specific case of a function being GC'd by the linker.  */
 
-  if (address == 0 && address < lowpc)
+  if (address == 0 && address < unrelocated_lowpc)
     {
       /* This line table is for a function which has been
         GCd by the linker.  Ignore it.  PR gdb/12528 */
@@ -20754,7 +20754,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
                    line_ptr += bytes_read;
 
                    state_machine.check_line_address (cu, line_ptr,
-                                                     lowpc, address);
+                                                     lowpc - baseaddr, address);
                    state_machine.handle_set_address (baseaddr, address);
                  }
                  break;
index b2901dbcc5e935a50793cbfcfde43be700d56226..edebc81a39c1ee4b99070e4d6887567aead8241f 100644 (file)
@@ -1,3 +1,9 @@
+2018-06-27  Omair Javaid  <omair.javaid@linaro.org>
+
+       PR gdb/21695
+       * gdb.base/infoline-reloc-main-from-zero.exp: New test.
+       * gdb.base/infoline-reloc-main-from-zero.c: New file.
+
 2018-06-26  Tom Tromey  <tom@tromey.com>
 
        PR rust/22574:
diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.c
new file mode 100644 (file)
index 0000000..f5e5c26
--- /dev/null
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+// Test case for PR gdb/21695
+
+int
+main ()
+{
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp b/gdb/testsuite/gdb.base/infoline-reloc-main-from-zero.exp
new file mode 100644 (file)
index 0000000..d525460
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite
+
+#
+# PR gdb/21695
+# This tests if gdb can display line information of relocated symbols in the
+# case where executable text section was at address zero before relocation.
+#
+
+standard_testfile .c
+
+if [get_compiler_info] {
+    return -1
+}
+
+# Build executable with stripped startup code and text section starting at zero
+
+set opts {debug "additional_flags=-nostdlib -emain -Wl,-Ttext=0x00"}
+
+if {[build_executable $testfile.exp $testfile $srcfile $opts] == -1} {
+    untested "failed to compile"
+    return -1
+}
+
+clean_restart
+
+# Load symbols at an offset 0xffff0000 using add-symbol-file
+
+gdb_test "add-symbol-file $binfile 0xffff0000" \
+    "Reading symbols from .*" \
+    "add-symbol-file" \
+    "add symbol table from file \".*\" at.*\\(y or n\\) " "y"
+
+# Check if we are able to read offset adjusted line information of main
+    
+gdb_test "info line main" \
+       "Line.*starts at address 0xffff0000.*and ends at.*"