Re: [RFA 1/2] Make line tables independent of progspace

Tom Tromey
2018-03-27T04:53:33Z

Tom> I've run the new patch through the buildbot. I'll resubmit it soon, I
Tom> just have to update the ChangeLog and rewrite the commit message.

Here it is. Let me reiterate that this probably requires careful review
as the buildbot may not test some of these paths.

Tom

commit 79caf09e07239e97ea9237d80a1da134b4a9cf87
Author: Tom Tromey <tom@tromey.com>
Date: Wed Mar 21 15:11:09 2018 -0600

Make line tables independent of progspace

This changes line tables to be independent of the program space.

Unlike the corresponding series for minimal symbols, this is a single
patch -- because line tables are used much less frequently than
symbols, it seemed ok to have one patch for the whole conversion.

This patch first renames the fields of the line table, making them
private. This made it simple to find all users of the fields. It
adds accessors and setters.

All the setters of the field are updated not to offset the PC by the
section offset. I think I've done this properly but I can't test all
the spots, unfortunately.

This patch also cleans up xcoffread.c:compare_lte to make it more
obviously correct.

It was difficult while writing this patch to decide what to do about
gdbarch_addr_bits_remove (and to a lesser extent,
gdbarch_adjust_dwarf2_line). Previously, all the symbol readers
called this during reading, with the relocated address. However,
there was an assumption later, in objfile_relocate1, that this did not
need to be re-done after relocation. So, one option would have been
to call this on the relocated address, and then "unrelocate" it (this
is what I did for gdbarch_adjust_dwarf2_line). Instead, though, in
this patch I chose to call gdbarch_addr_bits_remove at the point where
the PC is computed. I'm still not completely certain that this is the
best approach -- please consider this.

While this patch is a step forward, it is still using the backlink
from the symtab to the objfile. So, more work will be needed in this
area before line tables can be moved to the per-BFD storage.

gdb/ChangeLog
2018-03-21 Tom Tromey <tom@tromey.com>

Obsoletes PR symtab/8077:
* record-btrace.c (btrace_find_line_range): Update.
* dwarf2read.c (lnp_state_machine::handle_set_address): Remove
baseaddr argument.
(dwarf_record_line_1): Don't call gdbarch_addr_bits_remove.
* buildsym.c (record_line, compare_line_numbers): Update.
* coffread.c (enter_linenos): Don't add section offset when
creating line table.
(coff_symtab_read): Don't call gdbarch_addr_bits_remove.
* dbxread.c (process_one_symbol): Remove section offset when
creating line table.
* disasm.c (do_mixed_source_and_assembly): Update.
* dwarf2read.c (dwarf_decode_lines_1): Don't add section offset
when creating line table.
* jit.c (jit_symtab_line_mapping_add_impl): Update.
* mdebugread.c (parse_lines, psymtab_to_symtab_1): Don't add
section offset when creating line table.
(add_line): Update.
* mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines): Update.
* objfiles.c (objfile_relocate1): Don't relocate line tables.
* python/py-linetable.c (ltpy_iternext): Update.
* symmisc.c (dump_symtab_1): Update.
* symtab.c (find_pc_sect_line, find_pcs_for_symtab_line)
(skip_prologue_using_lineinfo, skip_prologue_using_sal): Update.
* symtab.h (struct linetable_entry) <m_pc>: Rename from "pc".
<m_line>: Rename from "line".
<set, raw_address, address, line>: New methods.
* xcoffread.c (compare_lte): Update and rewrite.
(arrange_linetable): Update.
(enter_line_range): Don't add section offset when creating line
table.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 64130c5392..1170c62673 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,37 @@
+2018-03-21 Tom Tromey <tom@tromey.com>
+
+ Obsoletes PR symtab/8077:
+ * record-btrace.c (btrace_find_line_range): Update.
+ * dwarf2read.c (lnp_state_machine::handle_set_address): Remove
+ baseaddr argument.
+ (dwarf_record_line_1): Don't call gdbarch_addr_bits_remove.
+ * buildsym.c (record_line, compare_line_numbers): Update.
+ * coffread.c (enter_linenos): Don't add section offset when
+ creating line table.
+ (coff_symtab_read): Don't call gdbarch_addr_bits_remove.
+ * dbxread.c (process_one_symbol): Remove section offset when
+ creating line table.
+ * disasm.c (do_mixed_source_and_assembly): Update.
+ * dwarf2read.c (dwarf_decode_lines_1): Don't add section offset
+ when creating line table.
+ * jit.c (jit_symtab_line_mapping_add_impl): Update.
+ * mdebugread.c (parse_lines, psymtab_to_symtab_1): Don't add
+ section offset when creating line table.
+ (add_line): Update.
+ * mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines): Update.
+ * objfiles.c (objfile_relocate1): Don't relocate line tables.
+ * python/py-linetable.c (ltpy_iternext): Update.
+ * symmisc.c (dump_symtab_1): Update.
+ * symtab.c (find_pc_sect_line, find_pcs_for_symtab_line)
+ (skip_prologue_using_lineinfo, skip_prologue_using_sal): Update.
+ * symtab.h (struct linetable_entry) <m_pc>: Rename from "pc".
+ <m_line>: Rename from "line".
+ <set, raw_address, address, line>: New methods.
+ * xcoffread.c (compare_lte): Update and rewrite.
+ (arrange_linetable): Update.
+ (enter_line_range): Don't add section offset when creating line
+ table.
+
2018-03-26 Tom Tromey <tom@tromey.com>

