aboutsummaryrefslogtreecommitdiff
path: root/binutils/dwarf.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2015-10-16 11:58:02 +0200
committerAndrew Burgess <andrew.burgess@embecosm.com>2015-11-30 13:28:26 +0000
commit42bcef4ad646732e0684557fe08b74dd0c5aa7e9 (patch)
tree2acf45f8515750719a487e904f25e08686c84572 /binutils/dwarf.c
parentbc301448c07afbf8aa70f2808be68dc8c50c9098 (diff)
downloadgdb-42bcef4ad646732e0684557fe08b74dd0c5aa7e9.zip
gdb-42bcef4ad646732e0684557fe08b74dd0c5aa7e9.tar.gz
gdb-42bcef4ad646732e0684557fe08b74dd0c5aa7e9.tar.bz2
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.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r--binutils/dwarf.c25
1 files changed, 14 insertions, 11 deletions
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);