aboutsummaryrefslogtreecommitdiff
path: root/gas/dwarf2dbg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/dwarf2dbg.c')
-rw-r--r--gas/dwarf2dbg.c69
1 files changed, 36 insertions, 33 deletions
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 2963e52..84c9661 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -171,10 +171,18 @@ struct line_entry
struct dwarf2_line_info loc;
};
-/* Don't change the offset of next in line_entry. set_or_check_view
- calls in dwarf2_gen_line_info_1 depend on it. */
-static char unused[offsetof(struct line_entry, next) ? -1 : 1]
-ATTRIBUTE_UNUSED;
+/* Given line_entry list HEAD and PTAIL pointers, return a pointer to
+ the last line_entry on the list. */
+static inline struct line_entry *
+line_entry_at_tail (void *head, struct line_entry **ptail)
+{
+ /* If the list is empty ptail points at head. */
+ if (head == NULL)
+ return NULL;
+ /* Otherwise ptail points to line_entry.next of the last entry. */
+ void *p = (char *) ptail - offsetof (struct line_entry, next);
+ return p;
+}
struct line_subseg
{
@@ -528,7 +536,8 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
/* Subseg heads are chained to previous subsegs in
dwarf2_finish. */
if (loc->filenum != -1u && loc->u.view && lss->head)
- set_or_check_view (e, (struct line_entry *) lss->ptail, lss->head);
+ set_or_check_view (e, line_entry_at_tail (lss->head, lss->ptail),
+ lss->head);
*lss->ptail = e;
lss->ptail = &e->next;
@@ -650,9 +659,8 @@ get_directory_table_entry (const char *dirname,
is set to the current build directory). Since we are
about to create a directory entry that is not the
same, allocate the current directory first. */
- (void) get_directory_table_entry (pwd, file0_dirname,
- strlen (pwd), true);
- d = 1;
+ (void) get_directory_table_entry (pwd, pwd, strlen (pwd), true);
+ d = dirs_in_use;
}
else
d = 0;
@@ -678,18 +686,17 @@ get_directory_table_entry (const char *dirname,
}
static bool
-assign_file_to_slot (unsigned int i, const char *file, unsigned int dir)
+assign_file_to_slot (valueT i, const char *file, unsigned int dir)
{
if (i >= files_allocated)
{
unsigned int want = i + 32;
- /* Catch wraparound. */
- if (want < files_allocated
- || want < i
- || want > UINT_MAX / sizeof (struct file_entry))
+ /* If this array is taking 1G or more, someone is using silly
+ file numbers. */
+ if (want < i || want > UINT_MAX / 4 / sizeof (struct file_entry))
{
- as_bad (_("file number %u is too big"), i);
+ as_bad (_("file number %" PRIu64 " is too big"), (uint64_t) i);
return false;
}
@@ -843,7 +850,7 @@ purge_generated_debug (bool thelot)
static bool
allocate_filename_to_slot (const char *dirname,
const char *filename,
- unsigned int num,
+ valueT num,
bool with_md5)
{
const char *file;
@@ -921,8 +928,9 @@ allocate_filename_to_slot (const char *dirname,
}
fail:
- as_bad (_("file table slot %u is already occupied by a different file (%s%s%s vs %s%s%s)"),
- num,
+ as_bad (_("file table slot %u is already occupied by a different file"
+ " (%s%s%s vs %s%s%s)"),
+ (unsigned int) num,
dir == NULL ? "" : dir,
dir == NULL ? "" : "/",
files[num].filename,
@@ -968,7 +976,7 @@ allocate_filename_to_slot (const char *dirname,
d = get_directory_table_entry (dirname, file0_dirname, dirlen, num == 0);
i = num;
- if (! assign_file_to_slot (i, file, d))
+ if (!assign_file_to_slot (num, file, d))
return false;
if (with_md5)
@@ -1228,15 +1236,7 @@ dwarf2_directive_filename (void)
purge_generated_debug (false);
debug_type = DEBUG_NONE;
- if (num != (unsigned int) num
- || num >= (size_t) -1 / sizeof (struct file_entry) - 32)
- {
- as_bad (_("file number %lu is too big"), (unsigned long) num);
- return NULL;
- }
-
- if (! allocate_filename_to_slot (dirname, filename, (unsigned int) num,
- with_md5))
+ if (!allocate_filename_to_slot (dirname, filename, num, with_md5))
return NULL;
return filename;
@@ -1632,7 +1632,7 @@ size_inc_line_addr (int line_delta, addressT addr_delta)
}
/* Bias the line delta by the base. */
- tmp = line_delta - DWARF2_LINE_BASE;
+ tmp = (unsigned) line_delta - DWARF2_LINE_BASE;
/* If the line increment is out of range of a special opcode, we
must encode it with DW_LNS_advance_line. */
@@ -1703,7 +1703,7 @@ emit_inc_line_addr (int line_delta, addressT addr_delta, char *p, int len)
}
/* Bias the line delta by the base. */
- tmp = line_delta - DWARF2_LINE_BASE;
+ tmp = (unsigned) line_delta - DWARF2_LINE_BASE;
/* If the line increment is out of range of a special opcode, we
must encode it with DW_LNS_advance_line. */
@@ -3028,6 +3028,11 @@ out_debug_str (segT str_seg, symbolS **name_sym, symbolS **comp_dir_sym,
int len;
int first_file = DWARF2_LINE_VERSION > 4 ? 0 : 1;
+ if (files_in_use == 0)
+ abort ();
+ if (first_file == 0 && files[first_file].filename == NULL)
+ first_file = 1;
+
subseg_set (str_seg, 0);
/* DW_AT_name. We don't have the actual file name that was present
@@ -3035,8 +3040,7 @@ out_debug_str (segT str_seg, symbolS **name_sym, symbolS **comp_dir_sym,
We're not supposed to get called unless at least one line number
entry was emitted, so this should always be defined. */
*name_sym = symbol_temp_new_now_octets ();
- if (files_in_use == 0)
- abort ();
+
if (files[first_file].dir)
{
char *dirname = remap_debug_filename (dirs[files[first_file].dir]);
@@ -3199,8 +3203,7 @@ dwarf2_finish (void)
/* Link the first view of subsequent subsections to the
previous view. */
if (lss->head && lss->head->loc.u.view)
- set_or_check_view (lss->head,
- !s->head ? NULL : (struct line_entry *)ptail,
+ set_or_check_view (lss->head, line_entry_at_tail (s->head, ptail),
s->head ? s->head->head : NULL);
*ptail = lss->head;
lss->head = NULL;