* stack.c (backtrace_command_1): Remove verbose code.
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 5d38cb250f..f2c08aa530 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -947,7 +947,8 @@ record_line (struct subfile *subfile, int line, CORE_ADDR pc)
if (line == 0 && subfile->line_vector->nitems > 0)
{
e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
- while (subfile->line_vector->nitems > 0 && e->pc == pc)
+ while (subfile->line_vector->nitems > 0
+ && e->raw_address () == pc)
{
e--;
subfile->line_vector->nitems--;
@@ -955,8 +956,7 @@ record_line (struct subfile *subfile, int line, CORE_ADDR pc)
}

e = subfile->line_vector->item + subfile->line_vector->nitems++;
- e->line = line;
- e->pc = pc;
+ e->set (line, pc);
}

/* Needed in order to sort line tables from IBM xcoff files. Sigh! */
@@ -969,15 +969,15 @@ compare_line_numbers (const void *ln1p, const void *ln2p)

/* Note: this code does not assume that CORE_ADDRs can fit in ints.
Please keep it that way. */
- if (ln1->pc < ln2->pc)
+ if (ln1->raw_address () < ln2->raw_address ())
return -1;

- if (ln1->pc > ln2->pc)
+ if (ln1->raw_address () > ln2->raw_address ())
return 1;

/* If pc equal, sort by line. I'm not sure whether this is optimum
behavior (see comment at struct linetable in symtab.h). */
- return ln1->line - ln2->line;
+ return ln1->line () - ln2->line ();
}
\f
/* See buildsym.h. */
diff --git a/gdb/coffread.c b/gdb/coffread.c
index cad3e7e2f1..8408d07bde 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -1130,8 +1130,7 @@ coff_symtab_read (minimal_symbol_reader &reader,
other statement-line-number. */
if (fcn_last_line == 1)
record_line (current_subfile, fcn_first_line,
- gdbarch_addr_bits_remove (gdbarch,
- fcn_first_line_addr));
+ fcn_first_line_addr);
else
enter_linenos (fcn_line_ptr, fcn_first_line,
fcn_last_line, objfile);
@@ -1506,11 +1505,9 @@ enter_linenos (long file_offset, int first_line,
if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
{
CORE_ADDR addr = lptr.l_addr.l_paddr;
- addr += ANOFFSET (objfile->section_offsets,
- SECT_OFF_TEXT (objfile));
record_line (current_subfile,
first_line + L_LNNO32 (&lptr),
- gdbarch_addr_bits_remove (gdbarch, addr));
+ addr);
}
else
break;
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index bdf4fb9c79..ff6f9ec20f 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -2562,10 +2562,10 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
but no N_SLINE stabs. */
if (sline_found_in_function)
{
- CORE_ADDR addr = last_function_start + valu;
-
- record_line (current_subfile, 0,
- gdbarch_addr_bits_remove (gdbarch, addr));
+ CORE_ADDR addr = (last_function_start + valu
+ - ANOFFSET (section_offsets,
+ SECT_OFF_TEXT (objfile)));
+ record_line (current_subfile, 0, addr);
}

