This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ARC port broken reloc processing


* Alan Modra <amodra@gmail.com> [2015-11-27 14:09:38 +1030]:

> On Fri, Nov 27, 2015 at 01:14:12PM +1030, Alan Modra wrote:
> > Why allow zero for the base address, and the variant ranges?
> 
> I had a look.  If it was for arc-elf, please don't weaken the test.
> arc-elf reloc processing via howto is broken.

Here's a revised patch for the base address in debug_ranges issue, for
now I setup have setup arc to xfail the new test.

The arc patch I posted in the other mail fixes this issue, but it
would be nice to push this patch regardless of whether the arc fix
gets merged or not.

Is this OK?

Thanks,
Andrew

---

When the DWARF address size is 32-bit, but the host machine is 64-bit,
objdump fails to spot base addresses specified in the .debug_ranges and
.debug_loc lists.

As an example, here is the output when dumping an example .debug_ranges
section with the pre-patched objdump:

    Contents of the .debug_ranges section:

        Offset   Begin    End
        00000000 ffffffff 00000004 (start > end)
        00000000 00000000 00000004
        00000000 ffffffff 00000008 (start > end)
        00000000 00000000 00000004
        00000000 <End of list>

And this is what the same section looks like when dumped with the
patched version of objdump:

    Contents of the .debug_ranges section:

        Offset   Begin    End
        00000000 ffffffff 00000004 (base address)
        00000000 00000004 00000008
        00000000 ffffffff 00000008 (base address)
        00000000 00000008 0000000c
        00000000 <End of list>

binutils/ChangeLog:

	* dwarf.c (is_max_address): New function.
	(display_loc_list): Remove out of date comment, use
	is_max_address.
	(display_debug_ranges): Likewise.

binutils/testsuite/ChangeLog:

	* binutils-all/objdump.exp: Add test for .debug_ranges decode.
	* binutils-all/dw2-ranges.S: New file.
	* binutils-all/dw2-ranges.W: New file.
---
 binutils/ChangeLog                           |   7 ++
 binutils/dwarf.c                             |  25 ++---
 binutils/testsuite/ChangeLog                 |   6 ++
 binutils/testsuite/binutils-all/dw2-ranges.S | 140 +++++++++++++++++++++++++++
 binutils/testsuite/binutils-all/dw2-ranges.W |  11 +++
 binutils/testsuite/binutils-all/objdump.exp  |  36 +++++++
 6 files changed, 214 insertions(+), 11 deletions(-)
 create mode 100644 binutils/testsuite/binutils-all/dw2-ranges.S
 create mode 100644 binutils/testsuite/binutils-all/dw2-ranges.W

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index e1d8ea3..f947f08 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,10 @@
+2015-11-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* dwarf.c (is_max_address): New function.
+	(display_loc_list): Remove out of date comment, use
+	is_max_address.
+	(display_debug_ranges): Likewise.
+
 2015-11-20  Ronald Hoogenboom  <hoogenboom30@zonnet.nl>
 
 	* objcopy.c (parse_symflags): Use xstrndup in place of strndup.
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 9f1baea..03e0117 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -4326,6 +4326,16 @@ display_debug_abbrev (struct dwarf_section *section,
   return 1;
 }
 
+/* Return true when ADDR is the maximum address, when addresses are
+   POINTER_SIZE bytes long.  */
+
+static bfd_boolean
+is_max_address (dwarf_vma addr, unsigned int pointer_size)
+{
+  dwarf_vma mask = ~(~(dwarf_vma) 1 << (pointer_size * 8 - 1));
+  return ((addr & mask) == mask);
+}
+
 /* Display a location list from a normal (ie, non-dwo) .debug_loc section.  */
 
 static void
@@ -4380,10 +4390,6 @@ display_loc_list (struct dwarf_section *section,
 
       printf ("    %8.8lx ", off);
 
-      /* Note: we use sign extension here in order to be sure that we can detect
-	 the -1 escape value.  Sign extension into the top 32 bits of a 32-bit
-	 address will not affect the values that we display since we always show
-	 hex values, and always the bottom 32-bits.  */
       SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, section_end);
       SAFE_BYTE_GET_AND_INC (end, start, pointer_size, section_end);
 
@@ -4404,7 +4410,8 @@ display_loc_list (struct dwarf_section *section,
 	}
 
       /* Check base address specifiers.  */
