This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] bfd/: bfd_elf_bfd_from_remote_memory 32bit &= 0xffffffff


On Wed, 17 Feb 2010 00:24:01 +0100, Tom Tromey wrote:
> Jan> +typedef struct
> Jan> +  {
> Jan> +    CORE_ADDR a;
> Jan> +  }
> Jan> +addr_offset_t;
[...]
> It seems like you could just call the struct CORE_ADDR.

I thought it would be good to have different type for _address_ vs. for
_displacement_.  With this difference some math operations are no longer
valid and I have discovered for example:

displacement used as address: invalid but used in read_type_unit_scope; it
                              should get some cleanup (not investigated more).

valid operations:
address + displacement: valid
address - address used as displacement: valid
displacement + displacement: valid for PIC/PIE offset of section start address.
                             but these are two difference displacements,
                             arbitrary adding of displacements is forbidden.
                             Maybe there should have been distinct types
                             section_displacement and objfile_displacement.
displacement - displacement: valid for delta in objfile_relocate

Anyway with
	[patch] Fix PIE for 64bit gdb -> 32bit inferior
	http://sourceware.org/ml/gdb-patches/2010-02/msg00289.html

this patch will no longer be included (attached just FYI).


> Jan> But as I see now fixing few GDB places to always sign-extend the
> Jan> displacement CORE_ADDR will permit using the current standard 64bit
> Jan> math operators even for 32bit inferiors.
> 
> Maybe I am being fuzzy today, but I don't follow the logic of this
> statement.  Is this just because we don't expect "too much" overflow?
> Is it impossible for overflow to accumulate in a CORE_ADDR?

In general "displacement + displacement" operation is invalid and thus it
cannot overflow.


Thanks,
Jan


--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -1745,6 +1745,8 @@ NAME(_bfd_elf,bfd_from_remote_memory)
 	  if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
 	    {
 	      loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
+	      if (ELFCLASS == ELFCLASS32)
+		loadbase &= 0xffffffff;
 	      loadbase_set = TRUE;
 	    }
 
@@ -1789,11 +1791,13 @@ NAME(_bfd_elf,bfd_from_remote_memory)
 	bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
 	bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
 		       + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
+	bfd_vma vaddr = (i_phdrs[i].p_vaddr + loadbase) & -i_phdrs[i].p_align;
+
+	if (ELFCLASS == ELFCLASS32)
+	  vaddr &= 0xffffffff;
 	if (end > (bfd_vma) contents_size)
 	  end = contents_size;
-	err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
-				  & -i_phdrs[i].p_align,
-				  contents + start, end - start);
+	err = target_read_memory (vaddr, contents + start, end - start);
 	if (err)
 	  {
 	    free (x_phdrs);
--- a/gdb/addrmap.c
+++ b/gdb/addrmap.c
@@ -25,6 +25,7 @@
 #include "gdb_obstack.h"
 #include "addrmap.h"
 #include "gdb_assert.h"
+#include "symtab.h"
 
 
 
@@ -40,13 +41,15 @@ struct addrmap_funcs
   void *(*find) (struct addrmap *this, CORE_ADDR addr);
   struct addrmap *(*create_fixed) (struct addrmap *this,
                                    struct obstack *obstack);
-  void (*relocate) (struct addrmap *this, CORE_ADDR offset);
+  void (*relocate) (struct addrmap *this, addr_offset_t offset);
 };
 
 
 struct addrmap
 {
   const struct addrmap_funcs *funcs;
+
+  struct gdbarch *gdbarch;
 };
 
 
@@ -76,7 +79,7 @@ addrmap_create_fixed (struct addrmap *original, struct obstack *obstack)
 /* Relocate all the addresses in MAP by OFFSET.  (This can be applied
    to either mutable or immutable maps.)  */
 void
-addrmap_relocate (struct addrmap *map, CORE_ADDR offset)
+addrmap_relocate (struct addrmap *map, addr_offset_t offset)
 {
   map->funcs->relocate (map, offset);
 }
@@ -165,13 +168,15 @@ addrmap_fixed_create_fixed (struct addrmap *this, struct obstack *obstack)
 
 
 static void
-addrmap_fixed_relocate (struct addrmap *this, CORE_ADDR offset)
+addrmap_fixed_relocate (struct addrmap *this, addr_offset_t offset)
 {
   struct addrmap_fixed *map = (struct addrmap_fixed *) this;
   size_t i;
 
   for (i = 0; i < map->num_transitions; i++)
-    map->transitions[i].addr += offset;
+    map->transitions[i].addr = addr_add_offset (this->gdbarch,
+						map->transitions[i].addr,
+						offset);
 }
 
 
@@ -201,7 +206,7 @@ struct addrmap_mutable
      fixed maps, we have no entry at (CORE_ADDR) 0; it doesn't 
      simplify enough.)
 
-     The last region is assumed to end at CORE_ADDR_MAX.
+     The last region is assumed to end at ADDR_MINUS_ONE (the maximal one).
 
      Since we can't know whether CORE_ADDR is larger or smaller than
      splay_tree_key (unsigned long) --- I think both are possible,
