*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / arm-tdep.c
index 38d50155b4b6dc1df42ba5db13d43339f776ac1e..325bd80df7ffd5a8f094dcf1e9b39137f3e0dff0 100644 (file)
@@ -7,7 +7,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <ctype.h>             /* XXX for isupper () */
 
@@ -724,7 +722,8 @@ arm_scan_prologue (struct frame_info *next_frame, struct arm_prologue_cache *cac
         return;
       else
         {
-          prologue_start = ADDR_BITS_REMOVE (return_value) - 8;
+          prologue_start = gdbarch_addr_bits_remove 
+                            (current_gdbarch, return_value) - 8;
           prologue_end = prologue_start + 64;  /* See above.  */
         }
     }
@@ -1211,7 +1210,8 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
     {
       if (arm_debug)
        fprintf_unfiltered (gdb_stdlog, "struct return in %s = 0x%s\n",
-                           REGISTER_NAME (argreg), paddr (struct_addr));
+                           gdbarch_register_name (current_gdbarch, argreg),
+                           paddr (struct_addr));
       regcache_cooked_write_unsigned (regcache, argreg, struct_addr);
       argreg++;
     }
@@ -1280,17 +1280,21 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
         registers and stack.  */
       while (len > 0)
        {
-         int partial_len = len < DEPRECATED_REGISTER_SIZE ? len : DEPRECATED_REGISTER_SIZE;
+         int partial_len = len < INT_REGISTER_SIZE ? len : INT_REGISTER_SIZE;
 
          if (argreg <= ARM_LAST_ARG_REGNUM)
            {
              /* The argument is being passed in a general purpose
                 register.  */
              CORE_ADDR regval = extract_unsigned_integer (val, partial_len);
+             if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+               regval <<= (INT_REGISTER_SIZE - partial_len) * 8;
              if (arm_debug)
                fprintf_unfiltered (gdb_stdlog, "arg %d in %s = 0x%s\n",
-                                   argnum, REGISTER_NAME (argreg),
-                                   phex (regval, DEPRECATED_REGISTER_SIZE));
+                                   argnum,
+                                   gdbarch_register_name
+                                     (current_gdbarch, argreg),
+                                   phex (regval, INT_REGISTER_SIZE));
              regcache_cooked_write_unsigned (regcache, argreg, regval);
              argreg++;
            }
@@ -1300,8 +1304,8 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              if (arm_debug)
                fprintf_unfiltered (gdb_stdlog, "arg %d @ sp + %d\n",
                                    argnum, nstack);
-             si = push_stack_item (si, val, DEPRECATED_REGISTER_SIZE);
-             nstack += DEPRECATED_REGISTER_SIZE;
+             si = push_stack_item (si, val, INT_REGISTER_SIZE);
+             nstack += INT_REGISTER_SIZE;
            }
              
          len -= partial_len;
