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

Tom Tromey
2018-03-21T17:18:18Z

From: Tom Tromey <tromey@redhat.com>

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 "pc" field of the line table. This made
it simple to find all users of the field. It adds accessors and
setters for the new field.

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".
(SET_LINETABLE_ENTRY_ADDRESS, LINETABLE_ENTRY_RAW_ADDRESS)
(LINETABLE_ENTRY_ADDRESS): New macros.
* xcoffread.c (compare_lte): Update and rewrite.
(arrange_linetable): Update.
(enter_line_range): Don't add section offset when creating line
table.
---
gdb/ChangeLog | 34 +++++++++++++++++++++++++
gdb/buildsym.c | 9 ++++---
gdb/coffread.c | 7 ++----
gdb/dbxread.c | 26 +++++++++++--------
gdb/disasm.c | 30 +++++++++++++---------
gdb/dwarf2read.c | 9 ++++---
gdb/jit.c | 5 +++-
gdb/mdebugread.c | 10 +++-----
gdb/mi/mi-symbol-cmds.c | 11 ++++++---
gdb/objfiles.c | 17 -------------
gdb/python/py-linetable.c | 4 ++-
gdb/record-btrace.c | 4 ++-
gdb/symmisc.c | 8 ++++--
gdb/symtab.c | 63 ++++++++++++++++++++++++++++++-----------------
gdb/symtab.h | 16 +++++++++++-
gdb/xcoffread.c | 28 ++++++++++++++-------
16 files changed, 183 insertions(+), 98 deletions(-)

diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 5d38cb250f..99a92a8e31 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
+ && LINETABLE_ENTRY_RAW_ADDRESS (*e) == pc)
{
e--;
subfile->line_vector->nitems--;
@@ -956,7 +957,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;
+ SET_LINETABLE_ENTRY_ADDRESS (*e, pc);
}

/* Needed in order to sort line tables from IBM xcoff files. Sigh! */
@@ -969,10 +970,10 @@ 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 (LINETABLE_ENTRY_RAW_ADDRESS (*ln1) < LINETABLE_ENTRY_RAW_ADDRESS (*ln2))
return -1;

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

/* If pc equal, sort by line. I'm not sure whether this is optimum
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..ec5b8a9b81 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,13 +369,18 @@ 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 && LINETABLE_ENTRY_ADDRESS (symtab, le[i]) < 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 && LINETABLE_ENTRY_ADDRESS (symtab, le[i]) < 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
+ && (LINETABLE_ENTRY_RAW_ADDRESS (le[i])
+ == LINETABLE_ENTRY_RAW_ADDRESS (le[i + 1])))
continue; /* Ignore duplicates. */

/* Skip any end-of-function markers. */
@@ -384,19 +390,19 @@ do_mixed_source_and_assembly_deprecated
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 = LINETABLE_ENTRY_ADDRESS (symtab, le[i]);
+ mle[newlines].end_pc = LINETABLE_ENTRY_ADDRESS (symtab, le[i + 1]);
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 && LINETABLE_ENTRY_ADDRESS (symtab, le[i]) < high)
{
mle[newlines].line = le[i].line;
- mle[newlines].start_pc = le[i].pc;
- sal = find_pc_line (le[i].pc, 0);
+ mle[newlines].start_pc = LINETABLE_ENTRY_ADDRESS (symtab, le[i]);
+ sal = find_pc_line (LINETABLE_ENTRY_ADDRESS (symtab, le[i]), 0);
mle[newlines].end_pc = sal.end;
newlines++;
}
@@ -517,10 +523,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 && LINETABLE_ENTRY_ADDRESS (main_symtab, le[i]) < low;
+ i++)
+ ;

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

/* Add lines for every pc value. */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 6100438049..eb7a53c331 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -20860,8 +20860,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. */
@@ -21087,8 +21090,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,
@@ -21097,7 +21098,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..e5c64cc791 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -622,7 +622,10 @@ 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;
+ /* Use the absolute address here, as the offsets will all be
+ zero. */
+ SET_LINETABLE_ENTRY_ADDRESS (stab->linetable->item[i],
+ (CORE_ADDR) map[i].pc);
stab->linetable->item[i].line = map[i].line;
}
}
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index c0bce55148..c9b29bcc0f 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
@@ -4635,7 +4632,8 @@ add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last)
return lineno;

lt->item[lt->nitems].line = lineno;
- lt->item[lt->nitems++].pc = adr << 2;
+ SET_LINETABLE_ENTRY_ADDRESS (lt->item[lt->nitems], 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..8f3b28e8f8 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,13 @@ 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_ENTRY_ADDRESS (s, linetable->item[i]));
+ 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..5f91804d60 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
@@ -423,7 +424,8 @@ 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,
+ LINETABLE_ENTRY_ADDRESS (symtab, *item));
iter_obj->current_index++;

return obj;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 7264b8ed2b..0b447292f6 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,7 +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))
+ if (LINETABLE_ENTRY_ADDRESS (symtab, lines[i]) == pc
+ && (lines[i].line != 0))
range = btrace_line_range_add (range, lines[i].line);
}

diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 9adde044cd..89506ebfc0 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -303,7 +303,10 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile)
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);
+ fputs_filtered (paddress (gdbarch,
+ LINETABLE_ENTRY_ADDRESS (symtab,
+ l->item[i])),
+ outfile);
fprintf_filtered (outfile, "\n");
}
}
@@ -1018,7 +1021,8 @@ maintenance_print_one_line_table (struct symtab *symtab, void *data)

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

diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2b1f9558ab..f57ecafa42 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3070,6 +3070,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 +3210,18 @@ 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 (LINETABLE_ENTRY_ADDRESS (iter_s, *item) > pc
+ && (!alt || (LINETABLE_ENTRY_ADDRESS (iter_s, *item)
+ < LINETABLE_ENTRY_ADDRESS (alt_symtab, *alt))))
+ {
+ 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 < LINETABLE_ENTRY_ADDRESS (iter_s, lhs);
};

struct linetable_entry *first = item;
@@ -3234,22 +3240,28 @@ 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 || (LINETABLE_ENTRY_ADDRESS (iter_s, *prev)
+ > LINETABLE_ENTRY_ADDRESS (best_symtab, *best))))
{
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 <= LINETABLE_ENTRY_ADDRESS (best_symtab, *best))
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
+ && (LINETABLE_ENTRY_ADDRESS (iter_s, *item)
+ > LINETABLE_ENTRY_ADDRESS (best_symtab, *best))
+ && (best_end == 0
+ || best_end > LINETABLE_ENTRY_ADDRESS (iter_s, *item)))
+ best_end = LINETABLE_ENTRY_ADDRESS (iter_s, *item);
}

if (!best_symtab)
@@ -3271,11 +3283,12 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
{
val.symtab = best_symtab;
val.line = best->line;
- val.pc = best->pc;
- if (best_end && (!alt || best_end < alt->pc))
+ val.pc = LINETABLE_ENTRY_ADDRESS (best_symtab, *best);
+ if (best_end && (!alt || best_end < LINETABLE_ENTRY_ADDRESS (alt_symtab,
+ *alt)))
val.end = best_end;
else if (alt)
- val.end = alt->pc;
+ val.end = LINETABLE_ENTRY_ADDRESS (alt_symtab, *alt);
else
val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK));
}
@@ -3419,6 +3432,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,14 +3440,13 @@ 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)
*best_item = item;
@@ -3441,7 +3454,8 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
break;
}

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

@@ -3467,7 +3481,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 = LINETABLE_ENTRY_ADDRESS (symtab, l->item[ind]);
return 1;
}
else
@@ -3656,8 +3670,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 <= LINETABLE_ENTRY_ADDRESS (symtab, *item)
+ && LINETABLE_ENTRY_ADDRESS (symtab, *item) < func_end)
+ return LINETABLE_ENTRY_ADDRESS (symtab, *item);
}

return func_addr;
@@ -3878,13 +3894,16 @@ 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
+ while ((LINETABLE_ENTRY_ADDRESS (prologue_sal.symtab,
+ linetable->item[idx])
+ != 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_ENTRY_ADDRESS (prologue_sal.symtab,
+ linetable->item[idx+1]) == start_pc)
return start_pc;
}

diff --git a/gdb/symtab.h b/gdb/symtab.h
index f9d52e7697..2b3d8018a7 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1228,9 +1228,23 @@ struct rust_vtable_symbol : public symbol
struct linetable_entry
{
int line;
- CORE_ADDR pc;
+
+ /* Note that the PC as stored is unrelocated. The appropriate
+ offset must be applied before it can be used. */
+ CORE_ADDR m_pc;
};

+#define SET_LINETABLE_ENTRY_ADDRESS(ENTRY, PC) \
+ ((ENTRY).m_pc = (PC))
+#define LINETABLE_ENTRY_RAW_ADDRESS(ENTRY) \
+ ((ENTRY).m_pc + 0)
+#define LINETABLE_ENTRY_ADDRESS(SYMTAB, ENTRY) \
+ gdbarch_addr_bits_remove \
+ (get_objfile_arch (SYMTAB_OBJFILE (SYMTAB)), \
+ ((ENTRY).m_pc \
+ + ANOFFSET (SYMTAB_OBJFILE (SYMTAB)->section_offsets, \
+ SYMTAB_COMPUNIT (SYMTAB)->block_line_section)))
+
/* The order of entries in the linetable is significant. They should
be sorted by increasing values of the pc field. If there is more than
one entry for a given pc, then I'm not sure what should happen (and
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index 8c707aa8fe..8a07af402d 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 (LINETABLE_ENTRY_RAW_ADDRESS (*lte1) < LINETABLE_ENTRY_RAW_ADDRESS (*lte2))
+ return -1;
+ if (LINETABLE_ENTRY_RAW_ADDRESS (*lte1) > LINETABLE_ENTRY_RAW_ADDRESS (*lte2))
+ return 1;
+ return 0;
}

/* Given a line table with function entries are marked, arrange its
@@ -458,13 +462,16 @@ arrange_linetable (struct linetable *oldLineTb)
fentry_size * sizeof (struct linetable_entry));
}
fentry[function_count].line = ii;
- fentry[function_count].pc = oldLineTb->item[ii].pc;
+ SET_LINETABLE_ENTRY_ADDRESS
+ (fentry[function_count],
+ LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[ii]));
++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)
+ && (LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[ii])
+ != LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[ii + 1])))
extra_lines++;
}
}
@@ -501,7 +508,8 @@ arrange_linetable (struct linetable *oldLineTb)
extra line to cover the function prologue. */
jj = fentry[ii].line;
if (jj + 1 < oldLineTb->nitems
- && oldLineTb->item[jj].pc != oldLineTb->item[jj + 1].pc)
+ && (LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[jj])
+ != LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[jj + 1])))
{
newLineTb->item[newline] = oldLineTb->item[jj];
newLineTb->item[newline].line = oldLineTb->item[jj + 1].line;
@@ -871,6 +879,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 +889,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;
}
}
--
2.13.6