diff options
author | Andrew Cagney <cagney@redhat.com> | 1998-11-23 12:35:23 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1998-11-23 12:35:23 +0000 |
commit | 98760eab33f4963e075077cb094f9f195ca33d01 (patch) | |
tree | 60590f385f7cdd40ccf6ce14fa0437140b19686a /gdb/arm-tdep.c | |
parent | 554eb429e4555ceaa7892a8ab93c7a41045a6824 (diff) | |
download | gdb-98760eab33f4963e075077cb094f9f195ca33d01.zip gdb-98760eab33f4963e075077cb094f9f195ca33d01.tar.gz gdb-98760eab33f4963e075077cb094f9f195ca33d01.tar.bz2 |
CARP: Convert macro definitions of USE_STRUCT_CONVENTION into target
specific functions.
Diffstat (limited to 'gdb/arm-tdep.c')
-rw-r--r-- | gdb/arm-tdep.c | 98 |
1 files changed, 71 insertions, 27 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index ce55733..a190765 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -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. */ |