mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 17:18:55 +00:00
ChangeLog:
* Makefile.in (ppc_linux_tdep_h): New macro. (powerpc_32l_c, powerpc_altivec32_c, powerpc_altivec32l_c): Likewise. (powerpc_64l_c, powerpc_altivec64_c, powerpc_altivec64l_c): Likewise. (powerpc_e500l_c): Likewise. (ppc-linux-nat.o): Update dependencies. (ppc-linux-tdep.o): Update dependencies. (rs6000-tdep.o): Update dependencies. * ppc-tdep.h (ppc_linux_memory_remove_breakpoint): Remove. (ppc_linux_svr4_fetch_link_map_offsets): Remove. (ppc_linux_gregset, ppc_linux_fpregset): Move to ppc-linux-tdep.h (ppc_supply_reg, ppc_collect_reg): Add prototypes. (tdesc_powerpc_e500): Remove. * rs6000.c: Include "features/rs6000/powerpc-altivec32.c" and "features/rs6000/powerpc-altivec64.c". (ppc_supply_reg, ppc_collect_reg): Make global. (variants): Use tdesc_powerpc_32 for "powerpc" and tdesc_powerpc_altivec64 for "powerpc64". (_initialize_rs6000_tdep): Initialize AltiVec descriptions. * ppc-linux-tdep.h: New file. * ppc-linux-tdep.c: Include "ppc-linux-tdep.c". Include "features/rs6000/powerpc-32l.c". Include "features/rs6000/powerpc-altivec32l.c". Include "features/rs6000/powerpc-64l.c". Include "features/rs6000/powerpc-altivec64l.c". Include "features/rs6000/powerpc-e500l.c". (ppc_linux_supply_gregset): New function. (ppc_linux_collect_gregset): Handle orig_r3 and trap registers. (ppc32_linux_gregset): Use ppc_linux_supply_gregset. (ppc64_linux_gregset): Likewise. (ppc_linux_sigtramp_cache): Handle orig_r3 and trap registers. (ppc_linux_trap_reg_p): New function. (ppc_linux_write_pc): New function. (ppc_linux_core_read_description): New function. (ppc_linux_init_abi): Install ppc_linux_write_pc and ppc_linux_core_read_description. Install orig_r3 and trap registers if present in the target description. (_initialize_ppc_linux_tdep): Initialize Linux target descriptions. * ppc-linux-nat.c: Include "ppc-linux-tdep.h". (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_register_u_addr): Handle orig_r3 and trap registers. (fetch_ppc_registers): Likewise. (store_ppc_registers): Likewise. (store_register): Likewise. (ppc_linux_read_description): Check whether AltiVec is supported. Check whether inferior is 32-bit or 64-bit. Return the appropriate Linux target description. * features/Makefile (WHICH): Use rs6000/powerpc-32l and rs6000/powerpc-altivec32l instead of rs6000/powerpc-32. Use rs6000/powerpc-64l and rs6000/powerpc-altivec64l instead of rs6000/powerpc-64. Use rs6000/powerpc-e500l instead of rs6000/powerpc-e500. Update -expedite variables accordingly. * features/rs6000/power-spe.xml: Use regnum 73 for "acc". * features/rs6000/powerpc-32.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-64.xml: Do not include power-altivec.xml. * features/rs6000/powerpc-e500.c: Regenerate. * features/rs6000/powerpc-32.c: Regenerate. * features/rs6000/powerpc-64.c: Regenerate. * features/rs6000/power-linux.xml: New file. * features/rs6000/power64-linux.xml: New file. * features/rs6000/powerpc-32l.xml: New file. * features/rs6000/powerpc-altivec32l.xml: New file. * features/rs6000/powerpc-64l.xml: New file. * features/rs6000/powerpc-altivec64l.xml: New file. * features/rs6000/powerpc-e500l.xml: New file. * features/rs6000/powerpc-32l.c: New (generated) file. * features/rs6000/powerpc-altivec32l.c: New (generated) file. * features/rs6000/powerpc-64l.c: New (generated) file. * features/rs6000/powerpc-altivec64l.c: New (generated) file. * features/rs6000/powerpc-e500l.xml: New (generated) file. * regformats/reg-ppc.dat: Remove. * regformats/reg-ppc64.dat: Remove. * regformats/rs6000/powerpc-32.dat: Remove. * regformats/rs6000/powerpc-64.dat: Remove. * regformats/rs6000/powerpc-e500.dat: Remove. * regformats/rs6000/powerpc-32l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec32l.dat: New (generated) file. * regformats/rs6000/powerpc-64l.dat: New (generated) file. * regformats/rs6000/powerpc-altivec64l.dat: New (generated) file. * regformats/rs6000/powerpc-e500l.dat: New (generated) file. gdbserver/ChangeLog: * configure.srv (powerpc*-*-linux*): Set srv_regobj to powerpc-32l.o, powerpc-altivec32l.o, powerpc-e500l.o, powerpc-64l.o, and powerpc-altivec64l.o. Remove rs6000/powerpc-32.xml, rs6000/powerpc-64.xml, and rs6000/powerpc-e500.xml; add rs6000/powerpc-32l.xml, rs6000/powerpc-altivec32l.xml, rs6000/powerpc-e500l.xml, rs6000/powerpc-64l.xml, rs6000/powerpc-altivec64l.xml, rs6000/power-linux.xml, and rs6000/power64-linux.xml to srv_xmlfiles. * Makefile.in (reg-ppc.o, reg-ppc.c): Remove, replace by ... (powerpc-32l.o, powerpc-32l.c): ... these new rules. (powerpc-32.o, powerpc-32.c): Remove, replace by ... (powerpc-altivec32l.o, powerpc-altivec32l.c): ... these new rules. (powerpc-e500.o, powerpc-e500.c): Remove, replace by ... (powerpc-e500l.o, powerpc-e500l.c): ... these new rules. (reg-ppc64.o, reg-ppc64.c): Remove, replace by ... (powerpc-64l.o, powerpc-64l.c): ... these new rules. (powerpc-64.o, powerpc-64.c): Remove, replace by ... (powerpc-altivec64l.o, powerpc-altivec64l.c): ... these new rules. (clean): Update. * linux-ppc-low.c (init_registers_ppc): Remove, replace by ... (init_registers_powerpc_32l): ... this new prototype. (init_registers_powerpc_32): Remove, replace by ... (init_registers_powerpc_altivec32l): ... this new prototype. (init_registers_powerpc_e500): Remove, replace by ... (init_registers_powerpc_e500l): ... this new prototype. (init_registers_ppc64): Remove, replace by ... (init_registers_powerpc_64l): ... this new prototype. (init_registers_powerpc_64): Remove, replace by ... (init_registers_powerpc_altivec64l): ... this new prototype. (ppc_num_regs): Set to 73. (PT_ORIG_R3, PT_TRAP): Define if necessary. (ppc_regmap, ppc_regmap_e500): Add values for orig_r3 and trap. (ppc_cannot_store_register): Handle orig_r3 and trap. (ppc_arch_setup): Update init_registers_... calls. (ppc_fill_gregset): Handle orig_r3 and trap. * inferiors.c (clear_inferiors): Reset current_inferior.
This commit is contained in:
@@ -34,10 +34,17 @@
|
||||
#include "regset.h"
|
||||
#include "solib-svr4.h"
|
||||
#include "ppc-tdep.h"
|
||||
#include "ppc-linux-tdep.h"
|
||||
#include "trad-frame.h"
|
||||
#include "frame-unwind.h"
|
||||
#include "tramp-frame.h"
|
||||
|
||||
#include "features/rs6000/powerpc-32l.c"
|
||||
#include "features/rs6000/powerpc-altivec32l.c"
|
||||
#include "features/rs6000/powerpc-64l.c"
|
||||
#include "features/rs6000/powerpc-altivec64l.c"
|
||||
#include "features/rs6000/powerpc-e500l.c"
|
||||
|
||||
static CORE_ADDR
|
||||
ppc_linux_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
|
||||
{
|
||||
@@ -620,17 +627,60 @@ ppc_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* This wrapper clears areas in the linux gregset not written by
|
||||
ppc_collect_gregset. */
|
||||
/* Wrappers to handle Linux-only registers. */
|
||||
|
||||
static void
|
||||
ppc_linux_supply_gregset (const struct regset *regset,
|
||||
struct regcache *regcache,
|
||||
int regnum, const void *gregs, size_t len)
|
||||
{
|
||||
const struct ppc_reg_offsets *offsets = regset->descr;
|
||||
|
||||
ppc_supply_gregset (regset, regcache, regnum, gregs, len);
|
||||
|
||||
if (ppc_linux_trap_reg_p (get_regcache_arch (regcache)))
|
||||
{
|
||||
/* "orig_r3" is stored 2 slots after "pc". */
|
||||
if (regnum == -1 || regnum == PPC_ORIG_R3_REGNUM)
|
||||
ppc_supply_reg (regcache, PPC_ORIG_R3_REGNUM, gregs,
|
||||
offsets->pc_offset + 2 * offsets->gpr_size,
|
||||
offsets->gpr_size);
|
||||
|
||||
/* "trap" is stored 8 slots after "pc". */
|
||||
if (regnum == -1 || regnum == PPC_TRAP_REGNUM)
|
||||
ppc_supply_reg (regcache, PPC_TRAP_REGNUM, gregs,
|
||||
offsets->pc_offset + 8 * offsets->gpr_size,
|
||||
offsets->gpr_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ppc_linux_collect_gregset (const struct regset *regset,
|
||||
const struct regcache *regcache,
|
||||
int regnum, void *gregs, size_t len)
|
||||
{
|
||||
const struct ppc_reg_offsets *offsets = regset->descr;
|
||||
|
||||
/* Clear areas in the linux gregset not written elsewhere. */
|
||||
if (regnum == -1)
|
||||
memset (gregs, 0, len);
|
||||
|
||||
ppc_collect_gregset (regset, regcache, regnum, gregs, len);
|
||||
|
||||
if (ppc_linux_trap_reg_p (get_regcache_arch (regcache)))
|
||||
{
|
||||
/* "orig_r3" is stored 2 slots after "pc". */
|
||||
if (regnum == -1 || regnum == PPC_ORIG_R3_REGNUM)
|
||||
ppc_collect_reg (regcache, PPC_ORIG_R3_REGNUM, gregs,
|
||||
offsets->pc_offset + 2 * offsets->gpr_size,
|
||||
offsets->gpr_size);
|
||||
|
||||
/* "trap" is stored 8 slots after "pc". */
|
||||
if (regnum == -1 || regnum == PPC_TRAP_REGNUM)
|
||||
ppc_collect_reg (regcache, PPC_TRAP_REGNUM, gregs,
|
||||
offsets->pc_offset + 8 * offsets->gpr_size,
|
||||
offsets->gpr_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Regset descriptions. */
|
||||
@@ -686,14 +736,14 @@ static const struct ppc_reg_offsets ppc64_linux_reg_offsets =
|
||||
|
||||
static const struct regset ppc32_linux_gregset = {
|
||||
&ppc32_linux_reg_offsets,
|
||||
ppc_supply_gregset,
|
||||
ppc_linux_supply_gregset,
|
||||
ppc_linux_collect_gregset,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct regset ppc64_linux_gregset = {
|
||||
&ppc64_linux_reg_offsets,
|
||||
ppc_supply_gregset,
|
||||
ppc_linux_supply_gregset,
|
||||
ppc_linux_collect_gregset,
|
||||
NULL
|
||||
};
|
||||
@@ -789,6 +839,14 @@ ppc_linux_sigtramp_cache (struct frame_info *this_frame,
|
||||
trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum,
|
||||
gpregs + 38 * tdep->wordsize);
|
||||
|
||||
if (ppc_linux_trap_reg_p (gdbarch))
|
||||
{
|
||||
trad_frame_set_reg_addr (this_cache, PPC_ORIG_R3_REGNUM,
|
||||
gpregs + 34 * tdep->wordsize);
|
||||
trad_frame_set_reg_addr (this_cache, PPC_TRAP_REGNUM,
|
||||
gpregs + 40 * tdep->wordsize);
|
||||
}
|
||||
|
||||
if (ppc_floating_point_unit_p (gdbarch))
|
||||
{
|
||||
/* Floating point registers. */
|
||||
@@ -895,11 +953,69 @@ static struct tramp_frame ppc64_linux_sighandler_tramp_frame = {
|
||||
ppc64_linux_sighandler_cache_init
|
||||
};
|
||||
|
||||
|
||||
/* Return 1 if PPC_ORIG_R3_REGNUM and PPC_TRAP_REGNUM are usable. */
|
||||
int
|
||||
ppc_linux_trap_reg_p (struct gdbarch *gdbarch)
|
||||
{
|
||||
/* If we do not have a target description with registers, then
|
||||
the special registers will not be included in the register set. */
|
||||
if (!tdesc_has_registers (gdbarch_target_desc (gdbarch)))
|
||||
return 0;
|
||||
|
||||
/* If we do, then it is safe to check the size. */
|
||||
return register_size (gdbarch, PPC_ORIG_R3_REGNUM) > 0
|
||||
&& register_size (gdbarch, PPC_TRAP_REGNUM) > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ppc_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_regcache_arch (regcache);
|
||||
|
||||
regcache_cooked_write_unsigned (regcache, gdbarch_pc_regnum (gdbarch), pc);
|
||||
|
||||
/* Set special TRAP register to -1 to prevent the kernel from
|
||||
messing with the PC we just installed, if we happen to be
|
||||
within an interrupted system call that the kernel wants to
|
||||
restart.
|
||||
|
||||
Note that after we return from the dummy call, the TRAP and
|
||||
ORIG_R3 registers will be automatically restored, and the
|
||||
kernel continues to restart the system call at this point. */
|
||||
if (ppc_linux_trap_reg_p (gdbarch))
|
||||
regcache_cooked_write_unsigned (regcache, PPC_TRAP_REGNUM, -1);
|
||||
}
|
||||
|
||||
static const struct target_desc *
|
||||
ppc_linux_core_read_description (struct gdbarch *gdbarch,
|
||||
struct target_ops *target,
|
||||
bfd *abfd)
|
||||
{
|
||||
asection *altivec = bfd_get_section_by_name (abfd, ".reg-ppc-vmx");
|
||||
asection *section = bfd_get_section_by_name (abfd, ".reg");
|
||||
if (! section)
|
||||
return NULL;
|
||||
|
||||
switch (bfd_section_size (abfd, section))
|
||||
{
|
||||
case 48 * 4:
|
||||
return altivec? tdesc_powerpc_altivec32l : tdesc_powerpc_32l;
|
||||
|
||||
case 48 * 8:
|
||||
return altivec? tdesc_powerpc_altivec64l : tdesc_powerpc_64l;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ppc_linux_init_abi (struct gdbarch_info info,
|
||||
struct gdbarch *gdbarch)
|
||||
{
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
|
||||
struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
|
||||
|
||||
/* PPC GNU/Linux uses either 64-bit or 128-bit long doubles; where
|
||||
128-bit, they are IBM long double, not IEEE quad long double as
|
||||
@@ -914,6 +1030,9 @@ ppc_linux_init_abi (struct gdbarch_info info,
|
||||
set_gdbarch_convert_from_func_ptr_addr
|
||||
(gdbarch, ppc_linux_convert_from_func_ptr_addr);
|
||||
|
||||
/* Handle inferior calls during interrupted system calls. */
|
||||
set_gdbarch_write_pc (gdbarch, ppc_linux_write_pc);
|
||||
|
||||
if (tdep->wordsize == 4)
|
||||
{
|
||||
/* Until November 2001, gcc did not comply with the 32 bit SysV
|
||||
@@ -951,10 +1070,33 @@ ppc_linux_init_abi (struct gdbarch_info info,
|
||||
tramp_frame_prepend_unwinder (gdbarch, &ppc64_linux_sighandler_tramp_frame);
|
||||
}
|
||||
set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
|
||||
set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
|
||||
|
||||
/* Enable TLS support. */
|
||||
set_gdbarch_fetch_tls_load_module_address (gdbarch,
|
||||
svr4_fetch_objfile_link_map);
|
||||
|
||||
if (tdesc_data)
|
||||
{
|
||||
const struct tdesc_feature *feature;
|
||||
|
||||
/* If we have target-described registers, then we can safely
|
||||
reserve a number for PPC_ORIG_R3_REGNUM and PPC_TRAP_REGNUM
|
||||
(whether they are described or not). */
|
||||
gdb_assert (gdbarch_num_regs (gdbarch) <= PPC_ORIG_R3_REGNUM);
|
||||
set_gdbarch_num_regs (gdbarch, PPC_TRAP_REGNUM + 1);
|
||||
|
||||
/* If they are present, then assign them to the reserved number. */
|
||||
feature = tdesc_find_feature (info.target_desc,
|
||||
"org.gnu.gdb.power.linux");
|
||||
if (feature != NULL)
|
||||
{
|
||||
tdesc_numbered_register (feature, tdesc_data,
|
||||
PPC_ORIG_R3_REGNUM, "orig_r3");
|
||||
tdesc_numbered_register (feature, tdesc_data,
|
||||
PPC_TRAP_REGNUM, "trap");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -968,4 +1110,11 @@ _initialize_ppc_linux_tdep (void)
|
||||
ppc_linux_init_abi);
|
||||
gdbarch_register_osabi (bfd_arch_rs6000, bfd_mach_rs6k, GDB_OSABI_LINUX,
|
||||
ppc_linux_init_abi);
|
||||
|
||||
/* Initialize the Linux target descriptions. */
|
||||
initialize_tdesc_powerpc_32l ();
|
||||
initialize_tdesc_powerpc_altivec32l ();
|
||||
initialize_tdesc_powerpc_64l ();
|
||||
initialize_tdesc_powerpc_altivec64l ();
|
||||
initialize_tdesc_powerpc_e500l ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user