@@ -330,7 +335,7 @@ addrmap_mutable_set_empty (struct addrmap *this,
 
   /* Establish transitions at the start and end.  */
   force_transition (map, start);
-  if (end_inclusive < CORE_ADDR_MAX)
+  if (end_inclusive < addr_minus_one (this->gdbarch))
     force_transition (map, end_inclusive + 1);
 
   /* Walk the area, changing all NULL regions to OBJ.  */
@@ -348,7 +353,7 @@ addrmap_mutable_set_empty (struct addrmap *this,
   n = addrmap_splay_tree_predecessor (map, start);
   prior_value = n ? addrmap_node_value (n) : NULL;
   for (n = addrmap_splay_tree_lookup (map, start), gdb_assert (n);
-       n && (end_inclusive == CORE_ADDR_MAX
+       n && (end_inclusive == addr_minus_one (this->gdbarch)
              || addrmap_node_key (n) <= end_inclusive + 1);
        n = next)
     {
@@ -419,6 +424,7 @@ addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
                           + (num_transitions
                              * sizeof (fixed->transitions[0]))));
   fixed->addrmap.funcs = &addrmap_fixed_funcs;
+  fixed->addrmap.gdbarch = this->gdbarch;
   fixed->num_transitions = 1;
   fixed->transitions[0].addr = 0;
   fixed->transitions[0].value = NULL;
@@ -435,7 +441,7 @@ addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
 
 
 static void
-addrmap_mutable_relocate (struct addrmap *this, CORE_ADDR offset)
+addrmap_mutable_relocate (struct addrmap *this, addr_offset_t offset)
 {
   /* Not needed yet.  */
   internal_error (__FILE__, __LINE__,
@@ -507,11 +513,12 @@ splay_compare_CORE_ADDR_ptr (splay_tree_key ak, splay_tree_key bk)
 
 
 struct addrmap *
-addrmap_create_mutable (struct obstack *obstack)
+addrmap_create_mutable (struct gdbarch *gdbarch, struct obstack *obstack)
 {
   struct addrmap_mutable *map = obstack_alloc (obstack, sizeof (*map));
 
   map->addrmap.funcs = &addrmap_mutable_funcs;
+  map->addrmap.gdbarch = gdbarch;
   map->obstack = obstack;
 
   /* splay_tree_new_with_allocator uses the provided allocation
--- a/gdb/addrmap.h
+++ b/gdb/addrmap.h
@@ -36,7 +36,8 @@ struct addrmap;
 
 /* Create a mutable address map which maps every address to NULL.
    Allocate entries in OBSTACK.  */
-struct addrmap *addrmap_create_mutable (struct obstack *obstack);
+struct addrmap *addrmap_create_mutable (struct gdbarch *gdbarch,
+					struct obstack *obstack);
 
 /* In the mutable address map MAP, associate the addresses from START
    to END_INCLUSIVE that are currently associated with NULL with OBJ
@@ -89,6 +90,6 @@ struct addrmap *addrmap_create_fixed (struct addrmap *original,
 
 /* Relocate all the addresses in MAP by OFFSET.  (This can be applied
    to either mutable or immutable maps.)  */
-void addrmap_relocate (struct addrmap *map, CORE_ADDR offset);
+void addrmap_relocate (struct addrmap *map, addr_offset_t offset);
 
 #endif /* ADDRMAP_H */
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7530,6 +7530,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct frame_info *frame = get_selected_frame (NULL);
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   struct breakpoint *breakpoint;
   struct breakpoint *breakpoint2 = NULL;
   struct cleanup *old_chain;
@@ -7585,7 +7586,7 @@ until_break_command (char *arg, int from_tty, int anywhere)
       make_cleanup_delete_breakpoint (breakpoint2);
     }
 
-  proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
+  proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
 
   /* If we are running asynchronously, and proceed call above has actually
      managed to start the target, arrange for breakpoints to be
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -432,7 +432,7 @@ record_pending_block (struct objfile *objfile, struct block *block,
    already provided by BLOCK_START and BLOCK_END, then we create an
    address map for the block.  */
 void
-record_block_range (struct block *block,
+record_block_range (struct gdbarch *gdbarch, struct block *block,
                     CORE_ADDR start, CORE_ADDR end_inclusive)
 {
   /* If this is any different from the range recorded in the block's
@@ -447,7 +447,8 @@ record_block_range (struct block *block,
   if (! pending_addrmap)
     {
       obstack_init (&pending_addrmap_obstack);
-      pending_addrmap = addrmap_create_mutable (&pending_addrmap_obstack);
+      pending_addrmap = addrmap_create_mutable (gdbarch,
+						&pending_addrmap_obstack);
     }
 
   addrmap_set_empty (pending_addrmap, start, end_inclusive, block);
--- a/gdb/buildsym.h
+++ b/gdb/buildsym.h
@@ -248,7 +248,7 @@ extern struct block *finish_block (struct symbol *symbol,
                                    CORE_ADDR start, CORE_ADDR end,
                                    struct objfile *objfile);
 
-extern void record_block_range (struct block *,
+extern void record_block_range (struct gdbarch *gdbarch, struct block *,
                                 CORE_ADDR start, CORE_ADDR end_inclusive);
 
 extern void really_free_pendings (void *dummy);
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -430,7 +430,7 @@ add_dump_command (char *name, void (*func) (char *args, char *mode),
 
 /* Opaque data for restore_section_callback. */
 struct callback_data {
-  CORE_ADDR load_offset;
+  addr_offset_t load_offset;
   CORE_ADDR load_start;
   CORE_ADDR load_end;
 };
@@ -489,19 +489,24 @@ restore_section_callback (bfd *ibfd, asection *isec, void *args)
 		   (unsigned long) sec_start, 
 		   (unsigned long) sec_end);
 
-  if (data->load_offset != 0 || data->load_start != 0 || data->load_end != 0)
+  if (data->load_offset.a != 0 || data->load_start != 0 || data->load_end != 0)
     printf_filtered (" into memory (%s to %s)\n",
 		     paddress (target_gdbarch,
-			       (unsigned long) sec_start
-			       + sec_offset + data->load_offset), 
+			       addr_add_offset (target_gdbarch,
+						sec_start + sec_offset,
+						data->load_offset)),
 		     paddress (target_gdbarch,
-			       (unsigned long) sec_start + sec_offset
-				+ data->load_offset + sec_load_count));
+			       addr_add_offset (target_gdbarch,
+						(sec_start + sec_offset
+						 + sec_load_count),
+						data->load_offset)));
   else
     puts_filtered ("\n");
 
   /* Write the data.  */
-  ret = target_write_memory (sec_start + sec_offset + data->load_offset, 
+  ret = target_write_memory (addr_add_offset (target_gdbarch,
+					      sec_start + sec_offset,
+					      data->load_offset),
 			     buf + sec_offset, sec_load_count);
   if (ret != 0)
     warning (_("restore: memory write failed (%s)."), safe_strerror (ret));
@@ -535,10 +540,14 @@ restore_binary_file (char *filename, struct callback_data *data)
     len -= data->load_start;
 
   printf_filtered 
-    ("Restoring binary file %s into memory (0x%lx to 0x%lx)\n", 
+    ("Restoring binary file %s into memory (%s to %s)\n", 
      filename, 
-     (unsigned long) (data->load_start + data->load_offset),
-     (unsigned long) (data->load_start + data->load_offset + len));
+     paddress (target_gdbarch, addr_add_offset (target_gdbarch,
+						data->load_start,
+						data->load_offset)),
+     paddress (target_gdbarch, addr_add_offset (target_gdbarch,
+						data->load_start + len,
+						data->load_offset)));
 
   /* Now set the file pos to the requested load start pos.  */
   if (fseek (file, data->load_start, SEEK_SET) != 0)
@@ -551,7 +560,9 @@ restore_binary_file (char *filename, struct callback_data *data)
     perror_with_name (filename);
 
   /* Now write the buffer into target memory. */
-  len = target_write_memory (data->load_start + data->load_offset, buf, len);
+  len = target_write_memory (addr_add_offset (target_gdbarch, data->load_start,
+					      data->load_offset),
+			     buf, len);
   if (len != 0)
     warning (_("restore: memory write failed (%s)."), safe_strerror (len));
   return;
@@ -568,9 +579,9 @@ restore_command (char *args, int from_tty)
   if (!target_has_execution)
     noprocess ();
 
-  data.load_offset = 0;
-  data.load_start  = 0;
-  data.load_end    = 0;
+  data.load_offset.a = 0;
+  data.load_start = 0;
+  data.load_end = 0;
 
   /* Parse the input arguments.  First is filename (required). */
   filename = scan_filename_with_cleanup (&args, NULL);
@@ -587,8 +598,8 @@ restore_command (char *args, int from_tty)
 	}
       /* Parse offset (optional). */
       if (args != NULL && *args != '\0')
-      data.load_offset = 
-	parse_and_eval_address (scan_expression_with_cleanup (&args, NULL));
+      data.load_offset = addr_to_offset (target_gdbarch,
+	parse_and_eval_address (scan_expression_with_cleanup (&args, NULL)));
       if (args != NULL && *args != '\0')
 	{
 	  /* Parse start address (optional). */
@@ -605,10 +616,10 @@ restore_command (char *args, int from_tty)
     }
 
   if (info_verbose)
-    printf_filtered ("Restore file %s offset 0x%lx start 0x%lx end 0x%lx\n",
-		     filename, (unsigned long) data.load_offset, 
-		     (unsigned long) data.load_start, 
-		     (unsigned long) data.load_end);
+    printf_filtered ("Restore file %s offset %s start %s end %s\n",
+		     filename, paddress (target_gdbarch, data.load_offset.a),
+		     paddress (target_gdbarch, data.load_start),
+		     paddress (target_gdbarch, data.load_end));
 
   if (binary_flag)
     {
--- a/gdb/coff-pe-read.c
+++ b/gdb/coff-pe-read.c
@@ -36,7 +36,8 @@
 
 struct read_pe_section_data
 {
-  CORE_ADDR vma_offset;		/* Offset to loaded address of section. */
+  struct gdbarch *gdbarch;	/* gdbarch of this objfile.  */
+  addr_offset_t vma_offset;	/* Offset to loaded address of section. */
   unsigned long rva_start;	/* Start offset within the pe. */
   unsigned long rva_end;	/* End offset within the pe. */
   enum minimal_symbol_type ms_type;	/* Type to assign symbols in section. */
@@ -89,8 +90,10 @@ get_section_vmas (bfd *abfd, asection *sectp, void *context)
       /* Data within the section start at rva_start in the pe and at
          bfd_get_section_vma() within memory. Store the offset. */
 
-      sections[sectix].vma_offset
-	= bfd_get_section_vma (abfd, sectp) - sections[sectix].rva_start;
+      sections[sectix].vma_offset = addr_sub_to_offset (sections->gdbarch,
+						    bfd_get_section_vma (abfd,
+									 sectp),
+						    sections[sectix].rva_start);
     }
 }
 
@@ -104,7 +107,8 @@ add_pe_exported_sym (char *sym_name,
 {
   /* Add the stored offset to get the loaded address of the symbol. */
 
-  CORE_ADDR vma = func_rva + section_data->vma_offset;
+  CORE_ADDR vma = addr_add_offset (section_data->gdbarch, func_rva,
+				   section_data->vma_offset);
 
   char *qualified_name = 0;
   int dll_name_len = strlen (dll_name);
@@ -184,6 +188,7 @@ pe_as32 (void *ptr)
 void
 read_pe_exported_syms (struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *dll = objfile->obfd;
   unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
   unsigned long export_rva, export_size, nsections, secptr, expptr;
@@ -198,9 +203,9 @@ read_pe_exported_syms (struct objfile *objfile)
      Initialization with start_rva > end_rva guarantees that
      unused sections won't be matched. */
   struct read_pe_section_data section_data[PE_SECTION_TABLE_SIZE]
-    = { {0, 1, 0, mst_text},
-  {0, 1, 0, mst_data},
-  {0, 1, 0, mst_bss}
+    = { {gdbarch, {0}, 1, 0, mst_text},
+  {gdbarch, {0}, 1, 0, mst_data},
+  {gdbarch, {0}, 1, 0, mst_bss}
   };
 
   struct cleanup *back_to = 0;
@@ -322,10 +327,10 @@ read_pe_exported_syms (struct objfile *objfile)
      assumes that *all* sections share the same relocation offset
      as the text section. */
   for (i = 0; i < PE_SECTION_TABLE_SIZE; i++)
-    {
-      section_data[i].vma_offset
-	+= ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-    }
+    section_data[i].vma_offset = addr_offset_add (gdbarch,
+						  section_data[i].vma_offset,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 
   /* Truncate name at first dot. Should maybe also convert to all
      lower case for convenience on Windows. */
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -779,7 +779,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 	{
 	  /* Record all functions -- external and static -- in minsyms. */
 	  int section = cs_to_section (cs, objfile);
-	  tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	  tmpaddr = addr_add_offset (gdbarch, cs->c_value,
+				     ANOFFSET (objfile->section_offsets,
+					       SECT_OFF_TEXT (objfile)));
 	  record_minimal_symbol (cs, tmpaddr, mst_text, section, objfile);
 
 	  fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
@@ -844,8 +846,10 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 		     a file with debugging symbols
 		     followed by a later file with no symbols.  */
 		  if (in_source_file)
-		    complete_symtab (filestring,
-		    cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+		    complete_symtab (filestring, addr_add_offset (gdbarch,
+								  cs->c_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile))),
 				     main_aux.x_scn.x_scnlen);
 		  in_source_file = 0;
 		}
@@ -915,7 +919,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
  		    || cs->c_sclass == C_THUMBEXTFUNC
  		    || cs->c_sclass == C_THUMBEXT
  		    || (pe_file && (cs->c_sclass == C_STAT)))
-		  tmpaddr += ANOFFSET (objfile->section_offsets, sec);
+		  tmpaddr = addr_add_offset (gdbarch, tmpaddr,
+					     ANOFFSET (objfile->section_offsets,
+						       sec));
 
 		if (bfd_section->flags & SEC_CODE)
 		  {
@@ -1034,9 +1040,11 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 
 	      finish_block (new->name, &local_symbols, new->old_blocks,
 			    new->start_addr,
-			    fcn_cs_saved.c_value
-			    + fcn_aux_saved.x_sym.x_misc.x_fsize
-			    + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+			    addr_add_offset (gdbarch,
+			                     (fcn_cs_saved.c_value
+					  + fcn_aux_saved.x_sym.x_misc.x_fsize),
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile))),
 			    objfile
 		);
 	      within_function = 0;
@@ -1046,8 +1054,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 	case C_BLOCK:
 	  if (strcmp (cs->c_name, ".bb") == 0)
 	    {
-	      tmpaddr = cs->c_value;
-	      tmpaddr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	      tmpaddr = addr_add_offset (gdbarch, cs->c_value,
+					 ANOFFSET (objfile->section_offsets,
+						   SECT_OFF_TEXT (objfile)));
 	      push_context (++depth, tmpaddr);
 	    }
 	  else if (strcmp (cs->c_name, ".eb") == 0)
@@ -1070,8 +1079,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 		}
 	      if (local_symbols && context_stack_depth > 0)
 		{
-		  tmpaddr =
-		    cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		  tmpaddr = addr_add_offset (gdbarch, cs->c_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		  /* Make a block for the local symbols within.  */
 		  finish_block (0, &local_symbols, new->old_blocks,
 				new->start_addr, tmpaddr, objfile);
@@ -1387,8 +1397,11 @@ enter_linenos (long file_offset, int first_line,
 	 we exit. */
       if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
 	{
-	  CORE_ADDR addr = lptr.l_addr.l_paddr;
-	  addr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	  CORE_ADDR addr;
+
+	  addr = addr_add_offset (gdbarch, lptr.l_addr.l_paddr,
+	                          ANOFFSET (objfile->section_offsets,
+				            SECT_OFF_TEXT (objfile)));
 	  record_line (current_subfile, first_line + L_LNNO32 (&lptr),
 		       gdbarch_addr_bits_remove (gdbarch, addr));
 	}
@@ -1496,6 +1509,7 @@ process_coff_symbol (struct coff_symbol *cs,
 		     union internal_auxent *aux,
 		     struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symbol *sym
   = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
 				     sizeof (struct symbol));
@@ -1514,7 +1528,10 @@ process_coff_symbol (struct coff_symbol *cs,
 
   if (ISFCN (cs->c_type))
     {
-      SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+      SYMBOL_VALUE (sym) = addr_add_offset (gdbarch,
+					    SYMBOL_VALUE (sym),
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
       SYMBOL_TYPE (sym) =
 	lookup_function_type (decode_function_type (cs, cs->c_type, aux, objfile));
 
@@ -1543,8 +1560,10 @@ process_coff_symbol (struct coff_symbol *cs,
 	case C_THUMBEXTFUNC:
 	case C_EXT:
 	  SYMBOL_CLASS (sym) = LOC_STATIC;
-	  SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
-	  SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	  SYMBOL_VALUE_ADDRESS (sym) = addr_add_offset (gdbarch,
+							(CORE_ADDR) cs->c_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 	  add_symbol_to_list (sym, &global_symbols);
 	  break;
 
@@ -1552,8 +1571,10 @@ process_coff_symbol (struct coff_symbol *cs,
 	case C_THUMBSTATFUNC:
 	case C_STAT:
 	  SYMBOL_CLASS (sym) = LOC_STATIC;
-	  SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
-	  SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	  SYMBOL_VALUE_ADDRESS (sym) = addr_add_offset (gdbarch,
+							(CORE_ADDR) cs->c_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 	  if (within_function)
 	    {
 	      /* Static symbol of local scope */
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -980,6 +980,7 @@ set_namestring (struct objfile *objfile, const struct internal_nlist *nlist)
 static void
 read_dbx_dynamic_symtab (struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = objfile->obfd;
   struct cleanup *back_to;
   int counter;
@@ -1036,20 +1037,23 @@ read_dbx_dynamic_symtab (struct objfile *objfile)
 
 	  if (bfd_get_section_flags (abfd, sec) & SEC_CODE)
 	    {
-	      sym_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_TEXT (objfile));
+	      sym_value = addr_add_offset (gdbarch, sym_value,
+					   ANOFFSET (objfile->section_offsets,
+						     SECT_OFF_TEXT (objfile)));
 	      type = N_TEXT;
 	    }
 	  else if (bfd_get_section_flags (abfd, sec) & SEC_DATA)
 	    {
-	      sym_value	+= ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_DATA (objfile));
+	      sym_value	= addr_add_offset (gdbarch, sym_value,
+					   ANOFFSET (objfile->section_offsets,
+						     SECT_OFF_DATA (objfile)));
 	      type = N_DATA;
 	    }
 	  else if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
 	    {
-	      sym_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_BSS (objfile));
+	      sym_value = addr_add_offset (gdbarch, sym_value,
+					   ANOFFSET (objfile->section_offsets,
+						     SECT_OFF_BSS (objfile)));
 	      type = N_BSS;
 	    }
 	  else
@@ -1089,9 +1093,9 @@ read_dbx_dynamic_symtab (struct objfile *objfile)
        counter++, relptr++)
     {
       arelent *rel = *relptr;
-      CORE_ADDR address =
-      rel->address + ANOFFSET (objfile->section_offsets,
-			       SECT_OFF_DATA (objfile));
+      CORE_ADDR address = addr_add_offset (gdbarch, rel->address,
+                                           ANOFFSET (objfile->section_offsets,
+					             SECT_OFF_DATA (objfile)));
 
       switch (bfd_get_arch (abfd))
 	{
@@ -1238,928 +1242,943 @@ read_dbx_symtab (struct objfile *objfile)
 
   last_source_file = NULL;
 
-  lowest_text_address = (CORE_ADDR) -1;
-
-  symfile_bfd = objfile->obfd;	/* For next_text_symbol */
-  abfd = objfile->obfd;
-  symbuf_end = symbuf_idx = 0;
-  next_symbol_text_func = dbx_next_symbol_text;
-  textlow_not_set = 1;
-  has_line_numbers = 0;
-
-  /* FIXME: jimb/2003-09-12: We don't apply the right section's offset
-     to global and static variables.  The stab for a global or static
-     variable doesn't give us any indication of which section it's in,
-     so we can't tell immediately which offset in
-     objfile->section_offsets we should apply to the variable's
-     address.
-
-     We could certainly find out which section contains the variable
-     by looking up the variable's unrelocated address with
-     find_pc_section, but that would be expensive; this is the
-     function that constructs the partial symbol tables by examining
-     every symbol in the entire executable, and it's
-     performance-critical.  So that expense would not be welcome.  I'm
-     not sure what to do about this at the moment.
-
-     What we have done for years is to simply assume that the .data
-     section's offset is appropriate for all global and static
-     variables.  Recently, this was expanded to fall back to the .bss
-     section's offset if there is no .data section, and then to the
-     .rodata section's offset.  */
-  data_sect_index = objfile->sect_index_data;
-  if (data_sect_index == -1)
-    data_sect_index = SECT_OFF_BSS (objfile);
-  if (data_sect_index == -1)
-    data_sect_index = SECT_OFF_RODATA (objfile);
-
-  /* If data_sect_index is still -1, that's okay.  It's perfectly fine
-     for the file to have no .data, no .bss, and no .text at all, if
-     it also has no global or static variables.  If it does, we will
-     get an internal error from an ANOFFSET macro below when we try to
-     use data_sect_index.  */
-
-  for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
-    {
-      /* Get the symbol for this run and pull out some info */
-      QUIT;			/* allow this to be interruptable */
-      if (symbuf_idx == symbuf_end)
-	fill_symbuf (abfd);
-      bufp = &symbuf[symbuf_idx++];
+lowest_text_address = addr_minus_one (gdbarch);
+
+symfile_bfd = objfile->obfd;	/* For next_text_symbol */
+abfd = objfile->obfd;
+symbuf_end = symbuf_idx = 0;
+next_symbol_text_func = dbx_next_symbol_text;
+textlow_not_set = 1;
+has_line_numbers = 0;
+
+/* FIXME: jimb/2003-09-12: We don't apply the right section's offset
+   to global and static variables.  The stab for a global or static
+   variable doesn't give us any indication of which section it's in,
+   so we can't tell immediately which offset in
+   objfile->section_offsets we should apply to the variable's
+   address.
+
+   We could certainly find out which section contains the variable
+   by looking up the variable's unrelocated address with
+   find_pc_section, but that would be expensive; this is the
+   function that constructs the partial symbol tables by examining
+   every symbol in the entire executable, and it's
+   performance-critical.  So that expense would not be welcome.  I'm
+   not sure what to do about this at the moment.
+
+   What we have done for years is to simply assume that the .data
+   section's offset is appropriate for all global and static
+   variables.  Recently, this was expanded to fall back to the .bss
+   section's offset if there is no .data section, and then to the
+   .rodata section's offset.  */
+data_sect_index = objfile->sect_index_data;
+if (data_sect_index == -1)
+  data_sect_index = SECT_OFF_BSS (objfile);
+if (data_sect_index == -1)
+  data_sect_index = SECT_OFF_RODATA (objfile);
+
+/* If data_sect_index is still -1, that's okay.  It's perfectly fine
+   for the file to have no .data, no .bss, and no .text at all, if
+   it also has no global or static variables.  If it does, we will
+   get an internal error from an ANOFFSET macro below when we try to
+   use data_sect_index.  */
+
+for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
+  {
+    /* Get the symbol for this run and pull out some info */
+    QUIT;			/* allow this to be interruptable */
+    if (symbuf_idx == symbuf_end)
+      fill_symbuf (abfd);
+    bufp = &symbuf[symbuf_idx++];
 
-      /*
-       * Special case to speed up readin.
-       */
-      if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
-	{
-	  has_line_numbers = 1;
-	  continue;
-	}
+    /*
+     * Special case to speed up readin.
+     */
+    if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
+      {
+	has_line_numbers = 1;
+	continue;
+      }
 
-      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
-      OBJSTAT (objfile, n_stabs++);
+    INTERNALIZE_SYMBOL (nlist, bufp, abfd);
+    OBJSTAT (objfile, n_stabs++);
 
-      /* Ok.  There is a lot of code duplicated in the rest of this
-         switch statement (for efficiency reasons).  Since I don't
-         like duplicating code, I will do my penance here, and
-         describe the code which is duplicated:
+    /* Ok.  There is a lot of code duplicated in the rest of this
+       switch statement (for efficiency reasons).  Since I don't
+       like duplicating code, I will do my penance here, and
+       describe the code which is duplicated:
 
-         *) The assignment to namestring.
-         *) The call to strchr.
-         *) The addition of a partial symbol the the two partial
-         symbol lists.  This last is a large section of code, so
-         I've imbedded it in the following macro.
-      */
+       *) The assignment to namestring.
+       *) The call to strchr.
+       *) The addition of a partial symbol the the two partial
+       symbol lists.  This last is a large section of code, so
+       I've imbedded it in the following macro.
+    */
 
-      switch (nlist.n_type)
-	{
-	  /*
-	   * Standard, external, non-debugger, symbols
-	   */
-
-	case N_TEXT | N_EXT:
-	case N_NBTEXT | N_EXT:
-	  nlist.n_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_TEXT (objfile));
+    switch (nlist.n_type)
+      {
+	/*
+	 * Standard, external, non-debugger, symbols
+	 */
+
+      case N_TEXT | N_EXT:
+      case N_NBTEXT | N_EXT:
+	nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					 ANOFFSET (objfile->section_offsets,
+						   SECT_OFF_TEXT (objfile)));
+	goto record_it;
+
+      case N_DATA | N_EXT:
+      case N_NBDATA | N_EXT:
+	nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					 ANOFFSET (objfile->section_offsets,
+						   SECT_OFF_DATA (objfile)));
+	goto record_it;
+
+      case N_BSS:
+      case N_BSS | N_EXT:
+      case N_NBBSS | N_EXT:
+      case N_SETV | N_EXT:		/* FIXME, is this in BSS? */
+	nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					 ANOFFSET (objfile->section_offsets,
+						   SECT_OFF_BSS (objfile)));
+	goto record_it;
+
+      case N_ABS | N_EXT:
+	record_it:
+	namestring = set_namestring (objfile, &nlist);
+
+      bss_ext_symbol:
+	record_minimal_symbol (namestring, nlist.n_value,
+			       nlist.n_type, objfile);	/* Always */
+	continue;
+
+	/* Standard, local, non-debugger, symbols */
+
+      case N_NBTEXT:
+
+	/* We need to be able to deal with both N_FN or N_TEXT,
+	   because we have no way of knowing whether the sys-supplied ld
+	   or GNU ld was used to make the executable.  Sequents throw
+	   in another wrinkle -- they renumbered N_FN.  */
+
+      case N_FN:
+      case N_FN_SEQ:
+      case N_TEXT:
+	nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					 ANOFFSET (objfile->section_offsets,
+						   SECT_OFF_TEXT (objfile)));
+	namestring = set_namestring (objfile, &nlist);
+
+	if ((namestring[0] == '-' && namestring[1] == 'l')
+	    || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
+		&& namestring[nsl - 2] == '.'))
+	  {
+	    if (past_first_source_file && pst
+		/* The gould NP1 uses low values for .o and -l symbols
+		   which are not the address.  */
+		&& nlist.n_value >= pst->textlow)
+	      {
+		end_psymtab (pst, psymtab_include_list, includes_used,
+			     symnum * symbol_size,
+			     nlist.n_value > pst->texthigh
+			     ? nlist.n_value : pst->texthigh,
+			     dependency_list, dependencies_used,
+			     textlow_not_set);
+		pst = (struct partial_symtab *) 0;
+		includes_used = 0;
+		dependencies_used = 0;
+		has_line_numbers = 0;
+	      }
+	    else
+	      past_first_source_file = 1;
+	    last_o_file_start = nlist.n_value;
+	  }
+	else
 	  goto record_it;
+	continue;
 
-	case N_DATA | N_EXT:
-	case N_NBDATA | N_EXT:
-	  nlist.n_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_DATA (objfile));
-	  goto record_it;
+      case N_DATA:
+	nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					 ANOFFSET (objfile->section_offsets,
+						   SECT_OFF_DATA (objfile)));
+	goto record_it;
 
-	case N_BSS:
-	case N_BSS | N_EXT:
-	case N_NBBSS | N_EXT:
-	case N_SETV | N_EXT:		/* FIXME, is this in BSS? */
-	  nlist.n_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_BSS (objfile));
-	  goto record_it;
+      case N_UNDF | N_EXT:
+	if (nlist.n_value != 0)
+	  {
+	    /* This is a "Fortran COMMON" symbol.  See if the target
+	       environment knows where it has been relocated to.  */
 
-	case N_ABS | N_EXT:
-	  record_it:
-	  namestring = set_namestring (objfile, &nlist);
+	    CORE_ADDR reladdr;
 
-	bss_ext_symbol:
-	  record_minimal_symbol (namestring, nlist.n_value,
-				 nlist.n_type, objfile);	/* Always */
-	  continue;
+	    namestring = set_namestring (objfile, &nlist);
+	    if (target_lookup_symbol (namestring, &reladdr))
+	      {
+		continue;	/* Error in lookup; ignore symbol for now.  */
+	      }
+	    nlist.n_type ^= (N_BSS ^ N_UNDF);	/* Define it as a bss-symbol */
+	    nlist.n_value = reladdr;
+	    goto bss_ext_symbol;
+	  }
+	continue;			/* Just undefined, not COMMON */
 
-	  /* Standard, local, non-debugger, symbols */
+      case N_UNDF:
+	if (processing_acc_compilation && nlist.n_strx == 1)
+	  {
+	    /* Deal with relative offsets in the string table
+	       used in ELF+STAB under Solaris.  If we want to use the
+	       n_strx field, which contains the name of the file,
+	       we must adjust file_string_table_offset *before* calling
+	       set_namestring().  */
+	    past_first_source_file = 1;
+	    file_string_table_offset = next_file_string_table_offset;
+	    next_file_string_table_offset =
+	      file_string_table_offset + nlist.n_value;
+	    if (next_file_string_table_offset < file_string_table_offset)
+	      error (_("string table offset backs up at %d"), symnum);
+	    /* FIXME -- replace error() with complaint.  */
+	    continue;
+	  }
+	continue;
+
+	/* Lots of symbol types we can just ignore.  */
+
+      case N_ABS:
+      case N_NBDATA:
+      case N_NBBSS:
+	continue;
+
+	/* Keep going . . . */
+
+	/*
+	 * Special symbol types for GNU
+	 */
+      case N_INDR:
+      case N_INDR | N_EXT:
+      case N_SETA:
+      case N_SETA | N_EXT:
+      case N_SETT:
+      case N_SETT | N_EXT:
+      case N_SETD:
+      case N_SETD | N_EXT:
+      case N_SETB:
+      case N_SETB | N_EXT:
+      case N_SETV:
+	continue;
+
+	/*
+	 * Debugger symbols
+	 */
+
+      case N_SO:
+	{
+	  CORE_ADDR valu;
+	  static int prev_so_symnum = -10;
+	  static int first_so_symnum;
+	  char *p;
+	  static char *dirname_nso;
+	  int prev_textlow_not_set;
 
-	case N_NBTEXT:
+	  nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					  ANOFFSET (objfile->section_offsets,
+						    SECT_OFF_TEXT (objfile)));
+	  valu = nlist.n_value;
 
-	  /* We need to be able to deal with both N_FN or N_TEXT,
-	     because we have no way of knowing whether the sys-supplied ld
-	     or GNU ld was used to make the executable.  Sequents throw
-	     in another wrinkle -- they renumbered N_FN.  */
+	  prev_textlow_not_set = textlow_not_set;
 
-	case N_FN:
-	case N_FN_SEQ:
-	case N_TEXT:
-	  nlist.n_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_TEXT (objfile));
-	  namestring = set_namestring (objfile, &nlist);
+	  /* A zero value is probably an indication for the SunPRO 3.0
+	     compiler. end_psymtab explicitly tests for zero, so
+	     don't relocate it.  */
 
-	  if ((namestring[0] == '-' && namestring[1] == 'l')
-	      || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
-		  && namestring[nsl - 2] == '.'))
+	  if (nlist.n_value == 0
+	      && gdbarch_sofun_address_maybe_missing (gdbarch))
 	    {
-	      if (past_first_source_file && pst
-		  /* The gould NP1 uses low values for .o and -l symbols
-		     which are not the address.  */
-		  && nlist.n_value >= pst->textlow)
+	      textlow_not_set = 1;
+	      valu = 0;
+	    }
+	  else
+	    textlow_not_set = 0;
+
+	  past_first_source_file = 1;
+
+	  if (prev_so_symnum != symnum - 1)
+	    {			/* Here if prev stab wasn't N_SO */
+	      first_so_symnum = symnum;
+
+	      if (pst)
 		{
 		  end_psymtab (pst, psymtab_include_list, includes_used,
 			       symnum * symbol_size,
-			       nlist.n_value > pst->texthigh
-			       ? nlist.n_value : pst->texthigh,
+			       valu > pst->texthigh ? valu : pst->texthigh,
 			       dependency_list, dependencies_used,
-			       textlow_not_set);
+			       prev_textlow_not_set);
 		  pst = (struct partial_symtab *) 0;
 		  includes_used = 0;
 		  dependencies_used = 0;
 		  has_line_numbers = 0;
 		}
-	      else
-		past_first_source_file = 1;
-	      last_o_file_start = nlist.n_value;
 	    }
-	  else
-	    goto record_it;
-	  continue;
 
-	case N_DATA:
-	  nlist.n_value += ANOFFSET (objfile->section_offsets,
-				     SECT_OFF_DATA (objfile));
-	  goto record_it;
+	  prev_so_symnum = symnum;
+
+	  /* End the current partial symtab and start a new one */
 
-	case N_UNDF | N_EXT:
-	  if (nlist.n_value != 0)
+	  namestring = set_namestring (objfile, &nlist);
+
+	  /* Null name means end of .o file.  Don't start a new one. */
+	  if (*namestring == '\000')
+	    continue;
+
+	  /* Some compilers (including gcc) emit a pair of initial N_SOs.
+	     The first one is a directory name; the second the file name.
+	     If pst exists, is empty, and has a filename ending in '/',
+	     we assume the previous N_SO was a directory name. */
+
+	  p = strrchr (namestring, '/');
+	  if (p && *(p + 1) == '\000')
 	    {
-	      /* This is a "Fortran COMMON" symbol.  See if the target
-		 environment knows where it has been relocated to.  */
+	      /* Save the directory name SOs locally, then save it into
+		 the psymtab when it's created below. */
+	      dirname_nso = namestring;
+	      continue;		
+	    }
 
-	      CORE_ADDR reladdr;
+	  /* Some other compilers (C++ ones in particular) emit useless
+	     SOs for non-existant .c files.  We ignore all subsequent SOs
+	     that immediately follow the first.  */
 
-	      namestring = set_namestring (objfile, &nlist);
-	      if (target_lookup_symbol (namestring, &reladdr))
-		{
-		  continue;	/* Error in lookup; ignore symbol for now.  */
-		}
-	      nlist.n_type ^= (N_BSS ^ N_UNDF);	/* Define it as a bss-symbol */
-	      nlist.n_value = reladdr;
-	      goto bss_ext_symbol;
+	  if (!pst)
+	    {
+	      pst = start_psymtab (objfile,
+				   namestring, valu,
+				   first_so_symnum * symbol_size,
+				   objfile->global_psymbols.next,
+				   objfile->static_psymbols.next);
+	      pst->dirname = dirname_nso;
+	      dirname_nso = NULL;
 	    }
-	  continue;			/* Just undefined, not COMMON */
+	  continue;
+	}
+
+      case N_BINCL:
+	{
+	  enum language tmp_language;
+	  /* Add this bincl to the bincl_list for future EXCLs.  No
+	     need to save the string; it'll be around until
+	     read_dbx_symtab function returns */
 
-	case N_UNDF:
-	  if (processing_acc_compilation && nlist.n_strx == 1)
+	  namestring = set_namestring (objfile, &nlist);
+	  tmp_language = deduce_language_from_filename (namestring);
+
+	  /* Only change the psymtab's language if we've learned
+	     something useful (eg. tmp_language is not language_unknown).
+	     In addition, to match what start_subfile does, never change
+	     from C++ to C.  */
+	  if (tmp_language != language_unknown
+	      && (tmp_language != language_c
+		  || psymtab_language != language_cplus))
+	    psymtab_language = tmp_language;
+
+	  if (pst == NULL)
 	    {
-	      /* Deal with relative offsets in the string table
-		 used in ELF+STAB under Solaris.  If we want to use the
-		 n_strx field, which contains the name of the file,
-		 we must adjust file_string_table_offset *before* calling
-		 set_namestring().  */
-	      past_first_source_file = 1;
-	      file_string_table_offset = next_file_string_table_offset;
-	      next_file_string_table_offset =
-		file_string_table_offset + nlist.n_value;
-	      if (next_file_string_table_offset < file_string_table_offset)
-		error (_("string table offset backs up at %d"), symnum);
-	      /* FIXME -- replace error() with complaint.  */
+	      /* FIXME: we should not get here without a PST to work on.
+		 Attempt to recover.  */
+	      complaint (&symfile_complaints,
+			 _("N_BINCL %s not in entries for any file, at symtab \
+pos %d"),
+			 namestring, symnum);
 	      continue;
 	    }
-	  continue;
+	  add_bincl_to_list (pst, namestring, nlist.n_value);
 
-	  /* Lots of symbol types we can just ignore.  */
+	  /* Mark down an include file in the current psymtab */
 
-	case N_ABS:
-	case N_NBDATA:
-	case N_NBBSS:
-	  continue;
+	  goto record_include_file;
+	}
+
+      case N_SOL:
+	{
+	  enum language tmp_language;
+	  /* Mark down an include file in the current psymtab */
+
+	  namestring = set_namestring (objfile, &nlist);
+	  tmp_language = deduce_language_from_filename (namestring);
+
+	  /* Only change the psymtab's language if we've learned
+	     something useful (eg. tmp_language is not language_unknown).
+	     In addition, to match what start_subfile does, never change
+	     from C++ to C.  */
+	  if (tmp_language != language_unknown
+	      && (tmp_language != language_c
+		  || psymtab_language != language_cplus))
+	    psymtab_language = tmp_language;
+
+	  /* In C++, one may expect the same filename to come round many
+	     times, when code is coming alternately from the main file
+	     and from inline functions in other files. So I check to see
+	     if this is a file we've seen before -- either the main
+	     source file, or a previously included file.
+
+	     This seems to be a lot of time to be spending on N_SOL, but
+	     things like "break c-exp.y:435" need to work (I
+	     suppose the psymtab_include_list could be hashed or put
+	     in a binary tree, if profiling shows this is a major hog).  */
+	  if (pst && strcmp (namestring, pst->filename) == 0)
+	    continue;
+	  {
+	    int i;
+	    for (i = 0; i < includes_used; i++)
+	      if (strcmp (namestring, psymtab_include_list[i]) == 0)
+		{
+		  i = -1;
+		  break;
+		}
+	    if (i == -1)
+	      continue;
+	  }
+
+	record_include_file:
+
+	  psymtab_include_list[includes_used++] = namestring;
+	  if (includes_used >= includes_allocated)
+	    {
+	      char **orig = psymtab_include_list;
 
-	  /* Keep going . . . */
-
-	  /*
-	   * Special symbol types for GNU
-	   */
-	case N_INDR:
-	case N_INDR | N_EXT:
-	case N_SETA:
-	case N_SETA | N_EXT:
-	case N_SETT:
-	case N_SETT | N_EXT:
-	case N_SETD:
-	case N_SETD | N_EXT:
-	case N_SETB:
-	case N_SETB | N_EXT:
-	case N_SETV:
+	      psymtab_include_list = (char **)
+		alloca ((includes_allocated *= 2) * sizeof (char *));
+	      memcpy (psymtab_include_list, orig,
+		      includes_used * sizeof (char *));
+	    }
 	  continue;
+	}
+      case N_LSYM:		/* Typedef or automatic variable. */
+      case N_STSYM:		/* Data seg var -- static  */
+      case N_LCSYM:		/* BSS      "  */
+      case N_ROSYM:		/* Read-only data seg var -- static.  */
+      case N_NBSTS:		/* Gould nobase.  */
+      case N_NBLCS:		/* symbols.  */
+      case N_FUN:
+      case N_GSYM:		/* Global (extern) variable; can be
+				 data or bss (sigh FIXME).  */
+
+	/* Following may probably be ignored; I'll leave them here
+	   for now (until I do Pascal and Modula 2 extensions).  */
+
+      case N_PC:		/* I may or may not need this; I
+				 suspect not.  */
+      case N_M2C:		/* I suspect that I can ignore this here. */
+      case N_SCOPE:		/* Same.   */
+      {
+	char *p;
 
-	  /*
-	   * Debugger symbols
-	   */
+	namestring = set_namestring (objfile, &nlist);
 
-	case N_SO:
+	/* See if this is an end of function stab.  */
+	if (pst && nlist.n_type == N_FUN && *namestring == '\000')
 	  {
 	    CORE_ADDR valu;
-	    static int prev_so_symnum = -10;
-	    static int first_so_symnum;
-	    char *p;
-	    static char *dirname_nso;
-	    int prev_textlow_not_set;
 
-	    valu = nlist.n_value + ANOFFSET (objfile->section_offsets,
-					     SECT_OFF_TEXT (objfile));
-
-	    prev_textlow_not_set = textlow_not_set;
+	    /* It's value is the size (in bytes) of the function for
+	       function relative stabs, or the address of the function's
+	       end for old style stabs.  */
+	    valu = nlist.n_value + last_function_start;
+	    if (pst->texthigh == 0 || valu > pst->texthigh)
+	      pst->texthigh = valu;
+	    break;
+	  }
 
-	    /* A zero value is probably an indication for the SunPRO 3.0
-	       compiler. end_psymtab explicitly tests for zero, so
-	       don't relocate it.  */
+	p = (char *) strchr (namestring, ':');
+	if (!p)
+	  continue;			/* Not a debugging symbol.   */
 
-	    if (nlist.n_value == 0
-		&& gdbarch_sofun_address_maybe_missing (gdbarch))
+	sym_len = 0;
+	sym_name = NULL;	/* pacify "gcc -Werror" */
+	if (psymtab_language == language_cplus)
+	  {
+	    char *new_name, *name = xmalloc (p - namestring + 1);
+	    memcpy (name, namestring, p - namestring);
+	    name[p - namestring] = '\0';
+	    new_name = cp_canonicalize_string (name);
+	    if (new_name != NULL)
 	      {
-		textlow_not_set = 1;
-		valu = 0;
+		sym_len = strlen (new_name);
+		sym_name = obsavestring (new_name, sym_len,
+					 &objfile->objfile_obstack);
+		xfree (new_name);
 	      }
-	    else
-	      textlow_not_set = 0;
+	    xfree (name);
+	  }
 
-	    past_first_source_file = 1;
+	if (sym_len == 0)
+	  {
+	    sym_name = namestring;
+	    sym_len = p - namestring;
+	  }
+
+	/* Main processing section for debugging symbols which
+	   the initial read through the symbol tables needs to worry
+	   about.  If we reach this point, the symbol which we are
+	   considering is definitely one we are interested in.
+	   p must also contain the (valid) index into the namestring
+	   which indicates the debugging type symbol.  */
+
+	switch (p[1])
+	  {
+	  case 'S':
+	    nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					   ANOFFSET (objfile->section_offsets,
+						     data_sect_index));
+
+	    if (gdbarch_static_transform_name_p (gdbarch))
+	      namestring = gdbarch_static_transform_name (gdbarch,
+							  namestring);
+
+	    add_psymbol_to_list (sym_name, sym_len, 1,
+				 VAR_DOMAIN, LOC_STATIC,
+				 &objfile->static_psymbols,
+				 0, nlist.n_value,
+				 psymtab_language, objfile);
+	    continue;
 
-	    if (prev_so_symnum != symnum - 1)
-	      {			/* Here if prev stab wasn't N_SO */
-		first_so_symnum = symnum;
+	  case 'G':
+	    nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					   ANOFFSET (objfile->section_offsets,
+						     data_sect_index));
+
+	    /* The addresses in these entries are reported to be
+	       wrong.  See the code that reads 'G's for symtabs. */
+	    add_psymbol_to_list (sym_name, sym_len, 1,
+				 VAR_DOMAIN, LOC_STATIC,
+				 &objfile->global_psymbols,
+				 0, nlist.n_value,
+				 psymtab_language, objfile);
+	    continue;
 
-		if (pst)
+	  case 'T':
+	    /* When a 'T' entry is defining an anonymous enum, it
+	       may have a name which is the empty string, or a
+	       single space.  Since they're not really defining a
+	       symbol, those shouldn't go in the partial symbol
+	       table.  We do pick up the elements of such enums at
+	       'check_enum:', below.  */
+	    if (p >= namestring + 2
+		|| (p == namestring + 1
+		    && namestring[0] != ' '))
+	      {
+		add_psymbol_to_list (sym_name, sym_len, 1,
+				     STRUCT_DOMAIN, LOC_TYPEDEF,
+				     &objfile->static_psymbols,
+				     nlist.n_value, 0,
+				     psymtab_language, objfile);
+		if (p[2] == 't')
 		  {
-		    end_psymtab (pst, psymtab_include_list, includes_used,
-				 symnum * symbol_size,
-				 valu > pst->texthigh ? valu : pst->texthigh,
-				 dependency_list, dependencies_used,
-				 prev_textlow_not_set);
-		    pst = (struct partial_symtab *) 0;
-		    includes_used = 0;
-		    dependencies_used = 0;
-		    has_line_numbers = 0;
+		    /* Also a typedef with the same name.  */
+		    add_psymbol_to_list (sym_name, sym_len, 1,
+					 VAR_DOMAIN, LOC_TYPEDEF,
+					 &objfile->static_psymbols,
+					 nlist.n_value, 0,
+					 psymtab_language, objfile);
+		    p += 1;
 		  }
 	      }
+	    goto check_enum;
 
-	    prev_so_symnum = symnum;
-
-	    /* End the current partial symtab and start a new one */
+	  case 't':
+	    if (p != namestring)	/* a name is there, not just :T... */
+	      {
+		add_psymbol_to_list (sym_name, sym_len, 1,
+				     VAR_DOMAIN, LOC_TYPEDEF,
+				     &objfile->static_psymbols,
+				     nlist.n_value, 0,
+				     psymtab_language, objfile);
+	      }
+	  check_enum:
+	    /* If this is an enumerated type, we need to
+	       add all the enum constants to the partial symbol
+	       table.  This does not cover enums without names, e.g.
+	       "enum {a, b} c;" in C, but fortunately those are
+	       rare.  There is no way for GDB to find those from the
+	       enum type without spending too much time on it.  Thus
+	       to solve this problem, the compiler needs to put out the
+	       enum in a nameless type.  GCC2 does this.  */
+
+	    /* We are looking for something of the form
+	       <name> ":" ("t" | "T") [<number> "="] "e"
+	       {<constant> ":" <value> ","} ";".  */
+
+	    /* Skip over the colon and the 't' or 'T'.  */
+	    p += 2;
+	    /* This type may be given a number.  Also, numbers can come
+	       in pairs like (0,26).  Skip over it.  */
+	    while ((*p >= '0' && *p <= '9')
+		   || *p == '(' || *p == ',' || *p == ')'
+		   || *p == '=')
+	      p++;
+
+	    if (*p++ == 'e')
+	      {
+		/* The aix4 compiler emits extra crud before the members.  */
+		if (*p == '-')
+		  {
+		    /* Skip over the type (?).  */
+		    while (*p != ':')
+		      p++;
 
-	    namestring = set_namestring (objfile, &nlist);
+		    /* Skip over the colon.  */
+		    p++;
+		  }
 
-	    /* Null name means end of .o file.  Don't start a new one. */
-	    if (*namestring == '\000')
-	      continue;
+		/* We have found an enumerated type.  */
+		/* According to comments in read_enum_type
+		   a comma could end it instead of a semicolon.
+		   I don't know where that happens.
+		   Accept either.  */
+		while (*p && *p != ';' && *p != ',')
+		  {
+		    char *q;
+
+		    /* Check for and handle cretinous dbx symbol name
+		       continuation!  */
+		    if (*p == '\\' || (*p == '?' && p[1] == '\0'))
+		      p = next_symbol_text (objfile);
+
+		    /* Point to the character after the name
+		       of the enum constant.  */
+		    for (q = p; *q && *q != ':'; q++)
+		      ;
+		    /* Note that the value doesn't matter for
+		       enum constants in psymtabs, just in symtabs.  */
+		    add_psymbol_to_list (p, q - p, 1,
+					 VAR_DOMAIN, LOC_CONST,
+					 &objfile->static_psymbols, 0,
+					 0, psymtab_language, objfile);
+		    /* Point past the name.  */
+		    p = q;
+		    /* Skip over the value.  */
+		    while (*p && *p != ',')
+		      p++;
+		    /* Advance past the comma.  */
+		    if (*p)
+		      p++;
+		  }
+	      }
+	    continue;
 
-	    /* Some compilers (including gcc) emit a pair of initial N_SOs.
-	       The first one is a directory name; the second the file name.
-	       If pst exists, is empty, and has a filename ending in '/',
-	       we assume the previous N_SO was a directory name. */
+	  case 'c':
+	    /* Constant, e.g. from "const" in Pascal.  */
+	    add_psymbol_to_list (sym_name, sym_len, 1,
+				 VAR_DOMAIN, LOC_CONST,
+				 &objfile->static_psymbols, nlist.n_value,
+				 0, psymtab_language, objfile);
+	    continue;
 
-	    p = strrchr (namestring, '/');
-	    if (p && *(p + 1) == '\000')
+	  case 'f':
+	    if (! pst)
 	      {
-		/* Save the directory name SOs locally, then save it into
-		   the psymtab when it's created below. */
-	        dirname_nso = namestring;
-	        continue;		
+		int name_len = p - namestring;
+		char *name = xmalloc (name_len + 1);
+		memcpy (name, namestring, name_len);
+		name[name_len] = '\0';
+		function_outside_compilation_unit_complaint (name);
+		xfree (name);
 	      }
-
-	    /* Some other compilers (C++ ones in particular) emit useless
-	       SOs for non-existant .c files.  We ignore all subsequent SOs
-	       that immediately follow the first.  */
-
-	    if (!pst)
+	    /* Kludges for ELF/STABS with Sun ACC */
+	    last_function_name = namestring;
+	    /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
+	       value for the bottom of the text seg in those cases. */
+	    if (nlist.n_value == 0
+		&& gdbarch_sofun_address_maybe_missing (gdbarch))
+	      {
+		CORE_ADDR minsym_valu = 
+		  find_stab_function_addr (namestring, 
+					   pst ? pst->filename : NULL, 
+					   objfile);
+		/* find_stab_function_addr will return 0 if the minimal
+		   symbol wasn't found.  (Unfortunately, this might also
+		   be a valid address.)  Anyway, if it *does* return 0,
+		   it is likely that the value was set correctly to begin
+		   with... */
+		if (minsym_valu != 0)
+		  nlist.n_value = minsym_valu;
+	      }
+	    else
+	      nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					  ANOFFSET (objfile->section_offsets,
+						    SECT_OFF_TEXT (objfile)));
+	    if (pst && textlow_not_set
+		&& gdbarch_sofun_address_maybe_missing (gdbarch))
+	      {
+		pst->textlow = nlist.n_value;
+		textlow_not_set = 0;
+	      }
+	    /* End kludge.  */
+
+	    /* Keep track of the start of the last function so we
+	       can handle end of function symbols.  */
+	    last_function_start = nlist.n_value;
+
+	    /* In reordered executables this function may lie outside
+	       the bounds created by N_SO symbols.  If that's the case
+	       use the address of this function as the low bound for
+	       the partial symbol table.  */
+	    if (pst
+		&& (textlow_not_set
+		    || (nlist.n_value < pst->textlow
+			&& (addr_sub_offset (gdbarch, nlist.n_value,
+					  ANOFFSET (objfile->section_offsets,
+						    SECT_OFF_TEXT (objfile)))
+			    != 0))))
 	      {
-		pst = start_psymtab (objfile,
-				     namestring, valu,
-				     first_so_symnum * symbol_size,
-				     objfile->global_psymbols.next,
-				     objfile->static_psymbols.next);
-		pst->dirname = dirname_nso;
-		dirname_nso = NULL;
+		pst->textlow = nlist.n_value;
+		textlow_not_set = 0;
 	      }
+	    add_psymbol_to_list (sym_name, sym_len, 1,
+				 VAR_DOMAIN, LOC_BLOCK,
+				 &objfile->static_psymbols,
+				 0, nlist.n_value,
+				 psymtab_language, objfile);
 	    continue;
-	  }
-
-	case N_BINCL:
-	  {
-	    enum language tmp_language;
-	    /* Add this bincl to the bincl_list for future EXCLs.  No
-	       need to save the string; it'll be around until
-	       read_dbx_symtab function returns */
 
-	    namestring = set_namestring (objfile, &nlist);
-	    tmp_language = deduce_language_from_filename (namestring);
-
-	    /* Only change the psymtab's language if we've learned
-	       something useful (eg. tmp_language is not language_unknown).
-	       In addition, to match what start_subfile does, never change
-	       from C++ to C.  */
-	    if (tmp_language != language_unknown
-		&& (tmp_language != language_c
-		    || psymtab_language != language_cplus))
-	      psymtab_language = tmp_language;
-
-	    if (pst == NULL)
+	    /* Global functions were ignored here, but now they
+	       are put into the global psymtab like one would expect.
+	       They're also in the minimal symbol table.  */
+	  case 'F':
+	    if (! pst)
 	      {
-		/* FIXME: we should not get here without a PST to work on.
-		   Attempt to recover.  */
-		complaint (&symfile_complaints,
-			   _("N_BINCL %s not in entries for any file, at symtab \
-pos %d"),
-			   namestring, symnum);
-		continue;
+		int name_len = p - namestring;
+		char *name = xmalloc (name_len + 1);
+		memcpy (name, namestring, name_len);
+		name[name_len] = '\0';
+		function_outside_compilation_unit_complaint (name);
+		xfree (name);
 	      }
-	    add_bincl_to_list (pst, namestring, nlist.n_value);
-
-	    /* Mark down an include file in the current psymtab */
-
-	    goto record_include_file;
-	  }
-
-	case N_SOL:
-	  {
-	    enum language tmp_language;
-	    /* Mark down an include file in the current psymtab */
-
-	    namestring = set_namestring (objfile, &nlist);
-	    tmp_language = deduce_language_from_filename (namestring);
-
-	    /* Only change the psymtab's language if we've learned
-	       something useful (eg. tmp_language is not language_unknown).
-	       In addition, to match what start_subfile does, never change
-	       from C++ to C.  */
-	    if (tmp_language != language_unknown
-		&& (tmp_language != language_c
-		    || psymtab_language != language_cplus))
-	      psymtab_language = tmp_language;
-
-	    /* In C++, one may expect the same filename to come round many
-	       times, when code is coming alternately from the main file
-	       and from inline functions in other files. So I check to see
-	       if this is a file we've seen before -- either the main
-	       source file, or a previously included file.
-
-	       This seems to be a lot of time to be spending on N_SOL, but
-	       things like "break c-exp.y:435" need to work (I
-	       suppose the psymtab_include_list could be hashed or put
-	       in a binary tree, if profiling shows this is a major hog).  */
-	    if (pst && strcmp (namestring, pst->filename) == 0)
-	      continue;
-	    {
-	      int i;
-	      for (i = 0; i < includes_used; i++)
-		if (strcmp (namestring, psymtab_include_list[i]) == 0)
-		  {
-		    i = -1;
-		    break;
-		  }
-	      if (i == -1)
-		continue;
-	    }
-
-	  record_include_file:
-
-	    psymtab_include_list[includes_used++] = namestring;
-	    if (includes_used >= includes_allocated)
+	    /* Kludges for ELF/STABS with Sun ACC */
+	    last_function_name = namestring;
+	    /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
+	       value for the bottom of the text seg in those cases. */
+	    if (nlist.n_value == 0
+		&& gdbarch_sofun_address_maybe_missing (gdbarch))
 	      {
-		char **orig = psymtab_include_list;
-
-		psymtab_include_list = (char **)
-		  alloca ((includes_allocated *= 2) * sizeof (char *));
-		memcpy (psymtab_include_list, orig,
-			includes_used * sizeof (char *));
+		CORE_ADDR minsym_valu = 
+		  find_stab_function_addr (namestring, 
+					   pst ? pst->filename : NULL, 
+					   objfile);
+		/* find_stab_function_addr will return 0 if the minimal
+		   symbol wasn't found.  (Unfortunately, this might also
+		   be a valid address.)  Anyway, if it *does* return 0,
+		   it is likely that the value was set correctly to begin
+		   with... */
+		if (minsym_valu != 0)
+		  nlist.n_value = minsym_valu;
 	      }
+	    else
+	      nlist.n_value = addr_add_offset (gdbarch, nlist.n_value,
+					  ANOFFSET (objfile->section_offsets,
+						    SECT_OFF_TEXT (objfile)));
+	    if (pst && textlow_not_set
+		&& gdbarch_sofun_address_maybe_missing (gdbarch))
+	      {
+		pst->textlow = nlist.n_value;
+		textlow_not_set = 0;
+	      }
+	    /* End kludge.  */
+
+	    /* Keep track of the start of the last function so we
+	       can handle end of function symbols.  */
+	    last_function_start = nlist.n_value;
+
+	    /* In reordered executables this function may lie outside
+	       the bounds created by N_SO symbols.  If that's the case
+	       use the address of this function as the low bound for
+	       the partial symbol table.  */
+	    if (pst
+		&& (textlow_not_set
+		    || (nlist.n_value < pst->textlow
+			&& (addr_sub_offset (gdbarch, nlist.n_value,
+					  ANOFFSET (objfile->section_offsets,
+						    SECT_OFF_TEXT (objfile)))
+			    != 0))))
+	      {
+		pst->textlow = nlist.n_value;
+		textlow_not_set = 0;
+	      }
+	    add_psymbol_to_list (sym_name, sym_len, 1,
+				 VAR_DOMAIN, LOC_BLOCK,
+				 &objfile->global_psymbols,
+				 0, nlist.n_value,
+				 psymtab_language, objfile);
 	    continue;
-	  }
-	case N_LSYM:		/* Typedef or automatic variable. */
-	case N_STSYM:		/* Data seg var -- static  */
-	case N_LCSYM:		/* BSS      "  */
-	case N_ROSYM:		/* Read-only data seg var -- static.  */
-	case N_NBSTS:		/* Gould nobase.  */
-	case N_NBLCS:		/* symbols.  */
-	case N_FUN:
-	case N_GSYM:		/* Global (extern) variable; can be
-				   data or bss (sigh FIXME).  */
-
-	  /* Following may probably be ignored; I'll leave them here
-	     for now (until I do Pascal and Modula 2 extensions).  */
-
-	case N_PC:		/* I may or may not need this; I
-				   suspect not.  */
-	case N_M2C:		/* I suspect that I can ignore this here. */
-	case N_SCOPE:		/* Same.   */
-	{
-	  char *p;
-
-	  namestring = set_namestring (objfile, &nlist);
 
-	  /* See if this is an end of function stab.  */
-	  if (pst && nlist.n_type == N_FUN && *namestring == '\000')
-	    {
-	      CORE_ADDR valu;
-
-	      /* It's value is the size (in bytes) of the function for
-		 function relative stabs, or the address of the function's
-		 end for old style stabs.  */
-	      valu = nlist.n_value + last_function_start;
-	      if (pst->texthigh == 0 || valu > pst->texthigh)
-		pst->texthigh = valu;
-	      break;
-	    }
-
-	  p = (char *) strchr (namestring, ':');
-	  if (!p)
-	    continue;			/* Not a debugging symbol.   */
+	    /* Two things show up here (hopefully); static symbols of
+	       local scope (static used inside braces) or extensions
+	       of structure symbols.  We can ignore both.  */
+	  case 'V':
+	  case '(':
+	  case '0':
+	  case '1':
+	  case '2':
+	  case '3':
+	  case '4':
+	  case '5':
+	  case '6':
+	  case '7':
+	  case '8':
+	  case '9':
+	  case '-':
+	  case '#':	/* for symbol identification (used in live ranges) */
+	    continue;
 
- 	  sym_len = 0;
-	  sym_name = NULL;	/* pacify "gcc -Werror" */
- 	  if (psymtab_language == language_cplus)
- 	    {
- 	      char *new_name, *name = xmalloc (p - namestring + 1);
- 	      memcpy (name, namestring, p - namestring);
- 	      name[p - namestring] = '\0';
- 	      new_name = cp_canonicalize_string (name);
- 	      if (new_name != NULL)
- 		{
- 		  sym_len = strlen (new_name);
- 		  sym_name = obsavestring (new_name, sym_len,
- 					   &objfile->objfile_obstack);
- 		  xfree (new_name);
- 		}
-              xfree (name);
- 	    }
+	  case ':':
+	    /* It is a C++ nested symbol.  We don't need to record it
+	       (I don't think); if we try to look up foo::bar::baz,
+	       then symbols for the symtab containing foo should get
+	       read in, I think.  */
+	    /* Someone says sun cc puts out symbols like
+	       /foo/baz/maclib::/usr/local/bin/maclib,
+	       which would get here with a symbol type of ':'.  */
+	    continue;
 
- 	  if (sym_len == 0)
- 	    {
- 	      sym_name = namestring;
- 	      sym_len = p - namestring;
- 	    }
+	  default:
+	    /* Unexpected symbol descriptor.  The second and subsequent stabs
+	       of a continued stab can show up here.  The question is
+	       whether they ever can mimic a normal stab--it would be
+	       nice if not, since we certainly don't want to spend the
+	       time searching to the end of every string looking for
+	       a backslash.  */
+
+	    complaint (&symfile_complaints, _("unknown symbol descriptor `%c'"),
+		       p[1]);
+
+	    /* Ignore it; perhaps it is an extension that we don't
+	       know about.  */
+	    continue;
+	  }
+      }
 