@@ -1359,7 +1363,7 @@ static void
 arm_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
                      struct frame_info *frame, const char *args)
 {
-  unsigned long status = read_register (ARM_FPS_REGNUM);
+  unsigned long status = get_frame_register_unsigned (frame, ARM_FPS_REGNUM);
   int type;
 
   type = (status >> 24) & 127;
@@ -1470,7 +1474,7 @@ convert_from_extended (const struct floatformat *fmt, const void *ptr,
                       void *dbl)
 {
   DOUBLEST d;
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     floatformat_to_doublest (&floatformat_arm_ext_big, ptr, &d);
   else
     floatformat_to_doublest (&floatformat_arm_ext_littlebyte_bigword,
@@ -1483,7 +1487,7 @@ convert_to_extended (const struct floatformat *fmt, void *dbl, const void *ptr)
 {
   DOUBLEST d;
   floatformat_to_doublest (fmt, ptr, &d);
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     floatformat_from_doublest (&floatformat_arm_ext_big, &d, dbl);
   else
     floatformat_from_doublest (&floatformat_arm_ext_littlebyte_bigword,
@@ -1543,8 +1547,8 @@ condition_true (unsigned long cond, unsigned long status_reg)
 #define ARM_PC_32 1
 
 static unsigned long
-shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val,
-                unsigned long status_reg)
+shifted_reg_val (struct frame_info *frame, unsigned long inst, int carry,
+                unsigned long pc_val, unsigned long status_reg)
 {
   unsigned long res, shift;
   int rm = bits (inst, 0, 3);
@@ -1553,7 +1557,8 @@ shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val,
   if (bit (inst, 4))
     {
       int rs = bits (inst, 8, 11);
-      shift = (rs == 15 ? pc_val + 8 : read_register (rs)) & 0xFF;
+      shift = (rs == 15 ? pc_val + 8
+                       : get_frame_register_unsigned (frame, rs)) & 0xFF;
     }
   else
     shift = bits (inst, 7, 11);
@@ -1561,7 +1566,7 @@ shifted_reg_val (unsigned long inst, int carry, unsigned long pc_val,
   res = (rm == 15
         ? ((pc_val | (ARM_PC_32 ? 0 : status_reg))
            + (bit (inst, 4) ? 12 : 8))
-        : read_register (rm));
+        : get_frame_register_unsigned (frame, rm));
 
   switch (shifttype)
     {
@@ -1604,7 +1609,7 @@ bitcount (unsigned long val)
 }
 
 static CORE_ADDR
-thumb_get_next_pc (CORE_ADDR pc)
+thumb_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
   unsigned long pc_val = ((unsigned long) pc) + 4;     /* PC after prefetch */
   unsigned short inst1 = read_memory_unsigned_integer (pc, 2);
@@ -1617,16 +1622,16 @@ thumb_get_next_pc (CORE_ADDR pc)
 
       /* Fetch the saved PC from the stack.  It's stored above
          all of the other registers.  */
-      offset = bitcount (bits (inst1, 0, 7)) * DEPRECATED_REGISTER_SIZE;
-      sp = read_register (ARM_SP_REGNUM);
+      offset = bitcount (bits (inst1, 0, 7)) * INT_REGISTER_SIZE;
+      sp = get_frame_register_unsigned (frame, ARM_SP_REGNUM);
       nextpc = (CORE_ADDR) read_memory_unsigned_integer (sp + offset, 4);
-      nextpc = ADDR_BITS_REMOVE (nextpc);
+      nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
       if (nextpc == pc)
        error (_("Infinite loop detected"));
     }
   else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
     {
-      unsigned long status = read_register (ARM_PS_REGNUM);
+      unsigned long status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
       unsigned long cond = bits (inst1, 8, 11);
       if (cond != 0x0f && condition_true (cond, status))    /* 0x0f = SWI */
        nextpc = pc_val + (sbits (inst1, 0, 7) << 1);
@@ -1649,9 +1654,9 @@ thumb_get_next_pc (CORE_ADDR pc)
       if (bits (inst1, 3, 6) == 0x0f)
        nextpc = pc_val;
       else
-       nextpc = read_register (bits (inst1, 3, 6));
+       nextpc = get_frame_register_unsigned (frame, bits (inst1, 3, 6));
 
-      nextpc = ADDR_BITS_REMOVE (nextpc);
+      nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
       if (nextpc == pc)
        error (_("Infinite loop detected"));
     }
@@ -1659,8 +1664,8 @@ thumb_get_next_pc (CORE_ADDR pc)
   return nextpc;
 }
 
-static CORE_ADDR
-arm_get_next_pc (CORE_ADDR pc)
+CORE_ADDR
+arm_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
   unsigned long pc_val;
   unsigned long this_instr;
@@ -1668,14 +1673,37 @@ arm_get_next_pc (CORE_ADDR pc)
   CORE_ADDR nextpc;
 
   if (arm_pc_is_thumb (pc))
-    return thumb_get_next_pc (pc);
+    return thumb_get_next_pc (frame, pc);
 
   pc_val = (unsigned long) pc;
   this_instr = read_memory_unsigned_integer (pc, 4);
-  status = read_register (ARM_PS_REGNUM);
+  status = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
   nextpc = (CORE_ADDR) (pc_val + 4);   /* Default case */
 
-  if (condition_true (bits (this_instr, 28, 31), status))
+  if (bits (this_instr, 28, 31) == INST_NV)
+    switch (bits (this_instr, 24, 27))
+      {
+      case 0xa:
+      case 0xb:
+       {
+         /* Branch with Link and change to Thumb.  */
+         nextpc = BranchDest (pc, this_instr);
+         nextpc |= bit (this_instr, 24) << 1;
+
+         nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
+         if (nextpc == pc)
+           error (_("Infinite loop detected"));
+         break;
+       }
+      case 0xc:
+      case 0xd:
+      case 0xe:
+       /* Coprocessor register transfer.  */
+        if (bits (this_instr, 12, 15) == 15)
+         error (_("Invalid update to pc in instruction"));
+       break;
+      }
+  else if (condition_true (bits (this_instr, 28, 31), status))
     {
       switch (bits (this_instr, 24, 27))
        {
@@ -1700,8 +1728,10 @@ arm_get_next_pc (CORE_ADDR pc)
                || bits (this_instr, 4, 27) == 0x12fff3)
              {
                rn = bits (this_instr, 0, 3);
-               result = (rn == 15) ? pc_val + 8 : read_register (rn);
-               nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result);
+               result = (rn == 15) ? pc_val + 8
+                                   : get_frame_register_unsigned (frame, rn);
+               nextpc = (CORE_ADDR) gdbarch_addr_bits_remove
+                                      (current_gdbarch, result);
 
                if (nextpc == pc)
                  error (_("Infinite loop detected"));
@@ -1712,7 +1742,8 @@ arm_get_next_pc (CORE_ADDR pc)
            /* Multiply into PC */
            c = (status & FLAG_C) ? 1 : 0;
            rn = bits (this_instr, 16, 19);
-           operand1 = (rn == 15) ? pc_val + 8 : read_register (rn);
+           operand1 = (rn == 15) ? pc_val + 8
+                                 : get_frame_register_unsigned (frame, rn);
 
            if (bit (this_instr, 25))
              {
@@ -1722,7 +1753,7 @@ arm_get_next_pc (CORE_ADDR pc)
                  & 0xffffffff;
              }
            else                /* operand 2 is a shifted register */
-             operand2 = shifted_reg_val (this_instr, c, pc_val, status);
+             operand2 = shifted_reg_val (frame, this_instr, c, pc_val, status);
 
            switch (bits (this_instr, 21, 24))
              {
@@ -1782,7 +1813,8 @@ arm_get_next_pc (CORE_ADDR pc)
                result = ~operand2;
                break;
              }
-           nextpc = (CORE_ADDR) ADDR_BITS_REMOVE (result);
+           nextpc = (CORE_ADDR) gdbarch_addr_bits_remove
+                                  (current_gdbarch, result);
 
            if (nextpc == pc)
              error (_("Infinite loop detected"));
@@ -1807,14 +1839,15 @@ arm_get_next_pc (CORE_ADDR pc)
 
                  /* byte write to PC */
                  rn = bits (this_instr, 16, 19);
-                 base = (rn == 15) ? pc_val + 8 : read_register (rn);
+                 base = (rn == 15) ? pc_val + 8
+                                   : get_frame_register_unsigned (frame, rn);
                  if (bit (this_instr, 24))
                    {
                      /* pre-indexed */
                      int c = (status & FLAG_C) ? 1 : 0;
                      unsigned long offset =
                      (bit (this_instr, 25)
-                      ? shifted_reg_val (this_instr, c, pc_val, status)
+                      ? shifted_reg_val (frame, this_instr, c, pc_val, status)
                       : bits (this_instr, 0, 11));
 
                      if (bit (this_instr, 23))
@@ -1825,7 +1858,7 @@ arm_get_next_pc (CORE_ADDR pc)
                  nextpc = (CORE_ADDR) read_memory_integer ((CORE_ADDR) base,
                                                            4);
 
-                 nextpc = ADDR_BITS_REMOVE (nextpc);
+                 nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
 
                  if (nextpc == pc)
                    error (_("Infinite loop detected"));
@@ -1856,13 +1889,15 @@ arm_get_next_pc (CORE_ADDR pc)
 
                  {
                    unsigned long rn_val =
-                   read_register (bits (this_instr, 16, 19));
+                   get_frame_register_unsigned (frame,
+                                                bits (this_instr, 16, 19));
                    nextpc =
                      (CORE_ADDR) read_memory_integer ((CORE_ADDR) (rn_val
                                                                  + offset),
                                                       4);
                  }
-                 nextpc = ADDR_BITS_REMOVE (nextpc);
+                 nextpc = gdbarch_addr_bits_remove
+                            (current_gdbarch, nextpc);
                  if (nextpc == pc)
                    error (_("Infinite loop detected"));
                }
@@ -1874,11 +1909,7 @@ arm_get_next_pc (CORE_ADDR pc)
          {
            nextpc = BranchDest (pc, this_instr);
 
-           /* BLX */
-           if (bits (this_instr, 28, 31) == INST_NV)
-             nextpc |= bit (this_instr, 24) << 1;
-
-           nextpc = ADDR_BITS_REMOVE (nextpc);
+           nextpc = gdbarch_addr_bits_remove (current_gdbarch, nextpc);
            if (nextpc == pc)
              error (_("Infinite loop detected"));
            break;
@@ -1905,13 +1936,13 @@ arm_get_next_pc (CORE_ADDR pc)
    and breakpoint it.  */
 
 int
-arm_software_single_step (struct regcache *regcache)
+arm_software_single_step (struct frame_info *frame)
 {
   /* NOTE: This may insert the wrong breakpoint instruction when
      single-stepping over a mode-changing instruction, if the
      CPSR heuristics are used.  */
 
-  CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
+  CORE_ADDR next_pc = arm_get_next_pc (frame, get_frame_pc (frame));
   insert_single_step_breakpoint (next_pc);
 
   return 1;
@@ -1954,7 +1985,7 @@ gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
   else
     info->symbols = NULL;
 
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     return print_insn_big_arm (memaddr, info);
   else
     return print_insn_little_arm (memaddr, info);
@@ -2126,7 +2157,7 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
 
   /* In the ARM ABI, "integer" like aggregate types are returned in
      registers.  For an aggregate type to be integer like, its size
-     must be less than or equal to DEPRECATED_REGISTER_SIZE and the
+     must be less than or equal to INT_REGISTER_SIZE and the
      offset of each addressable subfield must be zero.  Note that bit
      fields are not addressable, and all addressable subfields of
      unions always start at offset zero.
@@ -2143,7 +2174,7 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
 
   /* All aggregate types that won't fit in a register must be returned
      in memory.  */
-  if (TYPE_LENGTH (type) > DEPRECATED_REGISTER_SIZE)
+  if (TYPE_LENGTH (type) > INT_REGISTER_SIZE)
     {
       return 1;
     }
@@ -2170,7 +2201,7 @@ arm_return_in_memory (struct gdbarch *gdbarch, struct type *type)
       int i;
       /* Need to check if this struct/union is "integer" like.  For
          this to be true, its size must be less than or equal to
-         DEPRECATED_REGISTER_SIZE and the offset of each addressable
+         INT_REGISTER_SIZE and the offset of each addressable
          subfield must be zero.  Note that bit fields are not
          addressable, and unions always start at offset zero.  If any
          of the subfields is a floating point type, the struct/union
@@ -2330,13 +2361,13 @@ arm_return_value (struct gdbarch *gdbarch, struct type *valtype,
 
 
 static int
-arm_get_longjmp_target (CORE_ADDR *pc)
+arm_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
 {
   CORE_ADDR jb_addr;
   char buf[INT_REGISTER_SIZE];
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
   
-  jb_addr = read_register (ARM_A1_REGNUM);
+  jb_addr = get_frame_register_unsigned (frame, ARM_A1_REGNUM);
 
   if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
                          INT_REGISTER_SIZE))
@@ -2346,38 +2377,24 @@ arm_get_longjmp_target (CORE_ADDR *pc)
   return 1;
 }
 
-/* Return non-zero if the PC is inside a thumb call thunk.  */
-
-int
-arm_in_call_stub (CORE_ADDR pc, char *name)
-{
-  CORE_ADDR start_addr;
-
-  /* Find the starting address of the function containing the PC.  If
-     the caller didn't give us a name, look it up at the same time.  */
-  if (0 == find_pc_partial_function (pc, name ? NULL : &name, 
-                                    &start_addr, NULL))
-    return 0;
-
-  return strncmp (name, "_call_via_r", 11) == 0;
-}
-
-/* If PC is in a Thumb call or return stub, return the address of the
-   target PC, which is in a register.  The thunk functions are called
-   _called_via_xx, where x is the register name.  The possible names
-   are r0-r9, sl, fp, ip, sp, and lr.  */
+/* Recognize GCC and GNU ld's trampolines.  If we are in a trampoline,
+   return the target PC.  Otherwise return 0.  */
 
 CORE_ADDR
-arm_skip_stub (CORE_ADDR pc)
+arm_skip_stub (struct frame_info *frame, CORE_ADDR pc)
 {
   char *name;
+  int namelen;
   CORE_ADDR start_addr;
 
   /* Find the starting address and name of the function containing the PC.  */
   if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0)
     return 0;
 
-  /* Call thunks always start with "_call_via_".  */
+  /* If PC is in a Thumb call or return stub, return the address of the
+     target PC, which is in a register.  The thunk functions are called
+     _call_via_xx, where x is the register name.  The possible names
+     are r0-r9, sl, fp, ip, sp, and lr.  */
   if (strncmp (name, "_call_via_", 10) == 0)
     {
       /* Use the name suffix to determine which register contains the
@@ -2387,10 +2404,47 @@ arm_skip_stub (CORE_ADDR pc)
        "r8", "r9", "sl", "fp", "ip", "sp", "lr"
       };
       int regno;
+      int offset = strlen (name) - 2;
 
       for (regno = 0; regno <= 14; regno++)
-       if (strcmp (&name[10], table[regno]) == 0)
-         return read_register (regno);
+       if (strcmp (&name[offset], table[regno]) == 0)
+         return get_frame_register_unsigned (frame, regno);
+    }
+
+  /* GNU ld generates __foo_from_arm or __foo_from_thumb for
+     non-interworking calls to foo.  We could decode the stubs
+     to find the target but it's easier to use the symbol table.  */
+  namelen = strlen (name);
+  if (name[0] == '_' && name[1] == '_'
+      && ((namelen > 2 + strlen ("_from_thumb")
+          && strncmp (name + namelen - strlen ("_from_thumb"), "_from_thumb",
+                      strlen ("_from_thumb")) == 0)
+         || (namelen > 2 + strlen ("_from_arm")
+             && strncmp (name + namelen - strlen ("_from_arm"), "_from_arm",
+                         strlen ("_from_arm")) == 0)))
+    {
+      char *target_name;
+      int target_len = namelen - 2;
+      struct minimal_symbol *minsym;
+      struct objfile *objfile;
+      struct obj_section *sec;
+
+      if (name[namelen - 1] == 'b')
+       target_len -= strlen ("_from_thumb");
+      else
+       target_len -= strlen ("_from_arm");
+
+      target_name = alloca (target_len + 1);
+      memcpy (target_name, name + 2, target_len);
+      target_name[target_len] = '\0';
+
+      sec = find_pc_section (pc);
+      objfile = (sec == NULL) ? NULL : sec->objfile;
+      minsym = lookup_minimal_symbol (target_name, NULL, objfile);
+      if (minsym != NULL)
+       return SYMBOL_VALUE_ADDRESS (minsym);
+      else
+       return 0;
     }
 
   return 0;                    /* not a stub */
@@ -2576,18 +2630,20 @@ arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
 }
 
 static void
-arm_write_pc (CORE_ADDR pc, ptid_t ptid)
+arm_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  write_register_pid (ARM_PC_REGNUM, pc, ptid);
+  regcache_cooked_write_unsigned (regcache, ARM_PC_REGNUM, pc);
 
   /* If necessary, set the T bit.  */
   if (arm_apcs_32)
     {
-      CORE_ADDR val = read_register_pid (ARM_PS_REGNUM, ptid);
+      ULONGEST val;
+      regcache_cooked_read_unsigned (regcache, ARM_PS_REGNUM, &val);
       if (arm_pc_is_thumb (pc))
-       write_register_pid (ARM_PS_REGNUM, val | 0x20, ptid);
+       regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM, val | 0x20);
       else
-       write_register_pid (ARM_PS_REGNUM, val & ~(CORE_ADDR) 0x20, ptid);
+       regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM,
+                                       val & ~(ULONGEST) 0x20);
     }
 }
 
@@ -2819,39 +2875,17 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        }
     }
 
-  /* Now that we have inferred any architecture settings that we
-     can, try to inherit from the last ARM ABI.  */
-  if (arches != NULL)
-    {
-      if (arm_abi == ARM_ABI_AUTO)
-       arm_abi = gdbarch_tdep (arches->gdbarch)->arm_abi;
-
-      if (fp_model == ARM_FLOAT_AUTO)
-       fp_model = gdbarch_tdep (arches->gdbarch)->fp_model;
-    }
-  else
-    {
-      /* There was no prior ARM architecture; fill in default values.  */
-
-      if (arm_abi == ARM_ABI_AUTO)
-       arm_abi = ARM_ABI_APCS;
-
-      /* We used to default to FPA for generic ARM, but almost nobody
-        uses that now, and we now provide a way for the user to force
-        the model.  So default to the most useful variant.  */
-      if (fp_model == ARM_FLOAT_AUTO)
-       fp_model = ARM_FLOAT_SOFT_FPA;
-    }
-
   /* If there is already a candidate, use it.  */
   for (best_arch = gdbarch_list_lookup_by_info (arches, &info);
        best_arch != NULL;
        best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
     {
-      if (arm_abi != gdbarch_tdep (best_arch->gdbarch)->arm_abi)
+      if (arm_abi != ARM_ABI_AUTO
+         && arm_abi != gdbarch_tdep (best_arch->gdbarch)->arm_abi)
        continue;
 
-      if (fp_model != gdbarch_tdep (best_arch->gdbarch)->fp_model)
+      if (fp_model != ARM_FLOAT_AUTO
+         && fp_model != gdbarch_tdep (best_arch->gdbarch)->fp_model)
        continue;
 
       /* Found a match.  */
@@ -2954,8 +2988,6 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
   set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno);
 
-  /* Integer registers are 4 bytes.  */
-  set_gdbarch_deprecated_register_size (gdbarch, 4);
   set_gdbarch_register_name (gdbarch, arm_register_name);
 
   /* Returning results.  */
@@ -2983,12 +3015,23 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Now we have tuned the configuration, set a few final things,
      based on what the OS ABI has told us.  */
 
+  /* If the ABI is not otherwise marked, assume the old GNU APCS.  EABI
+     binaries are always marked.  */
+  if (tdep->arm_abi == ARM_ABI_AUTO)
+    tdep->arm_abi = ARM_ABI_APCS;
+
+  /* We used to default to FPA for generic ARM, but almost nobody
+     uses that now, and we now provide a way for the user to force
+     the model.  So default to the most useful variant.  */
+  if (tdep->fp_model == ARM_FLOAT_AUTO)
+    tdep->fp_model = ARM_FLOAT_SOFT_FPA;
+
   if (tdep->jb_pc >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
 
   /* Floating point sizes and format.  */
   set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
-  if (fp_model == ARM_FLOAT_SOFT_FPA || fp_model == ARM_FLOAT_FPA)
+  if (tdep->fp_model == ARM_FLOAT_SOFT_FPA || tdep->fp_model == ARM_FLOAT_FPA)
     {
       set_gdbarch_double_format
        (gdbarch, floatformats_ieee_double_littlebyte_bigword);
This page took 0.032403 seconds and 4 git commands to generate.