diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 6594da68131..33c51beed57 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -655,7 +655,7 @@ buildsym_compunit::record_line (struct subfile *subfile, int line,
 	  linetable_entry *last = &subfile->line_vector_entries.back ();
 	  last_line = last->line;
 
-	  if (last->pc != pc)
+	  if (last->raw_pc () != pc)
 	    break;
 
 	  subfile->line_vector_entries.pop_back ();
@@ -670,7 +670,7 @@ buildsym_compunit::record_line (struct subfile *subfile, int line,
   linetable_entry &e = subfile->line_vector_entries.back ();
   e.line = line;
   e.is_stmt = (flags & LEF_IS_STMT) != 0;
-  e.pc = pc;
+  e.set_pc (pc);
   e.prologue_end = (flags & LEF_PROLOGUE_END) != 0;
 }
 
diff --git a/gdb/coffread.c b/gdb/coffread.c
index 45542bc2432..81df2579619 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -1463,7 +1463,6 @@ enter_linenos (file_ptr file_offset, int first_line,
       if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
 	{
 	  CORE_ADDR addr = lptr.l_addr.l_paddr;
-	  addr += objfile->text_section_offset ();
 	  record_line (get_current_subfile (),
 		       first_line + L_LNNO32 (&lptr),
 		       gdbarch_addr_bits_remove (gdbarch, addr));
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 02c7e3118ad..1e88121f11c 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -2454,7 +2454,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 	      CORE_ADDR addr = last_function_start + valu;
 
 	      record_line (get_current_subfile (), 0,
-			   gdbarch_addr_bits_remove (gdbarch, addr));
+			   gdbarch_addr_bits_remove (gdbarch, addr)
+			   - objfile->text_section_offset ());
 	    }
 
 	  within_function = 0;
@@ -2662,12 +2663,14 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 			   last_function_start : valu;
 
 	  record_line (get_current_subfile (), desc,
-		       gdbarch_addr_bits_remove (gdbarch, addr));
+		       gdbarch_addr_bits_remove (gdbarch, addr)
+		       - objfile->text_section_offset ());
 	  sline_found_in_function = 1;
 	}
       else
 	record_line (get_current_subfile (), desc,
-		     gdbarch_addr_bits_remove (gdbarch, valu));
+		     gdbarch_addr_bits_remove (gdbarch, valu)
+		     - objfile->text_section_offset ());
       break;
 
     case N_BCOMM:
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 49053dcfbad..2acde04ffe9 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -32,6 +32,7 @@
 #include "gdbsupport/gdb_optional.h"
 #include "valprint.h"
 #include "cli/cli-style.h"
+#include "objfiles.h"
 
 /* Disassemble functions.
    FIXME: We should get rid of all the duplicate code in gdb that does
@@ -592,17 +593,21 @@ do_mixed_source_and_assembly_deprecated
   mle = (struct deprecated_dis_line_entry *)
     alloca (nlines * sizeof (struct deprecated_dis_line_entry));
 
+  struct objfile *objfile = symtab->compunit ()->objfile ();
+  low -= objfile->text_section_offset ();
+  high -= objfile->text_section_offset ();
+
   /* Copy linetable entries for this function into our data
      structure, creating end_pc's and setting out_of_order as
      appropriate.  */
 
   /* 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].raw_pc () < 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].raw_pc () < high; i++)
     {
       if (le[i] == le[i + 1])
 	continue;		/* Ignore duplicates.  */
@@ -614,19 +619,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 = le[i].pc (objfile);
+      mle[newlines].end_pc = le[i + 1].pc (objfile);
       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].raw_pc () < 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 = le[i].pc (objfile);
+      sal = find_pc_line (le[i].pc (objfile), 0);
       mle[newlines].end_pc = sal.end;
       newlines++;
     }
@@ -733,6 +738,10 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch,
 
   htab_up dis_line_table (allocate_dis_line_table ());
 
