diff options
-rw-r--r-- | gas/dwarf2dbg.c | 152 | ||||
-rw-r--r-- | gas/dwarf2dbg.h | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/dwarf2-line-3.s | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/dwarf2-line-4.d | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/dwarf2-line-4.s | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/dwarf4-line-1.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/dwarf5-line-1.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/dwarf5-line-2.d | 3 |
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 |