diff options
Diffstat (limited to 'gdb/config/arm/tm-arm.h')
-rw-r--r-- | gdb/config/arm/tm-arm.h | 443 |
1 files changed, 245 insertions, 198 deletions
diff --git a/gdb/config/arm/tm-arm.h b/gdb/config/arm/tm-arm.h index d33477d..fb7f7b9 100644 --- a/gdb/config/arm/tm-arm.h +++ b/gdb/config/arm/tm-arm.h @@ -1,4 +1,4 @@ -/* Definitions to make GDB target for an ARM +/* Definitions to target GDB to ARM targets. Copyright 1986-1989, 1991, 1993-1999 Free Software Foundation, Inc. This file is part of GDB. @@ -18,120 +18,168 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* Forward decls for prototypes */ +#ifndef TM_ARM_H +#define TM_ARM_H + +/* Forward declarations for prototypes. */ struct type; struct value; #define TARGET_BYTE_ORDER_SELECTABLE -/* IEEE format floating point */ +/* Target byte order on ARM defaults to selectable, and defaults to + little endian. */ +#define TARGET_BYTE_ORDER_SELECTABLE_P 1 +#define TARGET_BYTE_ORDER_DEFAULT LITTLE_ENDIAN +/* IEEE format floating point. */ #define IEEE_FLOAT +#define TARGET_DOUBLE_FORMAT (target_byte_order == BIG_ENDIAN \ + ? &floatformat_ieee_double_big \ + : &floatformat_ieee_double_littlebyte_bigword) -/* FIXME: may need a floatformat_ieee_double_bigbyte_littleword format for - BIG_ENDIAN use. -fnf */ - -#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. */ +/* 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)); +CORE_ADDR arm_addr_bits_remove (CORE_ADDR); -#define ADDR_BITS_REMOVE(val) (arm_addr_bits_remove (val)) +#define ADDR_BITS_REMOVE(val) (arm_addr_bits_remove (val)) -/* Offset from address of function to start of its code. - Zero on most machines. */ +/* Offset from address of function to start of its code. Zero on most + machines. */ -#define FUNCTION_START_OFFSET 0 +#define FUNCTION_START_OFFSET 0 -/* Advance PC across any function entry prologue instructions - to reach some "real" code. */ +/* Advance PC across any function entry prologue instructions to reach + some "real" code. */ -extern CORE_ADDR arm_skip_prologue PARAMS ((CORE_ADDR pc)); +extern CORE_ADDR arm_skip_prologue (CORE_ADDR pc); -#define SKIP_PROLOGUE(pc) (arm_skip_prologue (pc)) +#define SKIP_PROLOGUE(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. */ +/* 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) arm_saved_pc_after_call (frame) +#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 -#define TARGET_NBPG NBPG - -/* Address of end of stack space. */ - -#define STACK_END_ADDR (0x01000000 - (TARGET_UPAGES * TARGET_NBPG)) +extern CORE_ADDR arm_saved_pc_after_call (struct frame_info *); + +/* The following define instruction sequences that will cause ARM + cpu's to take an undefined instruction trap. These are used to + signal a breakpoint to GDB. + + The newer ARMv4T cpu's are capable of operating in ARM or Thumb + modes. A different instruction is required for each mode. The ARM + cpu's can also be big or little endian. Thus four different + instructions are needed to support all cases. + + Note: ARMv4 defines several new instructions that will take the + undefined instruction trap. ARM7TDMI is nominally ARMv4T, but does + not in fact add the new instructions. The new undefined + instructions in ARMv4 are all instructions that had no defined + behaviour in earlier chips. There is no guarantee that they will + raise an exception, but may be treated as NOP's. In practice, it + may only safe to rely on instructions matching: + + 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 + 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + C C C C 0 1 1 x x x x x x x x x x x x x x x x x x x x 1 x x x x + + Even this may only true if the condition predicate is true. The + following use a condition predicate of ALWAYS so it is always TRUE. + + There are other ways of forcing a breakpoint. ARM Linux, RisciX, + and I suspect NetBSD will all use a software interrupt rather than + an undefined instruction to force a trap. This can be handled by + redefining some or all of the following in a target dependent + fashion. */ + +#define ARM_LE_BREAKPOINT {0xFE,0xDE,0xFF,0xE7} +#define ARM_BE_BREAKPOINT {0xE7,0xFF,0xDE,0xFE} +#define THUMB_LE_BREAKPOINT {0xfe,0xdf} +#define THUMB_BE_BREAKPOINT {0xdf,0xfe} /* Stack grows downward. */ #define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) -/* !!!! 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 +/* !!!! 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. */ -/* 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. */ +/* 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. */ extern breakpoint_from_pc_fn arm_breakpoint_from_pc; #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 - but not always. */ +/* Amount PC must be decremented by after a breakpoint. This is often + the number of bytes in BREAKPOINT but not always. */ #define DECR_PC_AFTER_BREAK 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. - */ +/* Code to execute to print interesting information about the floating + point processor (if any) or emulator. No need to define if there + is nothing to do. */ extern void arm_float_info (void); -#define FLOAT_INFO { arm_float_info (); } +#define FLOAT_INFO { arm_float_info (); } /* 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 */ - -/* Note: I make a fake copy of the pc in register 25 (calling it ps) so - that I can clear the status bits from pc (register 15) */ - -#define NUM_REGS 26 +#define REGISTER_SIZE 4 + +/* Say how long FP registers are. Used for documentation purposes and + code readability in this header. IEEE extended doubles are 80 + bits. DWORD aligned they use 96 bits. */ +#define FP_REGISTER_RAW_SIZE 12 + +/* GCC doesn't support long doubles (extended IEEE values). The FP + register virtual size is therefore 64 bits. Used for documentation + purposes and code readability in this header. */ +#define FP_REGISTER_VIRTUAL_SIZE 8 + +/* Status registers are the same size as general purpose registers. + Used for documentation purposes and code readability in this + header. */ +#define STATUS_REGISTER_SIZE REGISTER_SIZE + +/* Number of machine registers. The only define actually required + is NUM_REGS. The other definitions are used for documentation + purposes and code readability. */ +/* For 26 bit ARM code, a fake copy of the PC is placed in register 25 (PS) + (and called PS for processor status) so the status bits can be cleared + from the PC (register 15). For 32 bit ARM code, a copy of CPSR is placed + in PS. */ +#define NUM_FREGS 8 /* Number of floating point registers. */ +#define NUM_SREGS 2 /* Number of status registers. */ +#define NUM_GREGS 16 /* Number of general purpose registers. */ +#define NUM_REGS (NUM_GREGS + NUM_FREGS + NUM_SREGS) /* An array of names of registers. */ - extern char **arm_register_names; + #define REGISTER_NAME(i) arm_register_names[i] -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - 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. */ +/* Register numbers of various important registers. Note that some of + these values are "real" register numbers, and correspond to the + general registers of the machine, and some are "phony" register + numbers which are too large 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 */ @@ -180,88 +228,97 @@ extern char **arm_register_names; /* Total amount of space needed to store our copies of the machine's register state, the array `registers'. */ -#define REGISTER_BYTES (16*4 + 12*8 + 4 + 4) + +#define REGISTER_BYTES ((NUM_GREGS * REGISTER_SIZE) + \ + (NUM_FREGS * FP_REGISTER_RAW_SIZE) + \ + (NUM_SREGS * STATUS_REGISTER_SIZE)) /* Index within `registers' of the first byte of the space for register N. */ -#define REGISTER_BYTE(N) (((N) < F0_REGNUM) ? (N)*4 : \ - (((N) < PS_REGNUM) ? 16*4 + ((N) - 16)*12 : \ - 16*4 + 8*12 + ((N) - FPS_REGNUM) * 4)) - -/* Number of bytes of storage in the actual machine representation - for register N. On the vax, all regs are 4 bytes. */ - -#define REGISTER_RAW_SIZE(N) (((N) < F0_REGNUM || (N) >= FPS_REGNUM) ? 4 : 12) - -/* Number of bytes of storage in the program's representation - for register N. On the vax, all regs are 4 bytes. */ - -#define REGISTER_VIRTUAL_SIZE(N) (((N) < F0_REGNUM || (N) >= FPS_REGNUM) ? 4 : 8) +#define REGISTER_BYTE(N) \ + ((N) < F0_REGNUM \ + ? (N) * REGISTER_SIZE \ + : ((N) < PS_REGNUM \ + ? (NUM_GREGS * REGISTER_SIZE + \ + ((N) - F0_REGNUM) * FP_REGISTER_RAW_SIZE) \ + : (NUM_GREGS * REGISTER_SIZE + \ + NUM_FREGS * FP_REGISTER_RAW_SIZE + \ + ((N) - FPS_REGNUM) * STATUS_REGISTER_SIZE))) + +/* Number of bytes of storage in the actual machine representation for + register N. All registers are 4 bytes, except fp0 - fp7, which are + 12 bytes in length. */ +#define REGISTER_RAW_SIZE(N) \ + ((N) < F0_REGNUM ? REGISTER_SIZE : \ + (N) < FPS_REGNUM ? FP_REGISTER_RAW_SIZE : STATUS_REGISTER_SIZE) + +/* Number of bytes of storage in a program's representation + for register N. */ +#define REGISTER_VIRTUAL_SIZE(N) \ + ((N) < F0_REGNUM ? REGISTER_SIZE : \ + (N) < FPS_REGNUM ? FP_REGISTER_VIRTUAL_SIZE : STATUS_REGISTER_SIZE) /* Largest value REGISTER_RAW_SIZE can have. */ -#define MAX_REGISTER_RAW_SIZE 12 +#define MAX_REGISTER_RAW_SIZE FP_REGISTER_RAW_SIZE /* Largest value REGISTER_VIRTUAL_SIZE can have. */ +#define MAX_REGISTER_VIRTUAL_SIZE FP_REGISTER_VIRTUAL_SIZE -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* 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 in buffer FROM - to virtual format with type TYPE in buffer TO. */ +/* Nonzero if register N requires conversion from raw format to + virtual format. */ +extern int arm_register_convertible (unsigned int); +#define REGISTER_CONVERTIBLE(REGNUM) (arm_register_convertible (REGNUM)) -void convert_from_extended (void *ptr, /*double*/void *dbl); +/* Convert data from raw format for register REGNUM in buffer FROM to + virtual format with type TYPE in buffer TO. */ +extern void arm_register_convert_to_virtual (unsigned int regnum, + struct type *type, + void *from, void *to); #define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \ -{ \ - double val; \ - convert_from_extended ((FROM), & val); \ - store_floating ((TO), TYPE_LENGTH (TYPE), val); \ -} + arm_register_convert_to_virtual (REGNUM, TYPE, FROM, TO) -/* Convert data from virtual format with type TYPE in buffer FROM - to raw format for register REGNUM in buffer TO. */ +/* Convert data from virtual format with type TYPE in buffer FROM to + raw format for register REGNUM in buffer TO. */ -extern void convert_to_extended (void *ptr, /*double*/void *dbl); +extern void arm_register_convert_to_raw (unsigned int regnum, + struct type *type, + void *from, void *to); +#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \ + arm_register_convert_to_raw (REGNUM, TYPE, FROM, 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. */ +/* Return the GDB type object for the "standard" data type of data in + register N. */ #define REGISTER_VIRTUAL_TYPE(N) \ - (((unsigned)(N) - F0_REGNUM) < 8 ? builtin_type_double : builtin_type_int) - + (((unsigned)(N) - F0_REGNUM) < NUM_FREGS \ + ? builtin_type_double : builtin_type_int) + /* The system C compiler uses a similar structure return convention to gcc */ extern use_struct_convention_fn arm_use_struct_convention; -#define USE_STRUCT_CONVENTION(gcc_p, type) arm_use_struct_convention (gcc_p, type) +#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. */ #define STORE_STRUCT_RETURN(ADDR, SP) \ - { write_register (0, (ADDR)); } + write_register (A1_REGNUM, (ADDR)) -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ +/* Extract from an array REGBUF containing the (raw) register state a + function return value of type TYPE, and copy that, in virtual + format, into VALBUF. */ +extern void arm_extract_return_value (struct type *, char[], char *); #define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \ - convert_from_extended (REGBUF + REGISTER_BYTE (F0_REGNUM), VALBUF); \ - else \ - memcpy (VALBUF, REGBUF, TYPE_LENGTH (TYPE)) + arm_extract_return_value ((TYPE), (REGBUF), (VALBUF)) -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. */ +/* Write into appropriate registers a function return value of type + TYPE, given in virtual format. */ +extern void convert_to_extended (void *dbl, void *ptr); #define STORE_RETURN_VALUE(TYPE,VALBUF) \ if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) { \ char _buf[MAX_REGISTER_RAW_SIZE]; \ @@ -275,7 +332,7 @@ extern use_struct_convention_fn arm_use_struct_convention; as a CORE_ADDR (or an expression that can be used as one). */ #define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \ - (extract_address ((PTR) (REGBUF), REGISTER_RAW_SIZE(0))) + (extract_address ((PTR)(REGBUF), REGISTER_RAW_SIZE(0))) /* Specify that for the native compiler variables for a particular lexical context are listed after the beginning LBRAC instead of @@ -283,11 +340,11 @@ extern use_struct_convention_fn arm_use_struct_convention; #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 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; \ @@ -295,29 +352,29 @@ extern use_struct_convention_fn arm_use_struct_convention; int frameoffset; \ int framereg; -extern void arm_init_extra_frame_info PARAMS ((int fromleaf, - struct frame_info *fi)); +extern void arm_init_extra_frame_info (int fromleaf, struct frame_info * fi); #define INIT_EXTRA_FRAME_INFO(fromleaf, fi) \ - arm_init_extra_frame_info (fromleaf, fi) + arm_init_extra_frame_info ((fromleaf), (fi)) /* Return the frame address. On ARM, it is R11; on Thumb it is R7. */ -CORE_ADDR arm_target_read_fp PARAMS ((void)); +CORE_ADDR arm_target_read_fp (void); #define TARGET_READ_FP() arm_target_read_fp () -/* Describe the pointer in each stack frame to the previous stack frame - (its caller). */ +/* Describe the pointer in each stack frame to the previous stack + frame (its caller). */ -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. +/* FRAME_CHAIN takes a frame's nominal address and produces the + frame's chain-pointer. However, if FRAME_CHAIN_VALID returns zero, it means the given frame is the outermost one and has no caller. */ -#define FRAME_CHAIN(thisframe) (CORE_ADDR) arm_frame_chain (thisframe) -extern CORE_ADDR arm_frame_chain PARAMS ((struct frame_info *)); +#define FRAME_CHAIN(thisframe) arm_frame_chain (thisframe) +extern CORE_ADDR arm_frame_chain (struct frame_info *); -extern int arm_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); -#define FRAME_CHAIN_VALID(chain, thisframe) arm_frame_chain_valid (chain, thisframe) +extern int arm_frame_chain_valid (CORE_ADDR, struct frame_info *); +#define FRAME_CHAIN_VALID(chain, thisframe) \ + arm_frame_chain_valid (chain, thisframe) /* Define other aspects of the stack frame. */ @@ -325,14 +382,14 @@ extern int arm_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); by FI does not have a frame on the stack associated with it. If it does not, FRAMELESS is set to 1, else 0. - Sometimes we have functions that do a little setup (like saving the vN - registers with the stmdb instruction, but DO NOT set up a frame. + Sometimes we have functions that do a little setup (like saving the + vN registers with the stmdb instruction, but DO NOT set up a frame. The symbol table will report this as a prologue. However, it is - important not to try to parse these partial frames as frames, or we + important not to try to parse these partial frames as frames, or we will get really confused. - So I will demand 3 instructions between the start & end of the prologue - before I call it a real prologue, i.e. at least + So I will demand 3 instructions between the start & end of the + prologue before I call it a real prologue, i.e. at least mov ip, sp, stmdb sp!, {} sub sp, ip, #4. */ @@ -340,11 +397,11 @@ extern int arm_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *)); extern int arm_frameless_function_invocation (struct frame_info *fi); #define FRAMELESS_FUNCTION_INVOCATION(FI) \ (arm_frameless_function_invocation (FI)) - + /* Saved Pc. */ #define FRAME_SAVED_PC(FRAME) arm_frame_saved_pc (FRAME) -extern CORE_ADDR arm_frame_saved_pc PARAMS ((struct frame_info *)); +extern CORE_ADDR arm_frame_saved_pc (struct frame_info *); #define FRAME_ARGS_ADDRESS(fi) (fi->frame) @@ -355,15 +412,15 @@ extern CORE_ADDR arm_frame_saved_pc PARAMS ((struct frame_info *)); #define FRAME_NUM_ARGS(fi) (-1) -/* Return number of bytes at start of arglist that are not really args. */ +/* Return number of bytes at start of arglist that are not really args. */ #define FRAME_ARGS_SKIP 0 -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. +/* Put here the code to store, into a struct frame_saved_regs, the + addresses of the saved registers of frame described by FRAME_INFO. This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ + 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; @@ -371,24 +428,24 @@ void arm_frame_find_saved_regs (struct frame_info * fi, struct frame_saved_regs * fsr); #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ - arm_frame_find_saved_regs (frame_info, &(frame_saved_regs)); - + 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) \ - (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)); + sp = arm_push_arguments ((nargs), (args), (sp), (struct_return), (struct_addr)) +extern CORE_ADDR arm_push_arguments (int, struct value **, CORE_ADDR, int, + CORE_ADDR); /* Push an empty stack frame, to record the current PC, etc. */ -void arm_push_dummy_frame PARAMS ((void)); +void arm_push_dummy_frame (void); #define PUSH_DUMMY_FRAME arm_push_dummy_frame () /* Discard from the stack the innermost frame, restoring all registers. */ -void arm_pop_frame PARAMS ((void)); +void arm_pop_frame (void); #define POP_FRAME arm_pop_frame () @@ -400,69 +457,59 @@ void arm_pop_frame PARAMS ((void)); Note this is 12 bytes. */ -#define CALL_DUMMY {0xe1a0e00f, 0xe1a0f004, 0xE7FFDEFE} - -#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */ +#define CALL_DUMMY {0xe1a0e00f, 0xe1a0f004, 0xe7ffdefe} +#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)); +extern int arm_call_dummy_breakpoint_offset (void); -/* Insert the specified number of args and function address - into a call sequence of the above form stored at DUMMYNAME. */ +/* 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) \ - 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)); + arm_fix_call_dummy ((dummyname), (pc), (fun), (nargs), (args), (type), (gcc_p)) -CORE_ADDR arm_get_next_pc PARAMS ((CORE_ADDR)); +void arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, + int nargs, struct value ** args, + struct type * type, int gcc_p); -/* 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)); +CORE_ADDR arm_get_next_pc (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. +/* 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 - */ + ELF_MAKE_MSYMBOL_SPECIAL + + These macros test whether the COFF or ELF symbol corresponds to a + thumb function, and set 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) + 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) */ +/* Thumb symbols 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); } + { 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); } -#undef IN_SIGTRAMP -#define IN_SIGTRAMP(pc, name) 0 +#endif /* TM_ARM_H */ |