* arm-tdep.h: New file.
* arm-tdep.c: Include arm-tdep.h. (arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call) (arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy) (arm_print_float_info, arm_register_type, convert_to_extended) (arm_elf_make_msymbols_special, arm_coff_make_msymbol_special) (arm_extract_return_value, arm_register_name): Make static. (arm_software_single_step): Similarly. Fix types in declaration. (arm_register_byte, arm_register_raw_size, arm_register_virtual_size) (arm_store_return_value, arm_store_struct_return): New functions. (arm_gdbarch_init): Register the above functions. Also register call_dummy_start_offset, sizeof_call_dummy_words, function_start_offset, inner_than, decr_pc_after_break, fp_regnum, sp_regnum, pc_regnum, register_bytes, num_regs, max_register_raw_size, max_register_virtual_size, register_size. Set up prologue_cache.saved_regs here, rather than ... (_initialize_arm_tdep): ... here. * config/arm/tm-arm.h (struct type, struct value): Delete forward declarations. (arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call) (arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy) (arm_print_float_info, arm_register_type, convert_to_extended) (arm_elf_make_msymbols_special, arm_coff_make_msymbol_special) (arm_extract_return_value, arm_register_name): Delete declarations. (SMASH_TEXT_ADDRESS, ADDR_BITS_REMOVE, FUNCTION_START_OFFSET) (SKIP_PROLOGUE, SAVED_PC_AFTER_CALL, INNER_THAN, BREAKPOINT_FROM_PC) (DECR_PC_AFTER_BREAK, PRINT_FLOAT_INFO, REGISTER_SIZE, NUM_REGS) (REGISTER_NAME, REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE) (REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE) (MAX_REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE, STORE_STRUCT_RETURN) (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, CALL_DUMMY_WORDS) (SIZEOF_CALL_DUMMY_WORDS, CALL_DUMMY_START_OFFSET, FIX_CALL_DUMMY) (SOFTWARE_SINGLE_STEP_P, SOFTWARE_SINGLE_STEP) (ELF_MAKE_MSYMBOL_SPECIAL, COFF_MAKE_MSYMBOL_SPECIAL) Delete. (arm_pc_is_thumb, arm_pc_is_thumb_dummy, thumb_get_next_pc) (arm_get_next_pc): No-longer static -- these are needed by the RDI interface. * arm-linux-nat.c arm-linux-tdep.c armnbsd-nat.c: Include arm-tdep.h. * remote-rdi.c remote-rdp.c: Likewise. * Makefile.in (arm-linux-nat.o, arm-linux-tdep.o arm-tdep.o) (armnbsd-nat.o, remote-rdi.o, remote_rdp.o): Update dependencies. * config/arm/tm-nbsd.h (SOFTWARE_SINGLE_STEP_P): Delete bogus definition. * arm-tdep.h (ARM_A1_REGNUM, ARM_A4_REGNUM, ARM_AP_REGNUM) (ARM_SP_REGNUM, ARM_LR_REGNUM, ARM_PC_REGNUM, ARM_F0_REGNUM) (ARM_F3_REGNUM, ARM_F7_REGNUM, ARM_FPS_REGNUM, ARM_PS_REGNUM): Renamed from non-ARM_ prefixed definitions. * arm-tdep.c armnbsd-nat.c arm-linux-nat.c arm-linux-tdep.c: Update all uses of above. * remote-rdi.c remote-rdp.c: Likewise. * arm-linux-nat.c (ARM_CPSR_REGNUM): Renamed from CPSR_REGNUM.
This commit is contained in:
parent
56930d376b
commit
34e8f22ded
|
@ -1,3 +1,58 @@
|
|||
2002-02-11 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm-tdep.h: New file.
|
||||
* arm-tdep.c: Include arm-tdep.h.
|
||||
(arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call)
|
||||
(arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy)
|
||||
(arm_print_float_info, arm_register_type, convert_to_extended)
|
||||
(arm_elf_make_msymbols_special, arm_coff_make_msymbol_special)
|
||||
(arm_extract_return_value, arm_register_name): Make static.
|
||||
(arm_software_single_step): Similarly. Fix types in declaration.
|
||||
(arm_register_byte, arm_register_raw_size, arm_register_virtual_size)
|
||||
(arm_store_return_value, arm_store_struct_return): New functions.
|
||||
(arm_gdbarch_init): Register the above functions. Also register
|
||||
call_dummy_start_offset, sizeof_call_dummy_words,
|
||||
function_start_offset, inner_than, decr_pc_after_break, fp_regnum,
|
||||
sp_regnum, pc_regnum, register_bytes, num_regs, max_register_raw_size,
|
||||
max_register_virtual_size, register_size. Set up
|
||||
prologue_cache.saved_regs here, rather than ...
|
||||
(_initialize_arm_tdep): ... here.
|
||||
* config/arm/tm-arm.h (struct type, struct value): Delete forward
|
||||
declarations.
|
||||
(arm_addr_bits_remove, arm_smash_text_address, arm_saved_pc_after_call)
|
||||
(arm_skip_prologue, arm_call_dummy_words, arm_fix_call_dummy)
|
||||
(arm_print_float_info, arm_register_type, convert_to_extended)
|
||||
(arm_elf_make_msymbols_special, arm_coff_make_msymbol_special)
|
||||
(arm_extract_return_value, arm_register_name): Delete declarations.
|
||||
(SMASH_TEXT_ADDRESS, ADDR_BITS_REMOVE, FUNCTION_START_OFFSET)
|
||||
(SKIP_PROLOGUE, SAVED_PC_AFTER_CALL, INNER_THAN, BREAKPOINT_FROM_PC)
|
||||
(DECR_PC_AFTER_BREAK, PRINT_FLOAT_INFO, REGISTER_SIZE, NUM_REGS)
|
||||
(REGISTER_NAME, REGISTER_BYTES, REGISTER_BYTE, REGISTER_RAW_SIZE)
|
||||
(REGISTER_VIRTUAL_SIZE, MAX_REGISTER_RAW_SIZE)
|
||||
(MAX_REGISTER_VIRTUAL_SIZE, REGISTER_VIRTUAL_TYPE, STORE_STRUCT_RETURN)
|
||||
(EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, CALL_DUMMY_WORDS)
|
||||
(SIZEOF_CALL_DUMMY_WORDS, CALL_DUMMY_START_OFFSET, FIX_CALL_DUMMY)
|
||||
(SOFTWARE_SINGLE_STEP_P, SOFTWARE_SINGLE_STEP)
|
||||
(ELF_MAKE_MSYMBOL_SPECIAL, COFF_MAKE_MSYMBOL_SPECIAL) Delete.
|
||||
(arm_pc_is_thumb, arm_pc_is_thumb_dummy, thumb_get_next_pc)
|
||||
(arm_get_next_pc): No-longer static -- these are needed by the RDI
|
||||
interface.
|
||||
* arm-linux-nat.c arm-linux-tdep.c armnbsd-nat.c: Include arm-tdep.h.
|
||||
* remote-rdi.c remote-rdp.c: Likewise.
|
||||
* Makefile.in (arm-linux-nat.o, arm-linux-tdep.o arm-tdep.o)
|
||||
(armnbsd-nat.o, remote-rdi.o, remote_rdp.o): Update dependencies.
|
||||
* config/arm/tm-nbsd.h (SOFTWARE_SINGLE_STEP_P): Delete bogus
|
||||
definition.
|
||||
|
||||
* arm-tdep.h (ARM_A1_REGNUM, ARM_A4_REGNUM, ARM_AP_REGNUM)
|
||||
(ARM_SP_REGNUM, ARM_LR_REGNUM, ARM_PC_REGNUM, ARM_F0_REGNUM)
|
||||
(ARM_F3_REGNUM, ARM_F7_REGNUM, ARM_FPS_REGNUM, ARM_PS_REGNUM): Renamed
|
||||
from non-ARM_ prefixed definitions.
|
||||
* arm-tdep.c armnbsd-nat.c arm-linux-nat.c arm-linux-tdep.c: Update
|
||||
all uses of above.
|
||||
* remote-rdi.c remote-rdp.c: Likewise.
|
||||
* arm-linux-nat.c (ARM_CPSR_REGNUM): Renamed from CPSR_REGNUM.
|
||||
|
||||
2002-02-11 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm-tdep.c (arm_frameless_function_invocation)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* GNU/Linux on ARM native support.
|
||||
Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -39,7 +39,7 @@ extern int arm_apcs_32;
|
|||
#define typeDouble 0x02
|
||||
#define typeExtended 0x03
|
||||
#define FPWORDS 28
|
||||
#define CPSR_REGNUM 16
|
||||
#define ARM_CPSR_REGNUM 16
|
||||
|
||||
typedef union tagFPREG
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
|
|||
mem[0] = fpa11->fpreg[fn].fSingle;
|
||||
mem[1] = 0;
|
||||
mem[2] = 0;
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -111,7 +111,7 @@ fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
|
|||
mem[0] = fpa11->fpreg[fn].fDouble[1];
|
||||
mem[1] = fpa11->fpreg[fn].fDouble[0];
|
||||
mem[2] = 0;
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -120,7 +120,7 @@ fetch_nwfpe_none (unsigned int fn)
|
|||
unsigned int mem[3] =
|
||||
{0, 0, 0};
|
||||
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -131,13 +131,13 @@ fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
|
|||
mem[0] = fpa11->fpreg[fn].fExtended[0]; /* sign & exponent */
|
||||
mem[1] = fpa11->fpreg[fn].fExtended[2]; /* ls bits */
|
||||
mem[2] = fpa11->fpreg[fn].fExtended[1]; /* ms bits */
|
||||
supply_register (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
supply_register (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
fetch_nwfpe_register (int regno, FPA11 * fpa11)
|
||||
{
|
||||
int fn = regno - F0_REGNUM;
|
||||
int fn = regno - ARM_F0_REGNUM;
|
||||
|
||||
switch (fpa11->fType[fn])
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ store_nwfpe_single (unsigned int fn, FPA11 * fpa11)
|
|||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
read_register_gen (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
fpa11->fpreg[fn].fSingle = mem[0];
|
||||
fpa11->fType[fn] = typeSingle;
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ store_nwfpe_double (unsigned int fn, FPA11 * fpa11)
|
|||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
read_register_gen (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
fpa11->fpreg[fn].fDouble[1] = mem[0];
|
||||
fpa11->fpreg[fn].fDouble[0] = mem[1];
|
||||
fpa11->fType[fn] = typeDouble;
|
||||
|
@ -184,7 +184,7 @@ store_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
|
|||
{
|
||||
unsigned int mem[3];
|
||||
|
||||
read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
|
||||
read_register_gen (ARM_F0_REGNUM + fn, (char *) &mem[0]);
|
||||
fpa11->fpreg[fn].fExtended[0] = mem[0]; /* sign & exponent */
|
||||
fpa11->fpreg[fn].fExtended[2] = mem[1]; /* ls bits */
|
||||
fpa11->fpreg[fn].fExtended[1] = mem[2]; /* ms bits */
|
||||
|
@ -196,7 +196,7 @@ store_nwfpe_register (int regno, FPA11 * fpa11)
|
|||
{
|
||||
if (register_cached (regno))
|
||||
{
|
||||
unsigned int fn = regno - F0_REGNUM;
|
||||
unsigned int fn = regno - ARM_F0_REGNUM;
|
||||
switch (fpa11->fType[fn])
|
||||
{
|
||||
case typeSingle:
|
||||
|
@ -236,13 +236,13 @@ fetch_fpregister (int regno)
|
|||
}
|
||||
|
||||
/* Fetch fpsr. */
|
||||
if (FPS_REGNUM == regno)
|
||||
supply_register (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
if (ARM_FPS_REGNUM == regno)
|
||||
supply_register (ARM_FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Fetch the floating point register. */
|
||||
if (regno >= F0_REGNUM && regno <= F7_REGNUM)
|
||||
if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
|
||||
{
|
||||
int fn = regno - F0_REGNUM;
|
||||
int fn = regno - ARM_F0_REGNUM;
|
||||
|
||||
switch (fp.fType[fn])
|
||||
{
|
||||
|
@ -285,12 +285,12 @@ fetch_fpregs (void)
|
|||
}
|
||||
|
||||
/* Fetch fpsr. */
|
||||
supply_register (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
supply_register (ARM_FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Fetch the floating point registers. */
|
||||
for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
|
||||
for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
|
||||
{
|
||||
int fn = regno - F0_REGNUM;
|
||||
int fn = regno - ARM_F0_REGNUM;
|
||||
|
||||
switch (fp.fType[fn])
|
||||
{
|
||||
|
@ -333,11 +333,11 @@ store_fpregister (int regno)
|
|||
}
|
||||
|
||||
/* Store fpsr. */
|
||||
if (FPS_REGNUM == regno && register_cached (FPS_REGNUM))
|
||||
read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
if (ARM_FPS_REGNUM == regno && register_cached (ARM_FPS_REGNUM))
|
||||
read_register_gen (ARM_FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Store the floating point register. */
|
||||
if (regno >= F0_REGNUM && regno <= F7_REGNUM)
|
||||
if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
|
||||
{
|
||||
store_nwfpe_register (regno, &fp);
|
||||
}
|
||||
|
@ -371,11 +371,11 @@ store_fpregs (void)
|
|||
}
|
||||
|
||||
/* Store fpsr. */
|
||||
if (register_cached (FPS_REGNUM))
|
||||
read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
|
||||
if (register_cached (ARM_FPS_REGNUM))
|
||||
read_register_gen (ARM_FPS_REGNUM, (char *) &fp.fpsr);
|
||||
|
||||
/* Store the floating point registers. */
|
||||
for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
|
||||
for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
|
||||
{
|
||||
fetch_nwfpe_register (regno, &fp);
|
||||
}
|
||||
|
@ -407,21 +407,21 @@ fetch_register (int regno)
|
|||
return;
|
||||
}
|
||||
|
||||
if (regno >= A1_REGNUM && regno < PC_REGNUM)
|
||||
if (regno >= ARM_A1_REGNUM && regno < ARM_PC_REGNUM)
|
||||
supply_register (regno, (char *) ®s[regno]);
|
||||
|
||||
if (PS_REGNUM == regno)
|
||||
if (ARM_PS_REGNUM == regno)
|
||||
{
|
||||
if (arm_apcs_32)
|
||||
supply_register (PS_REGNUM, (char *) ®s[CPSR_REGNUM]);
|
||||
supply_register (ARM_PS_REGNUM, (char *) ®s[ARM_CPSR_REGNUM]);
|
||||
else
|
||||
supply_register (PS_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
supply_register (ARM_PS_REGNUM, (char *) ®s[ARM_PC_REGNUM]);
|
||||
}
|
||||
|
||||
if (PC_REGNUM == regno)
|
||||
if (ARM_PC_REGNUM == regno)
|
||||
{
|
||||
regs[PC_REGNUM] = ADDR_BITS_REMOVE (regs[PC_REGNUM]);
|
||||
supply_register (PC_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
regs[ARM_PC_REGNUM] = ADDR_BITS_REMOVE (regs[ARM_PC_REGNUM]);
|
||||
supply_register (ARM_PC_REGNUM, (char *) ®s[ARM_PC_REGNUM]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,16 +444,16 @@ fetch_regs (void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
|
||||
for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
|
||||
supply_register (regno, (char *) ®s[regno]);
|
||||
|
||||
if (arm_apcs_32)
|
||||
supply_register (PS_REGNUM, (char *) ®s[CPSR_REGNUM]);
|
||||
supply_register (ARM_PS_REGNUM, (char *) ®s[ARM_CPSR_REGNUM]);
|
||||
else
|
||||
supply_register (PS_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
supply_register (ARM_PS_REGNUM, (char *) ®s[ARM_PC_REGNUM]);
|
||||
|
||||
regs[PC_REGNUM] = ADDR_BITS_REMOVE (regs[PC_REGNUM]);
|
||||
supply_register (PC_REGNUM, (char *) ®s[PC_REGNUM]);
|
||||
regs[ARM_PC_REGNUM] = ADDR_BITS_REMOVE (regs[ARM_PC_REGNUM]);
|
||||
supply_register (ARM_PC_REGNUM, (char *) ®s[ARM_PC_REGNUM]);
|
||||
}
|
||||
|
||||
/* Store all general registers of the process from the values in
|
||||
|
@ -479,7 +479,7 @@ store_register (int regno)
|
|||
return;
|
||||
}
|
||||
|
||||
if (regno >= A1_REGNUM && regno <= PC_REGNUM)
|
||||
if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
|
||||
read_register_gen (regno, (char *) ®s[regno]);
|
||||
|
||||
ret = ptrace (PTRACE_SETREGS, tid, 0, ®s);
|
||||
|
@ -507,7 +507,7 @@ store_regs (void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++)
|
||||
for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
|
||||
{
|
||||
if (register_cached (regno))
|
||||
read_register_gen (regno, (char *) ®s[regno]);
|
||||
|
@ -536,10 +536,10 @@ fetch_inferior_registers (int regno)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (regno < F0_REGNUM || regno > FPS_REGNUM)
|
||||
if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
|
||||
fetch_register (regno);
|
||||
|
||||
if (regno >= F0_REGNUM && regno <= FPS_REGNUM)
|
||||
if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
|
||||
fetch_fpregister (regno);
|
||||
}
|
||||
}
|
||||
|
@ -558,10 +558,10 @@ store_inferior_registers (int regno)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
|
||||
if ((regno < ARM_F0_REGNUM) || (regno > ARM_FPS_REGNUM))
|
||||
store_register (regno);
|
||||
|
||||
if ((regno >= F0_REGNUM) && (regno <= FPS_REGNUM))
|
||||
if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
|
||||
store_fpregister (regno);
|
||||
}
|
||||
}
|
||||
|
@ -576,18 +576,20 @@ fill_gregset (gdb_gregset_t *gregsetp, int regno)
|
|||
if (-1 == regno)
|
||||
{
|
||||
int regnum;
|
||||
for (regnum = A1_REGNUM; regnum <= PC_REGNUM; regnum++)
|
||||
for (regnum = ARM_A1_REGNUM; regnum <= ARM_PC_REGNUM; regnum++)
|
||||
read_register_gen (regnum, (char *) &(*gregsetp)[regnum]);
|
||||
}
|
||||
else if (regno >= A1_REGNUM && regno <= PC_REGNUM)
|
||||
else if (regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
|
||||
read_register_gen (regno, (char *) &(*gregsetp)[regno]);
|
||||
|
||||
if (PS_REGNUM == regno || -1 == regno)
|
||||
if (ARM_PS_REGNUM == regno || -1 == regno)
|
||||
{
|
||||
if (arm_apcs_32)
|
||||
read_register_gen (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
|
||||
read_register_gen (ARM_PS_REGNUM,
|
||||
(char *) &(*gregsetp)[ARM_CPSR_REGNUM]);
|
||||
else
|
||||
read_register_gen (PC_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
|
||||
read_register_gen (ARM_PC_REGNUM,
|
||||
(char *) &(*gregsetp)[ARM_PC_REGNUM]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,16 +601,16 @@ supply_gregset (gdb_gregset_t *gregsetp)
|
|||
{
|
||||
int regno, reg_pc;
|
||||
|
||||
for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
|
||||
for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
|
||||
supply_register (regno, (char *) &(*gregsetp)[regno]);
|
||||
|
||||
if (arm_apcs_32)
|
||||
supply_register (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
|
||||
supply_register (ARM_PS_REGNUM, (char *) &(*gregsetp)[ARM_CPSR_REGNUM]);
|
||||
else
|
||||
supply_register (PS_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
|
||||
supply_register (ARM_PS_REGNUM, (char *) &(*gregsetp)[ARM_PC_REGNUM]);
|
||||
|
||||
reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[PC_REGNUM]);
|
||||
supply_register (PC_REGNUM, (char *) ®_pc);
|
||||
reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[ARM_PC_REGNUM]);
|
||||
supply_register (ARM_PC_REGNUM, (char *) ®_pc);
|
||||
}
|
||||
|
||||
/* Fill register regno (if it is a floating-point register) in
|
||||
|
@ -623,18 +625,18 @@ fill_fpregset (gdb_fpregset_t *fpregsetp, int regno)
|
|||
if (-1 == regno)
|
||||
{
|
||||
int regnum;
|
||||
for (regnum = F0_REGNUM; regnum <= F7_REGNUM; regnum++)
|
||||
for (regnum = ARM_F0_REGNUM; regnum <= ARM_F7_REGNUM; regnum++)
|
||||
store_nwfpe_register (regnum, fp);
|
||||
}
|
||||
else if (regno >= F0_REGNUM && regno <= F7_REGNUM)
|
||||
else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
|
||||
{
|
||||
store_nwfpe_register (regno, fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store fpsr. */
|
||||
if (FPS_REGNUM == regno || -1 == regno)
|
||||
read_register_gen (FPS_REGNUM, (char *) &fp->fpsr);
|
||||
if (ARM_FPS_REGNUM == regno || -1 == regno)
|
||||
read_register_gen (ARM_FPS_REGNUM, (char *) &fp->fpsr);
|
||||
}
|
||||
|
||||
/* Fill GDB's register array with the floating-point register values
|
||||
|
@ -647,10 +649,10 @@ supply_fpregset (gdb_fpregset_t *fpregsetp)
|
|||
FPA11 *fp = (FPA11 *) fpregsetp;
|
||||
|
||||
/* Fetch fpsr. */
|
||||
supply_register (FPS_REGNUM, (char *) &fp->fpsr);
|
||||
supply_register (ARM_FPS_REGNUM, (char *) &fp->fpsr);
|
||||
|
||||
/* Fetch the floating point registers. */
|
||||
for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
|
||||
for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
|
||||
{
|
||||
fetch_nwfpe_register (regno, fp);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* GNU/Linux on ARM target support.
|
||||
Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -28,6 +28,8 @@
|
|||
#include "regcache.h"
|
||||
#include "doublest.h"
|
||||
|
||||
#include "arm-tdep.h"
|
||||
|
||||
/* For arm_linux_skip_solib_resolver. */
|
||||
#include "symtab.h"
|
||||
#include "symfile.h"
|
||||
|
@ -51,10 +53,10 @@ LONGEST arm_linux_call_dummy_words[] =
|
|||
|
||||
/* Figure out where the longjmp will land. We expect that we have
|
||||
just entered longjmp and haven't yet altered r0, r1, so the
|
||||
arguments are still in the registers. (A1_REGNUM) points at the
|
||||
jmp_buf structure from which we extract the pc (JB_PC) that we will
|
||||
land at. The pc is copied into ADDR. This routine returns true on
|
||||
success. */
|
||||
arguments are still in the registers. (ARM_A1_REGNUM) points at
|
||||
the jmp_buf structure from which we extract the pc (JB_PC) that we
|
||||
will land at. The pc is copied into ADDR. This routine returns
|
||||
true on success. */
|
||||
|
||||
#define LONGJMP_TARGET_SIZE sizeof(int)
|
||||
#define JB_ELEMENT_SIZE sizeof(int)
|
||||
|
@ -69,7 +71,7 @@ arm_get_longjmp_target (CORE_ADDR * pc)
|
|||
CORE_ADDR jb_addr;
|
||||
char buf[LONGJMP_TARGET_SIZE];
|
||||
|
||||
jb_addr = read_register (A1_REGNUM);
|
||||
jb_addr = read_register (ARM_A1_REGNUM);
|
||||
|
||||
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
|
||||
LONGJMP_TARGET_SIZE))
|
||||
|
@ -96,7 +98,8 @@ arm_linux_extract_return_value (struct type *type,
|
|||
GDB. I suspect this won't handle NWFPE registers correctly, nor
|
||||
will the default ARM version (arm_extract_return_value()). */
|
||||
|
||||
int regnum = (TYPE_CODE_FLT == TYPE_CODE (type)) ? F0_REGNUM : A1_REGNUM;
|
||||
int regnum = ((TYPE_CODE_FLT == TYPE_CODE (type))
|
||||
? ARM_F0_REGNUM : ARM_A1_REGNUM);
|
||||
memcpy (valbuf, ®buf[REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
|
||||
}
|
||||
|
||||
|
@ -160,7 +163,7 @@ arm_linux_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
|||
}
|
||||
|
||||
/* Initialize the integer argument register pointer. */
|
||||
argreg = A1_REGNUM;
|
||||
argreg = ARM_A1_REGNUM;
|
||||
|
||||
/* The struct_return pointer occupies the first parameter passing
|
||||
register. */
|
||||
|
@ -518,9 +521,9 @@ arm_linux_sigcontext_register_address (CORE_ADDR sp, CORE_ADDR pc, int regno)
|
|||
PSR value follows the sixteen registers which accounts for
|
||||
the constant 19 below. */
|
||||
|
||||
if (0 <= regno && regno <= PC_REGNUM)
|
||||
if (0 <= regno && regno <= ARM_PC_REGNUM)
|
||||
reg_addr = sigcontext_addr + 12 + (4 * regno);
|
||||
else if (regno == PS_REGNUM)
|
||||
else if (regno == ARM_PS_REGNUM)
|
||||
reg_addr = sigcontext_addr + 19 * 4;
|
||||
}
|
||||
|
||||
|
|
316
gdb/arm-tdep.c
316
gdb/arm-tdep.c
|
@ -19,6 +19,8 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <ctype.h> /* XXX for isupper () */
|
||||
|
||||
#include "defs.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
@ -26,13 +28,15 @@
|
|||
#include "gdbcore.h"
|
||||
#include "symfile.h"
|
||||
#include "gdb_string.h"
|
||||
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
|
||||
#include "dis-asm.h" /* For register flavors. */
|
||||
#include <ctype.h> /* for isupper () */
|
||||
#include "regcache.h"
|
||||
#include "doublest.h"
|
||||
#include "value.h"
|
||||
#include "arch-utils.h"
|
||||
#include "solib-svr4.h"
|
||||
|
||||
#include "arm-tdep.h"
|
||||
|
||||
#include "elf-bfd.h"
|
||||
#include "coff/internal.h"
|
||||
|
||||
|
@ -262,7 +266,7 @@ static int caller_is_thumb;
|
|||
/* Determine if the program counter specified in MEMADDR is in a Thumb
|
||||
function. */
|
||||
|
||||
static int
|
||||
int
|
||||
arm_pc_is_thumb (CORE_ADDR memaddr)
|
||||
{
|
||||
struct minimal_symbol *sym;
|
||||
|
@ -286,7 +290,7 @@ arm_pc_is_thumb (CORE_ADDR memaddr)
|
|||
/* Determine if the program counter specified in MEMADDR is in a call
|
||||
dummy being called from a Thumb function. */
|
||||
|
||||
static int
|
||||
int
|
||||
arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
|
||||
{
|
||||
CORE_ADDR sp = read_sp ();
|
||||
|
@ -305,7 +309,7 @@ arm_pc_is_thumb_dummy (CORE_ADDR memaddr)
|
|||
}
|
||||
|
||||
/* Remove useless bits from addresses in a running program. */
|
||||
CORE_ADDR
|
||||
static CORE_ADDR
|
||||
arm_addr_bits_remove (CORE_ADDR val)
|
||||
{
|
||||
if (arm_pc_is_thumb (val))
|
||||
|
@ -316,16 +320,21 @@ arm_addr_bits_remove (CORE_ADDR val)
|
|||
|
||||
/* When reading symbols, we need to zap the low bit of the address,
|
||||
which may be set to 1 for Thumb functions. */
|
||||
CORE_ADDR
|
||||
static CORE_ADDR
|
||||
arm_smash_text_address (CORE_ADDR val)
|
||||
{
|
||||
return val & ~1;
|
||||
}
|
||||
|
||||
CORE_ADDR
|
||||
/* Immediately after a function call, return the saved pc. Can't
|
||||
always go through the frames for this because on some machines the
|
||||
new frame is not set up until the new function executes some
|
||||
instructions. */
|
||||
|
||||
static CORE_ADDR
|
||||
arm_saved_pc_after_call (struct frame_info *frame)
|
||||
{
|
||||
return ADDR_BITS_REMOVE (read_register (LR_REGNUM));
|
||||
return ADDR_BITS_REMOVE (read_register (ARM_LR_REGNUM));
|
||||
}
|
||||
|
||||
/* Determine whether the function invocation represented by FI has a
|
||||
|
@ -456,7 +465,10 @@ thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end)
|
|||
return current_pc;
|
||||
}
|
||||
|
||||
/* The APCS (ARM Procedure Call Standard) defines the following
|
||||
/* Advance the PC across any function entry prologue instructions to reach
|
||||
some "real" code.
|
||||
|
||||
The APCS (ARM Procedure Call Standard) defines the following
|
||||
prologue:
|
||||
|
||||
mov ip, sp
|
||||
|
@ -468,7 +480,7 @@ thumb_skip_prologue (CORE_ADDR pc, CORE_ADDR func_end)
|
|||
[stfe f4, [sp, #-12]!]
|
||||
sub fp, ip, #nn @@ nn == 20 or 4 depending on second insn */
|
||||
|
||||
CORE_ADDR
|
||||
static CORE_ADDR
|
||||
arm_skip_prologue (CORE_ADDR pc)
|
||||
{
|
||||
unsigned long inst;
|
||||
|
@ -626,7 +638,7 @@ thumb_scan_prologue (struct frame_info *fi)
|
|||
mask = (insn & 0xff) | ((insn & 0x100) << 6);
|
||||
|
||||
/* Calculate offsets of saved R0-R7 and LR. */
|
||||
for (regno = LR_REGNUM; regno >= 0; regno--)
|
||||
for (regno = ARM_LR_REGNUM; regno >= 0; regno--)
|
||||
if (mask & (1 << regno))
|
||||
{
|
||||
fi->extra_info->framesize += 4;
|
||||
|
@ -662,7 +674,7 @@ thumb_scan_prologue (struct frame_info *fi)
|
|||
findmask |= 2; /* setting of r7 found */
|
||||
fi->extra_info->framereg = THUMB_FP_REGNUM;
|
||||
fi->extra_info->frameoffset = 0;
|
||||
saved_reg[THUMB_FP_REGNUM] = SP_REGNUM;
|
||||
saved_reg[THUMB_FP_REGNUM] = ARM_SP_REGNUM;
|
||||
}
|
||||
else if ((insn & 0xffc0) == 0x4640) /* mov r0-r7, r8-r15 */
|
||||
{
|
||||
|
@ -809,7 +821,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||
return;
|
||||
|
||||
/* Assume there is no frame until proven otherwise. */
|
||||
fi->extra_info->framereg = SP_REGNUM;
|
||||
fi->extra_info->framereg = ARM_SP_REGNUM;
|
||||
fi->extra_info->framesize = 0;
|
||||
fi->extra_info->frameoffset = 0;
|
||||
|
||||
|
@ -910,7 +922,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||
int mask = insn & 0xffff;
|
||||
|
||||
/* Calculate offsets of saved registers. */
|
||||
for (regno = PC_REGNUM; regno >= 0; regno--)
|
||||
for (regno = ARM_PC_REGNUM; regno >= 0; regno--)
|
||||
if (mask & (1 << regno))
|
||||
{
|
||||
sp_offset -= 4;
|
||||
|
@ -923,7 +935,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||
unsigned rot = (insn & 0xf00) >> 7; /* rotate amount */
|
||||
imm = (imm >> rot) | (imm << (32 - rot));
|
||||
fp_offset = -imm;
|
||||
fi->extra_info->framereg = FP_REGNUM;
|
||||
fi->extra_info->framereg = ARM_FP_REGNUM;
|
||||
}
|
||||
else if ((insn & 0xfffff000) == 0xe24dd000) /* sub sp, sp #n */
|
||||
{
|
||||
|
@ -935,7 +947,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||
else if ((insn & 0xffff7fff) == 0xed6d0103) /* stfe f?, [sp, -#c]! */
|
||||
{
|
||||
sp_offset -= 12;
|
||||
regno = F0_REGNUM + ((insn >> 12) & 0x07);
|
||||
regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
|
||||
fi->saved_regs[regno] = sp_offset;
|
||||
}
|
||||
else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */
|
||||
|
@ -958,7 +970,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||
n_saved_fp_regs = 4;
|
||||
}
|
||||
|
||||
fp_start_reg = F0_REGNUM + ((insn >> 12) & 0x7);
|
||||
fp_start_reg = ARM_F0_REGNUM + ((insn >> 12) & 0x7);
|
||||
fp_bound_reg = fp_start_reg + n_saved_fp_regs;
|
||||
for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
|
||||
{
|
||||
|
@ -980,7 +992,7 @@ arm_scan_prologue (struct frame_info *fi)
|
|||
of the last thing thing we pushed on the stack. The frame offset is
|
||||
[new FP] - [new SP]. */
|
||||
fi->extra_info->framesize = -sp_offset;
|
||||
if (fi->extra_info->framereg == FP_REGNUM)
|
||||
if (fi->extra_info->framereg == ARM_FP_REGNUM)
|
||||
fi->extra_info->frameoffset = fp_offset - sp_offset;
|
||||
else
|
||||
fi->extra_info->frameoffset = 0;
|
||||
|
@ -1028,7 +1040,7 @@ arm_frame_chain (struct frame_info *fi)
|
|||
|
||||
/* is caller-of-this a dummy frame? */
|
||||
callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */
|
||||
fp = arm_find_callers_reg (fi, FP_REGNUM);
|
||||
fp = arm_find_callers_reg (fi, ARM_FP_REGNUM);
|
||||
if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
|
||||
return fp; /* dummy frame's frame may bear no relation to ours */
|
||||
|
||||
|
@ -1081,7 +1093,7 @@ arm_frame_chain (struct frame_info *fi)
|
|||
|
||||
/* If the caller used a frame register, return its value.
|
||||
Otherwise, return the caller's stack pointer. */
|
||||
if (framereg == FP_REGNUM || framereg == THUMB_FP_REGNUM)
|
||||
if (framereg == ARM_FP_REGNUM || framereg == THUMB_FP_REGNUM)
|
||||
return arm_find_callers_reg (fi, framereg);
|
||||
else
|
||||
return fi->frame + fi->extra_info->framesize;
|
||||
|
@ -1122,7 +1134,8 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
|||
{
|
||||
/* We need to setup fi->frame here because run_stack_dummy gets it wrong
|
||||
by assuming it's always FP. */
|
||||
fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
|
||||
fi->frame = generic_read_register_dummy (fi->pc, fi->frame,
|
||||
ARM_SP_REGNUM);
|
||||
fi->extra_info->framesize = 0;
|
||||
fi->extra_info->frameoffset = 0;
|
||||
return;
|
||||
|
@ -1157,7 +1170,7 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
|||
fi->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg);
|
||||
|
||||
/* FIXME: What about thumb mode? */
|
||||
fi->extra_info->framereg = SP_REGNUM;
|
||||
fi->extra_info->framereg = ARM_SP_REGNUM;
|
||||
fi->frame =
|
||||
read_memory_integer (fi->saved_regs[fi->extra_info->framereg],
|
||||
REGISTER_RAW_SIZE (fi->extra_info->framereg));
|
||||
|
@ -1174,17 +1187,17 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
|||
rp = fi->frame - REGISTER_SIZE;
|
||||
|
||||
/* Fill in addresses of saved registers. */
|
||||
fi->saved_regs[PS_REGNUM] = rp;
|
||||
rp -= REGISTER_RAW_SIZE (PS_REGNUM);
|
||||
for (reg = PC_REGNUM; reg >= 0; reg--)
|
||||
fi->saved_regs[ARM_PS_REGNUM] = rp;
|
||||
rp -= REGISTER_RAW_SIZE (ARM_PS_REGNUM);
|
||||
for (reg = ARM_PC_REGNUM; reg >= 0; reg--)
|
||||
{
|
||||
fi->saved_regs[reg] = rp;
|
||||
rp -= REGISTER_RAW_SIZE (reg);
|
||||
}
|
||||
|
||||
callers_sp = read_memory_integer (fi->saved_regs[SP_REGNUM],
|
||||
REGISTER_RAW_SIZE (SP_REGNUM));
|
||||
fi->extra_info->framereg = FP_REGNUM;
|
||||
callers_sp = read_memory_integer (fi->saved_regs[ARM_SP_REGNUM],
|
||||
REGISTER_RAW_SIZE (ARM_SP_REGNUM));
|
||||
fi->extra_info->framereg = ARM_FP_REGNUM;
|
||||
fi->extra_info->framesize = callers_sp - sp;
|
||||
fi->extra_info->frameoffset = fi->frame - sp;
|
||||
}
|
||||
|
@ -1195,7 +1208,7 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
|||
if (!fi->next)
|
||||
/* this is the innermost frame? */
|
||||
fi->frame = read_register (fi->extra_info->framereg);
|
||||
else if (fi->extra_info->framereg == FP_REGNUM
|
||||
else if (fi->extra_info->framereg == ARM_FP_REGNUM
|
||||
|| fi->extra_info->framereg == THUMB_FP_REGNUM)
|
||||
{
|
||||
/* not the innermost frame */
|
||||
|
@ -1220,7 +1233,7 @@ arm_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
|||
}
|
||||
|
||||
|
||||
/* Find the caller of this frame. We do this by seeing if LR_REGNUM
|
||||
/* Find the caller of this frame. We do this by seeing if ARM_LR_REGNUM
|
||||
is saved in the stack anywhere, otherwise we get it from the
|
||||
registers.
|
||||
|
||||
|
@ -1233,18 +1246,18 @@ arm_frame_saved_pc (struct frame_info *fi)
|
|||
{
|
||||
#if 0 /* FIXME: enable this code if we convert to new call dummy scheme. */
|
||||
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
|
||||
return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
|
||||
return generic_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM);
|
||||
else
|
||||
#endif
|
||||
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset,
|
||||
fi->frame))
|
||||
{
|
||||
return read_memory_integer (fi->saved_regs[PC_REGNUM],
|
||||
REGISTER_RAW_SIZE (PC_REGNUM));
|
||||
return read_memory_integer (fi->saved_regs[ARM_PC_REGNUM],
|
||||
REGISTER_RAW_SIZE (ARM_PC_REGNUM));
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE_ADDR pc = arm_find_callers_reg (fi, LR_REGNUM);
|
||||
CORE_ADDR pc = arm_find_callers_reg (fi, ARM_LR_REGNUM);
|
||||
return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
|
||||
}
|
||||
}
|
||||
|
@ -1255,10 +1268,10 @@ arm_frame_saved_pc (struct frame_info *fi)
|
|||
static CORE_ADDR
|
||||
arm_read_fp (void)
|
||||
{
|
||||
if (read_register (PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
|
||||
if (read_register (ARM_PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
|
||||
return read_register (THUMB_FP_REGNUM); /* R7 if Thumb */
|
||||
else
|
||||
return read_register (FP_REGNUM); /* R11 if ARM */
|
||||
return read_register (ARM_FP_REGNUM); /* R11 if ARM */
|
||||
}
|
||||
|
||||
/* Store into a struct frame_saved_regs the addresses of the saved
|
||||
|
@ -1282,7 +1295,7 @@ arm_frame_init_saved_regs (struct frame_info *fip)
|
|||
static void
|
||||
arm_push_dummy_frame (void)
|
||||
{
|
||||
CORE_ADDR old_sp = read_register (SP_REGNUM);
|
||||
CORE_ADDR old_sp = read_register (ARM_SP_REGNUM);
|
||||
CORE_ADDR sp = old_sp;
|
||||
CORE_ADDR fp, prologue_start;
|
||||
int regnum;
|
||||
|
@ -1300,16 +1313,16 @@ arm_push_dummy_frame (void)
|
|||
fp = sp = push_word (sp, prologue_start + 12);
|
||||
|
||||
/* Push the processor status. */
|
||||
sp = push_word (sp, read_register (PS_REGNUM));
|
||||
sp = push_word (sp, read_register (ARM_PS_REGNUM));
|
||||
|
||||
/* Push all 16 registers starting with r15. */
|
||||
for (regnum = PC_REGNUM; regnum >= 0; regnum--)
|
||||
for (regnum = ARM_PC_REGNUM; regnum >= 0; regnum--)
|
||||
sp = push_word (sp, read_register (regnum));
|
||||
|
||||
/* Update fp (for both Thumb and ARM) and sp. */
|
||||
write_register (FP_REGNUM, fp);
|
||||
write_register (ARM_FP_REGNUM, fp);
|
||||
write_register (THUMB_FP_REGNUM, fp);
|
||||
write_register (SP_REGNUM, sp);
|
||||
write_register (ARM_SP_REGNUM, sp);
|
||||
}
|
||||
|
||||
/* CALL_DUMMY_WORDS:
|
||||
|
@ -1321,7 +1334,7 @@ arm_push_dummy_frame (void)
|
|||
|
||||
Note this is 12 bytes. */
|
||||
|
||||
LONGEST arm_call_dummy_words[] =
|
||||
static LONGEST arm_call_dummy_words[] =
|
||||
{
|
||||
0xe1a0e00f, 0xe1a0f004, 0xe7ffdefe
|
||||
};
|
||||
|
@ -1341,7 +1354,7 @@ LONGEST arm_call_dummy_words[] =
|
|||
All three call dummies expect to receive the target function
|
||||
address in R4, with the low bit set if it's a Thumb function. */
|
||||
|
||||
void
|
||||
static void
|
||||
arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
|
||||
struct value **args, struct type *type, int gcc_p)
|
||||
{
|
||||
|
@ -1452,7 +1465,7 @@ arm_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
|
|||
}
|
||||
|
||||
/* Initialize the integer argument register pointer. */
|
||||
argreg = A1_REGNUM;
|
||||
argreg = ARM_A1_REGNUM;
|
||||
|
||||
/* The struct_return pointer occupies the first parameter passing
|
||||
register. */
|
||||
|
@ -1553,8 +1566,8 @@ arm_pop_frame (void)
|
|||
read_memory_integer (frame->saved_regs[regnum],
|
||||
REGISTER_RAW_SIZE (regnum)));
|
||||
|
||||
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
|
||||
write_register (SP_REGNUM, old_SP);
|
||||
write_register (ARM_PC_REGNUM, FRAME_SAVED_PC (frame));
|
||||
write_register (ARM_SP_REGNUM, old_SP);
|
||||
|
||||
flush_cached_frames ();
|
||||
}
|
||||
|
@ -1577,10 +1590,10 @@ print_fpu_flags (int flags)
|
|||
|
||||
/* Print interesting information about the floating point processor
|
||||
(if present) or emulator. */
|
||||
void
|
||||
static void
|
||||
arm_print_float_info (void)
|
||||
{
|
||||
register unsigned long status = read_register (FPS_REGNUM);
|
||||
register unsigned long status = read_register (ARM_FPS_REGNUM);
|
||||
int type;
|
||||
|
||||
type = (status >> 24) & 127;
|
||||
|
@ -1593,10 +1606,13 @@ arm_print_float_info (void)
|
|||
print_fpu_flags (status);
|
||||
}
|
||||
|
||||
struct type *
|
||||
/* Return the GDB type object for the "standard" data type of data in
|
||||
register N. */
|
||||
|
||||
static struct type *
|
||||
arm_register_type (int regnum)
|
||||
{
|
||||
if (regnum >= F0_REGNUM && regnum < F0_REGNUM + NUM_FREGS)
|
||||
if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
|
||||
{
|
||||
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
|
||||
return builtin_type_arm_ext_big;
|
||||
|
@ -1607,6 +1623,52 @@ arm_register_type (int regnum)
|
|||
return builtin_type_int32;
|
||||
}
|
||||
|
||||
/* Index within `registers' of the first byte of the space for
|
||||
register N. */
|
||||
|
||||
static int
|
||||
arm_register_byte (int regnum)
|
||||
{
|
||||
if (regnum < ARM_F0_REGNUM)
|
||||
return regnum * INT_REGISTER_RAW_SIZE;
|
||||
else if (regnum < ARM_PS_REGNUM)
|
||||
return (NUM_GREGS * INT_REGISTER_RAW_SIZE
|
||||
+ (regnum - ARM_F0_REGNUM) * FP_REGISTER_RAW_SIZE);
|
||||
else
|
||||
return (NUM_GREGS * INT_REGISTER_RAW_SIZE
|
||||
+ NUM_FREGS * FP_REGISTER_RAW_SIZE
|
||||
+ (regnum - ARM_FPS_REGNUM) * STATUS_REGISTER_SIZE);
|
||||
}
|
||||
|
||||
/* Number of bytes of storage in the actual machine representation for
|
||||
register N. All registers are 4 bytes, except fp0 - fp7, which are
|
||||
12 bytes in length. */
|
||||
|
||||
static int
|
||||
arm_register_raw_size (int regnum)
|
||||
{
|
||||
if (regnum < ARM_F0_REGNUM)
|
||||
return INT_REGISTER_RAW_SIZE;
|
||||
else if (regnum < ARM_FPS_REGNUM)
|
||||
return FP_REGISTER_RAW_SIZE;
|
||||
else
|
||||
return STATUS_REGISTER_SIZE;
|
||||
}
|
||||
|
||||
/* Number of bytes of storage in a program's representation
|
||||
for register N. */
|
||||
static int
|
||||
arm_register_virtual_size (int regnum)
|
||||
{
|
||||
if (regnum < ARM_F0_REGNUM)
|
||||
return INT_REGISTER_VIRTUAL_SIZE;
|
||||
else if (regnum < ARM_FPS_REGNUM)
|
||||
return FP_REGISTER_VIRTUAL_SIZE;
|
||||
else
|
||||
return STATUS_REGISTER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: cagney/2001-08-20: Both convert_from_extended() and
|
||||
convert_to_extended() use floatformat_arm_ext_littlebyte_bigword.
|
||||
It is thought that this is is the floating-point register format on
|
||||
|
@ -1624,7 +1686,7 @@ convert_from_extended (void *ptr, void *dbl)
|
|||
floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &d, dbl);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
convert_to_extended (void *dbl, void *ptr)
|
||||
{
|
||||
DOUBLEST d;
|
||||
|
@ -1749,7 +1811,7 @@ bitcount (unsigned long val)
|
|||
return nbits;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
CORE_ADDR
|
||||
thumb_get_next_pc (CORE_ADDR pc)
|
||||
{
|
||||
unsigned long pc_val = ((unsigned long) pc) + 4; /* PC after prefetch */
|
||||
|
@ -1764,7 +1826,7 @@ 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)) * REGISTER_SIZE;
|
||||
sp = read_register (SP_REGNUM);
|
||||
sp = read_register (ARM_SP_REGNUM);
|
||||
nextpc = (CORE_ADDR) read_memory_integer (sp + offset, 4);
|
||||
nextpc = ADDR_BITS_REMOVE (nextpc);
|
||||
if (nextpc == pc)
|
||||
|
@ -1772,7 +1834,7 @@ thumb_get_next_pc (CORE_ADDR pc)
|
|||
}
|
||||
else if ((inst1 & 0xf000) == 0xd000) /* conditional branch */
|
||||
{
|
||||
unsigned long status = read_register (PS_REGNUM);
|
||||
unsigned long status = read_register (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);
|
||||
|
@ -1791,7 +1853,7 @@ thumb_get_next_pc (CORE_ADDR pc)
|
|||
return nextpc;
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
CORE_ADDR
|
||||
arm_get_next_pc (CORE_ADDR pc)
|
||||
{
|
||||
unsigned long pc_val;
|
||||
|
@ -1804,7 +1866,7 @@ arm_get_next_pc (CORE_ADDR pc)
|
|||
|
||||
pc_val = (unsigned long) pc;
|
||||
this_instr = read_memory_integer (pc, 4);
|
||||
status = read_register (PS_REGNUM);
|
||||
status = read_register (ARM_PS_REGNUM);
|
||||
nextpc = (CORE_ADDR) (pc_val + 4); /* Default case */
|
||||
|
||||
if (condition_true (bits (this_instr, 28, 31), status))
|
||||
|
@ -2021,15 +2083,15 @@ arm_get_next_pc (CORE_ADDR pc)
|
|||
single_step is also called just after the inferior stops. If we had
|
||||
set up a simulated single-step, we undo our damage. */
|
||||
|
||||
void
|
||||
arm_software_single_step (int ignore, int insert_bpt)
|
||||
static void
|
||||
arm_software_single_step (enum target_signal sig, int insert_bpt)
|
||||
{
|
||||
static int next_pc; /* State between setting and unsetting. */
|
||||
static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */
|
||||
|
||||
if (insert_bpt)
|
||||
{
|
||||
next_pc = arm_get_next_pc (read_register (PC_REGNUM));
|
||||
next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM));
|
||||
target_insert_breakpoint (next_pc, break_mem);
|
||||
}
|
||||
else
|
||||
|
@ -2078,14 +2140,19 @@ gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
|
|||
return print_insn_little_arm (memaddr, info);
|
||||
}
|
||||
|
||||
/* This function implements the BREAKPOINT_FROM_PC macro. It uses the
|
||||
program counter value to determine whether a 16-bit or 32-bit
|
||||
/* Determine the type and size of breakpoint to insert at PCPTR. Uses
|
||||
the program counter value to determine whether a 16-bit or 32-bit
|
||||
breakpoint should be used. It returns a pointer to a string of
|
||||
bytes that encode a breakpoint instruction, stores the length of
|
||||
the string to *lenptr, and adjusts the program counter (if
|
||||
necessary) to point to the actual memory location where the
|
||||
breakpoint should be inserted. */
|
||||
|
||||
/* XXX ??? from old tm-arm.h: if we're using RDP, then we're inserting
|
||||
breakpoints and storing their handles instread of what was in
|
||||
memory. It is nice that this is the same size as a handle -
|
||||
otherwise remote-rdp will have to change. */
|
||||
|
||||
unsigned char *
|
||||
arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
|
||||
{
|
||||
|
@ -2127,15 +2194,44 @@ arm_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
|
|||
function return value of type TYPE, and copy that, in virtual
|
||||
format, into VALBUF. */
|
||||
|
||||
void
|
||||
static void
|
||||
arm_extract_return_value (struct type *type,
|
||||
char regbuf[REGISTER_BYTES],
|
||||
char *valbuf)
|
||||
{
|
||||
if (TYPE_CODE_FLT == TYPE_CODE (type))
|
||||
convert_from_extended (®buf[REGISTER_BYTE (F0_REGNUM)], valbuf);
|
||||
convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf);
|
||||
else
|
||||
memcpy (valbuf, ®buf[REGISTER_BYTE (A1_REGNUM)], TYPE_LENGTH (type));
|
||||
memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)],
|
||||
TYPE_LENGTH (type));
|
||||
}
|
||||
|
||||
/* Write into appropriate registers a function return value of type
|
||||
TYPE, given in virtual format. */
|
||||
|
||||
static void
|
||||
arm_store_return_value (struct type *type, char *valbuf)
|
||||
{
|
||||
if (TYPE_CODE (type) == TYPE_CODE_FLT)
|
||||
{
|
||||
char buf[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
convert_to_extended (valbuf, buf);
|
||||
/* XXX Is this correct for soft-float? */
|
||||
write_register_bytes (REGISTER_BYTE (ARM_F0_REGNUM), buf,
|
||||
MAX_REGISTER_RAW_SIZE);
|
||||
}
|
||||
else
|
||||
write_register_bytes (0, valbuf, TYPE_LENGTH (type));
|
||||
}
|
||||
|
||||
/* Store the address of the place in which to copy the structure the
|
||||
subroutine will return. This is called from call_function. */
|
||||
|
||||
static void
|
||||
arm_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
|
||||
{
|
||||
write_register (ARM_A1_REGNUM, addr);
|
||||
}
|
||||
|
||||
/* Return non-zero if the PC is inside a thumb call thunk. */
|
||||
|
@ -2200,8 +2296,8 @@ set_disassembly_flavor_sfunc (char *args, int from_tty,
|
|||
}
|
||||
|
||||
/* Return the ARM register name corresponding to register I. */
|
||||
char *
|
||||
arm_register_name(int i)
|
||||
static char *
|
||||
arm_register_name (int i)
|
||||
{
|
||||
return arm_register_names[i];
|
||||
}
|
||||
|
@ -2225,15 +2321,15 @@ set_disassembly_flavor (void)
|
|||
arm_register_names[j] = (char *) regnames[j];
|
||||
|
||||
/* Adjust case. */
|
||||
if (isupper (*regnames[PC_REGNUM]))
|
||||
if (isupper (*regnames[ARM_PC_REGNUM]))
|
||||
{
|
||||
arm_register_names[FPS_REGNUM] = "FPS";
|
||||
arm_register_names[PS_REGNUM] = "CPSR";
|
||||
arm_register_names[ARM_FPS_REGNUM] = "FPS";
|
||||
arm_register_names[ARM_PS_REGNUM] = "CPSR";
|
||||
}
|
||||
else
|
||||
{
|
||||
arm_register_names[FPS_REGNUM] = "fps";
|
||||
arm_register_names[PS_REGNUM] = "cpsr";
|
||||
arm_register_names[ARM_FPS_REGNUM] = "fps";
|
||||
arm_register_names[ARM_PS_REGNUM] = "cpsr";
|
||||
}
|
||||
|
||||
/* Synchronize the disassembler. */
|
||||
|
@ -2318,7 +2414,7 @@ coff_sym_is_thumb (int val)
|
|||
an address in thumb code, and set a "special" bit in a minimal
|
||||
symbol to indicate that it does. */
|
||||
|
||||
void
|
||||
static void
|
||||
arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
|
||||
{
|
||||
/* Thumb symbols are of type STT_LOPROC, (synonymous with
|
||||
|
@ -2328,7 +2424,7 @@ arm_elf_make_msymbol_special(asymbol *sym, struct minimal_symbol *msym)
|
|||
MSYMBOL_SET_SPECIAL (msym);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
arm_coff_make_msymbol_special(int val, struct minimal_symbol *msym)
|
||||
{
|
||||
if (coff_sym_is_thumb (val))
|
||||
|
@ -2354,6 +2450,12 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
set_gdbarch_call_dummy_p (gdbarch, 1);
|
||||
set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
|
||||
|
||||
set_gdbarch_call_dummy_words (gdbarch, arm_call_dummy_words);
|
||||
set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (arm_call_dummy_words));
|
||||
set_gdbarch_call_dummy_start_offset (gdbarch, 0);
|
||||
|
||||
set_gdbarch_fix_call_dummy (gdbarch, arm_fix_call_dummy);
|
||||
|
||||
set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
|
||||
|
||||
set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
|
||||
|
@ -2375,6 +2477,71 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
|||
set_gdbarch_push_dummy_frame (gdbarch, arm_push_dummy_frame);
|
||||
set_gdbarch_pop_frame (gdbarch, arm_pop_frame);
|
||||
|
||||
/* Address manipulation. */
|
||||
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);
|
||||
|
||||
/* Get the PC when a frame might not be available. */
|
||||
set_gdbarch_saved_pc_after_call (gdbarch, arm_saved_pc_after_call);
|
||||
|
||||
/* The stack grows downward. */
|
||||
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
|
||||
|
||||
/* 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);
|
||||
set_gdbarch_fp_regnum (gdbarch, ARM_FP_REGNUM); /* ??? */
|
||||
set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM);
|
||||
set_gdbarch_pc_regnum (gdbarch, ARM_PC_REGNUM);
|
||||
set_gdbarch_register_byte (gdbarch, arm_register_byte);
|
||||
set_gdbarch_register_bytes (gdbarch,
|
||||
(NUM_GREGS * INT_REGISTER_RAW_SIZE
|
||||
+ NUM_FREGS * FP_REGISTER_RAW_SIZE
|
||||
+ NUM_SREGS * STATUS_REGISTER_SIZE));
|
||||
set_gdbarch_num_regs (gdbarch, NUM_GREGS + NUM_FREGS + NUM_SREGS);
|
||||
set_gdbarch_register_raw_size (gdbarch, arm_register_raw_size);
|
||||
set_gdbarch_register_virtual_size (gdbarch, arm_register_virtual_size);
|
||||
set_gdbarch_max_register_raw_size (gdbarch, FP_REGISTER_RAW_SIZE);
|
||||
set_gdbarch_max_register_virtual_size (gdbarch, FP_REGISTER_VIRTUAL_SIZE);
|
||||
set_gdbarch_register_virtual_type (gdbarch, arm_register_type);
|
||||
|
||||
/* Integer registers are 4 bytes. */
|
||||
set_gdbarch_register_size (gdbarch, 4);
|
||||
set_gdbarch_register_name (gdbarch, arm_register_name);
|
||||
|
||||
/* Returning results. */
|
||||
set_gdbarch_extract_return_value (gdbarch, arm_extract_return_value);
|
||||
set_gdbarch_store_return_value (gdbarch, arm_store_return_value);
|
||||
set_gdbarch_store_struct_return (gdbarch, arm_store_struct_return);
|
||||
|
||||
/* Single stepping. */
|
||||
/* XXX For an RDI target we should ask the target if it can single-step. */
|
||||
set_gdbarch_software_single_step (gdbarch, arm_software_single_step);
|
||||
|
||||
/* Minsymbol frobbing. */
|
||||
set_gdbarch_elf_make_msymbol_special (gdbarch, arm_elf_make_msymbol_special);
|
||||
set_gdbarch_coff_make_msymbol_special (gdbarch,
|
||||
arm_coff_make_msymbol_special);
|
||||
|
||||
/* XXX We can't do this until NUM_REGS is set for the architecture.
|
||||
Even then, we can't use SIZEOF_FRAME_SAVED_REGS, since that still
|
||||
references the old architecture vector, not the one we are
|
||||
building here. */
|
||||
if (prologue_cache.saved_regs != NULL)
|
||||
xfree (prologue_cache.saved_regs);
|
||||
|
||||
prologue_cache.saved_regs = (CORE_ADDR *)
|
||||
xcalloc (1, (sizeof (CORE_ADDR)
|
||||
* (NUM_GREGS + NUM_FREGS + NUM_SREGS + NUM_PSEUDO_REGS)));
|
||||
|
||||
return gdbarch;
|
||||
}
|
||||
|
@ -2454,8 +2621,7 @@ The valid values are:\n");
|
|||
"Switch to the next set of register names.");
|
||||
|
||||
/* Fill in the prologue_cache fields. */
|
||||
prologue_cache.saved_regs = NULL;
|
||||
prologue_cache.extra_info = (struct frame_extra_info *)
|
||||
xcalloc (1, sizeof (struct frame_extra_info));
|
||||
prologue_cache.saved_regs = (CORE_ADDR *)
|
||||
xcalloc (1, SIZEOF_FRAME_SAVED_REGS);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* Common target dependent code for GDB on ARM systems.
|
||||
Copyright 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
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., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Register numbers of various important registers. Note that some of
|
||||
these values are "real" register numbers, and correspond to the
|
||||
general registers of the machine, and some are "phony" register
|
||||
numbers which are too large to be actual register numbers as far as
|
||||
the user is concerned but do serve to get the desired values when
|
||||
passed to read_register. */
|
||||
|
||||
#define ARM_A1_REGNUM 0 /* first integer-like argument */
|
||||
#define ARM_A4_REGNUM 3 /* last integer-like argument */
|
||||
#define ARM_AP_REGNUM 11
|
||||
#define ARM_SP_REGNUM 13 /* Contains address of top of stack */
|
||||
#define ARM_LR_REGNUM 14 /* address to return to from a function call */
|
||||
#define ARM_PC_REGNUM 15 /* Contains program counter */
|
||||
#define ARM_F0_REGNUM 16 /* first floating point register */
|
||||
#define ARM_F3_REGNUM 19 /* last floating point argument register */
|
||||
#define ARM_F7_REGNUM 23 /* last floating point register */
|
||||
#define ARM_FPS_REGNUM 24 /* floating point status register */
|
||||
#define ARM_PS_REGNUM 25 /* Contains processor status */
|
||||
|
||||
#define ARM_FP_REGNUM 11 /* Frame register in ARM code, if used. */
|
||||
#define THUMB_FP_REGNUM 7 /* Frame register in Thumb code, if used. */
|
||||
|
||||
#define ARM_NUM_ARG_REGS 4
|
||||
#define ARM_LAST_ARG_REGNUM ARM_A4_REGNUM
|
||||
#define ARM_NUM_FP_ARG_REGS 4
|
||||
#define ARM_LAST_FP_ARG_REGNUM ARM_F3_REGNUM
|
||||
|
||||
/* Size of integer registers. */
|
||||
#define INT_REGISTER_RAW_SIZE 4
|
||||
#define INT_REGISTER_VIRTUAL_SIZE 4
|
||||
|
||||
/* Say how long FP registers are. Used for documentation purposes and
|
||||
code readability in this header. IEEE extended doubles are 80
|
||||
bits. DWORD aligned they use 96 bits. */
|
||||
#define FP_REGISTER_RAW_SIZE 12
|
||||
|
||||
/* GCC doesn't support long doubles (extended IEEE values). The FP
|
||||
register virtual size is therefore 64 bits. Used for documentation
|
||||
purposes and code readability in this header. */
|
||||
#define FP_REGISTER_VIRTUAL_SIZE 8
|
||||
|
||||
/* Status registers are the same size as general purpose registers.
|
||||
Used for documentation purposes and code readability in this
|
||||
header. */
|
||||
#define STATUS_REGISTER_SIZE 4
|
||||
|
||||
/* Number of machine registers. The only define actually required
|
||||
is NUM_REGS. The other definitions are used for documentation
|
||||
purposes and code readability. */
|
||||
/* For 26 bit ARM code, a fake copy of the PC is placed in register 25 (PS)
|
||||
(and called PS for processor status) so the status bits can be cleared
|
||||
from the PC (register 15). For 32 bit ARM code, a copy of CPSR is placed
|
||||
in PS. */
|
||||
#define NUM_FREGS 8 /* Number of floating point registers. */
|
||||
#define NUM_SREGS 2 /* Number of status registers. */
|
||||
#define NUM_GREGS 16 /* Number of general purpose registers. */
|
||||
|
||||
|
||||
/* Instruction condition field values. */
|
||||
#define INST_EQ 0x0
|
||||
#define INST_NE 0x1
|
||||
#define INST_CS 0x2
|
||||
#define INST_CC 0x3
|
||||
#define INST_MI 0x4
|
||||
#define INST_PL 0x5
|
||||
#define INST_VS 0x6
|
||||
#define INST_VC 0x7
|
||||
#define INST_HI 0x8
|
||||
#define INST_LS 0x9
|
||||
#define INST_GE 0xa
|
||||
#define INST_LT 0xb
|
||||
#define INST_GT 0xc
|
||||
#define INST_LE 0xd
|
||||
#define INST_AL 0xe
|
||||
#define INST_NV 0xf
|
||||
|
||||
#define FLAG_N 0x80000000
|
||||
#define FLAG_Z 0x40000000
|
||||
#define FLAG_C 0x20000000
|
||||
#define FLAG_V 0x10000000
|
||||
|
||||
/* Prototypes for internal interfaces needed by more than one MD file. */
|
||||
int arm_pc_is_thumb_dummy (CORE_ADDR);
|
||||
|
||||
int arm_pc_is_thumb (CORE_ADDR);
|
||||
|
||||
CORE_ADDR thumb_get_next_pc (CORE_ADDR);
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
/* Native-dependent code for BSD Unix running on ARM's, for GDB.
|
||||
Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999 Free Software Foundation, Inc.
|
||||
Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
|
@ -20,6 +21,8 @@
|
|||
|
||||
#include "defs.h"
|
||||
|
||||
#include "arm-tdep.h"
|
||||
|
||||
#ifdef FETCH_INFERIOR_REGISTERS
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
@ -38,13 +41,15 @@ fetch_inferior_registers (regno)
|
|||
(PTRACE_ARG3_TYPE) &inferior_registers, 0);
|
||||
memcpy (®isters[REGISTER_BYTE (0)], &inferior_registers,
|
||||
16 * sizeof (unsigned int));
|
||||
memcpy (®isters[REGISTER_BYTE (PS_REGNUM)], &inferior_registers.r_cpsr,
|
||||
memcpy (®isters[REGISTER_BYTE (ARM_PS_REGNUM)],
|
||||
&inferior_registers.r_cpsr,
|
||||
sizeof (unsigned int));
|
||||
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &inferior_fpregisters, 0);
|
||||
memcpy (®isters[REGISTER_BYTE (F0_REGNUM)], &inferior_fpregisters.fpr[0],
|
||||
memcpy (®isters[REGISTER_BYTE (ARM_F0_REGNUM)],
|
||||
&inferior_fpregisters.fpr[0],
|
||||
8 * sizeof (fp_reg_t));
|
||||
memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)],
|
||||
memcpy (®isters[REGISTER_BYTE (ARM_FPS_REGNUM)],
|
||||
&inferior_fpregisters.fpr_fpsr, sizeof (unsigned int));
|
||||
registers_fetched ();
|
||||
}
|
||||
|
@ -57,7 +62,8 @@ store_inferior_registers (regno)
|
|||
|
||||
memcpy (&inferior_registers, ®isters[REGISTER_BYTE (0)],
|
||||
16 * sizeof (unsigned int));
|
||||
memcpy (&inferior_registers.r_cpsr, ®isters[REGISTER_BYTE (PS_REGNUM)],
|
||||
memcpy (&inferior_registers.r_cpsr,
|
||||
®isters[REGISTER_BYTE (ARM_PS_REGNUM)],
|
||||
sizeof (unsigned int));
|
||||
ptrace (PT_SETREGS, PIDGET (inferior_ptid),
|
||||
(PTRACE_ARG3_TYPE) &inferior_registers, 0);
|
||||
|
|
|
@ -29,42 +29,11 @@
|
|||
#include "regcache.h"
|
||||
#include "floatformat.h"
|
||||
|
||||
/* Forward declarations for prototypes. */
|
||||
struct type;
|
||||
struct value;
|
||||
|
||||
/* IEEE format floating point. */
|
||||
#define TARGET_DOUBLE_FORMAT (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG \
|
||||
? &floatformat_ieee_double_big \
|
||||
: &floatformat_ieee_double_littlebyte_bigword)
|
||||
|
||||
CORE_ADDR arm_smash_text_address(CORE_ADDR);
|
||||
#define SMASH_TEXT_ADDRESS(ADDR) arm_smash_text_address (ADDR)
|
||||
|
||||
CORE_ADDR arm_addr_bits_remove (CORE_ADDR);
|
||||
#define ADDR_BITS_REMOVE(VAL) arm_addr_bits_remove (VAL)
|
||||
|
||||
/* Offset from address of function to start of its code. Zero on most
|
||||
machines. */
|
||||
|
||||
#define FUNCTION_START_OFFSET 0
|
||||
|
||||
/* Advance PC across any function entry prologue instructions to reach
|
||||
some "real" code. */
|
||||
|
||||
extern CORE_ADDR arm_skip_prologue (CORE_ADDR pc);
|
||||
|
||||
#define SKIP_PROLOGUE(pc) (arm_skip_prologue (pc))
|
||||
|
||||
/* Immediately after a function call, return the saved pc. Can't
|
||||
always go through the frames for this because on some machines the
|
||||
new frame is not set up until the new function executes some
|
||||
instructions. */
|
||||
|
||||
#define SAVED_PC_AFTER_CALL(frame) arm_saved_pc_after_call (frame)
|
||||
struct frame_info;
|
||||
extern CORE_ADDR arm_saved_pc_after_call (struct frame_info *);
|
||||
|
||||
/* The following define instruction sequences that will cause ARM
|
||||
cpu's to take an undefined instruction trap. These are used to
|
||||
signal a breakpoint to GDB.
|
||||
|
@ -100,201 +69,11 @@ extern CORE_ADDR arm_saved_pc_after_call (struct frame_info *);
|
|||
#define THUMB_LE_BREAKPOINT {0xfe,0xdf}
|
||||
#define THUMB_BE_BREAKPOINT {0xdf,0xfe}
|
||||
|
||||
/* Stack grows downward. */
|
||||
|
||||
#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
|
||||
|
||||
/* !!!! if we're using RDP, then we're inserting breakpoints and
|
||||
storing their handles instread of what was in memory. It is nice
|
||||
that this is the same size as a handle - otherwise remote-rdp will
|
||||
have to change. */
|
||||
|
||||
/* BREAKPOINT_FROM_PC uses the program counter value to determine
|
||||
whether a 16- or 32-bit breakpoint should be used. It returns a
|
||||
pointer to a string of bytes that encode a breakpoint instruction,
|
||||
stores the length of the string to *lenptr, and adjusts the pc (if
|
||||
necessary) to point to the actual memory location where the
|
||||
breakpoint should be inserted. */
|
||||
|
||||
extern breakpoint_from_pc_fn arm_breakpoint_from_pc;
|
||||
#define BREAKPOINT_FROM_PC(pcptr, lenptr) arm_breakpoint_from_pc (pcptr, lenptr)
|
||||
|
||||
/* Amount PC must be decremented by after a breakpoint. This is often
|
||||
the number of bytes in BREAKPOINT but not always. */
|
||||
|
||||
#define DECR_PC_AFTER_BREAK 0
|
||||
|
||||
void arm_print_float_info (void);
|
||||
#define PRINT_FLOAT_INFO() arm_print_float_info ()
|
||||
|
||||
/* Say how long (ordinary) registers are. This is a piece of bogosity
|
||||
used in push_word and a few other places; REGISTER_RAW_SIZE is the
|
||||
real way to know how big a register is. */
|
||||
|
||||
#define REGISTER_SIZE 4
|
||||
|
||||
/* Say how long FP registers are. Used for documentation purposes and
|
||||
code readability in this header. IEEE extended doubles are 80
|
||||
bits. DWORD aligned they use 96 bits. */
|
||||
#define FP_REGISTER_RAW_SIZE 12
|
||||
|
||||
/* GCC doesn't support long doubles (extended IEEE values). The FP
|
||||
register virtual size is therefore 64 bits. Used for documentation
|
||||
purposes and code readability in this header. */
|
||||
#define FP_REGISTER_VIRTUAL_SIZE 8
|
||||
|
||||
/* Status registers are the same size as general purpose registers.
|
||||
Used for documentation purposes and code readability in this
|
||||
header. */
|
||||
#define STATUS_REGISTER_SIZE REGISTER_SIZE
|
||||
|
||||
/* Number of machine registers. The only define actually required
|
||||
is NUM_REGS. The other definitions are used for documentation
|
||||
purposes and code readability. */
|
||||
/* For 26 bit ARM code, a fake copy of the PC is placed in register 25 (PS)
|
||||
(and called PS for processor status) so the status bits can be cleared
|
||||
from the PC (register 15). For 32 bit ARM code, a copy of CPSR is placed
|
||||
in PS. */
|
||||
#define NUM_FREGS 8 /* Number of floating point registers. */
|
||||
#define NUM_SREGS 2 /* Number of status registers. */
|
||||
#define NUM_GREGS 16 /* Number of general purpose registers. */
|
||||
#define NUM_REGS (NUM_GREGS + NUM_FREGS + NUM_SREGS)
|
||||
|
||||
/* An array of names of registers. */
|
||||
extern char **arm_register_names;
|
||||
|
||||
#define REGISTER_NAME(i) arm_register_name(i)
|
||||
char *arm_register_name (int);
|
||||
|
||||
/* Register numbers of various important registers. Note that some of
|
||||
these values are "real" register numbers, and correspond to the
|
||||
general registers of the machine, and some are "phony" register
|
||||
numbers which are too large to be actual register numbers as far as
|
||||
the user is concerned but do serve to get the desired values when
|
||||
passed to read_register. */
|
||||
|
||||
#define A1_REGNUM 0 /* first integer-like argument */
|
||||
#define A4_REGNUM 3 /* last integer-like argument */
|
||||
#define AP_REGNUM 11
|
||||
#define FP_REGNUM 11 /* Contains address of executing stack frame */
|
||||
#define SP_REGNUM 13 /* Contains address of top of stack */
|
||||
#define LR_REGNUM 14 /* address to return to from a function call */
|
||||
#define PC_REGNUM 15 /* Contains program counter */
|
||||
#define F0_REGNUM 16 /* first floating point register */
|
||||
#define F3_REGNUM 19 /* last floating point argument register */
|
||||
#define F7_REGNUM 23 /* last floating point register */
|
||||
#define FPS_REGNUM 24 /* floating point status register */
|
||||
#define PS_REGNUM 25 /* Contains processor status */
|
||||
|
||||
#define THUMB_FP_REGNUM 7 /* R7 is frame register on Thumb */
|
||||
|
||||
#define ARM_NUM_ARG_REGS 4
|
||||
#define ARM_LAST_ARG_REGNUM A4_REGNUM
|
||||
#define ARM_NUM_FP_ARG_REGS 4
|
||||
#define ARM_LAST_FP_ARG_REGNUM F3_REGNUM
|
||||
|
||||
/* Instruction condition field values. */
|
||||
#define INST_EQ 0x0
|
||||
#define INST_NE 0x1
|
||||
#define INST_CS 0x2
|
||||
#define INST_CC 0x3
|
||||
#define INST_MI 0x4
|
||||
#define INST_PL 0x5
|
||||
#define INST_VS 0x6
|
||||
#define INST_VC 0x7
|
||||
#define INST_HI 0x8
|
||||
#define INST_LS 0x9
|
||||
#define INST_GE 0xa
|
||||
#define INST_LT 0xb
|
||||
#define INST_GT 0xc
|
||||
#define INST_LE 0xd
|
||||
#define INST_AL 0xe
|
||||
#define INST_NV 0xf
|
||||
|
||||
#define FLAG_N 0x80000000
|
||||
#define FLAG_Z 0x40000000
|
||||
#define FLAG_C 0x20000000
|
||||
#define FLAG_V 0x10000000
|
||||
|
||||
|
||||
|
||||
/* Total amount of space needed to store our copies of the machine's
|
||||
register state, the array `registers'. */
|
||||
|
||||
#define REGISTER_BYTES ((NUM_GREGS * REGISTER_SIZE) + \
|
||||
(NUM_FREGS * FP_REGISTER_RAW_SIZE) + \
|
||||
(NUM_SREGS * STATUS_REGISTER_SIZE))
|
||||
|
||||
/* Index within `registers' of the first byte of the space for
|
||||
register N. */
|
||||
|
||||
#define REGISTER_BYTE(N) \
|
||||
((N) < F0_REGNUM \
|
||||
? (N) * REGISTER_SIZE \
|
||||
: ((N) < PS_REGNUM \
|
||||
? (NUM_GREGS * REGISTER_SIZE + \
|
||||
((N) - F0_REGNUM) * FP_REGISTER_RAW_SIZE) \
|
||||
: (NUM_GREGS * REGISTER_SIZE + \
|
||||
NUM_FREGS * FP_REGISTER_RAW_SIZE + \
|
||||
((N) - FPS_REGNUM) * STATUS_REGISTER_SIZE)))
|
||||
|
||||
/* Number of bytes of storage in the actual machine representation for
|
||||
register N. All registers are 4 bytes, except fp0 - fp7, which are
|
||||
12 bytes in length. */
|
||||
#define REGISTER_RAW_SIZE(N) \
|
||||
((N) < F0_REGNUM ? REGISTER_SIZE : \
|
||||
(N) < FPS_REGNUM ? FP_REGISTER_RAW_SIZE : STATUS_REGISTER_SIZE)
|
||||
|
||||
/* Number of bytes of storage in a program's representation
|
||||
for register N. */
|
||||
#define REGISTER_VIRTUAL_SIZE(N) \
|
||||
((N) < F0_REGNUM ? REGISTER_SIZE : \
|
||||
(N) < FPS_REGNUM ? FP_REGISTER_VIRTUAL_SIZE : STATUS_REGISTER_SIZE)
|
||||
|
||||
/* Largest value REGISTER_RAW_SIZE can have. */
|
||||
|
||||
#define MAX_REGISTER_RAW_SIZE FP_REGISTER_RAW_SIZE
|
||||
|
||||
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
|
||||
#define MAX_REGISTER_VIRTUAL_SIZE FP_REGISTER_VIRTUAL_SIZE
|
||||
|
||||
/* Return the GDB type object for the "standard" data type of data in
|
||||
register N. */
|
||||
|
||||
extern struct type *arm_register_type (int regnum);
|
||||
#define REGISTER_VIRTUAL_TYPE(N) arm_register_type (N)
|
||||
|
||||
/* The system C compiler uses a similar structure return convention to gcc */
|
||||
extern use_struct_convention_fn arm_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) \
|
||||
arm_use_struct_convention (gcc_p, type)
|
||||
|
||||
/* Store the address of the place in which to copy the structure the
|
||||
subroutine will return. This is called from call_function. */
|
||||
|
||||
#define STORE_STRUCT_RETURN(ADDR, SP) \
|
||||
write_register (A1_REGNUM, (ADDR))
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state a
|
||||
function return value of type TYPE, and copy that, in virtual
|
||||
format, into VALBUF. */
|
||||
|
||||
extern void arm_extract_return_value (struct type *, char[], char *);
|
||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||
arm_extract_return_value ((TYPE), (REGBUF), (VALBUF))
|
||||
|
||||
/* Write into appropriate registers a function return value of type
|
||||
TYPE, given in virtual format. */
|
||||
|
||||
extern void convert_to_extended (void *dbl, void *ptr);
|
||||
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
|
||||
if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) { \
|
||||
char _buf[MAX_REGISTER_RAW_SIZE]; \
|
||||
convert_to_extended (VALBUF, _buf); \
|
||||
write_register_bytes (REGISTER_BYTE (F0_REGNUM), _buf, MAX_REGISTER_RAW_SIZE); \
|
||||
} else \
|
||||
write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
the address in which a function should return its structure value,
|
||||
as a CORE_ADDR (or an expression that can be used as one). */
|
||||
|
@ -307,44 +86,10 @@ extern void convert_to_extended (void *dbl, void *ptr);
|
|||
before in the executables list of symbols. */
|
||||
#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) (!(gcc_p))
|
||||
|
||||
#define CALL_DUMMY_WORDS arm_call_dummy_words
|
||||
extern LONGEST arm_call_dummy_words[];
|
||||
|
||||
#define SIZEOF_CALL_DUMMY_WORDS (3 * sizeof (LONGEST))
|
||||
|
||||
#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */
|
||||
|
||||
/* XXX This is NOT multi-arch compatible. */
|
||||
#define CALL_DUMMY_BREAKPOINT_OFFSET arm_call_dummy_breakpoint_offset()
|
||||
extern int arm_call_dummy_breakpoint_offset (void);
|
||||
|
||||
/* Insert the specified number of args and function address into a
|
||||
call sequence of the above form stored at DUMMYNAME. */
|
||||
|
||||
#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
|
||||
arm_fix_call_dummy ((dummyname), (pc), (fun), (nargs), (args), (type), (gcc_p))
|
||||
|
||||
void arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
|
||||
int nargs, struct value ** args,
|
||||
struct type * type, int gcc_p);
|
||||
|
||||
/* Most ARMs don't have single stepping capability, so provide a
|
||||
single-stepping mechanism by default */
|
||||
#undef SOFTWARE_SINGLE_STEP_P
|
||||
#define SOFTWARE_SINGLE_STEP_P() 1
|
||||
|
||||
#define SOFTWARE_SINGLE_STEP(sig,bpt) arm_software_single_step((sig), (bpt))
|
||||
void arm_software_single_step (int, int);
|
||||
|
||||
struct minimal_symbol;
|
||||
|
||||
void arm_elf_make_msymbol_special(asymbol *, struct minimal_symbol *);
|
||||
#define ELF_MAKE_MSYMBOL_SPECIAL(SYM,MSYM) \
|
||||
arm_elf_make_msymbol_special (SYM, MSYM)
|
||||
|
||||
void arm_coff_make_msymbol_special(int, struct minimal_symbol *);
|
||||
#define COFF_MAKE_MSYMBOL_SPECIAL(VAL,MSYM) \
|
||||
arm_coff_make_msymbol_special (VAL, MSYM)
|
||||
|
||||
/* The first 0x20 bytes are the trap vectors. */
|
||||
#define LOWEST_PC 0x20
|
||||
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
#ifndef TM_NBSD_H
|
||||
#define TM_NBSD_H
|
||||
|
||||
/* NetBSD doesn't have single stepping support in ptrace(). */
|
||||
#define SOFTWARE_SINGLE_STEP_P 1
|
||||
|
||||
#include "arm/tm-arm.h"
|
||||
#include "tm-nbsd.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue