/* Parameters for target execution on an RS6000, for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1997
Free Software Foundation, Inc.
Contributed by IBM Corporation.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef __STDC__ /* Forward decls for prototypes */
+struct frame_info;
+struct type;
+struct value;
+#endif
/* Minimum possible text address in AIX */
/* Load segment of a given pc value. */
#define PC_LOAD_SEGMENT(PC) pc_load_segment_name(PC)
+extern char *pc_load_segment_name PARAMS ((CORE_ADDR));
/* AIX cc seems to get this right. */
#endif
extern int inferior_pid;
-/* setpgrp() messes up controling terminal. The other version of it
- requires libbsd.a. */
-#define setpgrp(XX,YY) setpgid (XX, YY)
-
/* We are missing register descriptions in the system header files. Sigh! */
struct regs {
};
-/* To be used by function_frame_info. */
+/* To be used by skip_prologue. */
-struct aix_framedata {
- int offset; /* # of bytes in gpr's and fpr's are saved */
+struct rs6000_framedata {
+ int offset; /* total size of frame --- the distance
+ by which we decrement sp to allocate
+ the frame */
int saved_gpr; /* smallest # of saved gpr */
int saved_fpr; /* smallest # of saved fpr */
int alloca_reg; /* alloca register number (frame ptr) */
char frameless; /* true if frameless functions. */
char nosavedpc; /* true if pc not saved. */
+ int gpr_offset; /* offset of saved gprs from prev sp */
+ int fpr_offset; /* offset of saved fprs from prev sp */
+ int lr_offset; /* offset of saved lr */
+ int cr_offset; /* offset of saved cr */
};
-void
-function_frame_info PARAMS ((CORE_ADDR, struct aix_framedata *));
-
/* Define the byte order of the machine. */
-#define TARGET_BYTE_ORDER BIG_ENDIAN
+#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN
/* AIX's assembler doesn't grok dollar signs in identifiers.
So we use dots instead. This item must be coordinated with G++. */
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
-#define SKIP_PROLOGUE(pc) pc = skip_prologue (pc)
+extern CORE_ADDR rs6000_skip_prologue PARAMS ((CORE_ADDR));
+#define SKIP_PROLOGUE(pc) (rs6000_skip_prologue (pc))
+
+extern CORE_ADDR skip_prologue PARAMS((CORE_ADDR, struct rs6000_framedata *));
+
/* If PC is in some function-call trampoline code, return the PC
where the function itself actually starts. If not, return NULL. */
#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc)
+extern CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR));
/* Number of trap signals we need to skip over, once the inferior process
starts running. */
once, when we are closing the current symbol table in end_symtab(). */
#define PROCESS_LINENUMBER_HOOK() aix_process_linenos ()
+extern void aix_process_linenos PARAMS ((void));
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
/* Stack grows downward. */
-#define INNER_THAN <
-
-#if 0
-/* No, we shouldn't use this. push_arguments() should leave stack in a
- proper alignment! */
-/* Stack has strict alignment. */
-
-#define STACK_ALIGN(ADDR) (((ADDR)+7)&-8)
-#endif
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
-/* This is how argumets pushed onto stack or passed in registers. */
+/* This is how arguments pushed onto stack or passed in registers.
+ Stack must be aligned on 64-bit boundaries when synthesizing
+ function calls. We don't need STACK_ALIGN, PUSH_ARGUMENTS will
+ handle it. */
#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
- sp = push_arguments(nargs, args, sp, struct_return, struct_addr)
-
-/* Sequence of bytes for breakpoint instruction. */
+ sp = push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))
+extern CORE_ADDR push_arguments PARAMS ((int, struct value **, CORE_ADDR,
+ int, CORE_ADDR));
-#define BREAKPOINT {0x7d, 0x82, 0x10, 0x08}
+/* BREAKPOINT_FROM_PC uses the program counter value to determine the
+ breakpoint that should be used */
+extern breakpoint_from_pc_fn rs6000_breakpoint_from_pc;
+#define BREAKPOINT_FROM_PC(pcptr, lenptr) rs6000_breakpoint_from_pc (pcptr, lenptr)
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
#define DECR_PC_AFTER_BREAK 0
-/* Nonzero if instruction at PC is a return instruction. */
-/* Allow any of the return instructions, including a trapv and a return
- from interrupt. */
-
-#define ABOUT_TO_RETURN(pc) \
- ((read_memory_integer (pc, 4) & 0xfe8007ff) == 0x4e800020)
-
/* 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
-/* Number of machine registers */
-
-#define NUM_REGS 71
-/* Initializer for an array of names of registers.
- There should be NUM_REGS strings in this initializer. */
+/* Return the name of register number REG. This may return "" to
+ indicate a register number that's not used on this variant.
+ (Register numbers may be sparse for consistency between variants.) */
+#define REGISTER_NAME(reg) (rs6000_register_name(reg))
+extern char *rs6000_register_name (int reg);
-#define REGISTER_NAMES \
- {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10","r11","r12","r13","r14","r15", \
- "r16","r17","r18","r19","r20","r21","r22","r23", \
- "r24","r25","r26","r27","r28","r29","r30","r31", \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10","f11","f12","f13","f14","f15", \
- "f16","f17","f18","f19","f20","f21","f22","f23", \
- "f24","f25","f26","f27","f28","f29","f30","f31", \
- "pc", "ps", "cnd", "lr", "cnt", "xer", "mq" }
+/* Number of machine registers */
+#define NUM_REGS 183
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
#define FPLAST_REGNUM 63 /* Last floating point register */
/* Special purpose registers... */
-/* P.S. keep these in the same order as in /usr/mstsave.h `mstsave' structure, for
- easier processing */
+/* P.S. keep these in the same order as in /usr/mstsave.h `mstsave'
+ structure, for easier processing */
-#define PC_REGNUM 64 /* Program counter (instruction address %iar) */
+#define PC_REGNUM 64 /* Program counter (instruction address %iar)*/
#define PS_REGNUM 65 /* Processor (or machine) status (%msr) */
#define CR_REGNUM 66 /* Condition register */
#define LR_REGNUM 67 /* Link register */
#define XER_REGNUM 69 /* Fixed point exception registers */
#define MQ_REGNUM 70 /* Multiply/quotient register */
-#define FIRST_SP_REGNUM 64 /* first special register number */
-#define LAST_SP_REGNUM 70 /* last special register number */
+/* These #defines are used to parse core files and talk to ptrace, so they
+ must remain fixed. */
+#define FIRST_UISA_SP_REGNUM 64 /* first special register number */
+#define LAST_UISA_SP_REGNUM 70 /* last special register number */
+
+/* This is the offset in REG_NAMES at which the `set processor'
+ command starts plugging in its names. */
+#define FIRST_VARIANT_REGISTER 66
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'.
-
- 32 4-byte gpr's
- 32 8-byte fpr's
- 7 4-byte special purpose registers,
-
- total 416 bytes. Keep some extra space for now, in case to add more. */
-
-#define REGISTER_BYTES 420
+ 32 4-byte gpr's
+ 32 8-byte fpr's
+ 7 4-byte UISA special purpose registers,
+ 16 4-byte segment registers,
+ 32 4-byte standard OEA special-purpose registers,
+ and up to 64 4-byte non-standard OEA special purpose regs.
+ total: (+ (* 32 4) (* 32 8) (* 7 4) (* 16 4) (* 32 4) (* 64 4)) 860 bytes
+ Keep some extra space for now, in case to add more. */
+#define REGISTER_BYTES 880
/* Index within `registers' of the first byte of the space for
/* Number of bytes of storage in the actual machine representation
for register N. */
/* Note that the unsigned cast here forces the result of the
- subtractiion to very high positive values if N < FP0_REGNUM */
+ subtraction to very high positive values if N < FP0_REGNUM */
#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 32 ? 8 : 4)
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
extract_return_value(TYPE,REGBUF,VALBUF)
+extern void extract_return_value PARAMS ((struct type *, char [], char *));
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
is the address of a 4-byte word containing the calling frame's address. */
#define FRAME_CHAIN(thisframe) rs6000_frame_chain (thisframe)
-#ifdef __STDC__
-struct frame_info;
-#endif
CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *));
/* Define other aspects of the stack frame. */
does not, FRAMELESS is set to 1, else 0. */
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
- FRAMELESS = frameless_function_invocation (FI, 0)
-
-/* Functions calling alloca() change the value of the stack pointer. We
- need to use initial stack pointer (which is saved in r31 by gcc) in
- such cases. If a compiler emits traceback table, then we should use the
- alloca register specified in traceback table. FIXME. */
-/* Also, it is a good idea to cache information about frame's saved registers
- in the frame structure to speed things up. See tm-m88k.h. FIXME. */
+ FRAMELESS = frameless_function_invocation (FI)
-#define EXTRA_FRAME_INFO \
- CORE_ADDR initial_sp; /* initial stack pointer. */ \
- struct frame_saved_regs *cache_fsr; /* saved registers */
+extern int frameless_function_invocation PARAMS((struct frame_info *));
#define INIT_FRAME_PC_FIRST(fromleaf, prev) \
prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \
prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
#define INIT_FRAME_PC(fromleaf, prev) /* nothing */
-#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \
- fi->initial_sp = 0; \
- fi->cache_fsr = 0; \
- if (fi->next != (CORE_ADDR)0 \
- && fi->pc < TEXT_SEGMENT_BASE) \
- /* We're in get_prev_frame_info */ \
- /* and this is a special signal frame. */ \
- /* (fi->pc will be some low address in the kernel, */ \
- /* to which the signal handler returns). */
- fi->signal_handler_caller = 1;
+extern void rs6000_init_extra_frame_info (int fromleaf, struct frame_info *);
+#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) rs6000_init_extra_frame_info (fromleaf, fi)
/* If the kernel has to deliver a signal, it pushes a sigcontext
structure on the stack and then calls the signal handler, passing
frame.
The following constants were determined by experimentation on AIX 3.2. */
#define SIG_FRAME_PC_OFFSET 96
+#define SIG_FRAME_LR_OFFSET 108
#define SIG_FRAME_FP_OFFSET 284
-/* Frameless function invocation in IBM RS/6000 is sometimes
- half-done. It perfectly sets up a new frame, e.g. a new frame (in
- fact stack) pointer, etc, but it doesn't save the %pc. We call
- frameless_function_invocation to tell us how to get the %pc. */
+/* Default offset from SP where the LR is stored */
+#define DEFAULT_LR_SAVE 8
-#define FRAME_SAVED_PC(FRAME) \
- (frameless_function_invocation (FRAME, 1) \
- ? SAVED_PC_AFTER_CALL (FRAME) \
- : (FRAME)->signal_handler_caller \
- ? read_memory_integer ((FRAME)->frame + SIG_FRAME_PC_OFFSET, 4) \
- : read_memory_integer (rs6000_frame_chain (FRAME) + 8, 4))
+/* Return saved PC from a frame */
+#define FRAME_SAVED_PC(FRAME) frame_saved_pc (FRAME)
-#define FRAME_ARGS_ADDRESS(FI) \
- (((struct frame_info*)(FI))->initial_sp ? \
- ((struct frame_info*)(FI))->initial_sp : \
- frame_initial_stack_address (FI))
+extern unsigned long frame_saved_pc PARAMS ((struct frame_info *));
+
+extern CORE_ADDR rs6000_frame_args_address PARAMS ((struct frame_info *));
+#define FRAME_ARGS_ADDRESS(FI) rs6000_frame_args_address (FI)
#define FRAME_LOCALS_ADDRESS(FI) FRAME_ARGS_ADDRESS(FI)
not sure if it will be needed. The following macro takes care of gpr's
and fpr's only. */
-#define FRAME_FIND_SAVED_REGS(FRAME_INFO, FRAME_SAVED_REGS) \
-{ \
- int ii; \
- CORE_ADDR frame_addr, func_start; \
- struct aix_framedata fdata; \
- \
- /* find the start of the function and collect info about its frame. */\
- \
- func_start = get_pc_function_start ((FRAME_INFO)->pc) + FUNCTION_START_OFFSET; \
- function_frame_info (func_start, &fdata); \
- memset (&(FRAME_SAVED_REGS), '\0', sizeof (FRAME_SAVED_REGS)); \
- \
- /* if there were any saved registers, figure out parent's stack pointer. */ \
- frame_addr = 0; \
- /* the following is true only if the frame doesn't have a call to alloca(), \
- FIXME. */ \
- if (fdata.saved_fpr >= 0 || fdata.saved_gpr >= 0) { \
- if ((FRAME_INFO)->prev && (FRAME_INFO)->prev->frame) \
- frame_addr = (FRAME_INFO)->prev->frame; \
- else \
- frame_addr = read_memory_integer ((FRAME_INFO)->frame, 4); \
- } \
- \
- /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All fpr's \
- from saved_fpr to fp31 are saved right underneath caller stack pointer, \
- starting from fp31 first. */ \
- \
- if (fdata.saved_fpr >= 0) { \
- for (ii=31; ii >= fdata.saved_fpr; --ii) \
- (FRAME_SAVED_REGS).regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8); \
- frame_addr -= (32 - fdata.saved_fpr) * 8; \
- } \
- \
- /* if != -1, fdata.saved_gpr is the smallest number of saved_gpr. All gpr's \
- from saved_gpr to gpr31 are saved right under saved fprs, starting \
- from r31 first. */ \
- \
- if (fdata.saved_gpr >= 0) \
- for (ii=31; ii >= fdata.saved_gpr; --ii) \
- (FRAME_SAVED_REGS).regs [ii] = frame_addr - ((32 - ii) * 4); \
-}
+extern void rs6000_frame_init_saved_regs PARAMS ((struct frame_info *));
+#define FRAME_INIT_SAVED_REGS(FI) rs6000_frame_init_saved_regs (FI)
-\f
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
/* Change these names into rs6k_{push, pop}_frame(). FIXMEmgo. */
#define PUSH_DUMMY_FRAME push_dummy_frame ()
+extern void push_dummy_frame PARAMS ((void));
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME pop_frame ()
+extern void pop_frame PARAMS ((void));
/* This sequence of words is the instructions:
#define CALL_DUMMY_START_OFFSET 16
-/* 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, using_gcc) \
- fix_call_dummy(dummyname, pc, fun, nargs, type)
-
-/* Usually a function pointer's representation is simply the address of
- the function. On the RS/6000 however, a function pointer is represented
- by a pointer to a TOC entry. This TOC entry contains three words,
- the first word is the address of the function, the second word is the
- TOC pointer (r2), and the third word is the static chain value.
- Throughout GDB it is currently assumed that a function pointer contains
- the address of the function, which is not easy to fix.
- In addition, the conversion of a function address to a function
- pointer would require allocation of a TOC entry in the inferior's
- memory space, with all its drawbacks.
- To be able to call C++ virtual methods in the inferior (which are called
- via function pointers), find_function_addr uses this macro to
- get the function address from a function pointer. */
-#define CONVERT_FROM_FUNC_PTR_ADDR(ADDR) read_memory_integer (ADDR, 4)
+/* 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) \
+ rs6000_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
+extern void rs6000_fix_call_dummy PARAMS ((char *, CORE_ADDR, CORE_ADDR,
+ int, struct value **,
+ struct type *, int));
+
+/* Hook in rs6000-tdep.c for determining the TOC address when
+ calling functions in the inferior. */
+extern CORE_ADDR (*find_toc_address_hook) PARAMS ((CORE_ADDR));
+
+/* xcoffread.c provides a function to determine the TOC offset
+ for a given object file.
+ It is used under native AIX configurations for determining the
+ TOC address when calling functions in the inferior. */
+#ifdef __STDC__
+struct objfile;
+#endif
+extern CORE_ADDR get_toc_offset PARAMS ((struct objfile *));
+
+/* Usually a function pointer's representation is simply the address
+ of the function. On the RS/6000 however, a function pointer is
+ represented by a pointer to a TOC entry. This TOC entry contains
+ three words, the first word is the address of the function, the
+ second word is the TOC pointer (r2), and the third word is the
+ static chain value. Throughout GDB it is currently assumed that a
+ function pointer contains the address of the function, which is not
+ easy to fix. In addition, the conversion of a function address to
+ a function pointer would require allocation of a TOC entry in the
+ inferior's memory space, with all its drawbacks. To be able to
+ call C++ virtual methods in the inferior (which are called via
+ function pointers), find_function_addr uses this macro to get the
+ function address from a function pointer. */
+
+#define CONVERT_FROM_FUNC_PTR_ADDR(ADDR) \
+ (is_magic_function_pointer (ADDR) ? read_memory_integer (ADDR, 4) : (ADDR))
+extern int is_magic_function_pointer PARAMS ((CORE_ADDR));
/* Flag for machine-specific stuff in shared files. FIXME */
#define IBM6000_TARGET
/* RS6000/AIX does not support PT_STEP. Has to be simulated. */
-#define NO_SINGLE_STEP
+#define SOFTWARE_SINGLE_STEP_P 1
+extern void rs6000_software_single_step PARAMS ((unsigned int, int));
+#define SOFTWARE_SINGLE_STEP(sig,bp_p) rs6000_software_single_step (sig, bp_p)
+
+/* If the current gcc for for this target does not produce correct debugging
+ information for float parameters, both prototyped and unprototyped, then
+ define this macro. This forces gdb to always assume that floats are
+ passed as doubles and then converted in the callee.
+
+ For the PowerPC, it appears that the debug info marks the parameters as
+ floats regardless of whether the function is prototyped, but the actual
+ values are always passed in as doubles. Thus by setting this to 1, both
+ types of calls will work. */
+
+#define COERCE_FLOAT_TO_DOUBLE 1