-	  /* Main processing section for debugging symbols which
-	     the initial read through the symbol tables needs to worry
-	     about.  If we reach this point, the symbol which we are
-	     considering is definitely one we are interested in.
-	     p must also contain the (valid) index into the namestring
-	     which indicates the debugging type symbol.  */
+      case N_EXCL:
 
-	  switch (p[1])
-	    {
-	    case 'S':
-	      nlist.n_value += ANOFFSET (objfile->section_offsets,
-					 data_sect_index);
-
-	      if (gdbarch_static_transform_name_p (gdbarch))
-		namestring = gdbarch_static_transform_name (gdbarch,
-							    namestring);
-
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_STATIC,
-				   &objfile->static_psymbols,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
-	      continue;
+	namestring = set_namestring (objfile, &nlist);
 
-	    case 'G':
-	      nlist.n_value += ANOFFSET (objfile->section_offsets,
-					 data_sect_index);
-	      /* The addresses in these entries are reported to be
-		 wrong.  See the code that reads 'G's for symtabs. */
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_STATIC,
-				   &objfile->global_psymbols,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
-	      continue;
+	/* Find the corresponding bincl and mark that psymtab on the
+	   psymtab dependency list */
+	{
+	  struct partial_symtab *needed_pst =
+	    find_corresponding_bincl_psymtab (namestring, nlist.n_value);
 
-	    case 'T':
-	      /* When a 'T' entry is defining an anonymous enum, it
-		 may have a name which is the empty string, or a
-		 single space.  Since they're not really defining a
-		 symbol, those shouldn't go in the partial symbol
-		 table.  We do pick up the elements of such enums at
-		 'check_enum:', below.  */
-	      if (p >= namestring + 2
-		  || (p == namestring + 1
-		      && namestring[0] != ' '))
-		{
-		  add_psymbol_to_list (sym_name, sym_len, 1,
-				       STRUCT_DOMAIN, LOC_TYPEDEF,
-				       &objfile->static_psymbols,
-				       nlist.n_value, 0,
-				       psymtab_language, objfile);
-		  if (p[2] == 't')
-		    {
-		      /* Also a typedef with the same name.  */
-		      add_psymbol_to_list (sym_name, sym_len, 1,
-					   VAR_DOMAIN, LOC_TYPEDEF,
-					   &objfile->static_psymbols,
-					   nlist.n_value, 0,
-					   psymtab_language, objfile);
-		      p += 1;
-		    }
-		}
-	      goto check_enum;
+	  /* If this include file was defined earlier in this file,
+	     leave it alone.  */
+	  if (needed_pst == pst)
+	    continue;
 
-	    case 't':
-	      if (p != namestring)	/* a name is there, not just :T... */
-		{
-		  add_psymbol_to_list (sym_name, sym_len, 1,
-				       VAR_DOMAIN, LOC_TYPEDEF,
-				       &objfile->static_psymbols,
-				       nlist.n_value, 0,
-				       psymtab_language, objfile);
-		}
-	    check_enum:
-	      /* If this is an enumerated type, we need to
-		 add all the enum constants to the partial symbol
-		 table.  This does not cover enums without names, e.g.
-		 "enum {a, b} c;" in C, but fortunately those are
-		 rare.  There is no way for GDB to find those from the
-		 enum type without spending too much time on it.  Thus
-		 to solve this problem, the compiler needs to put out the
-		 enum in a nameless type.  GCC2 does this.  */
-
-	      /* We are looking for something of the form
-		 <name> ":" ("t" | "T") [<number> "="] "e"
-		 {<constant> ":" <value> ","} ";".  */
-
-	      /* Skip over the colon and the 't' or 'T'.  */
-	      p += 2;
-	      /* This type may be given a number.  Also, numbers can come
-		 in pairs like (0,26).  Skip over it.  */
-	      while ((*p >= '0' && *p <= '9')
-		     || *p == '(' || *p == ',' || *p == ')'
-		     || *p == '=')
-		p++;
-
-	      if (*p++ == 'e')
-		{
-		  /* The aix4 compiler emits extra crud before the members.  */
-		  if (*p == '-')
-		    {
-		      /* Skip over the type (?).  */
-		      while (*p != ':')
-			p++;
-
-		      /* Skip over the colon.  */
-		      p++;
-		    }
-
-		  /* We have found an enumerated type.  */
-		  /* According to comments in read_enum_type
-		     a comma could end it instead of a semicolon.
-		     I don't know where that happens.
-		     Accept either.  */
-		  while (*p && *p != ';' && *p != ',')
-		    {
-		      char *q;
-
-		      /* Check for and handle cretinous dbx symbol name
-			 continuation!  */
-		      if (*p == '\\' || (*p == '?' && p[1] == '\0'))
-			p = next_symbol_text (objfile);
-
-		      /* Point to the character after the name
-			 of the enum constant.  */
-		      for (q = p; *q && *q != ':'; q++)
-			;
-		      /* Note that the value doesn't matter for
-			 enum constants in psymtabs, just in symtabs.  */
-		      add_psymbol_to_list (p, q - p, 1,
-					   VAR_DOMAIN, LOC_CONST,
-					   &objfile->static_psymbols, 0,
-					   0, psymtab_language, objfile);
-		      /* Point past the name.  */
-		      p = q;
-		      /* Skip over the value.  */
-		      while (*p && *p != ',')
-			p++;
-		      /* Advance past the comma.  */
-		      if (*p)
-			p++;
-		    }
-		}
-	      continue;
+	  if (needed_pst)
+	    {
+	      int i;
+	      int found = 0;
 
-	    case 'c':
-	      /* Constant, e.g. from "const" in Pascal.  */
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_CONST,
-				   &objfile->static_psymbols, nlist.n_value,
-				   0, psymtab_language, objfile);
-	      continue;
+	      for (i = 0; i < dependencies_used; i++)
+		if (dependency_list[i] == needed_pst)
+		  {
+		    found = 1;
+		    break;
+		  }
 
-	    case 'f':
-	      if (! pst)
-		{
-		  int name_len = p - namestring;
-		  char *name = xmalloc (name_len + 1);
-		  memcpy (name, namestring, name_len);
-		  name[name_len] = '\0';
-		  function_outside_compilation_unit_complaint (name);
-		  xfree (name);
-		}
-	      nlist.n_value += ANOFFSET (objfile->section_offsets, 
-					 SECT_OFF_TEXT (objfile));
-	      /* Kludges for ELF/STABS with Sun ACC */
-	      last_function_name = namestring;
-	      /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
-		 value for the bottom of the text seg in those cases. */
-	      if (nlist.n_value == ANOFFSET (objfile->section_offsets, 
-					     SECT_OFF_TEXT (objfile))
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  CORE_ADDR minsym_valu = 
-		    find_stab_function_addr (namestring, 
-					     pst ? pst->filename : NULL, 
-					     objfile);
-		  /* find_stab_function_addr will return 0 if the minimal
-		     symbol wasn't found.  (Unfortunately, this might also
-		     be a valid address.)  Anyway, if it *does* return 0,
-		     it is likely that the value was set correctly to begin
-		     with... */
-		  if (minsym_valu != 0)
-		    nlist.n_value = minsym_valu;
-		}
-	      if (pst && textlow_not_set
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  pst->textlow = nlist.n_value;
-		  textlow_not_set = 0;
-		}
-	      /* End kludge.  */
-
-	      /* Keep track of the start of the last function so we
-		 can handle end of function symbols.  */
-	      last_function_start = nlist.n_value;
-
-	      /* In reordered executables this function may lie outside
-		 the bounds created by N_SO symbols.  If that's the case
-		 use the address of this function as the low bound for
-		 the partial symbol table.  */
-	      if (pst
-		  && (textlow_not_set
-		      || (nlist.n_value < pst->textlow
-			  && (nlist.n_value
-			      != ANOFFSET (objfile->section_offsets,
-					   SECT_OFF_TEXT (objfile))))))
-		{
-		  pst->textlow = nlist.n_value;
-		  textlow_not_set = 0;
-		}
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_BLOCK,
-				   &objfile->static_psymbols,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
-	      continue;
+	      /* If it's already in the list, skip the rest.  */
+	      if (found)
+		continue;
 
-	      /* Global functions were ignored here, but now they
-		 are put into the global psymtab like one would expect.
-		 They're also in the minimal symbol table.  */
-	    case 'F':
-	      if (! pst)
+	      dependency_list[dependencies_used++] = needed_pst;
+	      if (dependencies_used >= dependencies_allocated)
 		{
-		  int name_len = p - namestring;
-		  char *name = xmalloc (name_len + 1);
-		  memcpy (name, namestring, name_len);
-		  name[name_len] = '\0';
-		  function_outside_compilation_unit_complaint (name);
-		  xfree (name);
-		}
-	      nlist.n_value += ANOFFSET (objfile->section_offsets, 
-					 SECT_OFF_TEXT (objfile));
-	      /* Kludges for ELF/STABS with Sun ACC */
-	      last_function_name = namestring;
-	      /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
-		 value for the bottom of the text seg in those cases. */
-	      if (nlist.n_value == ANOFFSET (objfile->section_offsets, 
-					     SECT_OFF_TEXT (objfile))
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  CORE_ADDR minsym_valu = 
-		    find_stab_function_addr (namestring, 
-					     pst ? pst->filename : NULL, 
-					     objfile);
-		  /* find_stab_function_addr will return 0 if the minimal
-		     symbol wasn't found.  (Unfortunately, this might also
-		     be a valid address.)  Anyway, if it *does* return 0,
-		     it is likely that the value was set correctly to begin
-		     with... */
-		  if (minsym_valu != 0)
-		    nlist.n_value = minsym_valu;
-		}
-	      if (pst && textlow_not_set
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  pst->textlow = nlist.n_value;
-		  textlow_not_set = 0;
-		}
-	      /* End kludge.  */
-
-	      /* Keep track of the start of the last function so we
-		 can handle end of function symbols.  */
-	      last_function_start = nlist.n_value;
-
-	      /* In reordered executables this function may lie outside
-		 the bounds created by N_SO symbols.  If that's the case
-		 use the address of this function as the low bound for
-		 the partial symbol table.  */
-	      if (pst
-		  && (textlow_not_set
-		      || (nlist.n_value < pst->textlow
-			  && (nlist.n_value
-			      != ANOFFSET (objfile->section_offsets,
-					   SECT_OFF_TEXT (objfile))))))
-		{
-		  pst->textlow = nlist.n_value;
-		  textlow_not_set = 0;
+		  struct partial_symtab **orig = dependency_list;
+		  dependency_list =
+		    (struct partial_symtab **)
+		    alloca ((dependencies_allocated *= 2)
+			    * sizeof (struct partial_symtab *));
+		  memcpy (dependency_list, orig,
+			  (dependencies_used
+			   * sizeof (struct partial_symtab *)));
+#ifdef DEBUG_INFO
+		  fprintf_unfiltered (gdb_stderr,
+				      "Had to reallocate dependency list.\n");
+		  fprintf_unfiltered (gdb_stderr,
+				      "New dependencies allocated: %d\n",
+				      dependencies_allocated);
+#endif
 		}
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_BLOCK,
-				   &objfile->global_psymbols,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
-	      continue;
-
-	      /* Two things show up here (hopefully); static symbols of
-		 local scope (static used inside braces) or extensions
-		 of structure symbols.  We can ignore both.  */
-	    case 'V':
-	    case '(':
-	    case '0':
-	    case '1':
-	    case '2':
-	    case '3':
-	    case '4':
-	    case '5':
-	    case '6':
-	    case '7':
-	    case '8':
-	    case '9':
-	    case '-':
-	    case '#':	/* for symbol identification (used in live ranges) */
-	      continue;
-
-	    case ':':
-	      /* It is a C++ nested symbol.  We don't need to record it
-		 (I don't think); if we try to look up foo::bar::baz,
-		 then symbols for the symtab containing foo should get
-		 read in, I think.  */
-	      /* Someone says sun cc puts out symbols like
-		 /foo/baz/maclib::/usr/local/bin/maclib,
-		 which would get here with a symbol type of ':'.  */
-	      continue;
-
-	    default:
-	      /* Unexpected symbol descriptor.  The second and subsequent stabs
-		 of a continued stab can show up here.  The question is
-		 whether they ever can mimic a normal stab--it would be
-		 nice if not, since we certainly don't want to spend the
-		 time searching to the end of every string looking for
-		 a backslash.  */
-
-	      complaint (&symfile_complaints, _("unknown symbol descriptor `%c'"),
-			 p[1]);
-
-	      /* Ignore it; perhaps it is an extension that we don't
-		 know about.  */
-	      continue;
 	    }
 	}
-
-	case N_EXCL:
-
-	  namestring = set_namestring (objfile, &nlist);
-
-	  /* Find the corresponding bincl and mark that psymtab on the
-	     psymtab dependency list */
+	continue;
+
+      case N_ENDM:
+	/* Solaris 2 end of module, finish current partial symbol table.
+	   end_psymtab will set pst->texthigh to the proper value, which
+	   is necessary if a module compiled without debugging info
+	   follows this module.  */
+	if (pst && gdbarch_sofun_address_maybe_missing (gdbarch))
 	  {
-	    struct partial_symtab *needed_pst =
-	      find_corresponding_bincl_psymtab (namestring, nlist.n_value);
-
-	    /* If this include file was defined earlier in this file,
-	       leave it alone.  */
-	    if (needed_pst == pst)
-	      continue;
-
-	    if (needed_pst)
-	      {
-		int i;
-		int found = 0;
-
-		for (i = 0; i < dependencies_used; i++)
-		  if (dependency_list[i] == needed_pst)
-		    {
-		      found = 1;
-		      break;
-		    }
-
-		/* If it's already in the list, skip the rest.  */
-		if (found)
-		  continue;
-
-		dependency_list[dependencies_used++] = needed_pst;
-		if (dependencies_used >= dependencies_allocated)
-		  {
-		    struct partial_symtab **orig = dependency_list;
-		    dependency_list =
-		      (struct partial_symtab **)
-		      alloca ((dependencies_allocated *= 2)
-			      * sizeof (struct partial_symtab *));
-		    memcpy (dependency_list, orig,
-			    (dependencies_used
-			     * sizeof (struct partial_symtab *)));
-#ifdef DEBUG_INFO
-		    fprintf_unfiltered (gdb_stderr,
-					"Had to reallocate dependency list.\n");
-		    fprintf_unfiltered (gdb_stderr,
-					"New dependencies allocated: %d\n",
-					dependencies_allocated);
-#endif
-		  }
-	      }
+	    end_psymtab (pst, psymtab_include_list, includes_used,
+			 symnum * symbol_size,
+			 (CORE_ADDR) 0,
+			 dependency_list, dependencies_used, textlow_not_set);
+	    pst = (struct partial_symtab *) 0;
+	    includes_used = 0;
+	    dependencies_used = 0;
+	    has_line_numbers = 0;
 	  }
-	  continue;
+	continue;
 
-	case N_ENDM:
-	  /* Solaris 2 end of module, finish current partial symbol table.
-	     end_psymtab will set pst->texthigh to the proper value, which
-	     is necessary if a module compiled without debugging info
-	     follows this module.  */
-	  if (pst && gdbarch_sofun_address_maybe_missing (gdbarch))
-	    {
-	      end_psymtab (pst, psymtab_include_list, includes_used,
-			   symnum * symbol_size,
-			   (CORE_ADDR) 0,
-			   dependency_list, dependencies_used, textlow_not_set);
-	      pst = (struct partial_symtab *) 0;
-	      includes_used = 0;
-	      dependencies_used = 0;
-	      has_line_numbers = 0;
-	    }
-	  continue;
-
-	case N_RBRAC:
+      case N_RBRAC:
 #ifdef HANDLE_RBRAC
-	  HANDLE_RBRAC (nlist.n_value);
-	  continue;
+	HANDLE_RBRAC (nlist.n_value);
+	continue;
 #endif
