aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/dwarf2dbg.c152
-rw-r--r--gas/dwarf2dbg.h7
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-3.s1
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-4.d5
-rw-r--r--gas/testsuite/gas/i386/dwarf2-line-4.s1
-rw-r--r--gas/testsuite/gas/i386/dwarf4-line-1.d4
-rw-r--r--gas/testsuite/gas/i386/dwarf5-line-1.d4
-rw-r--r--gas/testsuite/gas/i386/dwarf5-line-2.d3
8 files changed, 105 insertions, 72 deletions
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 9e3437b..c6303ba 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -207,7 +207,6 @@ struct file_entry
static struct file_entry *files;
static unsigned int files_in_use;
static unsigned int files_allocated;
-static unsigned int num_of_auto_assigned;
/* Table of directories used by .debug_line. */
static char ** dirs = NULL;
@@ -233,7 +232,7 @@ static struct dwarf2_line_info current =
{
1, 1, 0, 0,
DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0,
- 0, NULL
+ 0, { NULL }
};
/* This symbol is used to recognize view number forced resets in loc
@@ -342,7 +341,7 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
/* First, compute !(E->label > P->label), to tell whether or not
we're to reset the view number. If we can't resolve it to a
constant, keep it symbolic. */
- if (!p || (e->loc.view == force_reset_view && force_reset_view))
+ if (!p || (e->loc.u.view == force_reset_view && force_reset_view))
{
viewx.X_op = O_constant;
viewx.X_add_number = 0;
@@ -367,9 +366,9 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
}
}
- if (S_IS_DEFINED (e->loc.view) && symbol_constant_p (e->loc.view))
+ if (S_IS_DEFINED (e->loc.u.view) && symbol_constant_p (e->loc.u.view))
{
- expressionS *value = symbol_get_value_expression (e->loc.view);
+ expressionS *value = symbol_get_value_expression (e->loc.u.view);
/* We can't compare the view numbers at this point, because in
VIEWX we've only determined whether we're to reset it so
far. */
@@ -404,16 +403,16 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
{
expressionS incv;
- if (!p->loc.view)
+ if (!p->loc.u.view)
{
- p->loc.view = symbol_temp_make ();
- gas_assert (!S_IS_DEFINED (p->loc.view));
+ p->loc.u.view = symbol_temp_make ();
+ gas_assert (!S_IS_DEFINED (p->loc.u.view));
}
memset (&incv, 0, sizeof (incv));
incv.X_unsigned = 1;
incv.X_op = O_symbol;
- incv.X_add_symbol = p->loc.view;
+ incv.X_add_symbol = p->loc.u.view;
incv.X_add_number = 1;
if (viewx.X_op == O_constant)
@@ -430,16 +429,16 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
}
}
- if (!S_IS_DEFINED (e->loc.view))
+ if (!S_IS_DEFINED (e->loc.u.view))
{
- symbol_set_value_expression (e->loc.view, &viewx);
- S_SET_SEGMENT (e->loc.view, expr_section);
- symbol_set_frag (e->loc.view, &zero_address_frag);
+ symbol_set_value_expression (e->loc.u.view, &viewx);
+ S_SET_SEGMENT (e->loc.u.view, expr_section);
+ symbol_set_frag (e->loc.u.view, &zero_address_frag);
}
/* Define and attempt to simplify any earlier views needed to
compute E's. */
- if (h && p && p->loc.view && !S_IS_DEFINED (p->loc.view))
+ if (h && p && p->loc.u.view && !S_IS_DEFINED (p->loc.u.view))
{
struct line_entry *h2;
/* Reverse the list to avoid quadratic behavior going backwards
@@ -459,7 +458,9 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
break;
set_or_check_view (r, r->next, NULL);
}
- while (r->next && r->next->loc.view && !S_IS_DEFINED (r->next->loc.view)
+ while (r->next
+ && r->next->loc.u.view
+ && !S_IS_DEFINED (r->next->loc.u.view)
&& (r = r->next));
/* Unreverse the list, so that we can go forward again. */
@@ -475,14 +476,14 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
view of the previous subsegment. */
if (r == h)
continue;
- gas_assert (S_IS_DEFINED (r->loc.view));
- resolve_expression (symbol_get_value_expression (r->loc.view));
+ gas_assert (S_IS_DEFINED (r->loc.u.view));
+ resolve_expression (symbol_get_value_expression (r->loc.u.view));
}
while (r != p && (r = r->next));
/* Now that we've defined and computed all earlier views that might
be needed to compute E's, attempt to simplify it. */
- resolve_expression (symbol_get_value_expression (e->loc.view));
+ resolve_expression (symbol_get_value_expression (e->loc.u.view));
}
}
@@ -518,10 +519,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->view && lss->head)
- set_or_check_view (e,
- (struct line_entry *)lss->ptail,
- lss->head);
+ if (loc->filenum != -1u && loc->u.view && lss->head)
+ set_or_check_view (e, (struct line_entry *) lss->ptail, lss->head);
*lss->ptail = e;
lss->ptail = &e->next;
@@ -532,9 +531,6 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
void
dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
{
- static unsigned int line = -1;
- static unsigned int filenum = -1;
-
symbolS *sym;
/* Early out for as-yet incomplete location information. */
@@ -552,20 +548,35 @@ dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
symbols apply to assembler code. It is necessary to emit
duplicate line symbols when a compiler asks for them, because GDB
uses them to determine the end of the prologue. */
- if (debug_type == DEBUG_DWARF2
- && line == loc->line && filenum == loc->filenum)
- return;
+ if (debug_type == DEBUG_DWARF2)
+ {
+ static unsigned int line = -1;
+ static const char *filename = NULL;
+
+ if (line == loc->line)
+ {
+ if (filename == loc->u.filename)
+ return;
+ if (filename_cmp (filename, loc->u.filename) == 0)
+ {
+ filename = loc->u.filename;
+ return;
+ }
+ }
- line = loc->line;
- filenum = loc->filenum;
+ line = loc->line;
+ filename = loc->u.filename;
+ }
if (linkrelax)
{
- char name[120];
+ static int label_num = 0;
+ char name[32];
/* Use a non-fake name for the line number location,
so that it can be referred to by relocations. */
- sprintf (name, ".Loc.%u.%u", line, filenum);
+ sprintf (name, ".Loc.%u", label_num);
+ label_num++;
sym = symbol_new (name, now_seg, frag_now, ofs);
}
else
@@ -624,13 +635,15 @@ get_directory_table_entry (const char *dirname,
{
const char * pwd = file0_dirname ? file0_dirname : getpwd ();
- if (dwarf_level >= 5 && strcmp (dirname, pwd) != 0)
+ if (dwarf_level >= 5 && filename_cmp (dirname, pwd) != 0)
{
- /* In DWARF-5 the 0 entry in the directory table is expected to be
- the same as the DW_AT_comp_dir (which 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.
- FIXME: Alternatively we could generate an error message here. */
+ /* In DWARF-5 the 0 entry in the directory table is
+ expected to be the same as the DW_AT_comp_dir (which
+ 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.
+ FIXME: Alternatively we could generate an error
+ message here. */
(void) get_directory_table_entry (pwd, NULL, strlen (pwd),
true);
d = 1;
@@ -745,14 +758,30 @@ allocate_filenum (const char * pathname)
if (!assign_file_to_slot (i, file, dir))
return -1;
- num_of_auto_assigned++;
-
last_used = i;
last_used_dir_len = dir_len;
return i;
}
+/* Run through the list of line entries starting at E, allocating
+ file entries for gas generated debug. */
+
+static void
+do_allocate_filenum (struct line_entry *e)
+{
+ do
+ {
+ if (e->loc.filenum == -1u)
+ {
+ e->loc.filenum = allocate_filenum (e->loc.u.filename);
+ e->loc.u.view = NULL;
+ }
+ e = e->next;
+ }
+ while (e);
+}
+
/* Allocate slot NUM in the .debug_line file table to FILENAME.
If DIRNAME is not NULL or there is a directory component to FILENAME
then this will be stored in the directory table, if not already present.
@@ -929,17 +958,12 @@ dwarf2_where (struct dwarf2_line_info *line)
{
if (debug_type == DEBUG_DWARF2)
{
- const char *filename;
-
- memset (line, 0, sizeof (*line));
- filename = as_where (&line->line);
- line->filenum = allocate_filenum (filename);
- /* FIXME: We should check the return value from allocate_filenum. */
+ line->u.filename = as_where (&line->line);
+ line->filenum = -1u;
line->column = 0;
line->flags = DWARF2_FLAG_IS_STMT;
line->isa = current.isa;
line->discriminator = current.discriminator;
- line->view = NULL;
}
else
*line = current;
@@ -1018,7 +1042,7 @@ dwarf2_consume_line_info (void)
| DWARF2_FLAG_PROLOGUE_END
| DWARF2_FLAG_EPILOGUE_BEGIN);
current.discriminator = 0;
- current.view = NULL;
+ current.u.view = NULL;
}
/* Called for each (preferably code) label. If dwarf2_loc_mark_labels
@@ -1060,7 +1084,6 @@ dwarf2_directive_filename (void)
char *filename;
const char * dirname = NULL;
int filename_len;
- unsigned int i;
/* Continue to accept a bare string and pass it off. */
SKIP_WHITESPACE ();
@@ -1132,18 +1155,6 @@ dwarf2_directive_filename (void)
return NULL;
}
- if (num_of_auto_assigned)
- {
- /* Clear slots auto-assigned before the first .file <NUMBER>
- directive was seen. */
- if (files_in_use != (num_of_auto_assigned + 1))
- abort ();
- for (i = 1; i < files_in_use; i++)
- files[i].filename = NULL;
- files_in_use = 0;
- num_of_auto_assigned = 0;
- }
-
if (! allocate_filename_to_slot (dirname, filename, (unsigned int) num,
with_md5))
return NULL;
@@ -1191,6 +1202,11 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
return;
}
+ /* debug_type will be turned off by dwarf2_directive_filename, and
+ if we don't have a dwarf style .file then files_in_use will be
+ zero and the above error will trigger. */
+ gas_assert (debug_type == DEBUG_NONE);
+
current.filenum = filenum;
current.line = line;
current.discriminator = 0;
@@ -1333,7 +1349,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
S_SET_VALUE (sym, 0);
symbol_set_frag (sym, &zero_address_frag);
}
- current.view = sym;
+ current.u.view = sym;
}
else
{
@@ -1347,10 +1363,9 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
dwarf2_any_loc_directive_seen = dwarf2_loc_directive_seen = true;
- debug_type = DEBUG_NONE;
/* If we were given a view id, emit the row right away. */
- if (current.view)
+ if (current.u.view)
dwarf2_emit_insn (0);
}
@@ -1984,7 +1999,7 @@ process_entries (segT seg, struct line_entry *e)
frag_ofs = S_GET_VALUE (lab);
if (last_frag == NULL
- || (e->loc.view == force_reset_view && force_reset_view
+ || (e->loc.u.view == force_reset_view && force_reset_view
/* If we're going to reset the view, but we know we're
advancing the PC, we don't have to force with
set_address. We know we do when we're at the same
@@ -2850,16 +2865,19 @@ dwarf2_finish (void)
struct line_subseg *lss = s->head;
struct line_entry **ptail = lss->ptail;
+ if (lss->head && SEG_NORMAL (s->seg))
+ do_allocate_filenum (lss->head);
+
/* Reset the initial view of the first subsection of the
section. */
- if (lss->head && lss->head->loc.view)
+ if (lss->head && lss->head->loc.u.view)
set_or_check_view (lss->head, NULL, NULL);
while ((lss = lss->next) != NULL)
{
/* Link the first view of subsequent subsections to the
previous view. */
- if (lss->head && lss->head->loc.view)
+ if (lss->head && lss->head->loc.u.view)
set_or_check_view (lss->head,
!s->head ? NULL : (struct line_entry *)ptail,
s->head ? s->head->head : NULL);
diff --git a/gas/dwarf2dbg.h b/gas/dwarf2dbg.h
index 14d770c..700d9de 100644
--- a/gas/dwarf2dbg.h
+++ b/gas/dwarf2dbg.h
@@ -36,7 +36,12 @@ struct dwarf2_line_info
unsigned int isa;
unsigned int flags;
unsigned int discriminator;
- symbolS *view;
+ /* filenum == -1u chooses filename, otherwise view. */
+ union
+ {
+ symbolS *view;
+ const char *filename;
+ } u;
};
/* Implements the .file FILENO "FILENAME" directive. FILENO can be 0
diff --git a/gas/testsuite/gas/i386/dwarf2-line-3.s b/gas/testsuite/gas/i386/dwarf2-line-3.s
index 2085ef9..e933719 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-3.s
+++ b/gas/testsuite/gas/i386/dwarf2-line-3.s
@@ -7,6 +7,7 @@
main:
.cfi_startproc
nop
+ .file 1 "dwarf2-test.c"
.loc 1 1
ret
.cfi_endproc
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.d b/gas/testsuite/gas/i386/dwarf2-line-4.d
index c0c85f4..a01fd05 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-4.d
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.d
@@ -33,11 +33,14 @@ Raw dump of debug contents of section \.z?debug_line:
The File Name Table \(offset 0x.*\):
Entry Dir Time Size Name
- 1 1 0 0 dwarf2-line-4.s
+ 1 0 0 0 dwarf2-test.c
+ 2 1 0 0 dwarf2-line-4.s
Line Number Statements:
+ \[0x.*\] Set File Name to entry 2 in the File Name Table
\[0x.*\] Extended opcode 2: set Address to 0x0
\[0x.*\] Special opcode 13: advance Address by 0 to 0x0 and Line by 8 to 9
+ \[0x.*\] Set File Name to entry 1 in the File Name Table
\[0x.*\] Advance Line by -8 to 1
\[0x.*\] Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 1
\[0x.*\] Advance PC by 1 to 0x2
diff --git a/gas/testsuite/gas/i386/dwarf2-line-4.s b/gas/testsuite/gas/i386/dwarf2-line-4.s
index 89bb62d..7348f4b 100644
--- a/gas/testsuite/gas/i386/dwarf2-line-4.s
+++ b/gas/testsuite/gas/i386/dwarf2-line-4.s
@@ -7,6 +7,7 @@
main:
.cfi_startproc
nop
+ .file 1 "dwarf2-test.c"
.loc 1 1
ret
.cfi_endproc
diff --git a/gas/testsuite/gas/i386/dwarf4-line-1.d b/gas/testsuite/gas/i386/dwarf4-line-1.d
index 4f8321e..8199efb 100644
--- a/gas/testsuite/gas/i386/dwarf4-line-1.d
+++ b/gas/testsuite/gas/i386/dwarf4-line-1.d
@@ -36,12 +36,14 @@ Raw dump of debug contents of section \.z?debug_line:
Entry Dir Time Size Name
1 0 0 0 foo.c
2 0 0 0 foo.h
+ 3 1 0 0 dwarf4-line-1.s
Line Number Statements:
+ \[0x.*\] Set File Name to entry 2 in the File Name Table
\[0x.*\] Extended opcode 2: set Address to 0x0
\[0x.*\] Advance Line by 81 to 82
\[0x.*\] Copy
- \[0x.*\] Set File Name to entry 2 in the File Name Table
+ \[0x.*\] Set File Name to entry 3 in the File Name Table
\[0x.*\] Advance Line by -73 to 9
\[0x.*\] Special opcode 19: advance Address by 1 to 0x1 and Line by 0 to 9
\[0x.*\] Advance PC by 3 to 0x4
diff --git a/gas/testsuite/gas/i386/dwarf5-line-1.d b/gas/testsuite/gas/i386/dwarf5-line-1.d
index f57fc47..2c2cf56 100644
--- a/gas/testsuite/gas/i386/dwarf5-line-1.d
+++ b/gas/testsuite/gas/i386/dwarf5-line-1.d
@@ -36,12 +36,14 @@ Raw dump of debug contents of section \.z?debug_line:
0 \(indirect line string, offset: 0x.*\): .*/gas/testsuite
1 \(indirect line string, offset: 0x.*\): .*/gas/testsuite/gas/i386
- The File Name Table \(offset 0x.*, lines 2, columns 3\):
+ The File Name Table \(offset 0x.*, lines 3, columns 3\):
Entry Dir MD5 Name
0 0 0xbbd69fc03ce253b2dbaab2522dd519ae \(indirect line string, offset: 0x.*\): core.c
1 0 0x0 \(indirect line string, offset: 0x.*\): types.h
+ 2 1 0x0 \(indirect line string, offset: 0x.*\): dwarf5-line-1.s
Line Number Statements:
+ \[0x.*\] Set File Name to entry 2 in the File Name Table
\[0x.*\] Extended opcode 2: set Address to 0x0
\[0x.*\] Special opcode 8: advance Address by 0 to 0x0 and Line by 3 to 4
\[0x.*\] Advance PC by 1 to 0x1
diff --git a/gas/testsuite/gas/i386/dwarf5-line-2.d b/gas/testsuite/gas/i386/dwarf5-line-2.d
index 2f96df5..85f98c8 100644
--- a/gas/testsuite/gas/i386/dwarf5-line-2.d
+++ b/gas/testsuite/gas/i386/dwarf5-line-2.d
@@ -36,9 +36,10 @@ Raw dump of debug contents of section \.z?debug_line:
0 \(indirect line string, offset: 0x.*\): .*/gas/testsuite
1 \(indirect line string, offset: 0x.*\): .*/gas/testsuite/gas/i386
- The File Name Table \(offset 0x.*, lines 1, columns 3\):
+ The File Name Table \(offset 0x.*, lines 2, columns 3\):
Entry Dir MD5 Name
0 0 0xbbd69fc03ce253b2dbaab2522dd519ae \(indirect line string, offset: 0x.*\): core.c
+ 1 1 0x0 \(indirect line string, offset: .*\): dwarf5-line-2.s
Line Number Statements:
\[0x.*\] Extended opcode 2: set Address to 0x0