within_function = 0;
@@ -2767,16 +2767,22 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,

if (within_function && sline_found_in_function == 0)
{
- CORE_ADDR addr = processing_gcc_compilation == 2 ?
- last_function_start : valu;
+ CORE_ADDR addr = ((processing_gcc_compilation == 2 ?
+ last_function_start : valu)
+ - ANOFFSET (section_offsets,
+ SECT_OFF_TEXT (objfile)));

- record_line (current_subfile, desc,
- gdbarch_addr_bits_remove (gdbarch, addr));
+ record_line (current_subfile, desc, addr);
sline_found_in_function = 1;
}
else
- record_line (current_subfile, desc,
- gdbarch_addr_bits_remove (gdbarch, valu));
+ {
+ CORE_ADDR addr = (valu
+ - ANOFFSET (section_offsets,
+ SECT_OFF_TEXT (objfile)));
+
+ record_line (current_subfile, desc, addr);
+ }
break;

case N_BCOMM:
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 833341a169..506152d214 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -30,6 +30,7 @@
#include "safe-ctype.h"
#include <algorithm>
#include "common/gdb_optional.h"
+#include "objfiles.h"

/* Disassemble functions.
FIXME: We should get rid of all the duplicate code in gdb that does
@@ -368,35 +369,39 @@ do_mixed_source_and_assembly_deprecated

/* First, skip all the preceding functions. */

- for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+ for (i = 0;
+ i < nlines - 1 && le[i].address (symtab) < low;
+ i++)
+ ;

/* Now, copy all entries before the end of this function. */

- for (; i < nlines - 1 && le[i].pc < high; i++)
+ for (; i < nlines - 1 && le[i].address (symtab) < high; i++)
{
- if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
+ if (le[i].line () == le[i + 1].line ()
+ && le[i].raw_address () == le[i + 1].raw_address ())
continue; /* Ignore duplicates. */

/* Skip any end-of-function markers. */
- if (le[i].line == 0)
+ if (le[i].line () == 0)
continue;

- mle[newlines].line = le[i].line;
- if (le[i].line > le[i + 1].line)
+ mle[newlines].line = le[i].line ();
+ if (le[i].line () > le[i + 1].line ())
out_of_order = 1;
- mle[newlines].start_pc = le[i].pc;
- mle[newlines].end_pc = le[i + 1].pc;
+ mle[newlines].start_pc = le[i].address (symtab);
+ mle[newlines].end_pc = le[i + 1].address (symtab);
newlines++;
}

/* If we're on the last line, and it's part of the function,
then we need to get the end pc in a special way. */

- if (i == nlines - 1 && le[i].pc < high)
+ if (i == nlines - 1 && le[i].address (symtab) < high)
{
- mle[newlines].line = le[i].line;
- mle[newlines].start_pc = le[i].pc;
- sal = find_pc_line (le[i].pc, 0);
+ mle[newlines].line = le[i].line ();
+ mle[newlines].start_pc = le[i].address (symtab);
+ sal = find_pc_line (le[i].address (symtab), 0);
mle[newlines].end_pc = sal.end;
newlines++;
}
@@ -517,10 +522,12 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch,
first_le = NULL;

/* Skip all the preceding functions. */
- for (i = 0; i < nlines && le[i].pc < low; i++)
- continue;
+ for (i = 0;
+ i < nlines - 1 && le[i].address (main_symtab) < low;
+ i++)
+ ;

- if (i < nlines && le[i].pc < high)
+ if (i < nlines && le[i].address (main_symtab) < high)
first_le = &le[i];

/* Add lines for every pc value. */
@@ -589,9 +596,9 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch,
lines. */
if (last_line == 0
&& first_le != NULL
- && first_le->line < sal.line)
+ && first_le->line () < sal.line)
{
- start_preceding_line_to_display = first_le->line;
+ start_preceding_line_to_display = first_le->line ();
end_preceding_line_to_display = sal.line;
}
}
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 211364c428..ab6e687952 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -20859,8 +20859,11 @@ public:
void handle_set_address (CORE_ADDR baseaddr, CORE_ADDR address)
{
m_op_index = 0;
+ /* Pass the relocated address to the gdbarch for modification, but
+ then only store the relative address. */
address += baseaddr;
- m_address = gdbarch_adjust_dwarf2_line (m_gdbarch, address, false);
+ m_address = (gdbarch_adjust_dwarf2_line (m_gdbarch, address, false)
+ - baseaddr);
}

