This is the mail archive of the binutils-cvs@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]

[binutils-gdb/binutils-2_26-branch] objdump: Handle 32-bit base address in debug_ranges / debug_loc.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3a0dfbe2872116cad4f821624fd9d62d582485fe

commit 3a0dfbe2872116cad4f821624fd9d62d582485fe
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Fri Oct 16 11:58:02 2015 +0200

    objdump: Handle 32-bit base address in debug_ranges / debug_loc.
    
    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.

Diff:
---
 binutils/ChangeLog                           |   9 ++
 binutils/dwarf.c                             |  25 ++---
 binutils/testsuite/ChangeLog                 |   8 ++
 binutils/testsuite/binutils-all/dw2-ranges.S | 140 +++++++++++++++++++++++++++
 binutils/testsuite/binutils-all/dw2-ranges.W |  11 +++
 binutils/testsuite/binutils-all/objdump.exp  |  29 ++++++
 6 files changed, 211 insertions(+), 11 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 99b3f08..73efc3f 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,12 @@
+2015-12-10  Alan Modra  <amodra@gmail.com>
+
+	Apply from master.
+	2015-11-30  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-25  Tejas Belagod  <tejas.belagod@arm.com>
 
 	Backport from mainline:
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..c579c69 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2015-12-10  Alan Modra  <amodra@gmail.com>
+
+	Apply from master.
+	2015-11-30  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..66b27e3 100644
--- a/binutils/testsuite/binutils-all/objdump.exp
+++ b/binutils/testsuite/binutils-all/objdump.exp
@@ -244,6 +244,35 @@ 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"
+    }
+
+    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


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