-      if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
+      if (is_max_address (begin, pointer_size)
+          && !is_max_address (end, pointer_size))
 	{
 	  base_address = end;
 	  print_dwarf_vma (begin, pointer_size);
@@ -5202,11 +5209,6 @@ display_debug_ranges (struct dwarf_section *section,
 	  dwarf_vma begin;
 	  dwarf_vma end;
 
-	  /* Note: we use sign extension here in order to be sure that
-	     we can detect the -1 escape value.  Sign extension into the
-	     top 32 bits of a 32-bit address will not affect the values
-	     that we display since we always show hex values, and always
-	     the bottom 32-bits.  */
 	  SAFE_BYTE_GET_AND_INC (begin, start, pointer_size, finish);
 	  if (start >= finish)
 	    break;
@@ -5221,7 +5223,8 @@ display_debug_ranges (struct dwarf_section *section,
 	    }
 
 	  /* Check base address specifiers.  */
-	  if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
+          if (is_max_address (begin, pointer_size)
+              && !is_max_address (end, pointer_size))
 	    {
 	      base_address = end;
 	      print_dwarf_vma (begin, pointer_size);
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 64348e6..bc447d8 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-11-26  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* binutils-all/objdump.exp: Add test for .debug_ranges decode.
+	* binutils-all/dw2-ranges.S: New file.
+	* binutils-all/dw2-ranges.W: New file.
+
 2015-10-22  Alan Modra  <amodra@gmail.com>
 
 	* binutils-all/add-symbol.d: Run test on mips.  Support either
diff --git a/binutils/testsuite/binutils-all/dw2-ranges.S b/binutils/testsuite/binutils-all/dw2-ranges.S
new file mode 100644
index 0000000..74d7287
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dw2-ranges.S
@@ -0,0 +1,140 @@
+/* Copyright (C) 2015 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 tests makes use of the .debug_ranges section, especially,
+   making sure that the base address encoding scheme is used.  */
+
+/* Dummy function to provide debug information for.  */
+
+	.text
+	.globl _start
+_start:
+	.4byte 0
+.Lbegin_text1:
+	.globl func_cu1
+	.type func_cu1, %function
+func_cu1:
+.Lbegin_func_cu1:
+	.4byte 0
+.Lend_func_cu1:
+	.size func_cu1, .-func_cu1
+.Lend_text1:
+
+.Lbegin_text2:
+	.globl func_cu2
+	.type func_cu2, %function
+func_cu2:
+.Lbegin_func_cu2:
+	.4byte 0
+.Lend_func_cu2:
+	.size func_cu2, .-func_cu2
+.Lend_text2:
+
+/* Debug information */
+
+	.section .debug_info
+.Lcu1_begin:
+	/* CU header */
+	.4byte	.Lcu1_end - .Lcu1_start		/* Length of Compilation Unit */
+.Lcu1_start:
+	.2byte	2				/* DWARF Version */
+	.4byte	.Labbrev1_begin			/* Offset into abbrev section */
+	.byte	4				/* Pointer size */
+
+	/* CU die */
+	.uleb128 1				/* Abbrev: DW_TAG_compile_unit */
+        .4byte  .Lrange1_begin
+	.ascii	"file1.c\0"			/* DW_AT_name */
+	.byte	1				/* DW_AT_language (C) */
+
+	/* func_cu1 */
+	.uleb128	2			/* Abbrev: DW_TAG_subprogram */
+	.ascii		"func_cu1\0"		/* DW_AT_name */
+	.4byte		.Ltype_int-.Lcu1_begin	/* DW_AT_type */
+	.4byte		.Lbegin_func_cu1	/* DW_AT_low_pc */
+	.4byte		.Lend_func_cu1		/* DW_AT_high_pc */
+
+	/* func_cu1 */
+	.uleb128	2			/* Abbrev: DW_TAG_subprogram */
+	.ascii		"func_cu2\0"		/* DW_AT_name */
+	.4byte		.Ltype_int-.Lcu1_begin	/* DW_AT_type */
+	.4byte		.Lbegin_func_cu2	/* DW_AT_low_pc */
+	.4byte		.Lend_func_cu2		/* DW_AT_high_pc */
+
+.Ltype_int:
+	.uleb128	3			/* Abbrev: DW_TAG_base_type */
+	.ascii		"int\0"			/* DW_AT_name */
+	.byte		4			/* DW_AT_byte_size */
+	.byte		5			/* DW_AT_encoding */
+
+	.byte		0			/* End of children of CU */
+
+.Lcu1_end:
+
+        .section .debug_ranges
+.Lrange1_begin:
+        .4byte  0xffffffff                      /* base address marker */
+	.4byte	.Lbegin_text1                   /* base address */
+        .4byte  0                               /* start offset */
+	.4byte	.Lend_text1 - .Lbegin_text1     /* end offset */
+        .4byte  0xffffffff                      /* base address marker */
+	.4byte	.Lbegin_text2                   /* base address */
+        .4byte  0                               /* start offset */
+	.4byte	.Lend_text2 - .Lbegin_text2     /* end offset */
+        .4byte  0                               /* End marker (Part 1) */
+        .4byte  0                               /* End marker (Part 2) */
+
+	.section .debug_abbrev
+.Labbrev1_begin:
+	.uleb128	1			/* Abbrev code */
+	.uleb128	0x11			/* DW_TAG_compile_unit */
+	.byte		1			/* has_children */
+        .uleb128	0x55			/* DW_AT_ranges */
+	.uleb128	0x17			/* DW_FORM_sec_offset */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x13			/* DW_AT_language */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	2			/* Abbrev code */
+	.uleb128	0x2e			/* DW_TAG_subprogram */
+	.byte		0			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0x49			/* DW_AT_type */
+	.uleb128	0x13			/* DW_FORM_ref4 */
+	.uleb128	0x11			/* DW_AT_low_pc */
+	.uleb128	0x1			/* DW_FORM_addr */
+	.uleb128	0x12			/* DW_AT_high_pc */
+	.uleb128	0x1			/* DW_FORM_addr */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.uleb128	3			/* Abbrev code */
+	.uleb128	0x24			/* DW_TAG_base_type */
+	.byte		0			/* has_children */
+	.uleb128	0x3			/* DW_AT_name */
+	.uleb128	0x8			/* DW_FORM_string */
+	.uleb128	0xb			/* DW_AT_byte_size */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.uleb128	0x3e			/* DW_AT_encoding */
+	.uleb128	0xb			/* DW_FORM_data1 */
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
+
+	.byte		0x0			/* Terminator */
+	.byte		0x0			/* Terminator */
diff --git a/binutils/testsuite/binutils-all/dw2-ranges.W b/binutils/testsuite/binutils-all/dw2-ranges.W
new file mode 100644
index 0000000..4dfd248
--- /dev/null
+++ b/binutils/testsuite/binutils-all/dw2-ranges.W
@@ -0,0 +1,11 @@
+
+.*:     file format .*
+
+Contents of the \.debug_ranges section:
+
+    Offset   Begin    End
+    00000000 ffffffff 00000004 \(base address\)
+    00000000 00000004 00000008 
+    00000000 ffffffff 00000008 \(base address\)
+    00000000 00000008 0000000c 
+    00000000 <End of list>
diff --git a/binutils/testsuite/binutils-all/objdump.exp b/binutils/testsuite/binutils-all/objdump.exp
index c3cbb13..3ff717e 100644
--- a/binutils/testsuite/binutils-all/objdump.exp
+++ b/binutils/testsuite/binutils-all/objdump.exp
@@ -244,6 +244,42 @@ if { ![is_elf_format]
     }
 }
 
+# Test objdump -W on a file containing debug_ranges information.
+
+if { ![is_elf_format] } then {
+    unsupported "objdump debug_ranges test"
+} elseif { ![binutils_assemble $srcdir/$subdir/dw2-ranges.S tmpdir/dw2-ranges.o] } then {
+    fail "objdump debug_ranges test"
+} else {
+    if [is_remote host] {
+	set ranges_testfile [remote_download host tmpdir/dw2-ranges.o]
+    } else {
+	set ranges_testfile tmpdir/dw2-ranges.o
+    }
+
+    set got [remote_exec host "$OBJDUMP $OBJDUMPFLAGS --dwarf=Ranges $ranges_testfile" "" "/dev/null" "objdump.out"]
+
+    if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+	fail "objdump -W for debug_ranges (reason: unexpected output)"
+	send_log $got
+	send_log "\n"
+    }
+
+    # We skip this test for msp430-elf as its use of DIFF relocations
+    # results in the wrong result when viewing the ranges within an
+    # object file (the result within a fully linked executable should
+    # be fine).  We skip the test on arc, as currently it's use of
+    # bfd_perform_relococation is broken, the dst mask is missing.
+    setup_xfail "arc-*-*" "msp430-*-elf"
+
+    if { [regexp_diff objdump.out $srcdir/$subdir/dw2-ranges.W] } then {
+	fail "objdump -W for debug_ranges"
+    } else {
+	pass "objdump -W for debug_ranges"
+    }
+}
+
+
 # Options which are not tested: -a -d -D -R -T -x -l --stabs
 # I don't see any generic way to test any of these other than -a.
 # Tests could be written for specific targets, and that should be done
-- 
2.5.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]