Make GNU/Linux/PPC work again.
This commit is contained in:
parent
dc62a253bc
commit
9aa1e687a2
22 changed files with 287 additions and 107 deletions
|
@ -1,3 +1,55 @@
|
||||||
|
2000-07-31 Kevin Buettner <kevinb@redhat.com>
|
||||||
|
|
||||||
|
* ppc-tdep.h: New file.
|
||||||
|
* Makefile.in (ppc-linux-tdep.o, rs6000-tdep.o): Add ppc-tdep.h
|
||||||
|
as a dependency.
|
||||||
|
* ppc-linux-tdep.c, rs6000-tdep.c (ppc-tdep.h): Include.
|
||||||
|
|
||||||
|
* ppc-linux-tdep.c (ppc_linux_at_sigtramp_return_path): Made static.
|
||||||
|
|
||||||
|
* rs6000-tdep.c (elf-bfd.h): Include.
|
||||||
|
(gdbarch_tdep): Add field osabi to this struct.
|
||||||
|
(rs6000_init_extra_frame_info, rs6000_frame_init_saved_regs,
|
||||||
|
rs6000_frameless_function_invocation, rs6000_frame_saved_pc,
|
||||||
|
rs6000_frame_chain): No longer static.
|
||||||
|
(process_note_abi_tag_sections, get_elfosabi): New static
|
||||||
|
functions.
|
||||||
|
(rs6000_gdbarch_init): Revised to accomodate ELF executables;
|
||||||
|
also use Linux specific methods when the target is Linux.
|
||||||
|
|
||||||
|
* config/powerpc/aix.mt, config/powerpc/cygwin.mt,
|
||||||
|
config/powerpc/macos.mt, config/powerpc/nbsd.mt,
|
||||||
|
config/powerpc/ppc-eabi.mt, config/powerpc/ppc-nw.mt,
|
||||||
|
config/powerpc/ppc-sim.mt, config/powerpc/ppcle-eabi.mt,
|
||||||
|
config/powerpc/ppcle-sim.mt, config/powerpc/solaris.mt,
|
||||||
|
config/powerpc/vxworks.mt, config/rs6000/aix4.mt,
|
||||||
|
config/rs6000/rs6000.mt, config/rs6000/rs6000lynx.mt
|
||||||
|
(TDEPFILES): Add ppc-linux-tdep.o.
|
||||||
|
|
||||||
|
* config/tm-linux.h (SIGCONTEXT_PC_OFFSET, FRAME_SAVED_PC,
|
||||||
|
INIT_EXTRA_FRAME_INFO, FRAMELESS_FUNCTION_INVOCATION,
|
||||||
|
FRAME_INIT_SAVED_REGS, FRAME_CHAIN, PUSH_ARGUMENTS,
|
||||||
|
MEMORY_REMOVE_BREAKPOINT: Removed defines.
|
||||||
|
(ppc_linux_frame_saved_pc, ppc_linux_init_extra_frame_info,
|
||||||
|
ppc_linux_frameless_function_invocation,
|
||||||
|
ppc_linux_frame_init_saved_regs, ppc_linux_frame_chain,
|
||||||
|
ppc_sysv_abi_push_arguments, ppc_linux_memory_remove_breakpoint):
|
||||||
|
Removed declarations.
|
||||||
|
(CANNOT_FETCH_REGISTER, CANNOT_STORE_REGISTER): Disabled.
|
||||||
|
|
||||||
|
* dink32-rom.c (dink32_regnames): Make array size implicit.
|
||||||
|
|
||||||
|
* ppc-bdm.h (ppc-tdep.h): Include.
|
||||||
|
|
||||||
|
* rs6000-tdep.c, ppc-linux-tdep.c, ppc-bdm.h, ppc-tdep.h
|
||||||
|
(GP0_REGNUM, TOC_REGNUM, PS_REGNUM, CR_REGNUM, LR_REGNUM,
|
||||||
|
CTR_REGNUM, XER_REGNUM, MQ_REGNUM): Add PPC_ prefix.
|
||||||
|
|
||||||
|
From Nick Duffek:
|
||||||
|
* ppc-tdep.h (ppc_linux_frame_saved_pc, rs6000_frame_saved_pc):
|
||||||
|
Change return type to CORE_ADDR.
|
||||||
|
* ppc-linux-tdep.c (ppc_linux_frame_saved_pc): Likewise.
|
||||||
|
|
||||||
2000-07-31 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
2000-07-31 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||||
|
|
||||||
* remote-e7000.c (e7000_start_remote): Use void *, not char * as
|
* remote-e7000.c (e7000_start_remote): Use void *, not char * as
|
||||||
|
|
|
@ -1627,7 +1627,7 @@ ppc-linux-nat.o: ppc-linux-nat.c $(defs_h) $(gdbcore_h) $(frame_h) \
|
||||||
$(inferior_h) target.h
|
$(inferior_h) target.h
|
||||||
|
|
||||||
ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
|
ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||||
target.h
|
target.h ppc-tdep.h
|
||||||
|
|
||||||
ppcbug-rom.o: ppcbug-rom.c monitor.h $(bfd_h) gdb_wait.h $(defs_h) $(gdbcmd_h) \
|
ppcbug-rom.o: ppcbug-rom.c monitor.h $(bfd_h) gdb_wait.h $(defs_h) $(gdbcmd_h) \
|
||||||
$(inferior_h) target.h serial.h terminal.h
|
$(inferior_h) target.h serial.h terminal.h
|
||||||
|
@ -1769,7 +1769,7 @@ rs6000-nat.o: rs6000-nat.c $(bfd_h) $(defs_h) $(inferior_h) target.h \
|
||||||
xcoffsolib.h
|
xcoffsolib.h
|
||||||
|
|
||||||
rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
|
rs6000-tdep.o: rs6000-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||||
target.h xcoffsolib.h
|
target.h xcoffsolib.h ppc-tdep.h
|
||||||
|
|
||||||
scm-exp.o: $(defs_h) $(value_h) parser-defs.h language.h c-lang.h \
|
scm-exp.o: $(defs_h) $(value_h) parser-defs.h language.h c-lang.h \
|
||||||
scm-lang.h scm-tags.h
|
scm-lang.h scm-tags.h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: PowerPC running AIX
|
# Target: PowerPC running AIX
|
||||||
TDEPFILES= rs6000-tdep.o xcoffsolib.o
|
TDEPFILES= rs6000-tdep.o xcoffsolib.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-ppc-aix.h
|
TM_FILE= tm-ppc-aix.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Target: Powerpc running cygnus's unix api over win32
|
# Target: Powerpc running cygnus's unix api over win32
|
||||||
TDEPFILES= rs6000-tdep.o
|
TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-cygwin.h
|
TM_FILE= tm-cygwin.h
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: PowerMac (PowerPC running MacOS)
|
# Target: PowerMac (PowerPC running MacOS)
|
||||||
TDEPFILES= rs6000-tdep.o xcoffread.o
|
TDEPFILES= rs6000-tdep.o xcoffread.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-macos.h
|
TM_FILE= tm-macos.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Target: PowerPC, running NetBSD
|
# Target: PowerPC, running NetBSD
|
||||||
TDEPFILES= rs6000-tdep.o
|
TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-nbsd.h
|
TM_FILE= tm-nbsd.h
|
||||||
|
|
||||||
GDBSERVER_DEPFILES= low-nbsd.o
|
GDBSERVER_DEPFILES= low-nbsd.o
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: PowerPC running eabi
|
# Target: PowerPC running eabi
|
||||||
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o
|
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-ppc-eabi.h
|
TM_FILE= tm-ppc-eabi.h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: PowerPC running Netware
|
# Target: PowerPC running Netware
|
||||||
TDEPFILES= rs6000-tdep.o
|
TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-ppc-nw.h
|
TM_FILE= tm-ppc-nw.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Target: PowerPC running eabi and including the simulator
|
# Target: PowerPC running eabi and including the simulator
|
||||||
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o
|
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o dink32-rom.o ppc-bdm.o ocd.o remote-sds.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-ppc-eabi.h
|
TM_FILE= tm-ppc-eabi.h
|
||||||
|
|
||||||
SIM_OBS = remote-sim.o
|
SIM_OBS = remote-sim.o
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: PowerPC running eabi in little endian mode
|
# Target: PowerPC running eabi in little endian mode
|
||||||
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o
|
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-ppcle-eabi.h
|
TM_FILE= tm-ppcle-eabi.h
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Target: PowerPC running eabi in little endian mode under the simulator
|
# Target: PowerPC running eabi in little endian mode under the simulator
|
||||||
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o
|
TDEPFILES= ser-ocd.o rs6000-tdep.o monitor.o dsrec.o ppcbug-rom.o ppc-bdm.o ocd.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-ppcle-eabi.h
|
TM_FILE= tm-ppcle-eabi.h
|
||||||
|
|
||||||
SIM_OBS = remote-sim.o
|
SIM_OBS = remote-sim.o
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: PowerPC, running Solaris 2
|
# Target: PowerPC, running Solaris 2
|
||||||
TDEPFILES= rs6000-tdep.o
|
TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-solaris.h
|
TM_FILE= tm-solaris.h
|
||||||
|
|
|
@ -42,9 +42,6 @@ extern int at_subroutine_call_instruction_target();
|
||||||
in symfile.c) */
|
in symfile.c) */
|
||||||
#undef IBM6000_TARGET
|
#undef IBM6000_TARGET
|
||||||
|
|
||||||
/* Offset to saved PC in sigcontext, from <linux/signal.h>. */
|
|
||||||
#define SIGCONTEXT_PC_OFFSET 184
|
|
||||||
|
|
||||||
extern CORE_ADDR ppc_linux_skip_trampoline_code (CORE_ADDR pc);
|
extern CORE_ADDR ppc_linux_skip_trampoline_code (CORE_ADDR pc);
|
||||||
#undef SKIP_TRAMPOLINE_CODE
|
#undef SKIP_TRAMPOLINE_CODE
|
||||||
#define SKIP_TRAMPOLINE_CODE(pc) ppc_linux_skip_trampoline_code (pc)
|
#define SKIP_TRAMPOLINE_CODE(pc) ppc_linux_skip_trampoline_code (pc)
|
||||||
|
@ -53,36 +50,10 @@ extern int ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name);
|
||||||
#undef IN_SIGTRAMP
|
#undef IN_SIGTRAMP
|
||||||
#define IN_SIGTRAMP(pc,func_name) ppc_linux_in_sigtramp (pc,func_name)
|
#define IN_SIGTRAMP(pc,func_name) ppc_linux_in_sigtramp (pc,func_name)
|
||||||
|
|
||||||
extern unsigned long ppc_linux_frame_saved_pc (struct frame_info *);
|
#if 0
|
||||||
#undef FRAME_SAVED_PC
|
|
||||||
#define FRAME_SAVED_PC(FRAME) ppc_linux_frame_saved_pc (FRAME)
|
|
||||||
|
|
||||||
extern void ppc_linux_init_extra_frame_info (int fromleaf, struct frame_info *);
|
|
||||||
#undef INIT_EXTRA_FRAME_INFO
|
|
||||||
#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
|
|
||||||
ppc_linux_init_extra_frame_info (fromleaf, fi)
|
|
||||||
|
|
||||||
extern int ppc_linux_frameless_function_invocation (struct frame_info *);
|
|
||||||
#undef FRAMELESS_FUNCTION_INVOCATION
|
|
||||||
#define FRAMELESS_FUNCTION_INVOCATION(FI) \
|
|
||||||
(ppc_linux_frameless_function_invocation (FI))
|
|
||||||
|
|
||||||
extern void ppc_linux_frame_init_saved_regs (struct frame_info *);
|
|
||||||
#undef FRAME_INIT_SAVED_REGS
|
|
||||||
#define FRAME_INIT_SAVED_REGS(FI) ppc_linux_frame_init_saved_regs (FI)
|
|
||||||
|
|
||||||
CORE_ADDR ppc_linux_frame_chain (struct frame_info *);
|
|
||||||
#undef FRAME_CHAIN
|
|
||||||
#define FRAME_CHAIN(thisframe) ppc_linux_frame_chain (thisframe)
|
|
||||||
|
|
||||||
CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int,
|
|
||||||
CORE_ADDR);
|
|
||||||
#undef PUSH_ARGUMENTS
|
|
||||||
#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
|
|
||||||
(ppc_sysv_abi_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr)))
|
|
||||||
|
|
||||||
#define CANNOT_FETCH_REGISTER(regno) ((regno) >= MQ_REGNUM)
|
#define CANNOT_FETCH_REGISTER(regno) ((regno) >= MQ_REGNUM)
|
||||||
#define CANNOT_STORE_REGISTER(regno) ((regno) >= MQ_REGNUM)
|
#define CANNOT_STORE_REGISTER(regno) ((regno) >= MQ_REGNUM)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Linux doesn't use the PowerOpen ABI for function pointer representation */
|
/* Linux doesn't use the PowerOpen ABI for function pointer representation */
|
||||||
#undef CONVERT_FROM_FUNC_PTR_ADDR
|
#undef CONVERT_FROM_FUNC_PTR_ADDR
|
||||||
|
@ -94,13 +65,6 @@ CORE_ADDR ppc_sysv_abi_push_arguments (int, struct value **, CORE_ADDR, int,
|
||||||
#define PROLOGUE_FIRSTLINE_OVERLAP
|
#define PROLOGUE_FIRSTLINE_OVERLAP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Needed to handled the self-modifying code situation due to the dynamic
|
|
||||||
linker. */
|
|
||||||
int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
|
|
||||||
#undef MEMORY_REMOVE_BREAKPOINT
|
|
||||||
#define MEMORY_REMOVE_BREAKPOINT(addr, contents_cache) \
|
|
||||||
ppc_linux_memory_remove_breakpoint(addr, contents_cache)
|
|
||||||
|
|
||||||
/* N_FUN symbols in shared libaries have 0 for their values and need
|
/* N_FUN symbols in shared libaries have 0 for their values and need
|
||||||
to be relocated. */
|
to be relocated. */
|
||||||
#define SOFUN_ADDRESS_MAYBE_MISSING
|
#define SOFUN_ADDRESS_MAYBE_MISSING
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: Powerpc running VxWorks
|
# Target: Powerpc running VxWorks
|
||||||
TDEPFILES= rs6000-tdep.o
|
TDEPFILES= rs6000-tdep.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-vxworks.h
|
TM_FILE= tm-vxworks.h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: IBM RS/6000 running AIX4
|
# Target: IBM RS/6000 running AIX4
|
||||||
TDEPFILES= rs6000-tdep.o xcoffsolib.o xcoffread.o
|
TDEPFILES= rs6000-tdep.o xcoffsolib.o xcoffread.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-rs6000-aix4.h
|
TM_FILE= tm-rs6000-aix4.h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: IBM RS/6000 running AIX
|
# Target: IBM RS/6000 running AIX
|
||||||
TDEPFILES= rs6000-tdep.o xcoffsolib.o xcoffread.o
|
TDEPFILES= rs6000-tdep.o xcoffsolib.o xcoffread.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-rs6000.h
|
TM_FILE= tm-rs6000.h
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Target: IBM RS6000 running LynxOS
|
# Target: IBM RS6000 running LynxOS
|
||||||
TDEPFILES= coff-solib.o rs6000-tdep.o
|
TDEPFILES= coff-solib.o rs6000-tdep.o ppc-linux-tdep.o
|
||||||
TM_FILE= tm-rs6000ly.h
|
TM_FILE= tm-rs6000ly.h
|
||||||
|
|
|
@ -115,7 +115,7 @@ dink32_load (struct monitor_ops *monops, char *filename, int from_tty)
|
||||||
different names than GDB does, and don't support all the registers
|
different names than GDB does, and don't support all the registers
|
||||||
either. */
|
either. */
|
||||||
|
|
||||||
static char *dink32_regnames[NUM_REGS] =
|
static char *dink32_regnames[] =
|
||||||
{
|
{
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "ocd.h"
|
#include "ocd.h"
|
||||||
|
#include "ppc-tdep.h"
|
||||||
|
|
||||||
static void bdm_ppc_open (char *name, int from_tty);
|
static void bdm_ppc_open (char *name, int from_tty);
|
||||||
|
|
||||||
|
@ -198,7 +199,7 @@ bdm_ppc_fetch_registers (int regno)
|
||||||
/* printf("Asking for register %d\n", first_regno); */
|
/* printf("Asking for register %d\n", first_regno); */
|
||||||
|
|
||||||
/* if asking for an invalid register */
|
/* if asking for an invalid register */
|
||||||
if ((first_regno == MQ_REGNUM) ||
|
if ((first_regno == PPC_MQ_REGNUM) ||
|
||||||
((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
|
((first_regno >= FP0_REGNUM) && (first_regno <= FPLAST_REGNUM)))
|
||||||
{
|
{
|
||||||
/* printf("invalid reg request!\n"); */
|
/* printf("invalid reg request!\n"); */
|
||||||
|
@ -287,14 +288,14 @@ bdm_ppc_store_registers (int regno)
|
||||||
|
|
||||||
/* only attempt to write if it's a valid ppc 8xx register */
|
/* only attempt to write if it's a valid ppc 8xx register */
|
||||||
/* (need to avoid FP regs and MQ reg) */
|
/* (need to avoid FP regs and MQ reg) */
|
||||||
if ((i != MQ_REGNUM) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
|
if ((i != PPC_MQ_REGNUM) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
|
||||||
{
|
{
|
||||||
/* printf("write valid reg %d\n", bdm_regno); */
|
/* printf("write valid reg %d\n", bdm_regno); */
|
||||||
ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
|
ocd_write_bdm_registers (bdm_regno, registers + REGISTER_BYTE (i), 4);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
else if (i == MQ_REGNUM)
|
else if (i == PPC_MQ_REGNUM)
|
||||||
printf("don't write invalid reg %d (MQ_REGNUM)\n", bdm_regno);
|
printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
|
||||||
else
|
else
|
||||||
printf("don't write invalid reg %d\n", bdm_regno);
|
printf("don't write invalid reg %d\n", bdm_regno);
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
|
||||||
|
#include "ppc-tdep.h"
|
||||||
|
|
||||||
/* The following two instructions are used in the signal trampoline
|
/* The following two instructions are used in the signal trampoline
|
||||||
code on linux/ppc */
|
code on linux/ppc */
|
||||||
#define INSTR_LI_R0_0x7777 0x38007777
|
#define INSTR_LI_R0_0x7777 0x38007777
|
||||||
|
@ -95,7 +97,7 @@
|
||||||
#define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31)
|
#define PPC_LINUX_PT_FPR31 (PPC_LINUX_PT_FPR0 + 2*31)
|
||||||
#define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1)
|
#define PPC_LINUX_PT_FPSCR (PPC_LINUX_PT_FPR0 + 2*32 + 1)
|
||||||
|
|
||||||
int ppc_linux_at_sigtramp_return_path (CORE_ADDR pc);
|
static int ppc_linux_at_sigtramp_return_path (CORE_ADDR pc);
|
||||||
|
|
||||||
/* Determine if pc is in a signal trampoline...
|
/* Determine if pc is in a signal trampoline...
|
||||||
|
|
||||||
|
@ -150,7 +152,7 @@ ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
|
||||||
char buf[4];
|
char buf[4];
|
||||||
CORE_ADDR handler;
|
CORE_ADDR handler;
|
||||||
|
|
||||||
lr = read_register (LR_REGNUM);
|
lr = read_register (PPC_LR_REGNUM);
|
||||||
if (!ppc_linux_at_sigtramp_return_path (lr))
|
if (!ppc_linux_at_sigtramp_return_path (lr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -177,7 +179,7 @@ ppc_linux_in_sigtramp (CORE_ADDR pc, char *func_name)
|
||||||
* instructions. It'd be faster though if we could find a way to do this
|
* instructions. It'd be faster though if we could find a way to do this
|
||||||
* via some simple address comparisons.
|
* via some simple address comparisons.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
ppc_linux_at_sigtramp_return_path (CORE_ADDR pc)
|
ppc_linux_at_sigtramp_return_path (CORE_ADDR pc)
|
||||||
{
|
{
|
||||||
char buf[12];
|
char buf[12];
|
||||||
|
@ -308,7 +310,7 @@ ppc_linux_skip_trampoline_code (CORE_ADDR pc)
|
||||||
/* The rs6000 version of FRAME_SAVED_PC will almost work for us. The
|
/* The rs6000 version of FRAME_SAVED_PC will almost work for us. The
|
||||||
signal handler details are different, so we'll handle those here
|
signal handler details are different, so we'll handle those here
|
||||||
and call the rs6000 version to do the rest. */
|
and call the rs6000 version to do the rest. */
|
||||||
unsigned long
|
CORE_ADDR
|
||||||
ppc_linux_frame_saved_pc (struct frame_info *fi)
|
ppc_linux_frame_saved_pc (struct frame_info *fi)
|
||||||
{
|
{
|
||||||
if (fi->signal_handler_caller)
|
if (fi->signal_handler_caller)
|
||||||
|
@ -372,14 +374,14 @@ ppc_linux_frame_init_saved_regs (struct frame_info *fi)
|
||||||
regs_addr =
|
regs_addr =
|
||||||
read_memory_integer (fi->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
|
read_memory_integer (fi->frame + PPC_LINUX_REGS_PTR_OFFSET, 4);
|
||||||
fi->saved_regs[PC_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_NIP;
|
fi->saved_regs[PC_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_NIP;
|
||||||
fi->saved_regs[PS_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_MSR;
|
fi->saved_regs[PPC_PS_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_MSR;
|
||||||
fi->saved_regs[CR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_CCR;
|
fi->saved_regs[PPC_CR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_CCR;
|
||||||
fi->saved_regs[LR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_LNK;
|
fi->saved_regs[PPC_LR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_LNK;
|
||||||
fi->saved_regs[CTR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_CTR;
|
fi->saved_regs[PPC_CTR_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_CTR;
|
||||||
fi->saved_regs[XER_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_XER;
|
fi->saved_regs[PPC_XER_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_XER;
|
||||||
fi->saved_regs[MQ_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_MQ;
|
fi->saved_regs[PPC_MQ_REGNUM] = regs_addr + 4 * PPC_LINUX_PT_MQ;
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
fi->saved_regs[GP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_R0 + 4 * i;
|
fi->saved_regs[PPC_GP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_R0 + 4 * i;
|
||||||
for (i = 0; i < 32; i++)
|
for (i = 0; i < 32; i++)
|
||||||
fi->saved_regs[FP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_FPR0 + 8 * i;
|
fi->saved_regs[FP0_REGNUM + i] = regs_addr + 4 * PPC_LINUX_PT_FPR0 + 8 * i;
|
||||||
}
|
}
|
||||||
|
|
49
gdb/ppc-tdep.h
Normal file
49
gdb/ppc-tdep.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* Target-dependent code for GDB, the GNU debugger.
|
||||||
|
Copyright 2000
|
||||||
|
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. */
|
||||||
|
|
||||||
|
/* From ppc-linux-tdep.c... */
|
||||||
|
CORE_ADDR ppc_linux_frame_saved_pc (struct frame_info *fi);
|
||||||
|
void ppc_linux_init_extra_frame_info (int fromleaf, struct frame_info *);
|
||||||
|
int ppc_linux_frameless_function_invocation (struct frame_info *);
|
||||||
|
void ppc_linux_frame_init_saved_regs (struct frame_info *);
|
||||||
|
CORE_ADDR ppc_linux_frame_chain (struct frame_info *);
|
||||||
|
CORE_ADDR ppc_sysv_abi_push_arguments (int, value_ptr *, CORE_ADDR, int,
|
||||||
|
CORE_ADDR);
|
||||||
|
int ppc_linux_memory_remove_breakpoint (CORE_ADDR addr, char *contents_cache);
|
||||||
|
|
||||||
|
|
||||||
|
/* From rs6000-tdep.c... */
|
||||||
|
CORE_ADDR rs6000_frame_saved_pc (struct frame_info *fi);
|
||||||
|
void rs6000_init_extra_frame_info (int fromleaf, struct frame_info *);
|
||||||
|
int rs6000_frameless_function_invocation (struct frame_info *);
|
||||||
|
void rs6000_frame_init_saved_regs (struct frame_info *);
|
||||||
|
CORE_ADDR rs6000_frame_chain (struct frame_info *);
|
||||||
|
|
||||||
|
/* Some important register numbers. */
|
||||||
|
|
||||||
|
#define PPC_GP0_REGNUM 0 /* GPR register 0 */
|
||||||
|
#define PPC_TOC_REGNUM 2 /* TOC register */
|
||||||
|
#define PPC_PS_REGNUM 65 /* Processor (or machine) status (%msr) */
|
||||||
|
#define PPC_CR_REGNUM 66 /* Condition register */
|
||||||
|
#define PPC_LR_REGNUM 67 /* Link register */
|
||||||
|
#define PPC_CTR_REGNUM 68 /* Count register */
|
||||||
|
#define PPC_XER_REGNUM 69 /* Integer exception register */
|
||||||
|
#define PPC_MQ_REGNUM 70 /* Multiply/Divide extension register */
|
|
@ -35,15 +35,9 @@
|
||||||
#include "coff/internal.h" /* for libcoff.h */
|
#include "coff/internal.h" /* for libcoff.h */
|
||||||
#include "bfd/libcoff.h" /* for xcoff_data */
|
#include "bfd/libcoff.h" /* for xcoff_data */
|
||||||
|
|
||||||
/* Some important register numbers. Keep these in the same order as in
|
#include "elf-bfd.h"
|
||||||
/usr/mstsave.h `mstsave' structure, for easier processing. */
|
|
||||||
|
|
||||||
#define GP0_REGNUM 0 /* GPR register 0 */
|
#include "ppc-tdep.h"
|
||||||
#define TOC_REGNUM 2 /* TOC register */
|
|
||||||
#define PS_REGNUM 65 /* Processor (or machine) status (%msr) */
|
|
||||||
#define CR_REGNUM 66 /* Condition register */
|
|
||||||
#define LR_REGNUM 67 /* Link register */
|
|
||||||
#define CTR_REGNUM 68 /* Count register */
|
|
||||||
|
|
||||||
/* If the kernel has to deliver a signal, it pushes a sigcontext
|
/* If the kernel has to deliver a signal, it pushes a sigcontext
|
||||||
structure on the stack and then calls the signal handler, passing
|
structure on the stack and then calls the signal handler, passing
|
||||||
|
@ -89,6 +83,7 @@ struct reg
|
||||||
struct gdbarch_tdep
|
struct gdbarch_tdep
|
||||||
{
|
{
|
||||||
int wordsize; /* size in bytes of fixed-point word */
|
int wordsize; /* size in bytes of fixed-point word */
|
||||||
|
int osabi; /* OS / ABI from ELF header */
|
||||||
int *regoff; /* byte offsets in register arrays */
|
int *regoff; /* byte offsets in register arrays */
|
||||||
const struct reg *regs; /* from current variant */
|
const struct reg *regs; /* from current variant */
|
||||||
};
|
};
|
||||||
|
@ -157,7 +152,7 @@ struct frame_extra_info
|
||||||
CORE_ADDR initial_sp; /* initial stack pointer. */
|
CORE_ADDR initial_sp; /* initial stack pointer. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
void
|
||||||
rs6000_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
rs6000_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||||
{
|
{
|
||||||
fi->extra_info = (struct frame_extra_info *)
|
fi->extra_info = (struct frame_extra_info *)
|
||||||
|
@ -182,7 +177,7 @@ rs6000_init_extra_frame_info (int fromleaf, struct frame_info *fi)
|
||||||
not sure if it will be needed. The following function takes care of gpr's
|
not sure if it will be needed. The following function takes care of gpr's
|
||||||
and fpr's only. */
|
and fpr's only. */
|
||||||
|
|
||||||
static void
|
void
|
||||||
rs6000_frame_init_saved_regs (struct frame_info *fi)
|
rs6000_frame_init_saved_regs (struct frame_info *fi)
|
||||||
{
|
{
|
||||||
frame_get_saved_regs (fi, NULL);
|
frame_get_saved_regs (fi, NULL);
|
||||||
|
@ -205,7 +200,7 @@ rs6000_frame_args_address (struct frame_info *fi)
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
rs6000_saved_pc_after_call (struct frame_info *fi)
|
rs6000_saved_pc_after_call (struct frame_info *fi)
|
||||||
{
|
{
|
||||||
return read_register (LR_REGNUM);
|
return read_register (PPC_LR_REGNUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the destination of a branch/jump. Return -1 if not a branch. */
|
/* Calculate the destination of a branch/jump. Return -1 if not a branch. */
|
||||||
|
@ -243,7 +238,7 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
|
||||||
|
|
||||||
if (ext_op == 16) /* br conditional register */
|
if (ext_op == 16) /* br conditional register */
|
||||||
{
|
{
|
||||||
dest = read_register (LR_REGNUM) & ~3;
|
dest = read_register (PPC_LR_REGNUM) & ~3;
|
||||||
|
|
||||||
/* If we are about to return from a signal handler, dest is
|
/* If we are about to return from a signal handler, dest is
|
||||||
something like 0x3c90. The current frame is a signal handler
|
something like 0x3c90. The current frame is a signal handler
|
||||||
|
@ -262,13 +257,13 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety)
|
||||||
|
|
||||||
else if (ext_op == 528) /* br cond to count reg */
|
else if (ext_op == 528) /* br cond to count reg */
|
||||||
{
|
{
|
||||||
dest = read_register (CTR_REGNUM) & ~3;
|
dest = read_register (PPC_CTR_REGNUM) & ~3;
|
||||||
|
|
||||||
/* If we are about to execute a system call, dest is something
|
/* If we are about to execute a system call, dest is something
|
||||||
like 0x22fc or 0x3b00. Upon completion the system call
|
like 0x22fc or 0x3b00. Upon completion the system call
|
||||||
will return to the address in the link register. */
|
will return to the address in the link register. */
|
||||||
if (dest < TEXT_SEGMENT_BASE)
|
if (dest < TEXT_SEGMENT_BASE)
|
||||||
dest = read_register (LR_REGNUM) & ~3;
|
dest = read_register (PPC_LR_REGNUM) & ~3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -715,7 +710,7 @@ rs6000_pop_frame (void)
|
||||||
else
|
else
|
||||||
prev_sp = read_memory_addr (sp, wordsize);
|
prev_sp = read_memory_addr (sp, wordsize);
|
||||||
if (fdata.lr_offset == 0)
|
if (fdata.lr_offset == 0)
|
||||||
lr = read_register (LR_REGNUM);
|
lr = read_register (PPC_LR_REGNUM);
|
||||||
else
|
else
|
||||||
lr = read_memory_addr (prev_sp + fdata.lr_offset, wordsize);
|
lr = read_memory_addr (prev_sp + fdata.lr_offset, wordsize);
|
||||||
|
|
||||||
|
@ -766,7 +761,7 @@ rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun,
|
||||||
if (rs6000_find_toc_address_hook != NULL)
|
if (rs6000_find_toc_address_hook != NULL)
|
||||||
{
|
{
|
||||||
CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (fun);
|
CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (fun);
|
||||||
write_register (TOC_REGNUM, tocvalue);
|
write_register (PPC_TOC_REGNUM, tocvalue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,7 +984,7 @@ ran_out_of_registers_for_arguments:
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
ppc_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
|
ppc_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
|
||||||
{
|
{
|
||||||
write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
|
write_register (PPC_LR_REGNUM, CALL_DUMMY_ADDRESS ());
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,7 +1080,7 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
|
||||||
|
|
||||||
/* Determines whether the function FI has a frame on the stack or not. */
|
/* Determines whether the function FI has a frame on the stack or not. */
|
||||||
|
|
||||||
static int
|
int
|
||||||
rs6000_frameless_function_invocation (struct frame_info *fi)
|
rs6000_frameless_function_invocation (struct frame_info *fi)
|
||||||
{
|
{
|
||||||
CORE_ADDR func_start;
|
CORE_ADDR func_start;
|
||||||
|
@ -1119,7 +1114,7 @@ rs6000_frameless_function_invocation (struct frame_info *fi)
|
||||||
|
|
||||||
/* Return the PC saved in a frame */
|
/* Return the PC saved in a frame */
|
||||||
|
|
||||||
static CORE_ADDR
|
CORE_ADDR
|
||||||
rs6000_frame_saved_pc (struct frame_info *fi)
|
rs6000_frame_saved_pc (struct frame_info *fi)
|
||||||
{
|
{
|
||||||
CORE_ADDR func_start;
|
CORE_ADDR func_start;
|
||||||
|
@ -1152,7 +1147,7 @@ rs6000_frame_saved_pc (struct frame_info *fi)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fdata.lr_offset == 0)
|
if (fdata.lr_offset == 0)
|
||||||
return read_register (LR_REGNUM);
|
return read_register (PPC_LR_REGNUM);
|
||||||
|
|
||||||
return read_memory_addr (FRAME_CHAIN (fi) + fdata.lr_offset, wordsize);
|
return read_memory_addr (FRAME_CHAIN (fi) + fdata.lr_offset, wordsize);
|
||||||
}
|
}
|
||||||
|
@ -1223,12 +1218,12 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap)
|
||||||
/* If != 0, fdatap->cr_offset is the offset from the frame that holds
|
/* If != 0, fdatap->cr_offset is the offset from the frame that holds
|
||||||
the CR. */
|
the CR. */
|
||||||
if (fdatap->cr_offset != 0)
|
if (fdatap->cr_offset != 0)
|
||||||
fi->saved_regs[CR_REGNUM] = frame_addr + fdatap->cr_offset;
|
fi->saved_regs[PPC_CR_REGNUM] = frame_addr + fdatap->cr_offset;
|
||||||
|
|
||||||
/* If != 0, fdatap->lr_offset is the offset from the frame that holds
|
/* If != 0, fdatap->lr_offset is the offset from the frame that holds
|
||||||
the LR. */
|
the LR. */
|
||||||
if (fdatap->lr_offset != 0)
|
if (fdatap->lr_offset != 0)
|
||||||
fi->saved_regs[LR_REGNUM] = frame_addr + fdatap->lr_offset;
|
fi->saved_regs[PPC_LR_REGNUM] = frame_addr + fdatap->lr_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the address of a frame. This is the inital %sp value when the frame
|
/* Return the address of a frame. This is the inital %sp value when the frame
|
||||||
|
@ -1313,7 +1308,7 @@ frame_initial_stack_address (struct frame_info *fi)
|
||||||
/* In the case of the RS/6000, the frame's nominal address
|
/* In the case of the RS/6000, the frame's nominal address
|
||||||
is the address of a 4-byte word containing the calling frame's address. */
|
is the address of a 4-byte word containing the calling frame's address. */
|
||||||
|
|
||||||
static CORE_ADDR
|
CORE_ADDR
|
||||||
rs6000_frame_chain (struct frame_info *thisframe)
|
rs6000_frame_chain (struct frame_info *thisframe)
|
||||||
{
|
{
|
||||||
CORE_ADDR fp, fpp, lr;
|
CORE_ADDR fp, fpp, lr;
|
||||||
|
@ -1338,7 +1333,7 @@ rs6000_frame_chain (struct frame_info *thisframe)
|
||||||
else
|
else
|
||||||
fp = read_memory_addr ((thisframe)->frame, wordsize);
|
fp = read_memory_addr ((thisframe)->frame, wordsize);
|
||||||
|
|
||||||
lr = read_register (LR_REGNUM);
|
lr = read_register (PPC_LR_REGNUM);
|
||||||
if (lr == entry_point_address ())
|
if (lr == entry_point_address ())
|
||||||
if (fp != 0 && (fpp = read_memory_addr (fp, wordsize)) != 0)
|
if (fp != 0 && (fpp = read_memory_addr (fp, wordsize)) != 0)
|
||||||
if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
|
if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
|
||||||
|
@ -1500,7 +1495,7 @@ rs6000_store_return_value (struct type *type, char *valbuf)
|
||||||
TYPE_LENGTH (type));
|
TYPE_LENGTH (type));
|
||||||
else
|
else
|
||||||
/* Everything else is returned in GPR3 and up. */
|
/* Everything else is returned in GPR3 and up. */
|
||||||
write_register_bytes (REGISTER_BYTE (GP0_REGNUM + 3), valbuf,
|
write_register_bytes (REGISTER_BYTE (PPC_GP0_REGNUM + 3), valbuf,
|
||||||
TYPE_LENGTH (type));
|
TYPE_LENGTH (type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1909,6 +1904,84 @@ find_variant_by_arch (enum bfd_architecture arch, unsigned long mach)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
|
||||||
|
{
|
||||||
|
int *os_ident_ptr = obj;
|
||||||
|
const char *name;
|
||||||
|
unsigned int sectsize;
|
||||||
|
|
||||||
|
name = bfd_get_section_name (abfd, sect);
|
||||||
|
sectsize = bfd_section_size (abfd, sect);
|
||||||
|
if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
|
||||||
|
{
|
||||||
|
unsigned int name_length, data_length, note_type;
|
||||||
|
char *note = alloca (sectsize);
|
||||||
|
|
||||||
|
bfd_get_section_contents (abfd, sect, note,
|
||||||
|
(file_ptr) 0, (bfd_size_type) sectsize);
|
||||||
|
|
||||||
|
name_length = bfd_h_get_32 (abfd, note);
|
||||||
|
data_length = bfd_h_get_32 (abfd, note + 4);
|
||||||
|
note_type = bfd_h_get_32 (abfd, note + 8);
|
||||||
|
|
||||||
|
if (name_length == 4 && data_length == 16 && note_type == 1
|
||||||
|
&& strcmp (note + 12, "GNU") == 0)
|
||||||
|
{
|
||||||
|
int os_number = bfd_h_get_32 (abfd, note + 16);
|
||||||
|
|
||||||
|
/* The case numbers are from abi-tags in glibc */
|
||||||
|
switch (os_number)
|
||||||
|
{
|
||||||
|
case 0 :
|
||||||
|
*os_ident_ptr = ELFOSABI_LINUX;
|
||||||
|
break;
|
||||||
|
case 1 :
|
||||||
|
*os_ident_ptr = ELFOSABI_HURD;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
*os_ident_ptr = ELFOSABI_SOLARIS;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
internal_error (
|
||||||
|
"process_note_abi_sections: unknown OS number %d", os_number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return one of the ELFOSABI_ constants for BFDs representing ELF
|
||||||
|
executables. If it's not an ELF executable or if the OS/ABI couldn't
|
||||||
|
be determined, simply return -1. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_elfosabi (bfd *abfd)
|
||||||
|
{
|
||||||
|
int elfosabi = -1;
|
||||||
|
|
||||||
|
if (abfd != NULL && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
||||||
|
{
|
||||||
|
elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
|
||||||
|
|
||||||
|
/* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
|
||||||
|
that we're on a SYSV system. However, GNU/Linux uses a note section
|
||||||
|
to record OS/ABI info, but leaves e_ident[EI_OSABI] zero. So we
|
||||||
|
have to check the note sections too. */
|
||||||
|
if (elfosabi == 0)
|
||||||
|
{
|
||||||
|
bfd_map_over_sections (abfd,
|
||||||
|
process_note_abi_tag_sections,
|
||||||
|
&elfosabi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return elfosabi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Initialize the current architecture based on INFO. If possible, re-use an
|
/* Initialize the current architecture based on INFO. If possible, re-use an
|
||||||
|
@ -1923,25 +1996,40 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
{
|
{
|
||||||
struct gdbarch *gdbarch;
|
struct gdbarch *gdbarch;
|
||||||
struct gdbarch_tdep *tdep;
|
struct gdbarch_tdep *tdep;
|
||||||
int wordsize, fromexec, power, i, off;
|
int wordsize, from_xcoff_exec, from_elf_exec, power, i, off;
|
||||||
struct reg *regs;
|
struct reg *regs;
|
||||||
const struct variant *v;
|
const struct variant *v;
|
||||||
enum bfd_architecture arch;
|
enum bfd_architecture arch;
|
||||||
unsigned long mach;
|
unsigned long mach;
|
||||||
bfd abfd;
|
bfd abfd;
|
||||||
|
int osabi, sysv_abi;
|
||||||
|
|
||||||
fromexec = info.abfd && info.abfd->format == bfd_object &&
|
from_xcoff_exec = info.abfd && info.abfd->format == bfd_object &&
|
||||||
bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
|
bfd_get_flavour (info.abfd) == bfd_target_xcoff_flavour;
|
||||||
|
|
||||||
|
from_elf_exec = info.abfd && info.abfd->format == bfd_object &&
|
||||||
|
bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
|
||||||
|
|
||||||
|
sysv_abi = info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour;
|
||||||
|
|
||||||
|
osabi = get_elfosabi (info.abfd);
|
||||||
|
|
||||||
/* Check word size. If INFO is from a binary file, infer it from that,
|
/* Check word size. If INFO is from a binary file, infer it from that,
|
||||||
else use the previously-inferred size. */
|
else use the previously-inferred size. */
|
||||||
if (fromexec)
|
if (from_xcoff_exec)
|
||||||
{
|
{
|
||||||
if (xcoff_data (info.abfd)->xcoff64)
|
if (xcoff_data (info.abfd)->xcoff64)
|
||||||
wordsize = 8;
|
wordsize = 8;
|
||||||
else
|
else
|
||||||
wordsize = 4;
|
wordsize = 4;
|
||||||
}
|
}
|
||||||
|
else if (from_elf_exec)
|
||||||
|
{
|
||||||
|
if (elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
|
||||||
|
wordsize = 8;
|
||||||
|
else
|
||||||
|
wordsize = 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tdep = TDEP;
|
tdep = TDEP;
|
||||||
|
@ -1960,7 +2048,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
|
meaningful, because 64-bit CPUs can run in 32-bit mode. So, perform
|
||||||
separate word size check. */
|
separate word size check. */
|
||||||
tdep = gdbarch_tdep (arches->gdbarch);
|
tdep = gdbarch_tdep (arches->gdbarch);
|
||||||
if (tdep && tdep->wordsize == wordsize)
|
if (tdep && tdep->wordsize == wordsize && tdep->osabi == osabi)
|
||||||
return arches->gdbarch;
|
return arches->gdbarch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,7 +2060,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
- "set arch" trust blindly
|
- "set arch" trust blindly
|
||||||
- GDB startup useless but harmless */
|
- GDB startup useless but harmless */
|
||||||
|
|
||||||
if (!fromexec)
|
if (!from_xcoff_exec)
|
||||||
{
|
{
|
||||||
arch = info.bfd_architecture;
|
arch = info.bfd_architecture;
|
||||||
mach = info.bfd_arch_info->mach;
|
mach = info.bfd_arch_info->mach;
|
||||||
|
@ -1986,6 +2074,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
}
|
}
|
||||||
tdep = xmalloc (sizeof (struct gdbarch_tdep));
|
tdep = xmalloc (sizeof (struct gdbarch_tdep));
|
||||||
tdep->wordsize = wordsize;
|
tdep->wordsize = wordsize;
|
||||||
|
tdep->osabi = osabi;
|
||||||
gdbarch = gdbarch_alloc (&info, tdep);
|
gdbarch = gdbarch_alloc (&info, tdep);
|
||||||
power = arch == bfd_arch_rs6000;
|
power = arch == bfd_arch_rs6000;
|
||||||
|
|
||||||
|
@ -2060,16 +2149,17 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
set_gdbarch_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw);
|
set_gdbarch_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw);
|
||||||
|
|
||||||
set_gdbarch_extract_return_value (gdbarch, rs6000_extract_return_value);
|
set_gdbarch_extract_return_value (gdbarch, rs6000_extract_return_value);
|
||||||
set_gdbarch_push_arguments (gdbarch, rs6000_push_arguments);
|
|
||||||
|
if (sysv_abi)
|
||||||
|
set_gdbarch_push_arguments (gdbarch, ppc_sysv_abi_push_arguments);
|
||||||
|
else
|
||||||
|
set_gdbarch_push_arguments (gdbarch, rs6000_push_arguments);
|
||||||
|
|
||||||
set_gdbarch_store_struct_return (gdbarch, rs6000_store_struct_return);
|
set_gdbarch_store_struct_return (gdbarch, rs6000_store_struct_return);
|
||||||
set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value);
|
set_gdbarch_store_return_value (gdbarch, rs6000_store_return_value);
|
||||||
set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address);
|
set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address);
|
||||||
set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
|
set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
|
||||||
|
|
||||||
set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
|
|
||||||
set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
|
|
||||||
|
|
||||||
set_gdbarch_pop_frame (gdbarch, rs6000_pop_frame);
|
set_gdbarch_pop_frame (gdbarch, rs6000_pop_frame);
|
||||||
|
|
||||||
set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
|
set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
|
||||||
|
@ -2081,10 +2171,32 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
/* Not sure on this. FIXMEmgo */
|
/* Not sure on this. FIXMEmgo */
|
||||||
set_gdbarch_frame_args_skip (gdbarch, 8);
|
set_gdbarch_frame_args_skip (gdbarch, 8);
|
||||||
|
|
||||||
set_gdbarch_frameless_function_invocation (gdbarch, rs6000_frameless_function_invocation);
|
|
||||||
set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain);
|
|
||||||
set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
|
set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
|
||||||
set_gdbarch_frame_saved_pc (gdbarch, rs6000_frame_saved_pc);
|
if (osabi == ELFOSABI_LINUX)
|
||||||
|
{
|
||||||
|
set_gdbarch_frameless_function_invocation (gdbarch,
|
||||||
|
ppc_linux_frameless_function_invocation);
|
||||||
|
set_gdbarch_frame_chain (gdbarch, ppc_linux_frame_chain);
|
||||||
|
set_gdbarch_frame_saved_pc (gdbarch, ppc_linux_frame_saved_pc);
|
||||||
|
|
||||||
|
set_gdbarch_frame_init_saved_regs (gdbarch,
|
||||||
|
ppc_linux_frame_init_saved_regs);
|
||||||
|
set_gdbarch_init_extra_frame_info (gdbarch,
|
||||||
|
ppc_linux_init_extra_frame_info);
|
||||||
|
|
||||||
|
set_gdbarch_memory_remove_breakpoint (gdbarch,
|
||||||
|
ppc_linux_memory_remove_breakpoint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_gdbarch_frameless_function_invocation (gdbarch,
|
||||||
|
rs6000_frameless_function_invocation);
|
||||||
|
set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain);
|
||||||
|
set_gdbarch_frame_saved_pc (gdbarch, rs6000_frame_saved_pc);
|
||||||
|
|
||||||
|
set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs);
|
||||||
|
set_gdbarch_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info);
|
||||||
|
}
|
||||||
set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address);
|
set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address);
|
||||||
set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address);
|
set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address);
|
||||||
set_gdbarch_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call);
|
set_gdbarch_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call);
|
||||||
|
|
Loading…
Add table
Reference in a new issue