mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
CARP: Convert macro definitions of USE_STRUCT_CONVENTION into target
specific functions.
This commit is contained in:
parent
554eb429e4
commit
98760eab33
@ -1,3 +1,30 @@
|
||||
Mon Nov 23 10:47:54 1998 Andrew Cagney <cagney@chook.cygnus.com>
|
||||
|
||||
* config/sh/tm-sh.h, config/mn10200/tm-mn10200.h,
|
||||
config/m32r/tm-m32r.h, config/arm/tm-arm.h, config/i960/tm-i960.h,
|
||||
config/gould/tm-np1.h, config/d10v/tm-d10v.h,
|
||||
config/v850/tm-v850.h, config/pa/tm-hppa.h, config/a29k/tm-a29k.h,
|
||||
config/mn10300/tm-mn10300.h, config/mips/tm-mips.h
|
||||
(USE_STRUCT_CONVENTION): Cleanup, define macro as function.
|
||||
|
||||
* sh-tdep.c (sh_use_struct_convention), mn10200-tdep.c
|
||||
(mn10200_use_struct_convention), i960-tdep.c
|
||||
(i960_use_struct_convention), gould-tdep.c
|
||||
(gould_use_struct_convention), d10v-tdep.c
|
||||
(d10v_use_struct_convention), v850-tdep.c
|
||||
(v850_use_struct_convention), hppa-tdep.c
|
||||
(hpha_use_struct_convention), m32r-tdep.c
|
||||
(m32r_use_struct_convention), arm-tdep.c
|
||||
(arm_use_struct_convention), mn10300-tdep.c
|
||||
(mn10300_use_struct_convention), a29k-tdep.c
|
||||
(a29k_use_struct_convention), mips-tdep.c
|
||||
(mips_use_struct_convention): New functions
|
||||
|
||||
* value.h, values.c (generic_use_struct_convention): New function,
|
||||
replace macro.
|
||||
* values.c (USE_STRUCT_CONVENTION): Macro defaults to function
|
||||
generic_use_struct_convention.
|
||||
|
||||
Sat Nov 21 17:15:40 1998 Philippe De Muyter <phdm@macqel.be>
|
||||
|
||||
* breakpoint.c (bpstat_stop_status): Do not increment hit_count
|
||||
|
@ -41,6 +41,18 @@ extern CORE_ADDR text_start; /* FIXME, kludge... */
|
||||
|
||||
static CORE_ADDR rstack_high_address = UINT_MAX;
|
||||
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
/* On the a29k objects over 16 words require the caller to allocate space. */
|
||||
int
|
||||
a29k_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH (type) > 16 * 4);
|
||||
}
|
||||
|
||||
|
||||
/* Structure to hold cached info about function prologues. */
|
||||
|
||||
struct prologue_info
|
||||
|
@ -27,6 +27,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "gdb_string.h"
|
||||
#include "coff/internal.h" /* Internal format of COFF symbols in BFD */
|
||||
|
||||
/*
|
||||
The following macros are actually wrong. Neither arm nor thumb can
|
||||
or should set the lsb on addr.
|
||||
The thumb addresses are mod 2, so (addr & 2) would be a good heuristic
|
||||
to use when checking for thumb (see arm_pc_is_thumb() below).
|
||||
Unfortunately, something else depends on these (incorrect) macros, so
|
||||
fixing them actually breaks gdb. I didn't have time to investigate. Z.R.
|
||||
*/
|
||||
/* Thumb function addresses are odd (bit 0 is set). Here are some
|
||||
macros to test, set, or clear bit 0 of addresses. */
|
||||
#define IS_THUMB_ADDR(addr) ((addr) & 1)
|
||||
@ -38,6 +46,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define ROUND_DOWN(n,a) ((n) & ~((a) - 1))
|
||||
#define ROUND_UP(n,a) (((n) + (a) - 1) & ~((a) - 1))
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
/* The system C compiler uses a similar structure return convention to gcc */
|
||||
int
|
||||
arm_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH (type) > 4);
|
||||
}
|
||||
|
||||
/* Set to true if the 32-bit mode is in use. */
|
||||
|
||||
int arm_apcs_32 = 1;
|
||||
@ -838,6 +856,15 @@ arm_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||
int float_argreg;
|
||||
int argnum;
|
||||
int stack_offset;
|
||||
struct stack_arg {
|
||||
char *val;
|
||||
int len;
|
||||
int offset;
|
||||
};
|
||||
struct stack_arg *stack_args =
|
||||
(struct stack_arg*)alloca (nargs * sizeof (struct stack_arg));
|
||||
int nstack_args = 0;
|
||||
|
||||
|
||||
/* Initialize the integer and float register pointers. */
|
||||
argreg = A1_REGNUM;
|
||||
@ -852,10 +879,9 @@ arm_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||
This leaves room for the "home" area for register parameters. */
|
||||
stack_offset = REGISTER_SIZE * 4;
|
||||
|
||||
/* Now load as many as possible of the first arguments into
|
||||
registers, and push the rest onto the stack. Loop thru args
|
||||
from first to last. */
|
||||
for (argnum = 0; argnum < nargs; argnum++)
|
||||
/* Process args from left to right. Store as many as allowed in
|
||||
registers, save the rest to be pushed on the stack */
|
||||
for(argnum = 0; argnum < nargs; argnum++)
|
||||
{
|
||||
char * val;
|
||||
value_ptr arg = args[argnum];
|
||||
@ -864,6 +890,7 @@ arm_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||
int len = TYPE_LENGTH (arg_type);
|
||||
enum type_code typecode = TYPE_CODE (arg_type);
|
||||
CORE_ADDR regval;
|
||||
int newarg;
|
||||
|
||||
val = (char *) VALUE_CONTENTS (arg);
|
||||
|
||||
@ -899,30 +926,35 @@ arm_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||
registers and stack. */
|
||||
while (len > 0)
|
||||
{
|
||||
int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
|
||||
|
||||
if (argreg <= ARM_LAST_ARG_REGNUM)
|
||||
{
|
||||
int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE;
|
||||
regval = extract_address (val, partial_len);
|
||||
|
||||
/* It's a simple argument being passed in a general
|
||||
register. */
|
||||
write_register (argreg, regval);
|
||||
argreg++;
|
||||
len -= partial_len;
|
||||
val += partial_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write this portion of the argument to the stack. */
|
||||
partial_len = len;
|
||||
sp -= partial_len;
|
||||
write_memory (sp, val, partial_len);
|
||||
/* keep for later pushing */
|
||||
stack_args[nstack_args].val = val;
|
||||
stack_args[nstack_args++].len = len;
|
||||
break;
|
||||
}
|
||||
|
||||
len -= partial_len;
|
||||
val += partial_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* now do the real stack pushing, process args right to left */
|
||||
while(nstack_args--)
|
||||
{
|
||||
sp -= stack_args[nstack_args].len;
|
||||
write_memory(sp, stack_args[nstack_args].val,
|
||||
stack_args[nstack_args].len);
|
||||
}
|
||||
|
||||
/* Return adjusted stack pointer. */
|
||||
return sp;
|
||||
@ -1436,27 +1468,39 @@ arm_breakpoint_from_pc (pcptr, lenptr)
|
||||
CORE_ADDR * pcptr;
|
||||
int * lenptr;
|
||||
{
|
||||
CORE_ADDR sp = read_sp();
|
||||
|
||||
if (arm_pc_is_thumb (*pcptr) || arm_pc_is_thumb_dummy (*pcptr))
|
||||
{
|
||||
static char thumb_breakpoint[] = THUMB_BREAKPOINT;
|
||||
|
||||
*pcptr = UNMAKE_THUMB_ADDR (*pcptr);
|
||||
*lenptr = sizeof (thumb_breakpoint);
|
||||
|
||||
return thumb_breakpoint;
|
||||
if (TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
{
|
||||
static char thumb_breakpoint[] = THUMB_BE_BREAKPOINT;
|
||||
*pcptr = UNMAKE_THUMB_ADDR (*pcptr);
|
||||
*lenptr = sizeof (thumb_breakpoint);
|
||||
return thumb_breakpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
static char thumb_breakpoint[] = THUMB_LE_BREAKPOINT;
|
||||
*pcptr = UNMAKE_THUMB_ADDR (*pcptr);
|
||||
*lenptr = sizeof (thumb_breakpoint);
|
||||
return thumb_breakpoint;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static char arm_breakpoint[] = ARM_BREAKPOINT;
|
||||
|
||||
*lenptr = sizeof (arm_breakpoint);
|
||||
|
||||
return arm_breakpoint;
|
||||
if (TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
{
|
||||
static char arm_breakpoint[] = ARM_BE_BREAKPOINT;
|
||||
*lenptr = sizeof (arm_breakpoint);
|
||||
return arm_breakpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
static char arm_breakpoint[] = ARM_LE_BREAKPOINT;
|
||||
*lenptr = sizeof (arm_breakpoint);
|
||||
return arm_breakpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return non-zero if the PC is inside a call thunk (aka stub or trampoline).
|
||||
This implements the IN_SOLIB_CALL_TRAMPOLINE macro. */
|
||||
|
||||
|
@ -281,7 +281,8 @@ CORE_ADDR skip_prologue ();
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
/* On the a29k objects over 16 words require the caller to allocate space. */
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 16 * 4)
|
||||
extern use_struct_convention_fn a29k_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) a29k_use_struct_convention (gcc_p, type)
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
a function return value of type TYPE, and copy that, in virtual format,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definitions to make GDB target for an ARM under RISCiX (4.3bsd).
|
||||
Copyright 1986, 1987, 1989, 1991, 1993 Free Software Foundation, Inc.
|
||||
/* Definitions to make GDB target for an ARM
|
||||
Copyright 1986, 1987, 1989, 1991, 1993, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -15,17 +15,36 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define TARGET_BYTE_ORDER LITTLE_ENDIAN
|
||||
#ifdef __STDC__ /* Forward decls for prototypes */
|
||||
struct type;
|
||||
struct value;
|
||||
#endif
|
||||
|
||||
#define TARGET_BYTE_ORDER_SELECTABLE
|
||||
|
||||
/* IEEE format floating point */
|
||||
|
||||
#define IEEE_FLOAT
|
||||
|
||||
/* I provide my own xfer_core_file to cope with shared libraries */
|
||||
/* FIXME: may need a floatformat_ieee_double_bigbyte_littleword format for
|
||||
BIG_ENDIAN use. -fnf */
|
||||
|
||||
#define XFER_CORE_FILE
|
||||
#define TARGET_DOUBLE_FORMAT (target_byte_order == BIG_ENDIAN \
|
||||
? &floatformat_ieee_double_big \
|
||||
: &floatformat_ieee_double_littlebyte_bigword)
|
||||
|
||||
/* When reading symbols, we need to zap the low bit of the address, which
|
||||
may be set to 1 for Thumb functions. */
|
||||
|
||||
#define SMASH_TEXT_ADDRESS(addr) ((addr) &= ~0x1)
|
||||
|
||||
/* Remove useless bits from addresses in a running program. */
|
||||
|
||||
CORE_ADDR arm_addr_bits_remove PARAMS ((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. */
|
||||
@ -35,14 +54,18 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* Advance PC across any function entry prologue instructions
|
||||
to reach some "real" code. */
|
||||
|
||||
#define SKIP_PROLOGUE(pc) pc = skip_prologue(pc)
|
||||
extern CORE_ADDR arm_skip_prologue PARAMS ((CORE_ADDR pc));
|
||||
|
||||
#define SKIP_PROLOGUE(pc) { 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) (read_register (LR_REGNUM) & 0x03fffffc)
|
||||
#define SAVED_PC_AFTER_CALL(frame) arm_saved_pc_after_call (frame)
|
||||
struct frame_info;
|
||||
extern CORE_ADDR arm_saved_pc_after_call PARAMS ((struct frame_info *));
|
||||
|
||||
/* I don't know the real values for these. */
|
||||
#define TARGET_UPAGES UPAGES
|
||||
@ -58,7 +81,30 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Sequence of bytes for breakpoint instruction. */
|
||||
|
||||
#define BREAKPOINT {0x00,0x00,0x18,0xef} /* BKPT_SWI from <sys/ptrace.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. */
|
||||
|
||||
#define ARM_LE_BREAKPOINT {0x00,0x00,0x18,0xef} /* BKPT_SWI from <sys/ptrace.h> */
|
||||
#define ARM_BE_BREAKPOINT {0xef,0x18,0x00,0x00} /* BKPT_SWI from <sys/ptrace.h> */
|
||||
#define THUMB_LE_BREAKPOINT {0x18,0xdf} /* swi 24 */
|
||||
#define THUMB_BE_BREAKPOINT {0xdf,0x18} /* swi 24 */
|
||||
|
||||
/* The following has been superseded by BREAKPOINT_FOR_PC, but
|
||||
is defined merely to keep mem-break.c happy. */
|
||||
#define LITTLE_BREAKPOINT ARM_LE_BREAKPOINT
|
||||
#define BIG_BREAKPOINT ARM_BE_BREAKPOINT
|
||||
|
||||
/* 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. */
|
||||
|
||||
unsigned char * arm_breakpoint_from_pc PARAMS ((CORE_ADDR * pcptr, int * lenptr));
|
||||
#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
|
||||
@ -72,20 +118,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
((read_memory_integer(pc, 4) & 0x0fffffff == 0x01b0f00e) || \
|
||||
(read_memory_integer(pc, 4) & 0x0ffff800 == 0x09eba800))
|
||||
|
||||
/* Return 1 if P points to an invalid floating point value.
|
||||
LEN is the length in bytes. */
|
||||
|
||||
#define INVALID_FLOAT(p, len) 0
|
||||
|
||||
/* code to execute to print interesting information about the
|
||||
* floating point processor (if any)
|
||||
* No need to define if there is nothing to do.
|
||||
*/
|
||||
#define FLOAT_INFO { arm_float_info (); }
|
||||
|
||||
/* Say how long (ordinary) registers are. */
|
||||
/* 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_TYPE long
|
||||
#define REGISTER_SIZE 4
|
||||
|
||||
/* Number of machine registers */
|
||||
|
||||
@ -97,11 +140,32 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* Initializer for an array of names of registers.
|
||||
There should be NUM_REGS strings in this initializer. */
|
||||
|
||||
#define REGISTER_NAMES \
|
||||
{ "a1", "a2", "a3", "a4", \
|
||||
"v1", "v2", "v3", "v4", "v5", "v6", \
|
||||
"sl", "fp", "ip", "sp", "lr", "pc", \
|
||||
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "fps", "ps" }
|
||||
#define ORIGINAL_REGISTER_NAMES \
|
||||
{ "a1", "a2", "a3", "a4", /* 0 1 2 3 */ \
|
||||
"v1", "v2", "v3", "v4", /* 4 5 6 7 */ \
|
||||
"v5", "v6", "sl", "fp", /* 8 9 10 11 */ \
|
||||
"ip", "sp", "lr", "pc", /* 12 13 14 15 */ \
|
||||
"f0", "f1", "f2", "f3", /* 16 17 18 19 */ \
|
||||
"f4", "f5", "f6", "f7", /* 20 21 22 23 */ \
|
||||
"fps","ps" } /* 24 25 */
|
||||
|
||||
/* These names are the ones which gcc emits, and
|
||||
I find them less confusing. Toggle between them
|
||||
using the `othernames' command. */
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
{ "r0", "r1", "r2", "r3", /* 0 1 2 3 */ \
|
||||
"r4", "r5", "r6", "r7", /* 4 5 6 7 */ \
|
||||
"r8", "r9", "sl", "fp", /* 8 9 10 11 */ \
|
||||
"ip", "sp", "lr", "pc", /* 12 13 14 15 */ \
|
||||
"f0", "f1", "f2", "f3", /* 16 17 18 19 */ \
|
||||
"f4", "f5", "f6", "f7", /* 20 21 22 23 */ \
|
||||
"fps","ps" } /* 24 25 */
|
||||
|
||||
#define REGISTER_NAMES ADDITIONAL_REGISTER_NAMES
|
||||
#ifndef REGISTER_NAMES
|
||||
#define REGISTER_NAMES ORIGINAL_REGISTER_NAMES
|
||||
#endif
|
||||
|
||||
/* Register numbers of various important registers.
|
||||
Note that some of these values are "real" register numbers,
|
||||
@ -110,15 +174,50 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
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'. */
|
||||
@ -143,7 +242,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Largest value REGISTER_RAW_SIZE can have. */
|
||||
|
||||
#define MAX_REGISTER_RAW_SIZE 12
|
||||
#define MAX_REGISTER_RAW_SIZE 12
|
||||
|
||||
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
|
||||
|
||||
@ -151,27 +250,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Nonzero if register N requires conversion
|
||||
from raw format to virtual format. */
|
||||
|
||||
#define REGISTER_CONVERTIBLE(N) ((unsigned)(N) - F0_REGNUM < 8)
|
||||
|
||||
/* Convert data from raw format for register REGNUM
|
||||
to virtual format for register REGNUM. */
|
||||
/* Convert data from raw format for register REGNUM in buffer FROM
|
||||
to virtual format with type TYPE in buffer TO. */
|
||||
|
||||
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
|
||||
if (REGISTER_CONVERTIBLE(REGNUM)) \
|
||||
convert_from_extended((FROM), (TO)); \
|
||||
else \
|
||||
memcpy ((TO), (FROM), 4);
|
||||
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
|
||||
{ \
|
||||
double val; \
|
||||
convert_from_extended ((FROM), & val); \
|
||||
store_floating ((TO), TYPE_LENGTH (TYPE), val); \
|
||||
}
|
||||
|
||||
/* Convert data from virtual format for register REGNUM
|
||||
to raw format for register REGNUM. */
|
||||
|
||||
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
|
||||
if (REGISTER_CONVERTIBLE(REGNUM)) \
|
||||
convert_to_extended((FROM), (TO)); \
|
||||
else \
|
||||
memcpy ((TO), (FROM), 4);
|
||||
/* Convert data from virtual format with type TYPE in buffer FROM
|
||||
to raw format for register REGNUM in buffer TO. */
|
||||
|
||||
#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
|
||||
{ \
|
||||
double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
|
||||
convert_to_extended (&val, (TO)); \
|
||||
}
|
||||
/* Return the GDB type object for the "standard" data type
|
||||
of data in register N. */
|
||||
|
||||
@ -179,8 +277,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
(((unsigned)(N) - F0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
|
||||
|
||||
/* The system C compiler uses a similar structure return convention to gcc */
|
||||
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 4)
|
||||
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. */
|
||||
@ -194,7 +292,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||
if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
|
||||
convert_from_extended(REGBUF + REGISTER_BYTE (F0_REGNUM), VALBUF); \
|
||||
convert_from_extended (REGBUF + REGISTER_BYTE (F0_REGNUM), VALBUF); \
|
||||
else \
|
||||
memcpy (VALBUF, REGBUF, TYPE_LENGTH (TYPE))
|
||||
|
||||
@ -204,7 +302,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
|
||||
if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) { \
|
||||
char _buf[MAX_REGISTER_RAW_SIZE]; \
|
||||
convert_to_extended(VALBUF, _buf); \
|
||||
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))
|
||||
@ -221,6 +319,25 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define VARIABLES_INSIDE_BLOCK(desc, gcc_p) (!(gcc_p))
|
||||
|
||||
|
||||
/* Define other aspects of the stack frame.
|
||||
We keep the offsets of all saved registers, 'cause we need 'em a lot!
|
||||
We also keep the current size of the stack frame, and the offset of
|
||||
the frame pointer from the stack pointer (for frameless functions, and
|
||||
when we're still in the prologue of a function with a frame) */
|
||||
|
||||
#define EXTRA_FRAME_INFO \
|
||||
struct frame_saved_regs fsr; \
|
||||
int framesize; \
|
||||
int frameoffset; \
|
||||
int framereg;
|
||||
|
||||
extern void arm_init_extra_frame_info PARAMS ((struct frame_info *fi));
|
||||
#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) arm_init_extra_frame_info (fi)
|
||||
|
||||
/* Return the frame address. On ARM, it is R11; on Thumb it is R7. */
|
||||
CORE_ADDR arm_target_read_fp PARAMS ((void));
|
||||
#define TARGET_READ_FP() arm_target_read_fp ()
|
||||
|
||||
/* Describe the pointer in each stack frame to the previous stack frame
|
||||
(its caller). */
|
||||
|
||||
@ -230,16 +347,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
However, if FRAME_CHAIN_VALID returns zero,
|
||||
it means the given frame is the outermost one and has no caller. */
|
||||
|
||||
/* In the case of the ARM, the frame's nominal address is the FP value,
|
||||
and 12 bytes before comes the saved previous FP value as a 4-byte word. */
|
||||
#define FRAME_CHAIN(thisframe) (CORE_ADDR) arm_frame_chain (thisframe)
|
||||
extern CORE_ADDR arm_frame_chain PARAMS ((struct frame_info *));
|
||||
|
||||
#define FRAME_CHAIN(thisframe) \
|
||||
((thisframe)->pc >= first_object_file_end ? \
|
||||
read_memory_integer ((thisframe)->frame - 12, 4) :\
|
||||
0)
|
||||
#define LOWEST_PC 0x20 /* the first 0x20 bytes are the trap vectors. */
|
||||
|
||||
#define FRAME_CHAIN_VALID(chain, thisframe) \
|
||||
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
|
||||
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= LOWEST_PC))
|
||||
|
||||
/* Define other aspects of the stack frame. */
|
||||
|
||||
@ -258,8 +372,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Saved Pc. */
|
||||
|
||||
#define FRAME_SAVED_PC(FRAME) \
|
||||
(read_memory_integer ((FRAME)->frame - 4, 4) & 0x03fffffc)
|
||||
#define FRAME_SAVED_PC(FRAME) arm_frame_saved_pc (FRAME)
|
||||
extern CORE_ADDR arm_frame_saved_pc PARAMS ((struct frame_info *));
|
||||
|
||||
#define FRAME_ARGS_ADDRESS(fi) (fi->frame)
|
||||
|
||||
@ -280,121 +394,102 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
ways in the stack frame. sp is even more special:
|
||||
the address we return for it IS the sp for the next frame. */
|
||||
|
||||
struct frame_saved_regs;
|
||||
struct frame_info;
|
||||
void frame_find_saved_regs PARAMS((struct frame_info *fi,
|
||||
struct frame_saved_regs *fsr));
|
||||
|
||||
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
|
||||
{ \
|
||||
register int regnum; \
|
||||
register int frame; \
|
||||
register int next_addr; \
|
||||
register int return_data_save; \
|
||||
register int saved_register_mask; \
|
||||
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
|
||||
frame = (frame_info)->frame; \
|
||||
return_data_save = read_memory_integer(frame, 4) & 0x03fffffc - 12; \
|
||||
saved_register_mask = \
|
||||
read_memory_integer(return_data_save, 4); \
|
||||
next_addr = frame - 12; \
|
||||
for (regnum = 4; regnum < 10; regnum++) \
|
||||
if (saved_register_mask & (1<<regnum)) { \
|
||||
next_addr -= 4; \
|
||||
(frame_saved_regs).regs[regnum] = next_addr; \
|
||||
} \
|
||||
if (read_memory_integer(return_data_save + 4, 4) == 0xed6d7103) { \
|
||||
next_addr -= 12; \
|
||||
(frame_saved_regs).regs[F0_REGNUM + 7] = next_addr; \
|
||||
} \
|
||||
if (read_memory_integer(return_data_save + 8, 4) == 0xed6d6103) { \
|
||||
next_addr -= 12; \
|
||||
(frame_saved_regs).regs[F0_REGNUM + 6] = next_addr; \
|
||||
} \
|
||||
if (read_memory_integer(return_data_save + 12, 4) == 0xed6d5103) { \
|
||||
next_addr -= 12; \
|
||||
(frame_saved_regs).regs[F0_REGNUM + 5] = next_addr; \
|
||||
} \
|
||||
if (read_memory_integer(return_data_save + 16, 4) == 0xed6d4103) { \
|
||||
next_addr -= 12; \
|
||||
(frame_saved_regs).regs[F0_REGNUM + 4] = next_addr; \
|
||||
} \
|
||||
(frame_saved_regs).regs[SP_REGNUM] = next_addr; \
|
||||
(frame_saved_regs).regs[PC_REGNUM] = frame - 4; \
|
||||
(frame_saved_regs).regs[PS_REGNUM] = frame - 4; \
|
||||
(frame_saved_regs).regs[FP_REGNUM] = frame - 12; \
|
||||
}
|
||||
arm_frame_find_saved_regs (frame_info, &(frame_saved_regs));
|
||||
|
||||
|
||||
/* Things needed for making the inferior call functions. */
|
||||
|
||||
#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
|
||||
sp = arm_push_arguments ((nargs), (args), (sp), (struct_return), (struct_addr))
|
||||
extern CORE_ADDR
|
||||
arm_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int, CORE_ADDR));
|
||||
|
||||
/* Push an empty stack frame, to record the current PC, etc. */
|
||||
|
||||
#define PUSH_DUMMY_FRAME \
|
||||
{ \
|
||||
register CORE_ADDR sp = read_register (SP_REGNUM); \
|
||||
register int regnum; \
|
||||
/* opcode for ldmdb fp,{v1-v6,fp,ip,lr,pc}^ */ \
|
||||
sp = push_word(sp, 0xe92dbf0); /* dummy return_data_save ins */ \
|
||||
/* push a pointer to the dummy instruction minus 12 */ \
|
||||
sp = push_word(sp, read_register (SP_REGNUM) - 16); \
|
||||
sp = push_word(sp, read_register (PS_REGNUM)); \
|
||||
sp = push_word(sp, read_register (SP_REGNUM)); \
|
||||
sp = push_word(sp, read_register (FP_REGNUM)); \
|
||||
for (regnum = 9; regnum >= 4; regnum --) \
|
||||
sp = push_word(sp, read_register (regnum)); \
|
||||
write_register (FP_REGNUM, read_register (SP_REGNUM) - 8); \
|
||||
write_register (SP_REGNUM, sp); }
|
||||
void arm_push_dummy_frame PARAMS ((void));
|
||||
|
||||
#define PUSH_DUMMY_FRAME arm_push_dummy_frame ()
|
||||
|
||||
/* Discard from the stack the innermost frame, restoring all registers. */
|
||||
|
||||
#define POP_FRAME \
|
||||
{ \
|
||||
register CORE_ADDR fp = read_register (FP_REGNUM); \
|
||||
register unsigned long return_data_save = \
|
||||
read_memory_integer ( (read_memory_integer (fp, 4) & \
|
||||
0x03fffffc) - 12, 4); \
|
||||
register int regnum; \
|
||||
write_register (PS_REGNUM, read_memory_integer (fp - 4, 4)); \
|
||||
write_register (PC_REGNUM, read_register (PS_REGNUM) & 0x03fffffc); \
|
||||
write_register (SP_REGNUM, read_memory_integer (fp - 8, 4)); \
|
||||
write_register (FP_REGNUM, read_memory_integer (fp - 12, 4)); \
|
||||
fp -= 12; \
|
||||
for (regnum = 9; regnum >= 4; regnum--) \
|
||||
if (return_data_save & (1<<regnum)) { \
|
||||
fp -= 4; \
|
||||
write_register (regnum, read_memory_integer(fp, 4)); \
|
||||
} \
|
||||
flush_cached_frames (); \
|
||||
set_current_frame (create_new_frame (read_register (FP_REGNUM), \
|
||||
read_pc ())); \
|
||||
}
|
||||
void arm_pop_frame PARAMS ((void));
|
||||
|
||||
#define POP_FRAME arm_pop_frame ()
|
||||
|
||||
/* This sequence of words is the instructions
|
||||
|
||||
ldmia sp!,{a1-a4}
|
||||
mov lk,pc
|
||||
bl *+8
|
||||
mov lr,pc
|
||||
mov pc,r4
|
||||
swi bkpt_swi
|
||||
|
||||
Note this is 16 bytes. */
|
||||
Note this is 12 bytes. */
|
||||
|
||||
#define CALL_DUMMY {0xe8bd000f, 0xe1a0e00f, 0xeb000000, 0xef180000}
|
||||
#define CALL_DUMMY {0xe1a0e00f, 0xe1a0f004, 0xef180000}
|
||||
|
||||
#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */
|
||||
|
||||
#define CALL_DUMMY_BREAKPOINT_OFFSET arm_call_dummy_breakpoint_offset()
|
||||
extern int arm_call_dummy_breakpoint_offset PARAMS ((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) \
|
||||
{ \
|
||||
register enum type_code code = TYPE_CODE (type); \
|
||||
register nargs_in_registers, struct_return = 0; \
|
||||
/* fix the load-arguments mask to move the first 4 or less arguments \
|
||||
into a1-a4 but make sure the structure return address in a1 is \
|
||||
not disturbed if the function is returning a structure */ \
|
||||
if ((code == TYPE_CODE_STRUCT || \
|
||||
code == TYPE_CODE_UNION || \
|
||||
code == TYPE_CODE_ARRAY) && \
|
||||
TYPE_LENGTH (type) > 4) { \
|
||||
nargs_in_registers = min(nargs + 1, 4); \
|
||||
struct_return = 1; \
|
||||
} else \
|
||||
nargs_in_registers = min(nargs, 4); \
|
||||
*(char *) dummyname = (1 << nargs_in_registers) - 1 - struct_return; \
|
||||
*(int *)((char *) dummyname + 8) = \
|
||||
(((fun - (pc + 16)) / 4) & 0x00ffffff) | 0xeb000000; }
|
||||
arm_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
|
||||
|
||||
void arm_fix_call_dummy PARAMS ((char *dummy, CORE_ADDR pc, CORE_ADDR fun,
|
||||
int nargs, struct value **args,
|
||||
struct type *type, int gcc_p));
|
||||
|
||||
CORE_ADDR arm_get_next_pc PARAMS ((CORE_ADDR));
|
||||
|
||||
/* Functions for dealing with Thumb call thunks. */
|
||||
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) arm_in_call_stub (pc, name)
|
||||
#define SKIP_TRAMPOLINE_CODE(pc) arm_skip_stub (pc)
|
||||
extern int arm_in_call_stub PARAMS ((CORE_ADDR pc, char *name));
|
||||
extern CORE_ADDR arm_skip_stub PARAMS ((CORE_ADDR pc));
|
||||
|
||||
/* Function to determine whether MEMADDR is in a Thumb function. */
|
||||
extern int arm_pc_is_thumb PARAMS ((bfd_vma memaddr));
|
||||
|
||||
/* Function to determine whether MEMADDR is in a call dummy called from
|
||||
a Thumb function. */
|
||||
extern int arm_pc_is_thumb_dummy PARAMS ((bfd_vma memaddr));
|
||||
|
||||
/* Macros for setting and testing a bit in a minimal symbol that
|
||||
marks it as Thumb function. The MSB of the minimal symbol's
|
||||
"info" field is used for this purpose. This field is already
|
||||
being used to store the symbol size, so the assumption is
|
||||
that the symbol size cannot exceed 2^31.
|
||||
|
||||
COFF_MAKE_MSYMBOL_SPECIAL
|
||||
ELF_MAKE_MSYMBOL_SPECIAL tests whether the COFF or ELF symbol corresponds
|
||||
to a thumb function, and sets a "special" bit in a
|
||||
minimal symbol to indicate that it does
|
||||
MSYMBOL_SET_SPECIAL actually sets the "special" bit
|
||||
MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol
|
||||
MSYMBOL_SIZE returns the size of the minimal symbol, i.e.
|
||||
the "info" field with the "special" bit masked out
|
||||
*/
|
||||
|
||||
extern int coff_sym_is_thumb(int val);
|
||||
#define MSYMBOL_SET_SPECIAL(msym) \
|
||||
MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) | 0x80000000)
|
||||
#define MSYMBOL_IS_SPECIAL(msym) \
|
||||
(((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
|
||||
#define MSYMBOL_SIZE(msym) \
|
||||
((long) MSYMBOL_INFO (msym) & 0x7fffffff)
|
||||
|
||||
/* Thumb symbol are of type STT_LOPROC, (synonymous with STT_ARM_TFUNC) */
|
||||
#define ELF_MAKE_MSYMBOL_SPECIAL(sym,msym) \
|
||||
{ if(ELF_ST_TYPE(((elf_symbol_type *)(sym))->internal_elf_sym.st_info) == STT_LOPROC) \
|
||||
MSYMBOL_SET_SPECIAL(msym); }
|
||||
|
||||
#define COFF_MAKE_MSYMBOL_SPECIAL(val,msym) \
|
||||
{ if(coff_sym_is_thumb(val)) MSYMBOL_SET_SPECIAL(msym); }
|
||||
|
@ -186,8 +186,8 @@ extern CORE_ADDR d10v_skip_prologue ();
|
||||
The d10v returns anything less than 8 bytes in size in
|
||||
registers. */
|
||||
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) \
|
||||
(TYPE_LENGTH (type) > 8)
|
||||
extern use_struct_convention_fn d10v_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) d10v_use_struct_convention (gcc_p, type)
|
||||
|
||||
|
||||
|
||||
|
@ -210,7 +210,8 @@ extern CORE_ADDR saved_pc_after_call ();
|
||||
On i960, a structure is returned in registers g0-g3, if it will fit.
|
||||
If it's more than 16 bytes long, g13 pointed to it on entry. */
|
||||
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 16)
|
||||
extern use_struct_convention_fn i960_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) i960_use_struct_convention (gcc_p, type)
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
a function return value of type TYPE, and copy that, in virtual format,
|
||||
|
@ -180,8 +180,8 @@ extern CORE_ADDR m32r_skip_prologue PARAMS ((CORE_ADDR pc));
|
||||
#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP) \
|
||||
write_register (0, STRUCT_ADDR)
|
||||
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
|
||||
(TYPE_LENGTH (TYPE) > 8)
|
||||
extern use_struct_convention_fn m32r_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) m32r_use_struct_convention (GCC_P, TYPE)
|
||||
|
||||
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
|
||||
extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
|
||||
|
@ -350,14 +350,8 @@ extern void mips_store_return_value PARAMS ((struct type *, char *));
|
||||
(extract_address (REGBUF + REGISTER_BYTE (V0_REGNUM), \
|
||||
REGISTER_RAW_SIZE (V0_REGNUM)))
|
||||
|
||||
#if MIPS_EABI
|
||||
#undef USE_STRUCT_CONVENTION
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) \
|
||||
(TYPE_LENGTH (type) > 2 * MIPS_REGSIZE)
|
||||
#else
|
||||
/* Structures are returned by ref in extra arg0 */
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) 1
|
||||
#endif
|
||||
extern use_struct_convention_fn mips_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) mips_use_struct_convention (gcc_p, type)
|
||||
|
||||
/* Describe the pointer in each stack frame to the previous stack frame
|
||||
(its caller). */
|
||||
|
@ -201,8 +201,8 @@ mn10200_push_arguments PARAMS ((int, struct value **, CORE_ADDR,
|
||||
#define REG_STRUCT_HAS_ADDR(gcc_p,TYPE) \
|
||||
(TYPE_LENGTH (TYPE) > 8)
|
||||
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
|
||||
(TYPE_NFIELDS (TYPE) > 1 || TYPE_LENGTH (TYPE) > 8)
|
||||
extern use_struct_convention_fn mn10200_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) mn10200_use_struct_convention (GCC_P, TYPE)
|
||||
|
||||
/* Override the default get_saved_register function with
|
||||
one that takes account of generic CALL_DUMMY frames. */
|
||||
|
@ -162,8 +162,8 @@ mn10300_push_arguments PARAMS ((int, struct value **, CORE_ADDR,
|
||||
#define REG_STRUCT_HAS_ADDR(gcc_p,TYPE) \
|
||||
(TYPE_LENGTH (TYPE) > 8)
|
||||
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
|
||||
(TYPE_NFIELDS (TYPE) > 1 || TYPE_LENGTH (TYPE) > 8)
|
||||
extern use_struct_convention_fn mn10300_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) mn10300_use_struct_convention (GCC_P, TYPE)
|
||||
|
||||
/* override the default get_saved_register function with
|
||||
one that takes account of generic CALL_DUMMY frames */
|
||||
|
@ -167,7 +167,8 @@ extern CORE_ADDR sh_skip_prologue ();
|
||||
#define STORE_STRUCT_RETURN(ADDR, SP) \
|
||||
{ write_register (STRUCT_RETURN_REGNUM, (ADDR)); }
|
||||
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH(type) > 1)
|
||||
extern use_struct_convention_fn sh_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type) sh_use_struct_convention (gcc_p, type)
|
||||
|
||||
/* Extract from an array REGBUF containing the (raw) register state
|
||||
a function return value of type TYPE, and copy that, in virtual format,
|
||||
|
@ -153,8 +153,8 @@ v850_push_arguments PARAMS ((int nargs, struct value **args, CORE_ADDR sp,
|
||||
|
||||
#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP)
|
||||
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
|
||||
(TYPE_NFIELDS (TYPE) > 1 || TYPE_LENGTH (TYPE) > 4)
|
||||
extern use_struct_convention_fn v850_use_struct_convention;
|
||||
#define USE_STRUCT_CONVENTION(GCC_P, TYPE) v850_use_struct_convention (GCC_P, TYPE);
|
||||
|
||||
/* override the default get_saved_register function with
|
||||
one that takes account of generic CALL_DUMMY frames */
|
||||
|
@ -36,6 +36,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
void d10v_frame_find_saved_regs PARAMS ((struct frame_info *fi,
|
||||
struct frame_saved_regs *fsr));
|
||||
|
||||
/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of
|
||||
EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc
|
||||
and TYPE is the type (which is known to be struct, union or array).
|
||||
|
||||
The d10v returns anything less than 8 bytes in size in
|
||||
registers. */
|
||||
|
||||
int
|
||||
d10v_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH (type) > 8);
|
||||
}
|
||||
|
||||
|
||||
/* Discard from the stack the innermost frame, restoring all saved
|
||||
registers. */
|
||||
|
||||
|
@ -285,6 +285,11 @@ extern void mfree PARAMS ((PTR, PTR));
|
||||
|
||||
extern void set_demangling_style PARAMS ((char *));
|
||||
|
||||
/* From tm.h */
|
||||
struct type;
|
||||
typedef int (use_struct_convention_fn) PARAMS ((int gcc_p, struct type *value_type));
|
||||
extern use_struct_convention_fn generic_use_struct_convention;
|
||||
|
||||
|
||||
/* Annotation stuff. */
|
||||
|
||||
|
@ -33,6 +33,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
/* Number of elements in the opcode table. */
|
||||
#define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0])
|
||||
|
||||
/* Both gcc and cc return small structs in registers (i.e. in GDB
|
||||
terminology, small structs don't use the struct return convention). */
|
||||
int
|
||||
gould_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH(type) > 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print the GOULD instruction at address MEMADDR in debugged memory,
|
||||
on STREAM. Returns length of the instruction, in bytes. */
|
||||
|
@ -110,6 +110,16 @@ static void internalize_unwinds PARAMS ((struct objfile *,
|
||||
static void pa_print_registers PARAMS ((char *, int, int));
|
||||
static void pa_print_fp_reg PARAMS ((int));
|
||||
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
int
|
||||
hppa_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH (type) > 8);
|
||||
}
|
||||
|
||||
|
||||
/* Routines to extract various sized constants out of hppa
|
||||
instructions. */
|
||||
|
@ -31,6 +31,28 @@ static CORE_ADDR next_insn PARAMS ((CORE_ADDR memaddr,
|
||||
unsigned int *pword1,
|
||||
unsigned int *pword2));
|
||||
|
||||
/* Does the specified function use the "struct returning" convention
|
||||
or the "value returning" convention? The "value returning" convention
|
||||
almost invariably returns the entire value in registers. The
|
||||
"struct returning" convention often returns the entire value in
|
||||
memory, and passes a pointer (out of or into the function) saying
|
||||
where the value (is or should go).
|
||||
|
||||
Since this sometimes depends on whether it was compiled with GCC,
|
||||
this is also an argument. This is used in call_function to build a
|
||||
stack, and in value_being_returned to print return values.
|
||||
|
||||
On i960, a structure is returned in registers g0-g3, if it will fit.
|
||||
If it's more than 16 bytes long, g13 pointed to it on entry. */
|
||||
|
||||
int
|
||||
i960_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH (type) > 16);
|
||||
}
|
||||
|
||||
/* gdb960 is always running on a non-960 host. Check its characteristics.
|
||||
This routine must be called as part of gdb initialization. */
|
||||
|
||||
|
@ -211,6 +211,21 @@ struct linked_proc_info
|
||||
} *linked_proc_desc_table = NULL;
|
||||
|
||||
|
||||
/* Should the upper word of 64-bit addresses be zeroed? */
|
||||
static int mask_address_p = 1;
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
int
|
||||
mips_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
if (MIPS_EABI)
|
||||
return (TYPE_LENGTH (type) > 2 * MIPS_REGSIZE);
|
||||
else
|
||||
return 1; /* Structures are returned by ref in extra arg0 */
|
||||
}
|
||||
|
||||
/* Tell if the program counter value in MEMADDR is in a MIPS16 function. */
|
||||
|
||||
static int
|
||||
@ -1009,10 +1024,7 @@ mips_addr_bits_remove (addr)
|
||||
CORE_ADDR addr;
|
||||
{
|
||||
#if GDB_TARGET_IS_MIPS64
|
||||
if ((addr >> 32 == (CORE_ADDR)0xffffffff)
|
||||
&& (strcmp (target_shortname,"pmon")==0
|
||||
|| strcmp (target_shortname,"ddb")==0
|
||||
|| strcmp (target_shortname,"sim")==0))
|
||||
if (mask_address_p && (addr >> 32 == (CORE_ADDR)0xffffffff))
|
||||
{
|
||||
/* This hack is a work-around for existing boards using PMON,
|
||||
the simulator, and any other 64-bit targets that doesn't have
|
||||
@ -1766,9 +1778,11 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||
#define ROUND_UP(n,a) (((n)+(a)-1) & ~((a)-1))
|
||||
|
||||
/* First ensure that the stack and structure return address (if any)
|
||||
are properly aligned. The stack has to be 64-bit aligned even
|
||||
on 32-bit machines, because doubles must be 64-bit aligned. */
|
||||
sp = ROUND_DOWN (sp, 8);
|
||||
are properly aligned. The stack has to be at least 64-bit aligned
|
||||
even on 32-bit machines, because doubles must be 64-bit aligned.
|
||||
On at least one MIPS variant, stack frames need to be 128-bit
|
||||
aligned, so we round to this widest known alignment. */
|
||||
sp = ROUND_DOWN (sp, 16);
|
||||
struct_addr = ROUND_DOWN (struct_addr, MIPS_REGSIZE);
|
||||
|
||||
/* Now make space on the stack for the args. We allocate more
|
||||
@ -1776,7 +1790,7 @@ mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
|
||||
passed in registers, but that's OK. */
|
||||
for (argnum = 0; argnum < nargs; argnum++)
|
||||
len += ROUND_UP (TYPE_LENGTH(VALUE_TYPE(args[argnum])), MIPS_REGSIZE);
|
||||
sp -= ROUND_UP (len, 8);
|
||||
sp -= ROUND_UP (len, 16);
|
||||
|
||||
/* Initialize the integer and float register pointers. */
|
||||
argreg = A0_REGNUM;
|
||||
@ -2253,8 +2267,8 @@ do_gp_register_row (regnum)
|
||||
int numregs = NUM_REGS;
|
||||
|
||||
/* start-sanitize-sky */
|
||||
#ifdef NUM_R5900_REGS
|
||||
numregs = NUM_R5900_REGS;
|
||||
#ifdef NUM_CORE_REGS
|
||||
numregs = NUM_CORE_REGS;
|
||||
#endif
|
||||
/* end-sanitize-sky */
|
||||
|
||||
@ -2331,10 +2345,10 @@ mips_do_registers_info (regnum, fpregs)
|
||||
else
|
||||
regnum = do_gp_register_row (regnum); /* GP (int) regs */
|
||||
/* start-sanitize-sky */
|
||||
#ifdef NUM_R5900_REGS
|
||||
#ifdef NUM_CORE_REGS
|
||||
/* For the sky project, NUM_REGS includes the vector slaves,
|
||||
which are handled elsewhere */
|
||||
if (regnum >= NUM_R5900_REGS)
|
||||
if (regnum >= NUM_CORE_REGS)
|
||||
break;
|
||||
#endif
|
||||
/* end-sanitize-sky */
|
||||
@ -3151,6 +3165,24 @@ mips_ignore_helper (pc)
|
||||
}
|
||||
|
||||
|
||||
/* Return a location where we can set a breakpoint that will be hit
|
||||
when an inferior function call returns. This is normally the
|
||||
program's entry point. Executables that don't have an entry
|
||||
point (e.g. programs in ROM) should define a symbol __CALL_DUMMY_ADDRESS
|
||||
whose address is the location where the breakpoint should be placed. */
|
||||
|
||||
CORE_ADDR
|
||||
mips_call_dummy_address ()
|
||||
{
|
||||
struct minimal_symbol *sym;
|
||||
|
||||
sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL);
|
||||
if (sym)
|
||||
return SYMBOL_VALUE_ADDRESS (sym);
|
||||
else
|
||||
return entry_point_address ();
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_mips_tdep ()
|
||||
{
|
||||
@ -3215,4 +3247,13 @@ search. The only need to set it is when debugging a stripped executable.",
|
||||
might change our ability to get backtraces. */
|
||||
c->function.sfunc = reinit_frame_cache_sfunc;
|
||||
add_show_from_set (c, &showlist);
|
||||
|
||||
/* Allow the user to control whether the upper bits of 64-bit
|
||||
addresses should be zeroed. */
|
||||
add_show_from_set
|
||||
(add_set_cmd ("mask-address", no_class, var_boolean, (char *)&mask_address_p,
|
||||
"Set zeroing of upper 32 bits of 64-bit addresses.\n\
|
||||
Use \"on\" to enable the masking, and \"off\" to disable it.\n\
|
||||
Without an argument, zeroing of upper address bits is enabled.", &setlist),
|
||||
&showlist);
|
||||
}
|
||||
|
@ -28,6 +28,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "gdbcore.h"
|
||||
#include "symfile.h"
|
||||
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
int
|
||||
mn10200_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The main purpose of this file is dealing with prologues to extract
|
||||
information about stack frames and saved registers.
|
||||
|
||||
|
@ -49,6 +49,16 @@ static CORE_ADDR mn10300_analyze_prologue PARAMS ((struct frame_info *fi,
|
||||
#define NO_MORE_FRAMES 0x4
|
||||
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
int
|
||||
mn10300_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 8);
|
||||
}
|
||||
|
||||
|
||||
/* Fix fi->frame if it's bogus at this point. This is a helper
|
||||
function for mn10300_analyze_prologue. */
|
||||
|
||||
@ -187,7 +197,8 @@ mn10300_analyze_prologue (fi, pc)
|
||||
/* If we're in start, then give up. */
|
||||
if (strcmp (name, "start") == 0)
|
||||
{
|
||||
fi->status = NO_MORE_FRAMES;
|
||||
if (fi != NULL)
|
||||
fi->status = NO_MORE_FRAMES;
|
||||
return pc;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,17 @@ struct {
|
||||
#define IS_FMOV(x) (((x) & 0xf00f) == 0xf00b)
|
||||
#define FPSCR_SZ (1 << 20)
|
||||
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
int
|
||||
sh_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_LENGTH (type) > 1);
|
||||
}
|
||||
|
||||
|
||||
/* Skip any prologue before the guts of a function */
|
||||
|
||||
CORE_ADDR
|
||||
|
@ -48,6 +48,17 @@ struct prologue_info
|
||||
|
||||
static CORE_ADDR v850_scan_prologue PARAMS ((CORE_ADDR pc,
|
||||
struct prologue_info *fs));
|
||||
|
||||
|
||||
/* Should call_function allocate stack space for a struct return? */
|
||||
int
|
||||
v850_use_struct_convention (gcc_p, type)
|
||||
int gcc_p;
|
||||
struct type *type;
|
||||
{
|
||||
return (TYPE_NFIELDS (type) > 1 || TYPE_LENGTH (type) > 4);
|
||||
}
|
||||
|
||||
|
||||
/* Function: scan_prologue
|
||||
Scan the prologue of the function that contains PC, and record what
|
||||
|
23
gdb/values.c
23
gdb/values.c
@ -1381,14 +1381,21 @@ value_being_returned (valtype, retbuf, struct_return)
|
||||
2.0-2.3.3. This is somewhat unfortunate, but changing gcc2_compiled
|
||||
would cause more chaos than dealing with some struct returns being
|
||||
handled wrong. */
|
||||
#if !defined (USE_STRUCT_CONVENTION)
|
||||
#define USE_STRUCT_CONVENTION(gcc_p, type)\
|
||||
(!((gcc_p == 1) && (TYPE_LENGTH (value_type) == 1 \
|
||||
|| TYPE_LENGTH (value_type) == 2 \
|
||||
|| TYPE_LENGTH (value_type) == 4 \
|
||||
|| TYPE_LENGTH (value_type) == 8 \
|
||||
) \
|
||||
))
|
||||
|
||||
int
|
||||
generic_use_struct_convention (gcc_p, value_type)
|
||||
int gcc_p;
|
||||
struct type *value_type;
|
||||
{
|
||||
return !((gcc_p == 1)
|
||||
&& (TYPE_LENGTH (value_type) == 1
|
||||
|| TYPE_LENGTH (value_type) == 2
|
||||
|| TYPE_LENGTH (value_type) == 4
|
||||
|| TYPE_LENGTH (value_type) == 8));
|
||||
}
|
||||
|
||||
#ifndef USE_STRUCT_CONVENTION
|
||||
#define USE_STRUCT_CONVENTION(gcc_p,type) generic_use_struct_convention (gcc_p, type)
|
||||
#endif
|
||||
|
||||
/* Some fundamental types (such as long double) are returned on the stack for
|
||||
|
Loading…
Reference in New Issue
Block a user