public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC 00/10] More use of unrelocated_addr
@ 2023-04-24 16:22 Tom Tromey
  2023-04-24 16:22 ` [RFC 01/10] Remove baseaddr parameter from dwarf2_record_block_ranges Tom Tromey
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches

While working on a different patch, I decided to add more use of
unrelocated_addr to the DWARF reader.  This caught at least one latent
bug, see patch #10.  (I thought there was another one as well, but I
can't find it now.)

The main ugliness here is that it adds a lot of casts.  Partly (but
not entirely) this is due to the decision to not use
DEFINE_OFFSET_TYPE for unrelocated_addr.  Maybe it would be better to
write a custom wrapper class for unrelocated_addr instead.

I moved unrelocated_addr to gdbsupport, but maybe it would be better
in defs.h.  I'm not sure.

Regression tested on x86-64 Fedora 36.

Let me know what you think.

Tom



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 01/10] Remove baseaddr parameter from dwarf2_record_block_ranges
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 02/10] Minor cleanup in loclist_describe_location Tom Tromey
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

dwarf2_record_block_ranges is only ever called with the text section
offset, so this patch removes the parameter entirely.  This makes a
subsequent patch a little simpler.
---
 gdb/dwarf2/read.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 29a95cb8b2f..904dcc09405 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -904,7 +904,7 @@ static void get_scope_pc_bounds (struct die_info *,
 				 struct dwarf2_cu *);
 
 static void dwarf2_record_block_ranges (struct die_info *, struct block *,
-					CORE_ADDR, struct dwarf2_cu *);
+					struct dwarf2_cu *);
 
 static void dwarf2_add_field (struct field_info *, struct die_info *,
 			      struct dwarf2_cu *);
@@ -6423,7 +6423,7 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
      (such as virtual method tables).  Record the ranges in STATIC_BLOCK's
      addrmap to help ensure it has an accurate map of pc values belonging to
      this comp unit.  */
-  dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
+  dwarf2_record_block_ranges (cu->dies, static_block, cu);
 
   cust = cu->get_builder ()->end_compunit_symtab_from_static_block
     (static_block, 0);
@@ -10188,7 +10188,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 		      &objfile->objfile_obstack);
 
   /* If we have address ranges, record them.  */
-  dwarf2_record_block_ranges (die, block, baseaddr, cu);
+  dwarf2_record_block_ranges (die, block, cu);
 
   gdbarch_make_symbol_special (gdbarch, cstk.name, objfile);
 
@@ -10301,7 +10301,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 	 there.  But since we don't even decide whether to create a
 	 block until after we've traversed its children, that's hard
 	 to do.  */
-      dwarf2_record_block_ranges (die, block, baseaddr, cu);
+      dwarf2_record_block_ranges (die, block, cu);
     }
   *cu->get_builder ()->get_local_symbols () = cstk.locals;
   cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
@@ -11278,9 +11278,10 @@ get_scope_pc_bounds (struct die_info *die,
 
 static void
 dwarf2_record_block_ranges (struct die_info *die, struct block *block,
-			    CORE_ADDR baseaddr, struct dwarf2_cu *cu)
+			    struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->per_objfile->objfile;
+  CORE_ADDR baseaddr = objfile->text_section_offset ();
   struct gdbarch *gdbarch = objfile->arch ();
   struct attribute *attr;
   struct attribute *attr_high;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 02/10] Minor cleanup in loclist_describe_location
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
  2023-04-24 16:22 ` [RFC 01/10] Remove baseaddr parameter from dwarf2_record_block_ranges Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 03/10] Move unrelocated_addr to common-types.h Tom Tromey
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

loclist_describe_location already has a per_objfile local variable, so
use it consistently.
---
 gdb/dwarf2/loc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index d9615870aeb..c1955f28a44 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -3968,7 +3968,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 
       if (dlbaton->per_cu->version () < 5 && dlbaton->from_dwo)
 	kind = decode_debug_loc_dwo_addresses (dlbaton->per_cu,
-					       dlbaton->per_objfile,
+					       per_objfile,
 					       loc_ptr, buf_end, &new_ptr,
 					       &low, &high, byte_order);
       else if (dlbaton->per_cu->version () < 5)
@@ -3978,7 +3978,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 					   signed_addr_p);
       else
 	kind = decode_debug_loclists_addresses (dlbaton->per_cu,
-						dlbaton->per_objfile,
+						per_objfile,
 						loc_ptr, buf_end, &new_ptr,
 						&low, &high, byte_order,
 						addr_size, signed_addr_p);
@@ -4041,7 +4041,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
       /* Now describe this particular location.  */
       locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
 				   addr_size, offset_size,
-				   dlbaton->per_cu, dlbaton->per_objfile);
+				   dlbaton->per_cu, per_objfile);
 
       gdb_printf (stream, "\n");
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 03/10] Move unrelocated_addr to common-types.h
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
  2023-04-24 16:22 ` [RFC 01/10] Remove baseaddr parameter from dwarf2_record_block_ranges Tom Tromey
  2023-04-24 16:22 ` [RFC 02/10] Minor cleanup in loclist_describe_location Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 04/10] Use unrelocated_addr in the DWARF reader Tom Tromey
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

unrelocated_addr is currently defined in symtab.h, but in order to
avoid having to include that in more places, I wanted to move the type
elsewhere.  I considered defs.h, but it seemed reasonable to have it
next to CORE_ADDR, which is what this patch does.
---
 gdb/symtab.h              | 6 ------
 gdbsupport/common-types.h | 6 ++++++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gdb/symtab.h b/gdb/symtab.h
index 404d0ab30a8..495e7522e25 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -58,12 +58,6 @@ class probe;
 struct lookup_name_info;
 struct code_breakpoint;
 
-/* Like a CORE_ADDR, but not directly convertible.  This is used to
-   represent an unrelocated CORE_ADDR.  DEFINE_OFFSET_TYPE is not used
-   here because there's no need to add or subtract values of this
-   type.  */
-enum class unrelocated_addr : CORE_ADDR { };
-
 /* How to match a lookup name against a symbol search name.  */
 enum class symbol_name_match_type
 {
diff --git a/gdbsupport/common-types.h b/gdbsupport/common-types.h
index 4156021abb4..3717162b36b 100644
--- a/gdbsupport/common-types.h
+++ b/gdbsupport/common-types.h
@@ -28,6 +28,12 @@ typedef unsigned char gdb_byte;
 /* * An address in the program being debugged.  Host byte order.  */
 typedef uint64_t CORE_ADDR;
 
+/* Like a CORE_ADDR, but not directly convertible.  This is used to
+   represent an unrelocated CORE_ADDR.  DEFINE_OFFSET_TYPE is not used
+   here because there's no need to add or subtract values of this
+   type.  */
+enum class unrelocated_addr : CORE_ADDR { };
+
 /* LONGEST must be at least as big as CORE_ADDR.  */
 
 typedef int64_t LONGEST;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 04/10] Use unrelocated_addr in the DWARF reader
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (2 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 03/10] Move unrelocated_addr to common-types.h Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 05/10] Use unrelocated_addr in dwarf_decode_lines Tom Tromey
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes various spots in the DWARF reader to use
unrelocated_addr.
---
 gdb/dwarf2/attribute.c      |   6 +-
 gdb/dwarf2/attribute.h      |   6 +-
 gdb/dwarf2/call-site.h      |  14 +-
 gdb/dwarf2/comp-unit-head.c |   6 +-
 gdb/dwarf2/comp-unit-head.h |   4 +-
 gdb/dwarf2/cu.h             |   2 +-
 gdb/dwarf2/die.c            |   2 +-
 gdb/dwarf2/expr.c           |  12 +-
 gdb/dwarf2/loc.c            | 117 +++++-----
 gdb/dwarf2/loc.h            |   2 +-
 gdb/dwarf2/read-gdb-index.c |   9 +-
 gdb/dwarf2/read.c           | 446 ++++++++++++++++++------------------
 gdb/dwarf2/read.h           |  15 +-
 gdb/gdbtypes.c              |   3 +-
 gdb/symtab.c                |   5 +-
 15 files changed, 339 insertions(+), 310 deletions(-)

diff --git a/gdb/dwarf2/attribute.c b/gdb/dwarf2/attribute.c
index 3b14757f9db..aab87014c8c 100644
--- a/gdb/dwarf2/attribute.c
+++ b/gdb/dwarf2/attribute.c
@@ -31,10 +31,10 @@
 
 /* See attribute.h.  */
 
-CORE_ADDR
+unrelocated_addr
 attribute::as_address () const
 {
-  CORE_ADDR addr;
+  unrelocated_addr addr;
 
   gdb_assert (!requires_reprocessing);
 
@@ -53,7 +53,7 @@ attribute::as_address () const
 	 as well as update callers to pass in at least the CU's DWARF
 	 version.  This is more overhead than what we're willing to
 	 expand for a pretty rare case.  */
-      addr = u.unsnd;
+      addr = (unrelocated_addr) u.unsnd;
     }
   else
     addr = u.addr;
diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index e13822af911..4cfdaa1e355 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -45,7 +45,7 @@ struct attribute
 {
   /* Read the given attribute value as an address, taking the
      attribute's form into account.  */
-  CORE_ADDR as_address () const;
+  unrelocated_addr as_address () const;
 
   /* If the attribute has a string form, return the string value;
      otherwise return NULL.  */
@@ -261,7 +261,7 @@ struct attribute
   }
 
   /* Set this attribute to an address.  */