/* Handle DW_LNS_advance_pc. */
@@ -21086,8 +21089,6 @@ 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);
-
if (dwarf_line_debug)
{
fprintf_unfiltered (gdb_stdlog,
@@ -21096,7 +21097,7 @@ dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
paddress (gdbarch, address));
}

- (*p_record_line) (subfile, line, addr);
+ (*p_record_line) (subfile, line, address);
}

/* Subroutine of dwarf_decode_lines_1 to simplify it.
diff --git a/gdb/jit.c b/gdb/jit.c
index 2f23c058a0..eb4579c96b 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -622,8 +622,9 @@ jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb,
stab->linetable->nitems = nlines;
for (i = 0; i < nlines; i++)
{
- stab->linetable->item[i].pc = (CORE_ADDR) map[i].pc;
- stab->linetable->item[i].line = map[i].line;
+ /* Use the absolute address here, as the offsets will all be
+ zero. */
+ stab->linetable->item[i].set (map[i].line, (CORE_ADDR) map[i].pc);
}
}

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 1236b3f475..d9ad798200 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -2199,7 +2199,7 @@ create_sals_line_offset (struct linespec_state *self,
= decode_digits_ordinary (self, ls, val.line, &best_entry);
if (intermediate_results.empty () && best_entry != NULL)
intermediate_results = decode_digits_ordinary (self, ls,
- best_entry->line,
+ best_entry->line (),
&best_entry);

/* For optimized code, the compiler can scatter one source line
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index c0bce55148..a12e459cc6 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -2213,7 +2213,7 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
halt = base + fh->cbLine;
base += pr->cbLineOffset;

- adr = pst->textlow + pr->adr - lowest_pdr_addr;
+ adr = pr->adr - lowest_pdr_addr;

l = adr >> 2; /* in words */
for (lineno = pr->lnLow; base < halt;)
@@ -4090,10 +4090,7 @@ psymtab_to_symtab_1 (struct objfile *objfile,
else
{
/* Handle encoded stab line number. */
- valu += ANOFFSET (section_offsets,
- SECT_OFF_TEXT (objfile));
- record_line (current_subfile, sh.index,
- gdbarch_addr_bits_remove (gdbarch, valu));
+ record_line (current_subfile, sh.index, valu);
}
}
else if (sh.st == stProc || sh.st == stStaticProc
@@ -4634,8 +4631,8 @@ add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last)
if (last == lineno) /* Skip continuation lines. */
return lineno;

- lt->item[lt->nitems].line = lineno;
- lt->item[lt->nitems++].pc = adr << 2;
+ lt->item[lt->nitems].set (lineno, adr << 2);
+ ++lt->nitems;
return lineno;
}
\f
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c
index 223b8c3ce1..ca0fc379a4 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -34,6 +34,7 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc)
struct symtab *s;
int i;
struct ui_out *uiout = current_uiout;
+ struct linetable *linetable;

if (argc != 1)
error (_("-symbol-list-lines: Usage: SOURCE_FILENAME"));
@@ -51,11 +52,12 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc)
gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));