-	case N_EINCL:
-	case N_DSLINE:
-	case N_BSLINE:
-	case N_SSYM:		/* Claim: Structure or union element.
-				   Hopefully, I can ignore this.  */
-	case N_ENTRY:		/* Alternate entry point; can ignore. */
-	case N_MAIN:		/* Can definitely ignore this.   */
-	case N_CATCH:		/* These are GNU C++ extensions */
-	case N_EHDECL:		/* that can safely be ignored here. */
-	case N_LENG:
-	case N_BCOMM:
-	case N_ECOMM:
-	case N_ECOML:
-	case N_FNAME:
-	case N_SLINE:
-	case N_RSYM:
-	case N_PSYM:
-	case N_LBRAC:
-	case N_NSYMS:		/* Ultrix 4.0: symbol count */
-	case N_DEFD:		/* GNU Modula-2 */
-	case N_ALIAS:		/* SunPro F77: alias name, ignore for now.  */
-
-	case N_OBJ:		/* useless types from Solaris */
-	case N_OPT:
-	case N_PATCH:
-	  /* These symbols aren't interesting; don't worry about them */
-
-	  continue;
-
-	default:
-	  /* If we haven't found it yet, ignore it.  It's probably some
-	     new type we don't know about yet.  */
-	  unknown_symtype_complaint (hex_string (nlist.n_type));
-	  continue;
-	}
-    }
+      case N_EINCL:
+      case N_DSLINE:
+      case N_BSLINE:
+      case N_SSYM:		/* Claim: Structure or union element.
+				 Hopefully, I can ignore this.  */
+      case N_ENTRY:		/* Alternate entry point; can ignore. */
+      case N_MAIN:		/* Can definitely ignore this.   */
+      case N_CATCH:		/* These are GNU C++ extensions */
+      case N_EHDECL:		/* that can safely be ignored here. */
+      case N_LENG:
+      case N_BCOMM:
+      case N_ECOMM:
+      case N_ECOML:
+      case N_FNAME:
+      case N_SLINE:
+      case N_RSYM:
+      case N_PSYM:
+      case N_LBRAC:
+      case N_NSYMS:		/* Ultrix 4.0: symbol count */
+      case N_DEFD:		/* GNU Modula-2 */
+      case N_ALIAS:		/* SunPro F77: alias name, ignore for now.  */
+
+      case N_OBJ:		/* useless types from Solaris */
+      case N_OPT:
+      case N_PATCH:
+	/* These symbols aren't interesting; don't worry about them */
+
+	continue;
+
+      default:
+	/* If we haven't found it yet, ignore it.  It's probably some
+	   new type we don't know about yet.  */
+	unknown_symtype_complaint (hex_string (nlist.n_type));
+	continue;
+      }
+  }
 
-  /* If there's stuff to be cleaned up, clean it up.  */
-  if (pst)
-    {
-      /* Don't set pst->texthigh lower than it already is.  */
-      CORE_ADDR text_end =
-	(lowest_text_address == (CORE_ADDR) -1
-	 ? (text_addr + ANOFFSET (objfile->section_offsets,
-				  SECT_OFF_TEXT (objfile)))
+/* If there's stuff to be cleaned up, clean it up.  */
+if (pst)
+  {
+    /* Don't set pst->texthigh lower than it already is.  */
+    CORE_ADDR text_end =
+      (lowest_text_address == addr_minus_one (gdbarch)
+	 ? addr_add_offset (gdbarch, text_addr,
+			    ANOFFSET (objfile->section_offsets,
+				      SECT_OFF_TEXT (objfile)))
 	 : lowest_text_address)
 	+ text_size;
 
@@ -2723,7 +2742,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
      other than Solaris 2, this just holds the SECT_OFF_TEXT value,
      and is used to relocate these symbol types rather than
      SECTION_OFFSETS.  */
-  static CORE_ADDR function_start_offset;
+  static addr_offset_t function_start_offset;
 
   /* This holds the address of the start of a function, without the
      system peculiarities of function_start_offset.  */
@@ -2807,7 +2826,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
 	  /* May be switching to an assembler file which may not be using
 	     block relative stabs, so reset the offset.  */
 	  if (block_address_function_relative)
-	    function_start_offset = 0;
+	    function_start_offset.a = 0;
 
 	  break;
 	}
@@ -2815,7 +2834,9 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
       sline_found_in_function = 0;
 
       /* Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_TEXT (objfile)));
       valu = gdbarch_smash_text_address (gdbarch, valu);
       last_function_start = valu;
 
@@ -2831,7 +2852,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
 
       if (block_address_function_relative)
 	/* Relocate for Sun ELF acc fn-relative syms.  */
-	valu += function_start_offset;
+	valu = addr_add_offset (gdbarch, valu, function_start_offset);
       else
 	/* On most machines, the block addresses are relative to the
 	   N_SO, the linker did not relocate them (sigh).  */
@@ -2850,7 +2871,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
 
       if (block_address_function_relative)
 	/* Relocate for Sun ELF acc fn-relative syms.  */
-	valu += function_start_offset;
+	valu = addr_add_offset (gdbarch, valu, function_start_offset);
       else
 	/* On most machines, the block addresses are relative to the
 	   N_SO, the linker did not relocate them (sigh).  */
@@ -2917,7 +2938,9 @@ no enclosing block"));
     case N_FN_SEQ:
       /* This kind of symbol indicates the start of an object file.
          Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_TEXT (objfile)));
       break;
 
     case N_SO:
@@ -2925,7 +2948,9 @@ no enclosing block"));
          source file.  Finish the symbol table of the previous source
          file (if any) and start accumulating a new symbol table.
          Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_TEXT (objfile)));
 
       n_opt_found = 0;
 
@@ -2950,7 +2975,7 @@ no enclosing block"));
 	break;
 
       if (block_address_function_relative)
-	function_start_offset = 0;
+	function_start_offset.a = 0;
 
       start_stabs ();
       start_symtab (name, NULL, valu);
@@ -2962,7 +2987,9 @@ no enclosing block"));
          sub-source-file, one whose contents were copied or included
          in the compilation of the main source file (whose name was
          given in the N_SO symbol).  Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_TEXT (objfile)));
       start_subfile (name, current_subfile->dirname);
       break;
 
@@ -2987,7 +3014,7 @@ no enclosing block"));
 
       /* Relocate for dynamic loading and for ELF acc
          function-relative symbols.  */
-      valu += function_start_offset;
+      valu = addr_add_offset (gdbarch, valu, function_start_offset);
 
       /* GCC 2.95.3 emits the first N_SLINE stab somwehere in the
 	 middle of the prologue instead of right at the start of the
@@ -3066,7 +3093,9 @@ no enclosing block"));
 		   elfstab_offset_sections ever starts dealing with
 		   the text offset, and we still need to do this, we
 		   need to invent a SECT_OFF_ADDR_KLUDGE or something.  */
-		valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+		valu = addr_add_offset (gdbarch, valu,
+					ANOFFSET (section_offsets,
+						  SECT_OFF_TEXT (objfile)));
 		goto define_a_symbol;
 	      }
 	  }
@@ -3088,22 +3117,30 @@ no enclosing block"));
 
     case_N_STSYM:		/* Static symbol in data segment.  */
     case N_DSLINE:		/* Source line number, data segment.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_DATA (objfile)));
       goto define_a_symbol;
 
     case_N_LCSYM:		/* Static symbol in BSS segment.  */
     case N_BSLINE:		/* Source line number, BSS segment.  */
       /* N_BROWS: overlaps with N_BSLINE.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_BSS (objfile)));
       goto define_a_symbol;
 
     case_N_ROSYM:		/* Static symbol in read-only data segment.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_RODATA (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_RODATA (objfile)));
       goto define_a_symbol;
 
     case N_ENTRY:		/* Alternate entry point.  */
       /* Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu = addr_add_offset (gdbarch, valu,
+			      ANOFFSET (section_offsets,
+					SECT_OFF_TEXT (objfile)));
       goto define_a_symbol;
 
       /* The following symbol types we don't know how to process.
@@ -3155,8 +3192,9 @@ no enclosing block"));
 	      /* Deal with the SunPRO 3.0 compiler which omits the
 	         address from N_FUN symbols.  */
 	      if (type == N_FUN
-		  && valu == ANOFFSET (section_offsets,
-				       SECT_OFF_TEXT (objfile))
+		  && addr_sub_offset (gdbarch, valu,
+				      ANOFFSET (section_offsets,
+						SECT_OFF_TEXT (objfile))) == 0
 		  && gdbarch_sofun_address_maybe_missing (gdbarch))
 		{
 		  CORE_ADDR minsym_valu = 
@@ -3179,7 +3217,7 @@ no enclosing block"));
 		   Solaris 2, these addresses are just absolute, or
 		   relative to the N_SO, depending on
 		   BLOCK_ADDRESS_ABSOLUTE.  */
-		function_start_offset = valu;
+		function_start_offset = addr_to_offset (gdbarch, valu);
 
 	      within_function = 1;
 
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -101,8 +101,11 @@ typedef bfd_byte gdb_byte;
 /* An address in the program being debugged.  Host byte order.  */
 typedef bfd_vma CORE_ADDR;
 
-/* The largest CORE_ADDR value.  */
-#define CORE_ADDR_MAX (~ (CORE_ADDR) 0)
+typedef struct
+  {
+    CORE_ADDR a;
+  }
+addr_offset_t;
 
 /* This is to make sure that LONGEST is at least as big as CORE_ADDR.  */
 
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -439,8 +439,9 @@ execute_cfa_program (struct dwarf2_fde *fde, gdb_byte *insn_ptr,
 					   fde->cie->addr_size, insn_ptr,
 					   &bytes_read, fde->initial_location);
 	      /* Apply the objfile offset for relocatable objects.  */
-	      fs->pc += ANOFFSET (fde->cie->unit->objfile->section_offsets,
-				  SECT_OFF_TEXT (fde->cie->unit->objfile));
+	      fs->pc = addr_add_offset (gdbarch, fs->pc,
+			    ANOFFSET (fde->cie->unit->objfile->section_offsets,
+				      SECT_OFF_TEXT (fde->cie->unit->objfile)));
 	      insn_ptr += bytes_read;
 	      break;
 
@@ -1577,9 +1578,10 @@ dwarf2_frame_find_fde (CORE_ADDR *pc)
 
   ALL_OBJFILES (objfile)
     {
+      struct gdbarch *gdbarch = get_objfile_arch (objfile);
       struct dwarf2_fde_table *fde_table;
       struct dwarf2_fde **p_fde;
-      CORE_ADDR offset;
+      addr_offset_t offset;
       CORE_ADDR seek_pc;
 
       fde_table = objfile_data (objfile, dwarf2_frame_objfile_data);
@@ -1590,15 +1592,17 @@ dwarf2_frame_find_fde (CORE_ADDR *pc)
       offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
       gdb_assert (fde_table->num_entries > 0);
-      if (*pc < offset + fde_table->entries[0]->initial_location)
+      if (*pc < addr_add_offset (gdbarch,
+				 fde_table->entries[0]->initial_location,
+				 offset))
         continue;
 
-      seek_pc = *pc - offset;
+      seek_pc = addr_sub_offset (gdbarch, *pc, offset);
       p_fde = bsearch (&seek_pc, fde_table->entries, fde_table->num_entries,
                        sizeof (fde_table->entries[0]), bsearch_fde_cmp);
       if (p_fde != NULL)
         {
-          *pc = (*p_fde)->initial_location + offset;
+          *pc = addr_add_offset (gdbarch, (*p_fde)->initial_location, offset);
           return *p_fde;
         }
     }
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -67,9 +67,10 @@ find_location_expression (struct dwarf2_loclist_baton *baton,
   unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
-  CORE_ADDR base_offset = ANOFFSET (objfile->section_offsets,
-				    SECT_OFF_TEXT (objfile));
-  CORE_ADDR base_address = baton->base_address + base_offset;
+  addr_offset_t base_offset = ANOFFSET (objfile->section_offsets,
+					SECT_OFF_TEXT (objfile));
+  CORE_ADDR base_address = addr_add_offset (gdbarch, baton->base_address,
+					    base_offset);
 
   loc_ptr = baton->data;
   buf_end = baton->data + baton->size;
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -967,7 +967,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 *);
+                                        addr_offset_t, struct dwarf2_cu *);
 
 static void dwarf2_add_field (struct field_info *, struct die_info *,
 			      struct dwarf2_cu *);
@@ -1865,11 +1865,12 @@ process_psymtab_comp_unit (struct objfile *objfile,
 			   gdb_byte *buffer, gdb_byte *info_ptr,
 			   unsigned int buffer_size)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = objfile->obfd;
   gdb_byte *beg_of_comp_unit = info_ptr;
   struct die_info *comp_unit_die;
   struct partial_symtab *pst;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
   struct cleanup *back_to_inner;
   struct dwarf2_cu cu;
   unsigned int bytes_read;
@@ -1975,8 +1976,9 @@ process_psymtab_comp_unit (struct objfile *objfile,
     /* Store the contiguous range if it is not empty; it can be empty for
        CUs with no code.  */
     addrmap_set_empty (objfile->psymtabs_addrmap,
-		       best_lowpc + baseaddr,
-		       best_highpc + baseaddr - 1, pst);
+		       addr_add_offset (gdbarch, best_lowpc, baseaddr),
+		       addr_add_offset (gdbarch, best_highpc - 1, baseaddr),
+		       pst);
 
   /* Check if comp unit has_children.
      If so, read the rest of the partial symbols from this comp unit.
@@ -1986,7 +1988,7 @@ process_psymtab_comp_unit (struct objfile *objfile,
       struct partial_die_info *first_die;
       CORE_ADDR lowpc, highpc;
 
-      lowpc = ((CORE_ADDR) -1);
+      lowpc = addr_minus_one (gdbarch);
       highpc = ((CORE_ADDR) 0);
 
       first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu);
@@ -1996,7 +1998,7 @@ process_psymtab_comp_unit (struct objfile *objfile,
 
       /* If we didn't find a lowpc, set it to highpc to avoid
 	 complaints from `maint check'.	 */
-      if (lowpc == ((CORE_ADDR) -1))
+      if (lowpc == addr_minus_one (gdbarch))
 	lowpc = highpc;
 
       /* If the compilation unit didn't have an explicit address range,
@@ -2007,8 +2009,8 @@ process_psymtab_comp_unit (struct objfile *objfile,
 	  best_highpc = highpc;
 	}
     }
-  pst->textlow = best_lowpc + baseaddr;
-  pst->texthigh = best_highpc + baseaddr;
+  pst->textlow = addr_add_offset (gdbarch, best_lowpc, baseaddr);
+  pst->texthigh = addr_add_offset (gdbarch, best_highpc, baseaddr);
 
   pst->n_global_syms = objfile->global_psymbols.next -
     (objfile->global_psymbols.list + pst->globals_offset);
@@ -2078,6 +2080,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
 {
   /* Instead of reading this into a big buffer, we should probably use
      mmap()  on architectures that support it. (FIXME) */
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = objfile->obfd;
   gdb_byte *info_ptr;
   struct cleanup *back_to;
@@ -2093,7 +2096,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
   create_all_comp_units (objfile);
 
   objfile->psymtabs_addrmap =
-    addrmap_create_mutable (&objfile->objfile_obstack);
+    addrmap_create_mutable (gdbarch, &objfile->objfile_obstack);
 
   /* Since the objects we're extracting from .debug_info vary in
      length, only the individual functions to extract them (like
@@ -2432,11 +2435,12 @@ static void
 add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   CORE_ADDR addr = 0;
   char *actual_name = NULL;
   const char *my_prefix;
   const struct partial_symbol *psym = NULL;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
   int built_actual_name = 0;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -2460,24 +2464,30 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
              of the global scope.  But in Ada, we want to be able to access
              nested procedures globally.  So all Ada subprograms are stored
              in the global scope.  */
-	  /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
-	     mst_text, objfile); */
+	  /*prim_record_minimal_symbol (actual_name,
+					addr_add_offset (gdbarch, pdi->lowpc,
+							 baseaddr),
+					mst_text, objfile); */
 	  psym = add_psymbol_to_list (actual_name, strlen (actual_name),
 				      built_actual_name,
 				      VAR_DOMAIN, LOC_BLOCK,
 				      &objfile->global_psymbols,
-				      0, pdi->lowpc + baseaddr,
+				      0, addr_add_offset (gdbarch, pdi->lowpc,
+							  baseaddr),
 				      cu->language, objfile);
 	}
       else
 	{
-	  /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
-	     mst_file_text, objfile); */
+	  /*prim_record_minimal_symbol (actual_name,
+					addr_add_offset (gdbarch, pdi->lowpc,
+							 baseaddr),
+					mst_file_text, objfile); */
 	  psym = add_psymbol_to_list (actual_name, strlen (actual_name),
 				      built_actual_name,
 				      VAR_DOMAIN, LOC_BLOCK,
 				      &objfile->static_psymbols,
-				      0, pdi->lowpc + baseaddr,
+				      0, addr_add_offset (gdbarch, pdi->lowpc,
+							  baseaddr),
 				      cu->language, objfile);
 	}
       break;
@@ -2504,7 +2514,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 					built_actual_name,
 					VAR_DOMAIN, LOC_STATIC,
 					&objfile->global_psymbols,
-					0, addr + baseaddr,
+					0, addr_add_offset (gdbarch, addr,
+							    baseaddr),
 					cu->language, objfile);
 	}
       else
@@ -2517,13 +2528,16 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 	      return;
 	    }
 	  addr = decode_locdesc (pdi->locdesc, cu);
-	  /*prim_record_minimal_symbol (actual_name, addr + baseaddr,
-	     mst_file_data, objfile); */
+	  /*prim_record_minimal_symbol (actual_name,
+					addr_add_offset (gdbarch, addr,
+							 baseaddr),
+					mst_file_data, objfile); */
 	  psym = add_psymbol_to_list (actual_name, strlen (actual_name),
 				      built_actual_name,
 				      VAR_DOMAIN, LOC_STATIC,
 				      &objfile->static_psymbols,
-				      0, addr + baseaddr,
+				      0, addr_add_offset (gdbarch, addr,
+							  baseaddr),
 				      cu->language, objfile);
 	}
       break;
@@ -2689,11 +2703,8 @@ add_partial_subprogram (struct partial_die_info *pdi,
             *highpc = pdi->highpc;
 	  if (need_pc)
 	    {
-	      CORE_ADDR baseaddr;
 	      struct objfile *objfile = cu->objfile;
 
-	      baseaddr = ANOFFSET (objfile->section_offsets,
-				   SECT_OFF_TEXT (objfile));
 	      addrmap_set_empty (objfile->psymtabs_addrmap,
 				 pdi->lowpc, pdi->highpc - 1,
 				 cu->per_cu->psymtab);
@@ -3218,11 +3229,12 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
   struct partial_symtab *pst = per_cu->psymtab;
   struct dwarf2_cu *cu = per_cu->cu;
   struct objfile *objfile = pst->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = objfile->obfd;
   CORE_ADDR lowpc, highpc;
   struct symtab *symtab;
   struct cleanup *back_to;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -3241,7 +3253,8 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
      it, by scanning the DIE's below the compilation unit.  */
   get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
 
-  symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
+  symtab = end_symtab (addr_add_offset (gdbarch, highpc, baseaddr), objfile,
+                       SECT_OFF_TEXT (objfile));
 
   /* Set symtab language to language from DW_AT_language.
      If the compilation is from a C file generated by language preprocessors,
@@ -3487,9 +3500,10 @@ static void
 read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct comp_unit_head *cu_header = &cu->header;
   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
-  CORE_ADDR lowpc = ((CORE_ADDR) -1);
+  CORE_ADDR lowpc = addr_minus_one (gdbarch);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
   char *name = NULL;
@@ -3497,7 +3511,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
   struct line_header *line_header = 0;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
   
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -3505,10 +3519,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   /* If we didn't find a lowpc, set it to highpc to avoid complaints
      from finish_block.  */
-  if (lowpc == ((CORE_ADDR) -1))
+  if (lowpc == addr_minus_one (gdbarch))
     lowpc = highpc;
-  lowpc += baseaddr;
-  highpc += baseaddr;
+  lowpc = addr_add_offset (gdbarch, lowpc, baseaddr);
+  highpc = addr_add_offset (gdbarch, highpc, baseaddr);
 
   /* Find the filename.  Do not use dwarf2_name here, since the filename
      is not a source language identifier.  */
@@ -3610,6 +3624,7 @@ static void
 read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   CORE_ADDR lowpc;
   struct attribute *attr;
@@ -3621,7 +3636,8 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   /* start_symtab needs a low pc, but we don't really have one.
      Do what read_file_scope would do in the absence of such info.  */
-  lowpc = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+  lowpc = addr_add_offset (gdbarch, 0, ANOFFSET (objfile->section_offsets,
+                                                 SECT_OFF_TEXT (objfile)));
 
   /* Find the filename.  Do not use dwarf2_name here, since the filename
      is not a source language identifier.  */
@@ -3824,13 +3840,14 @@ static void
 read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct context_stack *new;
   CORE_ADDR lowpc;
   CORE_ADDR highpc;
   struct die_info *child_die;
   struct attribute *attr, *call_line, *call_file;
   char *name;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
   struct block *block;
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
 
@@ -3857,8 +3874,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
     return;
 
-  lowpc += baseaddr;
-  highpc += baseaddr;
+  lowpc = addr_add_offset (gdbarch, lowpc, baseaddr);
+  highpc = addr_add_offset (gdbarch, highpc, baseaddr);
 
   /* Record the function range for dwarf_decode_lines.  */
   add_to_cu_func_list (name, lowpc, highpc, cu);
@@ -3930,10 +3947,11 @@ static void
 read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct context_stack *new;
   CORE_ADDR lowpc, highpc;
   struct die_info *child_die;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -3944,8 +3962,8 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
      describe ranges.  */
   if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
     return;
-  lowpc += baseaddr;
-  highpc += baseaddr;
+  lowpc = addr_add_offset (gdbarch, lowpc, baseaddr);
+  highpc = addr_add_offset (gdbarch, highpc, baseaddr);
 
   push_context (0, lowpc);
   if (die->child != NULL)
@@ -3991,6 +4009,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 		    struct partial_symtab *ranges_pst)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct comp_unit_head *cu_header = &cu->header;
   bfd *obfd = objfile->obfd;
   unsigned int addr_size = cu_header->addr_size;
@@ -4004,7 +4023,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
   int low_set;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
 
   found_base = cu->base_known;
   base = cu->base_address;
@@ -4075,7 +4094,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 
       if (ranges_pst != NULL && range_beginning < range_end)
 	addrmap_set_empty (objfile->psymtabs_addrmap,
-			   range_beginning + baseaddr, range_end - 1 + baseaddr,
+			   addr_add_offset (gdbarch, range_beginning, baseaddr),
+			   addr_add_offset (gdbarch, range_end - 1, baseaddr),
 			   ranges_pst);
 
       /* FIXME: This is recording everything as a low-high
@@ -4215,7 +4235,8 @@ get_scope_pc_bounds (struct die_info *die,
 		     CORE_ADDR *lowpc, CORE_ADDR *highpc,
 		     struct dwarf2_cu *cu)
 {
-  CORE_ADDR best_low = (CORE_ADDR) -1;
+  struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
+  CORE_ADDR best_low = addr_minus_one (gdbarch);
   CORE_ADDR best_high = (CORE_ADDR) 0;
   CORE_ADDR current_low, current_high;
 
@@ -4245,7 +4266,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 != addr_minus_one (gdbarch))
 	      {
 		best_low = min (best_low, current_low);
 		best_high = max (best_high, current_high);
@@ -4268,8 +4289,9 @@ get_scope_pc_bounds (struct die_info *die,
    in DIE.  */
 static void
 dwarf2_record_block_ranges (struct die_info *die, struct block *block,
-                            CORE_ADDR baseaddr, struct dwarf2_cu *cu)
+                            addr_offset_t baseaddr, struct dwarf2_cu *cu)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
   struct attribute *attr;
 
   attr = dwarf2_attr (die, DW_AT_high_pc, cu);
@@ -4280,7 +4302,10 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
       if (attr)
         {
           CORE_ADDR low = DW_ADDR (attr);
-          record_block_range (block, baseaddr + low, baseaddr + high - 1);
+
+          record_block_range (gdbarch, block,
+			      addr_add_offset (gdbarch, low, baseaddr),
+	                      addr_add_offset (gdbarch, high - 1, baseaddr));
         }
     }
 
@@ -4350,9 +4375,11 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
                   return;
                 }
 
-              record_block_range (block, 
-                                  baseaddr + base + start, 
-                                  baseaddr + base + end - 1);
+              record_block_range (gdbarch, block,
+                                  addr_add_offset (gdbarch, base + start,
+						   baseaddr),
+                                  addr_add_offset (gdbarch, base + end - 1,
+				                   baseaddr));
             }
         }
     }
@@ -7905,7 +7932,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
   gdb_byte *line_end;
   unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op, adj_opcode;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
   struct objfile *objfile = cu->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
   const int decode_for_pst_p = (pst != NULL);
@@ -8000,7 +8027,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
 		case DW_LNE_set_address:
 		  address = read_address (abfd, line_ptr, cu, &bytes_read);
 		  line_ptr += bytes_read;