-  void set_address (CORE_ADDR addr)
+  void set_address (unrelocated_addr addr)
   {
     gdb_assert (form == DW_FORM_addr
 		|| ((form == DW_FORM_addrx
@@ -319,7 +319,7 @@ struct attribute
       struct dwarf_block *blk;
       ULONGEST unsnd;
       LONGEST snd;
-      CORE_ADDR addr;
+      unrelocated_addr addr;
       ULONGEST signature;
     }
   u;
diff --git a/gdb/dwarf2/call-site.h b/gdb/dwarf2/call-site.h
index a397b8b6337..07257fae357 100644
--- a/gdb/dwarf2/call-site.h
+++ b/gdb/dwarf2/call-site.h
@@ -59,7 +59,7 @@ struct call_site_target
     ADDRESSES,
   };
 
-  void set_loc_physaddr (CORE_ADDR physaddr)
+  void set_loc_physaddr (unrelocated_addr physaddr)
   {
     m_loc_kind = PHYSADDR;
     m_loc.physaddr = physaddr;
@@ -77,7 +77,7 @@ struct call_site_target
       m_loc.dwarf_block = dwarf_block;
     }
 
-  void set_loc_array (unsigned length, const CORE_ADDR *data)
+  void set_loc_array (unsigned length, const unrelocated_addr *data)
   {
     m_loc_kind = ADDRESSES;
     m_loc.addresses.length = length;
@@ -102,7 +102,7 @@ struct call_site_target
   union
   {
     /* Address.  */
-    CORE_ADDR physaddr;
+    unrelocated_addr physaddr;
     /* Mangled name.  */
     const char *physname;
     /* DWARF block.  */
@@ -111,7 +111,7 @@ struct call_site_target
     struct
     {
       unsigned length;
-      const CORE_ADDR *values;
+      const unrelocated_addr *values;
     } addresses;
   } m_loc;
 
@@ -163,7 +163,7 @@ struct call_site_parameter
 
 struct call_site
 {
-  call_site (CORE_ADDR pc, dwarf2_per_cu_data *per_cu,
+  call_site (unrelocated_addr pc, dwarf2_per_cu_data *per_cu,
 	     dwarf2_per_objfile *per_objfile)
     : per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc)
   {}
@@ -177,7 +177,7 @@ struct call_site
   static hashval_t
   hash (const call_site *a)
   {
-    return a->m_unrelocated_pc;
+    return (hashval_t) a->m_unrelocated_pc;
   }
 
   static int
@@ -233,7 +233,7 @@ struct call_site
 
 private:
   /* Unrelocated address of the first instruction after this call.  */
-  const CORE_ADDR m_unrelocated_pc;
+  const unrelocated_addr m_unrelocated_pc;
 
 public:
   /* * Describe DW_TAG_call_site's DW_TAG_formal_parameter.  */
diff --git a/gdb/dwarf2/comp-unit-head.c b/gdb/dwarf2/comp-unit-head.c
index 2deceb50932..32dd60ad8bf 100644
--- a/gdb/dwarf2/comp-unit-head.c
+++ b/gdb/dwarf2/comp-unit-head.c
@@ -193,11 +193,11 @@ read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile,
   return info_ptr;
 }
 
-CORE_ADDR
+unrelocated_addr
 comp_unit_head::read_address (bfd *abfd, const gdb_byte *buf,
 			      unsigned int *bytes_read) const
 {
-  CORE_ADDR retval = 0;
+  ULONGEST retval = 0;
 
   if (signed_addr_p)
     {
@@ -238,5 +238,5 @@ comp_unit_head::read_address (bfd *abfd, const gdb_byte *buf,
     }
 
   *bytes_read = addr_size;
-  return retval;
+  return (unrelocated_addr) retval;
 }
diff --git a/gdb/dwarf2/comp-unit-head.h b/gdb/dwarf2/comp-unit-head.h
index 65a16f4ef14..696a62b7845 100644
--- a/gdb/dwarf2/comp-unit-head.h
+++ b/gdb/dwarf2/comp-unit-head.h
@@ -108,8 +108,8 @@ struct comp_unit_head
   }
 
   /* Read an address from BUF.  BYTES_READ is updated.  */
-  CORE_ADDR read_address (bfd *abfd, const gdb_byte *buf,
-			  unsigned int *bytes_read) const;
+  unrelocated_addr read_address (bfd *abfd, const gdb_byte *buf,
+				 unsigned int *bytes_read) const;
 };
 
 /* Expected enum dwarf_unit_type for read_comp_unit_head.  */
diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h
index 8059b70f721..0c15d8b02db 100644
--- a/gdb/dwarf2/cu.h
+++ b/gdb/dwarf2/cu.h
@@ -101,7 +101,7 @@ struct dwarf2_cu
   struct comp_unit_head header;
 
   /* Base address of this compilation unit.  */
-  gdb::optional<CORE_ADDR> base_address;
+  gdb::optional<unrelocated_addr> base_address;
 
   /* The language we are debugging.  */
   const struct language_defn *language_defn = nullptr;
diff --git a/gdb/dwarf2/die.c b/gdb/dwarf2/die.c
index d409d24d7f6..bba2976616f 100644
--- a/gdb/dwarf2/die.c
+++ b/gdb/dwarf2/die.c
@@ -91,7 +91,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
 	case DW_FORM_addrx:
 	case DW_FORM_GNU_addr_index:
 	  gdb_printf (f, "address: ");
-	  gdb_puts (hex_string (die->attrs[i].as_address ()), f);
+	  gdb_puts (hex_string ((CORE_ADDR) die->attrs[i].as_address ()), f);
 	  break;
 	case DW_FORM_block2:
 	case DW_FORM_block4:
diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 4aa4542d947..601cec0152a 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -1581,17 +1581,19 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
 	  ensure_have_per_cu (this->m_per_cu, "DW_OP_addrx");
 
 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
-	  result = dwarf2_read_addr_index (this->m_per_cu, this->m_per_objfile,
-					   uoffset);
-	  result += this->m_per_objfile->objfile->text_section_offset ();
+	  result = (m_per_objfile->relocate
+		    (dwarf2_read_addr_index (this->m_per_cu,
+					     this->m_per_objfile,
+					     uoffset)));
 	  result_val = value_from_ulongest (address_type, result);
 	  break;
 	case DW_OP_GNU_const_index:
 	  ensure_have_per_cu (this->m_per_cu, "DW_OP_GNU_const_index");
 
 	  op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
-	  result = dwarf2_read_addr_index (this->m_per_cu, this->m_per_objfile,
-					   uoffset);
+	  result = (ULONGEST) dwarf2_read_addr_index (this->m_per_cu,
+						      this->m_per_objfile,
+						      uoffset);
 	  result_val = value_from_ulongest (address_type, result);
 	  break;
 
diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
index c1955f28a44..e50e7f1e47e 100644
--- a/gdb/dwarf2/loc.c
+++ b/gdb/dwarf2/loc.c
@@ -107,7 +107,7 @@ invalid_synthetic_pointer (void)
 static enum debug_loc_kind
 decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end,
 			    const gdb_byte **new_ptr,
-			    CORE_ADDR *low, CORE_ADDR *high,
+			    unrelocated_addr *lowp, unrelocated_addr *highp,
 			    enum bfd_endian byte_order,
 			    unsigned int addr_size,
 			    int signed_addr_p)
@@ -117,26 +117,29 @@ decode_debug_loc_addresses (const gdb_byte *loc_ptr, const gdb_byte *buf_end,
   if (buf_end - loc_ptr < 2 * addr_size)
     return DEBUG_LOC_BUFFER_OVERFLOW;
 
+  CORE_ADDR low, high;
   if (signed_addr_p)
-    *low = extract_signed_integer (loc_ptr, addr_size, byte_order);
+    low = extract_signed_integer (loc_ptr, addr_size, byte_order);
   else
-    *low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+    low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
   loc_ptr += addr_size;
 
   if (signed_addr_p)
-    *high = extract_signed_integer (loc_ptr, addr_size, byte_order);
+    high = extract_signed_integer (loc_ptr, addr_size, byte_order);
   else
-    *high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+    high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
   loc_ptr += addr_size;
 
   *new_ptr = loc_ptr;
+  *lowp = (unrelocated_addr) low;
+  *highp = (unrelocated_addr) high;
 
   /* A base-address-selection entry.  */
-  if ((*low & base_mask) == base_mask)
+  if ((low & base_mask) == base_mask)
     return DEBUG_LOC_BASE_ADDRESS;
 
   /* An end-of-list entry.  */
-  if (*low == 0 && *high == 0)
+  if (low == 0 && high == 0)
     return DEBUG_LOC_END_OF_LIST;
 
   /* We want the caller to apply the base address, so we must return
@@ -155,7 +158,8 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
 				 const gdb_byte *loc_ptr,
 				 const gdb_byte *buf_end,
 				 const gdb_byte **new_ptr,
-				 CORE_ADDR *low, CORE_ADDR *high,
+				 unrelocated_addr *low,
+				 unrelocated_addr *high,
 				 enum bfd_endian byte_order,
 				 unsigned int addr_size,
 				 int signed_addr_p)
@@ -168,7 +172,7 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
   switch (*loc_ptr++)
     {
     case DW_LLE_base_addressx:
-      *low = 0;
+      *low = {};
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
       if (loc_ptr == NULL)
 	 return DEBUG_LOC_BUFFER_OVERFLOW;
@@ -188,7 +192,7 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
       if (loc_ptr == NULL)
 	 return DEBUG_LOC_BUFFER_OVERFLOW;
 
-      *high += u64;
+      *high = (unrelocated_addr) ((uint64_t) *high + u64);
       *new_ptr = loc_ptr;
       return DEBUG_LOC_START_LENGTH;
 
@@ -197,9 +201,11 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
 	 return DEBUG_LOC_BUFFER_OVERFLOW;
 
       if (signed_addr_p)
-	 *low = extract_signed_integer (loc_ptr, addr_size, byte_order);
+	*low = (unrelocated_addr) extract_signed_integer (loc_ptr, addr_size,
+							  byte_order);
       else
-	 *low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+	*low = (unrelocated_addr) extract_unsigned_integer (loc_ptr, addr_size,
+							    byte_order);
 
       loc_ptr += addr_size;
       *high = *low;
@@ -208,7 +214,7 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
       if (loc_ptr == NULL)
 	 return DEBUG_LOC_BUFFER_OVERFLOW;
 
-      *high += u64;
+      *high = (unrelocated_addr) ((uint64_t) *high + u64);
       *new_ptr = loc_ptr;
       return DEBUG_LOC_START_LENGTH;
 
@@ -221,9 +227,11 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
 	return DEBUG_LOC_BUFFER_OVERFLOW;
 
       if (signed_addr_p)
-	*high = extract_signed_integer (loc_ptr, addr_size, byte_order);
+	*high = (unrelocated_addr) extract_signed_integer (loc_ptr, addr_size,
+							   byte_order);
       else
-	*high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+	*high = (unrelocated_addr) extract_unsigned_integer (loc_ptr, addr_size,
+							     byte_order);
 
       loc_ptr += addr_size;
       *new_ptr = loc_ptr;
@@ -234,12 +242,12 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
 
-      *low = u64;
+      *low = (unrelocated_addr) u64;
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &u64);
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
 
-      *high = u64;
+      *high = (unrelocated_addr) u64;
       *new_ptr = loc_ptr;
       return DEBUG_LOC_OFFSET_PAIR;
 
@@ -248,15 +256,19 @@ decode_debug_loclists_addresses (dwarf2_per_cu_data *per_cu,
 	return DEBUG_LOC_BUFFER_OVERFLOW;
 
       if (signed_addr_p)
-	*low = extract_signed_integer (loc_ptr, addr_size, byte_order);
+	*low = (unrelocated_addr) extract_signed_integer (loc_ptr, addr_size,
+							  byte_order);
       else
-	*low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+	*low = (unrelocated_addr) extract_unsigned_integer (loc_ptr, addr_size,
+							    byte_order);
 
       loc_ptr += addr_size;
       if (signed_addr_p)
-	*high = extract_signed_integer (loc_ptr, addr_size, byte_order);
+	*high = (unrelocated_addr) extract_signed_integer (loc_ptr, addr_size,
+							   byte_order);
       else
-	*high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+	*high = (unrelocated_addr) extract_unsigned_integer (loc_ptr, addr_size,
+							     byte_order);
 
       loc_ptr += addr_size;
       *new_ptr = loc_ptr;
@@ -281,7 +293,8 @@ decode_debug_loc_dwo_addresses (dwarf2_per_cu_data *per_cu,
 				const gdb_byte *loc_ptr,
 				const gdb_byte *buf_end,
 				const gdb_byte **new_ptr,
-				CORE_ADDR *low, CORE_ADDR *high,
+				unrelocated_addr *low,
+				unrelocated_addr *high,
 				enum bfd_endian byte_order)
 {
   uint64_t low_index, high_index;
@@ -296,7 +309,7 @@ decode_debug_loc_dwo_addresses (dwarf2_per_cu_data *per_cu,
       return DEBUG_LOC_END_OF_LIST;
 
     case DW_LLE_GNU_base_address_selection_entry:
-      *low = 0;
+      *low = {};
       loc_ptr = gdb_read_uleb128 (loc_ptr, buf_end, &high_index);
       if (loc_ptr == NULL)
 	return DEBUG_LOC_BUFFER_OVERFLOW;
@@ -329,7 +342,9 @@ decode_debug_loc_dwo_addresses (dwarf2_per_cu_data *per_cu,
 	return DEBUG_LOC_BUFFER_OVERFLOW;
 
       *high = *low;
-      *high += extract_unsigned_integer (loc_ptr, 4, byte_order);
+      *high = (unrelocated_addr) ((CORE_ADDR) *high
+				  + extract_unsigned_integer (loc_ptr, 4,
+							      byte_order));
       *new_ptr = loc_ptr + 4;
       return DEBUG_LOC_START_LENGTH;
 
@@ -348,7 +363,7 @@ decode_debug_loc_dwo_addresses (dwarf2_per_cu_data *per_cu,
 
 const gdb_byte *
 dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
-				 size_t *locexpr_length, CORE_ADDR pc)
+				 size_t *locexpr_length, const CORE_ADDR pc)
 {
   dwarf2_per_objfile *per_objfile = baton->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
@@ -358,7 +373,8 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
   /* Adjustment for relocatable objects.  */
   CORE_ADDR text_offset = baton->per_objfile->objfile->text_section_offset ();
-  CORE_ADDR base_address = baton->base_address;
+  unrelocated_addr unrel_pc = (unrelocated_addr) (pc - text_offset);
+  unrelocated_addr base_address = baton->base_address;
   const gdb_byte *loc_ptr, *buf_end;
 
   loc_ptr = baton->data;
@@ -366,7 +382,7 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
 
   while (1)
     {
-      CORE_ADDR low = 0, high = 0; /* init for gcc -Wall */
+      unrelocated_addr low = {}, high = {}; /* init for gcc -Wall */
       int length;
       enum debug_loc_kind kind;
       const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */
@@ -421,12 +437,10 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
 	 operands are offsets relative to the applicable base address.
 	 If the entry is DW_LLE_start_end or DW_LLE_start_length, then
 	 it already is an address, and we don't need to add the base.  */
-      low += text_offset;
-      high += text_offset;
       if (!baton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
 	{
-	  low += base_address;
-	  high += base_address;
+	  low = (unrelocated_addr) ((CORE_ADDR) low + (CORE_ADDR) base_address);
+	  high = (unrelocated_addr) ((CORE_ADDR) high + (CORE_ADDR) base_address);
 	}
 
       if (baton->per_cu->version () < 5)
@@ -442,7 +456,7 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
 	  loc_ptr += bytes_read;
 	}
 
-      if (low == high && pc == low)
+      if (low == high && unrel_pc == low)
 	{
 	  /* This is entry PC record present only at entry point
 	     of a function.  Verify it is really the function entry point.  */
@@ -460,7 +474,7 @@ dwarf2_find_location_expression (const dwarf2_loclist_baton *baton,
 	    }
 	}
 
-      if (pc >= low && pc < high)
+      if (unrel_pc >= low && unrel_pc < high)
 	{
 	  *locexpr_length = length;
 	  return loc_ptr;
@@ -722,19 +736,17 @@ call_site_target::iterate_over_addresses
     case call_site_target::PHYSADDR:
       {
 	dwarf2_per_objfile *per_objfile = call_site->per_objfile;
-	CORE_ADDR delta = per_objfile->objfile->text_section_offset ();
 
-	callback (m_loc.physaddr + delta);
+	callback (per_objfile->relocate (m_loc.physaddr));
       }
       break;
 
     case call_site_target::ADDRESSES:
       {
 	dwarf2_per_objfile *per_objfile = call_site->per_objfile;
-	CORE_ADDR delta = per_objfile->objfile->text_section_offset ();
 
 	for (unsigned i = 0; i < m_loc.addresses.length; ++i)
-	  callback (m_loc.addresses.values[i] + delta);
+	  callback (per_objfile->relocate (m_loc.addresses.values[i]));
       }
       break;
 
@@ -3269,7 +3281,7 @@ locexpr_describe_location_piece (struct symbol *symbol, struct ui_file *stream,
       uint64_t offset;
 
       data = safe_read_uleb128 (data + 1, end, &offset);
-      offset = dwarf2_read_addr_index (per_cu, per_objfile, offset);
+      offset = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, offset);
       gdb_printf (stream, 
 		  _("a thread-local variable at offset 0x%s "
 		    "in the thread-local storage for `%s'"),
@@ -3663,13 +3675,13 @@ disassemble_dwarf_expression (struct ui_file *stream,
 	case DW_OP_addrx:
 	case DW_OP_GNU_addr_index:
 	  data = safe_read_uleb128 (data, end, &ul);
-	  ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
+	  ul = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, ul);
 	  gdb_printf (stream, " 0x%s", phex_nz (ul, addr_size));
 	  break;
 
 	case DW_OP_GNU_const_index:
 	  data = safe_read_uleb128 (data, end, &ul);
-	  ul = dwarf2_read_addr_index (per_cu, per_objfile, ul);
+	  ul = (uint64_t) dwarf2_read_addr_index (per_cu, per_objfile, ul);
 	  gdb_printf (stream, " %s", pulongest (ul));
 	  break;
 
@@ -3948,9 +3960,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   unsigned int addr_size = dlbaton->per_cu->addr_size ();
   int offset_size = dlbaton->per_cu->offset_size ();
   int signed_addr_p = bfd_get_sign_extend_vma (objfile->obfd.get ());
-  /* Adjustment for relocatable objects.  */
-  CORE_ADDR text_offset = objfile->text_section_offset ();
-  CORE_ADDR base_address = dlbaton->base_address;
+  unrelocated_addr base_address = dlbaton->base_address;
   int done = 0;
 
   loc_ptr = dlbaton->data;
@@ -3961,7 +3971,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
   /* Iterate through locations until we run out.  */
   while (!done)
     {
-      CORE_ADDR low = 0, high = 0; /* init for gcc -Wall */
+      unrelocated_addr low = {}, high = {}; /* init for gcc -Wall */
       int length;
       enum debug_loc_kind kind;
       const gdb_byte *new_ptr = NULL; /* init for gcc -Wall */
@@ -3992,7 +4002,7 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 	case DEBUG_LOC_BASE_ADDRESS:
 	  base_address = high;
 	  gdb_printf (stream, _("  Base address %s"),
-		      paddress (gdbarch, base_address));
+		      paddress (gdbarch, (CORE_ADDR) base_address));
 	  continue;
 
 	case DEBUG_LOC_START_END:
@@ -4010,16 +4020,16 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
 	}
 
       /* Otherwise, a location expression entry.  */
-      low += text_offset;
-      high += text_offset;
       if (!dlbaton->from_dwo && kind == DEBUG_LOC_OFFSET_PAIR)
 	{
-	  low += base_address;
-	  high += base_address;
+	  low = (unrelocated_addr) ((CORE_ADDR) low
+				    + (CORE_ADDR) base_address);
+	  high = (unrelocated_addr) ((CORE_ADDR) high
+				     + (CORE_ADDR) base_address);
 	}
 
-      low = gdbarch_adjust_dwarf2_addr (gdbarch, low);
-      high = gdbarch_adjust_dwarf2_addr (gdbarch, high);
+      CORE_ADDR low_reloc = per_objfile->relocate (low);
+      CORE_ADDR high_reloc = per_objfile->relocate (high);
 
       if (dlbaton->per_cu->version () < 5)
 	 {
@@ -4036,10 +4046,11 @@ loclist_describe_location (struct symbol *symbol, CORE_ADDR addr,
       /* (It would improve readability to print only the minimum
 	 necessary digits of the second number of the range.)  */
       gdb_printf (stream, _("  Range %s-%s: "),
-		  paddress (gdbarch, low), paddress (gdbarch, high));
+		  paddress (gdbarch, low_reloc),
+		  paddress (gdbarch, high_reloc));
 
       /* Now describe this particular location.  */
-      locexpr_describe_location_1 (symbol, low, stream, loc_ptr, length,
+      locexpr_describe_location_1 (symbol, low_reloc, stream, loc_ptr, length,
 				   addr_size, offset_size,
 				   dlbaton->per_cu, per_objfile);
 
diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h
index ad60177e93c..7e91ddc82dc 100644
--- a/gdb/dwarf2/loc.h
+++ b/gdb/dwarf2/loc.h
@@ -180,7 +180,7 @@ struct dwarf2_loclist_baton
 {
   /* The initial base address for the location list, based on the compilation
      unit.  */
-  CORE_ADDR base_address;
+  unrelocated_addr base_address;
 
   /* Pointer to the start of the location list.  */
   const gdb_byte *data;
diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c
index 1006386cb2d..1127643e53a 100644
--- a/gdb/dwarf2/read-gdb-index.c
+++ b/gdb/dwarf2/read-gdb-index.c
@@ -717,19 +717,14 @@ static void
 create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
 			       mapped_gdb_index *index)
 {
-  struct objfile *objfile = per_objfile->objfile;
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
-  struct gdbarch *gdbarch = objfile->arch ();
   const gdb_byte *iter, *end;
-  CORE_ADDR baseaddr;
 
   addrmap_mutable mutable_map;
 
   iter = index->address_table.data ();
   end = iter + index->address_table.size ();
 
-  baseaddr = objfile->text_section_offset ();
-
   while (iter < end)
     {
       ULONGEST hi, lo, cu_index;
@@ -754,8 +749,8 @@ create_addrmap_from_gdb_index (dwarf2_per_objfile *per_objfile,
 	  continue;
 	}
 
-      lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr;
-      hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr;
+      lo = (ULONGEST) per_objfile->adjust ((unrelocated_addr) lo);
+      hi = (ULONGEST) per_objfile->adjust ((unrelocated_addr) hi);
       mutable_map.set_empty (lo, hi - 1, per_bfd->get_cu (cu_index));
     }
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 904dcc09405..39e4f05b389 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -767,7 +767,8 @@ static void read_attribute_reprocess (const struct die_reader_specs *reader,
 				      struct attribute *attr,
 				      dwarf_tag tag = DW_TAG_padding);
 
-static CORE_ADDR read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index);
+static unrelocated_addr read_addr_index (struct dwarf2_cu *cu,
+					 unsigned int addr_index);
 
 static sect_offset read_abbrev_offset (dwarf2_per_objfile *per_objfile,
 				       dwarf2_section_info *, sect_offset);
@@ -776,9 +777,9 @@ static const char *read_indirect_string
   (dwarf2_per_objfile *per_objfile, bfd *, const gdb_byte *,
    const struct comp_unit_head *, unsigned int *);
 
-static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *,
-					      const gdb_byte *,
-					      unsigned int *);
+static unrelocated_addr read_addr_index_from_leb128 (struct dwarf2_cu *,
+						     const gdb_byte *,
+						     unsigned int *);
 
 static const char *read_dwo_str_index (const struct die_reader_specs *reader,
 				       ULONGEST str_index);
@@ -894,13 +895,14 @@ enum pc_bounds_kind
 };
 
 static enum pc_bounds_kind dwarf2_get_pc_bounds (struct die_info *,
-						 CORE_ADDR *, CORE_ADDR *,
+						 unrelocated_addr *,
+						 unrelocated_addr *,
 						 struct dwarf2_cu *,
 						 addrmap *,
 						 void *);
 
 static void get_scope_pc_bounds (struct die_info *,
-				 CORE_ADDR *, CORE_ADDR *,
+				 unrelocated_addr *, unrelocated_addr *,
 				 struct dwarf2_cu *);
 
 static void dwarf2_record_block_ranges (struct die_info *, struct block *,
@@ -1195,6 +1197,27 @@ dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
 	     arg1, arg2);
 }
 
+/* See read.h.  */
+
+unrelocated_addr
+dwarf2_per_objfile::adjust (unrelocated_addr addr)
+{
+  CORE_ADDR baseaddr = objfile->text_section_offset ();
+  CORE_ADDR tem = (CORE_ADDR) addr + baseaddr;
+  tem = gdbarch_adjust_dwarf2_addr (objfile->arch (), tem);
+  return (unrelocated_addr) (tem - baseaddr);
+}
+
+/* See read.h.  */
+
+CORE_ADDR
+dwarf2_per_objfile::relocate (unrelocated_addr addr)
+{
+  CORE_ADDR baseaddr = objfile->text_section_offset ();
+  CORE_ADDR tem = (CORE_ADDR) addr + baseaddr;
+  return gdbarch_adjust_dwarf2_addr (objfile->arch (), tem);
+}
+
 /* Hash function for line_header_hash.  */
 
 static hashval_t
@@ -1818,7 +1841,6 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
   struct objfile *objfile = per_objfile->objfile;
   bfd *abfd = objfile->obfd.get ();
   struct gdbarch *gdbarch = objfile->arch ();
-  const CORE_ADDR baseaddr = objfile->text_section_offset ();
   dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
 
   std::unordered_map<sect_offset,
@@ -1976,10 +1998,8 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
 	      continue;
 	    }
 	  ULONGEST end = start + length;
-	  start = (gdbarch_adjust_dwarf2_addr (gdbarch, start + baseaddr)
-		   - baseaddr);
-	  end = (gdbarch_adjust_dwarf2_addr (gdbarch, end + baseaddr)
-		 - baseaddr);
+	  start = (ULONGEST) per_objfile->adjust ((unrelocated_addr) start);
+	  end = (ULONGEST) per_objfile->adjust ((unrelocated_addr) end);
 	  mutable_map->set_empty (start, end - 1, per_cu);
 	}
 
@@ -6364,16 +6384,11 @@ static void
 process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
-  struct objfile *objfile = per_objfile->objfile;
-  struct gdbarch *gdbarch = objfile->arch ();
-  CORE_ADDR lowpc, highpc;
+  unrelocated_addr lowpc, highpc;
   struct compunit_symtab *cust;
-  CORE_ADDR baseaddr;
   struct block *static_block;
   CORE_ADDR addr;
 
-  baseaddr = objfile->text_section_offset ();
-
   /* Clear the list here in case something was left over.  */
   cu->method_list.clear ();
 
@@ -6414,7 +6429,7 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
      it, by scanning the DIE's below the compilation unit.  */
   get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
 
-  addr = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
+  addr = per_objfile->relocate (highpc);
   static_block
     = cu->get_builder ()->end_compunit_symtab_get_static_block (addr, 0, 1);
 
@@ -7624,23 +7639,20 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
-  struct gdbarch *gdbarch = objfile->arch ();
-  CORE_ADDR lowpc = ((CORE_ADDR) -1);
-  CORE_ADDR highpc = ((CORE_ADDR) 0);
+  CORE_ADDR lowpc;
   struct attribute *attr;
   struct die_info *child_die;
-  CORE_ADDR baseaddr;
 
   prepare_one_comp_unit (cu, die, cu->lang ());
-  baseaddr = objfile->text_section_offset ();
 
-  get_scope_pc_bounds (die, &lowpc, &highpc, cu);
+  unrelocated_addr unrel_low, unrel_high;
+  get_scope_pc_bounds (die, &unrel_low, &unrel_high, cu);
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
      from finish_block.  */
-  if (lowpc == ((CORE_ADDR) -1))
-    lowpc = highpc;
-  lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
+  if (unrel_low == ((unrelocated_addr) -1))
+    unrel_low = unrel_high;
+  lowpc = per_objfile->relocate (unrel_low);
 
   file_and_directory &fnd = find_file_and_directory (die, cu);
 
@@ -7654,7 +7666,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   /* Decode line number information if present.  We do this before
      processing child DIEs, so that the line header table is available
      for DW_AT_decl_file.  */
-  handle_DW_AT_stmt_list (die, cu, fnd, lowpc, lowpc != highpc);
+  handle_DW_AT_stmt_list (die, cu, fnd, lowpc, unrel_low != unrel_high);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -10017,7 +10029,8 @@ dwarf2_func_is_main_p (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_objfile->objfile;
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct context_stack *newobj;
   CORE_ADDR lowpc;
@@ -10025,7 +10038,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   struct attribute *attr, *call_line, *call_file;
   const char *name;
-  CORE_ADDR baseaddr;
   struct block *block;
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
   std::vector<struct symbol *> template_args;
@@ -10045,8 +10057,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 	}
     }
 
