/* dwarf2dbg.c - DWARF2 debug support
- Copyright (C) 1999-2018 Free Software Foundation, Inc.
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of GAS, the GNU Assembler.
#define DWARF2_ARANGES_VERSION 2
#endif
-/* This implementation output version 2 .debug_line information. */
+/* This implementation outputs version 3 .debug_line information. */
#ifndef DWARF2_LINE_VERSION
-#define DWARF2_LINE_VERSION 2
+#define DWARF2_LINE_VERSION 3
#endif
#include "subsegs.h"
{
expressionS exp;
+ memset (&exp, 0, sizeof exp);
exp.X_op = O_symbol;
exp.X_add_symbol = symbol;
exp.X_add_number = 0;
if (view_assert_failed)
{
expressionS chk;
+
memset (&chk, 0, sizeof (chk));
chk.X_unsigned = 1;
chk.X_op = O_add;
if (!S_IS_DEFINED (e->loc.view))
{
symbol_set_value_expression (e->loc.view, &viewx);
- S_SET_SEGMENT (e->loc.view, absolute_section);
+ S_SET_SEGMENT (e->loc.view, expr_section);
symbol_set_frag (e->loc.view, &zero_address_frag);
}
dwarf2_where (&loc);
- dwarf2_gen_line_info (frag_now_fix () - size, &loc);
+ dwarf2_gen_line_info ((frag_now_fix_octets () - size) / OCTETS_PER_BYTE, &loc);
dwarf2_consume_line_info ();
}
| DWARF2_FLAG_PROLOGUE_END
| DWARF2_FLAG_EPILOGUE_BEGIN);
current.discriminator = 0;
+ current.view = NULL;
}
/* Called for each (preferably code) label. If dwarf2_loc_mark_labels
if (!name)
return;
sym = symbol_find_or_make (name);
- if (S_IS_DEFINED (sym))
+ if (S_IS_DEFINED (sym) || symbol_equated_p (sym))
{
- if (!S_CAN_BE_REDEFINED (sym))
- as_bad (_("symbol `%s' is already defined"), name);
- else
+ if (S_IS_VOLATILE (sym))
sym = symbol_clone (sym, 1);
- S_SET_SEGMENT (sym, undefined_section);
- S_SET_VALUE (sym, 0);
- symbol_set_frag (sym, &zero_address_frag);
+ else if (!S_CAN_BE_REDEFINED (sym))
+ {
+ as_bad (_("symbol `%s' is already defined"), name);
+ return;
+ }
}
+ S_SET_SEGMENT (sym, undefined_section);
+ S_SET_VALUE (sym, 0);
+ symbol_set_frag (sym, &zero_address_frag);
}
current.view = sym;
}
/* Set an absolute address (may result in a relocation entry). */
+static void
+out_inc_line_addr (int line_delta, addressT addr_delta);
+
static void
out_set_addr (symbolS *sym)
{
expressionS exp;
+ addressT expr_addr, expr_addr_aligned;
+
+ memset (&exp, 0, sizeof exp);
+
+ /* The expression at the bottom must be aligned to OCTETS_PER_BYTE. The
+ statements after the for loop will contribute 3 more octets. */
+ expr_addr = frag_now_fix_octets () + 3;
+ expr_addr_aligned = (expr_addr + OCTETS_PER_BYTE - 1) & -OCTETS_PER_BYTE;
+ for ( ; expr_addr != expr_addr_aligned; expr_addr++)
+ out_inc_line_addr (0, 0); /* NOP */
- out_opcode (DW_LNS_extended_op);
- out_uleb128 (sizeof_address + 1);
+ out_opcode (DW_LNS_extended_op); /* 1 octet */
+ out_uleb128 (sizeof_address + 1); /* 1 octet */
- out_opcode (DW_LNE_set_address);
+ out_opcode (DW_LNE_set_address); /* 1 octet */
exp.X_op = O_symbol;
exp.X_add_symbol = sym;
exp.X_add_number = 0;
symbolS *to_sym;
expressionS exp;
+ memset (&exp, 0, sizeof exp);
gas_assert (pexp->X_op == O_subtract);
to_sym = pexp->X_add_symbol;
expressionS exp;
int max_chars;
+ memset (&exp, 0, sizeof exp);
exp.X_op = O_subtract;
exp.X_add_symbol = to_sym;
exp.X_op_symbol = from_sym;
}
else
{
- start_sym = symbol_temp_new_now ();
+ start_sym = symbol_temp_new_now_octets ();
end_sym = symbol_temp_make ();
}
symbolS *line_end;
struct line_seg *s;
int sizeof_offset;
+ addressT section_end, section_end_aligned;
+ memset (&exp, 0, sizeof exp);
sizeof_offset = out_header (line_seg, &exp);
line_end = exp.X_add_symbol;
exp.X_op_symbol = prologue_start;
exp.X_add_number = 0;
emit_expr (&exp, sizeof_offset);
- symbol_set_value_now (prologue_start);
+ symbol_set_value_now_octets (prologue_start);
/* Parameters of the state machine. */
out_byte (DWARF2_LINE_MIN_INSN_LENGTH);
out_file_list ();
- symbol_set_value_now (prologue_end);
+ symbol_set_value_now_octets (prologue_end);
/* For each section, emit a statement program. */
for (s = all_segs; s; s = s->next)
in the DWARF Line Number header. */
subseg_set (subseg_get (".debug_line_end", FALSE), 0);
- symbol_set_value_now (line_end);
+ /* Pad size of .debug_line section to a multiple of OCTETS_PER_BYTE.
+ Simply sizing the section in md_section_align() is not sufficient,
+ also the size field in the .debug_line header must be a multiple
+ of OCTETS_PER_BYTE. Not doing so will introduce gaps within the
+ .debug_line sections after linking. */
+ section_end = frag_now_fix_octets ();
+ section_end_aligned = (section_end + OCTETS_PER_BYTE - 1) & -OCTETS_PER_BYTE;
+ for ( ; section_end != section_end_aligned; section_end++)
+ out_inc_line_addr (0, 0); /* NOP */
+
+ symbol_set_value_now_octets (line_end);
}
static void
expressionS exp;
unsigned int i;
+ memset (&exp, 0, sizeof exp);
subseg_set (ranges_seg, 0);
/* Base Address Entry. */
char *p;
int sizeof_offset;
+ memset (&exp, 0, sizeof exp);
sizeof_offset = out_header (aranges_seg, &exp);
aranges_end = exp.X_add_symbol;
size = -exp.X_add_number;
md_number_to_chars (p, 0, addr_size);
md_number_to_chars (p + addr_size, 0, addr_size);
- symbol_set_value_now (aranges_end);
+ symbol_set_value_now_octets (aranges_end);
}
/* Emit data for .debug_abbrev. Note that this must be kept in
symbolS *info_end;
int sizeof_offset;
+ memset (&exp, 0, sizeof exp);
sizeof_offset = out_header (info_seg, &exp);
info_end = exp.X_add_symbol;
dwarf2 draft has no standard code for assembler. */
out_two (DW_LANG_Mips_Assembler);
- symbol_set_value_now (info_end);
+ symbol_set_value_now_octets (info_end);
}
/* Emit the three debug strings needed in .debug_str and setup symbols
on the command line, so assume files[1] is the main input file.
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 ();
+ *name_sym = symbol_temp_new_now_octets ();
if (files_in_use == 0)
abort ();
if (files[1].dir)
memcpy (p, files[1].filename, len);
/* DW_AT_comp_dir */
- *comp_dir_sym = symbol_temp_new_now ();
+ *comp_dir_sym = symbol_temp_new_now_octets ();
comp_dir = remap_debug_filename (getpwd ());
len = strlen (comp_dir) + 1;
p = frag_more (len);
memcpy (p, comp_dir, len);
/* DW_AT_producer */
- *producer_sym = symbol_temp_new_now ();
+ *producer_sym = symbol_temp_new_now_octets ();
sprintf (producer, "GNU AS %s", VERSION);
len = strlen (producer) + 1;
p = frag_more (len);