+  struct objfile *objfile = main_symtab->compunit ()->objfile ();
+  low -= objfile->text_section_offset ();
+  high -= objfile->text_section_offset ();
+
   pc = low;
 
   /* The prologue may be empty, but there may still be a line number entry
@@ -746,10 +755,10 @@ 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++)
+  for (i = 0; i < nlines && le[i].raw_pc () < low; i++)
     continue;
 
-  if (i < nlines && le[i].pc < high)
+  if (i < nlines && le[i].raw_pc () < high)
     first_le = &le[i];
 
   /* Add lines for every pc value.  */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index a9758c305b3..e1e2b4a805d 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -17980,10 +17980,9 @@ class lnp_state_machine
   }
 
   /* Handle DW_LNE_set_address.  */
-  void handle_set_address (CORE_ADDR baseaddr, CORE_ADDR address)
+  void handle_set_address (CORE_ADDR address)
   {
     m_op_index = 0;
-    address += baseaddr;
     m_address = gdbarch_adjust_dwarf2_line (m_gdbarch, address, false);
   }
 
@@ -18458,7 +18457,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 
 		    state_machine.check_line_address (cu, line_ptr,
 						      lowpc - baseaddr, address);
-		    state_machine.handle_set_address (baseaddr, address);
+		    state_machine.handle_set_address (address);
 		  }
 		  break;
 		case DW_LNE_define_file:
diff --git a/gdb/jit.c b/gdb/jit.c
index 7f4b9f0fd37..f9f2c92553c 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -491,7 +491,7 @@ 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].set_pc ((CORE_ADDR) map[i].pc);
       stab->linetable->item[i].line = map[i].line;
       stab->linetable->item[i].is_stmt = 1;
     }
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index 793795c903a..85dceb54fe7 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -2152,7 +2152,7 @@ parse_external (EXTR *es, int bigend, const section_offsets &section_offsets,
 
 static void
 parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
-	     CORE_ADDR textlow, CORE_ADDR lowest_pdr_addr)
+	     CORE_ADDR lowest_pdr_addr)
 {
   unsigned char *base;
   int j, k;
@@ -2183,7 +2183,7 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
 	halt = base + fh->cbLine;
       base += pr->cbLineOffset;
 
-      adr = textlow + pr->adr - lowest_pdr_addr;
+      adr = pr->adr - lowest_pdr_addr;
 
       l = adr >> 2;		/* in words */
       for (lineno = pr->lnLow; base < halt;)
@@ -4011,7 +4011,6 @@ mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
 	      else
 		{
 		  /* Handle encoded stab line number.  */
-		  valu += section_offsets[SECT_OFF_TEXT (objfile)];
 		  record_line (get_current_subfile (), sh.index,
 			       gdbarch_addr_bits_remove (gdbarch, valu));
 		}
@@ -4163,7 +4162,7 @@ mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
 		}
 
 	      parse_lines (fh, pr_block.data (), lines, maxlines,
-			   pst->text_low (objfile), lowest_pdr_addr);
+			   lowest_pdr_addr);
 	      if (lines->nitems < fh->cline)
 		lines = shrink_linetable (lines);
 
@@ -4540,7 +4539,7 @@ 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;
+  lt->item[lt->nitems++].set_pc (adr << 2);
   return lineno;
 }
 
diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c
index 16947dad51b..08e6e15e14d 100644
--- a/gdb/mi/mi-symbol-cmds.c
+++ b/gdb/mi/mi-symbol-cmds.c
@@ -50,14 +50,16 @@ mi_cmd_symbol_list_lines (const char *command, char **argv, int argc)
      already sorted by increasing values in the symbol table, so no
      need to perform any other sorting.  */
 