-  baseaddr = objfile->text_section_offset ();
-
   name = dwarf2_name (die, cu);
   if (name == nullptr)
     name = dw2_linkage_name (die, cu);
@@ -10061,7 +10071,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   /* Ignore functions with missing or invalid low and high pc attributes.  */
-  if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, nullptr, nullptr)
+  unrelocated_addr unrel_low, unrel_high;
+  if (dwarf2_get_pc_bounds (die, &unrel_low, &unrel_high, cu, nullptr, nullptr)
       <= PC_BOUNDS_INVALID)
     {
       if (have_complaint ())
@@ -10084,8 +10095,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
       return;
     }
 
-  lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
-  highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
+  lowpc = per_objfile->relocate (unrel_low);
+  highpc = per_objfile->relocate (unrel_high);
 
   /* If we have any template arguments, then we must allocate a
      different sort of symbol.  */
@@ -10232,20 +10243,18 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 static void
 read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_objfile->objfile;
-  struct gdbarch *gdbarch = objfile->arch ();
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
-  CORE_ADDR baseaddr;
-
-  baseaddr = objfile->text_section_offset ();
 
   /* Ignore blocks with missing or invalid low and high pc attributes.  */
   /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
      as multiple lexical blocks?  Handling children in a sane way would
      be nasty.  Might be easier to properly extend generic blocks to
      describe ranges.  */
