aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorJan Kratochvil <jan.kratochvil@redhat.com>2009-07-14 16:57:18 +0000
committerJan Kratochvil <jan.kratochvil@redhat.com>2009-07-14 16:57:18 +0000
commit01a8f077edb6f09060c339831a9b3c7e5f45c812 (patch)
tree3fefc13e20780b54fb1e22ba7fd1b4a36e0787b4 /binutils
parent140033b39116ffc7d6ca946c43c19880e2e48a0c (diff)
downloadgdb-01a8f077edb6f09060c339831a9b3c7e5f45c812.zip
gdb-01a8f077edb6f09060c339831a9b3c7e5f45c812.tar.gz
gdb-01a8f077edb6f09060c339831a9b3c7e5f45c812.tar.bz2
binutils/
Support unordered .debug_info references to .debug_ranges. * dwarf.c (struct range_entry, range_entry_compar): New. (display_debug_ranges): Remove variables last_offset, first, j, seen_first_offset, use_debug_info and next. New variables range_entries and range_entry_fill. Create the sorted copy range_entries. Remove the FIXME error on detected unordered references. * dwarf.h (debug_info <range_lists>): New comment. binutils/testsuite/ * binutils-all/objcopy.exp (testranges): New test. * binutils-all/testranges.d, binutils-all/testranges.s: New files.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog10
-rw-r--r--binutils/dwarf.c213
-rw-r--r--binutils/dwarf.h1
-rw-r--r--binutils/testsuite/ChangeLog5
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp1
-rw-r--r--binutils/testsuite/binutils-all/testranges.d14
-rw-r--r--binutils/testsuite/binutils-all/testranges.s57
7 files changed, 195 insertions, 106 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 91ea69c..0eedd9d 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,13 @@
+2009-07-14 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ Support unordered .debug_info references to .debug_ranges.
+ * dwarf.c (struct range_entry, range_entry_compar): New.
+ (display_debug_ranges): Remove variables last_offset, first, j,
+ seen_first_offset, use_debug_info and next. New variables
+ range_entries and range_entry_fill. Create the sorted copy
+ range_entries. Remove the FIXME error on detected unordered references.
+ * dwarf.h (debug_info <range_lists>): New comment.
+
2009-07-14 Nick Clifton <nickc@redhat.com>
PR 10380
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 78f9884..5a42d79 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -3457,6 +3457,31 @@ display_debug_aranges (struct dwarf_section *section,
return 1;
}
+/* Each debug_information[x].range_lists[y] gets this representation for
+ sorting purposes. */
+
+struct range_entry
+ {
+ /* The debug_information[x].range_lists[y] value. */
+ unsigned long ranges_offset;
+
+ /* Original debug_information to find parameters of the data. */
+ debug_info *debug_info_p;
+ };
+
+/* Sort struct range_entry in ascending order of its RANGES_OFFSET. */
+
+static int
+range_entry_compar (const void *ap, const void *bp)
+{
+ const struct range_entry *a_re = ap;
+ const struct range_entry *b_re = bp;
+ const unsigned long a = a_re->ranges_offset;
+ const unsigned long b = b_re->ranges_offset;
+
+ return (a > b) - (b > a);
+}
+
static int
display_debug_ranges (struct dwarf_section *section,
void *file ATTRIBUTE_UNUSED)
@@ -3465,14 +3490,8 @@ display_debug_ranges (struct dwarf_section *section,
unsigned char *section_end;
unsigned long bytes;
unsigned char *section_begin = start;
- unsigned int num_range_list = 0;
- unsigned long last_offset = 0;
- unsigned int first = 0;
- unsigned int i;
- unsigned int j;
- int seen_first_offset = 0;
- int use_debug_info = 1;
- unsigned char *next;
+ unsigned int num_range_list, i;
+ struct range_entry *range_entries, *range_entry_fill;
bytes = section->size;
section_end = start + bytes;
@@ -3490,135 +3509,117 @@ display_debug_ranges (struct dwarf_section *section,
return 0;
}
- /* Check the order of range list in .debug_info section. If
- offsets of range lists are in the ascending order, we can
- use `debug_information' directly. */
+ num_range_list = 0;
for (i = 0; i < num_debug_info_entries; i++)
- {
- unsigned int num;
+ num_range_list += debug_information [i].num_range_lists;
- num = debug_information [i].num_range_lists;
- num_range_list += num;
+ if (num_range_list == 0)
+ error (_("No range lists in .debug_info section!\n"));
- /* Check if we can use `debug_information' directly. */
- if (use_debug_info && num != 0)
- {
- if (!seen_first_offset)
- {
- /* This is the first range list. */
- last_offset = debug_information [i].range_lists [0];
- first = i;
- seen_first_offset = 1;
- j = 1;
- }
- else
- j = 0;
+ range_entries = xmalloc (sizeof (*range_entries) * num_range_list);
+ range_entry_fill = range_entries;
- for (; j < num; j++)
- {
- if (last_offset >
- debug_information [i].range_lists [j])
- {
- use_debug_info = 0;
- break;
- }
- last_offset = debug_information [i].range_lists [j];
- }
+ for (i = 0; i < num_debug_info_entries; i++)
+ {
+ debug_info *debug_info_p = &debug_information[i];
+ unsigned int j;
+
+ for (j = 0; j < debug_info_p->num_range_lists; j++)
+ {
+ range_entry_fill->ranges_offset = debug_info_p->range_lists[j];
+ range_entry_fill->debug_info_p = debug_info_p;
+ range_entry_fill++;
}
}
- if (!use_debug_info)
- /* FIXME: Should we handle this case? */
- error (_("Range lists in .debug_info section aren't in ascending order!\n"));
-
- if (!seen_first_offset)
- error (_("No range lists in .debug_info section!\n"));
+ qsort (range_entries, num_range_list, sizeof (*range_entries),
+ range_entry_compar);
/* DWARF sections under Mach-O have non-zero addresses. */
- if (debug_information [first].num_range_lists > 0
- && debug_information [first].range_lists [0] != section->address)
+ if (range_entries[0].ranges_offset != section->address)
warn (_("Range lists in %s section start at 0x%lx\n"),
- section->name, debug_information [first].range_lists [0]);
+ section->name, range_entries[0].ranges_offset);
printf (_("Contents of the %s section:\n\n"), section->name);
printf (_(" Offset Begin End\n"));
- seen_first_offset = 0;
- for (i = first; i < num_debug_info_entries; i++)
+ for (i = 0; i < num_range_list; i++)
{
- dwarf_vma begin;
- dwarf_vma end;
- unsigned long offset;
+ struct range_entry *range_entry = &range_entries[i];
+ debug_info *debug_info_p = range_entry->debug_info_p;
unsigned int pointer_size;
+ unsigned long offset;
+ unsigned char *next;
unsigned long base_address;
- pointer_size = debug_information [i].pointer_size;
+ pointer_size = debug_info_p->pointer_size;
+
+ /* DWARF sections under Mach-O have non-zero addresses. */
+ offset = range_entry->ranges_offset - section->address;
+ next = section_begin + offset;
+ base_address = debug_info_p->base_address;
- for (j = 0; j < debug_information [i].num_range_lists; j++)
+ if (i > 0)
{
- /* DWARF sections under Mach-O have non-zero addresses. */
- offset = debug_information [i].range_lists [j] - section->address;
- next = section_begin + offset;
- base_address = debug_information [i].base_address;
+ if (start < next)
+ warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
+ (unsigned long) (start - section_begin),
+ (unsigned long) (next - section_begin), section->name);
+ else if (start > next)
+ warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
+ (unsigned long) (start - section_begin),
+ (unsigned long) (next - section_begin), section->name);
+ }
+ start = next;
- if (!seen_first_offset)
- seen_first_offset = 1;
- else
+ while (1)
+ {
+ 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. */
+ begin = byte_get_signed (start, pointer_size);
+ start += pointer_size;
+ end = byte_get_signed (start, pointer_size);
+ start += pointer_size;
+
+ printf (" %8.8lx ", offset);
+
+ if (begin == 0 && end == 0)
{
- if (start < next)
- warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
- (unsigned long) (start - section_begin),
- (unsigned long) (next - section_begin), section->name);
- else if (start > next)
- warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
- (unsigned long) (start - section_begin),
- (unsigned long) (next - section_begin), section->name);
+ printf (_("<End of list>\n"));
+ break;
}
- start = next;
- while (1)
+ /* Check base address specifiers. */
+ if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
{
- /* 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. */
- begin = byte_get_signed (start, pointer_size);
- start += pointer_size;
- end = byte_get_signed (start, pointer_size);
- start += pointer_size;
-
- printf (" %8.8lx ", offset);
-
- if (begin == 0 && end == 0)
- {
- printf (_("<End of list>\n"));
- break;
- }
-
- /* Check base address specifiers. */
- if (begin == (dwarf_vma) -1 && end != (dwarf_vma) -1)
- {
- base_address = end;
- print_dwarf_vma (begin, pointer_size);
- print_dwarf_vma (end, pointer_size);
- printf ("(base address)\n");
- continue;
- }
+ base_address = end;
+ print_dwarf_vma (begin, pointer_size);
+ print_dwarf_vma (end, pointer_size);
+ printf ("(base address)\n");
+ continue;
+ }
- print_dwarf_vma (begin + base_address, pointer_size);
- print_dwarf_vma (end + base_address, pointer_size);
+ print_dwarf_vma (begin + base_address, pointer_size);
+ print_dwarf_vma (end + base_address, pointer_size);
- if (begin == end)
- fputs (_("(start == end)"), stdout);
- else if (begin > end)
- fputs (_("(start > end)"), stdout);
+ if (begin == end)
+ fputs (_("(start == end)"), stdout);
+ else if (begin > end)
+ fputs (_("(start > end)"), stdout);
- putchar ('\n');
- }
+ putchar ('\n');
}
}
putchar ('\n');
+
+ free (range_entries);
+
return 1;
}
diff --git a/binutils/dwarf.h b/binutils/dwarf.h
index 6b61360..533400f 100644
--- a/binutils/dwarf.h
+++ b/binutils/dwarf.h
@@ -87,6 +87,7 @@ typedef struct
int *have_frame_base;
unsigned int num_loc_offsets;
unsigned int max_loc_offsets;
+ /* List of .debug_ranges offsets seen in this .debug_info. */
unsigned long *range_lists;
unsigned int num_range_lists;
unsigned int max_range_lists;
diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog
index 2c5db0c..cf8d81f 100644
--- a/binutils/testsuite/ChangeLog
+++ b/binutils/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-14 Jan Kratochvil <jan.kratochvil@redhat.com>
+
+ * binutils-all/objcopy.exp (testranges): New test.
+ * binutils-all/testranges.d, binutils-all/testranges.s: New files.
+
2009-06-25 Christopher Faylor <me+cygwin@cgf.cx>
* binutils-all/objcopy.exp: Move XFAIL from objcopy_test to
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 5f63bbb..aa1da72 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -874,3 +874,4 @@ if [is_elf_format] {
run_dump_test "localize-hidden-1"
}
run_dump_test "localize-hidden-2"
+run_dump_test "testranges"
diff --git a/binutils/testsuite/binutils-all/testranges.d b/binutils/testsuite/binutils-all/testranges.d
new file mode 100644
index 0000000..5aa7912
--- /dev/null
+++ b/binutils/testsuite/binutils-all/testranges.d
@@ -0,0 +1,14 @@
+#PROG: objcopy
+#source: testranges.s
+#readelf: -wR --wide
+#name: unordered .debug_info references to .debug_ranges
+
+Contents of the .debug_ranges section:
+
+ Offset Begin End
+ 00000000 00000001 00000002
+ 00000000 <End of list>
+ 00000010 00000000 00000002
+ 00000010 <End of list>
+
+#pass
diff --git a/binutils/testsuite/binutils-all/testranges.s b/binutils/testsuite/binutils-all/testranges.s
new file mode 100644
index 0000000..565e1a2
--- /dev/null
+++ b/binutils/testsuite/binutils-all/testranges.s
@@ -0,0 +1,57 @@
+# Test .debug_info can reference .debug_ranges entries without ordering the
+# offsets strictly as increasing.
+
+ .text
+start:
+ .byte 1
+sub:
+ .byte 2
+end:
+
+ .section .debug_ranges,"",@progbits
+range:
+
+range_sub:
+ .long sub, end
+ .long 0, 0 # range terminator
+
+range_cu:
+ .long start, end
+ .long 0, 0 # range terminator
+
+ .section .debug_info,"",@progbits
+ .long debugE - debugS # Length of Compilation Unit Info
+debugS:
+ .value 0x2 # DWARF version number
+ .long abbrev0 # Offset Into Abbrev. Section
+ .byte 0x4 # Pointer Size (in bytes)
+
+ .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit)
+ .long range_cu - range # DW_AT_ranges
+
+ .uleb128 0x2 # (DIE (0x6d) DW_TAG_subprogram)
+ .ascii "A\0" # DW_AT_name
+ .long range_sub - range # DW_AT_ranges
+debugE:
+
+ .section .debug_abbrev,"",@progbits
+abbrev0:
+ .uleb128 0x1 # (abbrev code)
+ .uleb128 0x11 # (TAG: DW_TAG_compile_unit)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x55 # (DW_AT_ranges)
+ .uleb128 0x6 # (DW_FORM_data4)
+ .byte 0x0
+ .byte 0x0
+
+ .uleb128 0x2 # (abbrev code)
+ .uleb128 0x2e # (TAG: DW_TAG_subprogram)
+ .byte 0x0 # DW_children_no
+ .uleb128 0x3 # (DW_AT_name)
+ .uleb128 0x8 # (DW_FORM_string)
+ .uleb128 0x55 # (DW_AT_ranges)
+ .uleb128 0x6 # (DW_FORM_data4)
+ .byte 0x0
+ .byte 0x0
+
+ .byte 0x0 # abbrevs terminator