-  gdbarch = s->compunit ()->objfile ()->arch ();
+  struct objfile *objfile = s->compunit ()->objfile ();
+  gdbarch = objfile->arch ();
 
   ui_out_emit_list list_emitter (uiout, "lines");
   if (s->linetable () != NULL && s->linetable ()->nitems > 0)
     for (i = 0; i < s->linetable ()->nitems; i++)
       {
 	ui_out_emit_tuple tuple_emitter (uiout, NULL);
-	uiout->field_core_addr ("pc", gdbarch, s->linetable ()->item[i].pc);
+	uiout->field_core_addr ("pc", gdbarch,
+				s->linetable ()->item[i].pc (objfile));
 	uiout->field_signed ("line", s->linetable ()->item[i].line);
       }
 }
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 8e7be8e2e25..2c8f5d14444 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -616,22 +616,6 @@ objfile_relocate1 (struct objfile *objfile,
 
   /* OK, get all the symtabs.  */
   {
-    for (compunit_symtab *cust : objfile->compunits ())
-      {
-	for (symtab *s : cust->filetabs ())
-	  {
-	    struct linetable *l;
-
-	    /* First the line table.  */
-	    l = s->linetable ();
-	    if (l)
-	      {
-		for (int i = 0; i < l->nitems; ++i)
-		  l->item[i].pc += delta[SECT_OFF_TEXT (objfile)];
-	      }
-	  }
-      }
-
     for (compunit_symtab *cust : objfile->compunits ())
       {
 	struct blockvector *bv = cust->blockvector ();
diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c
index 7e5a6536fde..e42bcc2c792 100644
--- a/gdb/python/py-linetable.c
+++ b/gdb/python/py-linetable.c
@@ -422,7 +422,8 @@ ltpy_iternext (PyObject *self)
       item = &(symtab->linetable ()->item[iter_obj->current_index]);
     }
 
-  obj = build_linetable_entry (item->line, item->pc);
+  struct objfile *objfile = symtab->compunit ()->objfile ();
+  obj = build_linetable_entry (item->line, item->pc (objfile));
   iter_obj->current_index++;
 
   return obj;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 61de8491bb9..55fe25e84ae 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -44,6 +44,7 @@
 #include "cli/cli-style.h"
 #include "async-event.h"
 #include <forward_list>
+#include "objfiles.h"
 
 static const target_info record_btrace_target_info = {
   "record-btrace",
@@ -722,6 +723,9 @@ btrace_find_line_range (CORE_ADDR pc)
   if (nlines <= 0)
     return btrace_mk_line_range (symtab, 0, 0);
 
+  struct objfile *objfile = symtab->compunit ()->objfile ();
+  pc -= objfile->text_section_offset ();
+
   range = btrace_mk_line_range (symtab, 0, 0);
   for (i = 0; i < nlines - 1; i++)
     {
@@ -733,7 +737,7 @@ btrace_find_line_range (CORE_ADDR pc)
 	 possibly adding more line numbers to the range.  At the time this
 	 change was made I was unsure how to test this so chose to go with
 	 maintaining the existing experience.  */
-      if ((lines[i].pc == pc) && (lines[i].line != 0)
+      if ((lines[i].raw_pc () == pc) && (lines[i].line != 0)
 	  && (lines[i].is_stmt == 1))
 	range = btrace_line_range_add (range, lines[i].line);
     }
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 6ff06ccaa93..d1458784e5c 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -263,7 +263,7 @@ dump_symtab_1 (struct symtab *symtab, struct ui_file *outfile)
       for (int i = 0; i < len; i++)
 	{
 	  gdb_printf (outfile, " line %d at ", l->item[i].line);
-	  gdb_puts (paddress (gdbarch, l->item[i].pc), outfile);
+	  gdb_puts (paddress (gdbarch, l->item[i].raw_pc ()), outfile);
 	  if (l->item[i].is_stmt)
 	    gdb_printf (outfile, "\t(stmt)");
 	  gdb_printf (outfile, "\n");
@@ -996,7 +996,7 @@ maintenance_print_one_line_table (struct symtab *symtab, void *data)
 	  else
 	    uiout->field_string ("line", _("END"));
 	  uiout->field_core_addr ("address", objfile->arch (),
-				  item->pc);
+				  item->raw_pc ());
 	  uiout->field_string ("is-stmt", item->is_stmt ? "Y" : "");
 	  uiout->field_string ("prologue-end", item->prologue_end ? "Y" : "");
 	  uiout->text ("\n");
diff --git a/gdb/symtab.c b/gdb/symtab.c
index f26dd2cb187..df7d3b2a398 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -329,6 +329,14 @@ search_domain_name (enum search_domain e)
 
 /* See symtab.h.  */
 
+CORE_ADDR
+linetable_entry::pc (const struct objfile *objfile) const
+{
+  return m_pc + objfile->text_section_offset ();
+}
+
+/* See symtab.h.  */
+
 call_site *
 compunit_symtab::find_call_site (CORE_ADDR pc) const
 {
@@ -3126,6 +3134,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
     }
 
   bv = cust->blockvector ();
+  struct objfile *objfile = cust->objfile ();
 
   /* Look at all the symtabs that share this blockvector.
      They all have the same apriori range, that we found was right;
@@ -3152,18 +3161,21 @@ 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))
+      if (item->pc (objfile) > pc
+	  && (!alt || item->raw_pc () < alt->raw_pc ()))
 	alt = item;
 
       auto pc_compare = [](const CORE_ADDR & comp_pc,
 			   const struct linetable_entry & lhs)->bool
       {
-	return comp_pc < lhs.pc;
+	return comp_pc < lhs.raw_pc ();
       };
 
       struct linetable_entry *first = item;
       struct linetable_entry *last = item + len;
-      item = std::upper_bound (first, last, pc, pc_compare);
+      item = std::upper_bound (first, last,
+			       pc - objfile->text_section_offset (),
+			       pc_compare);
       if (item != first)
 	prev = item - 1;		/* Found a matching item.  */
 
@@ -3177,7 +3189,7 @@ 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->raw_pc () > best->raw_pc ()))
 	{
 	  best = prev;
 	  best_symtab = iter_s;
@@ -3192,7 +3204,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 	  if (!best->is_stmt)
 	    {
 	      struct linetable_entry *tmp = best;
-	      while (tmp > first && (tmp - 1)->pc == tmp->pc
+	      while (tmp > first && (tmp - 1)->raw_pc () == tmp->raw_pc ()
 		     && (tmp - 1)->line != 0 && !tmp->is_stmt)
 		--tmp;
 	      if (tmp->is_stmt)
@@ -3200,16 +3212,16 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 	    }
 
 	  /* Discard BEST_END if it's before the PC of the current BEST.  */
-	  if (best_end <= best->pc)
+	  if (best_end <= best->pc (objfile))
 	    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->raw_pc () > best->raw_pc ()
+	  && (best_end == 0 || best_end > item->pc (objfile)))
+	best_end = item->pc (objfile);
     }
 
   if (!best_symtab)
@@ -3232,11 +3244,11 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       val.is_stmt = best->is_stmt;
       val.symtab = best_symtab;
       val.line = best->line;
-      val.pc = best->pc;
-      if (best_end && (!alt || best_end < alt->pc))
+      val.pc = best->pc (objfile);
+      if (best_end && (!alt || best_end < alt->pc (objfile)))
 	val.end = best_end;
       else if (alt)
-	val.end = alt->pc;
+	val.end = alt->pc (objfile);
       else
 	val.end = bv->global_block ()->end ();
     }
@@ -3387,6 +3399,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
 {
   int start = 0;
   std::vector<CORE_ADDR> result;
+  struct objfile *objfile = symtab->compunit ()->objfile ();
 
   /* First, collect all the PCs that are at this line.  */
   while (1)
@@ -3410,7 +3423,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
 	  break;
 	}
 
-      result.push_back (symtab->linetable ()->item[idx].pc);
+      result.push_back (symtab->linetable ()->item[idx].pc (objfile));
       start = idx + 1;
     }
 