-  switch (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, nullptr, nullptr))
+  unrelocated_addr unrel_low, unrel_high;
+  switch (dwarf2_get_pc_bounds (die, &unrel_low, &unrel_high, cu,
+				nullptr, nullptr))
     {
     case PC_BOUNDS_NOT_PRESENT:
       /* DW_TAG_lexical_block has no attributes, process its children as if
@@ -10268,8 +10277,8 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
     case PC_BOUNDS_INVALID:
       return;
     }
-  lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
-  highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
+  lowpc = per_objfile->relocate (unrel_low);
+  highpc = per_objfile->relocate (unrel_high);
 
   cu->get_builder ()->push_context (0, lowpc);
   if (die->child != NULL)
@@ -10307,10 +10316,11 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
   cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
 }
 
-static void dwarf2_ranges_read_low_addrs (unsigned offset,
-					  struct dwarf2_cu *cu,
-					  dwarf_tag tag,
-					  std::vector<CORE_ADDR> &result);
+static void dwarf2_ranges_read_low_addrs
+     (unsigned offset,
+      struct dwarf2_cu *cu,
+      dwarf_tag tag,
+      std::vector<unrelocated_addr> &result);
 
 /* Read in DW_TAG_call_site and insert it to CU->call_site_htab.  */
 
@@ -10320,14 +10330,11 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
-  CORE_ADDR pc, baseaddr;
   struct attribute *attr;
   void **slot;
   int nparams;
   struct die_info *child_die;
 
-  baseaddr = objfile->text_section_offset ();
-
   attr = dwarf2_attr (die, DW_AT_call_return_pc, cu);
   if (attr == NULL)
     {
@@ -10342,9 +10349,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 		 sect_offset_str (die->sect_off), objfile_name (objfile));
       return;
     }
-  pc = attr->as_address () + baseaddr;
-  pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
-  pc -= baseaddr;
+  unrelocated_addr pc = per_objfile->adjust (attr->as_address ());
 
   if (cu->call_site_htab == NULL)
     cu->call_site_htab = htab_create_alloc_ex (16, call_site::hash,
@@ -10357,7 +10362,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
     {
       complaint (_("Duplicate PC %s for DW_TAG_call_site "
 		   "DIE %s [in module %s]"),
-		 paddress (gdbarch, pc), sect_offset_str (die->sect_off),
+		 paddress (gdbarch, (CORE_ADDR) pc), sect_offset_str (die->sect_off),
 		 objfile_name (objfile));
       return;
     }
@@ -10498,17 +10503,18 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  ULONGEST ranges_offset = (ranges_attr->as_unsigned ()
 				    + target_cu->gnu_ranges_base);
-	  std::vector<CORE_ADDR> addresses;
+	  std::vector<unrelocated_addr> addresses;
 	  dwarf2_ranges_read_low_addrs (ranges_offset, target_cu,
 					target_die->tag, addresses);
-	  CORE_ADDR *saved = XOBNEWVAR (&objfile->objfile_obstack, CORE_ADDR,
-					addresses.size ());
+	  unrelocated_addr *saved = XOBNEWVAR (&objfile->objfile_obstack,
+					       unrelocated_addr,
+					       addresses.size ());
 	  std::copy (addresses.begin (), addresses.end (), saved);
 	  call_site->target.set_loc_array (addresses.size (), saved);
 	}
       else
 	{
-	  CORE_ADDR lowpc;
+	  unrelocated_addr lowpc;
 
 	  /* DW_AT_entry_pc should be preferred.  */
 	  if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu,
@@ -10519,8 +10525,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
 		       sect_offset_str (die->sect_off), objfile_name (objfile));
 	  else
 	    {
-	      lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr)
-		       - baseaddr);
+	      lowpc = per_objfile->adjust (lowpc);
 	      call_site->target.set_loc_physaddr (lowpc);
 	    }
 	}
@@ -10731,7 +10736,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   struct objfile *objfile = per_objfile->objfile;
   bfd *obfd = objfile->obfd.get ();
   /* Base address selection entry.  */
-  gdb::optional<CORE_ADDR> base;
+  gdb::optional<unrelocated_addr> base;
   const gdb_byte *buffer;
   bool overflow = false;
   ULONGEST addr_index;
