aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2015-01-06 16:40:43 -0800
committerCary Coutant <ccoutant@google.com>2015-01-06 16:40:43 -0800
commitc85ff1442754273a15104789a31de6c6b4008d66 (patch)
treec978fc1216b3764cfcee2686bd846c72befaa002
parente7ca0f8d7d976ae35103285d10175f2223644663 (diff)
downloadbinutils-c85ff1442754273a15104789a31de6c6b4008d66.zip
binutils-c85ff1442754273a15104789a31de6c6b4008d66.tar.gz
binutils-c85ff1442754273a15104789a31de6c6b4008d66.tar.bz2
Update support for DWARF-5 and experimental two-level line number tables.
2015-01-06 Cary Coutant <ccoutant@google.com> gas/ * dwarf2dbg.c (emit_logicals): Replace DW_LNS_inlined_call with DW_LNS_set_context and DW_LNS_set_subprogram. Fix bug where we emit wrong value for line number. (process_entries): Don't emit DW_LNS_negate_stmt in actuals table. (out_dwarf5_file_list): Fix bug where dir list or file list is empty. (out_debug_line): Update table of opcode lengths.
-rw-r--r--gas/dwarf2dbg.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 96d2bcd..811feb1 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -1551,29 +1551,37 @@ emit_logicals (void)
// See if a sequence of DW_LNS_pop_context ops will get
// to the state we want.
- while (caller > 0 && caller <= logicals_in_use) {
- ++npop;
- if (logicals[caller - 1].subprog == subprog)
- break;
- caller = logicals[caller - 1].context;
- }
- if (caller > 0 && caller <= logicals_in_use && npop < 5) {
- while (npop-- > 0)
- out_opcode (DW_LNS_pop_context);
- filenum = logicals[caller - 1].loc.filenum;
- line = logicals[caller - 1].loc.line;
- column = logicals[caller - 1].loc.column;
- discriminator = logicals[caller - 1].loc.discriminator;
- flags = logicals[caller - 1].loc.flags;
- context = logicals[caller - 1].context;
- subprog = logicals[caller - 1].subprog;
- } else {
- out_opcode (DW_LNS_inlined_call);
- out_uleb128 (context);
- out_uleb128 (subprog);
- context = e->context;
- subprog = e->subprog;
- }
+ while (caller > 0 && caller <= logicals_in_use)
+ {
+ ++npop;
+ if (logicals[caller - 1].subprog == subprog)
+ break;
+ caller = logicals[caller - 1].context;
+ }
+ if (caller > 0 && caller <= logicals_in_use && npop < 5)
+ {
+ while (npop-- > 0)
+ out_opcode (DW_LNS_pop_context);
+ filenum = logicals[caller - 1].loc.filenum;
+ line = logicals[caller - 1].loc.line;
+ column = logicals[caller - 1].loc.column;
+ discriminator = logicals[caller - 1].loc.discriminator;
+ flags = logicals[caller - 1].loc.flags;
+ context = logicals[caller - 1].context;
+ subprog = logicals[caller - 1].subprog;
+ }
+ if (context != e->context)
+ {
+ context = e->context;
+ out_opcode (DW_LNS_set_context);
+ out_uleb128 (context);
+ }
+ if (subprog != e->subprog)
+ {
+ subprog = e->subprog;
+ out_opcode (DW_LNS_set_subprogram);
+ out_uleb128 (subprog);
+ }
}
if (filenum != e->loc.filenum)
@@ -1610,10 +1618,7 @@ emit_logicals (void)
if (e->loc.flags & DWARF2_FLAG_EPILOGUE_BEGIN)
out_opcode (DW_LNS_set_epilogue_begin);
- if (logicals_in_use == 0)
- line_delta = e->loc.line - line;
- else
- line_delta = e->loc.logical - line;
+ line_delta = e->loc.line - line;
lab = e->label;
frag = symbol_get_frag (lab);
frag_ofs = S_GET_VALUE (lab);
@@ -1722,17 +1727,17 @@ process_entries (segT seg, struct line_entry *e)
out_uleb128 (isa);
}
- if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT)
- {
- flags = e->loc.flags;
- out_opcode (DW_LNS_negate_stmt);
- }
-
if (e->loc.flags & DWARF2_FLAG_BASIC_BLOCK)
out_opcode (DW_LNS_set_basic_block);
if (logicals_in_use == 0)
{
+ if ((e->loc.flags ^ flags) & DWARF2_FLAG_IS_STMT)
+ {
+ flags = e->loc.flags;
+ out_opcode (DW_LNS_negate_stmt);
+ }
+
if (e->loc.flags & DWARF2_FLAG_PROLOGUE_END)
out_opcode (DW_LNS_set_prologue_end);
@@ -1915,6 +1920,8 @@ out_dwarf5_file_list (segT str_seg, int sizeof_offset)
offsetT strp;
unsigned int i;
expressionS exp;
+ unsigned int dir_count = dirs_in_use > 0 ? dirs_in_use - 1 : 0;
+ unsigned int file_count = files_in_use > 0 ? files_in_use - 1 : 0;
exp.X_op = O_symbol;
exp.X_add_symbol = section_symbol (str_seg);
@@ -1922,7 +1929,7 @@ out_dwarf5_file_list (segT str_seg, int sizeof_offset)
out_byte (1); /* directory_entry_format_count */
out_uleb128 (DW_LNCT_path); /* directory_entry_format[0].content_type */
out_uleb128 (DW_FORM_line_strp); /* directory_entry_format[0].form */
- out_uleb128 (dirs_in_use - 1); /* directories_count */
+ out_uleb128 (dir_count); /* directories_count */
/* Emit directories list. */
for (i = 1; i < dirs_in_use; ++i)
@@ -1938,7 +1945,7 @@ out_dwarf5_file_list (segT str_seg, int sizeof_offset)
out_uleb128 (DW_FORM_line_strp); /* file_name_entry_format[0].form */
out_uleb128 (DW_LNCT_directory_index); /* file_name_entry_format[0].type */
out_uleb128 (DW_FORM_udata); /* file_name_entry_format[0].form */
- out_uleb128 (files_in_use - 1); /* file_names_count */
+ out_uleb128 (file_count); /* file_names_count */
/* Emit file_names list. */
for (i = 1; i < files_in_use; ++i)
@@ -2112,9 +2119,9 @@ out_debug_line (segT line_seg, segT str_seg)
out_byte (1); /* DW_LNS_set_isa */
if (opcode_base == DWARF2_EXPERIMENTAL_LINE_OPCODE_BASE)
{
- out_byte (2); /* DW_LNS_inlined_call */
+ out_byte (1); /* DW_LNS_set_context/DW_LNS_set_address_from_logical */
+ out_byte (1); /* DW_LNS_set_subprogram */
out_byte (0); /* DW_LNS_pop_context */
- out_byte (1); /* DW_LNS_set_address_from_logical */
}
if (version >= 5)