-		  address += baseaddr;
+		  address = addr_add_offset (gdbarch, address, baseaddr);
 		  break;
 		case DW_LNE_define_file:
                   {
@@ -8267,6 +8294,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
 		     struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct comp_unit_head *cu_header = &cu->header;
 
   /* NOTE drow/2003-01-30: There used to be a comment and some special
@@ -8302,8 +8330,10 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
 	read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
       SYMBOL_CLASS (sym) = LOC_STATIC;
       fixup_symbol_section (sym, objfile);
-      SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
-					      SYMBOL_SECTION (sym));
+      SYMBOL_VALUE_ADDRESS (sym) = addr_add_offset (gdbarch,
+						    SYMBOL_VALUE_ADDRESS (sym),
+					     ANOFFSET (objfile->section_offsets,
+						       SYMBOL_SECTION (sym)));
       return;
     }
 
@@ -8328,11 +8358,12 @@ static struct symbol *
 new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symbol *sym = NULL;
   char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
-  CORE_ADDR baseaddr;
+  addr_offset_t baseaddr;
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -8392,9 +8423,9 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
 	case DW_TAG_label:
 	  attr = dwarf2_attr (die, DW_AT_low_pc, cu);
 	  if (attr)
-	    {
-	      SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
-	    }
+	    SYMBOL_VALUE_ADDRESS (sym) = addr_add_offset (gdbarch,
+							  DW_ADDR (attr),
+							  baseaddr);
 	  SYMBOL_CLASS (sym) = LOC_LABEL;
 	  break;
 	case DW_TAG_subprogram:
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -226,7 +226,7 @@ elf_symtab_read (struct objfile *objfile, int type,
   asymbol *sym;
   long i;
   CORE_ADDR symaddr;
-  CORE_ADDR offset;
+  addr_offset_t offset;
   enum minimal_symbol_type ms_type;
   /* If sectinfo is nonNULL, it contains section info that should end up
      filed in the objfile.  */
@@ -298,7 +298,9 @@ elf_symtab_read (struct objfile *objfile, int type,
 	  if (!sect)
 	    continue;
 
-	  symaddr += ANOFFSET (objfile->section_offsets, sect->index);
+	  symaddr = addr_add_offset (gdbarch, symaddr,
+				     ANOFFSET (objfile->section_offsets,
+					       sect->index));
 
 	  msym = record_minimal_symbol
 	    (sym->name, strlen (sym->name), copy_names,
@@ -343,9 +345,7 @@ elf_symtab_read (struct objfile *objfile, int type,
 	     section offset.  */
 	  if (sym->section != &bfd_abs_section
 	      && !(sym->section->flags & SEC_THREAD_LOCAL))
-	    {
-	      symaddr += offset;
-	    }
+	    symaddr = addr_add_offset (gdbarch, symaddr, offset);
 	  /* For non-absolute symbols, use the type of the section
 	     they are relative to, to intuit text/data.  Bfd provides
 	     no way of figuring this out for absolute symbols. */
@@ -381,7 +381,7 @@ elf_symtab_read (struct objfile *objfile, int type,
 		{
 		  if (sym->name[0] == '.')
 		    continue;
-		  symaddr += offset;
+		  symaddr = addr_add_offset (gdbarch, symaddr, offset);
 		}
 	    }
 	  else if (sym->section->flags & SEC_CODE)
@@ -483,7 +483,7 @@ elf_symtab_read (struct objfile *objfile, int type,
 		      /* Relocate non-absolute symbols by the
 			 section offset.  */
 		      if (sym->section != &bfd_abs_section)
-			symaddr += offset;
+			symaddr = addr_add_offset (gdbarch, symaddr, offset);
 		      sectinfo->sections[special_local_sect] = symaddr;
 		      /* The special local symbols don't go in the
 			 minimal symbol table, so ignore this one.  */
@@ -991,6 +991,7 @@ elf_symfile_init (struct objfile *objfile)
 void
 elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   char *filename = pst->filename;
   struct dbx_symfile_info *dbx = objfile->deprecated_sym_stab_info;
   struct stab_section_info *maybe = dbx->stab_section_info;
@@ -1034,7 +1035,8 @@ elfstab_offset_sections (struct objfile *objfile, struct partial_symtab *pst)
 	obstack_alloc (&objfile->objfile_obstack, 
 		       SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
       for (i = 0; i < maybe->num_sections; i++)
-	(pst->section_offsets)->offsets[i] = maybe->sections[i];
+	(pst->section_offsets)->offsets[i] = addr_to_offset (gdbarch,
+							    maybe->sections[i]);
       return;
     }
 
--- a/gdb/findcmd.c
+++ b/gdb/findcmd.c
@@ -49,7 +49,7 @@ put_bits (bfd_uint64_t data, char *buf, int bits, bfd_boolean big_p)
    Parse the arguments of the "find" command.  */
 
 static void
-parse_find_args (char *args, ULONGEST *max_countp,
+parse_find_args (struct gdbarch *gdbarch, char *args, ULONGEST *max_countp,
 		 char **pattern_bufp, ULONGEST *pattern_lenp,
 		 CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
 		 bfd_boolean big_p)
@@ -137,7 +137,7 @@ parse_find_args (char *args, ULONGEST *max_countp,
       if (len < 0)
 	error (_("Invalid length."));
       /* Watch for overflows.  */
-      if (len > CORE_ADDR_MAX
+      if (len > addr_minus_one (gdbarch)
 	  || (start_addr + len - 1) < start_addr)
 	error (_("Search space too large."));
       search_space_len = len;
@@ -254,7 +254,7 @@ find_command (char *args, int from_tty)
   CORE_ADDR last_found_addr;
   struct cleanup *old_cleanups;
 
-  parse_find_args (args, &max_count, &pattern_buf, &pattern_len, 
+  parse_find_args (gdbarch, args, &max_count, &pattern_buf, &pattern_len,
 		   &start_addr, &search_space_len, big_p);
 
   old_cleanups = make_cleanup (free_current_contents, &pattern_buf);
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1822,7 +1822,12 @@ get_frame_address_in_block (struct frame_info *this_frame)
   if (get_frame_type (next_frame) == NORMAL_FRAME
       && (get_frame_type (this_frame) == NORMAL_FRAME
 	  || get_frame_type (this_frame) == INLINE_FRAME))
-    return pc - 1;
+    {
+      /* Return PC - 1.  */
+      addr_offset_t offset = { 1 };
+
+      return addr_sub_offset (get_frame_arch (this_frame), pc, offset);
+    }
 
   return pc;
 }
--- a/gdb/hppa-hpux-tdep.c
+++ b/gdb/hppa-hpux-tdep.c
@@ -94,8 +94,12 @@ hppa32_hpux_in_solib_call_trampoline (struct gdbarch *gdbarch,
   struct unwind_table_entry *u;
 
   /* First see if PC is in one of the two C-library trampolines.  */
-  if (pc == hppa_symbol_address("$$dyncall") 
-      || pc == hppa_symbol_address("_sr4export"))
+
+  minsym = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
+  if (minsym != NULL && pc == SYMBOL_VALUE_ADDRESS (minsym))
+    return 1;
+  minsym = lookup_minimal_symbol ("_sr4export", NULL, NULL);
+  if (minsym != NULL && pc == SYMBOL_VALUE_ADDRESS (minsym))
     return 1;
 
   minsym = lookup_minimal_symbol_by_pc (pc);
@@ -317,7 +321,8 @@ hppa_hpux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
   /* Addresses passed to dyncall may *NOT* be the actual address
      of the function.  So we may have to do something special.  */
-  if (pc == hppa_symbol_address("$$dyncall"))
+  msym = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
+  if (msym != NULL && pc == SYMBOL_VALUE_ADDRESS (msym))
     {
       pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22);
 
@@ -327,13 +332,18 @@ hppa_hpux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
       if (pc & 0x2)
 	pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, word_size, byte_order);
     }
-  if (pc == hppa_symbol_address("$$dyncall_external"))
+  msym = lookup_minimal_symbol ("$$dyncall_external", NULL, NULL);
+  if (msym != NULL && pc == SYMBOL_VALUE_ADDRESS (msym))
     {
       pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22);
       pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, word_size, byte_order);
     }
-  else if (pc == hppa_symbol_address("_sr4export"))
-    pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22);
+  else
+    {
+      msym = lookup_minimal_symbol ("_sr4export", NULL, NULL);
+      if (msym != NULL && pc == SYMBOL_VALUE_ADDRESS (msym))
+	pc = (CORE_ADDR) get_frame_register_unsigned (frame, 22);
+    }
 
   /* Get the unwind descriptor corresponding to PC, return zero
      if no unwind was found.  */
@@ -853,6 +863,7 @@ hppa32_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
   CORE_ADDR addr, rp;
   char buf[4];
   unsigned int insn;
+  struct minimal_symbol *minsym;
 
   sec = find_pc_section (pc);
   obj = sec->objfile;
@@ -910,8 +921,10 @@ hppa32_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
 
   /* Finally, if this is the main executable, try to locate a sequence 
      from noshlibs */
-  addr = hppa_symbol_address ("noshlibs");
-  sec = find_pc_section (addr);
+  minsym = lookup_minimal_symbol ("noshlibs", NULL, NULL);
+  if (minsym == NULL)
+    return 0;
+  sec = find_pc_section (SYMBOL_VALUE_ADDRESS (minsym));
 
   if (sec && sec->objfile == obj)
     {
@@ -1473,11 +1486,17 @@ hppa_hpux_unwind_adjust_stub (struct frame_info *this_frame, CORE_ADDR base,
       stubpc = read_memory_integer (base - 24, word_size, byte_order);
       trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
     }
-  else if (hppa_symbol_address ("__gcc_plt_call") 
-           == get_pc_function_start (pcoq_head))
+  else
     {
-      stubpc = read_memory_integer (base - 8, word_size, byte_order);
-      trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
+      struct minimal_symbol *minsym;
+
+      minsym = lookup_minimal_symbol ("__gcc_plt_call", NULL, NULL);
+      if (minsym != NULL
+          && SYMBOL_VALUE_ADDRESS (minsym) == get_pc_function_start (pcoq_head))
+	{
+	  stubpc = read_memory_integer (base - 8, word_size, byte_order);
+	  trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
+	}
     }
 }
 
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -161,18 +161,6 @@ hppa_extract_17 (unsigned word)
 		      (word & 0x1) << 16, 17) << 2;
 }
 
-CORE_ADDR 
-hppa_symbol_address(const char *sym)
-{
-  struct minimal_symbol *minsym;
-
-  minsym = lookup_minimal_symbol (sym, NULL, NULL);
-  if (minsym)
-    return SYMBOL_VALUE_ADDRESS (minsym);
-  else
-    return (CORE_ADDR)-1;
-}
-
 struct hppa_objfile_private *
 hppa_init_objfile_priv_data (struct objfile *objfile)
 {
@@ -223,7 +211,7 @@ record_text_segment_lowaddr (bfd *abfd, asection *section, void *data)
 static void
 internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
 		     asection *section, unsigned int entries, unsigned int size,
-		     CORE_ADDR text_offset)
+		     addr_offset_t text_offset)
 {
   /* We will read the unwind entries into temporary memory, then
      fill in the actual unwind table.  */
@@ -242,7 +230,7 @@ internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
 	 Note that when loading a shared library (text_offset != 0) the
 	 unwinds are already relative to the text_offset that will be
 	 passed in.  */
-      if (gdbarch_tdep (gdbarch)->is_elf && text_offset == 0)
+      if (gdbarch_tdep (gdbarch)->is_elf && text_offset.a == 0)
 	{
           low_text_segment_address = -1;
 
@@ -250,11 +238,11 @@ internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
 				 record_text_segment_lowaddr, 
 				 &low_text_segment_address);
 
-	  text_offset = low_text_segment_address;
+	  text_offset.a = low_text_segment_address;
 	}
       else if (gdbarch_tdep (gdbarch)->solib_get_text_base)
         {
-	  text_offset = gdbarch_tdep (gdbarch)->solib_get_text_base (objfile);
+	  text_offset.a = gdbarch_tdep (gdbarch)->solib_get_text_base (objfile);
 	}
 
       bfd_get_section_contents (objfile->obfd, section, buf, 0, size);
@@ -265,10 +253,14 @@ internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
 	{
 	  table[i].region_start = bfd_get_32 (objfile->obfd,
 					      (bfd_byte *) buf);
-	  table[i].region_start += text_offset;
+	  table[i].region_start = addr_add_offset (get_objfile_arch (objfile),
+						   table[i].region_start,
+						   text_offset);
 	  buf += 4;
 	  table[i].region_end = bfd_get_32 (objfile->obfd, (bfd_byte *) buf);
-	  table[i].region_end += text_offset;
+	  table[i].region_end = addr_add_offset (get_objfile_arch (objfile),
+						 table[i].region_end,
+						 text_offset);
 	  buf += 4;
 	  tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf);
 	  buf += 4;
@@ -325,7 +317,7 @@ read_unwind_info (struct objfile *objfile)
   unsigned unwind_size, stub_unwind_size, total_size;
   unsigned index, unwind_entries;
   unsigned stub_entries, total_entries;
-  CORE_ADDR text_offset;
+  addr_offset_t text_offset;
   struct hppa_unwind_info *ui;
   struct hppa_objfile_private *obj_private;
 
@@ -422,7 +414,9 @@ read_unwind_info (struct objfile *objfile)
 	     Stuff away the stub type into "reserved" fields.  */
 	  ui->table[index].region_start = bfd_get_32 (objfile->obfd,
 						      (bfd_byte *) buf);
-	  ui->table[index].region_start += text_offset;
+	  ui->table[index].region_start
+	    = addr_add_offset (get_objfile_arch (objfile),
+			       ui->table[index].region_start, text_offset);
 	  buf += 4;
 	  ui->table[index].stub_unwind.stub_type = bfd_get_8 (objfile->obfd,
 							  (bfd_byte *) buf);
@@ -2841,8 +2835,13 @@ static int
 hppa_in_dyncall (CORE_ADDR pc)
 {
   struct unwind_table_entry *u;
+  struct minimal_symbol *minsym;
+
+  minsym = lookup_minimal_symbol ("$$dyncall", NULL, NULL);
+  if (minsym == NULL)
+    return 0;
 
-  u = find_unwind_entry (hppa_symbol_address ("$$dyncall"));
+  u = find_unwind_entry (SYMBOL_VALUE_ADDRESS (minsym));
   if (!u)
     return 0;
 
--- a/gdb/hppa-tdep.h
+++ b/gdb/hppa-tdep.h
@@ -223,7 +223,6 @@ unsigned hppa_extract_5r_store (unsigned int);
 int hppa_extract_17 (unsigned int);
 int hppa_extract_21 (unsigned);
 int hppa_extract_14 (unsigned);
-CORE_ADDR hppa_symbol_address(const char *sym);
 
 extern struct value *
   hppa_frame_prev_register_helper (struct frame_info *this_frame,
--- a/gdb/hppabsd-tdep.c
+++ b/gdb/hppabsd-tdep.c
@@ -87,8 +87,9 @@ hppabsd_find_global_pointer (struct gdbarch *gdbarch, struct value *function)
 		     we have to do it ourselves.  */
 		  pltgot = extract_unsigned_integer (buf, sizeof buf,
 						     byte_order);
-		  pltgot += ANOFFSET (sec->objfile->section_offsets,
-				      SECT_OFF_TEXT (sec->objfile));
+		  pltgot = addr_add_offset (gdbarch, pltgot,
+				       ANOFFSET (sec->objfile->section_offsets,
+						 SECT_OFF_TEXT (sec->objfile)));
 
 		  return pltgot;
 		}
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -793,7 +793,6 @@ i386_linux_resume (struct target_ops *ops,
     {
       struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid));
       struct gdbarch *gdbarch = get_regcache_arch (regcache);
-      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       ULONGEST pc;
       gdb_byte buf[LINUX_SYSCALL_LEN];
 
@@ -821,12 +820,14 @@ i386_linux_resume (struct target_ops *ops,
 	  /* Then check the system call number.  */
 	  if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn)
 	    {
-	      ULONGEST sp, addr;
+	      ULONGEST sp;
+	      CORE_ADDR addr;
 	      unsigned long int eflags;
+	      struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
 	      regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp);
 	      if (syscall == SYS_rt_sigreturn)
-		addr = read_memory_integer (sp + 8, 4, byte_order) + 20;
+		addr = read_memory_typed_address (sp + 8, ptr_type) + 20;
 	      else
 		addr = sp;
 
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -654,7 +654,7 @@ inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
 
   /* This isn't really an address, but ptrace thinks of it as one.  */
   addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0);
-  if (addr == (CORE_ADDR)-1
+  if (addr == addr_minus_one (gdbarch)
       || gdbarch_cannot_fetch_register (gdbarch, regnum))
     {
       regcache_raw_supply (regcache, regnum, NULL);
@@ -715,7 +715,7 @@ inf_ptrace_store_register (const struct regcache *regcache, int regnum)
 
   /* This isn't really an address, but ptrace thinks of it as one.  */
   addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1);
-  if (addr == (CORE_ADDR)-1 
+  if (addr == addr_minus_one (gdbarch)
       || gdbarch_cannot_store_register (gdbarch, regnum))
     return;
 
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -580,7 +580,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   post_create_inferior (&current_target, 0);
 
   /* Start the target running.  */
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+  proceed (addr_minus_one (target_gdbarch), TARGET_SIGNAL_0, 0);
 
   /* Since there was no error, there's no need to finish the thread
      states here.  */
@@ -619,6 +619,8 @@ start_command (char *args, int from_tty)
 static int
 proceed_thread_callback (struct thread_info *thread, void *arg)
 {
+  struct gdbarch *gdbarch = target_thread_architecture (thread->ptid);
+
   /* We go through all threads individually instead of compressing
      into a single target `resume_all' request, because some threads
      may be stopped in internal breakpoints/events, or stopped waiting
@@ -633,7 +635,7 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
 
   switch_to_thread (thread->ptid);
   clear_proceed_status ();
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+  proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
   return 0;
 }
 
@@ -667,10 +669,13 @@ continue_1 (int all_threads)
     }
   else
     {
+      struct gdbarch *gdbarch;
+
       ensure_valid_thread ();
       ensure_not_running ();
       clear_proceed_status ();
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+      gdbarch = target_thread_architecture (inferior_ptid);
+      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
     }
 }
 
@@ -953,6 +958,8 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
 	 INFERIOR_PTID thread instead, which is the same thread when
 	 THREAD is set.  */
       struct thread_info *tp = inferior_thread ();
+      struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);
+
       clear_proceed_status ();
       set_step_frame ();
 
@@ -1009,7 +1016,7 @@ which has no line number information.\n"), name);
 	tp->step_over_calls = STEP_OVER_ALL;
 
       tp->step_multi = (count > 1);
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 1);
 
       /* For async targets, register a continuation to do any
 	 additional steps.  For sync targets, the caller will handle
@@ -1143,11 +1150,13 @@ signal_command (char *signum_exp, int from_tty)
 {
   enum target_signal oursig;
   int async_exec = 0;
+  struct gdbarch *gdbarch;
 
   dont_repeat ();		/* Too dangerous.  */
   ERROR_NO_INFERIOR;
   ensure_valid_thread ();
   ensure_not_running ();
+  gdbarch = target_thread_architecture (inferior_ptid);
 
   /* Find out whether we must run in the background.  */
   if (signum_exp != NULL)
@@ -1195,7 +1204,7 @@ signal_command (char *signum_exp, int from_tty)
     }
 
   clear_proceed_status ();
-  proceed ((CORE_ADDR) -1, oursig, 0);
+  proceed (addr_minus_one (gdbarch), oursig, 0);
 }
 
 /* Proceed until we reach a different source line with pc greater than
@@ -1214,6 +1223,7 @@ until_next_command (int from_tty)
   struct symbol *func;
   struct symtab_and_line sal;
   struct thread_info *tp = inferior_thread ();
+  struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);
 
   clear_proceed_status ();
   set_step_frame ();
@@ -1249,7 +1259,7 @@ until_next_command (int from_tty)
 
   tp->step_multi = 0;		/* Only one call to proceed */
 
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+  proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 1);
 }
 
 static void
@@ -1480,7 +1490,7 @@ finish_backward (struct symbol *function)
          until we've done another reverse single-step.  */
       make_breakpoint_silent (breakpoint);
       old_chain = make_cleanup_delete_breakpoint (breakpoint);
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
       /* We will be stopped when proceed returns.  */
       back_up = bpstat_find_breakpoint (tp->stop_bpstat, breakpoint) != NULL;
       do_cleanups (old_chain);
@@ -1489,11 +1499,14 @@ finish_backward (struct symbol *function)
     back_up = 1;
   if (back_up)
     {
+      struct frame_info *frame = get_selected_frame (NULL);
+      struct gdbarch *gdbarch = get_frame_arch (frame);
+
       /* If in fact we hit the step-resume breakpoint (and not
 	 some other breakpoint), then we're almost there --
 	 we just need to back up by one more single-step.  */
       tp->step_range_start = tp->step_range_end = 1;
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 1);
     }
   return;
 }
@@ -1526,7 +1539,7 @@ finish_forward (struct symbol *function, struct frame_info *frame)
   cargs->function = function;
   add_continuation (tp, finish_command_continuation, cargs,
                     finish_command_continuation_free_arg);
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+  proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
 
   discard_cleanups (old_chain);
   if (!target_can_async_p ())
@@ -1588,6 +1601,7 @@ finish_command (char *arg, int from_tty)
 	 step_range_end, because then infrun will think this is nexti,
 	 and not step over the rest of this inlined function call.  */
       struct thread_info *tp = inferior_thread ();
+      struct gdbarch *gdbarch = target_thread_architecture (inferior_ptid);
       struct symtab_and_line empty_sal;
       init_sal (&empty_sal);
       set_step_info (frame, empty_sal);
@@ -1602,7 +1616,7 @@ finish_command (char *arg, int from_tty)
 	  print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
 	}
 
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
+      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 1);
       return;
     }
 
@@ -2162,9 +2176,11 @@ proceed_after_attach_callback (struct thread_info *thread,
       && !thread->stop_requested
       && thread->stop_signal == TARGET_SIGNAL_0)
     {
+      struct gdbarch *gdbarch = target_thread_architecture (thread->ptid);
+
       switch_to_thread (thread->ptid);
       clear_proceed_status ();
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
     }
 
   return 0;
@@ -2264,8 +2280,11 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 	{
 	  if (inferior_thread ()->stop_signal == TARGET_SIGNAL_0)
 	    {
+	      struct gdbarch *gdbarch;
+
+	      gdbarch = target_thread_architecture (inferior_ptid);
 	      clear_proceed_status ();
-	      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+	      proceed (addr_minus_one (gdbarch), TARGET_SIGNAL_DEFAULT, 0);
 	    }
 	}
     }
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -484,7 +484,8 @@ proceed_after_vfork_done (struct thread_info *thread,
 
       switch_to_thread (thread->ptid);
       clear_proceed_status ();
-      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+      proceed (addr_minus_one (target_thread_architecture (thread->ptid)),
+	       TARGET_SIGNAL_DEFAULT, 0);
     }
 
   return 0;
@@ -1730,7 +1731,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   if (step < 0)
     stop_after_trap = 1;
 
-  if (addr == (CORE_ADDR) -1)
+  if (addr == addr_minus_one (gdbarch))
     {
       if (pc == stop_pc && breakpoint_here_p (aspace, pc)
 	  && execution_direction != EXEC_REVERSE)
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -55,9 +55,6 @@ enum gdb_regnum
   E_NUM_REGS         = E_PC_REGNUM + 1
 };
 
-/* Use an invalid address value as 'not available' marker.  */
-enum { REG_UNAVAIL = (CORE_ADDR) -1 };
-
 struct iq2000_frame_cache
 {
   /* Base address.  */
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -88,7 +88,8 @@ java_value_print (struct value *val, struct ui_file *stream,
       if (el_type == NULL)
 	{
 	  CORE_ADDR element;
-	  CORE_ADDR next_element = -1; /* dummy initial value */
+	  /* dummy initial value */
+	  CORE_ADDR next_element = addr_minus_one (gdbarch);
 
 	  /* Skip object header and length. */
 	  address += get_java_object_header_size (gdbarch) + 4;
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -5092,12 +5092,7 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object,
      Compare ADDR_BIT first to avoid a compiler warning on shift overflow.  */
 
   if (object == TARGET_OBJECT_MEMORY)
-    {
-      int addr_bit = gdbarch_addr_bit (target_gdbarch);
-
-      if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT))
-	offset &= ((ULONGEST) 1 << addr_bit) - 1;
-    }
+    addr_width_assert (target_gdbarch, offset);
 
   xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf,
 				  offset, len);
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -758,7 +758,8 @@ m68hc11_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 	return sal.end;
     }
 
-  pc = m68hc11_scan_prologue (gdbarch, pc, (CORE_ADDR) -1, &tmp_cache);
+  pc = m68hc11_scan_prologue (gdbarch, pc, addr_minus_one (gdbarch),
+			      &tmp_cache);
   return pc;
 }
 
@@ -816,7 +817,7 @@ m68hc11_frame_unwind_cache (struct frame_info *this_frame,
 
   info->saved_regs[HARD_PC_REGNUM].addr = info->size;
 
-  if (info->sp_offset != (CORE_ADDR) -1)
+  if (info->sp_offset != addr_minus_one (gdbarch))
     {
       info->saved_regs[HARD_PC_REGNUM].addr = info->sp_offset;
       this_base = get_frame_register_unsigned (this_frame, HARD_SP_REGNUM);
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -848,7 +848,8 @@ m68k_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
   int op;
 
   cache.locals = -1;
-  pc = m68k_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache);
+  pc = m68k_analyze_prologue (gdbarch, start_pc, addr_minus_one (gdbarch),
+			      &cache);
   if (cache.locals < 0)
     return start_pc;
   return pc;
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -571,18 +571,24 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
          The value of a stBlock symbol is the displacement from the
          procedure address.  */
       if (sh->st != stEnd && sh->st != stBlock)
-	sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+	sh->value = addr_add_offset (gdbarch, sh->value,
+				     ANOFFSET (section_offsets,
+					       SECT_OFF_TEXT (objfile)));
       break;
     case scData:
     case scSData:
     case scRData:
     case scPData:
     case scXData:
-      sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+      sh->value = addr_add_offset (gdbarch, sh->value,
+				   ANOFFSET (section_offsets,
+					     SECT_OFF_DATA (objfile)));
       break;
     case scBss:
     case scSBss:
-      sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+      sh->value = addr_add_offset (gdbarch, sh->value,
+				   ANOFFSET (section_offsets,
+					     SECT_OFF_BSS (objfile)));
       break;
     }
 
@@ -2516,12 +2522,16 @@ parse_partial_symbols (struct objfile *objfile)
 	{
 	case stProc:
 	  /* Beginnning of Procedure */
-	  svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	  svalue = addr_add_offset (gdbarch, svalue,
+				    ANOFFSET (objfile->section_offsets,
+					      SECT_OFF_TEXT (objfile)));
 	  break;
 	case stStaticProc:
 	  /* Load time only static procs */
 	  ms_type = mst_file_text;
-	  svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	  svalue = addr_add_offset (gdbarch, svalue,
+				    ANOFFSET (objfile->section_offsets,
+					      SECT_OFF_TEXT (objfile)));
 	  break;
 	case stGlobal:
 	  /* External symbol */
@@ -2534,18 +2544,24 @@ parse_partial_symbols (struct objfile *objfile)
 	  else if (SC_IS_DATA (ext_in->asym.sc))
 	    {
 	      ms_type = mst_data;
-	      svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  SECT_OFF_DATA (objfile)));
 	    }
 	  else if (SC_IS_BSS (ext_in->asym.sc))
 	    {
 	      ms_type = mst_bss;
-	      svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  SECT_OFF_BSS (objfile)));
 	    }
           else if (SC_IS_SBSS (ext_in->asym.sc))
             {
               ms_type = mst_bss;
-              svalue += ANOFFSET (objfile->section_offsets, 
-                                  get_section_index (objfile, ".sbss"));
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  get_section_index (objfile,
+								     ".sbss")));
             }
 	  else
 	    ms_type = mst_abs;
@@ -2579,7 +2595,9 @@ parse_partial_symbols (struct objfile *objfile)
                 continue;
                 
 	      ms_type = mst_file_text;
-	      svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  SECT_OFF_TEXT (objfile)));
 	    }
 	  else if (SC_IS_DATA (ext_in->asym.sc))
 	    {
@@ -2587,7 +2605,9 @@ parse_partial_symbols (struct objfile *objfile)
                 continue;
 
 	      ms_type = mst_file_data;
-	      svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  SECT_OFF_DATA (objfile)));
 	    }
 	  else if (SC_IS_BSS (ext_in->asym.sc))
 	    {
@@ -2595,7 +2615,9 @@ parse_partial_symbols (struct objfile *objfile)
                 continue;
 
 	      ms_type = mst_file_bss;
-	      svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  SECT_OFF_BSS (objfile)));
 	    }
           else if (SC_IS_SBSS (ext_in->asym.sc))
             {
@@ -2605,7 +2627,9 @@ parse_partial_symbols (struct objfile *objfile)
                 continue;
 
               ms_type = mst_file_bss;
-              svalue += ANOFFSET (objfile->section_offsets, sbss_sect_index);
+	      svalue = addr_add_offset (gdbarch, svalue,
+					ANOFFSET (objfile->section_offsets,
+						  sbss_sect_index));
             }
 	  else
 	    ms_type = mst_abs;
@@ -2650,7 +2674,9 @@ parse_partial_symbols (struct objfile *objfile)
 	{
 	  textlow = fh->adr;
 	  if (relocatable || textlow != 0)
-	    textlow += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+	    textlow = addr_add_offset (gdbarch, textlow,
+				       ANOFFSET (objfile->section_offsets,
+						 SECT_OFF_TEXT (objfile)));
 	}
       else
 	textlow = 0;
@@ -2739,7 +2765,9 @@ parse_partial_symbols (struct objfile *objfile)
 		      CORE_ADDR procaddr;
 		      long isym;
 