@@ -10752,7 +10757,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
   while (1)
     {
       /* Initialize it due to a false compiler warning.  */
-      CORE_ADDR range_beginning = 0, range_end = 0;
+      unrelocated_addr range_beginning = {}, range_end = {};
       const gdb_byte *buf_end = (rnglists_section->buffer
 				 + rnglists_section->size);
       unsigned int bytes_read;
@@ -10790,8 +10795,10 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 	  range_beginning = cu->header.read_address (obfd, buffer,
 						     &bytes_read);
 	  buffer += bytes_read;
-	  range_end = (range_beginning
-		       + read_unsigned_leb128 (obfd, buffer, &bytes_read));
+	  range_end
+	    = (unrelocated_addr) ((CORE_ADDR) range_beginning
+				  + read_unsigned_leb128 (obfd, buffer,
+							  &bytes_read));
 	  buffer += bytes_read;
 	  if (buffer > buf_end)
 	    {
@@ -10808,19 +10815,23 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 	      overflow = true;
 	      break;
 	    }
-	  range_end = (range_beginning
-		       + read_unsigned_leb128 (obfd, buffer, &bytes_read));
+	  range_end
+	    = (unrelocated_addr) ((CORE_ADDR) range_beginning
+				  + read_unsigned_leb128 (obfd, buffer,
+							  &bytes_read));
 	  buffer += bytes_read;
 	  break;
 	case DW_RLE_offset_pair:
-	  range_beginning = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+	  range_beginning = (unrelocated_addr) read_unsigned_leb128 (obfd, buffer,
+								     &bytes_read);
 	  buffer += bytes_read;
 	  if (buffer > buf_end)
 	    {
 	      overflow = true;
 	      break;
 	    }
-	  range_end = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+	  range_end = (unrelocated_addr) read_unsigned_leb128 (obfd, buffer,
+							       &bytes_read);
 	  buffer += bytes_read;
 	  if (buffer > buf_end)
 	    {
@@ -10884,13 +10895,15 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 	      return false;
 	    }
 
-	  range_beginning += *base;
-	  range_end += *base;
+	  range_beginning = (unrelocated_addr) ((CORE_ADDR) range_beginning
+						+ (CORE_ADDR) *base);
+	  range_end = (unrelocated_addr) ((CORE_ADDR) range_end
+					  + (CORE_ADDR) *base);
 	}
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning == 0
+      if (range_beginning == (unrelocated_addr) 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_rnglists entry has start address of zero"
@@ -10914,7 +10927,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
 
 /* Call CALLBACK from DW_AT_ranges attribute value OFFSET reading .debug_ranges.
    Callback's type should be:
-    void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+    void (unrelocated_addr range_beginning, unrelocated_addr range_end)
    Return 1 if the attributes are present and valid, otherwise, return 0.  */
 
 template <typename Callback>
@@ -10929,7 +10942,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
   unsigned int addr_size = cu_header->addr_size;
   CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Base address selection entry.  */
-  gdb::optional<CORE_ADDR> base;
+  gdb::optional<unrelocated_addr> base;
   unsigned int dummy;
   const gdb_byte *buffer;
 
@@ -10949,7 +10962,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
 
   while (1)
     {
-      CORE_ADDR range_beginning, range_end;
+      unrelocated_addr range_beginning, range_end;
 
       range_beginning = cu->header.read_address (obfd, buffer, &dummy);
       buffer += addr_size;
@@ -10958,14 +10971,15 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
       offset += 2 * addr_size;
 
       /* An end of list marker is a pair of zero addresses.  */
-      if (range_beginning == 0 && range_end == 0)
+      if (range_beginning == (unrelocated_addr) 0
+	  && range_end == (unrelocated_addr) 0)
 	/* Found the end of list entry.  */
 	break;
 
       /* Each base address selection entry is a pair of 2 values.
 	 The first is the largest possible address, the second is
 	 the base address.  Check for a base address here.  */
-      if ((range_beginning & mask) == mask)
+      if (((CORE_ADDR) range_beginning & mask) == mask)
 	{
 	  /* If we found the largest possible address, then we already
 	     have the base address in range_end.  */
@@ -10992,12 +11006,14 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
       if (range_beginning == range_end)
 	continue;
 
-      range_beginning += *base;
-      range_end += *base;
+      range_beginning = (unrelocated_addr) ((CORE_ADDR) range_beginning
+					    + (CORE_ADDR) *base);
+      range_end = (unrelocated_addr) ((CORE_ADDR) range_end
+				      + (CORE_ADDR) *base);
 
       /* A not-uncommon case of bad debug info.
 	 Don't pollute the addrmap with bad data.  */
-      if (range_beginning == 0
+      if (range_beginning == (unrelocated_addr) 0
 	  && !per_objfile->per_bfd->has_section_at_zero)
 	{
 	  complaint (_(".debug_ranges entry has start address of zero"
@@ -11017,33 +11033,28 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
    ranges in MAP are set, using DATUM as the value.  */
 
 static int
-dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
-		    CORE_ADDR *high_return, struct dwarf2_cu *cu,
+dwarf2_ranges_read (unsigned offset, unrelocated_addr *low_return,
+		    unrelocated_addr *high_return, struct dwarf2_cu *cu,
 		    addrmap *map, void *datum, dwarf_tag tag)
 {
-  struct objfile *objfile = cu->per_objfile->objfile;
-  struct gdbarch *gdbarch = objfile->arch ();
-  const CORE_ADDR baseaddr = objfile->text_section_offset ();
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
   int low_set = 0;
-  CORE_ADDR low = 0;
-  CORE_ADDR high = 0;
+  unrelocated_addr low = {};
+  unrelocated_addr high = {};
   int retval;
 
   retval = dwarf2_ranges_process (offset, cu, tag,
-    [&] (CORE_ADDR range_beginning, CORE_ADDR range_end)
+    [&] (unrelocated_addr range_beginning, unrelocated_addr range_end)
     {
       if (map != nullptr)
 	{
-	  CORE_ADDR lowpc;
-	  CORE_ADDR highpc;
-
-	  lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
-					       range_beginning + baseaddr)
-		   - baseaddr);
-	  highpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
-						range_end + baseaddr)
-		    - baseaddr);
-	  map->set_empty (lowpc, highpc - 1, datum);
+	  unrelocated_addr lowpc;
+	  unrelocated_addr highpc;
+
+	  lowpc = per_objfile->adjust (range_beginning);
+	  highpc = per_objfile->adjust (range_end);
+	  /* addrmap only accepts CORE_ADDR, so we must cast here.  */
+	  map->set_empty ((CORE_ADDR) lowpc, (CORE_ADDR) highpc - 1, datum);
 	}
 
       /* FIXME: This is recording everything as a low-high
@@ -11084,10 +11095,10 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 static void
 dwarf2_ranges_read_low_addrs (unsigned offset, struct dwarf2_cu *cu,
 			      dwarf_tag tag,
-			      std::vector<CORE_ADDR> &result)
+			      std::vector<unrelocated_addr> &result)
 {
   dwarf2_ranges_process (offset, cu, tag,
-			 [&] (CORE_ADDR start, CORE_ADDR end)
+			 [&] (unrelocated_addr start, unrelocated_addr end)
     {
       result.push_back (start);
     });
@@ -11098,15 +11109,15 @@ dwarf2_ranges_read_low_addrs (unsigned offset, struct dwarf2_cu *cu,
    neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned.  */
 
 static enum pc_bounds_kind
-dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
-		      CORE_ADDR *highpc, struct dwarf2_cu *cu,
+dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc,
+		      unrelocated_addr *highpc, struct dwarf2_cu *cu,
 		      addrmap *map, void *datum)
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct attribute *attr;
   struct attribute *attr_high;
-  CORE_ADDR low = 0;
-  CORE_ADDR high = 0;
+  unrelocated_addr low = {};
+  unrelocated_addr high = {};
   enum pc_bounds_kind ret;
 
   attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
@@ -11118,7 +11129,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 	  low = attr->as_address ();
 	  high = attr_high->as_address ();
 	  if (cu->header.version >= 4 && attr_high->form_is_constant ())
-	    high += low;
+	    high = (unrelocated_addr) ((ULONGEST) high + (ULONGEST) low);
 	}
       else
 	/* Found high w/o low attribute.  */
@@ -11165,7 +11176,8 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
      labels are not in the output, so the relocs get a value of 0.
      If this is a discarded function, mark the pc bounds as invalid,
      so that GDB will ignore it.  */
-  if (low == 0 && !per_objfile->per_bfd->has_section_at_zero)
+  if (low == (unrelocated_addr) 0
+      && !per_objfile->per_bfd->has_section_at_zero)
     return PC_BOUNDS_INVALID;
 
   *lowpc = low;
@@ -11181,10 +11193,11 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
 
 static void
 dwarf2_get_subprogram_pc_bounds (struct die_info *die,
-				 CORE_ADDR *lowpc, CORE_ADDR *highpc,
+				 unrelocated_addr *lowpc,
+				 unrelocated_addr *highpc,
 				 struct dwarf2_cu *cu)
 {
-  CORE_ADDR low, high;
+  unrelocated_addr low, high;
   struct die_info *child = die->child;
 
   if (dwarf2_get_pc_bounds (die, &low, &high, cu, nullptr, nullptr)
@@ -11218,12 +11231,12 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
 
 static void
 get_scope_pc_bounds (struct die_info *die,
-		     CORE_ADDR *lowpc, CORE_ADDR *highpc,
+		     unrelocated_addr *lowpc, unrelocated_addr *highpc,
 		     struct dwarf2_cu *cu)
 {
-  CORE_ADDR best_low = (CORE_ADDR) -1;
-  CORE_ADDR best_high = (CORE_ADDR) 0;
-  CORE_ADDR current_low, current_high;
+  unrelocated_addr best_low = (unrelocated_addr) -1;
+  unrelocated_addr best_high = {};
+  unrelocated_addr current_low, current_high;
 
   if (dwarf2_get_pc_bounds (die, &current_low, &current_high, cu,
 			    nullptr, nullptr)
@@ -11254,7 +11267,7 @@ get_scope_pc_bounds (struct die_info *die,
 	       standards says that they have to be there.  */
 	    get_scope_pc_bounds (child, &current_low, &current_high, cu);
 
-	    if (current_low != ((CORE_ADDR) -1))
+	    if (current_low != ((unrelocated_addr) -1))
 	      {
 		best_low = std::min (best_low, current_low);
 		best_high = std::max (best_high, current_high);
@@ -11280,9 +11293,8 @@ static void
 dwarf2_record_block_ranges (struct die_info *die, struct block *block,
 			    struct dwarf2_cu *cu)
 {
-  struct objfile *objfile = cu->per_objfile->objfile;
-  CORE_ADDR baseaddr = objfile->text_section_offset ();
-  struct gdbarch *gdbarch = objfile->arch ();
+  dwarf2_per_objfile *per_objfile = cu->per_objfile;
+  struct objfile *objfile = per_objfile->objfile;
   struct attribute *attr;
   struct attribute *attr_high;
 
@@ -11292,14 +11304,15 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
       attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr != nullptr)
 	{
-	  CORE_ADDR low = attr->as_address ();
-	  CORE_ADDR high = attr_high->as_address ();
+	  unrelocated_addr unrel_low = attr->as_address ();
+	  unrelocated_addr unrel_high = attr_high->as_address ();
 
 	  if (cu->header.version >= 4 && attr_high->form_is_constant ())
-	    high += low;
+	    unrel_high = (unrelocated_addr) ((ULONGEST) unrel_high
+					     + (ULONGEST) unrel_low);
 
-	  low = gdbarch_adjust_dwarf2_addr (gdbarch, low + baseaddr);
-	  high = gdbarch_adjust_dwarf2_addr (gdbarch, high + baseaddr);
+	  CORE_ADDR low = per_objfile->relocate (unrel_low);
+	  CORE_ADDR high = per_objfile->relocate (unrel_high);
 	  cu->get_builder ()->record_block_range (block, low, high - 1);
 	}
     }
@@ -11318,14 +11331,13 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
 
       std::vector<blockrange> blockvec;
       dwarf2_ranges_process (ranges_offset, cu, die->tag,
-	[&] (CORE_ADDR start, CORE_ADDR end)
+	[&] (unrelocated_addr start, unrelocated_addr end)
 	{
-	  start += baseaddr;
-	  end += baseaddr;
-	  start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
-	  end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
-	  cu->get_builder ()->record_block_range (block, start, end - 1);
-	  blockvec.emplace_back (start, end);
+	  CORE_ADDR abs_start = per_objfile->relocate (start);
+	  CORE_ADDR abs_end = per_objfile->relocate (end);
+	  cu->get_builder ()->record_block_range (block, abs_start,
+						  abs_end - 1);
+	  blockvec.emplace_back (abs_start, abs_end);
 	});
 
       block->set_ranges (make_blockranges (objfile, blockvec));
@@ -16023,7 +16035,7 @@ cooked_indexer::check_bounds (cutu_reader *reader)
 
   dwarf2_cu *cu = reader->cu;
 
-  CORE_ADDR best_lowpc = 0, best_highpc = 0;
+  unrelocated_addr best_lowpc = {}, best_highpc = {};
   /* Possibly set the default values of LOWPC and HIGHPC from
      `DW_AT_ranges'.  */
   dwarf2_find_base_address (reader->comp_unit_die, cu);
@@ -16032,18 +16044,15 @@ cooked_indexer::check_bounds (cutu_reader *reader)
 			    cu, m_index_storage->get_addrmap (), cu->per_cu);
   if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
     {
-      struct objfile *objfile = cu->per_objfile->objfile;
-      CORE_ADDR baseaddr = objfile->text_section_offset ();
-      struct gdbarch *gdbarch = objfile->arch ();
-      CORE_ADDR low
-	= (gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr)
-	   - baseaddr);
-      CORE_ADDR high
-	= (gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr)
-	   - baseaddr - 1);
+      dwarf2_per_objfile *per_objfile = cu->per_objfile;
+      unrelocated_addr low = per_objfile->adjust (best_lowpc);
+      unrelocated_addr high = per_objfile->adjust (best_highpc);
       /* Store the contiguous range if it is not empty; it can be
-	 empty for CUs with no code.  */
-      m_index_storage->get_addrmap ()->set_empty (low, high, cu->per_cu);
+	 empty for CUs with no code.  addrmap requires CORE_ADDR, so
+	 we cast here.  */
+      m_index_storage->get_addrmap ()->set_empty ((CORE_ADDR) low,
+						  (CORE_ADDR) high - 1,
+						  cu->per_cu);
 
       cu->per_cu->addresses_seen = true;
     }
@@ -16133,8 +16142,8 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
   bool is_declaration = false;
   sect_offset origin_offset {};
 
-  gdb::optional<CORE_ADDR> low_pc;
-  gdb::optional<CORE_ADDR> high_pc;
+  gdb::optional<unrelocated_addr> low_pc;
+  gdb::optional<unrelocated_addr> high_pc;
   bool high_pc_relative = false;
 
   for (int i = 0; i < abbrev->num_attrs; ++i)
@@ -16231,11 +16240,11 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
 	      if (addr != 0
 		  || reader->cu->per_objfile->per_bfd->has_section_at_zero)
 		{
-		  low_pc = addr;
+		  low_pc = (unrelocated_addr) addr;
 		  /* For variables, we don't want to try decoding the
 		     type just to find the size -- for gdb's purposes
 		     we only need the address of a variable.  */
-		  high_pc = addr + 1;
+		  high_pc = (unrelocated_addr) (addr + 1);
 		  high_pc_relative = false;
 		}
 	    }
@@ -16252,7 +16261,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
 		 want to add this value.  */
 	      ranges_offset += reader->cu->gnu_ranges_base;
 
-	      CORE_ADDR lowpc, highpc;
+	      unrelocated_addr lowpc, highpc;
 	      dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, reader->cu,
 				  m_index_storage->get_addrmap (),
 				  scanning_per_cu, abbrev->tag);
@@ -16326,24 +16335,21 @@ cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
       if (!scanning_per_cu->addresses_seen
 	  && low_pc.has_value ()
 	  && (reader->cu->per_objfile->per_bfd->has_section_at_zero
-	      || *low_pc != 0)
+	      || *low_pc != (unrelocated_addr) 0)
 	  && high_pc.has_value ())
 	{
 	  if (high_pc_relative)
-	    high_pc = *high_pc + *low_pc;
+	    high_pc = (unrelocated_addr) ((ULONGEST) *high_pc
+					  + (ULONGEST) *low_pc);
 
 	  if (*high_pc > *low_pc)
 	    {
-	      struct objfile *objfile = reader->cu->per_objfile->objfile;
-	      CORE_ADDR baseaddr = objfile->text_section_offset ();
-	      struct gdbarch *gdbarch = objfile->arch ();
-	      CORE_ADDR lo
-		= (gdbarch_adjust_dwarf2_addr (gdbarch, *low_pc + baseaddr)
-		   - baseaddr);
-	      CORE_ADDR hi
-		= (gdbarch_adjust_dwarf2_addr (gdbarch, *high_pc + baseaddr)
-		   - baseaddr);
-	      m_index_storage->get_addrmap ()->set_empty (lo, hi - 1,
+	      dwarf2_per_objfile *per_objfile = reader->cu->per_objfile;
+	      unrelocated_addr lo = per_objfile->adjust (*low_pc);
+	      unrelocated_addr hi = per_objfile->adjust (*high_pc);
+	      /* Need CORE_ADDR casts for addrmap.  */
+	      m_index_storage->get_addrmap ()->set_empty ((CORE_ADDR) lo,
+							  (CORE_ADDR) hi - 1,
 							  scanning_per_cu);
 	    }
 	}
@@ -17127,8 +17133,8 @@ read_attribute_value (const struct die_reader_specs *reader,
     {
     case DW_FORM_ref_addr:
       if (cu_header->version == 2)
-	attr->set_unsigned (cu_header->read_address (abfd, info_ptr,
-						     &bytes_read));
+	attr->set_unsigned ((ULONGEST) cu_header->read_address (abfd, info_ptr,
+								&bytes_read));
       else
 	attr->set_unsigned (cu_header->read_offset (abfd, info_ptr,
 						    &bytes_read));
@@ -17141,9 +17147,9 @@ read_attribute_value (const struct die_reader_specs *reader,
       break;
     case DW_FORM_addr:
       {
-	struct gdbarch *gdbarch = objfile->arch ();
-	CORE_ADDR addr = cu_header->read_address (abfd, info_ptr, &bytes_read);
-	addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr);
+	unrelocated_addr addr = cu_header->read_address (abfd, info_ptr,
+							 &bytes_read);
+	addr = per_objfile->adjust (addr);
 	attr->set_address (addr);
 	info_ptr += bytes_read;
       }
@@ -17464,7 +17470,7 @@ dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
    ADDR_BASE is the DW_AT_addr_base (DW_AT_GNU_addr_base) attribute or zero.
    ADDR_SIZE is the size of addresses from the CU header.  */
 
-static CORE_ADDR
+static unrelocated_addr
 read_addr_index_1 (dwarf2_per_objfile *per_objfile, unsigned int addr_index,
 		   gdb::optional<ULONGEST> addr_base, int addr_size)
 {
@@ -17485,14 +17491,14 @@ read_addr_index_1 (dwarf2_per_objfile *per_objfile, unsigned int addr_index,
   info_ptr = (per_objfile->per_bfd->addr.buffer + addr_base_or_zero
 	      + addr_index * addr_size);
   if (addr_size == 4)
-    return bfd_get_32 (abfd, info_ptr);
+    return (unrelocated_addr) bfd_get_32 (abfd, info_ptr);
   else
-    return bfd_get_64 (abfd, info_ptr);
+    return (unrelocated_addr) bfd_get_64 (abfd, info_ptr);
 }
 
 /* Given index ADDR_INDEX in .debug_addr, fetch the value.  */
 
-static CORE_ADDR
+static unrelocated_addr
 read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
 {
   return read_addr_index_1 (cu->per_objfile, addr_index,
@@ -17501,7 +17507,7 @@ read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
 
 /* Given a pointer to an leb128 value, fetch the value from .debug_addr.  */
 
-static CORE_ADDR
+static unrelocated_addr
 read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
 			     unsigned int *bytes_read)
 {
@@ -17513,7 +17519,7 @@ read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
 
 /* See read.h.  */
 
-CORE_ADDR
+unrelocated_addr
 dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
 			dwarf2_per_objfile *per_objfile,
 			unsigned int addr_index)
@@ -18024,7 +18030,8 @@ class lnp_state_machine
      nop-out rest of the lines in this sequence.  */
   void check_line_address (struct dwarf2_cu *cu,
 			   const gdb_byte *line_ptr,
-			   CORE_ADDR unrelocated_lowpc, CORE_ADDR address);
+			   unrelocated_addr unrelocated_lowpc,
+			   unrelocated_addr address);
 
   void handle_set_discriminator (unsigned int discriminator)
   {
@@ -18033,10 +18040,13 @@ class lnp_state_machine
   }
 
   /* Handle DW_LNE_set_address.  */
-  void handle_set_address (CORE_ADDR address)
+  void handle_set_address (unrelocated_addr address)
   {
     m_op_index = 0;
-    m_address = gdbarch_adjust_dwarf2_line (m_gdbarch, address, false);
+    m_address
+      = (unrelocated_addr) gdbarch_adjust_dwarf2_line (m_gdbarch,
+						       (CORE_ADDR) address,
+						       false);
   }
 
   /* Handle DW_LNS_advance_pc.  */
@@ -18066,7 +18076,8 @@ class lnp_state_machine
   /* Handle DW_LNS_fixed_advance_pc.  */
   void handle_fixed_advance_pc (CORE_ADDR addr_adj)
   {
-    m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+    addr_adj = gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+    m_address = (unrelocated_addr) ((CORE_ADDR) m_address + addr_adj);
     m_op_index = 0;
   }
 
@@ -18117,7 +18128,7 @@ class lnp_state_machine
 
   /* These are initialized in the constructor.  */
 
-  CORE_ADDR m_address;
+  unrelocated_addr m_address;
   linetable_entry_flags m_flags;
   unsigned int m_discriminator = 0;
 
@@ -18130,7 +18141,7 @@ class lnp_state_machine
   struct subfile *m_last_subfile = NULL;
 
   /* The address of the last line entry.  */
-  CORE_ADDR m_last_address;
+  unrelocated_addr m_last_address;
 
   /* Set to true when a previous line at the same address (using
      m_last_address) had LEF_IS_STMT set in m_flags.  This is reset to false
@@ -18154,7 +18165,8 @@ lnp_state_machine::handle_advance_pc (CORE_ADDR adjust)
   CORE_ADDR addr_adj = (((m_op_index + adjust)
 			 / m_line_header->maximum_ops_per_instruction)
 			* m_line_header->minimum_instruction_length);
-  m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+  addr_adj = gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+  m_address = (unrelocated_addr) ((CORE_ADDR) m_address + addr_adj);
   m_op_index = ((m_op_index + adjust)
 		% m_line_header->maximum_ops_per_instruction);
 }
@@ -18168,7 +18180,8 @@ lnp_state_machine::handle_special_opcode (unsigned char op_code)
   CORE_ADDR addr_adj = (((m_op_index + adj_opcode_d)
 			 / m_line_header->maximum_ops_per_instruction)
 			* m_line_header->minimum_instruction_length);
-  m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+  addr_adj = gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+  m_address = (unrelocated_addr) ((CORE_ADDR) m_address + addr_adj);
   m_op_index = ((m_op_index + adj_opcode_d)
 		% m_line_header->maximum_ops_per_instruction);
 
@@ -18206,7 +18219,8 @@ lnp_state_machine::handle_const_add_pc ()
 	/ m_line_header->maximum_ops_per_instruction)
        * m_line_header->minimum_instruction_length);
 
-  m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+  addr_adj = gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+  m_address = (unrelocated_addr) ((CORE_ADDR) m_address + addr_adj);
   m_op_index = ((m_op_index + adjust)
 		% m_line_header->maximum_ops_per_instruction);
 }
@@ -18264,19 +18278,20 @@ dwarf_record_line_p (struct dwarf2_cu *cu,
 
 static void
 dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
-		     unsigned int line, CORE_ADDR address,
+		     unsigned int line, unrelocated_addr address,
 		     linetable_entry_flags flags,
 		     struct dwarf2_cu *cu)
 {
   unrelocated_addr addr
-    = unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, address));
+    = unrelocated_addr (gdbarch_addr_bits_remove (gdbarch,
+						  (CORE_ADDR) address));
 
   if (dwarf_line_debug)
     {
       gdb_printf (gdb_stdlog,
 		  "Recording line %u, file %s, address %s\n",
 		  line, lbasename (subfile->name.c_str ()),
-		  paddress (gdbarch, address));
+		  paddress (gdbarch, (CORE_ADDR) address));
     }
 
   if (cu != nullptr)
@@ -18290,7 +18305,7 @@ dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
 
 static void
 dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
-		   CORE_ADDR address, struct dwarf2_cu *cu)
+		   unrelocated_addr address, struct dwarf2_cu *cu)
 {
   if (subfile == NULL)
     return;
@@ -18300,7 +18315,7 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
       gdb_printf (gdb_stdlog,
 		  "Finishing current line, file %s, address %s\n",
 		  lbasename (subfile->name.c_str ()),
-		  paddress (gdbarch, address));
+		  paddress (gdbarch, (CORE_ADDR) address));
     }
 
   dwarf_record_line_1 (gdbarch, subfile, 0, address, LEF_IS_STMT, cu);
@@ -18315,7 +18330,7 @@ lnp_state_machine::record_line (bool end_sequence)
 		  "Processing actual line %u: file %u,"
 		  " address %s, is_stmt %u, prologue_end %u, discrim %u%s\n",
 		  m_line, m_file,
-		  paddress (m_gdbarch, m_address),
+		  paddress (m_gdbarch, (CORE_ADDR) m_address),
 		  (m_flags & LEF_IS_STMT) != 0,
 		  (m_flags & LEF_PROLOGUE_END) != 0,
 		  m_discriminator,
@@ -18401,7 +18416,7 @@ lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
        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'.  */
-    m_address (gdbarch_adjust_dwarf2_line (arch, 0, 0)),
+    m_address ((unrelocated_addr) gdbarch_adjust_dwarf2_line (arch, 0, 0)),
     m_flags (lh->default_is_stmt ? LEF_IS_STMT : (linetable_entry_flags) 0),
     m_last_address (m_address)
 {
@@ -18410,15 +18425,16 @@ lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
 void
 lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
 				       const gdb_byte *line_ptr,
-				       CORE_ADDR unrelocated_lowpc, CORE_ADDR address)
+				       unrelocated_addr unrelocated_lowpc,
+				       unrelocated_addr address)
 {
   /* Linkers resolve a symbolic relocation referencing a GC'd function to 0 or
      -1.  If ADDRESS is 0, ignoring the opcode will err if the text section is
      located at 0x0.  In this case, additionally check that if
      ADDRESS < UNRELOCATED_LOWPC.  */
 
-  if ((address == 0 && address < unrelocated_lowpc)
-      || address == (CORE_ADDR) -1)
+  if ((address == (unrelocated_addr) 0 && address < unrelocated_lowpc)
+      || address == (unrelocated_addr) -1)
     {
       /* This line table is for a function which has been
 	 GCd by the linker.  Ignore it.  PR gdb/12528 */
@@ -18505,12 +18521,13 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 		  break;
 		case DW_LNE_set_address:
 		  {
-		    CORE_ADDR address
+		    unrelocated_addr address
 		      = cu->header.read_address (abfd, line_ptr, &bytes_read);
 		    line_ptr += bytes_read;
 
-		    state_machine.check_line_address (cu, line_ptr,
-						      lowpc - baseaddr, address);
+		    state_machine.check_line_address
+		      (cu, line_ptr, (unrelocated_addr) (lowpc - baseaddr),
+		       address);
 		    state_machine.handle_set_address (address);
 		  }
 		  break;
@@ -18782,13 +18799,14 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
 	{
 	  unsigned int dummy;
 
+	  unrelocated_addr tem;
 	  if (block->data[0] == DW_OP_addr)
-	    sym->set_value_address
-	      (cu->header.read_address (objfile->obfd.get (), block->data + 1,
-					&dummy));
+	    tem = cu->header.read_address (objfile->obfd.get (),
+					   block->data + 1,
+					   &dummy);
 	  else
-	    sym->set_value_address
-	      (read_addr_index_from_leb128 (cu, block->data + 1, &dummy));
+	    tem = read_addr_index_from_leb128 (cu, block->data + 1, &dummy);
+	  sym->set_value_address ((CORE_ADDR) tem);
 	  sym->set_aclass_index (LOC_STATIC);
 	  fixup_symbol_section (sym, objfile);
 	  sym->set_value_address
@@ -18825,18 +18843,14 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
   struct objfile *objfile = per_objfile->objfile;
-  struct gdbarch *gdbarch = objfile->arch ();
   struct symbol *sym = NULL;
   const char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
-  CORE_ADDR baseaddr;
   struct pending **list_to_add = NULL;
 
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
 
-  baseaddr = objfile->text_section_offset ();
-
   name = dwarf2_name (die, cu);
   if (name == nullptr && (die->tag == DW_TAG_subprogram
 			  || die->tag == DW_TAG_inlined_subroutine
@@ -18916,10 +18930,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  attr = dwarf2_attr (die, DW_AT_low_pc, cu);
 	  if (attr != nullptr)
 	    {
-	      CORE_ADDR addr;
-
-	      addr = attr->as_address ();
-	      addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr);
+	      CORE_ADDR addr = per_objfile->relocate (attr->as_address ());
 	      sym->set_section_index (SECT_OFF_TEXT (objfile));
 	      sym->set_value_address (addr);
 	      sym->set_aclass_index (LOC_LABEL);
@@ -19329,7 +19340,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
 
 	data[0] = DW_OP_addr;
 	store_unsigned_integer (&data[1], cu_header->addr_size,
-				byte_order, attr->as_address ());
+				byte_order, (ULONGEST) attr->as_address ());
 	data[cu_header->addr_size + 1] = DW_OP_stack_value;
       }
       break;
@@ -20398,8 +20409,6 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 	  != per_objfile->per_bfd->abstract_to_concrete.end ()))
     {
       CORE_ADDR pc = get_frame_pc ();
-      CORE_ADDR baseaddr = objfile->text_section_offset ();
-      struct gdbarch *gdbarch = objfile->arch ();
 
       for (const auto &cand_off
 	     : per_objfile->per_bfd->abstract_to_concrete[die->sect_off])
@@ -20412,12 +20421,12 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
 	      || cand->parent->tag != DW_TAG_subprogram)
 	    continue;
 
-	  CORE_ADDR pc_low, pc_high;
-	  get_scope_pc_bounds (cand->parent, &pc_low, &pc_high, cu);
-	  if (pc_low == ((CORE_ADDR) -1))
+	  unrelocated_addr unrel_low, unrel_high;
+	  get_scope_pc_bounds (cand->parent, &unrel_low, &unrel_high, cu);
+	  if (unrel_low == ((unrelocated_addr) -1))
 	    continue;
-	  pc_low = gdbarch_adjust_dwarf2_addr (gdbarch, pc_low + baseaddr);
-	  pc_high = gdbarch_adjust_dwarf2_addr (gdbarch, pc_high + baseaddr);
+	  CORE_ADDR pc_low = per_objfile->relocate (unrel_low);
+	  CORE_ADDR pc_high = per_objfile->relocate (unrel_high);
 	  if (!(pc_low <= pc && pc < pc_high))
 	    continue;
 
@@ -20550,7 +20559,8 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
 
 	*len = cu->header.addr_size;
 	tem = (gdb_byte *) obstack_alloc (obstack, *len);
-	store_unsigned_integer (tem, *len, byte_order, attr->as_address ());
+	store_unsigned_integer (tem, *len, byte_order,
+				(ULONGEST) attr->as_address ());
 	result = tem;
       }
       break;
@@ -21049,9 +21059,10 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
 	  break;
 
 	case DW_OP_addr:
-	  stack[++stacki] = cu->header.read_address (objfile->obfd.get (),
-						     &data[i],
-						     &bytes_read);
+	  stack[++stacki]
+	    = (CORE_ADDR) cu->header.read_address (objfile->obfd.get (),
+						   &data[i],
+						   &bytes_read);
 	  i += bytes_read;
 	  break;
 
@@ -21164,8 +21175,9 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
 	case DW_OP_addrx:
 	case DW_OP_GNU_addr_index:
 	case DW_OP_GNU_const_index:
-	  stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
-							 &bytes_read);
+	  stack[++stacki]
+	    = (CORE_ADDR) read_addr_index_from_leb128 (cu, &data[i],
+						       &bytes_read);
 	  i += bytes_read;
 	  break;
 
@@ -21360,7 +21372,7 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
   if (cu->base_address.has_value ())
     baton->base_address = *cu->base_address;
   else
-    baton->base_address = 0;
+    baton->base_address = {};
   baton->from_dwo = cu->dwo_unit != NULL;
 }
 
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 37023a20709..a99299cbc6d 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -711,6 +711,15 @@ struct dwarf2_per_objfile
      any that are too old.  */
   void age_comp_units ();
 
+  /* Apply any needed adjustments to ADDR, returning an adjusted but
+     still unrelocated address.  */
+  unrelocated_addr adjust (unrelocated_addr addr);
+
+  /* Apply any needed adjustments to ADDR and then relocate the
+     address according to the objfile's section offsets, returning a
+     relocated address.  */
+  CORE_ADDR relocate (unrelocated_addr addr);
+
   /* Back link.  */
   struct objfile *objfile;
 
@@ -771,9 +780,9 @@ struct type *dwarf2_get_die_type (cu_offset die_offset,
    long after the debug information has been read, and thus per_cu->cu
    may no longer exist.  */
 
-CORE_ADDR dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
-				  dwarf2_per_objfile *per_objfile,
-				  unsigned int addr_index);
+unrelocated_addr dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
+					 dwarf2_per_objfile *per_objfile,
+					 unsigned int addr_index);
 
 /* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
    Returned value is intended for DW_OP_call*.  Returned
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 6af59351b76..093214db9b8 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -6153,8 +6153,7 @@ builtin_type (struct objfile *objfile)
 CORE_ADDR
 call_site::pc () const
 {
-  CORE_ADDR delta = this->per_objfile->objfile->text_section_offset ();
-  return m_unrelocated_pc + delta;
+  return per_objfile->relocate (m_unrelocated_pc);
 }
 
 void _initialize_gdbtypes ();
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 27611a34ec4..25e5825d42b 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -344,7 +344,7 @@ compunit_symtab::find_call_site (CORE_ADDR pc) const
     return nullptr;
 
   CORE_ADDR delta = this->objfile ()->text_section_offset ();
-  CORE_ADDR unrelocated_pc = pc - delta;
+  unrelocated_addr unrelocated_pc = (unrelocated_addr) (pc - delta);
 
   struct call_site call_site_local (unrelocated_pc, nullptr, nullptr);
   void **slot
@@ -360,7 +360,8 @@ compunit_symtab::find_call_site (CORE_ADDR pc) const
   if (pc == new_pc)
     return nullptr;
 
-  call_site new_call_site_local (new_pc - delta, nullptr, nullptr);
+  unrelocated_pc = (unrelocated_addr) (new_pc - delta);
+  call_site new_call_site_local (unrelocated_pc, nullptr, nullptr);
   slot = htab_find_slot (m_call_site_htab, &new_call_site_local, NO_INSERT);
   if (slot == nullptr)
     return nullptr;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 05/10] Use unrelocated_addr in dwarf_decode_lines
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (3 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 04/10] Use unrelocated_addr in the DWARF reader Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 06/10] Fix comment in address_class Tom Tromey
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes dwarf_decode_lines to accept an unrelocated_addr and
fixes up the fallout.
---
 gdb/dwarf2/read.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 39e4f05b389..6b3018831d1 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -809,7 +809,7 @@ static line_header_up dwarf_decode_line_header (sect_offset sect_off,
 
 static void dwarf_decode_lines (struct line_header *,
 				struct dwarf2_cu *,
-				CORE_ADDR, int decode_mapping);
+				unrelocated_addr, int decode_mapping);
 
 static void dwarf2_start_subfile (dwarf2_cu *cu, const file_entry &fe,
 				  const line_header &lh);
@@ -7537,7 +7537,7 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
 
 static void
 handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
-			const file_and_directory &fnd, CORE_ADDR lowpc,
+			const file_and_directory &fnd, unrelocated_addr lowpc,
 			bool have_code) /* ARI: editCase function */
 {
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
@@ -7666,7 +7666,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   /* Decode line number information if present.  We do this before
      processing child DIEs, so that the line header table is available
      for DW_AT_decl_file.  */
-  handle_DW_AT_stmt_list (die, cu, fnd, lowpc, unrel_low != unrel_high);
+  handle_DW_AT_stmt_list (die, cu, fnd, unrel_low, unrel_low != unrel_high);
 
   /* Process all dies in compilation unit.  */
   if (die->child != NULL)
@@ -18455,19 +18455,16 @@ lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
 
 static void
 dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
-		      CORE_ADDR lowpc)
+		      unrelocated_addr lowpc)
 {
   const gdb_byte *line_ptr, *extended_end;
   const gdb_byte *line_end;
   unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op;
-  CORE_ADDR baseaddr;
   struct objfile *objfile = cu->per_objfile->objfile;
   bfd *abfd = objfile->obfd.get ();
   struct gdbarch *gdbarch = objfile->arch ();
 
-  baseaddr = objfile->text_section_offset ();
-
   line_ptr = lh->statement_program_start;
   line_end = lh->statement_program_end;
 
@@ -18525,9 +18522,8 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 		      = cu->header.read_address (abfd, line_ptr, &bytes_read);
 		    line_ptr += bytes_read;
 
-		    state_machine.check_line_address
-		      (cu, line_ptr, (unrelocated_addr) (lowpc - baseaddr),
-		       address);
+		    state_machine.check_line_address (cu, line_ptr, lowpc,
+						      address);
 		    state_machine.handle_set_address (address);
 		  }
 		  break;
@@ -18684,7 +18680,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 
 static void
 dwarf_decode_lines (struct line_header *lh, struct dwarf2_cu *cu,
-		    CORE_ADDR lowpc, int decode_mapping)
+		    unrelocated_addr lowpc, int decode_mapping)
 {
   if (decode_mapping)
     dwarf_decode_lines_1 (lh, cu, lowpc);
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 06/10] Fix comment in address_class
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (4 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 05/10] Use unrelocated_addr in dwarf_decode_lines Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 07/10] Use "unrelocated" terminology in linetable_entry Tom Tromey
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

