/* Common target dependent code for GDB on ARM systems.
Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GDB.
#include "value.h"
#include "arch-utils.h"
#include "solib-svr4.h"
+#include "osabi.h"
#include "arm-tdep.h"
#include "gdb/sim-arm.h"
static int
arm_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
{
- return (chain != 0 && (FRAME_SAVED_PC (thisframe) >= LOWEST_PC));
+ return (FRAME_SAVED_PC (thisframe) >= LOWEST_PC);
}
/* Set to true if the 32-bit mode is in use. */
stmdb sp!, {}
sub sp, ip, #4. */
- func_start = (get_pc_function_start ((fi)->pc) + FUNCTION_START_OFFSET);
+ func_start = (get_pc_function_start (get_frame_pc (fi)) + FUNCTION_START_OFFSET);
after_prologue = SKIP_PROLOGUE (func_start);
/* There are some frameless functions whose first two instructions
/* Don't try to scan dummy frames. */
if (fi != NULL
- && DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ && DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0))
return;
- if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ if (find_pc_partial_function (get_frame_pc (fi), NULL, &prologue_start, &prologue_end))
{
struct symtab_and_line sal = find_pc_line (prologue_start, 0);
if (sal.line == 0) /* no line info, use current PC */
- prologue_end = fi->pc;
+ prologue_end = get_frame_pc (fi);
else if (sal.end < prologue_end) /* next line begins after fn end */
prologue_end = sal.end; /* (probably means no prologue) */
}
16 pushes, an add, and "mv fp,sp". */
prologue_end = prologue_start + 40;
- prologue_end = min (prologue_end, fi->pc);
+ prologue_end = min (prologue_end, get_frame_pc (fi));
/* Initialize the saved register map. When register H is copied to
register L, we will put H in saved_reg[L]. */
if (mask & (1 << regno))
{
fi->extra_info->framesize += 4;
- fi->saved_regs[saved_reg[regno]] =
+ get_frame_saved_regs (fi)[saved_reg[regno]] =
-(fi->extra_info->framesize);
/* Reset saved register map. */
saved_reg[regno] = regno;
{
int i;
- if (fi->pc == prologue_cache.pc)
+ if (get_frame_pc (fi) == get_frame_pc (&prologue_cache))
{
fi->extra_info->framereg = prologue_cache.extra_info->framereg;
fi->extra_info->framesize = prologue_cache.extra_info->framesize;
fi->extra_info->frameoffset = prologue_cache.extra_info->frameoffset;
for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
- fi->saved_regs[i] = prologue_cache.saved_regs[i];
+ get_frame_saved_regs (fi)[i] = get_frame_saved_regs (&prologue_cache)[i];
return 1;
}
else
{
int i;
- prologue_cache.pc = fi->pc;
+ deprecated_update_frame_pc_hack (&prologue_cache, get_frame_pc (fi));
prologue_cache.extra_info->framereg = fi->extra_info->framereg;
prologue_cache.extra_info->framesize = fi->extra_info->framesize;
prologue_cache.extra_info->frameoffset = fi->extra_info->frameoffset;
for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
- prologue_cache.saved_regs[i] = fi->saved_regs[i];
+ get_frame_saved_regs (&prologue_cache)[i] = get_frame_saved_regs (fi)[i];
}
fi->extra_info->frameoffset = 0;
/* Check for Thumb prologue. */
- if (arm_pc_is_thumb (fi->pc))
+ if (arm_pc_is_thumb (get_frame_pc (fi)))
{
thumb_scan_prologue (fi);
save_prologue_cache (fi);
/* Find the function prologue. If we can't find the function in
the symbol table, peek in the stack frame to find the PC. */
- if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
+ if (find_pc_partial_function (get_frame_pc (fi), NULL, &prologue_start, &prologue_end))
{
/* One way to find the end of the prologue (which works well
for unoptimized code) is to do the following:
struct symtab_and_line sal = find_pc_line (prologue_start, 0);
if (sal.line == 0)
- prologue_end = fi->pc;
+ prologue_end = get_frame_pc (fi);
else if (sal.end < prologue_end)
prologue_end = sal.end;
if (mask & (1 << regno))
{
sp_offset -= 4;
- fi->saved_regs[regno] = sp_offset;
+ get_frame_saved_regs (fi)[regno] = sp_offset;
}
}
else if ((insn & 0xffffc000) == 0xe54b0000 || /* strb rx,[r11,#-n] */
{
sp_offset -= 12;
regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
- fi->saved_regs[regno] = sp_offset;
+ get_frame_saved_regs (fi)[regno] = sp_offset;
}
else if ((insn & 0xffbf0fff) == 0xec2d0200) /* sfmfd f0, 4, [sp!] */
{
for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
{
sp_offset -= 12;
- fi->saved_regs[fp_start_reg++] = sp_offset;
+ get_frame_saved_regs (fi)[fp_start_reg++] = sp_offset;
}
}
else if ((insn & 0xf0000000) != 0xe0000000)
function could be called directly. */
for (; fi; fi = fi->next)
{
- if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0))
{
- return deprecated_read_register_dummy (fi->pc, fi->frame, regnum);
+ return deprecated_read_register_dummy (get_frame_pc (fi), fi->frame, regnum);
}
- else if (fi->saved_regs[regnum] != 0)
+ else if (get_frame_saved_regs (fi)[regnum] != 0)
{
/* NOTE: cagney/2002-05-03: This would normally need to
handle ARM_SP_REGNUM as a special case as, according to
the frame.h comments, saved_regs[SP_REGNUM] contains the
SP value not its address. It appears that the ARM isn't
doing this though. */
- return read_memory_integer (fi->saved_regs[regnum],
+ return read_memory_integer (get_frame_saved_regs (fi)[regnum],
REGISTER_RAW_SIZE (regnum));
}
}
CORE_ADDR caller_pc;
int framereg = fi->extra_info->framereg;
- if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, 0, 0))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0))
/* A generic call dummy's frame is the same as caller's. */
return fi->frame;
- if (fi->pc < LOWEST_PC)
+ if (get_frame_pc (fi) < LOWEST_PC)
return 0;
/* If the caller is the startup code, we're at the end of the chain. */
frame register number. */
/* XXX Fixme, we should try to do this without creating a temporary
caller_fi. */
- if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (fi->pc))
+ if (arm_pc_is_thumb (caller_pc) != arm_pc_is_thumb (get_frame_pc (fi)))
{
struct frame_info caller_fi;
struct cleanup *old_chain;
make_cleanup (xfree, caller_fi.saved_regs);
/* Now, scan the prologue and obtain the frame register. */
- caller_fi.pc = caller_pc;
+ deprecated_update_frame_pc_hack (&caller_fi, caller_pc);
arm_scan_prologue (&caller_fi);
framereg = caller_fi.extra_info->framereg;
int reg;
CORE_ADDR sp;
- if (fi->saved_regs == NULL)
+ if (get_frame_saved_regs (fi) == NULL)
frame_saved_regs_zalloc (fi);
fi->extra_info = (struct frame_extra_info *)
fi->extra_info->framereg = 0;
if (fi->next)
- fi->pc = FRAME_SAVED_PC (fi->next);
+ deprecated_update_frame_pc_hack (fi, FRAME_SAVED_PC (fi->next));
- memset (fi->saved_regs, '\000', sizeof fi->saved_regs);
+ memset (get_frame_saved_regs (fi), '\000', sizeof get_frame_saved_regs (fi));
/* Compute stack pointer for this frame. We use this value for both
the sigtramp and call dummy cases. */
if (!fi->next)
sp = read_sp();
- else if (DEPRECATED_PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
+ else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi->next), 0, 0))
/* For generic dummy frames, pull the value direct from the frame.
Having an unwind function to do this would be nice. */
- sp = deprecated_read_register_dummy (fi->next->pc, fi->next->frame,
+ sp = deprecated_read_register_dummy (get_frame_pc (fi->next), fi->next->frame,
ARM_SP_REGNUM);
else
sp = (fi->next->frame - fi->next->extra_info->frameoffset
before calling functions like this. */
if (SIGCONTEXT_REGISTER_ADDRESS_P ()
- && ((get_frame_type (fi) == SIGTRAMP_FRAME) || PC_IN_SIGTRAMP (fi->pc, (char *)0)))
+ && ((get_frame_type (fi) == SIGTRAMP_FRAME) || PC_IN_SIGTRAMP (get_frame_pc (fi), (char *)0)))
{
for (reg = 0; reg < NUM_REGS; reg++)
- fi->saved_regs[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, fi->pc, reg);
+ get_frame_saved_regs (fi)[reg] = SIGCONTEXT_REGISTER_ADDRESS (sp, get_frame_pc (fi), reg);
/* FIXME: What about thumb mode? */
fi->extra_info->framereg = ARM_SP_REGNUM;
fi->frame =
- read_memory_integer (fi->saved_regs[fi->extra_info->framereg],
+ read_memory_integer (get_frame_saved_regs (fi)[fi->extra_info->framereg],
REGISTER_RAW_SIZE (fi->extra_info->framereg));
fi->extra_info->framesize = 0;
fi->extra_info->frameoffset = 0;
if (!fi->next)
/* This is the innermost frame? */
fi->frame = read_register (fi->extra_info->framereg);
- else if (DEPRECATED_PC_IN_CALL_DUMMY (fi->next->pc, 0, 0))
+ else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi->next), 0, 0))
/* Next inner most frame is a dummy, just grab its frame.
Dummy frames always have the same FP as their caller. */
fi->frame = fi->next->frame;
{
/* not the innermost frame */
/* If we have an FP, the callee saved it. */
- if (fi->next->saved_regs[fi->extra_info->framereg] != 0)
+ if (get_frame_saved_regs (get_next_frame (fi))[fi->extra_info->framereg] != 0)
fi->frame =
- read_memory_integer (fi->next
- ->saved_regs[fi->extra_info->framereg], 4);
+ read_memory_integer (get_frame_saved_regs (get_next_frame (fi))[fi->extra_info->framereg], 4);
else if (fromleaf)
/* If we were called by a frameless fn. then our frame is
still in the frame pointer register on the board... */
/* Calculate actual addresses of saved registers using offsets
determined by arm_scan_prologue. */
for (reg = 0; reg < NUM_REGS; reg++)
- if (fi->saved_regs[reg] != 0)
- fi->saved_regs[reg] += (fi->frame + fi->extra_info->framesize
- - fi->extra_info->frameoffset);
+ if (get_frame_saved_regs (fi)[reg] != 0)
+ get_frame_saved_regs (fi)[reg] += (fi->frame + fi->extra_info->framesize
+ - fi->extra_info->frameoffset);
}
}
arm_frame_saved_pc (struct frame_info *fi)
{
/* If a dummy frame, pull the PC out of the frame's register buffer. */
- if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, 0, 0))
- return deprecated_read_register_dummy (fi->pc, fi->frame, ARM_PC_REGNUM);
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), 0, 0))
+ return deprecated_read_register_dummy (get_frame_pc (fi), fi->frame, ARM_PC_REGNUM);
- if (DEPRECATED_PC_IN_CALL_DUMMY (fi->pc, fi->frame - fi->extra_info->frameoffset,
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi), fi->frame - fi->extra_info->frameoffset,
fi->frame))
{
- return read_memory_integer (fi->saved_regs[ARM_PC_REGNUM],
+ return read_memory_integer (get_frame_saved_regs (fi)[ARM_PC_REGNUM],
REGISTER_RAW_SIZE (ARM_PC_REGNUM));
}
else
arm_frame_init_saved_regs (struct frame_info *fip)
{
- if (fip->saved_regs)
+ if (get_frame_saved_regs (fip))
return;
arm_init_extra_frame_info (0, fip);
CORE_ADDR old_SP = (frame->frame - frame->extra_info->frameoffset
+ frame->extra_info->framesize);
- if (DEPRECATED_PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), frame->frame, frame->frame))
{
generic_pop_dummy_frame ();
flush_cached_frames ();
}
for (regnum = 0; regnum < NUM_REGS; regnum++)
- if (frame->saved_regs[regnum] != 0)
+ if (get_frame_saved_regs (frame)[regnum] != 0)
write_register (regnum,
- read_memory_integer (frame->saved_regs[regnum],
+ read_memory_integer (get_frame_saved_regs (frame)[regnum],
REGISTER_RAW_SIZE (regnum)));
write_register (ARM_PC_REGNUM, FRAME_SAVED_PC (frame));
{
struct gdbarch_tdep *tdep;
struct gdbarch *gdbarch;
- enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
/* Try to deterimine the ABI of the object we are loading. */
- if (info.abfd != NULL)
+ if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN)
{
- osabi = gdbarch_lookup_osabi (info.abfd);
- if (osabi == GDB_OSABI_UNKNOWN)
+ switch (bfd_get_flavour (info.abfd))
{
- switch (bfd_get_flavour (info.abfd))
- {
- case bfd_target_aout_flavour:
- /* Assume it's an old APCS-style ABI. */
- osabi = GDB_OSABI_ARM_APCS;
- break;
+ case bfd_target_aout_flavour:
+ /* Assume it's an old APCS-style ABI. */
+ info.osabi = GDB_OSABI_ARM_APCS;
+ break;
- case bfd_target_coff_flavour:
- /* Assume it's an old APCS-style ABI. */
- /* XXX WinCE? */
- osabi = GDB_OSABI_ARM_APCS;
- break;
+ case bfd_target_coff_flavour:
+ /* Assume it's an old APCS-style ABI. */
+ /* XXX WinCE? */
+ info.osabi = GDB_OSABI_ARM_APCS;
+ break;
- default:
- /* Leave it as "unknown". */
- }
+ default:
+ /* Leave it as "unknown". */
}
}
- /* Find a candidate among extant architectures. */
- for (arches = gdbarch_list_lookup_by_info (arches, &info);
- arches != NULL;
- arches = gdbarch_list_lookup_by_info (arches->next, &info))
- {
- /* Make sure the ABI selection matches. */
- tdep = gdbarch_tdep (arches->gdbarch);
- if (tdep && tdep->osabi == osabi)
- return arches->gdbarch;
- }
+ /* If there is already a candidate, use it. */
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
tdep = xmalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
ready to unwind the PC first (see frame.c:get_prev_frame()). */
set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
- tdep->osabi = osabi;
-
/* This is the way it has always defaulted. */
tdep->fp_model = ARM_FLOAT_FPA;
set_gdbarch_push_return_address (gdbarch, arm_push_return_address);
set_gdbarch_push_arguments (gdbarch, arm_push_arguments);
- set_gdbarch_coerce_float_to_double (gdbarch,
- standard_coerce_float_to_double);
/* Frame handling. */
set_gdbarch_frame_chain_valid (gdbarch, arm_frame_chain_valid);
arm_coff_make_msymbol_special);
/* Hook in the ABI-specific overrides, if they have been registered. */
- gdbarch_init_osabi (info, gdbarch, osabi);
+ gdbarch_init_osabi (info, gdbarch);
/* Now we have tuned the configuration, set a few final things,
based on what the OS ABI has told us. */
/* We can't use SIZEOF_FRAME_SAVED_REGS here, 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);
+ if (get_frame_saved_regs (&prologue_cache) != NULL)
+ xfree (get_frame_saved_regs (&prologue_cache));
/* We can't use NUM_REGS nor NUM_PSEUDO_REGS here, since that still
references the old architecture vector, not the one we are
if (tdep == NULL)
return;
- fprintf_unfiltered (file, "arm_dump_tdep: OS ABI = %s\n",
- gdbarch_osabi_name (tdep->osabi));
-
fprintf_unfiltered (file, "arm_dump_tdep: Lowest pc = 0x%lx",
(unsigned long) tdep->lowest_pc);
}