-		      sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		      sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		      if (sh.st == stStaticProc)
 			{
 			  namestring = debug_info->ss + fh->issBase + sh.iss;
@@ -2786,7 +2814,9 @@ parse_partial_symbols (struct objfile *objfile)
 			case scPData:
 			case scXData:
 			  namestring = debug_info->ss + fh->issBase + sh.iss;
-			  sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+			  sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
                           record_minimal_symbol (namestring, sh.value,
                                                  mst_file_data, sh.sc,
                                                  objfile);
@@ -2796,7 +2826,9 @@ parse_partial_symbols (struct objfile *objfile)
 			  /* FIXME!  Shouldn't this use cases for bss, 
 			     then have the default be abs? */
 			  namestring = debug_info->ss + fh->issBase + sh.iss;
-			  sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+			  sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_BSS (objfile)));
                           record_minimal_symbol (namestring, sh.value,
                                                  mst_file_bss, sh.sc,
                                                  objfile);
@@ -2851,19 +2883,25 @@ parse_partial_symbols (struct objfile *objfile)
 
 		  case N_TEXT | N_EXT:
 		  case N_NBTEXT | N_EXT:
-		    sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		    sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		    goto record_it;
 
 		  case N_DATA | N_EXT:
 		  case N_NBDATA | N_EXT:
-		    sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+		    sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 		    goto record_it;
 
 		  case N_BSS:
 		  case N_BSS | N_EXT:
 		  case N_NBBSS | N_EXT:
 		  case N_SETV | N_EXT:		/* FIXME, is this in BSS? */
-		    sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+		    sh.value = addr_add_offset (gdbarch, sh.value,
+					     ANOFFSET (objfile->section_offsets,
+						       SECT_OFF_BSS (objfile)));
 		    goto record_it;
 
 		  case N_ABS | N_EXT:
@@ -2885,7 +2923,9 @@ parse_partial_symbols (struct objfile *objfile)
 		    continue;
 
 		  case N_DATA:
-		    sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+		    sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 		    goto record_it;
 
 		  case N_UNDF | N_EXT:
@@ -2931,7 +2971,9 @@ parse_partial_symbols (struct objfile *objfile)
 		      char *p;
 		      int prev_textlow_not_set;
 
-		      valu = sh.value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		      valu = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 
 		      prev_textlow_not_set = textlow_not_set;
 
@@ -3087,7 +3129,9 @@ parse_partial_symbols (struct objfile *objfile)
 		    switch (p[1])
 		      {
 		      case 'S':
-			sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+			sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 
 			if (gdbarch_static_transform_name_p (gdbarch))
 			  namestring = gdbarch_static_transform_name
@@ -3100,7 +3144,9 @@ parse_partial_symbols (struct objfile *objfile)
 					     psymtab_language, objfile);
 			continue;
 		      case 'G':
-			sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+			sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 			/* The addresses in these entries are reported to be
 			   wrong.  See the code that reads 'G's for symtabs. */
 			add_psymbol_to_list (namestring, p - namestring, 1,
@@ -3237,7 +3283,9 @@ parse_partial_symbols (struct objfile *objfile)
 			    function_outside_compilation_unit_complaint (name);
 			    xfree (name);
 			  }
-			sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+			sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 			add_psymbol_to_list (namestring, p - namestring, 1,
 					     VAR_DOMAIN, LOC_BLOCK,
 					     &objfile->static_psymbols,
@@ -3258,7 +3306,9 @@ parse_partial_symbols (struct objfile *objfile)
 			    function_outside_compilation_unit_complaint (name);
 			    xfree (name);
 			  }
-			sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+			sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 			add_psymbol_to_list (namestring, p - namestring, 1,
 					     VAR_DOMAIN, LOC_BLOCK,
 					     &objfile->global_psymbols,
@@ -3413,18 +3463,24 @@ parse_partial_symbols (struct objfile *objfile)
 		  /* The value of a stEnd symbol is the displacement from the
 		     corresponding start symbol value, do not relocate it.  */
 		  if (sh.st != stEnd)
-		    sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		    sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		  break;
 		case scData:
 		case scSData:
 		case scRData:
 		case scPData:
 		case scXData:
-		  sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+		  sh.value = addr_add_offset (gdbarch, sh.value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 		  break;
 		case scBss:
 		case scSBss:
-		  sh.value += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+		  sh.value = addr_add_offset (gdbarch, sh.value,
+					     ANOFFSET (objfile->section_offsets,
+						       SECT_OFF_BSS (objfile)));
 		  break;
 		}
 
@@ -3636,18 +3692,24 @@ parse_partial_symbols (struct objfile *objfile)
 		{
 		case scText:
 		case scRConst:
-		  svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		  svalue = addr_add_offset (gdbarch, svalue,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		  break;
 		case scData:
 		case scSData:
 		case scRData:
 		case scPData:
 		case scXData:
-		  svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+		  svalue = addr_add_offset (gdbarch, svalue,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 		  break;
 		case scBss:
 		case scSBss:
-		  svalue += ANOFFSET (objfile->section_offsets, SECT_OFF_BSS (objfile));
+		  svalue = addr_add_offset (gdbarch, svalue,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_BSS (objfile)));
 		  break;
 		}
 
@@ -4005,8 +4067,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename)
 		      && previous_stab_code != (unsigned char) N_SO
 		      && *name == '\000')
 		    {
-		      valu += ANOFFSET (pst->section_offsets,
-					SECT_OFF_TEXT (pst->objfile));
+		      valu = addr_add_offset (gdbarch, valu,
+				       ANOFFSET (pst->section_offsets,
+						 SECT_OFF_TEXT (pst->objfile)));
 		      previous_stab_code = N_SO;
 		      st = end_symtab (valu, pst->objfile,
 				       SECT_OFF_TEXT (pst->objfile));
@@ -4056,7 +4119,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, char *filename)
 	      else
 		{
 		  /* Handle encoded stab line number. */
-		  valu += ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (pst->objfile));
+		  valu = addr_add_offset (gdbarch, valu,
+				       ANOFFSET (pst->section_offsets,
+						 SECT_OFF_TEXT (pst->objfile)));
 		  record_line (current_subfile, sh.index,
 			       gdbarch_addr_bits_remove (gdbarch, valu));
 		}
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -191,7 +191,8 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
 
   switch_to_thread (thread->ptid);
   clear_proceed_status ();
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
+  proceed (addr_minus_one (target_thread_architecture (thread->ptid)),
+	   TARGET_SIGNAL_DEFAULT, 0);
   return 0;
 }
 
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -84,9 +84,9 @@ mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
   else if (regno == mips_regnum (gdbarch)->pc)
     regaddr = PC;
   else if (regno == mips_regnum (gdbarch)->cause)
-    regaddr = store? (CORE_ADDR) -1 : CAUSE;
+    regaddr = store ? addr_minus_one (gdbarch) : CAUSE;
   else if (regno == mips_regnum (gdbarch)->badvaddr)
-    regaddr = store? (CORE_ADDR) -1 : BADVADDR;
+    regaddr = store ? addr_minus_one (gdbarch) : BADVADDR;
   else if (regno == mips_regnum (gdbarch)->lo)
     regaddr = MMLO;
   else if (regno == mips_regnum (gdbarch)->hi)
@@ -94,11 +94,11 @@ mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
   else if (regno == mips_regnum (gdbarch)->fp_control_status)
     regaddr = FPC_CSR;
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
-    regaddr = store? (CORE_ADDR) -1 : FPC_EIR;
+    regaddr = store ? addr_minus_one (gdbarch) : FPC_EIR;
   else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
     regaddr = 0;
   else
-    regaddr = (CORE_ADDR) -1;
+    regaddr = addr_minus_one (gdbarch);
 
   return regaddr;
 }
@@ -119,9 +119,9 @@ mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
   else if (regno == mips_regnum (gdbarch)->pc)
     regaddr = MIPS64_PC;
   else if (regno == mips_regnum (gdbarch)->cause)
-    regaddr = store? (CORE_ADDR) -1 : MIPS64_CAUSE;
+    regaddr = store ? addr_minus_one (gdbarch) : MIPS64_CAUSE;
   else if (regno == mips_regnum (gdbarch)->badvaddr)
-    regaddr = store? (CORE_ADDR) -1 : MIPS64_BADVADDR;
+    regaddr = store ? addr_minus_one (gdbarch) : MIPS64_BADVADDR;
   else if (regno == mips_regnum (gdbarch)->lo)
     regaddr = MIPS64_MMLO;
   else if (regno == mips_regnum (gdbarch)->hi)
@@ -129,11 +129,11 @@ mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
   else if (regno == mips_regnum (gdbarch)->fp_control_status)
     regaddr = MIPS64_FPC_CSR;
   else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
-    regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
+    regaddr = store ? addr_minus_one (gdbarch) : MIPS64_FPC_EIR;
   else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
     regaddr = 0;
   else