enum address_class has a stale comment referring to
MSYMBOL_VALUE_RAW_ADDRESS, which no longer exists.  This patch updates
the comment.
---
 gdb/symtab.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gdb/symtab.h b/gdb/symtab.h
index 495e7522e25..600f2e47cec 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1047,11 +1047,11 @@ enum address_class
      without possibly having its address available for LOC_STATIC.  Testcase
      is provided as `gdb.dwarf2/dw2-unresolved.exp'.
 
-     This is also used for thread local storage (TLS) variables.  In this case,
-     the address of the TLS variable must be determined when the variable is
-     referenced, from the MSYMBOL_VALUE_RAW_ADDRESS, which is the offset
-     of the TLS variable in the thread local storage of the shared
-     library/object.  */
+     This is also used for thread local storage (TLS) variables.  In
+     this case, the address of the TLS variable must be determined
+     when the variable is referenced, from the msymbol's address,
+     which is the offset of the TLS variable in the thread local
+     storage of the shared library/object.  */
 
   LOC_UNRESOLVED,
 
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 07/10] Use "unrelocated" terminology in linetable_entry
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (5 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 06/10] Fix comment in address_class Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 08/10] Constify dwarf2_cie::augmentation Tom Tromey
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

I forgot to convert struct linetable_entry to use the "unrelocated"
(as opposed to "raw") terminology.  This patch corrects the oversight.
---
 gdb/buildsym.c      |  4 ++--
 gdb/disasm.c        | 10 +++++-----
 gdb/jit.c           |  3 ++-
 gdb/mdebugread.c    |  2 +-
 gdb/record-btrace.c |  2 +-
 gdb/symmisc.c       |  2 +-
 gdb/symtab.c        | 17 ++++++++++-------
 gdb/symtab.h        |  6 ++++--
 gdb/xcoffread.c     |  5 +++--
 9 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index f000233dafa..4a711a9cf22 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->raw_pc () != pc)
+	  if (last->unrelocated_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.set_raw_pc (pc);
+  e.set_unrelocated_pc (pc);
   e.prologue_end = (flags & LEF_PROLOGUE_END) != 0;
 }
 
diff --git a/gdb/disasm.c b/gdb/disasm.c
index 03cd4b7ee02..05397abc3fd 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -606,11 +606,11 @@ do_mixed_source_and_assembly_deprecated
 
   /* First, skip all the preceding functions.  */
 
-  for (i = 0; i < nlines - 1 && le[i].raw_pc () < unrel_low; i++);
+  for (i = 0; i < nlines - 1 && le[i].unrelocated_pc () < unrel_low; i++);
 
   /* Now, copy all entries before the end of this function.  */
 
-  for (; i < nlines - 1 && le[i].raw_pc () < unrel_high; i++)
+  for (; i < nlines - 1 && le[i].unrelocated_pc () < unrel_high; i++)
     {
       if (le[i] == le[i + 1])
 	continue;		/* Ignore duplicates.  */
@@ -630,7 +630,7 @@ do_mixed_source_and_assembly_deprecated
   /* 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].raw_pc () < unrel_high)
+  if (i == nlines - 1 && le[i].unrelocated_pc () < unrel_high)
     {
       mle[newlines].line = le[i].line;
       mle[newlines].start_pc = le[i].pc (objfile);
@@ -761,10 +761,10 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch,
   first_le = NULL;
 
   /* Skip all the preceding functions.  */
-  for (i = 0; i < nlines && le[i].raw_pc () < unrel_low; i++)
+  for (i = 0; i < nlines && le[i].unrelocated_pc () < unrel_low; i++)
     continue;
 
-  if (i < nlines && le[i].raw_pc () < unrel_high)
+  if (i < nlines && le[i].unrelocated_pc () < unrel_high)
     first_le = &le[i];
 
   /* Add lines for every pc value.  */
diff --git a/gdb/jit.c b/gdb/jit.c
index e085d562333..41f8e992b4a 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -491,7 +491,8 @@ 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].set_raw_pc (unrelocated_addr (map[i].pc));
+      stab->linetable->item[i].set_unrelocated_pc
+	(unrelocated_addr (map[i].pc));
       stab->linetable->item[i].line = map[i].line;
       stab->linetable->item[i].is_stmt = true;
     }
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index 697ce0b5b1a..673767fbdee 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -4546,7 +4546,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++].set_raw_pc (unrelocated_addr (adr << 2));
+  lt->item[lt->nitems++].set_unrelocated_pc (unrelocated_addr (adr << 2));
   return lineno;
 }
 \f
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 9dd8474673b..dd2fc790847 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -738,7 +738,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].raw_pc () == unrel_pc && lines[i].line != 0
+      if (lines[i].unrelocated_pc () == unrel_pc && lines[i].line != 0
 	  && lines[i].is_stmt)
 	range = btrace_line_range_add (range, lines[i].line);
     }
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 4b68f2b1f6f..e25bf032185 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -998,7 +998,7 @@ maintenance_print_one_line_table (struct symtab *symtab, void *data)
 	  uiout->field_core_addr ("rel-address", objfile->arch (),
 				  item->pc (objfile));
 	  uiout->field_core_addr ("unrel-address", objfile->arch (),
-				  CORE_ADDR (item->raw_pc ()));
+				  CORE_ADDR (item->unrelocated_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 25e5825d42b..c367c055c05 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3166,13 +3166,13 @@ 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 (objfile) > pc
-	  && (!alt || item->raw_pc () < alt->raw_pc ()))
+	  && (!alt || item->unrelocated_pc () < alt->unrelocated_pc ()))
 	alt = item;
 
       auto pc_compare = [] (const unrelocated_addr &comp_pc,
 			    const struct linetable_entry & lhs)
       {
-	return comp_pc < lhs.raw_pc ();
+	return comp_pc < lhs.unrelocated_pc ();
       };
 
       const linetable_entry *first = item;
@@ -3194,7 +3194,8 @@ 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->raw_pc () > best->raw_pc ()))
+      if (prev && prev->line
+	  && (!best || prev->unrelocated_pc () > best->unrelocated_pc ()))
 	{
 	  best = prev;
 	  best_symtab = iter_s;
@@ -3209,7 +3210,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 	  if (!best->is_stmt)
 	    {
 	      const linetable_entry *tmp = best;
-	      while (tmp > first && (tmp - 1)->raw_pc () == tmp->raw_pc ()
+	      while (tmp > first
+		     && (tmp - 1)->unrelocated_pc () == tmp->unrelocated_pc ()
 		     && (tmp - 1)->line != 0 && !tmp->is_stmt)
 		--tmp;
 	      if (tmp->is_stmt)
@@ -3224,7 +3226,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       /* 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->raw_pc () > best->raw_pc ()
+      if (best && item < last
+	  && item->unrelocated_pc () > best->unrelocated_pc ()
 	  && (best_end == 0 || best_end > item->pc (objfile)))
 	best_end = item->pc (objfile);
     }
@@ -3711,12 +3714,12 @@ skip_prologue_using_linetable (CORE_ADDR func_addr)
 	(linetable->item, linetable->item + linetable->nitems, unrel_start,
 	 [] (const linetable_entry &lte, unrelocated_addr pc)
 	 {
-	   return lte.raw_pc () < pc;
+	   return lte.unrelocated_pc () < pc;
 	 });
 
       for (;
 	   (it < linetable->item + linetable->nitems
-	    && it->raw_pc () < unrel_end);
+	    && it->unrelocated_pc () < unrel_end);
 	   it++)
 	if (it->prologue_end)
 	  return {it->pc (objfile)};
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 600f2e47cec..d6b28c4eece 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1571,11 +1571,11 @@ struct rust_vtable_symbol : public symbol
 struct linetable_entry
 {
   /* Set the (unrelocated) PC for this entry.  */
-  void set_raw_pc (unrelocated_addr pc)
+  void set_unrelocated_pc (unrelocated_addr pc)
   { m_pc = pc; }
 
   /* Return the unrelocated PC for this entry.  */
-  unrelocated_addr raw_pc () const
+  unrelocated_addr unrelocated_pc () const
   { return m_pc; }
 
   /* Return the relocated PC for this entry.  */
@@ -1604,6 +1604,8 @@ struct linetable_entry
      function prologue.  */
   bool prologue_end : 1;
 
+private:
+
   /* The address for this entry.  */
   unrelocated_addr m_pc;
 };
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index d71127b40f6..0631d18459e 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 = true;
-	  e.set_raw_pc (old_linetable[ii].raw_pc ());
+	  e.set_unrelocated_pc (old_linetable[ii].unrelocated_pc ());
 	}
     }
 
@@ -457,7 +457,8 @@ 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].raw_pc () != old_linetable[jj + 1].raw_pc ())
+	  && (old_linetable[jj].unrelocated_pc ()
+	      != old_linetable[jj + 1].unrelocated_pc ()))
 	{
 	  new_linetable.push_back (old_linetable[jj]);
 	  new_linetable.back ().line = old_linetable[jj + 1].line;
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 08/10] Constify dwarf2_cie::augmentation
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (6 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 07/10] Use "unrelocated" terminology in linetable_entry Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 09/10] Use local "text offset" variable in dwarf2_frame_cache Tom Tromey
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

I noticed that dwarf2_cie::augmentation could be 'const'.
---
 gdb/dwarf2/frame.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index a561aaf3100..8f8add201f4 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -80,7 +80,7 @@ struct dwarf2_cie
   const gdb_byte *end;
 
   /* Saved augmentation, in case it's needed later.  */
-  char *augmentation;
+  const char *augmentation;
 
   /* Encoding of addresses.  */
   gdb_byte encoding;
@@ -1746,7 +1746,7 @@ decode_frame_entry_1 (struct gdbarch *gdbarch,
     {
       /* This is a CIE.  */
       struct dwarf2_cie *cie;
-      char *augmentation;
+      const char *augmentation;
       unsigned int cie_version;
 
       /* Check that a CIE was expected.  */
@@ -1780,7 +1780,7 @@ decode_frame_entry_1 (struct gdbarch *gdbarch,
       buf += 1;
 
       /* Interpret the interesting bits of the augmentation.  */
-      cie->augmentation = augmentation = (char *) buf;
+      cie->augmentation = augmentation = (const char *) buf;
       buf += (strlen (augmentation) + 1);
 
       /* Ignore armcc augmentations.  We only use them for quirks,
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 09/10] Use local "text offset" variable in dwarf2_frame_cache
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (7 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 08/10] Constify dwarf2_cie::augmentation Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-04-24 16:22 ` [RFC 10/10] Use unrelocated_addr in dwarf2_fde Tom Tromey
  2023-06-05 16:13 ` [RFC 00/10] More use of unrelocated_addr Tom Tromey
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

A few spots in dwarf2_frame_cache use:

    cache->per_objfile->objfile->text_section_offset ()

... and a subsequent patch will add more, so move this into a local
variable.
---
 gdb/dwarf2/frame.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 8f8add201f4..705e2a7eeb9 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -922,6 +922,8 @@ dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache)
   gdb_assert (fde != NULL);
   gdb_assert (cache->per_objfile != nullptr);
 
+  CORE_ADDR text_offset = cache->per_objfile->objfile->text_section_offset ();
+
   /* Allocate and initialize the frame state.  */
   struct dwarf2_frame_state fs (pc1, fde->cie);
 
@@ -934,7 +936,7 @@ dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache)
   execute_cfa_program (fde, fde->cie->initial_instructions,
 		       fde->cie->end, gdbarch,
 		       get_frame_address_in_block (this_frame), &fs,
-		       cache->per_objfile->objfile->text_section_offset ());
+		       text_offset);
 
   /* Save the initialized register set.  */
   fs.initial = fs.regs;
@@ -950,9 +952,8 @@ dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache)
       && entry_pc < fde->initial_location + fde->address_range)
     {
       /* Decode the insns in the FDE up to the entry PC.  */
-      instr = execute_cfa_program
-	(fde, fde->instructions, fde->end, gdbarch, entry_pc, &fs,
-	 cache->per_objfile->objfile->text_section_offset ());
+      instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
+				   entry_pc, &fs, text_offset);
 
       if (fs.regs.cfa_how == CFA_REG_OFFSET
 	  && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg)
@@ -968,7 +969,7 @@ dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache)
   /* Then decode the insns in the FDE up to our target PC.  */
   execute_cfa_program (fde, instr, fde->end, gdbarch,
 		       get_frame_address_in_block (this_frame), &fs,
-		       cache->per_objfile->objfile->text_section_offset ());
+		       text_offset);
 
   try
     {
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [RFC 10/10] Use unrelocated_addr in dwarf2_fde
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (8 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 09/10] Use local "text offset" variable in dwarf2_frame_cache Tom Tromey
@ 2023-04-24 16:22 ` Tom Tromey
  2023-06-05 16:13 ` [RFC 00/10] More use of unrelocated_addr Tom Tromey
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-04-24 16:22 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

This changes dwarf2_fde to use the unrelocated_addr type.  This
pointed out a latent bug in dwarf2_frame_cache, where a relocated
address is compared to an unrelocated address.
---
 gdb/dwarf2/frame.c | 71 +++++++++++++++++++++++++---------------------
 1 file changed, 39 insertions(+), 32 deletions(-)

diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index 705e2a7eeb9..940a01e9612 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -112,14 +112,21 @@ typedef std::unordered_map<ULONGEST, dwarf2_cie *> dwarf2_cie_table;
 
 struct dwarf2_fde
 {
+  /* Return the final location in this FDE.  */
+  unrelocated_addr end_addr () const
+  {
+    return (unrelocated_addr) ((ULONGEST) initial_location
+			       + address_range);
+  }
+
   /* CIE for this FDE.  */
   struct dwarf2_cie *cie;
 
   /* First location associated with this FDE.  */
-  CORE_ADDR initial_location;
+  unrelocated_addr initial_location;
 
   /* Number of bytes of program instructions described by this FDE.  */
-  CORE_ADDR address_range;
+  ULONGEST address_range;
 
   /* Instruction sequence.  */
   const gdb_byte *instructions;
@@ -173,10 +180,10 @@ static struct dwarf2_fde *dwarf2_frame_find_fde
 static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
 				       int eh_frame_p);
 
-static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
-				     int ptr_len, const gdb_byte *buf,
-				     unsigned int *bytes_read_ptr,
-				     CORE_ADDR func_base);
+static ULONGEST read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
+				    int ptr_len, const gdb_byte *buf,
+				    unsigned int *bytes_read_ptr,
+				    unrelocated_addr func_base);
 \f
 
 /* See dwarf2/frame.h.  */
@@ -948,8 +955,8 @@ dwarf2_frame_cache (frame_info_ptr this_frame, void **this_cache)
   LONGEST entry_cfa_sp_offset;
   int entry_cfa_sp_offset_p = 0;
   if (get_frame_func_if_available (this_frame, &entry_pc)
-      && fde->initial_location <= entry_pc
-      && entry_pc < fde->initial_location + fde->address_range)
+      && fde->initial_location <= (unrelocated_addr) (entry_pc - text_offset)
+      && (unrelocated_addr) (entry_pc - text_offset) < fde->end_addr ())
     {
       /* Decode the insns in the FDE up to the entry PC.  */
       instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
@@ -1469,14 +1476,14 @@ encoding_for_size (unsigned int size)
     }
 }
 
-static CORE_ADDR
+static ULONGEST
 read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
 		    int ptr_len, const gdb_byte *buf,
 		    unsigned int *bytes_read_ptr,
-		    CORE_ADDR func_base)
+		    unrelocated_addr func_base)
 {
   ptrdiff_t offset;
-  CORE_ADDR base;
+  ULONGEST base;
 
   /* GCC currently doesn't generate DW_EH_PE_indirect encodings for
      FDE's.  */
@@ -1501,7 +1508,7 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
       base = unit->tbase;
       break;
     case DW_EH_PE_funcrel:
-      base = func_base;
+      base = (ULONGEST) func_base;
       break;
     case DW_EH_PE_aligned:
       base = 0;
@@ -1576,9 +1583,9 @@ find_cie (const dwarf2_cie_table &cie_table, ULONGEST cie_pointer)
 }
 
 static inline int
-bsearch_fde_cmp (const dwarf2_fde *fde, CORE_ADDR seek_pc)
+bsearch_fde_cmp (const dwarf2_fde *fde, unrelocated_addr seek_pc)
 {
-  if (fde->initial_location + fde->address_range <= seek_pc)
+  if (fde->end_addr () <= seek_pc)
     return -1;
   if (fde->initial_location <= seek_pc)
     return 0;
@@ -1619,7 +1626,6 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile)
   for (objfile *objfile : current_program_space->objfiles ())
     {
       CORE_ADDR offset;
-      CORE_ADDR seek_pc;
 
       if (objfile->obfd == nullptr)
 	continue;
@@ -1640,15 +1646,15 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile)
       offset = objfile->text_section_offset ();
 
       gdb_assert (!fde_table->empty ());
-      if (*pc < offset + (*fde_table)[0]->initial_location)
+      unrelocated_addr seek_pc = (unrelocated_addr) (*pc - offset);
+      if (seek_pc < (*fde_table)[0]->initial_location)
 	continue;
 
-      seek_pc = *pc - offset;
       auto it = gdb::binary_search (fde_table->begin (), fde_table->end (),
 				    seek_pc, bsearch_fde_cmp);
       if (it != fde_table->end ())
 	{
-	  *pc = (*it)->initial_location + offset;
+	  *pc = (CORE_ADDR) (*it)->initial_location + offset;
 	  if (out_per_objfile != nullptr)
 	    *out_per_objfile = get_dwarf2_per_objfile (objfile);
 
@@ -1884,7 +1890,7 @@ decode_frame_entry_1 (struct gdbarch *gdbarch,
 	      /* Skip.  Avoid indirection since we throw away the result.  */
 	      gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect;
 	      read_encoded_value (unit, encoding, cie->ptr_size,
-				  buf, &bytes_read, 0);
+				  buf, &bytes_read, (unrelocated_addr) 0);
 	      buf += bytes_read;
 	      augmentation++;
 	    }
@@ -1920,7 +1926,6 @@ decode_frame_entry_1 (struct gdbarch *gdbarch,
     {
       /* This is a FDE.  */
       struct dwarf2_fde *fde;
-      CORE_ADDR addr;
 
       /* Check that an FDE was expected.  */
       if ((entry_type & EH_FDE_TYPE_ID) == 0)
@@ -1953,16 +1958,19 @@ decode_frame_entry_1 (struct gdbarch *gdbarch,
 
       gdb_assert (fde->cie != NULL);
 
-      addr = read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size,
-				 buf, &bytes_read, 0);
-      fde->initial_location = gdbarch_adjust_dwarf2_addr (gdbarch, addr);
+      ULONGEST init_addr
+	= read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size,
+			      buf, &bytes_read, (unrelocated_addr) 0);
+      fde->initial_location
+	= (unrelocated_addr) gdbarch_adjust_dwarf2_addr (gdbarch, init_addr);
       buf += bytes_read;
 
-      fde->address_range =
-	read_encoded_value (unit, fde->cie->encoding & 0x0f,
-			    fde->cie->ptr_size, buf, &bytes_read, 0);
-      addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + fde->address_range);
-      fde->address_range = addr - fde->initial_location;
+      ULONGEST range
+	= read_encoded_value (unit, fde->cie->encoding & 0x0f,
+			      fde->cie->ptr_size, buf, &bytes_read,
+			      (unrelocated_addr) 0);
+      ULONGEST addr = gdbarch_adjust_dwarf2_addr (gdbarch, init_addr + range);
+      fde->address_range = addr - (ULONGEST) fde->initial_location;
       buf += bytes_read;
 
       /* A 'z' augmentation in the CIE implies the presence of an
@@ -2214,7 +2222,7 @@ dwarf2_build_frame_info (struct objfile *objfile)
      one.  */
   for (struct dwarf2_fde *fde : fde_table)
     {
-      if (fde->initial_location != 0)
+      if (fde->initial_location != (unrelocated_addr) 0)
 	{
 	  first_non_zero_fde = fde;
 	  break;
@@ -2226,10 +2234,9 @@ dwarf2_build_frame_info (struct objfile *objfile)
      Also discard leftovers from --gc-sections.  */
   for (struct dwarf2_fde *fde : fde_table)
     {
-      if (fde->initial_location == 0
+      if (fde->initial_location == (unrelocated_addr) 0
 	  && first_non_zero_fde != NULL
-	  && (first_non_zero_fde->initial_location
-	      < fde->initial_location + fde->address_range))
+	  && first_non_zero_fde->initial_location < fde->end_addr ())
 	continue;
 
       if (fde_prev != NULL
-- 
2.39.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC 00/10] More use of unrelocated_addr
  2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
                   ` (9 preceding siblings ...)
  2023-04-24 16:22 ` [RFC 10/10] Use unrelocated_addr in dwarf2_fde Tom Tromey
@ 2023-06-05 16:13 ` Tom Tromey
  10 siblings, 0 replies; 12+ messages in thread