ui_out_emit_list list_emitter (uiout, "lines");
- if (SYMTAB_LINETABLE (s) != NULL && SYMTAB_LINETABLE (s)->nitems > 0)
- for (i = 0; i < SYMTAB_LINETABLE (s)->nitems; i++)
+ linetable = SYMTAB_LINETABLE (s);
+ if (linetable != NULL && linetable->nitems > 0)
+ for (i = 0; i < linetable->nitems; i++)
{
ui_out_emit_tuple tuple_emitter (uiout, NULL);
- uiout->field_core_addr ("pc", gdbarch, SYMTAB_LINETABLE (s)->item[i].pc);
- uiout->field_int ("line", SYMTAB_LINETABLE (s)->item[i].line);
+ uiout->field_core_addr ("pc", gdbarch, linetable->item[i].address (s));
+ uiout->field_int ("line", linetable->item[i].line ());
}
}
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 98e81c48c4..0c1d3ffb57 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -799,23 +799,6 @@ objfile_relocate1 (struct objfile *objfile,
/* OK, get all the symtabs. */
{
struct compunit_symtab *cust;
- struct symtab *s;
-
- ALL_OBJFILE_FILETABS (objfile, cust, s)
- {
- struct linetable *l;
- int i;
-
- /* First the line table. */
- l = SYMTAB_LINETABLE (s);
- if (l)
- {
- for (i = 0; i < l->nitems; ++i)
- l->item[i].pc += ANOFFSET (delta,
- COMPUNIT_BLOCK_LINE_SECTION
- (cust));
- }
- }

ALL_OBJFILE_COMPUNITS (objfile, cust)
{
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index c4e80d02a5..c17aac31e8 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -20,6 +20,7 @@
#include "defs.h"
#include "python-internal.h"
#include "py-ref.h"
+#include "objfiles.h"

typedef struct {
PyObject_HEAD
@@ -204,7 +205,7 @@ ltpy_has_line (PyObject *self, PyObject *args)
for (index = 0; index < SYMTAB_LINETABLE (symtab)->nitems; index++)
{
struct linetable_entry *item = &(SYMTAB_LINETABLE (symtab)->item[index]);
- if (item->line == py_line)
+ if (item->line () == py_line)
Py_RETURN_TRUE;
}

@@ -242,9 +243,9 @@ ltpy_get_all_source_lines (PyObject *self, PyObject *args)

/* 0 is used to signify end of line table information. Do not
include in the source set. */
- if (item->line > 0)
+ if (item->line () > 0)
{
- gdbpy_ref<> line (gdb_py_object_from_longest (item->line));
+ gdbpy_ref<> line (gdb_py_object_from_longest (item->line ()));

if (line == NULL)
return NULL;
@@ -410,7 +411,7 @@ ltpy_iternext (PyObject *self)

/* Skip over internal entries such as 0. 0 signifies the end of
line table data and is not useful to the API user. */
- while (item->line < 1)
+ while (item->line () < 1)
{
iter_obj->current_index++;

@@ -423,7 +424,7 @@ ltpy_iternext (PyObject *self)
item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]);
}

- obj = build_linetable_entry (item->line, item->pc);
+ obj = build_linetable_entry (item->line (), item->address (symtab));
iter_obj->current_index++;

return obj;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 7264b8ed2b..d09a4ad8cb 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -40,6 +40,7 @@
#include "inf-loop.h"
#include "vec.h"
#include <algorithm>
+#include "objfiles.h"

/* The target_ops of record-btrace. */
static struct target_ops record_btrace_ops;
@@ -596,8 +597,8 @@ btrace_find_line_range (CORE_ADDR pc)
range = btrace_mk_line_range (symtab, 0, 0);
for (i = 0; i < nlines - 1; i++)
{
- if ((lines[i].pc == pc) && (lines[i].line != 0))
- range = btrace_line_range_add (range, lines[i].line);
+ if (lines[i].address (symtab) == pc && lines[i].line () != 0)
+ range = btrace_line_range_add (range, lines[i].line ());
}

return range;
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 9adde044cd..05348b880f 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -302,8 +302,9 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile)
len = l->nitems;
for (i = 0; i < len; i++)
{
- fprintf_filtered (outfile, " line %d at ", l->item[i].line);
- fputs_filtered (paddress (gdbarch, l->item[i].pc), outfile);
+ fprintf_filtered (outfile, " line %d at ", l->item[i].line ());
+ fputs_filtered (paddress (gdbarch, l->item[i].address (symtab)),
+ outfile);
fprintf_filtered (outfile, "\n");
}
}
@@ -1017,8 +1018,8 @@ maintenance_print_one_line_table (struct symtab *symtab, void *data)
struct linetable_entry *item;

item = &linetable->item [i];
- printf_filtered (_("%-6d %6d %s\n"), i, item->line,
- core_addr_to_string (item->pc));
+ printf_filtered (_("%-6d %6d %s\n"), i, item->line (),
+ core_addr_to_string (item->address (symtab)));
}
}

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2b1f9558ab..4baf57c755 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -287,6 +287,15 @@ search_domain_name (enum search_domain e)
}
}

+CORE_ADDR
+linetable_entry::address (struct symtab *symtab) const
+{
+ return gdbarch_addr_bits_remove
+ (get_objfile_arch (SYMTAB_OBJFILE (symtab)),
+ m_pc + ANOFFSET (SYMTAB_OBJFILE (symtab)->section_offsets,
+ SYMTAB_COMPUNIT (symtab)->block_line_section));
+}
+
/* See symtab.h. */