@@ -3436,7 +3449,7 @@ find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
   if (symtab != NULL)
     {
       l = symtab->linetable ();
-      *pc = l->item[ind].pc;
+      *pc = l->item[ind].pc (symtab->compunit ()->objfile ());
       return true;
     }
   else
@@ -3640,6 +3653,8 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
   if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end))
     return func_addr;
 
+  struct objfile *objfile = symtab->compunit ()->objfile ();
+
   /* Linetable entries are ordered by PC values, see the commentary in
      symtab.h where `struct linetable' is defined.  Thus, the first
      entry whose PC is in the range [FUNC_START..FUNC_END[ is the
@@ -3647,12 +3662,13 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
   for (i = 0; i < l->nitems; i++)
     {
       struct linetable_entry *item = &(l->item[i]);
+      CORE_ADDR item_pc = item->pc (objfile);
 
       /* 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_pc && item_pc < func_end)
+	return item_pc;
     }
 
   return func_addr;
@@ -3679,18 +3695,22 @@ skip_prologue_using_linetable (CORE_ADDR func_addr)
     {
       struct linetable *linetable = prologue_sal.symtab->linetable ();
 
+      struct objfile *objfile = prologue_sal.symtab->compunit ()->objfile ();
+      start_pc -= objfile->text_section_offset ();
+      end_pc -= objfile->text_section_offset ();
+
       auto it = std::lower_bound
 	(linetable->item, linetable->item + linetable->nitems, start_pc,
 	 [] (const linetable_entry &lte, CORE_ADDR pc) -> bool
 	 {
-	   return lte.pc < pc;
+	   return lte.raw_pc () < pc;
 	 });
 
       for (;
-	   it < linetable->item + linetable->nitems && it->pc <= end_pc;
+	   it < linetable->item + linetable->nitems && it->raw_pc () <= end_pc;
 	   it++)
 	if (it->prologue_end)
-	  return {it->pc};
+	  return {it->pc (objfile)};
     }
 
   return {};
@@ -3924,18 +3944,20 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
 	 do this.  */
       if (prologue_sal.symtab->language () != language_asm)
 	{
+	  struct objfile *objfile
+	    = prologue_sal.symtab->compunit ()->objfile ();
 	  struct linetable *linetable = prologue_sal.symtab->linetable ();
 	  int idx = 0;
 
 	  /* Skip any earlier lines, and any end-of-sequence marker
 	     from a previous function.  */
-	  while (linetable->item[idx].pc != prologue_sal.pc
+	  while (linetable->item[idx].pc (objfile) != 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].pc (objfile) == start_pc)
 	    return start_pc;
 	}
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 69f0eaa0f88..84d12617f31 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1547,18 +1547,29 @@ struct rust_vtable_symbol : public symbol
 
 struct linetable_entry
 {
+  /* Set the (unrelocated) PC for this entry.  */
+  void set_pc (CORE_ADDR pc)
+  { m_pc = pc; }
+
+  /* Return the unrelocated PC for this entry.  */
+  CORE_ADDR raw_pc () const
+  { return m_pc; }
+
+  /* Return the relocated PC for this entry.  */
+  CORE_ADDR pc (const struct objfile *objfile) const;
+
   bool operator< (const linetable_entry &other) const
   {
-    if (pc == other.pc
+    if (m_pc == other.m_pc
 	&& (line != 0) != (other.line != 0))
       return line == 0;
-    return pc < other.pc;
+    return m_pc < other.m_pc;
   }
 
   /* Two entries are equal if they have the same line and PC.  The
      other members are ignored.  */
   bool operator== (const linetable_entry &other) const
-  { return line == other.line && pc == other.pc; }
+  { return line == other.line && m_pc == other.m_pc; }
 
   /* The line number for this entry.  */
   int line;
@@ -1571,7 +1582,7 @@ struct linetable_entry
   bool prologue_end : 1;
 
   /* The address for this entry.  */
-  CORE_ADDR pc;
+  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 93054bdeb19..45578311705 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -432,7 +432,7 @@ arrange_linetable (std::vector<linetable_entry> &old_linetable)
 	  linetable_entry &e = fentries.back ();
 	  e.line = ii;
 	  e.is_stmt = 1;
-	  e.pc = old_linetable[ii].pc;
+	  e.set_pc (old_linetable[ii].raw_pc ());
 	}
     }
 
@@ -457,7 +457,7 @@ arrange_linetable (std::vector<linetable_entry> &old_linetable)
 	 extra line to cover the function prologue.  */
       int jj = entry.line;
       if (jj + 1 < old_linetable.size ()
-	  && old_linetable[jj].pc != old_linetable[jj + 1].pc)
+	  && old_linetable[jj].raw_pc () != old_linetable[jj + 1].raw_pc ())
 	{
 	  new_linetable.push_back (old_linetable[jj]);
 	  new_linetable.back ().line = old_linetable[jj + 1].line;
@@ -790,15 +790,16 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset,
       if (addr < startaddr || (endaddr && addr >= endaddr))
 	return;
 
+      CORE_ADDR record_addr = (gdbarch_addr_bits_remove (gdbarch, addr)
+			       - objfile->text_section_offset ());
       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, record_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, record_addr);
       curoffset += linesz;
     }
 }
