summaryrefslogtreecommitdiff
path: root/binutils/dwarf.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-05-25 15:10:55 +0000
committerJakub Jelinek <jakub@redhat.com>2011-05-25 15:10:55 +0000
commit219eae8c3a18b42385dfaad2a64cf35873ed7acd (patch)
treec36e824e8bc6fe343d888e04ed456a3572f15f57 /binutils/dwarf.c
parentf1eb73e130a7b851ef380fe12c0021213ed9913d (diff)
downloadbinutils-redhat-219eae8c3a18b42385dfaad2a64cf35873ed7acd.tar.gz
* dwarf.c (loc_offsets): New variable.
(loc_offsets_compar): New routine. (display_debug_loc): Handle loc_offsets not being in ascending order and also a single .debug_loc entry being used multiple times.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r--binutils/dwarf.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 5102aec27e..db76ce8ef2 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -3488,6 +3488,19 @@ display_debug_abbrev (struct dwarf_section *section,
return 1;
}
+/* Sort array of indexes in ascending order of loc_offsets[idx]. */
+
+static dwarf_vma *loc_offsets;
+
+static int
+loc_offsets_compar (const void *ap, const void *bp)
+{
+ dwarf_vma a = loc_offsets[*(const unsigned int *) ap];
+ dwarf_vma b = loc_offsets[*(const unsigned int *) bp];
+
+ return (a > b) - (b > a);
+}
+
static int
display_debug_loc (struct dwarf_section *section, void *file)
{
@@ -3500,9 +3513,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
unsigned int first = 0;
unsigned int i;
unsigned int j;
+ unsigned int k;
int seen_first_offset = 0;
- int use_debug_info = 1;
+ int locs_sorted = 1;
unsigned char *next;
+ unsigned int *array = NULL;
bytes = section->size;
section_end = start + bytes;
@@ -3528,10 +3543,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
unsigned int num;
num = debug_information [i].num_loc_offsets;
- num_loc_list += num;
+ if (num > num_loc_list)
+ num_loc_list = num;
/* Check if we can use `debug_information' directly. */
- if (use_debug_info && num != 0)
+ if (locs_sorted && num != 0)
{
if (!seen_first_offset)
{
@@ -3549,7 +3565,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
if (last_offset >
debug_information [i].loc_offsets [j])
{
- use_debug_info = 0;
+ locs_sorted = 0;
break;
}
last_offset = debug_information [i].loc_offsets [j];
@@ -3557,10 +3573,6 @@ display_debug_loc (struct dwarf_section *section, void *file)
}
}
- if (!use_debug_info)
- /* FIXME: Should we handle this case? */
- error (_("Location lists in .debug_info section aren't in ascending order!\n"));
-
if (!seen_first_offset)
error (_("No location lists in .debug_info section!\n"));
@@ -3571,6 +3583,8 @@ display_debug_loc (struct dwarf_section *section, void *file)
section->name,
dwarf_vmatoa ("x", debug_information [first].loc_offsets [0]));
+ if (!locs_sorted)
+ array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int));
printf (_("Contents of the %s section:\n\n"), section->name);
printf (_(" Offset Begin End Expression\n"));
@@ -3593,9 +3607,23 @@ display_debug_loc (struct dwarf_section *section, void *file)
cu_offset = debug_information [i].cu_offset;
offset_size = debug_information [i].offset_size;
dwarf_version = debug_information [i].dwarf_version;
+ if (!locs_sorted)
+ {
+ for (k = 0; k < debug_information [i].num_loc_offsets; k++)
+ array[k] = k;
+ loc_offsets = debug_information [i].loc_offsets;
+ qsort (array, debug_information [i].num_loc_offsets,
+ sizeof (*array), loc_offsets_compar);
+ }
- for (j = 0; j < debug_information [i].num_loc_offsets; j++)
+ for (k = 0; k < debug_information [i].num_loc_offsets; k++)
{
+ j = locs_sorted ? k : array[k];
+ if (k
+ && debug_information [i].loc_offsets [locs_sorted
+ ? k - 1 : array [k - 1]]
+ == debug_information [i].loc_offsets [j])
+ continue;
has_frame_base = debug_information [i].have_frame_base [j];
/* DWARF sections under Mach-O have non-zero addresses. */
offset = debug_information [i].loc_offsets [j] - section->address;
@@ -3709,6 +3737,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
warn (_("There are %ld unused bytes at the end of section %s\n"),
(long) (section_end - start), section->name);
putchar ('\n');
+ free (array);
return 1;
}