struct symtab *
@@ -3070,6 +3079,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
we will use a line one less than this,
with a range from the start of that file to the first line's pc. */
struct linetable_entry *alt = NULL;
+ struct symtab *alt_symtab = NULL;

/* Info on best line seen in this file. */

@@ -3209,13 +3219,17 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)

/* Is this file's first line closer than the first lines of other files?
If so, record this file, and its first line, as best alternate. */
- if (item->pc > pc && (!alt || item->pc < alt->pc))
- alt = item;
+ if (item->address (iter_s) > pc
+ && (!alt || (item->address (iter_s) < alt->address (alt_symtab))))
+ {
+ alt = item;
+ alt_symtab = iter_s;
+ }

- auto pc_compare = [](const CORE_ADDR & pc,
- const struct linetable_entry & lhs)->bool
+ auto pc_compare = [=](const CORE_ADDR & pc,
+ const struct linetable_entry & lhs)->bool
{
- return pc < lhs.pc;
+ return pc < lhs.address (iter_s);
};

struct linetable_entry *first = item;
@@ -3234,22 +3248,25 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
save prev if it represents the end of a function (i.e. line number
0) instead of a real line. */

- if (prev && prev->line && (!best || prev->pc > best->pc))
+ if (prev
+ && prev->line ()
+ && (!best || (prev->address (iter_s) > best->address (best_symtab))))
{
best = prev;
best_symtab = iter_s;

/* Discard BEST_END if it's before the PC of the current BEST. */
- if (best_end <= best->pc)
+ if (best_end <= best->address (best_symtab))
best_end = 0;
}

/* If another line (denoted by ITEM) is in the linetable and its
PC is after BEST's PC, but before the current BEST_END, then
use ITEM's PC as the new best_end. */
- if (best && item < last && item->pc > best->pc
- && (best_end == 0 || best_end > item->pc))
- best_end = item->pc;
+ if (best && item < last
+ && (item->address (iter_s) > best->address (best_symtab))
+ && (best_end == 0 || best_end > item->address (iter_s)))
+ best_end = item->address (iter_s);
}

if (!best_symtab)
@@ -3260,7 +3277,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
don't make some up. */
val.pc = pc;
}
- else if (best->line == 0)
+ else if (best->line () == 0)
{
/* If our best fit is in a range of PC's for which no line
number info is available (line number is zero) then we didn't
@@ -3270,12 +3287,12 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
else
{
val.symtab = best_symtab;
- val.line = best->line;
- val.pc = best->pc;
- if (best_end && (!alt || best_end < alt->pc))
+ val.line = best->line ();
+ val.pc = best->address (best_symtab);
+ if (best_end && (!alt || best_end < alt->address (alt_symtab)))
val.end = best_end;
else if (alt)
- val.end = alt->pc;
+ val.end = alt->address (alt_symtab);
else
val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
}
@@ -3355,7 +3372,7 @@ find_line_symtab (struct symtab *symtab, int line,
struct symtab *s;

if (best_index >= 0)
- best = best_linetable->item[best_index].line;
+ best = best_linetable->item[best_index].line ();
else
best = 0;

@@ -3387,9 +3404,9 @@ find_line_symtab (struct symtab *symtab, int line,
best_symtab = s;
goto done;
}
- if (best == 0 || l->item[ind].line < best)
+ if (best == 0 || l->item[ind].line () < best)
{
- best = l->item[ind].line;
+ best = l->item[ind].line ();
best_index = ind;
best_linetable = l;
best_symtab = s;
@@ -3419,6 +3436,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
{
int start = 0;
std::vector<CORE_ADDR> result;
+ struct linetable *linetable = SYMTAB_LINETABLE (symtab);

/* First, collect all the PCs that are at this line. */
while (1)
@@ -3426,22 +3444,21 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
int was_exact;
int idx;

- idx = find_line_common (SYMTAB_LINETABLE (symtab), line, &was_exact,
- start);
+ idx = find_line_common (linetable, line, &was_exact, start);
if (idx < 0)
break;

if (!was_exact)
{
- struct linetable_entry *item = &SYMTAB_LINETABLE (symtab)->item[idx];
+ struct linetable_entry *item = &linetable->item[idx];

- if (*best_item == NULL || item->line < (*best_item)->line)
+ if (*best_item == NULL || item->line () < (*best_item)->line ())
*best_item = item;

break;
}

- result.push_back (SYMTAB_LINETABLE (symtab)->item[idx].pc);
+ result.push_back (linetable->item[idx].address (symtab));
start = idx + 1;
}

