/* Common target dependent code for GDB on ARM systems.
Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999, 2000,
- 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
/* Macros for setting and testing a bit in a minimal symbol that marks
it as Thumb function. The MSB of the minimal symbol's "info" field
- is used for this purpose. This field is already being used to store
- the symbol size, so the assumption is that the symbol size cannot
- exceed 2^31.
+ is used for this purpose.
MSYMBOL_SET_SPECIAL Actually sets the "special" bit.
- MSYMBOL_IS_SPECIAL Tests the "special" bit in a minimal symbol.
- MSYMBOL_SIZE Returns the size of the minimal symbol,
- i.e. the "info" field with the "special" bit
- masked out. */
+ MSYMBOL_IS_SPECIAL Tests the "special" bit in a minimal symbol. */
#define MSYMBOL_SET_SPECIAL(msym) \
MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) \
#define MSYMBOL_IS_SPECIAL(msym) \
(((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
-#define MSYMBOL_SIZE(msym) \
- ((long) MSYMBOL_INFO (msym) & 0x7fffffff)
-
/* The list of available "set arm ..." and "show arm ..." commands. */
static struct cmd_list_element *setarmcmdlist = NULL;
static struct cmd_list_element *showarmcmdlist = NULL;
}
else if (insn == 0xe52de004) /* str lr, [sp, #-4]! */
{
- /* Function is frameless: extra_info defaults OK? */
+ sp_offset -= 4;
+ cache->saved_regs[ARM_LR_REGNUM].addr = sp_offset;
continue;
}
else if ((insn & 0xffff0000) == 0xe92d0000)
/* Calculate actual addresses of saved registers using offsets
determined by arm_scan_prologue. */
for (reg = 0; reg < NUM_REGS; reg++)
- if (cache->saved_regs[reg].addr != 0)
+ if (trad_frame_addr_p (cache->saved_regs, reg))
cache->saved_regs[reg].addr += cache->prev_sp;
return cache;
/* This is meant to halt the backtrace at "_start". Make sure we
don't halt it at a generic dummy frame. */
- if (func <= LOWEST_PC || deprecated_inside_entry_file (func))
+ if (func <= LOWEST_PC)
return;
/* If we've hit a wall, stop. */
cache->framereg = ARM_SP_REGNUM;
cache->prev_sp
= read_memory_integer (cache->saved_regs[cache->framereg].addr,
- REGISTER_RAW_SIZE (cache->framereg));
+ DEPRECATED_REGISTER_RAW_SIZE (cache->framereg));
return cache;
}
MSYMBOL_SET_SPECIAL (msym);
}
+static void
+arm_write_pc (CORE_ADDR pc, ptid_t ptid)
+{
+ write_register_pid (ARM_PC_REGNUM, pc, ptid);
+
+ /* If necessary, set the T bit. */
+ if (arm_apcs_32)
+ {
+ CORE_ADDR val = read_register_pid (ARM_PS_REGNUM, ptid);
+ if (arm_pc_is_thumb (pc))
+ write_register_pid (ARM_PS_REGNUM, val | 0x20, ptid);
+ else
+ write_register_pid (ARM_PS_REGNUM, val & ~(CORE_ADDR) 0x20, ptid);
+ }
+}
\f
static enum gdb_osabi
arm_elf_osabi_sniffer (bfd *abfd)
set_gdbarch_push_dummy_call (gdbarch, arm_push_dummy_call);
+ set_gdbarch_write_pc (gdbarch, arm_write_pc);
+
/* Frame handling. */
set_gdbarch_unwind_dummy_id (gdbarch, arm_unwind_dummy_id);
set_gdbarch_unwind_pc (gdbarch, arm_unwind_pc);
set_gdbarch_smash_text_address (gdbarch, arm_smash_text_address);
set_gdbarch_addr_bits_remove (gdbarch, arm_addr_bits_remove);
- /* Offset from address of function to start of its code. */
- set_gdbarch_function_start_offset (gdbarch, 0);
-
/* Advance PC across function entry code. */
set_gdbarch_skip_prologue (gdbarch, arm_skip_prologue);
/* Breakpoint manipulation. */
set_gdbarch_breakpoint_from_pc (gdbarch, arm_breakpoint_from_pc);
- set_gdbarch_decr_pc_after_break (gdbarch, 0);
/* Information about registers, etc. */
set_gdbarch_print_float_info (gdbarch, arm_print_float_info);