From: Tom Tromey @ 2023-06-05 16:13 UTC (permalink / raw)
  To: Tom Tromey via Gdb-patches; +Cc: Tom Tromey

>>>>> "Tom" == Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> writes:

Tom> While working on a different patch, I decided to add more use of
Tom> unrelocated_addr to the DWARF reader.  This caught at least one latent
Tom> bug, see patch #10.  (I thought there was another one as well, but I
Tom> can't find it now.)

Tom> The main ugliness here is that it adds a lot of casts.  Partly (but
Tom> not entirely) this is due to the decision to not use
Tom> DEFINE_OFFSET_TYPE for unrelocated_addr.  Maybe it would be better to
Tom> write a custom wrapper class for unrelocated_addr instead.

Tom> I moved unrelocated_addr to gdbsupport, but maybe it would be better
Tom> in defs.h.  I'm not sure.

Tom> Regression tested on x86-64 Fedora 36.

Tom> Let me know what you think.

I rebased this and re-regression tested it.
I'm checking it in now.

Tom

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-06-05 16:13 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-24 16:22 [RFC 00/10] More use of unrelocated_addr Tom Tromey
2023-04-24 16:22 ` [RFC 01/10] Remove baseaddr parameter from dwarf2_record_block_ranges Tom Tromey
2023-04-24 16:22 ` [RFC 02/10] Minor cleanup in loclist_describe_location Tom Tromey
2023-04-24 16:22 ` [RFC 03/10] Move unrelocated_addr to common-types.h Tom Tromey
2023-04-24 16:22 ` [RFC 04/10] Use unrelocated_addr in the DWARF reader Tom Tromey
2023-04-24 16:22 ` [RFC 05/10] Use unrelocated_addr in dwarf_decode_lines Tom Tromey
2023-04-24 16:22 ` [RFC 06/10] Fix comment in address_class Tom Tromey
2023-04-24 16:22 ` [RFC 07/10] Use "unrelocated" terminology in linetable_entry Tom Tromey
2023-04-24 16:22 ` [RFC 08/10] Constify dwarf2_cie::augmentation Tom Tromey
2023-04-24 16:22 ` [RFC 09/10] Use local "text offset" variable in dwarf2_frame_cache Tom Tromey
2023-04-24 16:22 ` [RFC 10/10] Use unrelocated_addr in dwarf2_fde Tom Tromey
2023-06-05 16:13 ` [RFC 00/10] More use of unrelocated_addr Tom Tromey

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).