* Re: [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state
@ 2015-05-27 22:22 Doug Evans
2015-06-10 19:44 ` Simon Marchi
0 siblings, 1 reply; 5+ messages in thread
From: Doug Evans @ 2015-05-27 22:22 UTC (permalink / raw)
To: gdb-patches
Doug Evans writes:
> Hi.
>
> This patch puts the line number state machine into a struct
> to make it clear exactly what is part of the state machine
> and what is not. Previously, gdb just had a bunch of local variables.
>
> 2015-03-12 Doug Evans <dje@google.com>
>
> * dwarf2read.c (lnp_state_machine): New typedef.
> (lnp_reader_state): New typedef.
> (dwarf_record_line_1): Renamed from dwarf_record_line.
> All callers updated.
> (dwarf_record_line): New function.
> (init_lnp_state_machine): New function.
> (check_line_address): Replace p_record_line parameter with state.
> All callers updated.
> (dwarf_decode_lines_1): Call dwarf_record_line, init_lnp_state_machine.
> Update to record state in lnp_state_machine.
Here is what I committed.
Just a few comment changes to remove references to two level
line tables, which are in a later patch.
2015-05-27 Doug Evans <dje@google.com>
* dwarf2read.c (lnp_state_machine): New typedef.
(lnp_reader_state): New typedef.
(dwarf_record_line_1): Renamed from dwarf_record_line.
All callers updated.
(dwarf_record_line): New function.
(init_lnp_state_machine): New function.
(check_line_address): Replace p_record_line parameter with state.
All callers updated.
(dwarf_decode_lines_1): Call dwarf_record_line, init_lnp_state_machine.
Update to record state in lnp_state_machine.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 0a7950f..1ce616a 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17480,6 +17480,54 @@ psymtab_include_file_name (const struct
line_header *lh, int file_index,
typedef void (record_line_ftype) (struct subfile *subfile, int line,
CORE_ADDR pc);
+/* State machine to track the state of the line number program. */
+
+typedef struct
+{
+ /* These are part of the standard DWARF line number state machine. */
+
+ unsigned char op_index;
+ unsigned int file;
+ unsigned int line;
+ CORE_ADDR address;
+ int is_stmt;
+ unsigned int discriminator;
+
+ /* Additional bits of state we need to track. */
+
+ /* The last file that we called dwarf2_start_subfile for.
+ This is only used for TLLs. */
+ unsigned int last_file;
+ /* The last file a line number was recorded for. */
+ struct subfile *last_subfile;
+
+ /* The function to call to record a line. */
+ record_line_ftype *record_line;
+
+ /* The last line number that was recorded, used to coalesce
+ consecutive entries for the same line. This can happen, for
+ example, when discriminators are present. PR 17276. */
+ unsigned int last_line;
+ int line_has_non_zero_discriminator;
+} lnp_state_machine;
+
+/* There's a lot of static state to pass to dwarf_record_line.
+ This keeps it all together. */
+
+typedef struct
+{
+ /* The gdbarch. */
+ struct gdbarch *gdbarch;
+
+ /* The line number header. */
+ struct line_header *line_header;
+
+ /* Non-zero if we're recording lines.
+ Otherwise we're building partial symtabs and are just interested in
+ finding include files mentioned by the line number program. */
+ int record_lines_p;
+} lnp_reader_state;
+
/* Ignore this record_line request. */
static void
@@ -17539,9 +17587,9 @@ dwarf_record_line_p (unsigned int line, unsigned
int last_line,
in the line table of subfile SUBFILE. */
static void
-dwarf_record_line (struct gdbarch *gdbarch, struct subfile *subfile,
- unsigned int line, CORE_ADDR address,
- record_line_ftype p_record_line)
+dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
+ unsigned int line, CORE_ADDR address,
+ record_line_ftype p_record_line)
{
CORE_ADDR addr = gdbarch_addr_bits_remove (gdbarch, address);
@@ -17558,7 +17606,7 @@ dwarf_record_line (struct gdbarch *gdbarch, struct
subfile *subfile,
/* Subroutine of dwarf_decode_lines_1 to simplify it.
Mark the end of a set of line number records.
- The arguments are the same as for dwarf_record_line.
+ The arguments are the same as for dwarf_record_line_1.
If SUBFILE is NULL the request is ignored. */
static void
@@ -17576,14 +17624,103 @@ dwarf_finish_line (struct gdbarch *gdbarch,
struct subfile *subfile,
paddress (gdbarch, address));
}
- dwarf_record_line (gdbarch, subfile, 0, address, p_record_line);
+ dwarf_record_line_1 (gdbarch, subfile, 0, address, p_record_line);
+}
+
+/* Record the line in STATE.
+ END_SEQUENCE is non-zero if we're processing the end of a sequence. */
+
+static void
+dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
+ int end_sequence)
+{
+ const struct line_header *lh = reader->line_header;
+ unsigned int file, line, discriminator;
+ int is_stmt;
+
+ file = state->file;
+ line = state->line;
+ is_stmt = state->is_stmt;
+ discriminator = state->discriminator;
+
+ if (dwarf_line_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Processing actual line %u: file %u,"
+ " address %s, is_stmt %u, discrim %u\n",
+ line, file,
+ paddress (reader->gdbarch, state->address),
+ is_stmt, discriminator);
+ }
+
+ if (file == 0 || file - 1 >= lh->num_file_names)
+ dwarf2_debug_line_missing_file_complaint ();
+ /* For now we ignore lines not starting on an instruction boundary.
+ But not when processing end_sequence for compatibility with the
+ previous version of the code. */
+ else if (state->op_index == 0 || end_sequence)
+ {
+ lh->file_names[file - 1].included_p = 1;
+ if (reader->record_lines_p && is_stmt)
+ {
+ if (state->last_subfile != current_subfile)
+ {
+ dwarf_finish_line (reader->gdbarch, state->last_subfile,
+ state->address, state->record_line);
+ }
+
+ if (!end_sequence)
+ {
+ if (dwarf_record_line_p (line, state->last_line,
+ state->line_has_non_zero_discriminator,
+ state->last_subfile))
+ {
+ dwarf_record_line_1 (reader->gdbarch, current_subfile,
+ line, state->address,
+ state->record_line);
+ }
+ state->last_subfile = current_subfile;
+ state->last_line = line;
+ }
+ }
+ }
+}
+
+/* Initialize STATE for the start of a line number program. */
+
+static void
+init_lnp_state_machine (lnp_state_machine *state,
+ const lnp_reader_state *reader)
+{
+ memset (state, 0, sizeof (*state));
+
+ /* Just starting, there is no "last file". */
+ state->last_file = 0;
+ state->last_subfile = NULL;
+
+ state->record_line = record_line;
+
+ state->last_line = 0;
+ state->line_has_non_zero_discriminator = 0;
+
+ /* Initialize these according to the DWARF spec. */
+ state->op_index = 0;
+ state->file = 1;
+ state->line = 1;
+ /* Call `gdbarch_adjust_dwarf2_line' on the initial 0 address as if there
+ was a line entry for it so that the backend has a chance to adjust it
+ and also record it in case it needs it. This is currently used by
MIPS
+ code, cf. `mips_adjust_dwarf2_line'. */
+ state->address = gdbarch_adjust_dwarf2_line (reader->gdbarch, 0, 0);
+ state->is_stmt = reader->line_header->default_is_stmt;
+ state->discriminator = 0;
}
/* Check address and if invalid nop-out the rest of the lines in this
sequence. */
static void
-check_line_address (struct dwarf2_cu *cu, record_line_ftype
**p_record_line,
+check_line_address (struct dwarf2_cu *cu, lnp_state_machine *state,
const gdb_byte *line_ptr,
CORE_ADDR lowpc, CORE_ADDR address)
{
@@ -17603,14 +17740,16 @@ check_line_address (struct dwarf2_cu *cu,
record_line_ftype **p_record_line,
complaint (&symfile_complaints,
_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
line_offset, objfile_name (objfile));
- *p_record_line = noop_record_line;
- /* Note: *p_record_line is left as noop_record_line
+ state->record_line = noop_record_line;
+ /* Note: sm.record_line is left as noop_record_line
until we see DW_LNE_end_sequence. */
}
}
/* Subroutine of dwarf_decode_lines to simplify it.
- Process the line number information in LH. */
+ Process the line number information in LH.
+ If DECODE_FOR_PST_P is non-zero, all we do is process the line number
+ program in order to set included_p for every referenced header. */
static void
dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
@@ -17624,43 +17763,38 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
struct objfile *objfile = cu->objfile;
bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct subfile *last_subfile = NULL;
- void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc)
- = record_line;
+ /* Non-zero if we're recording line info (as opposed to building partial
+ symtabs). */
+ int record_lines_p = !decode_for_pst_p;
+ /* A collection of things we need to pass to dwarf_record_line. */
+ lnp_reader_state reader_state;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
line_ptr = lh->statement_program_start;
line_end = lh->statement_program_end;
+ reader_state.gdbarch = gdbarch;
+ reader_state.line_header = lh;
+ reader_state.record_lines_p = record_lines_p;
+
/* Read the statement sequences until there's nothing left. */
while (line_ptr < line_end)
{
- /* State machine registers. Call `gdbarch_adjust_dwarf2_line'
- on the initial 0 address as if there was a line entry for it
- so that the backend has a chance to adjust it and also record
- it in case it needs it. This is currently used by MIPS code,
- cf. `mips_adjust_dwarf2_line'. */
- CORE_ADDR address = gdbarch_adjust_dwarf2_line (gdbarch, 0, 0);
- unsigned int file = 1;
- unsigned int line = 1;
- int is_stmt = lh->default_is_stmt;
+ /* The DWARF line number program state machine. */
+ lnp_state_machine state_machine;
int end_sequence = 0;
- unsigned char op_index = 0;
- unsigned int discriminator = 0;
- /* The last line number that was recorded, used to coalesce
- consecutive entries for the same line. This can happen, for
- example, when discriminators are present. PR 17276. */
- unsigned int last_line = 0;
- int line_has_non_zero_discriminator = 0;
-
- if (!decode_for_pst_p && lh->num_file_names >= file)
+
+ /* Reset the state machine at the start of each sequence. */
+ init_lnp_state_machine (&state_machine, &reader_state);
+
+ if (record_lines_p && lh->num_file_names >= state_machine.file)
{
/* Start a subfile for the current file of the state machine. */
/* lh->include_dirs and lh->file_names are 0-based, but the
directory and file name numbers in the statement program
are 1-based. */
- struct file_entry *fe = &lh->file_names[file - 1];
+ struct file_entry *fe = &lh->file_names[state_machine.file - 1];
const char *dir = NULL;
if (fe->dir_index && lh->include_dirs != NULL)
@@ -17670,15 +17804,10 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
}
/* Decode the table. */
- while (!end_sequence)
+ while (line_ptr < line_end && !end_sequence)
{
op_code = read_1_byte (abfd, line_ptr);
line_ptr += 1;
- if (line_ptr > line_end)
- {
- dwarf2_debug_line_missing_end_sequence_complaint ();
- break;
- }
if (op_code >= lh->opcode_base)
{
@@ -17688,42 +17817,23 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
int line_delta;
adj_opcode = op_code - lh->opcode_base;
- addr_adj = (((op_index + (adj_opcode / lh->line_range))
+ addr_adj = (((state_machine.op_index
+ + (adj_opcode / lh->line_range))
/ lh->maximum_ops_per_instruction)
* lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + (adj_opcode / lh->line_range))
- % lh->maximum_ops_per_instruction);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index
+ + (adj_opcode / lh->line_range))
+ % lh->maximum_ops_per_instruction);
line_delta = lh->line_base + (adj_opcode % lh->line_range);
- line += line_delta;
+ state_machine.line += line_delta;
if (line_delta != 0)
- line_has_non_zero_discriminator = discriminator != 0;
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- /* For now we ignore lines not starting on an
- instruction boundary. */
- else if (op_index == 0)
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p && is_stmt)
- {
- if (last_subfile != current_subfile)
- {
- dwarf_finish_line (gdbarch, last_subfile,
- address, p_record_line);
- }
- if (dwarf_record_line_p (line, last_line,
- line_has_non_zero_discriminator,
- last_subfile))
- {
- dwarf_record_line (gdbarch, current_subfile,
- line, address, p_record_line);
- }
- last_subfile = current_subfile;
- last_line = line;
- }
- }
- discriminator = 0;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
+
+ dwarf_record_line (&reader_state, &state_machine, 0);
+ state_machine.discriminator = 0;
}
else switch (op_code)
{
@@ -17737,17 +17847,22 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
switch (extended_op)
{
case DW_LNE_end_sequence:
- p_record_line = record_line;
+ state_machine.record_line = record_line;
end_sequence = 1;
break;
case DW_LNE_set_address:
- address = read_address (abfd, line_ptr, cu, &bytes_read);
- line_ptr += bytes_read;
- check_line_address (cu, &p_record_line, line_ptr,
- lowpc, address);
- op_index = 0;
- address += baseaddr;
- address = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+ {
+ CORE_ADDR address
+ = read_address (abfd, line_ptr, cu, &bytes_read);
+
+ line_ptr += bytes_read;
+ check_line_address (cu, &state_machine, line_ptr,
+ lowpc, address);
+ state_machine.op_index = 0;
+ address += baseaddr;
+ state_machine.address
+ = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+ }
break;
case DW_LNE_define_file:
{
@@ -17775,9 +17890,10 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
if there are consecutive entries for the same
(non-prologue) line we want to coalesce them.
PR 17276. */
- discriminator = read_unsigned_leb128 (abfd, line_ptr,
- &bytes_read);
- line_has_non_zero_discriminator |= discriminator != 0;
+ state_machine.discriminator
+ = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ state_machine.line_has_non_zero_discriminator
+ |= state_machine.discriminator != 0;
line_ptr += bytes_read;
break;
default:
@@ -17796,30 +17912,8 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
}
break;
case DW_LNS_copy:
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p && is_stmt)
- {
- if (last_subfile != current_subfile)
- {
- dwarf_finish_line (gdbarch, last_subfile,
- address, p_record_line);
- }
- if (dwarf_record_line_p (line, last_line,
- line_has_non_zero_discriminator,
- last_subfile))
- {
- dwarf_record_line (gdbarch, current_subfile,
- line, address, p_record_line);
- }
- last_subfile = current_subfile;
- last_line = line;
- }
- }
- discriminator = 0;
+ dwarf_record_line (&reader_state, &state_machine, 0);
+ state_machine.discriminator = 0;
break;
case DW_LNS_advance_pc:
{
@@ -17827,12 +17921,13 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
= read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
CORE_ADDR addr_adj;
- addr_adj = (((op_index + adjust)
+ addr_adj = (((state_machine.op_index + adjust)
/ lh->maximum_ops_per_instruction)
* lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + adjust)
- % lh->maximum_ops_per_instruction);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index + adjust)
+ % lh->maximum_ops_per_instruction);
line_ptr += bytes_read;
}
break;
@@ -17841,44 +17936,48 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
int line_delta
= read_signed_leb128 (abfd, line_ptr, &bytes_read);
- line += line_delta;
+ state_machine.line += line_delta;
if (line_delta != 0)
- line_has_non_zero_discriminator = discriminator != 0;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
line_ptr += bytes_read;
}
break;
case DW_LNS_set_file:
- {
- /* The arrays lh->include_dirs and lh->file_names are
- 0-based, but the directory and file name numbers in
- the statement program are 1-based. */
- struct file_entry *fe;
- const char *dir = NULL;
-
- file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- line_ptr += bytes_read;
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- fe = &lh->file_names[file - 1];
- if (fe->dir_index && lh->include_dirs != NULL)
- dir = lh->include_dirs[fe->dir_index - 1];
- if (!decode_for_pst_p)
- {
- last_subfile = current_subfile;
- line_has_non_zero_discriminator = discriminator != 0;
- dwarf2_start_subfile (fe->name, dir);
- }
- }
- }
+ {
+ /* The arrays lh->include_dirs and lh->file_names are
+ 0-based, but the directory and file name numbers in
+ the statement program are 1-based. */
+ struct file_entry *fe;
+ const char *dir = NULL;
+
+ state_machine.file = read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read);
+ line_ptr += bytes_read;
+ if (state_machine.file == 0
+ || state_machine.file - 1 >= lh->num_file_names)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
+ {
+ fe = &lh->file_names[state_machine.file - 1];
+ if (fe->dir_index && lh->include_dirs != NULL)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ if (record_lines_p)
+ {
+ state_machine.last_subfile = current_subfile;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
+ dwarf2_start_subfile (fe->name, dir);
+ }
+ }
+ }
break;
case DW_LNS_set_column:
(void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
break;
case DW_LNS_negate_stmt:
- is_stmt = (!is_stmt);
+ state_machine.is_stmt = (!state_machine.is_stmt);
break;
case DW_LNS_set_basic_block:
break;
@@ -17892,12 +17991,13 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range;
CORE_ADDR addr_adj;
- addr_adj = (((op_index + adjust)
+ addr_adj = (((state_machine.op_index + adjust)
/ lh->maximum_ops_per_instruction)
* lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + adjust)
- % lh->maximum_ops_per_instruction);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index + adjust)
+ % lh->maximum_ops_per_instruction);
}
break;
case DW_LNS_fixed_advance_pc:
@@ -17905,8 +18005,9 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
CORE_ADDR addr_adj;
addr_adj = read_2_bytes (abfd, line_ptr);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = 0;
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = 0;
line_ptr += 2;
}
break;
@@ -17923,17 +18024,13 @@ dwarf_decode_lines_1 (struct line_header *lh,
struct dwarf2_cu *cu,
}
}
}
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
- {
- dwarf_finish_line (gdbarch, current_subfile, address,
- p_record_line);
- }
- }
+
+ if (!end_sequence)
+ dwarf2_debug_line_missing_end_sequence_complaint ();
+
+ /* We got a DW_LNE_end_sequence (or we ran off the end of the buffer,
+ in which case we still finish recording the last line). */
+ dwarf_record_line (&reader_state, &state_machine, 1);
}
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state
2015-05-27 22:22 [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state Doug Evans
@ 2015-06-10 19:44 ` Simon Marchi
2015-06-10 20:04 ` Doug Evans
0 siblings, 1 reply; 5+ messages in thread
From: Simon Marchi @ 2015-06-10 19:44 UTC (permalink / raw)
To: Doug Evans, gdb-patches
On 15-05-27 06:21 PM, Doug Evans wrote:
> Doug Evans writes:
> > Hi.
> >
> > This patch puts the line number state machine into a struct
> > to make it clear exactly what is part of the state machine
> > and what is not. Previously, gdb just had a bunch of local variables.
> >
> > 2015-03-12 Doug Evans <dje@google.com>
> >
> > * dwarf2read.c (lnp_state_machine): New typedef.
> > (lnp_reader_state): New typedef.
> > (dwarf_record_line_1): Renamed from dwarf_record_line.
> > All callers updated.
> > (dwarf_record_line): New function.
> > (init_lnp_state_machine): New function.
> > (check_line_address): Replace p_record_line parameter with state.
> > All callers updated.
> > (dwarf_decode_lines_1): Call dwarf_record_line, init_lnp_state_machine.
> > Update to record state in lnp_state_machine.
>
> Here is what I committed.
> Just a few comment changes to remove references to two level
> line tables, which are in a later patch.
Hi Doug,
I have a little question about something this patch. One behaviour changed,
but I don't know if it was intentional or not. I assume it is not, since the goal
of this patch was to refactor/cleanup.
When reading full symbols, after an end_sequence, dwarf_finish_line was called
unconditionally. Now, the call to dwarf_finish_line is guarded by:
if (state->last_subfile != current_subfile) {
Before this patch, the two other calls to dwarf_finish_line were guarded by this if.
However, the third one wasn't. Is this change intentional?
I am asking this because that call is apparently important for gdb to properly
understand DWARF generated by one of our internal compiler. To restore the previous
behaviour, I did the following. Would it make sense to have the same change in FSF's gdb?
---8<---
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 1e290c3..d79b2e3 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17658,7 +17658,7 @@ dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
lh->file_names[file - 1].included_p = 1;
if (reader->record_lines_p && is_stmt)
{
- if (state->last_subfile != current_subfile)
+ if (state->last_subfile != current_subfile || end_sequence)
{
dwarf_finish_line (reader->gdbarch, state->last_subfile,
state->address, state->record_line);
--->8---
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state
2015-06-10 19:44 ` Simon Marchi
@ 2015-06-10 20:04 ` Doug Evans
2015-06-10 20:35 ` Simon Marchi
0 siblings, 1 reply; 5+ messages in thread
From: Doug Evans @ 2015-06-10 20:04 UTC (permalink / raw)
To: Simon Marchi; +Cc: gdb-patches
On Wed, Jun 10, 2015 at 12:44 PM, Simon Marchi
<simon.marchi@ericsson.com> wrote:
> On 15-05-27 06:21 PM, Doug Evans wrote:
>> Doug Evans writes:
>> > Hi.
>> >
>> > This patch puts the line number state machine into a struct
>> > to make it clear exactly what is part of the state machine
>> > and what is not. Previously, gdb just had a bunch of local variables.
>> >
>> > 2015-03-12 Doug Evans <dje@google.com>
>> >
>> > * dwarf2read.c (lnp_state_machine): New typedef.
>> > (lnp_reader_state): New typedef.
>> > (dwarf_record_line_1): Renamed from dwarf_record_line.
>> > All callers updated.
>> > (dwarf_record_line): New function.
>> > (init_lnp_state_machine): New function.
>> > (check_line_address): Replace p_record_line parameter with state.
>> > All callers updated.
>> > (dwarf_decode_lines_1): Call dwarf_record_line, init_lnp_state_machine.
>> > Update to record state in lnp_state_machine.
>>
>> Here is what I committed.
>> Just a few comment changes to remove references to two level
>> line tables, which are in a later patch.
>
> Hi Doug,
>
> I have a little question about something this patch. One behaviour changed,
> but I don't know if it was intentional or not. I assume it is not, since the goal
> of this patch was to refactor/cleanup.
>
> When reading full symbols, after an end_sequence, dwarf_finish_line was called
> unconditionally. Now, the call to dwarf_finish_line is guarded by:
>
> if (state->last_subfile != current_subfile) {
>
> Before this patch, the two other calls to dwarf_finish_line were guarded by this if.
> However, the third one wasn't. Is this change intentional?
>
> I am asking this because that call is apparently important for gdb to properly
> understand DWARF generated by one of our internal compiler. To restore the previous
> behaviour, I did the following. Would it make sense to have the same change in FSF's gdb?
>
> ---8<---
>
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index 1e290c3..d79b2e3 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -17658,7 +17658,7 @@ dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
> lh->file_names[file - 1].included_p = 1;
> if (reader->record_lines_p && is_stmt)
> {
> - if (state->last_subfile != current_subfile)
> + if (state->last_subfile != current_subfile || end_sequence)
> {
> dwarf_finish_line (reader->gdbarch, state->last_subfile,
> state->address, state->record_line);
>
> --->8---
Yikes.
My bad, thanks for catching this.
LGTM
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state
2015-06-10 20:04 ` Doug Evans
@ 2015-06-10 20:35 ` Simon Marchi
0 siblings, 0 replies; 5+ messages in thread
From: Simon Marchi @ 2015-06-10 20:35 UTC (permalink / raw)
To: Doug Evans; +Cc: gdb-patches
> Yikes.
> My bad, thanks for catching this.
>
> LGTM
Thanks. I pushed this:
From e815d2d2714a395d11abb350eff385931257ed9a Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@ericsson.com>
Date: Wed, 10 Jun 2015 16:34:16 -0400
Subject: [PATCH] dwarf2read: call dwarf_finish_line when ending a sequence
Commit d9b3de22f33e400f7f409cce3acf6c7dab07dd79 introduced a behaviour
change where dwarf_finish_line was not called anymore when ending a
sequence of machine instructions. This patch restores the original
behaviour.
gdb/ChangeLog:
* dwarf2read.c (dwarf_record_line): Call dwarf_record_line if
end_sequence is true.
---
gdb/ChangeLog | 5 +++++
gdb/dwarf2read.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5b19052..872d88a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2015-06-10 Simon Marchi <simon.marchi@ericsson.com>
+
+ * dwarf2read.c (dwarf_record_line): Call dwarf_record_line if
+ end_sequence is true.
+
2015-06-10 Jan Kratochvil <jan.kratochvil@redhat.com>
Code cleanup.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 1e290c3..d79b2e3 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17658,7 +17658,7 @@ dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
lh->file_names[file - 1].included_p = 1;
if (reader->record_lines_p && is_stmt)
{
- if (state->last_subfile != current_subfile)
+ if (state->last_subfile != current_subfile || end_sequence)
{
dwarf_finish_line (reader->gdbarch, state->last_subfile,
state->address, state->record_line);
--
2.1.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state
@ 2015-03-12 20:05 Doug Evans
0 siblings, 0 replies; 5+ messages in thread
From: Doug Evans @ 2015-03-12 20:05 UTC (permalink / raw)
To: gdb-patches; +Cc: ccoutant
Hi.
This patch puts the line number state machine into a struct
to make it clear exactly what is part of the state machine
and what is not. Previously, gdb just had a bunch of local variables.
2015-03-12 Doug Evans <dje@google.com>
* dwarf2read.c (lnp_state_machine): New typedef.
(lnp_reader_state): New typedef.
(dwarf_record_line_1): Renamed from dwarf_record_line.
All callers updated.
(dwarf_record_line): New function.
(init_lnp_state_machine): New function.
(check_line_address): Replace p_record_line parameter with state.
All callers updated.
(dwarf_decode_lines_1): Call dwarf_record_line, init_lnp_state_machine.
Update to record state in lnp_state_machine.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index fff5474..827ae6c 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17434,6 +17434,54 @@ psymtab_include_file_name (const struct line_header *lh, int file_index,
typedef void (record_line_ftype) (struct subfile *subfile, int line,
CORE_ADDR pc);
+/* State machine to track the state of the line number program. */
+
+typedef struct
+{
+ /* These are part of the standard DWARF line number state machine. */
+
+ unsigned char op_index;
+ unsigned int file;
+ unsigned int line;
+ CORE_ADDR address;
+ int is_stmt;
+ unsigned int discriminator;
+
+ /* Additional bits of state we need to track. */
+
+ /* The last file that we called dwarf2_start_subfile for.
+ This is only used for TLLs. */
+ unsigned int last_file;
+ /* The last file a line number was recorded for. */
+ struct subfile *last_subfile;
+
+ /* The function to call to record a line. */
+ record_line_ftype *record_line;
+
+ /* The last line number that was recorded, used to coalesce
+ consecutive entries for the same line. This can happen, for
+ example, when discriminators are present. PR 17276. */
+ unsigned int last_line;
+ int line_has_non_zero_discriminator;
+} lnp_state_machine;
+
+/* There's a lot of static state to pass to dwarf_record_line.
+ This keeps it all together. */
+
+typedef struct
+{
+ /* The gdbarch. */
+ struct gdbarch *gdbarch;
+
+ /* The line number header. */
+ struct line_header *line_header;
+
+ /* Non-zero if we're recording lines.
+ Otherwise we're building partial symtabs and are just interested in
+ finding include files mentioned by the line number program. */
+ int record_lines_p;
+} lnp_reader_state;
+
/* Ignore this record_line request. */
static void
@@ -17493,9 +17541,9 @@ dwarf_record_line_p (unsigned int line, unsigned int last_line,
in the line table of subfile SUBFILE. */
static void
-dwarf_record_line (struct gdbarch *gdbarch, struct subfile *subfile,
- unsigned int line, CORE_ADDR address,
- record_line_ftype p_record_line)
+dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
+ unsigned int line, CORE_ADDR address,
+ record_line_ftype p_record_line)
{
CORE_ADDR addr = gdbarch_addr_bits_remove (gdbarch, address);
@@ -17512,7 +17560,7 @@ dwarf_record_line (struct gdbarch *gdbarch, struct subfile *subfile,
/* Subroutine of dwarf_decode_lines_1 to simplify it.
Mark the end of a set of line number records.
- The arguments are the same as for dwarf_record_line.
+ The arguments are the same as for dwarf_record_line_1.
If SUBFILE is NULL the request is ignored. */
static void
@@ -17530,14 +17578,105 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
paddress (gdbarch, address));
}
- dwarf_record_line (gdbarch, subfile, 0, address, p_record_line);
+ dwarf_record_line_1 (gdbarch, subfile, 0, address, p_record_line);
+}
+
+/* Record either a logical line or an actual line.
+ END_SEQUENCE is non-zero if we're processing the end of a sequence. */
+
+static void
+dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
+ int end_sequence)
+{
+ const struct line_header *lh = reader->line_header;
+ unsigned int file, line, discriminator;
+ int is_stmt;
+
+ file = state->file;
+ line = state->line;
+ is_stmt = state->is_stmt;
+ discriminator = state->discriminator;
+
+ if (dwarf2_line_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Processing actual line %u: file %u,"
+ " address %s, is_stmt %u, discrim %u\n",
+ line, file,
+ paddress (reader->gdbarch, state->address),
+ is_stmt, discriminator);
+ }
+
+ if (file == 0 || file - 1 >= lh->num_file_names)
+ dwarf2_debug_line_missing_file_complaint ();
+ /* For now we ignore lines not starting on an instruction boundary.
+ But not when processing end_sequence for compatibility with the
+ previous version of the code. */
+ else if (state->op_index == 0 || end_sequence)
+ {
+ lh->file_names[file - 1].included_p = 1;
+ if (reader->record_lines_p && is_stmt)
+ {
+ if (state->last_subfile != current_subfile)
+ {
+ dwarf_finish_line (reader->gdbarch, state->last_subfile,
+ state->address, state->record_line);
+ }
+
+ if (!end_sequence)
+ {
+ if (dwarf_record_line_p (line, state->last_line,
+ state->line_has_non_zero_discriminator,
+ state->last_subfile))
+ {
+ dwarf_record_line_1 (reader->gdbarch, current_subfile,
+ line, state->address,
+ state->record_line);
+ }
+ state->last_subfile = current_subfile;
+ state->last_line = line;
+ }
+ }
+ }
+}
+
+/* Initialize STATE for the start of a line number program.
+ TODO(dje): Seems like this should be reset at the start of each sequence
+ but that's not what the previous code did. */
+
+static void
+init_lnp_state_machine (lnp_state_machine *state,
+ const lnp_reader_state *reader)
+{
+ memset (state, 0, sizeof (*state));
+
+ /* Just starting, there is no "last file". */
+ state->last_file = 0;
+ state->last_subfile = NULL;
+
+ state->record_line = record_line;
+
+ state->last_line = 0;
+ state->line_has_non_zero_discriminator = 0;
+
+ /* Initialize these according to the DWARF spec. */
+ state->op_index = 0;
+ state->file = 1;
+ state->line = 1;
+ /* Call `gdbarch_adjust_dwarf2_line' on the initial 0 address as if there
+ was a line entry for it so that the backend has a chance to adjust it
+ and also record it in case it needs it. This is currently used by MIPS
+ code, cf. `mips_adjust_dwarf2_line'. */
+ state->address = gdbarch_adjust_dwarf2_line (reader->gdbarch, 0, 0);
+ state->is_stmt = reader->line_header->default_is_stmt;
+ state->discriminator = 0;
}
/* Check address and if invalid nop-out the rest of the lines in this
sequence. */
static void
-check_line_address (struct dwarf2_cu *cu, record_line_ftype **p_record_line,
+check_line_address (struct dwarf2_cu *cu, lnp_state_machine *state,
const gdb_byte *line_ptr,
CORE_ADDR lowpc, CORE_ADDR address)
{
@@ -17557,14 +17696,16 @@ check_line_address (struct dwarf2_cu *cu, record_line_ftype **p_record_line,
complaint (&symfile_complaints,
_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
line_offset, objfile_name (objfile));
- *p_record_line = noop_record_line;
- /* Note: *p_record_line is left as noop_record_line
+ state->record_line = noop_record_line;
+ /* Note: sm.record_line is left as noop_record_line
until we see DW_LNE_end_sequence. */
}
}
/* Subroutine of dwarf_decode_lines to simplify it.
- Process the line number information in LH. */
+ Process the line number information in LH.
+ If DECODE_FOR_PST_P is non-zero, all we do is process the line number
+ program in order to set included_p for every referenced header. */
static void
dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
@@ -17578,43 +17719,38 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
struct objfile *objfile = cu->objfile;
bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct subfile *last_subfile = NULL;
- void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc)
- = record_line;
+ /* Non-zero if we're recording line info (as opposed to building partial
+ symtabs or building the logical line table). */
+ int record_lines_p = !decode_for_pst_p;
+ /* A collection of things we need to pass to dwarf_record_line. */
+ lnp_reader_state reader_state;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
line_ptr = lh->statement_program_start;
line_end = lh->statement_program_end;
+ reader_state.gdbarch = gdbarch;
+ reader_state.line_header = lh;
+ reader_state.record_lines_p = record_lines_p;
+
/* Read the statement sequences until there's nothing left. */
while (line_ptr < line_end)
{
- /* State machine registers. Call `gdbarch_adjust_dwarf2_line'
- on the initial 0 address as if there was a line entry for it
- so that the backend has a chance to adjust it and also record
- it in case it needs it. This is currently used by MIPS code,
- cf. `mips_adjust_dwarf2_line'. */
- CORE_ADDR address = gdbarch_adjust_dwarf2_line (gdbarch, 0, 0);
- unsigned int file = 1;
- unsigned int line = 1;
- int is_stmt = lh->default_is_stmt;
+ /* The DWARF line number program state machine. */
+ lnp_state_machine state_machine;
int end_sequence = 0;
- unsigned char op_index = 0;
- unsigned int discriminator = 0;
- /* The last line number that was recorded, used to coalesce
- consecutive entries for the same line. This can happen, for
- example, when discriminators are present. PR 17276. */
- unsigned int last_line = 0;
- int line_has_non_zero_discriminator = 0;
-
- if (!decode_for_pst_p && lh->num_file_names >= file)
+
+ /* Reset the state machine at the start of each sequence. */
+ init_lnp_state_machine (&state_machine, &reader_state);
+
+ if (record_lines_p && lh->num_file_names >= state_machine.file)
{
/* Start a subfile for the current file of the state machine. */
/* lh->include_dirs and lh->file_names are 0-based, but the
directory and file name numbers in the statement program
are 1-based. */
- struct file_entry *fe = &lh->file_names[file - 1];
+ struct file_entry *fe = &lh->file_names[state_machine.file - 1];
const char *dir = NULL;
if (fe->dir_index)
@@ -17624,15 +17760,10 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
}
/* Decode the table. */
- while (!end_sequence)
+ while (line_ptr < line_end && !end_sequence)
{
op_code = read_1_byte (abfd, line_ptr);
line_ptr += 1;
- if (line_ptr > line_end)
- {
- dwarf2_debug_line_missing_end_sequence_complaint ();
- break;
- }
if (op_code >= lh->opcode_base)
{
@@ -17642,42 +17773,23 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
int line_delta;
adj_opcode = op_code - lh->opcode_base;
- addr_adj = (((op_index + (adj_opcode / lh->line_range))
+ addr_adj = (((state_machine.op_index
+ + (adj_opcode / lh->line_range))
/ lh->maximum_ops_per_instruction)
* lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + (adj_opcode / lh->line_range))
- % lh->maximum_ops_per_instruction);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index
+ + (adj_opcode / lh->line_range))
+ % lh->maximum_ops_per_instruction);
line_delta = lh->line_base + (adj_opcode % lh->line_range);
- line += line_delta;
+ state_machine.line += line_delta;
if (line_delta != 0)
- line_has_non_zero_discriminator = discriminator != 0;
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- /* For now we ignore lines not starting on an
- instruction boundary. */
- else if (op_index == 0)
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p && is_stmt)
- {
- if (last_subfile != current_subfile)
- {
- dwarf_finish_line (gdbarch, last_subfile,
- address, p_record_line);
- }
- if (dwarf_record_line_p (line, last_line,
- line_has_non_zero_discriminator,
- last_subfile))
- {
- dwarf_record_line (gdbarch, current_subfile,
- line, address, p_record_line);
- }
- last_subfile = current_subfile;
- last_line = line;
- }
- }
- discriminator = 0;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
+
+ dwarf_record_line (&reader_state, &state_machine, 0);
+ state_machine.discriminator = 0;
}
else switch (op_code)
{
@@ -17691,17 +17803,22 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
switch (extended_op)
{
case DW_LNE_end_sequence:
- p_record_line = record_line;
+ state_machine.record_line = record_line;
end_sequence = 1;
break;
case DW_LNE_set_address:
- address = read_address (abfd, line_ptr, cu, &bytes_read);
- line_ptr += bytes_read;
- check_line_address (cu, &p_record_line, line_ptr,
- lowpc, address);
- op_index = 0;
- address += baseaddr;
- address = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+ {
+ CORE_ADDR address
+ = read_address (abfd, line_ptr, cu, &bytes_read);
+
+ line_ptr += bytes_read;
+ check_line_address (cu, &state_machine, line_ptr,
+ lowpc, address);
+ state_machine.op_index = 0;
+ address += baseaddr;
+ state_machine.address
+ = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+ }
break;
case DW_LNE_define_file:
{
@@ -17729,9 +17846,10 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
if there are consecutive entries for the same
(non-prologue) line we want to coalesce them.
PR 17276. */
- discriminator = read_unsigned_leb128 (abfd, line_ptr,
- &bytes_read);
- line_has_non_zero_discriminator |= discriminator != 0;
+ state_machine.discriminator
+ = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ state_machine.line_has_non_zero_discriminator
+ |= state_machine.discriminator != 0;
line_ptr += bytes_read;
break;
default:
@@ -17750,30 +17868,8 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
}
break;
case DW_LNS_copy:
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p && is_stmt)
- {
- if (last_subfile != current_subfile)
- {
- dwarf_finish_line (gdbarch, last_subfile,
- address, p_record_line);
- }
- if (dwarf_record_line_p (line, last_line,
- line_has_non_zero_discriminator,
- last_subfile))
- {
- dwarf_record_line (gdbarch, current_subfile,
- line, address, p_record_line);
- }
- last_subfile = current_subfile;
- last_line = line;
- }
- }
- discriminator = 0;
+ dwarf_record_line (&reader_state, &state_machine, 0);
+ state_machine.discriminator = 0;
break;
case DW_LNS_advance_pc:
{
@@ -17781,12 +17877,13 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
= read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
CORE_ADDR addr_adj;
- addr_adj = (((op_index + adjust)
+ addr_adj = (((state_machine.op_index + adjust)
/ lh->maximum_ops_per_instruction)
* lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + adjust)
- % lh->maximum_ops_per_instruction);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index + adjust)
+ % lh->maximum_ops_per_instruction);
line_ptr += bytes_read;
}
break;
@@ -17795,9 +17892,10 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
int line_delta
= read_signed_leb128 (abfd, line_ptr, &bytes_read);
- line += line_delta;
+ state_machine.line += line_delta;
if (line_delta != 0)
- line_has_non_zero_discriminator = discriminator != 0;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
line_ptr += bytes_read;
}
break;
@@ -17809,19 +17907,22 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
struct file_entry *fe;
const char *dir = NULL;
- file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ state_machine.file = read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read);
line_ptr += bytes_read;
- if (lh->num_file_names < file || file == 0)
+ if (state_machine.file == 0
+ || state_machine.file - 1 >= lh->num_file_names)
dwarf2_debug_line_missing_file_complaint ();
else
{
- fe = &lh->file_names[file - 1];
+ fe = &lh->file_names[state_machine.file - 1];
if (fe->dir_index)
- dir = lh->include_dirs[fe->dir_index - 1];
- if (!decode_for_pst_p)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ if (record_lines_p)
{
- last_subfile = current_subfile;
- line_has_non_zero_discriminator = discriminator != 0;
+ state_machine.last_subfile = current_subfile;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
dwarf2_start_subfile (fe->name, dir);
}
}
@@ -17832,7 +17933,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
line_ptr += bytes_read;
break;
case DW_LNS_negate_stmt:
- is_stmt = (!is_stmt);
+ state_machine.is_stmt = (!state_machine.is_stmt);
break;
case DW_LNS_set_basic_block:
break;
@@ -17846,12 +17947,13 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range;
CORE_ADDR addr_adj;
- addr_adj = (((op_index + adjust)
+ addr_adj = (((state_machine.op_index + adjust)
/ lh->maximum_ops_per_instruction)
* lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + adjust)
- % lh->maximum_ops_per_instruction);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index + adjust)
+ % lh->maximum_ops_per_instruction);
}
break;
case DW_LNS_fixed_advance_pc:
@@ -17859,8 +17961,9 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
CORE_ADDR addr_adj;
addr_adj = read_2_bytes (abfd, line_ptr);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = 0;
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = 0;
line_ptr += 2;
}
break;
@@ -17877,17 +17980,13 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
}
}
}
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
- {
- dwarf_finish_line (gdbarch, current_subfile, address,
- p_record_line);
- }
- }
+
+ if (!end_sequence)
+ dwarf2_debug_line_missing_end_sequence_complaint ();
+
+ /* We got a DW_LNE_end_sequence (or we ran off the end of the buffer,
+ in which case we still finish recording the last line). */
+ dwarf_record_line (&reader_state, &state_machine, 1);
}
}
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-06-10 20:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-27 22:22 [PATCH 4/6] DWARF Two Level Line Tables: lnp_state_machine, lnp_reader_state Doug Evans
2015-06-10 19:44 ` Simon Marchi
2015-06-10 20:04 ` Doug Evans
2015-06-10 20:35 ` Simon Marchi
-- strict thread matches above, loose matches on Subject: below --
2015-03-12 20:05 Doug Evans
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).