@@ -3467,7 +3484,7 @@ find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
if (symtab != NULL)
{
l = SYMTAB_LINETABLE (symtab);
- *pc = l->item[ind].pc;
+ *pc = l->item[ind].address (symtab);
return 1;
}
else
@@ -3546,16 +3563,16 @@ find_line_common (struct linetable *l, int lineno,
{
struct linetable_entry *item = &(l->item[i]);

- if (item->line == lineno)
+ if (item->line () == lineno)
{
/* Return the first (lowest address) entry which matches. */
*exact_match = 1;
return i;
}

- if (item->line > lineno && (best == 0 || item->line < best))
+ if (item->line () > lineno && (best == 0 || item->line () < best))
{
- best = item->line;
+ best = item->line ();
best_index = i;
}
}
@@ -3656,8 +3673,10 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
/* Don't use line numbers of zero, they mark special entries in
the table. See the commentary on symtab.h before the
definition of struct linetable. */
- if (item->line > 0 && func_start <= item->pc && item->pc < func_end)
- return item->pc;
+ if (item->line () > 0
+ && func_start <= item->address (symtab)
+ && item->address (symtab) < func_end)
+ return item->address (symtab);
}

return func_addr;
@@ -3878,13 +3897,15 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)

/* Skip any earlier lines, and any end-of-sequence marker
from a previous function. */
- while (linetable->item[idx].pc != prologue_sal.pc
- || linetable->item[idx].line == 0)
+ while ((linetable->item[idx].address (prologue_sal.symtab)
+ != prologue_sal.pc)
+ || linetable->item[idx].line () == 0)
idx++;

if (idx+1 < linetable->nitems
- && linetable->item[idx+1].line != 0
- && linetable->item[idx+1].pc == start_pc)
+ && linetable->item[idx+1].line () != 0
+ && (linetable->item[idx+1].address (prologue_sal.symtab)
+ == start_pc))
return start_pc;
}

diff --git a/gdb/symtab.h b/gdb/symtab.h
index f9d52e7697..ebb21abbd9 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -29,6 +29,7 @@
#include "common/function-view.h"
#include "common/gdb_optional.h"
#include "completer.h"
+#include "gdbarch.h"

/* Opaque declarations. */
struct ui_file;
@@ -1227,8 +1228,45 @@ struct rust_vtable_symbol : public symbol

struct linetable_entry
{
- int line;
- CORE_ADDR pc;
+ /* Set the members of this object. */
+ void set (int line_, CORE_ADDR pc)
+ {
+ m_line = line_;
+ m_pc = pc;
+ }
+
+ /* Set the members of this object from another linetable_entry. */
+ void set (const linetable_entry &other)
+ {
+ m_line = other.m_line;
+ m_pc = other.m_pc;
+ }
+
+ /* Return the raw address. */
+ CORE_ADDR raw_address () const
+ {
+ return m_pc;
+ }
+
+ /* Return the relocated address, using the offsets provided by
+ SYMTAB. */
+ CORE_ADDR address (struct symtab *symtab) const;
+
+ /* Return the line number. */
+ int line () const
+ {
+ return m_line;
+ }
+
+private:
+
+ int m_line;
+
+ /* Note that the PC as stored is unrelocated. The appropriate
+ offset must be applied before it can be used; see the "address"
+ method. */
+ CORE_ADDR m_pc;
+
};