-    regaddr = (CORE_ADDR) -1;
+    regaddr = addr_minus_one (gdbarch);
 
   return regaddr;
 }
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -2392,7 +2392,7 @@ static int
 deal_with_atomic_sequence (struct gdbarch *gdbarch,
 			   struct address_space *aspace, CORE_ADDR pc)
 {
-  CORE_ADDR breaks[2] = {-1, -1};
+  CORE_ADDR breaks[2] = { addr_minus_one (gdbarch), addr_minus_one (gdbarch) };
   CORE_ADDR loc = pc;
   CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination.  */
   unsigned long insn;
--- a/gdb/mipsread.c
+++ b/gdb/mipsread.c
@@ -180,6 +180,7 @@ static void
 read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
 			       struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = objfile->obfd;
   struct alphacoff_dynsecinfo si;
   char *sym_secptr;
@@ -352,7 +353,9 @@ read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
 		ms_type = mst_text;
 	      else
 		ms_type = mst_file_text;
-	      sym_value += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+	      sym_value = addr_add_offset (gdbarch, sym_value,
+	                                   ANOFFSET (section_offsets,
+					             SECT_OFF_TEXT (objfile)));
 	    }
 	  else if (sym_shndx == SHN_MIPS_DATA)
 	    {
@@ -360,7 +363,9 @@ read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
 		ms_type = mst_data;
 	      else
 		ms_type = mst_file_data;
-	      sym_value += ANOFFSET (section_offsets, SECT_OFF_DATA (objfile));
+	      sym_value = addr_add_offset (gdbarch, sym_value,
+					   ANOFFSET (section_offsets,
+						     SECT_OFF_DATA (objfile)));
 	    }
 	  else if (sym_shndx == SHN_MIPS_ACOMMON)
 	    {
@@ -368,7 +373,9 @@ read_alphacoff_dynamic_symtab (struct section_offsets *section_offsets,
 		ms_type = mst_bss;
 	      else
 		ms_type = mst_file_bss;
-	      sym_value += ANOFFSET (section_offsets, SECT_OFF_BSS (objfile));
+	      sym_value = addr_add_offset (gdbarch, sym_value,
+					   ANOFFSET (section_offsets,
+						     SECT_OFF_BSS (objfile)));
 	    }
 	  else if (sym_shndx == SHN_ABS)
 	    {
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -47,7 +47,7 @@
 extern void _initialize_moxie_tdep (void);
 
 /* Use an invalid address value as 'not available' marker.  */
-enum { REG_UNAVAIL = (CORE_ADDR) -1 };
+#define REG_UNAVAIL(gdbarch) addr_minus_one (gdbarch)
 
 struct moxie_frame_cache
 {
@@ -360,7 +360,7 @@ moxie_return_value (struct gdbarch *gdbarch, struct type *func_type,
 /* Allocate and initialize a moxie_frame_cache object.  */
 
 static struct moxie_frame_cache *
-moxie_alloc_frame_cache (void)
+moxie_alloc_frame_cache (struct gdbarch *gdbarch)
 {
   struct moxie_frame_cache *cache;
   int i;
@@ -372,7 +372,7 @@ moxie_alloc_frame_cache (void)
   cache->pc = 0;
   cache->framesize = 0;
   for (i = 0; i < MOXIE_NUM_REGS; ++i)
-    cache->saved_regs[i] = REG_UNAVAIL;
+    cache->saved_regs[i] = REG_UNAVAIL (gdbarch);
 
   return cache;
 }
@@ -382,6 +382,7 @@ moxie_alloc_frame_cache (void)
 static struct moxie_frame_cache *
 moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct moxie_frame_cache *cache;
   CORE_ADDR current_pc;
   int i;
@@ -389,7 +390,7 @@ moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
   if (*this_cache)
     return *this_cache;
 
-  cache = moxie_alloc_frame_cache ();
+  cache = moxie_alloc_frame_cache (gdbarch);
   *this_cache = cache;
 
   cache->base = get_frame_register_unsigned (this_frame, MOXIE_FP_REGNUM);
@@ -399,15 +400,12 @@ moxie_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache->pc = get_frame_func (this_frame);
   current_pc = get_frame_pc (this_frame);
   if (cache->pc)
-    {
-      struct gdbarch *gdbarch = get_frame_arch (this_frame);
-      moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
-    }
+    moxie_analyze_prologue (cache->pc, current_pc, cache, gdbarch);
 
   cache->saved_sp = cache->base - cache->framesize;
 
   for (i = 0; i < MOXIE_NUM_REGS; ++i)
-    if (cache->saved_regs[i] != REG_UNAVAIL)
+    if (cache->saved_regs[i] != REG_UNAVAIL (gdbarch))
       cache->saved_regs[i] = cache->base - cache->saved_regs[i];
 
   return cache;
@@ -444,6 +442,7 @@ static struct value *
 moxie_frame_prev_register (struct frame_info *this_frame,
 			  void **this_prologue_cache, int regnum)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct moxie_frame_cache *cache = moxie_frame_cache (this_frame,
 						   this_prologue_cache);
 
@@ -452,7 +451,8 @@ moxie_frame_prev_register (struct frame_info *this_frame,
   if (regnum == MOXIE_SP_REGNUM && cache->saved_sp)
     return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
 
-  if (regnum < MOXIE_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
+  if (regnum < MOXIE_NUM_REGS
+      && cache->saved_regs[regnum] != REG_UNAVAIL (gdbarch))
     return frame_unwind_got_memory (this_frame, regnum,
 				    cache->saved_regs[regnum]);
 
--- a/gdb/nto-tdep.c
+++ b/gdb/nto-tdep.c
@@ -265,7 +265,7 @@ struct lm_info
 static CORE_ADDR
 LM_ADDR (struct so_list *so)
 {
-  if (so->lm_info->l_addr == (CORE_ADDR)-1)
+  if (so->lm_info->l_addr == addr_minus_one (target_gdbarch))
     {
       struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
       struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -702,6 +702,7 @@ free_all_objfiles (void)
 static int
 objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct obj_section *s;
   struct section_offsets *delta =
     ((struct section_offsets *) 
@@ -712,9 +713,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
     int something_changed = 0;
     for (i = 0; i < objfile->num_sections; ++i)
       {
-	delta->offsets[i] =
-	  ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
-	if (ANOFFSET (delta, i) != 0)
+	delta->offsets[i] = addr_offset_sub (gdbarch,
+					     ANOFFSET (new_offsets, i),
+					ANOFFSET (objfile->section_offsets, i));
+	if (ANOFFSET (delta, i).a != 0)
 	  something_changed = 1;
       }
     if (!something_changed)
@@ -736,7 +738,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
       if (l)
 	{
 	  for (i = 0; i < l->nitems; ++i)
-	    l->item[i].pc += ANOFFSET (delta, s->block_line_section);
+	    l->item[i].pc = addr_add_offset (gdbarch,
+					     l->item[i].pc,
+					     ANOFFSET (delta,
+						       s->block_line_section));
 	}
 
       /* Don't relocate a shared blockvector more than once.  */
@@ -755,8 +760,14 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
 	  struct dict_iterator iter;
 
 	  b = BLOCKVECTOR_BLOCK (bv, i);
-	  BLOCK_START (b) += ANOFFSET (delta, s->block_line_section);
-	  BLOCK_END (b) += ANOFFSET (delta, s->block_line_section);
+	  BLOCK_START (b) = addr_add_offset (gdbarch,
+					     BLOCK_START (b),
+					     ANOFFSET (delta,
+					               s->block_line_section));
+	  BLOCK_END (b) = addr_add_offset (gdbarch,
+					   BLOCK_END (b),
+					   ANOFFSET (delta,
+						     s->block_line_section));
 
 	  ALL_BLOCK_SYMBOLS (b, iter, sym)
 	    {
@@ -770,8 +781,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
 		   || SYMBOL_CLASS (sym) == LOC_STATIC)
 		  && SYMBOL_SECTION (sym) >= 0)
 		{
-		  SYMBOL_VALUE_ADDRESS (sym) +=
-		    ANOFFSET (delta, SYMBOL_SECTION (sym));
+		  SYMBOL_VALUE_ADDRESS (sym) = addr_add_offset (gdbarch,
+						     SYMBOL_VALUE_ADDRESS (sym),
+					       ANOFFSET (delta,
+							 SYMBOL_SECTION (sym)));
 		}
 	    }
 	}
@@ -787,8 +800,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
 
     ALL_OBJFILE_PSYMTABS (objfile, p)
     {
-      p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
-      p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+      p->textlow = addr_add_offset (gdbarch, p->textlow,
+				    ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
+      p->texthigh = addr_add_offset (gdbarch, p->texthigh,
+				     ANOFFSET (delta, SECT_OFF_TEXT (objfile)));
     }
   }
 
@@ -801,8 +816,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
       {
 	fixup_psymbol_section (*psym, objfile);
 	if (SYMBOL_SECTION (*psym) >= 0)
-	  SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
-						    SYMBOL_SECTION (*psym));
+	  SYMBOL_VALUE_ADDRESS (*psym) = addr_add_offset (gdbarch,
+						   SYMBOL_VALUE_ADDRESS (*psym),
+					     ANOFFSET (delta,
+						       SYMBOL_SECTION (*psym)));
       }
     for (psym = objfile->static_psymbols.list;
 	 psym < objfile->static_psymbols.next;
@@ -810,8 +827,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
       {
 	fixup_psymbol_section (*psym, objfile);
 	if (SYMBOL_SECTION (*psym) >= 0)
-	  SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
-						    SYMBOL_SECTION (*psym));
+	  SYMBOL_VALUE_ADDRESS (*psym) = addr_add_offset (gdbarch,
+						   SYMBOL_VALUE_ADDRESS (*psym),
+					     ANOFFSET (delta,
+						       SYMBOL_SECTION (*psym)));
       }
   }
 
@@ -819,7 +838,10 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
     struct minimal_symbol *msym;
     ALL_OBJFILE_MSYMBOLS (objfile, msym)
       if (SYMBOL_SECTION (msym) >= 0)
-      SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
+	SYMBOL_VALUE_ADDRESS (msym) = addr_add_offset (gdbarch,
+						    SYMBOL_VALUE_ADDRESS (msym),
+					      ANOFFSET (delta,
+							SYMBOL_SECTION (msym)));
   }
   /* Relocating different sections by different amounts may cause the symbols
      to be out of order.  */
@@ -832,9 +854,15 @@ objfile_relocate1 (struct objfile *objfile, struct section_offsets *new_offsets)
       struct obj_section *s;
       s = find_pc_section (objfile->ei.entry_point);
       if (s)
-        objfile->ei.entry_point += ANOFFSET (delta, s->the_bfd_section->index);
+        objfile->ei.entry_point = addr_add_offset (gdbarch,
+						   objfile->ei.entry_point,
+					  ANOFFSET (delta,
+						    s->the_bfd_section->index));
       else
-        objfile->ei.entry_point += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
+        objfile->ei.entry_point = addr_add_offset (gdbarch,
+						   objfile->ei.entry_point,
+					    ANOFFSET (delta,
+						      SECT_OFF_TEXT (objfile)));
     }
 
   {
@@ -880,6 +908,7 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
        debug_objfile;
        debug_objfile = objfile_separate_debug_iterate (objfile, debug_objfile))
     {
+      struct gdbarch *gdbarch = get_objfile_arch (debug_objfile);
       struct section_addr_info *objfile_addrs;
       struct section_offsets *new_debug_offsets;
       int new_debug_num_sections;
@@ -891,14 +920,14 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
       /* Here OBJFILE_ADDRS contain the correct absolute addresses, the
 	 relative ones must be already created according to debug_objfile.  */
 
-      addr_info_make_relative (objfile_addrs, debug_objfile->obfd);
+      addr_info_make_relative (gdbarch, objfile_addrs, debug_objfile->obfd);
 
       gdb_assert (debug_objfile->num_sections
 		  == bfd_count_sections (debug_objfile->obfd));
       new_debug_offsets = xmalloc (SIZEOF_N_SECTION_OFFSETS
 						 (debug_objfile->num_sections));
       make_cleanup (xfree, new_debug_offsets);
-      relative_addr_info_to_section_offsets (new_debug_offsets,
+      relative_addr_info_to_section_offsets (gdbarch, new_debug_offsets,
 					     debug_objfile->num_sections,
 					     objfile_addrs);
 
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -126,16 +126,20 @@ struct obj_section
   (((s)->objfile->section_offsets)->offsets[(s)->the_bfd_section->index])
 
 /* The memory address of section S (vma + offset).  */
-#define obj_section_addr(s)				      		\
-  (bfd_get_section_vma ((s)->objfile->abfd, s->the_bfd_section)		\
-   + obj_section_offset (s))
+#define obj_section_addr(s)						\
+  addr_add_offset (get_objfile_arch ((s)->objfile),			\
+		   bfd_get_section_vma ((s)->objfile->abfd,		\
+		                        s->the_bfd_section),		\
+		   obj_section_offset (s))
 
 /* The one-passed-the-end memory address of section S
    (vma + size + offset).  */
 #define obj_section_endaddr(s)						\
-  (bfd_get_section_vma ((s)->objfile->abfd, s->the_bfd_section)		\
-   + bfd_get_section_size ((s)->the_bfd_section)			\
-   + obj_section_offset (s))
+  addr_add_offset (get_objfile_arch ((s)->objfile),			\
+		   (bfd_get_section_vma ((s)->objfile->abfd,		\
+					 s->the_bfd_section)		\
+		    + bfd_get_section_size ((s)->the_bfd_section)),	\
+		   obj_section_offset (s))
 
 /* The "objstats" structure provides a place for gdb to record some
    interesting information about its internal state at runtime, on a
--- a/gdb/prologue-value.c
+++ b/gdb/prologue-value.c
@@ -420,13 +420,20 @@ find_entry (struct pv_area *area, CORE_ADDR offset)
      discontinuity.  */
   while (((e->next->offset - offset) & area->addr_mask)
          < ((e->offset - offset) & area->addr_mask))
+    {
+      gdb_assert ((e->offset & ~area->addr_mask) == 0);
     e = e->next;
+    }
 
   /* If the previous entry would be better than the current one, then
      scan backwards.  */
   while (((e->prev->offset - offset) & area->addr_mask)
          < ((e->offset - offset) & area->addr_mask))
+    {
+      gdb_assert ((e->offset & ~area->addr_mask) == 0);
     e = e->prev;
+    }
+  gdb_assert ((e->offset & ~area->addr_mask) == 0);
 
   /* In case there's some locality to the searches, set the area's
      pointer to the entry we've found.  */
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2854,7 +2854,9 @@ get_offsets (void)
 
   if (do_segments)
     {
-      int ret = symfile_map_offsets_to_segments (symfile_objfile->obfd, data,
+      int ret = symfile_map_offsets_to_segments (get_objfile_arch
+							      (symfile_objfile),
+						 symfile_objfile->obfd, data,
 						 offs, num_segments, segments);
 
       if (ret == 0 && !do_sections)
@@ -2869,14 +2871,18 @@ get_offsets (void)
 
   if (do_sections)
     {
-      offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
+      struct gdbarch *gdbarch = get_objfile_arch (symfile_objfile);
+
+      offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = addr_to_offset (gdbarch,
+								     text_addr);
 
       /* This is a temporary kludge to force data and bss to use the same offsets
 	 because that's what nlmconv does now.  The real solution requires changes
 	 to the stub and remote.c that I don't have time to do right now.  */
 
-      offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
-      offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr;
+      offs->offsets[SECT_OFF_DATA (symfile_objfile)]
+      = offs->offsets[SECT_OFF_BSS (symfile_objfile)] = addr_to_offset (gdbarch,
+								     data_addr);
     }
 
   objfile_relocate (symfile_objfile, offs);
@@ -5728,8 +5734,7 @@ remote_address_masked (CORE_ADDR addr)
       /* Only create a mask when that mask can safely be constructed
          in a ULONGEST variable.  */
       ULONGEST mask = 1;
-      mask = (mask << address_size) - 1;
-      addr &= mask;
+      gdb_assert ((addr & -(mask << address_size)) == 0);
     }
   return addr;
 }
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -1087,7 +1087,7 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
   struct address_space *aspace = get_frame_address_space (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR pc = get_frame_pc (frame);
-  CORE_ADDR breaks[2] = {-1, -1};
+  CORE_ADDR breaks[2] = { addr_minus_one (gdbarch), addr_minus_one (gdbarch) };
   CORE_ADDR loc = pc;
   CORE_ADDR closing_insn; /* Instruction that closes the atomic sequence.  */
   int insn = read_memory_integer (loc, PPC_INSN_SIZE, byte_order);
--- a/gdb/s390-nat.c
+++ b/gdb/s390-nat.c
@@ -293,12 +293,13 @@ s390_stopped_by_watchpoint (void)
 static void
 s390_fix_watch_points (ptid_t ptid)
 {
+  struct gdbarch *gdbarch = get_thread_arch_regcache (ptid);
   int tid;
 
   per_struct per_info;
   ptrace_area parea;
 
-  CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
+  CORE_ADDR watch_lo_addr = addr_minus_one (gdbarch), watch_hi_addr = 0;
   struct watch_area *area;
 
   tid = TIDGET (ptid);
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -1265,7 +1265,8 @@ s390_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct s390_prologue_data data;
   CORE_ADDR skip_pc;
-  skip_pc = s390_analyze_prologue (gdbarch, pc, (CORE_ADDR)-1, &data);
+  skip_pc = s390_analyze_prologue (gdbarch, pc, addr_minus_one (gdbarch),
+				   &data);
   return skip_pc ? skip_pc : pc;
 }
 
@@ -1510,7 +1511,8 @@ s390_prologue_frame_unwind_cache (struct frame_info *this_frame,
 	  struct s390_prologue_data data2;
 	  pv_t *sp = &data2.gpr[S390_SP_REGNUM - S390_R0_REGNUM];
 
-	  if (!(s390_analyze_prologue (gdbarch, func, (CORE_ADDR)-1, &data2)
+	  if (!(s390_analyze_prologue (gdbarch, func, addr_minus_one (gdbarch),
+				       &data2)
 	        && pv_is_register (*sp, S390_SP_REGNUM)
 	        && sp->k != 0))
 	    return 0;
--- a/gdb/score-tdep.c
+++ b/gdb/score-tdep.c
@@ -874,7 +874,7 @@ score7_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
 
   char *memblock = NULL;
   char *memblock_ptr = NULL;
-  CORE_ADDR prev_pc = -1;
+  CORE_ADDR prev_pc = addr_minus_one (gdbarch);
 
   /* Allocate MEMBLOCK if PC - STARTADDR > 0.  */
   memblock_ptr = memblock =
@@ -1067,10 +1067,11 @@ score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
                         struct frame_info *this_frame,
                         struct score_frame_cache *this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR sp;
   CORE_ADDR fp;
   CORE_ADDR cur_pc = startaddr;
-  enum bfd_endian byte_order = gdbarch_byte_order (get_frame_arch (this_frame));
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   int sp_offset = 0;
   int ra_offset = 0;
@@ -1079,7 +1080,7 @@ score3_analyze_prologue (CORE_ADDR startaddr, CORE_ADDR pc,
   int fp_offset_p = 0;
   int inst_len = 0;
 
-  CORE_ADDR prev_pc = -1;
+  CORE_ADDR prev_pc = addr_minus_one (gdbarch);
 
   sp = get_frame_register_unsigned (this_frame, SCORE_SP_REGNUM);
   fp = get_frame_register_unsigned (this_frame, SCORE_FP_REGNUM);
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -746,7 +746,8 @@ sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
     return max (pc, start_pc);
 
   cache.sp_offset = -4;
-  pc = sh_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache, 0);
+  pc = sh_analyze_prologue (gdbarch, start_pc, addr_minus_one (gdbarch), &cache,
+			    0);
   if (!cache.uses_fp)
     return start_pc;
 
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -923,7 +923,9 @@ frv_relocate_main_executable (void)
 
   ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
     {
-      CORE_ADDR orig_addr, addr, offset;
+      struct gdbarch *gdbarch = get_objfile_arch (symfile_objfile);
+      CORE_ADDR orig_addr, addr;
+      addr_offset_t offset;
       int osect_idx;
       int seg;
       
@@ -934,17 +936,18 @@ frv_relocate_main_executable (void)
       /* Offset from where this section started.  */
       offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
       /* Original address prior to any past relocations.  */
-      orig_addr = addr - offset;
+      orig_addr = addr_sub_offset (gdbarch, addr, offset);
 
       for (seg = 0; seg < ldm->nsegs; seg++)
 	{
 	  if (ldm->segs[seg].p_vaddr <= orig_addr
 	      && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
 	    {
-	      new_offsets->offsets[osect_idx]
-		= ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
+	      new_offsets->offsets[osect_idx] = addr_sub_to_offset (gdbarch,
+							ldm->segs[seg].addr,
+							ldm->segs[seg].p_vaddr);
 
-	      if (new_offsets->offsets[osect_idx] != offset)
+	      if (new_offsets->offsets[osect_idx].a != offset.a)
 		changed = 1;
 	      break;
 	    }
--- a/gdb/solib-som.c
+++ b/gdb/solib-som.c
@@ -842,12 +842,13 @@ som_solib_section_offsets (struct objfile *objfile,
          is valid.  The BFDs will never match.  Make a best guess.  */
       if (strstr (objfile->name, so_list->so_name))
 	{
+	  struct gdbarch *gdbarch = get_objfile_arch (so_list->objfile);
 	  asection *private_section;
 
 	  /* The text offset is easy.  */
 	  offsets->offsets[SECT_OFF_TEXT (objfile)]
-	    = (so_list->lm_info->text_addr
-	       - so_list->lm_info->text_link_addr);
+	    = addr_sub_to_offset (gdbarch, so_list->lm_info->text_addr,
+				  so_list->lm_info->text_link_addr);
 	  offsets->offsets[SECT_OFF_RODATA (objfile)]
 	    = ANOFFSET (offsets, SECT_OFF_TEXT (objfile));
 
@@ -858,12 +859,13 @@ som_solib_section_offsets (struct objfile *objfile,
 	  if (!private_section)
 	    {
 	      warning (_("Unable to find $PRIVATE$ in shared library!"));
-	      offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
-	      offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
+	      offsets->offsets[SECT_OFF_DATA (objfile)].a = 0;
+	      offsets->offsets[SECT_OFF_BSS (objfile)].a = 0;
 	      return 1;
 	    }
 	  offsets->offsets[SECT_OFF_DATA (objfile)]
-	    = (so_list->lm_info->data_start - private_section->vma);
+	    = addr_sub_to_offset (gdbarch, so_list->lm_info->data_start,
+				  private_section->vma);
 	  offsets->offsets[SECT_OFF_BSS (objfile)]
 	    = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
 	  return 1;
--- a/gdb/solib-spu.c
+++ b/gdb/solib-spu.c
@@ -50,17 +50,19 @@
 static void
 spu_relocate_main_executable (int spufs_fd)
 {
+  struct gdbarch *gdbarch;
   struct section_offsets *new_offsets;
   int i;
 
   if (symfile_objfile == NULL)
     return;
+  gdbarch = get_objfile_arch (symfile_objfile);
 
   new_offsets = alloca (symfile_objfile->num_sections
 			* sizeof (struct section_offsets));
 
   for (i = 0; i < symfile_objfile->num_sections; i++)
-    new_offsets->offsets[i] = SPUADDR (spufs_fd, 0);
+    new_offsets->offsets[i] = addr_to_offset (gdbarch, SPUADDR (spufs_fd, 0));
 
   objfile_relocate (symfile_objfile, new_offsets);
 }
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -173,7 +173,7 @@ LM_DYNAMIC_FROM_LINK_MAP (struct so_list *so)
 static CORE_ADDR
 LM_ADDR_CHECK (struct so_list *so, bfd *abfd)
 {
-  if (so->lm_info->l_addr == (CORE_ADDR)-1)
+  if (so->lm_info->l_addr == addr_minus_one (target_gdbarch))
     {
       struct bfd_section *dyninfo_sect;
       CORE_ADDR l_addr, l_dynaddr, dynaddr, align = 0x1000;
@@ -918,7 +918,7 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
   old_chain = make_cleanup (xfree, new);
   new->lm_info = xmalloc (sizeof (struct lm_info));
   make_cleanup (xfree, new->lm_info);
-  new->lm_info->l_addr = (CORE_ADDR)-1;
+  new->lm_info->l_addr = addr_minus_one (target_gdbarch);
   new->lm_info->lm_addr = ldsomap;
   new->lm_info->lm = xzalloc (lmo->link_map_size);
   make_cleanup (xfree, new->lm_info->lm);
@@ -1095,7 +1095,7 @@ svr4_current_sos (void)
       new->lm_info = xmalloc (sizeof (struct lm_info));
       make_cleanup (xfree, new->lm_info);
 
-      new->lm_info->l_addr = (CORE_ADDR)-1;
+      new->lm_info->l_addr = addr_minus_one (target_gdbarch);
       new->lm_info->lm_addr = lm;
       new->lm_info->lm = xzalloc (lmo->link_map_size);
       make_cleanup (xfree, new->lm_info->lm);
@@ -1343,17 +1343,19 @@ enable_break (struct svr4_info *info, int from_tty)
 	  /* Record the relocated start and end address of the dynamic linker
 	     text and plt section for svr4_in_dynsym_resolve_code.  */
 	  bfd *tmp_bfd;
-	  CORE_ADDR load_addr;
+	  addr_offset_t load_offset;
 
 	  tmp_bfd = os->objfile->obfd;
-	  load_addr = ANOFFSET (os->objfile->section_offsets,
-				os->objfile->sect_index_text);
+	  load_offset = ANOFFSET (os->objfile->section_offsets,
+				  os->objfile->sect_index_text);
 
 	  interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
 	  if (interp_sect)
 	    {
 	      info->interp_text_sect_low =
-		bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+		addr_add_offset (get_objfile_arch (os->objfile),
+				 bfd_section_vma (tmp_bfd, interp_sect),
+				 load_offset);
 	      info->interp_text_sect_high =
 		info->interp_text_sect_low
 		+ bfd_section_size (tmp_bfd, interp_sect);
@@ -1362,7 +1364,9 @@ enable_break (struct svr4_info *info, int from_tty)
 	  if (interp_sect)
 	    {
 	      info->interp_plt_sect_low =
-		bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+		addr_add_offset (get_objfile_arch (os->objfile),
+				 bfd_section_vma (tmp_bfd, interp_sect),
+				 load_offset);
 	      info->interp_plt_sect_high =
 		info->interp_plt_sect_low
 		+ bfd_section_size (tmp_bfd, interp_sect);
@@ -1378,8 +1382,8 @@ enable_break (struct svr4_info *info, int from_tty)
   interp_name = find_program_interpreter ();
   if (interp_name)
     {
-      CORE_ADDR load_addr = 0;
-      int load_addr_found = 0;
+      addr_offset_t load_offset = { 0 };
+      int load_offset_found = 0;
       int loader_found_in_list = 0;
       struct so_list *so;
       bfd *tmp_bfd = NULL;
@@ -1416,9 +1420,10 @@ enable_break (struct svr4_info *info, int from_tty)
 	{
 	  if (svr4_same_1 (interp_name, so->so_original_name))
 	    {
-	      load_addr_found = 1;
+	      load_offset_found = 1;
 	      loader_found_in_list = 1;
-	      load_addr = LM_ADDR_CHECK (so, tmp_bfd);
+	      load_offset = addr_to_offset (target_gdbarch,
+					    LM_ADDR_CHECK (so, tmp_bfd));
 	      break;
 	    }
 	  so = so->next;
@@ -1426,9 +1431,16 @@ enable_break (struct svr4_info *info, int from_tty)
 
       /* If we were not able to find the base address of the loader
          from our so_list, then try using the AT_BASE auxilliary entry.  */
-      if (!load_addr_found)
-        if (target_auxv_search (&current_target, AT_BASE, &load_addr) > 0)
-          load_addr_found = 1;
+      if (!load_offset_found)
+	{
+	  CORE_ADDR load_addr;
+
+	  if (target_auxv_search (&current_target, AT_BASE, &load_addr) > 0)
+	    {
+	      load_offset_found = 1;
+	      load_offset = addr_to_offset (target_gdbarch, load_addr);
+	    }
+	}
 
       /* Otherwise we find the dynamic linker's base address by examining
 	 the current pc (which should point at the entry point for the
@@ -1437,19 +1449,21 @@ enable_break (struct svr4_info *info, int from_tty)
          This is more fragile than the previous approaches, but is a good
          fallback method because it has actually been working well in
          most cases.  */
-      if (!load_addr_found)
+      if (!load_offset_found)
 	{
 	  struct regcache *regcache
 	    = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
-	  load_addr = (regcache_read_pc (regcache)
-		       - exec_entry_point (tmp_bfd, tmp_bfd_target));
+	  load_offset = addr_sub_to_offset (target_gdbarch,
+					    regcache_read_pc (regcache),
+					    exec_entry_point (tmp_bfd,
+							      tmp_bfd_target));
 	}
 
       if (!loader_found_in_list)
 	{
 	  info->debug_loader_name = xstrdup (interp_name);
 	  info->debug_loader_offset_p = 1;
-	  info->debug_loader_offset = load_addr;
+	  info->debug_loader_offset = load_offset.a;
 	  solib_add (NULL, from_tty, &current_target, auto_solib_add);
 	}
 
@@ -1459,7 +1473,9 @@ enable_break (struct svr4_info *info, int from_tty)
       if (interp_sect)
 	{
 	  info->interp_text_sect_low =
-	    bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+	    addr_add_offset (target_gdbarch,
+			     bfd_section_vma (tmp_bfd, interp_sect),
+			     load_offset);
 	  info->interp_text_sect_high =
 	    info->interp_text_sect_low
 	    + bfd_section_size (tmp_bfd, interp_sect);
@@ -1468,7 +1484,9 @@ enable_break (struct svr4_info *info, int from_tty)
       if (interp_sect)
 	{
 	  info->interp_plt_sect_low =
-	    bfd_section_vma (tmp_bfd, interp_sect) + load_addr;
+	    addr_add_offset (target_gdbarch,
+			     bfd_section_vma (tmp_bfd, interp_sect),
+			     load_offset);
 	  info->interp_plt_sect_high =
 	    info->interp_plt_sect_low
 	    + bfd_section_size (tmp_bfd, interp_sect);
@@ -1496,7 +1514,9 @@ enable_break (struct svr4_info *info, int from_tty)
 
       if (sym_addr != 0)
 	{
-	  create_solib_event_breakpoint (target_gdbarch, load_addr + sym_addr);
+	  sym_addr = addr_add_offset (target_gdbarch, sym_addr, load_offset);
+
+	  create_solib_event_breakpoint (target_gdbarch, sym_addr);
 	  xfree (interp_name);
 	  return 1;
 	}
@@ -1679,6 +1699,7 @@ svr4_relocate_main_executable (void)
 
   if (symfile_objfile)
     {
+      struct gdbarch *gdbarch = get_objfile_arch (symfile_objfile);
       struct section_offsets *new_offsets;
       int i;
 
@@ -1686,18 +1707,21 @@ svr4_relocate_main_executable (void)
 			    * sizeof (*new_offsets));
 
       for (i = 0; i < symfile_objfile->num_sections; i++)
-	new_offsets->offsets[i] = displacement;
+	new_offsets->offsets[i] = addr_to_offset (gdbarch, displacement);
 
       objfile_relocate (symfile_objfile, new_offsets);
     }
   else if (exec_bfd)
     {
       asection *asect;
+      addr_offset_t offset = addr_to_offset (target_gdbarch, displacement);
 
       for (asect = exec_bfd->sections; asect != NULL; asect = asect->next)
 	exec_set_section_address (bfd_get_filename (exec_bfd), asect->index,
-				  (bfd_section_vma (exec_bfd, asect)
-				   + displacement));
+				  addr_add_offset (target_gdbarch,
+						   bfd_section_vma (exec_bfd,
+								    asect),
+						   offset));
     }
 }
 
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -330,8 +330,9 @@ static void
 solib_target_relocate_section_addresses (struct so_list *so,
 					 struct target_section *sec)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (so->objfile);
   int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
-  CORE_ADDR offset;
+  addr_offset_t offset;
 
   /* Build the offset table only once per object file.  We can not do
      it any earlier, since we need to open the file first.  */
@@ -367,7 +368,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 	      section_bases = VEC_address (CORE_ADDR,
 					   so->lm_info->section_bases);
 
-	      so->addr_low = ~(CORE_ADDR) 0;
+	      so->addr_low = addr_minus_one (gdbarch);
 	      so->addr_high = 0;
 	      for (i = 0, sect = so->abfd->sections;
 		   sect != NULL;
@@ -388,7 +389,8 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 		      gdb_assert (so->addr_low <= so->addr_high);
 		      found_range = 1;
 		    }
-		  so->lm_info->offsets->offsets[i] = section_bases[bases_index];
+		  so->lm_info->offsets->offsets[i] = addr_to_offset (gdbarch,
+						    section_bases[bases_index]);
 		  bases_index++;
 		}
 	      if (!found_range)
@@ -414,7 +416,7 @@ Could not relocate shared library \"%s\": no segments"), so->so_name);
 	      segment_bases = VEC_address (CORE_ADDR,
 					   so->lm_info->segment_bases);
 
-	      if (!symfile_map_offsets_to_segments (so->abfd, data,
+	      if (!symfile_map_offsets_to_segments (gdbarch, so->abfd, data,
 						    so->lm_info->offsets,
 						    num_bases, segment_bases))
 		warning (_("\
@@ -451,8 +453,8 @@ Could not relocate shared library \"%s\": bad offsets"), so->so_name);
     }
 
   offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
-  sec->addr += offset;
-  sec->endaddr += offset;
+  sec->addr = addr_add_offset (gdbarch, sec->addr, offset);
+  sec->endaddr = addr_add_offset (gdbarch, sec->endaddr, offset);
 }
 
 static int
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -803,7 +803,7 @@ static CORE_ADDR
 spu_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct spu_prologue_data data;
-  return spu_analyze_prologue (gdbarch, pc, (CORE_ADDR)-1, &data);
+  return spu_analyze_prologue (gdbarch, pc, addr_minus_one (gdbarch), &data);
 }
 
 /* Return the frame pointer in use at address PC.  */
@@ -812,7 +812,7 @@ spu_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc,
 			   int *reg, LONGEST *offset)
 {
   struct spu_prologue_data data;
-  spu_analyze_prologue (gdbarch, pc, (CORE_ADDR)-1, &data);
+  spu_analyze_prologue (gdbarch, pc, addr_minus_one (gdbarch), &data);
 
   if (data.size != -1 && data.cfa_reg != -1)
     {
--- a/gdb/symfile-mem.c
+++ b/gdb/symfile-mem.c
@@ -69,18 +69,21 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
   struct objfile *objf;
   struct bfd *nbfd;
   struct bfd_section *sec;
-  bfd_vma loadbase;
+  bfd_vma load_vma;
+  addr_offset_t load_offset;
   struct section_addr_info *sai;
   unsigned int i;
 
   if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
     error (_("add-symbol-file-from-memory not supported for this target"));
 
-  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
+  nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &load_vma,
 					 target_read_memory);
   if (nbfd == NULL)
     error (_("Failed to read a valid object file image from memory."));
 
+  load_offset = addr_to_offset (target_gdbarch, load_vma);
+
   if (name == NULL)
     nbfd->filename = xstrdup ("shared object read from target memory");
   else
@@ -102,7 +105,9 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
   for (sec = nbfd->sections; sec != NULL; sec = sec->next)
     if ((bfd_get_section_flags (nbfd, sec) & (SEC_ALLOC|SEC_LOAD)) != 0)
       {
-	sai->other[i].addr = bfd_get_section_vma (nbfd, sec) + loadbase;
+	sai->other[i].addr = addr_add_offset (target_gdbarch,
+					      bfd_get_section_vma (nbfd, sec),
+					      load_offset);
 	sai->other[i].name = (char *) bfd_get_section_name (nbfd, sec);
 	sai->other[i].sectindex = sec->index;
 	++i;
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -359,16 +359,12 @@ build_section_addr_info_from_section_table (const struct target_section *start,
 /* Create a section_addr_info from section offsets in OBJFILE.  */
 
 struct section_addr_info *
-build_section_addr_info_from_objfile (const struct objfile *objfile)
+build_section_addr_info_from_objfile (struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct section_addr_info *sap;
   int i;
   struct bfd_section *sec;
-  int addr_bit = gdbarch_addr_bit (objfile->gdbarch);
-  CORE_ADDR mask = CORE_ADDR_MAX;
-
-  if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
-    mask = ((CORE_ADDR) 1 << addr_bit) - 1;
 
   sap = alloc_section_addr_info (objfile->num_sections);
   for (i = 0, sec = objfile->obfd->sections;
@@ -376,8 +372,10 @@ build_section_addr_info_from_objfile (const struct objfile *objfile)
        i++, sec = sec->next)
     {
       gdb_assert (sec != NULL);
-      sap->other[i].addr = (bfd_get_section_vma (objfile->obfd, sec)
-                            + objfile->section_offsets->offsets[i]) & mask;
+      sap->other[i].addr = addr_add_offset (gdbarch,
+					    bfd_get_section_vma (objfile->obfd,
+								 sec),
+					  objfile->section_offsets->offsets[i]);
       sap->other[i].name = xstrdup (bfd_get_section_name (objfile->obfd, sec));
       sap->other[i].sectindex = sec->index;
     }
@@ -441,7 +439,7 @@ init_objfile_sect_indices (struct objfile *objfile)
 
   for (i = 0; i < objfile->num_sections; i++)
     {
-      if (ANOFFSET (objfile->section_offsets, i) != 0)
+      if (ANOFFSET (objfile->section_offsets, i).a != 0)
 	{
 	  break;
 	}
@@ -463,6 +461,7 @@ init_objfile_sect_indices (struct objfile *objfile)
 
 struct place_section_arg
 {
+  struct gdbarch *gdbarch;
   struct section_offsets *offsets;
   CORE_ADDR lowest;
 };
@@ -474,7 +473,9 @@ static void
 place_section (bfd *abfd, asection *sect, void *obj)
 {
   struct place_section_arg *arg = obj;
-  CORE_ADDR *offsets = arg->offsets->offsets, start_addr;
+  struct gdbarch *gdbarch = arg->gdbarch;
+  addr_offset_t *offsets = arg->offsets->offsets;
+  CORE_ADDR start_addr;
   int done;
   ULONGEST align = ((ULONGEST) 1) << bfd_get_section_alignment (abfd, sect);
 
@@ -483,7 +484,7 @@ place_section (bfd *abfd, asection *sect, void *obj)
     return;
 
   /* If the user specified an offset, honor it.  */
-  if (offsets[sect->index] != 0)
+  if (offsets[sect->index].a != 0)
     return;
 
   /* Otherwise, let's try to find a place for the section.  */
@@ -510,14 +511,14 @@ place_section (bfd *abfd, asection *sect, void *obj)
 	/* If the section offset is 0, either the section has not been placed
 	   yet, or it was the lowest section placed (in which case LOWEST
 	   will be past its end).  */
-	if (offsets[indx] == 0)
+	if (offsets[indx].a == 0)
 	  continue;
 
 	/* If this section would overlap us, then we must move up.  */
-	if (start_addr + bfd_get_section_size (sect) > offsets[indx]
-	    && start_addr < offsets[indx] + bfd_get_section_size (cur_sec))
+	if (start_addr + bfd_get_section_size (sect) > offsets[indx].a
+	    && start_addr < offsets[indx].a + bfd_get_section_size (cur_sec))
 	  {
-	    start_addr = offsets[indx] + bfd_get_section_size (cur_sec);
+	    start_addr = offsets[indx].a + bfd_get_section_size (cur_sec);
 	    start_addr = (start_addr + align - 1) & -align;
 	    done = 0;
 	    break;
@@ -528,7 +529,7 @@ place_section (bfd *abfd, asection *sect, void *obj)
     }
   while (!done);
 
-  offsets[sect->index] = start_addr;
+  offsets[sect->index] = addr_to_offset (gdbarch, start_addr);
   arg->lowest = start_addr + bfd_get_section_size (sect);
 }
 
@@ -537,7 +538,8 @@ place_section (bfd *abfd, asection *sect, void *obj)
    entries.  */
 
 void
-relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
+relative_addr_info_to_section_offsets (struct gdbarch *gdbarch,
+				       struct section_offsets *section_offsets,
 				       int num_sections,
 				       struct section_addr_info *addrs)
 {
@@ -557,7 +559,8 @@ relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
       /* Record all sections in offsets */
       /* The section_offsets in the objfile are here filled in using
          the BFD index. */
-      section_offsets->offsets[osp->sectindex] = osp->addr;
+      section_offsets->offsets[osp->sectindex] = addr_to_offset (gdbarch,
+								 osp->addr);
     }
 }
 
@@ -565,7 +568,8 @@ relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
    also SECTINDEXes there.  */
 
 void
-addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
+addr_info_make_relative (struct gdbarch *gdbarch,
+			 struct section_addr_info *addrs, bfd *abfd)
 {
   asection *lower_sect;
   asection *sect;
@@ -604,8 +608,12 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
 	  sect = bfd_get_section_by_name (abfd, addrs->other[i].name);
 	  if (sect)
 	    {
-	      addrs->other[i].addr -= bfd_section_vma (abfd, sect);
-	      lower_offset = addrs->other[i].addr;
+	      addr_offset_t offset;
+
+	      offset = addr_sub_to_offset (gdbarch, addrs->other[i].addr,
+					   bfd_section_vma (abfd, sect));
+	      addrs->other[i].addr = offset.a;
+	      lower_offset = offset.a;
 	      /* This is the index used by BFD. */
 	      addrs->other[i].sectindex = sect->index;
 	    }
@@ -631,11 +639,13 @@ void
 default_symfile_offsets (struct objfile *objfile,
 			 struct section_addr_info *addrs)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
   objfile->num_sections = bfd_count_sections (objfile->obfd);
   objfile->section_offsets = (struct section_offsets *)
     obstack_alloc (&objfile->objfile_obstack,
 		   SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
-  relative_addr_info_to_section_offsets (objfile->section_offsets,
+  relative_addr_info_to_section_offsets (gdbarch, objfile->section_offsets,
 					 objfile->num_sections, addrs);
 
   /* For relocatable files, all loadable sections will start at zero.
@@ -658,10 +668,11 @@ default_symfile_offsets (struct objfile *objfile,
 
       if (cur_sec == NULL)
 	{
-	  CORE_ADDR *offsets = objfile->section_offsets->offsets;
+	  addr_offset_t *offsets = objfile->section_offsets->offsets;
 
 	  /* Pick non-overlapping offsets for sections the user did not
 	     place explicitly.  */
+	  arg.gdbarch = gdbarch;
 	  arg.offsets = objfile->section_offsets;
 	  arg.lowest = 0;
 	  bfd_map_over_sections (objfile->obfd, place_section, &arg);
@@ -698,10 +709,10 @@ default_symfile_offsets (struct objfile *objfile,
 	      if ((bfd_get_section_flags (abfd, cur_sec) & SEC_ALLOC) == 0)
 		continue;
 
-	      bfd_set_section_vma (abfd, cur_sec, offsets[cur_sec->index]);
+	      bfd_set_section_vma (abfd, cur_sec, offsets[cur_sec->index].a);
 	      exec_set_section_address (bfd_get_filename (abfd), cur_sec->index,
-					offsets[cur_sec->index]);
-	      offsets[cur_sec->index] = 0;
+					offsets[cur_sec->index].a);
+	      offsets[cur_sec->index].a = 0;
 	    }
 	}
     }
@@ -813,6 +824,7 @@ syms_from_objfile (struct objfile *objfile,
                    int num_offsets,
 		   int add_flags)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct section_addr_info *local_addr = NULL;
   struct cleanup *old_chain;
   const int mainline = add_flags & SYMFILE_MAINLINE;
@@ -834,8 +846,7 @@ syms_from_objfile (struct objfile *objfile,
      no load address was specified. */
   if (! addrs && ! offsets)
     {
-      local_addr
-	= alloc_section_addr_info (bfd_count_sections (objfile->obfd));
+      local_addr = alloc_section_addr_info (bfd_count_sections (objfile->obfd));
       make_cleanup (xfree, local_addr);
       addrs = local_addr;
     }
@@ -871,7 +882,7 @@ syms_from_objfile (struct objfile *objfile,
      We no longer warn if the lowest section is not a text segment (as
      happens for the PA64 port.  */
   if (addrs && addrs->other[0].name)
-    addr_info_make_relative (addrs, objfile->obfd);
+    addr_info_make_relative (gdbarch, addrs, objfile->obfd);
 
   /* Initialize symbol reading routines for this objfile, allow complaints to
      appear for this new file, and record how verbose to be, then do the
@@ -3006,15 +3017,19 @@ pc_in_unmapped_range (CORE_ADDR pc, struct obj_section *section)
 {
   if (section_is_overlay (section))
     {
+      struct gdbarch *gdbarch = get_objfile_arch (section->objfile);
       bfd *abfd = section->objfile->obfd;
       asection *bfd_section = section->the_bfd_section;
 
       /* We assume the LMA is relocated by the same offset as the VMA.  */
       bfd_vma size = bfd_get_section_size (bfd_section);
-      CORE_ADDR offset = obj_section_offset (section);
+      addr_offset_t offset = obj_section_offset (section);
+
+      CORE_ADDR lma = addr_add_offset (gdbarch,
+				       bfd_get_section_lma (abfd, bfd_section),
+				       offset);
 
-      if (bfd_get_section_lma (abfd, bfd_section) + offset <= pc
-	  && pc < bfd_get_section_lma (abfd, bfd_section) + offset + size)
+      if (lma <= pc && pc < lma + size)
 	return 1;
     }
 
@@ -3707,7 +3722,8 @@ free_symfile_segment_data (struct symfile_segment_data *data)
    not be able to distinguish between an empty data segment and a
    missing data segment; a missing text segment is less plausible.  */
 int
-symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
+symfile_map_offsets_to_segments (struct gdbarch *gdbarch, bfd *abfd,
+				 struct symfile_segment_data *data,
 				 struct section_offsets *offsets,
 				 int num_segment_bases,
 				 const CORE_ADDR *segment_bases)
@@ -3740,8 +3756,9 @@ symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
       if (which > num_segment_bases)
         which = num_segment_bases;
 
-      offsets->offsets[i] = (segment_bases[which - 1]
-                             - data->segment_bases[which - 1]);
+      offsets->offsets[i] = addr_sub_to_offset (gdbarch,
+						segment_bases[which - 1],
+						data->segment_bases[which - 1]);
     }
 
   return 1;
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -182,13 +182,15 @@ struct sym_fns
 };
 
 extern struct section_addr_info *
-	   build_section_addr_info_from_objfile (const struct objfile *objfile);
+		 build_section_addr_info_from_objfile (struct objfile *objfile);
 
-extern void relative_addr_info_to_section_offsets
-  (struct section_offsets *section_offsets, int num_sections,
-   struct section_addr_info *addrs);
+extern void relative_addr_info_to_section_offsets (struct gdbarch *gdbarch,
+					struct section_offsets *section_offsets,
+						   int num_sections,
+					       struct section_addr_info *addrs);
 
-extern void addr_info_make_relative (struct section_addr_info *addrs,
+extern void addr_info_make_relative (struct gdbarch *gdbarch,
+				     struct section_addr_info *addrs,
 				     bfd *abfd);
 
 /* The default version of sym_fns.sym_offsets for readers that don't
@@ -265,8 +267,7 @@ extern char *find_separate_debug_file_by_debuglink (struct objfile *);
 
 /* Create a new section_addr_info, with room for NUM_SECTIONS.  */
 
-extern struct section_addr_info *alloc_section_addr_info (size_t
-							  num_sections);
+extern struct section_addr_info *alloc_section_addr_info (size_t num_sections);
 
 /* Build (allocate and populate) a section_addr_info struct from an
    existing section table.  */
@@ -390,7 +391,7 @@ extern void simple_overlay_update (struct obj_section *);
 extern bfd_byte *symfile_relocate_debug_section (struct objfile *, asection *,
 						 bfd_byte *);
 
-extern int symfile_map_offsets_to_segments (bfd *,
+extern int symfile_map_offsets_to_segments (struct gdbarch *gdbarch, bfd *,
 					    struct symfile_segment_data *,
 					    struct section_offsets *,
 					    int, const CORE_ADDR *);
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -378,7 +378,7 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
 	fprintf_filtered (outfile, ", ");
       wrap_here ("    ");
       fputs_filtered (paddress (gdbarch,
-				ANOFFSET (psymtab->section_offsets, i)),
+				ANOFFSET (psymtab->section_offsets, i).a),
 		      outfile);
     }
   fprintf_filtered (outfile, "\n");
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1144,11 +1144,13 @@ fixup_section (struct general_symbol_info *ginfo,
       struct obj_section *s;
       ALL_OBJFILE_OSECTIONS (objfile, s)
 	{
+	  struct gdbarch *gdbarch = get_objfile_arch (objfile);
 	  int idx = s->the_bfd_section->index;
-	  CORE_ADDR offset = ANOFFSET (objfile->section_offsets, idx);
+	  addr_offset_t offset = ANOFFSET (objfile->section_offsets, idx);
 
-	  if (obj_section_addr (s) - offset <= addr
-	      && addr < obj_section_endaddr (s) - offset)
+	  if (addr_sub_offset (gdbarch, obj_section_addr (s), offset) <= addr
+	      && addr < addr_sub_offset (gdbarch, obj_section_endaddr (s),
+					 offset))
 	    {
 	      ginfo->obj_section = s;
 	      ginfo->section = idx;
@@ -4859,6 +4861,128 @@ expand_line_sal (struct symtab_and_line sal)
   return ret;
 }
 
+void
+addr_width_assert (struct gdbarch *gdbarch, ULONGEST addr)
+{
+  int addr_bit = gdbarch_addr_bit (gdbarch);
+
+  if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT))
+    gdb_assert ((addr & -((ULONGEST) 1 << addr_bit)) == 0);
+}
+
+void
+addr_width_check_error (struct gdbarch *gdbarch, ULONGEST addr)
+{
+  int addr_bit = gdbarch_addr_bit (gdbarch);
+
+  if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT)
+      && (addr & -((ULONGEST) 1 << addr_bit)) != 0)
+    error (_("Address %s does not fit the architecture %s size %d bits"),
+	   hex_string (addr), gdbarch_bfd_arch_info (gdbarch)->printable_name,
+	   addr_bit);
+}
+
+CORE_ADDR
+addr_width_clear (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  int addr_bit = gdbarch_addr_bit (gdbarch);
+
+  if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT))
+    addr &= ((ULONGEST) 1 << addr_bit) - 1;
+
+  return addr;
+}
+
+CORE_ADDR
+addr_add_offset (struct gdbarch *gdbarch, CORE_ADDR addr, addr_offset_t offset)
+{
+  addr_width_assert (gdbarch, addr);
+  addr_width_assert (gdbarch, offset.a);
+
+  addr += offset.a;
+
+  addr = addr_width_clear (gdbarch, addr);
+
+  return addr;
+}
+
+CORE_ADDR
+addr_sub_offset (struct gdbarch *gdbarch, CORE_ADDR addr, addr_offset_t offset)
+{
+  addr_width_assert (gdbarch, addr);
+  addr_width_assert (gdbarch, offset.a);
+
+  addr -= offset.a;
+
+  addr = addr_width_clear (gdbarch, addr);
+
+  return addr;
+}
+
+addr_offset_t
+addr_to_offset (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  addr_offset_t retval;
+
+  addr_width_assert (gdbarch, addr);
+
+  retval.a = addr;
+
+  return retval;
+}
+
+addr_offset_t
+addr_sub_to_offset (struct gdbarch *gdbarch, CORE_ADDR addr1, CORE_ADDR addr2)
+{
+  addr_offset_t retval;
+
+  addr_width_assert (gdbarch, addr1);
+  addr_width_assert (gdbarch, addr2);
+
+  retval.a = addr1 - addr2;
+
+  retval.a = addr_width_clear (gdbarch, retval.a);
+
+  return retval;
+}
+
+addr_offset_t
+addr_offset_add (struct gdbarch *gdbarch, addr_offset_t offset1, addr_offset_t offset2)
+{
+  addr_width_assert (gdbarch, offset1.a);
+  addr_width_assert (gdbarch, offset2.a);
+
+  offset1.a += offset2.a;
+
+  offset1.a = addr_width_clear (gdbarch, offset1.a);
+
+  return offset1;
+}
+
+addr_offset_t
+addr_offset_sub (struct gdbarch *gdbarch, addr_offset_t offset1, addr_offset_t offset2)
+{
+  addr_width_assert (gdbarch, offset1.a);
+  addr_width_assert (gdbarch, offset2.a);
+
+  offset1.a -= offset2.a;
+
+  offset1.a = addr_width_clear (gdbarch, offset1.a);
+
+  return offset1;
+}
+
+const addr_offset_t dummy_addr_offset;
+
+CORE_ADDR
+addr_minus_one (struct gdbarch *gdbarch)
+{
+  CORE_ADDR retval = -1;
+
+  retval = addr_width_clear (gdbarch, retval);
+
+  return retval;
+}
 
 void
 _initialize_symtab (void)
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -701,6 +701,35 @@ struct linetable
   struct linetable_entry item[1];
 };
 
+extern void addr_width_assert (struct gdbarch *gdbarch, ULONGEST addr);
+
+extern void addr_width_check_error (struct gdbarch *gdbarch, ULONGEST addr);
+
+extern CORE_ADDR addr_width_clear (struct gdbarch *gdbarch, CORE_ADDR addr);
+
+extern CORE_ADDR addr_add_offset (struct gdbarch *gdbarch, CORE_ADDR addr,
+				  addr_offset_t offset);
+
+extern CORE_ADDR addr_sub_offset (struct gdbarch *gdbarch, CORE_ADDR addr,
+				  addr_offset_t offset);
+
+extern addr_offset_t addr_to_offset (struct gdbarch *gdbarch, CORE_ADDR addr);
+
+extern addr_offset_t addr_sub_to_offset (struct gdbarch *gdbarch,
+					 CORE_ADDR addr1, CORE_ADDR addr2);
+
+extern addr_offset_t addr_offset_add (struct gdbarch *gdbarch,
+				      addr_offset_t offset1,
+				      addr_offset_t offset2);
+
+extern addr_offset_t addr_offset_sub (struct gdbarch *gdbarch,
+				      addr_offset_t offset1,
+				      addr_offset_t offset2);
+
+extern const addr_offset_t dummy_addr_offset;
+
+extern CORE_ADDR addr_minus_one (struct gdbarch *gdbarch);
+
 /* How to relocate the symbols from each section in a symbol file.
    Each struct contains an array of offsets.
    The ordering and meaning of the offsets is file-type-dependent;
@@ -713,12 +742,13 @@ struct linetable
 
 struct section_offsets
 {
-  CORE_ADDR offsets[1];		/* As many as needed. */
+  addr_offset_t offsets[1];		/* As many as needed. */
 };
 
 #define	ANOFFSET(secoff, whichone) \
    ((whichone == -1) \
-    ? (internal_error (__FILE__, __LINE__, _("Section index is uninitialized")), -1) \
+    ? (internal_error (__FILE__, __LINE__, _("Section index is uninitialized")), \
+       dummy_addr_offset)							 \
     : secoff->offsets[whichone])
 
 /* The size of a section_offsets table for N sections.  */
--- a/gdb/testsuite/gdb.base/long_long.exp
+++ b/gdb/testsuite/gdb.base/long_long.exp
@@ -177,7 +177,7 @@ gdb_test "p/d val.oct" "-6399925985474168457"
 gdb_test "p/u val.oct" "12046818088235383159"
 gdb_test "p/o val.oct" ""
 gdb_test "p/t val.oct" "1010011100101110111001010011100101110111000001010011100101110111"
-gdb_test_ptr "p/a val.oct" "" "" "0x77053977" "0xa72ee53977053977"
+gdb_test_ptr "p/a val.oct" "" "" "Address 0xa72ee53977053977 does not fit the architecture .* size 32 bits" "0xa72ee53977053977"
 gdb_test "p/c val.oct" "'w'"
 
 if { $sizeof_double == 8 || $sizeof_long_double == 8 } {
@@ -245,7 +245,7 @@ gdb_test_long_long "p/d *(long long *)ll" "" "" "" "81985529216486895"
 gdb_test_long_long "p/u *(long long *)ll" "" "" "" "81985529216486895"
 gdb_test_long_long "p/o *(long long *)ll" "" "" "" "04432126361152746757"
 gdb_test_long_long "p/t *(long long *)ll" "" "" "" "100100011010001010110011110001001101010111100110111101111"
-gdb_test_ptr "p/a *(long long *)ll" "" "" "0x89abcdef" "0x123456789abcdef"
+gdb_test_ptr "p/a *(long long *)ll" "" "" "Address 0x123456789abcdef does not fit the architecture .* size 32 bits" "0x123456789abcdef"
 gdb_test_long_long "p/f *(long long *)ll" "" "" "" "3.5127005640885037e-303"
 gdb_test_long_long "p/c *(long long *)ll" "" "" "" "-17 '.*'"
 
@@ -315,7 +315,7 @@ gdb_test "x/2gd g" "81985529216486895.*-6399925985474168457"
 gdb_test "x/2gu g" "81985529216486895.*12046818088235383159"
 gdb_test "x/2go g" "04432126361152746757.*01234567123456701234567"
 gdb_test "x/2gt g" "0000000100100011010001010110011110001001101010111100110111101111.*1010011100101110111001010011100101110111000001010011100101110111"
-gdb_test_ptr "x/2ga g" "" "" "0x89abcdef.*0x77053977" "0x123456789abcdef.*0xa72ee53977053977"
+gdb_test_ptr "x/2ga g" "" "" "Address 0x123456789abcdef does not fit the architecture .* size 32 bits" "0x123456789abcdef.*0xa72ee53977053977"
 gdb_test "x/2gc g" "-17 '.\[0-9\]*'.*119 'w'"
 gdb_test "x/2gf g" "3.5127005640885037e-303.*-5.9822653797615723e-120"
 
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -897,7 +897,7 @@ switch_to_thread (ptid_t ptid)
       && !is_executing (ptid))
     stop_pc = regcache_read_pc (get_thread_regcache (ptid));
   else
-    stop_pc = ~(CORE_ADDR) 0;
+    stop_pc = addr_minus_one (target_gdbarch);
 }
 
 static void
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -491,11 +491,10 @@ ui_out_field_core_addr (struct ui_out *uiout,
 			struct gdbarch *gdbarch,
 			CORE_ADDR address)
 {
-  char addstr[20];
   int addr_bit = gdbarch_addr_bit (gdbarch);
+  char addstr[20];
 
-  if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
-    address &= ((CORE_ADDR) 1 << addr_bit) - 1;
+  addr_width_assert (gdbarch, address);
 
   /* FIXME: cagney/2002-05-03: Need local_address_string() function
      that returns the language localized string formatted to a width
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -2907,16 +2907,17 @@ paddress (struct gdbarch *gdbarch, CORE_ADDR addr)
   /* Truncate address to the size of a target address, avoiding shifts
      larger or equal than the width of a CORE_ADDR.  The local
      variable ADDR_BIT stops the compiler reporting a shift overflow
-     when it won't occur. */
-  /* NOTE: This assumes that the significant address information is
+     when it won't occur.
+
+     NOTE: This assumes that the significant address information is
      kept in the least significant bits of ADDR - the upper bits were
      either zero or sign extended.  Should gdbarch_address_to_pointer or
-     some ADDRESS_TO_PRINTABLE() be used to do the conversion?  */
+     some ADDRESS_TO_PRINTABLE() be used to do the conversion?
+     
+     The value itself may be user-specified.  */
 
-  int addr_bit = gdbarch_addr_bit (gdbarch);
+  addr_width_check_error (gdbarch, addr);
 
-  if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
-    addr &= ((CORE_ADDR) 1 << addr_bit) - 1;
   return hex_string (addr);
 }
 
@@ -3029,6 +3030,9 @@ phex (ULONGEST l, int sizeof_l)
 {
   char *str;
 
+  if ((sizeof_l == 8 || sizeof_l == 4 || sizeof_l == 2) && sizeof (l) > sizeof_l)
+    gdb_assert ((l & -((ULONGEST) 1 << (8 * sizeof_l))) == 0);
+
   switch (sizeof_l)
     {
     case 8:
@@ -3058,6 +3062,9 @@ phex_nz (ULONGEST l, int sizeof_l)
 {
   char *str;
 
+  if ((sizeof_l == 8 || sizeof_l == 4 || sizeof_l == 2) && sizeof (l) > sizeof_l)
+    gdb_assert ((l & -((ULONGEST) 1 << (8 * sizeof_l))) == 0);
+
   switch (sizeof_l)
     {
     case 8:
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1658,7 +1658,7 @@ value_as_address (struct value *val)
     return gdbarch_integer_to_address (gdbarch, value_type (val),
 				       value_contents (val));
 
-  return unpack_long (value_type (val), value_contents (val));
+  return unpack_pointer (value_type (val), value_contents (val));
 #endif
 }
 
@@ -1796,9 +1796,27 @@ unpack_double (struct type *type, const gdb_byte *valaddr, int *invp)
 CORE_ADDR
 unpack_pointer (struct type *type, const gdb_byte *valaddr)
 {
+  struct gdbarch *gdbarch = get_type_arch (type);
+  int addr_bit = gdbarch_addr_bit (gdbarch);
+  ULONGEST retval;
+  unsigned len;
+
   /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure
      whether we want this to be true eventually.  */
-  return unpack_long (type, valaddr);
+  retval = unpack_long (type, valaddr);
+
+  type = check_typedef (type);
+  len = TYPE_LENGTH (type);
+
+  /* LEN for float types is unrelated to its integer bit width.  */
+  if (TYPE_CODE (type) != TYPE_CODE_FLT
+      && TYPE_CODE (type) != TYPE_CODE_DECFLOAT
+      && 8 * len <= gdbarch_addr_bit (gdbarch))
+    retval = addr_width_clear (gdbarch, retval);
+  else
+    addr_width_check_error (gdbarch, retval);
+
+  return retval;
 }
 
 
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -511,9 +511,8 @@ find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
 	 Truncate the frame base address in the same manner before
 	 comparing it against our argument.  */
       CORE_ADDR frame_base = get_frame_base_address (frame);
-      int addr_bit = gdbarch_addr_bit (get_frame_arch (frame));
-      if (addr_bit < (sizeof (CORE_ADDR) * HOST_CHAR_BIT))
-	frame_base &= ((CORE_ADDR) 1 << addr_bit) - 1;
+
+      addr_width_assert (get_frame_arch (frame), frame_base);
 
       if (frame_base == frame_addr)
 	return frame;
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -809,7 +809,9 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, unsigned endoff
       addr = (int_lnno.l_lnno
 	      ? int_lnno.l_addr.l_paddr
 	      : read_symbol_nvalue (int_lnno.l_addr.l_symndx));
-      addr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+      addr = addr_add_offset (gdbarch, addr,
+			      ANOFFSET (objfile->section_offsets,
+					SECT_OFF_TEXT (objfile)));
 
       if (addr < startaddr || (endaddr && addr >= endaddr))
 	return;
@@ -923,6 +925,7 @@ static void
 read_xcoff_symtab (struct partial_symtab *pst)
 {
   struct objfile *objfile = pst->objfile;
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   bfd *abfd = objfile->obfd;
   char *raw_auxptr;		/* Pointer to first raw aux entry for sym */
   char *strtbl = ((struct coff_symfile_info *) objfile->deprecated_sym_private)->strtbl;
@@ -1129,9 +1132,10 @@ read_xcoff_symtab (struct partial_symtab *pst)
 			  just_started = 0;
 			}
 
-		      file_start_addr =
-			cs->c_value + ANOFFSET (objfile->section_offsets,
-						SECT_OFF_TEXT (objfile));
+		      file_start_addr
+		        = addr_add_offset (gdbarch, cs->c_value,
+					   ANOFFSET (objfile->section_offsets,
+						     SECT_OFF_TEXT (objfile)));
 		      file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
 
 		      if (cs->c_name && (cs->c_name[0] == '.'
@@ -1272,17 +1276,19 @@ read_xcoff_symtab (struct partial_symtab *pst)
 	case C_FCN:
 	  if (strcmp (cs->c_name, ".bf") == 0)
 	    {
-	      CORE_ADDR off = ANOFFSET (objfile->section_offsets,
-					SECT_OFF_TEXT (objfile));
+	      addr_offset_t off = ANOFFSET (objfile->section_offsets,
+					    SECT_OFF_TEXT (objfile));
+
 	      bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
 				    0, cs->c_naux, &main_aux);
 
 	      within_function = 1;
 
-	      new = push_context (0, fcn_start_addr + off);
+	      new = push_context (0, addr_add_offset (gdbarch, fcn_start_addr,
+						      off));
 
 	      new->name = define_symbol
-		(fcn_cs_saved.c_value + off,
+		(addr_add_offset (gdbarch, fcn_cs_saved.c_value, off),
 		 fcn_stab_saved.c_name, 0, 0, objfile);
 	      if (new->name != NULL)
 		SYMBOL_SECTION (new->name) = SECT_OFF_TEXT (objfile);
@@ -1315,10 +1321,11 @@ read_xcoff_symtab (struct partial_symtab *pst)
 
 	      finish_block (new->name, &local_symbols, new->old_blocks,
 			    new->start_addr,
-			    (fcn_cs_saved.c_value
-			     + fcn_aux_saved.x_sym.x_misc.x_fsize
-			     + ANOFFSET (objfile->section_offsets,
-					 SECT_OFF_TEXT (objfile))),
+			    addr_add_offset (gdbarch,
+			                     (fcn_cs_saved.c_value
+					  + fcn_aux_saved.x_sym.x_misc.x_fsize),
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile))),
 			    objfile);
 	      within_function = 0;
 	    }
@@ -1385,9 +1392,9 @@ read_xcoff_symtab (struct partial_symtab *pst)
 	    {
 	      depth++;
 	      new = push_context (depth,
-				  (cs->c_value
-				   + ANOFFSET (objfile->section_offsets,
-					       SECT_OFF_TEXT (objfile))));
+				  addr_add_offset (gdbarch, cs->c_value,
+					   ANOFFSET (objfile->section_offsets,
+						     SECT_OFF_TEXT (objfile))));
 	    }
 	  else if (strcmp (cs->c_name, ".eb") == 0)
 	    {
@@ -1407,9 +1414,9 @@ read_xcoff_symtab (struct partial_symtab *pst)
 		  /* Make a block for the local symbols within.  */
 		  finish_block (new->name, &local_symbols, new->old_blocks,
 				new->start_addr,
-				(cs->c_value
-				 + ANOFFSET (objfile->section_offsets,
-					     SECT_OFF_TEXT (objfile))),
+				addr_add_offset (gdbarch, cs->c_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile))),
 				objfile);
 		}
 	      local_symbols = new->locals;
@@ -1454,19 +1461,20 @@ read_xcoff_symtab (struct partial_symtab *pst)
 static struct symbol *
 process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile)
 {
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   struct symbol onesymbol;
   struct symbol *sym = &onesymbol;
   struct symbol *sym2 = NULL;
   char *name, *pp;
 
   int sec;
-  CORE_ADDR off;
+  addr_offset_t off;
 
   if (cs->c_secnum < 0)
     {
       /* The value is a register number, offset within a frame, etc.,
          and does not get relocated.  */
-      off = 0;
+      off.a = 0;
       sec = -1;
     }
   else
@@ -1482,7 +1490,7 @@ process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile)
   memset (sym, '\0', sizeof (struct symbol));
 
   /* default assumptions */
-  SYMBOL_VALUE_ADDRESS (sym) = cs->c_value + off;
+  SYMBOL_VALUE_ADDRESS (sym) = addr_add_offset (gdbarch, cs->c_value, off);
   SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
   SYMBOL_SECTION (sym) = secnum_to_section (cs->c_secnum, objfile);
 
@@ -1547,7 +1555,8 @@ process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile)
 	case C_GSYM:
 
 	  {
-	    sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile);
+	    sym = define_symbol (addr_add_offset (gdbarch, cs->c_value, off),
+				 cs->c_name, 0, 0, objfile);
 	    if (sym != NULL)
 	      {
 		SYMBOL_SECTION (sym) = sec;
@@ -1570,9 +1579,9 @@ process_xcoff_symbol (struct coff_symbol *cs, struct objfile *objfile)
 	  ++pp;
 	  if (*pp == 'V' && !within_function)
 	    *pp = 'S';
-	  sym = define_symbol ((cs->c_value
-				+ ANOFFSET (objfile->section_offsets,
-					    static_block_section)),
+	  sym = define_symbol (addr_add_offset (gdbarch, cs->c_value,
+					     ANOFFSET (objfile->section_offsets,
+						       static_block_section)),
 			       cs->c_name, 0, 0, objfile);
 	  if (sym != NULL)
 	    {
@@ -2595,7 +2604,9 @@ scan_xcoff_symtab (struct objfile *objfile)
 	    switch (p[1])
 	      {
 	      case 'S':
-		symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+		symbol.n_value = addr_add_offset (gdbarch, symbol.n_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
 
 		if (gdbarch_static_transform_name_p (gdbarch))
 		  namestring = gdbarch_static_transform_name
@@ -2609,7 +2620,10 @@ scan_xcoff_symtab (struct objfile *objfile)
 		continue;
 
 	      case 'G':
-		symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_DATA (objfile));
+		symbol.n_value = addr_add_offset (gdbarch, symbol.n_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_DATA (objfile)));
+
 		/* The addresses in these entries are reported to be
 		   wrong.  See the code that reads 'G's for symtabs. */
 		add_psymbol_to_list (namestring, p - namestring, 1,
@@ -2747,7 +2761,9 @@ scan_xcoff_symtab (struct objfile *objfile)
 		    function_outside_compilation_unit_complaint (name);
 		    xfree (name);
 		  }
-		symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		symbol.n_value = addr_add_offset (gdbarch, symbol.n_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		add_psymbol_to_list (namestring, p - namestring, 1,
 				     VAR_DOMAIN, LOC_BLOCK,
 				     &objfile->static_psymbols,
@@ -2776,7 +2792,9 @@ scan_xcoff_symtab (struct objfile *objfile)
 		if (strncmp (namestring, "@FIX", 4) == 0)
 		  continue;
 
-		symbol.n_value += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+		symbol.n_value = addr_add_offset (gdbarch, symbol.n_value,
+					    ANOFFSET (objfile->section_offsets,
+						      SECT_OFF_TEXT (objfile)));
 		add_psymbol_to_list (namestring, p - namestring, 1,
 				     VAR_DOMAIN, LOC_BLOCK,
 				     &objfile->global_psymbols,
@@ -3007,7 +3025,7 @@ xcoff_symfile_offsets (struct objfile *objfile, struct section_addr_info *addrs)
 	 sensibly), so just ignore the addr parameter and use 0.
 	 rs6000-nat.c will set the correct section offsets via
 	 objfile_relocate.  */
-	(objfile->section_offsets)->offsets[i] = 0;
+      (objfile->section_offsets)->offsets[i].a = 0;
     }
 }
 
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -69,7 +69,7 @@ enum gdb_regnum
 };
 
 /* Use an invalid address value as 'not available' marker.  */
-enum { REG_UNAVAIL = (CORE_ADDR) -1 };
+#define REG_UNAVAIL(gdbarch) addr_minus_one (gdbarch)
 
 struct xstormy16_frame_cache
 {
@@ -641,7 +641,7 @@ xstormy16_address_to_pointer (struct gdbarch *gdbarch,
 }
 
 static struct xstormy16_frame_cache *
-xstormy16_alloc_frame_cache (void)
+xstormy16_alloc_frame_cache (struct gdbarch *gdbarch)
 {
   struct xstormy16_frame_cache *cache;
   int i;
@@ -654,7 +654,7 @@ xstormy16_alloc_frame_cache (void)
   cache->uses_fp = 0;
   cache->framesize = 0;
   for (i = 0; i < E_NUM_REGS; ++i)
-    cache->saved_regs[i] = REG_UNAVAIL;
+    cache->saved_regs[i] = REG_UNAVAIL (gdbarch);
 
   return cache;
 }
@@ -670,7 +670,7 @@ xstormy16_frame_cache (struct frame_info *this_frame, void **this_cache)
   if (*this_cache)
     return *this_cache;
 
-  cache = xstormy16_alloc_frame_cache ();
+  cache = xstormy16_alloc_frame_cache (gdbarch);
   *this_cache = cache;
 
   cache->base = get_frame_register_unsigned (this_frame, E_FP_REGNUM);
@@ -689,7 +689,7 @@ xstormy16_frame_cache (struct frame_info *this_frame, void **this_cache)
   cache->saved_sp = cache->base - cache->framesize;
 
   for (i = 0; i < E_NUM_REGS; ++i)
-    if (cache->saved_regs[i] != REG_UNAVAIL)
+    if (cache->saved_regs[i] != REG_UNAVAIL (gdbarch))
       cache->saved_regs[i] += cache->saved_sp;
 
   return cache;
@@ -699,6 +699,7 @@ static struct value *
 xstormy16_frame_prev_register (struct frame_info *this_frame, 
 			       void **this_cache, int regnum)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct xstormy16_frame_cache *cache = xstormy16_frame_cache (this_frame,
                                                                this_cache);
   gdb_assert (regnum >= 0);
@@ -706,7 +707,7 @@ xstormy16_frame_prev_register (struct frame_info *this_frame,
   if (regnum == E_SP_REGNUM && cache->saved_sp)
     return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
 
-  if (regnum < E_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL)
+  if (regnum < E_NUM_REGS && cache->saved_regs[regnum] != REG_UNAVAIL (gdbarch))
     return frame_unwind_got_memory (this_frame, regnum,
 				    cache->saved_regs[regnum]);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]