/* The order of entries in the linetable is significant. They should
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index 8c707aa8fe..880d87436e 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -420,7 +420,11 @@ compare_lte (const void *lte1p, const void *lte2p)
struct linetable_entry *lte1 = (struct linetable_entry *) lte1p;
struct linetable_entry *lte2 = (struct linetable_entry *) lte2p;

- return lte1->pc - lte2->pc;
+ if (lte1->raw_address () < lte2->raw_address ())
+ return -1;
+ if (lte1->raw_address () > lte2->raw_address ())
+ return -1;
+ return 0;
}

/* Given a line table with function entries are marked, arrange its
@@ -448,7 +452,7 @@ arrange_linetable (struct linetable *oldLineTb)

for (function_count = 0, ii = 0; ii < oldLineTb->nitems; ++ii)
{
- if (oldLineTb->item[ii].line == 0)
+ if (oldLineTb->item[ii].line () == 0)
{ /* Function entry found. */
if (function_count >= fentry_size)
{ /* Make sure you have room. */
@@ -457,14 +461,15 @@ arrange_linetable (struct linetable *oldLineTb)
xrealloc (fentry,
fentry_size * sizeof (struct linetable_entry));
}
- fentry[function_count].line = ii;
- fentry[function_count].pc = oldLineTb->item[ii].pc;
+ fentry[function_count].set (ii,
+ oldLineTb->item[ii].raw_address ());
++function_count;

/* If the function was compiled with XLC, we may have to add an
extra line entry later. Reserve space for that. */
if (ii + 1 < oldLineTb->nitems
- && oldLineTb->item[ii].pc != oldLineTb->item[ii + 1].pc)
+ && (oldLineTb->item[ii].raw_address ()
+ != oldLineTb->item[ii + 1].raw_address ()))
extra_lines++;
}
}
@@ -488,10 +493,11 @@ arrange_linetable (struct linetable *oldLineTb)
a function begin. */

newline = 0;
- if (oldLineTb->item[0].line != 0)
+ if (oldLineTb->item[0].line () != 0)
for (newline = 0;
- newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline)
- newLineTb->item[newline] = oldLineTb->item[newline];
+ newline < oldLineTb->nitems && oldLineTb->item[newline].line ();
+ ++newline)
+ newLineTb->item[newline].set (oldLineTb->item[newline]);

/* Now copy function lines one by one. */

@@ -499,19 +505,20 @@ arrange_linetable (struct linetable *oldLineTb)
{
/* If the function was compiled with XLC, we may have to add an
extra line to cover the function prologue. */
- jj = fentry[ii].line;
+ jj = fentry[ii].line ();
if (jj + 1 < oldLineTb->nitems
- && oldLineTb->item[jj].pc != oldLineTb->item[jj + 1].pc)
+ && (oldLineTb->item[jj].raw_address ()
+ != oldLineTb->item[jj + 1].raw_address ()))
{
- newLineTb->item[newline] = oldLineTb->item[jj];
- newLineTb->item[newline].line = oldLineTb->item[jj + 1].line;
+ newLineTb->item[newline].set (oldLineTb->item[jj].raw_address (),
+ oldLineTb->item[jj + 1].line ());
newline++;
}

- for (jj = fentry[ii].line + 1;
- jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0;
+ for (jj = fentry[ii].line () + 1;
+ jj < oldLineTb->nitems && oldLineTb->item[jj].line () != 0;
++jj, ++newline)
- newLineTb->item[newline] = oldLineTb->item[jj];
+ newLineTb->item[newline].set (oldLineTb->item[jj]);
}
xfree (fentry);
/* The number of items in the line table must include these
@@ -871,6 +878,8 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset,

while (curoffset <= limit_offset)
{
+ CORE_ADDR relocated;
+
bfd_seek (abfd, curoffset, SEEK_SET);
bfd_bread (ext_lnno, linesz, abfd);
bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno);
@@ -879,20 +888,20 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset,
addr = (int_lnno.l_lnno
? int_lnno.l_addr.l_paddr
: read_symbol_nvalue (int_lnno.l_addr.l_symndx));
- addr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));

- if (addr < startaddr || (endaddr && addr >= endaddr))
+ relocated = (addr + ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile)));
+ if (relocated < startaddr || (endaddr && relocated >= endaddr))
return;

if (int_lnno.l_lnno == 0)
{
*firstLine = read_symbol_lineno (int_lnno.l_addr.l_symndx);
- record_line (subfile, 0, gdbarch_addr_bits_remove (gdbarch, addr));
+ record_line (subfile, 0, addr);
--(*firstLine);
}
else
- record_line (subfile, *firstLine + int_lnno.l_lnno,
- gdbarch_addr_bits_remove (gdbarch, addr));
+ record_line (subfile, *firstLine + int_lnno.l_lnno, addr);
curoffset += linesz;
}
}