diff options
author | Andrew Cagney <cagney@redhat.com> | 2002-07-16 14:30:14 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2002-07-16 14:30:14 +0000 |
commit | 7a3085c168dec67f00ccc68ea4623666fa930736 (patch) | |
tree | 016c785340babe5ff06a9e605ef044cbe43e07a7 /gdb | |
parent | 25d3fb587f2c199aa9d84925188ab8924bf410a4 (diff) | |
download | gdb-7a3085c168dec67f00ccc68ea4623666fa930736.zip gdb-7a3085c168dec67f00ccc68ea4623666fa930736.tar.gz gdb-7a3085c168dec67f00ccc68ea4623666fa930736.tar.bz2 |
Obsolete fr30.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/MAINTAINERS | 4 | ||||
-rw-r--r-- | gdb/NEWS | 1 | ||||
-rw-r--r-- | gdb/config/fr30/fr30.mt | 10 | ||||
-rw-r--r-- | gdb/config/fr30/tm-fr30.h | 466 | ||||
-rw-r--r-- | gdb/configure.tgt | 6 | ||||
-rw-r--r-- | gdb/fr30-tdep.c | 1202 |
7 files changed, 853 insertions, 845 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2fb74fe..bb3ed2f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2002-07-16 Andrew Cagney <ac131313@redhat.com> + + * NEWS: Mention that the FR30 has been made obsolete. + * fr30-tdep.c: Make file obsolete. + * config/fr30/tm-fr30.h: Ditto. + * config/fr30/fr30.mt: Ditto. + * configure.tgt: Make fr30-*-elf obsolete. + * MAINTAINERS: Make fr30-elf obsolete. + 2002-07-16 Pierre Muller <muller@ics.u-strasbg.fr> * blockframe.c (get_pc_function_start): return 0 if the minimal symbol diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index a6582a2..5efb2b0 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -83,9 +83,7 @@ maintainer works with the native maintainer when resolving API issues. djgpp --target=i586-pc-msdosdjgpp ,-Werror (See native and host) - fr30 --target=fr30-elf -Werror - Maintenance only - OBSOLETE candidate, not multi-arch + fr30 (--target=fr30-elf OBSOLETE) h8300 --target=h8300hms -Werror Maintenance only @@ -61,6 +61,7 @@ configurations, the next release of GDB will have their sources permanently REMOVED. Mitsubishi D30V d30v-*-* +Fujitsu FR30 fr30-*-elf* * REMOVED configurations and files diff --git a/gdb/config/fr30/fr30.mt b/gdb/config/fr30/fr30.mt index fac307e..b702970 100644 --- a/gdb/config/fr30/fr30.mt +++ b/gdb/config/fr30/fr30.mt @@ -1,5 +1,5 @@ -# Target: Fujitsu FR30 processor -TDEPFILES= fr30-tdep.o -TM_FILE= tm-fr30.h -SIM_OBS = remote-sim.o -SIM = ../sim/fr30/libsim.a +# OBSOLETE # Target: Fujitsu FR30 processor +# OBSOLETE TDEPFILES= fr30-tdep.o +# OBSOLETE TM_FILE= tm-fr30.h +# OBSOLETE SIM_OBS = remote-sim.o +# OBSOLETE SIM = ../sim/fr30/libsim.a diff --git a/gdb/config/fr30/tm-fr30.h b/gdb/config/fr30/tm-fr30.h index e54154a..7a58337 100644 --- a/gdb/config/fr30/tm-fr30.h +++ b/gdb/config/fr30/tm-fr30.h @@ -1,233 +1,233 @@ -/* Parameters for execution on a Fujitsu FR30 processor. - Copyright 1999, 2000 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "regcache.h" - -#define FR30_GENREGS 16 -#define FR30_DEDICATEDREGS 8 -#define FR30_REGSIZE 4 /* bytes */ - -#define NUM_REGS (FR30_GENREGS + FR30_DEDICATEDREGS) -#define REGISTER_BYTES ((FR30_GENREGS + FR30_DEDICATEDREGS)*FR30_REGSIZE) - -/* Index within `registers' of the first byte of the space for - register N. */ -#define REGISTER_BYTE(N) ((N) * FR30_REGSIZE) - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ -#define REGISTER_NAMES \ -{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \ - "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ - "pc", "ps", "tbr", "rp", "ssp", "usp", "mdh", "mdl" } - -/* Offset from address of function to start of its code. - Zero on most machines. */ -#define FUNCTION_START_OFFSET 0 - -/* 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 - -/* Stack grows downward. */ - -#define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) - -#define R0_REGNUM 0 -#define R1_REGNUM 1 -#define R2_REGNUM 2 -#define R3_REGNUM 3 -#define R4_REGNUM 4 -#define R5_REGNUM 5 -#define R6_REGNUM 6 -#define R7_REGNUM 7 -#define R8_REGNUM 8 -#define R9_REGNUM 9 -#define R10_REGNUM 10 -#define R11_REGNUM 11 -#define R12_REGNUM 12 -#define R13_REGNUM 13 -#define FP_REGNUM 14 /* Frame pointer */ -#define SP_REGNUM 15 /* Stack pointer */ -#define PC_REGNUM 16 /* Program counter */ -#define RP_REGNUM 19 /* Return pointer */ - -#define FIRST_ARGREG R4_REGNUM /* first arg (or struct ret val addr) */ -#define LAST_ARGREG R7_REGNUM /* fourth (or third arg) */ -#define RETVAL_REG R4_REGNUM /* return vaue */ - -/* 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 FR30_REGSIZE - -/* Number of bytes of storage in the actual machine representation - for register N. */ -#define REGISTER_RAW_SIZE(N) FR30_REGSIZE - -/* Largest value REGISTER_RAW_SIZE can have. */ -#define MAX_REGISTER_RAW_SIZE FR30_REGSIZE - -/* Number of bytes of storage in the program's representation - for register N. */ -#define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N) - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ -#define MAX_REGISTER_VIRTUAL_SIZE FR30_REGSIZE - -extern void fr30_pop_frame (void); -#define POP_FRAME fr30_pop_frame() - -#define USE_GENERIC_DUMMY_FRAMES 1 -#define CALL_DUMMY {0} -#define CALL_DUMMY_START_OFFSET (0) -#define CALL_DUMMY_BREAKPOINT_OFFSET (0) -#define CALL_DUMMY_LOCATION AT_ENTRY_POINT -#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP) -#define CALL_DUMMY_ADDRESS() entry_point_address () -#define PUSH_RETURN_ADDRESS(PC, SP) (write_register(RP_REGNUM, CALL_DUMMY_ADDRESS()), SP) -#define PUSH_DUMMY_FRAME generic_push_dummy_frame () - -/* Number of bytes at start of arglist that are not really args. */ -#define FRAME_ARGS_SKIP 0 - -/* Return the GDB type object for the "standard" data type - of data in register N. */ -#define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int - -/* 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. */ -#define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - memcpy (VALBUF, REGBUF + REGISTER_BYTE(RETVAL_REG) + \ - (TYPE_LENGTH(TYPE) < 4 ? 4 - TYPE_LENGTH(TYPE) : 0), TYPE_LENGTH (TYPE)) - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ -#define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \ - extract_address (REGBUF + REGISTER_BYTE (RETVAL_REG), \ - REGISTER_RAW_SIZE (RETVAL_REG)) - -#define STORE_STRUCT_RETURN(ADDR, SP) \ - { write_register (RETVAL_REG, (ADDR)); } - -#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) -#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ -#define FRAME_NUM_ARGS(fi) (-1) - -/* Forward decls for prototypes */ -struct frame_info; -struct frame_saved_regs; -struct type; -struct value; - -#define EXTRA_FRAME_INFO \ - struct frame_saved_regs fsr; \ - int framesize; \ - int frameoffset; \ - int framereg; - -extern CORE_ADDR fr30_frame_chain (struct frame_info *fi); -#define FRAME_CHAIN(fi) fr30_frame_chain (fi) - -extern CORE_ADDR fr30_frame_saved_pc (struct frame_info *); -#define FRAME_SAVED_PC(fi) (fr30_frame_saved_pc (fi)) - -#define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM) - -extern CORE_ADDR fr30_skip_prologue (CORE_ADDR pc); -#define SKIP_PROLOGUE(pc) (fr30_skip_prologue (pc)) - -/* Write into appropriate registers a function return value of type - TYPE, given in virtual format. VALBUF is in the target byte order; - it's typically the VALUE_CONTENTS of some struct value, and those - are in the target's byte order. */ -extern void fr30_store_return_value (struct type *type, char *valbuf); - -#define STORE_RETURN_VALUE(TYPE,VALBUF) \ - (fr30_store_return_value ((TYPE), (VALBUF))) - -/* 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. */ -#define FRAME_FIND_SAVED_REGS(fi, regaddr) regaddr = fi->fsr - -/* Use INT #BREAKPOINT_INTNUM instruction for breakpoint */ -#define FR30_BREAKOP 0x1f /* opcode, type D instruction */ -#define BREAKPOINT_INTNUM 9 /* one of the reserved traps */ -#define BREAKPOINT {FR30_BREAKOP, BREAKPOINT_INTNUM} - -/* Define this for Wingdb */ -#define TARGET_FR30 - -/* Define other aspects of the stack frame. */ - -/* An expression that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. */ -extern int fr30_frameless_function_invocation (struct frame_info *frame); -#define FRAMELESS_FUNCTION_INVOCATION(FI) (fr30_frameless_function_invocation (FI)); - -extern void fr30_init_extra_frame_info (struct frame_info *fi); -#define INIT_EXTRA_FRAME_INFO(fromleaf, fi) fr30_init_extra_frame_info (fi) - -#define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI) - -extern CORE_ADDR -fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr); -#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \ - (fr30_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)) - -#define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) - -/* Fujitsu's ABI requires all structs to be passed using a pointer. - That is obviously not very efficient, so I am leaving the definitions - to make gdb work with GCC style struct passing, in case we decide - to go for better performance, rather than for compatibility with - Fujitsu (just change STRUCT_ALWAYS_BY_ADDR to 0) */ - -#define STRUCT_ALWAYS_BY_ADDR 1 - -#if(STRUCT_ALWAYS_BY_ADDR) -#define REG_STRUCT_HAS_ADDR(gcc_p,type) 1 -#else -/* more standard GCC (optimized) */ -#define REG_STRUCT_HAS_ADDR(gcc_p,type) \ - ((TYPE_LENGTH(type) > 4) && (TYPE_LENGTH(type) & 0x3)) -#endif -/* alway return struct by value by input pointer */ -#define USE_STRUCT_CONVENTION(GCC_P, TYPE) 1 - -/* The stack should always be aligned on a four-word boundary. */ -#define STACK_ALIGN(len) (((len) + 3) & ~3) - -/* I think the comment about this in value_arg_coerce is wrong; this - should be true on any system where you can rely on the prototyping - information. When this is true, value_arg_coerce will promote - floats to doubles iff the function is not prototyped. */ -#define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1) +// OBSOLETE /* Parameters for execution on a Fujitsu FR30 processor. +// OBSOLETE Copyright 1999, 2000 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE #define FR30_GENREGS 16 +// OBSOLETE #define FR30_DEDICATEDREGS 8 +// OBSOLETE #define FR30_REGSIZE 4 /* bytes */ +// OBSOLETE +// OBSOLETE #define NUM_REGS (FR30_GENREGS + FR30_DEDICATEDREGS) +// OBSOLETE #define REGISTER_BYTES ((FR30_GENREGS + FR30_DEDICATEDREGS)*FR30_REGSIZE) +// OBSOLETE +// OBSOLETE /* Index within `registers' of the first byte of the space for +// OBSOLETE register N. */ +// OBSOLETE #define REGISTER_BYTE(N) ((N) * FR30_REGSIZE) +// OBSOLETE +// OBSOLETE /* Initializer for an array of names of registers. +// OBSOLETE There should be NUM_REGS strings in this initializer. */ +// OBSOLETE #define REGISTER_NAMES \ +// OBSOLETE { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \ +// OBSOLETE "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ +// OBSOLETE "pc", "ps", "tbr", "rp", "ssp", "usp", "mdh", "mdl" } +// OBSOLETE +// OBSOLETE /* Offset from address of function to start of its code. +// OBSOLETE Zero on most machines. */ +// OBSOLETE #define FUNCTION_START_OFFSET 0 +// OBSOLETE +// OBSOLETE /* Amount PC must be decremented by after a breakpoint. +// OBSOLETE This is often the number of bytes in BREAKPOINT +// OBSOLETE but not always. */ +// OBSOLETE +// OBSOLETE #define DECR_PC_AFTER_BREAK 0 +// OBSOLETE +// OBSOLETE /* Stack grows downward. */ +// OBSOLETE +// OBSOLETE #define INNER_THAN(lhs,rhs) ((lhs) < (rhs)) +// OBSOLETE +// OBSOLETE #define R0_REGNUM 0 +// OBSOLETE #define R1_REGNUM 1 +// OBSOLETE #define R2_REGNUM 2 +// OBSOLETE #define R3_REGNUM 3 +// OBSOLETE #define R4_REGNUM 4 +// OBSOLETE #define R5_REGNUM 5 +// OBSOLETE #define R6_REGNUM 6 +// OBSOLETE #define R7_REGNUM 7 +// OBSOLETE #define R8_REGNUM 8 +// OBSOLETE #define R9_REGNUM 9 +// OBSOLETE #define R10_REGNUM 10 +// OBSOLETE #define R11_REGNUM 11 +// OBSOLETE #define R12_REGNUM 12 +// OBSOLETE #define R13_REGNUM 13 +// OBSOLETE #define FP_REGNUM 14 /* Frame pointer */ +// OBSOLETE #define SP_REGNUM 15 /* Stack pointer */ +// OBSOLETE #define PC_REGNUM 16 /* Program counter */ +// OBSOLETE #define RP_REGNUM 19 /* Return pointer */ +// OBSOLETE +// OBSOLETE #define FIRST_ARGREG R4_REGNUM /* first arg (or struct ret val addr) */ +// OBSOLETE #define LAST_ARGREG R7_REGNUM /* fourth (or third arg) */ +// OBSOLETE #define RETVAL_REG R4_REGNUM /* return vaue */ +// OBSOLETE +// OBSOLETE /* Say how long (ordinary) registers are. This is a piece of bogosity +// OBSOLETE used in push_word and a few other places; REGISTER_RAW_SIZE is the +// OBSOLETE real way to know how big a register is. */ +// OBSOLETE #define REGISTER_SIZE FR30_REGSIZE +// OBSOLETE +// OBSOLETE /* Number of bytes of storage in the actual machine representation +// OBSOLETE for register N. */ +// OBSOLETE #define REGISTER_RAW_SIZE(N) FR30_REGSIZE +// OBSOLETE +// OBSOLETE /* Largest value REGISTER_RAW_SIZE can have. */ +// OBSOLETE #define MAX_REGISTER_RAW_SIZE FR30_REGSIZE +// OBSOLETE +// OBSOLETE /* Number of bytes of storage in the program's representation +// OBSOLETE for register N. */ +// OBSOLETE #define REGISTER_VIRTUAL_SIZE(N) REGISTER_RAW_SIZE(N) +// OBSOLETE +// OBSOLETE /* Largest value REGISTER_VIRTUAL_SIZE can have. */ +// OBSOLETE #define MAX_REGISTER_VIRTUAL_SIZE FR30_REGSIZE +// OBSOLETE +// OBSOLETE extern void fr30_pop_frame (void); +// OBSOLETE #define POP_FRAME fr30_pop_frame() +// OBSOLETE +// OBSOLETE #define USE_GENERIC_DUMMY_FRAMES 1 +// OBSOLETE #define CALL_DUMMY {0} +// OBSOLETE #define CALL_DUMMY_START_OFFSET (0) +// OBSOLETE #define CALL_DUMMY_BREAKPOINT_OFFSET (0) +// OBSOLETE #define CALL_DUMMY_LOCATION AT_ENTRY_POINT +// OBSOLETE #define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP) +// OBSOLETE #define CALL_DUMMY_ADDRESS() entry_point_address () +// OBSOLETE #define PUSH_RETURN_ADDRESS(PC, SP) (write_register(RP_REGNUM, CALL_DUMMY_ADDRESS()), SP) +// OBSOLETE #define PUSH_DUMMY_FRAME generic_push_dummy_frame () +// OBSOLETE +// OBSOLETE /* Number of bytes at start of arglist that are not really args. */ +// OBSOLETE #define FRAME_ARGS_SKIP 0 +// OBSOLETE +// OBSOLETE /* Return the GDB type object for the "standard" data type +// OBSOLETE of data in register N. */ +// OBSOLETE #define REGISTER_VIRTUAL_TYPE(REG) builtin_type_int +// OBSOLETE +// OBSOLETE /* Extract from an array REGBUF containing the (raw) register state +// OBSOLETE a function return value of type TYPE, and copy that, in virtual format, +// OBSOLETE into VALBUF. */ +// OBSOLETE #define DEPRECATED_EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ +// OBSOLETE memcpy (VALBUF, REGBUF + REGISTER_BYTE(RETVAL_REG) + \ +// OBSOLETE (TYPE_LENGTH(TYPE) < 4 ? 4 - TYPE_LENGTH(TYPE) : 0), TYPE_LENGTH (TYPE)) +// OBSOLETE +// OBSOLETE /* Extract from an array REGBUF containing the (raw) register state +// OBSOLETE the address in which a function should return its structure value, +// OBSOLETE as a CORE_ADDR (or an expression that can be used as one). */ +// OBSOLETE #define DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \ +// OBSOLETE extract_address (REGBUF + REGISTER_BYTE (RETVAL_REG), \ +// OBSOLETE REGISTER_RAW_SIZE (RETVAL_REG)) +// OBSOLETE +// OBSOLETE #define STORE_STRUCT_RETURN(ADDR, SP) \ +// OBSOLETE { write_register (RETVAL_REG, (ADDR)); } +// OBSOLETE +// OBSOLETE #define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) +// OBSOLETE #define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) +// OBSOLETE +// OBSOLETE /* Return number of args passed to a frame. +// OBSOLETE Can return -1, meaning no way to tell. */ +// OBSOLETE #define FRAME_NUM_ARGS(fi) (-1) +// OBSOLETE +// OBSOLETE /* Forward decls for prototypes */ +// OBSOLETE struct frame_info; +// OBSOLETE struct frame_saved_regs; +// OBSOLETE struct type; +// OBSOLETE struct value; +// OBSOLETE +// OBSOLETE #define EXTRA_FRAME_INFO \ +// OBSOLETE struct frame_saved_regs fsr; \ +// OBSOLETE int framesize; \ +// OBSOLETE int frameoffset; \ +// OBSOLETE int framereg; +// OBSOLETE +// OBSOLETE extern CORE_ADDR fr30_frame_chain (struct frame_info *fi); +// OBSOLETE #define FRAME_CHAIN(fi) fr30_frame_chain (fi) +// OBSOLETE +// OBSOLETE extern CORE_ADDR fr30_frame_saved_pc (struct frame_info *); +// OBSOLETE #define FRAME_SAVED_PC(fi) (fr30_frame_saved_pc (fi)) +// OBSOLETE +// OBSOLETE #define SAVED_PC_AFTER_CALL(fi) read_register (RP_REGNUM) +// OBSOLETE +// OBSOLETE extern CORE_ADDR fr30_skip_prologue (CORE_ADDR pc); +// OBSOLETE #define SKIP_PROLOGUE(pc) (fr30_skip_prologue (pc)) +// OBSOLETE +// OBSOLETE /* Write into appropriate registers a function return value of type +// OBSOLETE TYPE, given in virtual format. VALBUF is in the target byte order; +// OBSOLETE it's typically the VALUE_CONTENTS of some struct value, and those +// OBSOLETE are in the target's byte order. */ +// OBSOLETE extern void fr30_store_return_value (struct type *type, char *valbuf); +// OBSOLETE +// OBSOLETE #define STORE_RETURN_VALUE(TYPE,VALBUF) \ +// OBSOLETE (fr30_store_return_value ((TYPE), (VALBUF))) +// OBSOLETE +// OBSOLETE /* Put here the code to store, into a struct frame_saved_regs, +// OBSOLETE the addresses of the saved registers of frame described by FRAME_INFO. +// OBSOLETE This includes special registers such as pc and fp saved in special +// OBSOLETE ways in the stack frame. sp is even more special: +// OBSOLETE the address we return for it IS the sp for the next frame. */ +// OBSOLETE #define FRAME_FIND_SAVED_REGS(fi, regaddr) regaddr = fi->fsr +// OBSOLETE +// OBSOLETE /* Use INT #BREAKPOINT_INTNUM instruction for breakpoint */ +// OBSOLETE #define FR30_BREAKOP 0x1f /* opcode, type D instruction */ +// OBSOLETE #define BREAKPOINT_INTNUM 9 /* one of the reserved traps */ +// OBSOLETE #define BREAKPOINT {FR30_BREAKOP, BREAKPOINT_INTNUM} +// OBSOLETE +// OBSOLETE /* Define this for Wingdb */ +// OBSOLETE #define TARGET_FR30 +// OBSOLETE +// OBSOLETE /* Define other aspects of the stack frame. */ +// OBSOLETE +// OBSOLETE /* An expression that tells us whether the function invocation represented +// OBSOLETE by FI does not have a frame on the stack associated with it. */ +// OBSOLETE extern int fr30_frameless_function_invocation (struct frame_info *frame); +// OBSOLETE #define FRAMELESS_FUNCTION_INVOCATION(FI) (fr30_frameless_function_invocation (FI)); +// OBSOLETE +// OBSOLETE extern void fr30_init_extra_frame_info (struct frame_info *fi); +// OBSOLETE #define INIT_EXTRA_FRAME_INFO(fromleaf, fi) fr30_init_extra_frame_info (fi) +// OBSOLETE +// OBSOLETE #define FRAME_CHAIN_VALID(FP, FI) generic_file_frame_chain_valid (FP, FI) +// OBSOLETE +// OBSOLETE extern CORE_ADDR +// OBSOLETE fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp, +// OBSOLETE int struct_return, CORE_ADDR struct_addr); +// OBSOLETE #define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \ +// OBSOLETE (fr30_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)) +// OBSOLETE +// OBSOLETE #define PC_IN_CALL_DUMMY(PC, SP, FP) generic_pc_in_call_dummy (PC, SP, FP) +// OBSOLETE +// OBSOLETE /* Fujitsu's ABI requires all structs to be passed using a pointer. +// OBSOLETE That is obviously not very efficient, so I am leaving the definitions +// OBSOLETE to make gdb work with GCC style struct passing, in case we decide +// OBSOLETE to go for better performance, rather than for compatibility with +// OBSOLETE Fujitsu (just change STRUCT_ALWAYS_BY_ADDR to 0) */ +// OBSOLETE +// OBSOLETE #define STRUCT_ALWAYS_BY_ADDR 1 +// OBSOLETE +// OBSOLETE #if(STRUCT_ALWAYS_BY_ADDR) +// OBSOLETE #define REG_STRUCT_HAS_ADDR(gcc_p,type) 1 +// OBSOLETE #else +// OBSOLETE /* more standard GCC (optimized) */ +// OBSOLETE #define REG_STRUCT_HAS_ADDR(gcc_p,type) \ +// OBSOLETE ((TYPE_LENGTH(type) > 4) && (TYPE_LENGTH(type) & 0x3)) +// OBSOLETE #endif +// OBSOLETE /* alway return struct by value by input pointer */ +// OBSOLETE #define USE_STRUCT_CONVENTION(GCC_P, TYPE) 1 +// OBSOLETE +// OBSOLETE /* The stack should always be aligned on a four-word boundary. */ +// OBSOLETE #define STACK_ALIGN(len) (((len) + 3) & ~3) +// OBSOLETE +// OBSOLETE /* I think the comment about this in value_arg_coerce is wrong; this +// OBSOLETE should be true on any system where you can rely on the prototyping +// OBSOLETE information. When this is true, value_arg_coerce will promote +// OBSOLETE floats to doubles iff the function is not prototyped. */ +// OBSOLETE #define COERCE_FLOAT_TO_DOUBLE(formal, actual) (1) diff --git a/gdb/configure.tgt b/gdb/configure.tgt index dd48ae5..6ef9d07 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -72,7 +72,7 @@ h8300-*-*) gdb_target=h8300 ;; h8500-*-*) gdb_target=h8500 ;; -fr30-*-elf*) gdb_target=fr30 ;; +# OBSOLETE fr30-*-elf*) gdb_target=fr30 ;; frv-*-*) gdb_target=frv ;; @@ -285,8 +285,8 @@ xstormy16-*-*) gdb_target=xstormy16 ;; vax-*-*) gdb_target=vax ;; -fr30-*-*) gdb_target=fr30 - ;; +# OBSOLETE fr30-*-*) gdb_target=fr30 +# OBSOLETE ;; v850*-*-*) gdb_target=v850 case ${gdb_host} in diff --git a/gdb/fr30-tdep.c b/gdb/fr30-tdep.c index 09f886f..12e9f7e 100644 --- a/gdb/fr30-tdep.c +++ b/gdb/fr30-tdep.c @@ -1,601 +1,601 @@ -/* Target-dependent code for the Fujitsu FR30. - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "obstack.h" -#include "target.h" -#include "value.h" -#include "bfd.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "symfile.h" -#include "regcache.h" - -/* An expression that tells us whether the function invocation represented - by FI does not have a frame on the stack associated with it. */ -int -fr30_frameless_function_invocation (struct frame_info *fi) -{ - int frameless; - CORE_ADDR func_start, after_prologue; - func_start = (get_pc_function_start ((fi)->pc) + - FUNCTION_START_OFFSET); - after_prologue = func_start; - after_prologue = SKIP_PROLOGUE (after_prologue); - frameless = (after_prologue == func_start); - return frameless; -} - -/* Function: pop_frame - This routine gets called when either the user uses the `return' - command, or the call dummy breakpoint gets hit. */ - -void -fr30_pop_frame (void) -{ - struct frame_info *frame = get_current_frame (); - int regnum; - CORE_ADDR sp = read_register (SP_REGNUM); - - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - { - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->fsr.regs[regnum] != 0) - { - write_register (regnum, - read_memory_unsigned_integer (frame->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum))); - } - write_register (SP_REGNUM, sp + frame->framesize); - } - flush_cached_frames (); -} - - -/* Function: fr30_store_return_value - Put a value where a caller expects to see it. Used by the 'return' - command. */ -void -fr30_store_return_value (struct type *type, - char *valbuf) -{ - /* Here's how the FR30 returns values (gleaned from gcc/config/ - fr30/fr30.h): - - If the return value is 32 bits long or less, it goes in r4. - - If the return value is 64 bits long or less, it goes in r4 (most - significant word) and r5 (least significant word. - - If the function returns a structure, of any size, the caller - passes the function an invisible first argument where the callee - should store the value. But GDB doesn't let you do that anyway. - - If you're returning a value smaller than a word, it's not really - necessary to zero the upper bytes of the register; the caller is - supposed to ignore them. However, the FR30 typically keeps its - values extended to the full register width, so we should emulate - that. */ - - /* The FR30 is big-endian, so if we return a small value (like a - short or a char), we need to position it correctly within the - register. We round the size up to a register boundary, and then - adjust the offset so as to place the value at the right end. */ - int value_size = TYPE_LENGTH (type); - int returned_size = (value_size + FR30_REGSIZE - 1) & ~(FR30_REGSIZE - 1); - int offset = (REGISTER_BYTE (RETVAL_REG) - + (returned_size - value_size)); - char *zeros = alloca (returned_size); - memset (zeros, 0, returned_size); - - write_register_bytes (REGISTER_BYTE (RETVAL_REG), zeros, returned_size); - write_register_bytes (offset, valbuf, value_size); -} - - -/* Function: skip_prologue - Return the address of the first code past the prologue of the function. */ - -CORE_ADDR -fr30_skip_prologue (CORE_ADDR pc) -{ - CORE_ADDR func_addr, func_end; - - /* See what the symbol table says */ - - if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - { - struct symtab_and_line sal; - - sal = find_pc_line (func_addr, 0); - - if (sal.line != 0 && sal.end < func_end) - { - return sal.end; - } - } - -/* Either we didn't find the start of this function (nothing we can do), - or there's no line info, or the line after the prologue is after - the end of the function (there probably isn't a prologue). */ - - return pc; -} - - -/* Function: push_arguments - Setup arguments and RP for a call to the target. First four args - go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on stack... - Structs are passed by reference. XXX not right now Z.R. - 64 bit quantities (doubles and long longs) may be split between - the regs and the stack. - When calling a function that returns a struct, a pointer to the struct - is passed in as a secret first argument (always in FIRST_ARGREG). - - Stack space for the args has NOT been allocated: that job is up to us. - */ - -CORE_ADDR -fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) -{ - int 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; - - argreg = FIRST_ARGREG; - - /* the struct_return pointer occupies the first parameter-passing reg */ - if (struct_return) - write_register (argreg++, struct_addr); - - stack_offset = 0; - - /* 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; - struct value *arg = args[argnum]; - struct type *arg_type = check_typedef (VALUE_TYPE (arg)); - struct type *target_type = TYPE_TARGET_TYPE (arg_type); - int len = TYPE_LENGTH (arg_type); - enum type_code typecode = TYPE_CODE (arg_type); - CORE_ADDR regval; - int newarg; - - val = (char *) VALUE_CONTENTS (arg); - - { - /* Copy the argument to general registers or the stack in - register-sized pieces. Large arguments are split between - registers and stack. */ - while (len > 0) - { - if (argreg <= LAST_ARGREG) - { - 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 - { - /* keep for later pushing */ - stack_args[nstack_args].val = val; - stack_args[nstack_args++].len = len; - break; - } - } - } - } - /* 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; -} - -void _initialize_fr30_tdep (void); - -void -_initialize_fr30_tdep (void) -{ - extern int print_insn_fr30 (bfd_vma, disassemble_info *); - tm_print_insn = print_insn_fr30; -} - -/* Function: check_prologue_cache - Check if prologue for this frame's PC has already been scanned. - If it has, copy the relevant information about that prologue and - return non-zero. Otherwise do not copy anything and return zero. - - The information saved in the cache includes: - * the frame register number; - * the size of the stack frame; - * the offsets of saved regs (relative to the old SP); and - * the offset from the stack pointer to the frame pointer - - The cache contains only one entry, since this is adequate - for the typical sequence of prologue scan requests we get. - When performing a backtrace, GDB will usually ask to scan - the same function twice in a row (once to get the frame chain, - and once to fill in the extra frame information). - */ - -static struct frame_info prologue_cache; - -static int -check_prologue_cache (struct frame_info *fi) -{ - int i; - - if (fi->pc == prologue_cache.pc) - { - fi->framereg = prologue_cache.framereg; - fi->framesize = prologue_cache.framesize; - fi->frameoffset = prologue_cache.frameoffset; - for (i = 0; i <= NUM_REGS; i++) - fi->fsr.regs[i] = prologue_cache.fsr.regs[i]; - return 1; - } - else - return 0; -} - - -/* Function: save_prologue_cache - Copy the prologue information from fi to the prologue cache. - */ - -static void -save_prologue_cache (struct frame_info *fi) -{ - int i; - - prologue_cache.pc = fi->pc; - prologue_cache.framereg = fi->framereg; - prologue_cache.framesize = fi->framesize; - prologue_cache.frameoffset = fi->frameoffset; - - for (i = 0; i <= NUM_REGS; i++) - { - prologue_cache.fsr.regs[i] = fi->fsr.regs[i]; - } -} - - -/* Function: scan_prologue - Scan the prologue of the function that contains PC, and record what - we find in PI. PI->fsr must be zeroed by the called. Returns the - pc after the prologue. Note that the addresses saved in pi->fsr - are actually just frame relative (negative offsets from the frame - pointer). This is because we don't know the actual value of the - frame pointer yet. In some circumstances, the frame pointer can't - be determined till after we have scanned the prologue. */ - -static void -fr30_scan_prologue (struct frame_info *fi) -{ - int sp_offset, fp_offset; - CORE_ADDR prologue_start, prologue_end, current_pc; - - /* Check if this function is already in the cache of frame information. */ - if (check_prologue_cache (fi)) - return; - - /* Assume there is no frame until proven otherwise. */ - fi->framereg = SP_REGNUM; - fi->framesize = 0; - fi->frameoffset = 0; - - /* Find the function prologue. If we can't find the function in - the symbol table, peek in the stack frame to find the PC. */ - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - /* Assume the prologue is everything between the first instruction - in the function and the first source line. */ - struct symtab_and_line sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) /* no line info, use current PC */ - prologue_end = fi->pc; - else if (sal.end < prologue_end) /* next line begins after fn end */ - prologue_end = sal.end; /* (probably means no prologue) */ - } - else - { - /* XXX Z.R. What now??? The following is entirely bogus */ - prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12; - prologue_end = prologue_start + 40; - } - - /* Now search the prologue looking for instructions that set up the - frame pointer, adjust the stack pointer, and save registers. */ - - sp_offset = fp_offset = 0; - for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2) - { - unsigned int insn; - - insn = read_memory_unsigned_integer (current_pc, 2); - - if ((insn & 0xfe00) == 0x8e00) /* stm0 or stm1 */ - { - int reg, mask = insn & 0xff; - - /* scan in one sweep - create virtual 16-bit mask from either insn's mask */ - if ((insn & 0x0100) == 0) - { - mask <<= 8; /* stm0 - move to upper byte in virtual mask */ - } - - /* Calculate offsets of saved registers (to be turned later into addresses). */ - for (reg = R4_REGNUM; reg <= R11_REGNUM; reg++) - if (mask & (1 << (15 - reg))) - { - sp_offset -= 4; - fi->fsr.regs[reg] = sp_offset; - } - } - else if ((insn & 0xfff0) == 0x1700) /* st rx,@-r15 */ - { - int reg = insn & 0xf; - - sp_offset -= 4; - fi->fsr.regs[reg] = sp_offset; - } - else if ((insn & 0xff00) == 0x0f00) /* enter */ - { - fp_offset = fi->fsr.regs[FP_REGNUM] = sp_offset - 4; - sp_offset -= 4 * (insn & 0xff); - fi->framereg = FP_REGNUM; - } - else if (insn == 0x1781) /* st rp,@-sp */ - { - sp_offset -= 4; - fi->fsr.regs[RP_REGNUM] = sp_offset; - } - else if (insn == 0x170e) /* st fp,@-sp */ - { - sp_offset -= 4; - fi->fsr.regs[FP_REGNUM] = sp_offset; - } - else if (insn == 0x8bfe) /* mov sp,fp */ - { - fi->framereg = FP_REGNUM; - } - else if ((insn & 0xff00) == 0xa300) /* addsp xx */ - { - sp_offset += 4 * (signed char) (insn & 0xff); - } - else if ((insn & 0xff0f) == 0x9b00 && /* ldi:20 xx,r0 */ - read_memory_unsigned_integer (current_pc + 4, 2) - == 0xac0f) /* sub r0,sp */ - { - /* large stack adjustment */ - sp_offset -= (((insn & 0xf0) << 12) | read_memory_unsigned_integer (current_pc + 2, 2)); - current_pc += 4; - } - else if (insn == 0x9f80 && /* ldi:32 xx,r0 */ - read_memory_unsigned_integer (current_pc + 6, 2) - == 0xac0f) /* sub r0,sp */ - { - /* large stack adjustment */ - sp_offset -= - (read_memory_unsigned_integer (current_pc + 2, 2) << 16 | - read_memory_unsigned_integer (current_pc + 4, 2)); - current_pc += 6; - } - } - - /* The frame size is just the negative of the offset (from the original SP) - of the last thing thing we pushed on the stack. The frame offset is - [new FP] - [new SP]. */ - fi->framesize = -sp_offset; - fi->frameoffset = fp_offset - sp_offset; - - save_prologue_cache (fi); -} - -/* Function: init_extra_frame_info - Setup the frame's frame pointer, pc, and frame addresses for saved - registers. Most of the work is done in scan_prologue(). - - Note that when we are called for the last frame (currently active frame), - that fi->pc and fi->frame will already be setup. However, fi->frame will - be valid only if this routine uses FP. For previous frames, fi-frame will - always be correct (since that is derived from fr30_frame_chain ()). - - We can be called with the PC in the call dummy under two circumstances. - First, during normal backtracing, second, while figuring out the frame - pointer just prior to calling the target function (see run_stack_dummy). */ - -void -fr30_init_extra_frame_info (struct frame_info *fi) -{ - int reg; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); - - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - { - /* We need to setup fi->frame here because run_stack_dummy gets it wrong - by assuming it's always FP. */ - fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); - fi->framesize = 0; - fi->frameoffset = 0; - return; - } - fr30_scan_prologue (fi); - - if (!fi->next) /* this is the innermost frame? */ - fi->frame = read_register (fi->framereg); - else - /* not the innermost frame */ - /* If we have an FP, the callee saved it. */ - if (fi->framereg == FP_REGNUM) - if (fi->next->fsr.regs[fi->framereg] != 0) - fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg], 4); - - /* Calculate actual addresses of saved registers using offsets determined - by fr30_scan_prologue. */ - for (reg = 0; reg < NUM_REGS; reg++) - if (fi->fsr.regs[reg] != 0) - { - fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset; - } -} - -/* Function: find_callers_reg - Find REGNUM on the stack. Otherwise, it's in an active register. - One thing we might want to do here is to check REGNUM against the - clobber mask, and somehow flag it as invalid if it isn't saved on - the stack somewhere. This would provide a graceful failure mode - when trying to get the value of caller-saves registers for an inner - frame. */ - -CORE_ADDR -fr30_find_callers_reg (struct frame_info *fi, int regnum) -{ - for (; fi; fi = fi->next) - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, regnum); - else if (fi->fsr.regs[regnum] != 0) - return read_memory_unsigned_integer (fi->fsr.regs[regnum], - REGISTER_RAW_SIZE (regnum)); - - return read_register (regnum); -} - - -/* Function: frame_chain - Figure out the frame prior to FI. Unfortunately, this involves - scanning the prologue of the caller, which will also be done - shortly by fr30_init_extra_frame_info. For the dummy frame, we - just return the stack pointer that was in use at the time the - function call was made. */ - - -CORE_ADDR -fr30_frame_chain (struct frame_info *fi) -{ - CORE_ADDR fn_start, callers_pc, fp; - struct frame_info caller_fi; - int framereg; - - /* is this a dummy frame? */ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return fi->frame; /* dummy frame same as caller's frame */ - - /* is caller-of-this a dummy frame? */ - callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ - fp = fr30_find_callers_reg (fi, FP_REGNUM); - if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) - return fp; /* dummy frame's frame may bear no relation to ours */ - - if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ - - framereg = fi->framereg; - - /* If the caller is the startup code, we're at the end of the chain. */ - if (find_pc_partial_function (callers_pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; - - memset (&caller_fi, 0, sizeof (caller_fi)); - caller_fi.pc = callers_pc; - fr30_scan_prologue (&caller_fi); - framereg = caller_fi.framereg; - - /* If the caller used a frame register, return its value. - Otherwise, return the caller's stack pointer. */ - if (framereg == FP_REGNUM) - return fr30_find_callers_reg (fi, framereg); - else - return fi->frame + fi->framesize; -} - -/* Function: frame_saved_pc - Find the caller of this frame. We do this by seeing if RP_REGNUM - is saved in the stack anywhere, otherwise we get it from the - registers. If the inner frame is a dummy frame, return its PC - instead of RP, because that's where "caller" of the dummy-frame - will be found. */ - -CORE_ADDR -fr30_frame_saved_pc (struct frame_info *fi) -{ - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); - else - return fr30_find_callers_reg (fi, RP_REGNUM); -} - -/* Function: fix_call_dummy - Pokes the callee function's address into the CALL_DUMMY assembly stub. - Assumes that the CALL_DUMMY looks like this: - jarl <offset24>, r31 - trap - */ - -int -fr30_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs, - struct value **args, struct type *type, int gcc_p) -{ - long offset24; - - offset24 = (long) fun - (long) entry_point_address (); - offset24 &= 0x3fffff; - offset24 |= 0xff800000; /* jarl <offset24>, r31 */ - - store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff); - store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16); - return 0; -} +// OBSOLETE /* Target-dependent code for the Fujitsu FR30. +// OBSOLETE Copyright 1999, 2000, 2001 Free Software Foundation, Inc. +// OBSOLETE +// OBSOLETE This file is part of GDB. +// OBSOLETE +// OBSOLETE This program is free software; you can redistribute it and/or modify +// OBSOLETE it under the terms of the GNU General Public License as published by +// OBSOLETE the Free Software Foundation; either version 2 of the License, or +// OBSOLETE (at your option) any later version. +// OBSOLETE +// OBSOLETE This program is distributed in the hope that it will be useful, +// OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of +// OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// OBSOLETE GNU General Public License for more details. +// OBSOLETE +// OBSOLETE You should have received a copy of the GNU General Public License +// OBSOLETE along with this program; if not, write to the Free Software +// OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, +// OBSOLETE Boston, MA 02111-1307, USA. */ +// OBSOLETE +// OBSOLETE #include "defs.h" +// OBSOLETE #include "frame.h" +// OBSOLETE #include "inferior.h" +// OBSOLETE #include "obstack.h" +// OBSOLETE #include "target.h" +// OBSOLETE #include "value.h" +// OBSOLETE #include "bfd.h" +// OBSOLETE #include "gdb_string.h" +// OBSOLETE #include "gdbcore.h" +// OBSOLETE #include "symfile.h" +// OBSOLETE #include "regcache.h" +// OBSOLETE +// OBSOLETE /* An expression that tells us whether the function invocation represented +// OBSOLETE by FI does not have a frame on the stack associated with it. */ +// OBSOLETE int +// OBSOLETE fr30_frameless_function_invocation (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE int frameless; +// OBSOLETE CORE_ADDR func_start, after_prologue; +// OBSOLETE func_start = (get_pc_function_start ((fi)->pc) + +// OBSOLETE FUNCTION_START_OFFSET); +// OBSOLETE after_prologue = func_start; +// OBSOLETE after_prologue = SKIP_PROLOGUE (after_prologue); +// OBSOLETE frameless = (after_prologue == func_start); +// OBSOLETE return frameless; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: pop_frame +// OBSOLETE This routine gets called when either the user uses the `return' +// OBSOLETE command, or the call dummy breakpoint gets hit. */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE fr30_pop_frame (void) +// OBSOLETE { +// OBSOLETE struct frame_info *frame = get_current_frame (); +// OBSOLETE int regnum; +// OBSOLETE CORE_ADDR sp = read_register (SP_REGNUM); +// OBSOLETE +// OBSOLETE if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) +// OBSOLETE generic_pop_dummy_frame (); +// OBSOLETE else +// OBSOLETE { +// OBSOLETE write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); +// OBSOLETE +// OBSOLETE for (regnum = 0; regnum < NUM_REGS; regnum++) +// OBSOLETE if (frame->fsr.regs[regnum] != 0) +// OBSOLETE { +// OBSOLETE write_register (regnum, +// OBSOLETE read_memory_unsigned_integer (frame->fsr.regs[regnum], +// OBSOLETE REGISTER_RAW_SIZE (regnum))); +// OBSOLETE } +// OBSOLETE write_register (SP_REGNUM, sp + frame->framesize); +// OBSOLETE } +// OBSOLETE flush_cached_frames (); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: fr30_store_return_value +// OBSOLETE Put a value where a caller expects to see it. Used by the 'return' +// OBSOLETE command. */ +// OBSOLETE void +// OBSOLETE fr30_store_return_value (struct type *type, +// OBSOLETE char *valbuf) +// OBSOLETE { +// OBSOLETE /* Here's how the FR30 returns values (gleaned from gcc/config/ +// OBSOLETE fr30/fr30.h): +// OBSOLETE +// OBSOLETE If the return value is 32 bits long or less, it goes in r4. +// OBSOLETE +// OBSOLETE If the return value is 64 bits long or less, it goes in r4 (most +// OBSOLETE significant word) and r5 (least significant word. +// OBSOLETE +// OBSOLETE If the function returns a structure, of any size, the caller +// OBSOLETE passes the function an invisible first argument where the callee +// OBSOLETE should store the value. But GDB doesn't let you do that anyway. +// OBSOLETE +// OBSOLETE If you're returning a value smaller than a word, it's not really +// OBSOLETE necessary to zero the upper bytes of the register; the caller is +// OBSOLETE supposed to ignore them. However, the FR30 typically keeps its +// OBSOLETE values extended to the full register width, so we should emulate +// OBSOLETE that. */ +// OBSOLETE +// OBSOLETE /* The FR30 is big-endian, so if we return a small value (like a +// OBSOLETE short or a char), we need to position it correctly within the +// OBSOLETE register. We round the size up to a register boundary, and then +// OBSOLETE adjust the offset so as to place the value at the right end. */ +// OBSOLETE int value_size = TYPE_LENGTH (type); +// OBSOLETE int returned_size = (value_size + FR30_REGSIZE - 1) & ~(FR30_REGSIZE - 1); +// OBSOLETE int offset = (REGISTER_BYTE (RETVAL_REG) +// OBSOLETE + (returned_size - value_size)); +// OBSOLETE char *zeros = alloca (returned_size); +// OBSOLETE memset (zeros, 0, returned_size); +// OBSOLETE +// OBSOLETE write_register_bytes (REGISTER_BYTE (RETVAL_REG), zeros, returned_size); +// OBSOLETE write_register_bytes (offset, valbuf, value_size); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: skip_prologue +// OBSOLETE Return the address of the first code past the prologue of the function. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE fr30_skip_prologue (CORE_ADDR pc) +// OBSOLETE { +// OBSOLETE CORE_ADDR func_addr, func_end; +// OBSOLETE +// OBSOLETE /* See what the symbol table says */ +// OBSOLETE +// OBSOLETE if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) +// OBSOLETE { +// OBSOLETE struct symtab_and_line sal; +// OBSOLETE +// OBSOLETE sal = find_pc_line (func_addr, 0); +// OBSOLETE +// OBSOLETE if (sal.line != 0 && sal.end < func_end) +// OBSOLETE { +// OBSOLETE return sal.end; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Either we didn't find the start of this function (nothing we can do), +// OBSOLETE or there's no line info, or the line after the prologue is after +// OBSOLETE the end of the function (there probably isn't a prologue). */ +// OBSOLETE +// OBSOLETE return pc; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: push_arguments +// OBSOLETE Setup arguments and RP for a call to the target. First four args +// OBSOLETE go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on stack... +// OBSOLETE Structs are passed by reference. XXX not right now Z.R. +// OBSOLETE 64 bit quantities (doubles and long longs) may be split between +// OBSOLETE the regs and the stack. +// OBSOLETE When calling a function that returns a struct, a pointer to the struct +// OBSOLETE is passed in as a secret first argument (always in FIRST_ARGREG). +// OBSOLETE +// OBSOLETE Stack space for the args has NOT been allocated: that job is up to us. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE fr30_push_arguments (int nargs, struct value **args, CORE_ADDR sp, +// OBSOLETE int struct_return, CORE_ADDR struct_addr) +// OBSOLETE { +// OBSOLETE int argreg; +// OBSOLETE int argnum; +// OBSOLETE int stack_offset; +// OBSOLETE struct stack_arg +// OBSOLETE { +// OBSOLETE char *val; +// OBSOLETE int len; +// OBSOLETE int offset; +// OBSOLETE }; +// OBSOLETE struct stack_arg *stack_args = +// OBSOLETE (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg)); +// OBSOLETE int nstack_args = 0; +// OBSOLETE +// OBSOLETE argreg = FIRST_ARGREG; +// OBSOLETE +// OBSOLETE /* the struct_return pointer occupies the first parameter-passing reg */ +// OBSOLETE if (struct_return) +// OBSOLETE write_register (argreg++, struct_addr); +// OBSOLETE +// OBSOLETE stack_offset = 0; +// OBSOLETE +// OBSOLETE /* Process args from left to right. Store as many as allowed in +// OBSOLETE registers, save the rest to be pushed on the stack */ +// OBSOLETE for (argnum = 0; argnum < nargs; argnum++) +// OBSOLETE { +// OBSOLETE char *val; +// OBSOLETE struct value *arg = args[argnum]; +// OBSOLETE struct type *arg_type = check_typedef (VALUE_TYPE (arg)); +// OBSOLETE struct type *target_type = TYPE_TARGET_TYPE (arg_type); +// OBSOLETE int len = TYPE_LENGTH (arg_type); +// OBSOLETE enum type_code typecode = TYPE_CODE (arg_type); +// OBSOLETE CORE_ADDR regval; +// OBSOLETE int newarg; +// OBSOLETE +// OBSOLETE val = (char *) VALUE_CONTENTS (arg); +// OBSOLETE +// OBSOLETE { +// OBSOLETE /* Copy the argument to general registers or the stack in +// OBSOLETE register-sized pieces. Large arguments are split between +// OBSOLETE registers and stack. */ +// OBSOLETE while (len > 0) +// OBSOLETE { +// OBSOLETE if (argreg <= LAST_ARGREG) +// OBSOLETE { +// OBSOLETE int partial_len = len < REGISTER_SIZE ? len : REGISTER_SIZE; +// OBSOLETE regval = extract_address (val, partial_len); +// OBSOLETE +// OBSOLETE /* It's a simple argument being passed in a general +// OBSOLETE register. */ +// OBSOLETE write_register (argreg, regval); +// OBSOLETE argreg++; +// OBSOLETE len -= partial_len; +// OBSOLETE val += partial_len; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* keep for later pushing */ +// OBSOLETE stack_args[nstack_args].val = val; +// OBSOLETE stack_args[nstack_args++].len = len; +// OBSOLETE break; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE } +// OBSOLETE /* now do the real stack pushing, process args right to left */ +// OBSOLETE while (nstack_args--) +// OBSOLETE { +// OBSOLETE sp -= stack_args[nstack_args].len; +// OBSOLETE write_memory (sp, stack_args[nstack_args].val, +// OBSOLETE stack_args[nstack_args].len); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Return adjusted stack pointer. */ +// OBSOLETE return sp; +// OBSOLETE } +// OBSOLETE +// OBSOLETE void _initialize_fr30_tdep (void); +// OBSOLETE +// OBSOLETE void +// OBSOLETE _initialize_fr30_tdep (void) +// OBSOLETE { +// OBSOLETE extern int print_insn_fr30 (bfd_vma, disassemble_info *); +// OBSOLETE tm_print_insn = print_insn_fr30; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: check_prologue_cache +// OBSOLETE Check if prologue for this frame's PC has already been scanned. +// OBSOLETE If it has, copy the relevant information about that prologue and +// OBSOLETE return non-zero. Otherwise do not copy anything and return zero. +// OBSOLETE +// OBSOLETE The information saved in the cache includes: +// OBSOLETE * the frame register number; +// OBSOLETE * the size of the stack frame; +// OBSOLETE * the offsets of saved regs (relative to the old SP); and +// OBSOLETE * the offset from the stack pointer to the frame pointer +// OBSOLETE +// OBSOLETE The cache contains only one entry, since this is adequate +// OBSOLETE for the typical sequence of prologue scan requests we get. +// OBSOLETE When performing a backtrace, GDB will usually ask to scan +// OBSOLETE the same function twice in a row (once to get the frame chain, +// OBSOLETE and once to fill in the extra frame information). +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static struct frame_info prologue_cache; +// OBSOLETE +// OBSOLETE static int +// OBSOLETE check_prologue_cache (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE if (fi->pc == prologue_cache.pc) +// OBSOLETE { +// OBSOLETE fi->framereg = prologue_cache.framereg; +// OBSOLETE fi->framesize = prologue_cache.framesize; +// OBSOLETE fi->frameoffset = prologue_cache.frameoffset; +// OBSOLETE for (i = 0; i <= NUM_REGS; i++) +// OBSOLETE fi->fsr.regs[i] = prologue_cache.fsr.regs[i]; +// OBSOLETE return 1; +// OBSOLETE } +// OBSOLETE else +// OBSOLETE return 0; +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: save_prologue_cache +// OBSOLETE Copy the prologue information from fi to the prologue cache. +// OBSOLETE */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE save_prologue_cache (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE int i; +// OBSOLETE +// OBSOLETE prologue_cache.pc = fi->pc; +// OBSOLETE prologue_cache.framereg = fi->framereg; +// OBSOLETE prologue_cache.framesize = fi->framesize; +// OBSOLETE prologue_cache.frameoffset = fi->frameoffset; +// OBSOLETE +// OBSOLETE for (i = 0; i <= NUM_REGS; i++) +// OBSOLETE { +// OBSOLETE prologue_cache.fsr.regs[i] = fi->fsr.regs[i]; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: scan_prologue +// OBSOLETE Scan the prologue of the function that contains PC, and record what +// OBSOLETE we find in PI. PI->fsr must be zeroed by the called. Returns the +// OBSOLETE pc after the prologue. Note that the addresses saved in pi->fsr +// OBSOLETE are actually just frame relative (negative offsets from the frame +// OBSOLETE pointer). This is because we don't know the actual value of the +// OBSOLETE frame pointer yet. In some circumstances, the frame pointer can't +// OBSOLETE be determined till after we have scanned the prologue. */ +// OBSOLETE +// OBSOLETE static void +// OBSOLETE fr30_scan_prologue (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE int sp_offset, fp_offset; +// OBSOLETE CORE_ADDR prologue_start, prologue_end, current_pc; +// OBSOLETE +// OBSOLETE /* Check if this function is already in the cache of frame information. */ +// OBSOLETE if (check_prologue_cache (fi)) +// OBSOLETE return; +// OBSOLETE +// OBSOLETE /* Assume there is no frame until proven otherwise. */ +// OBSOLETE fi->framereg = SP_REGNUM; +// OBSOLETE fi->framesize = 0; +// OBSOLETE fi->frameoffset = 0; +// OBSOLETE +// OBSOLETE /* Find the function prologue. If we can't find the function in +// OBSOLETE the symbol table, peek in the stack frame to find the PC. */ +// OBSOLETE if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) +// OBSOLETE { +// OBSOLETE /* Assume the prologue is everything between the first instruction +// OBSOLETE in the function and the first source line. */ +// OBSOLETE struct symtab_and_line sal = find_pc_line (prologue_start, 0); +// OBSOLETE +// OBSOLETE if (sal.line == 0) /* no line info, use current PC */ +// OBSOLETE prologue_end = fi->pc; +// OBSOLETE else if (sal.end < prologue_end) /* next line begins after fn end */ +// OBSOLETE prologue_end = sal.end; /* (probably means no prologue) */ +// OBSOLETE } +// OBSOLETE else +// OBSOLETE { +// OBSOLETE /* XXX Z.R. What now??? The following is entirely bogus */ +// OBSOLETE prologue_start = (read_memory_integer (fi->frame, 4) & 0x03fffffc) - 12; +// OBSOLETE prologue_end = prologue_start + 40; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Now search the prologue looking for instructions that set up the +// OBSOLETE frame pointer, adjust the stack pointer, and save registers. */ +// OBSOLETE +// OBSOLETE sp_offset = fp_offset = 0; +// OBSOLETE for (current_pc = prologue_start; current_pc < prologue_end; current_pc += 2) +// OBSOLETE { +// OBSOLETE unsigned int insn; +// OBSOLETE +// OBSOLETE insn = read_memory_unsigned_integer (current_pc, 2); +// OBSOLETE +// OBSOLETE if ((insn & 0xfe00) == 0x8e00) /* stm0 or stm1 */ +// OBSOLETE { +// OBSOLETE int reg, mask = insn & 0xff; +// OBSOLETE +// OBSOLETE /* scan in one sweep - create virtual 16-bit mask from either insn's mask */ +// OBSOLETE if ((insn & 0x0100) == 0) +// OBSOLETE { +// OBSOLETE mask <<= 8; /* stm0 - move to upper byte in virtual mask */ +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Calculate offsets of saved registers (to be turned later into addresses). */ +// OBSOLETE for (reg = R4_REGNUM; reg <= R11_REGNUM; reg++) +// OBSOLETE if (mask & (1 << (15 - reg))) +// OBSOLETE { +// OBSOLETE sp_offset -= 4; +// OBSOLETE fi->fsr.regs[reg] = sp_offset; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE else if ((insn & 0xfff0) == 0x1700) /* st rx,@-r15 */ +// OBSOLETE { +// OBSOLETE int reg = insn & 0xf; +// OBSOLETE +// OBSOLETE sp_offset -= 4; +// OBSOLETE fi->fsr.regs[reg] = sp_offset; +// OBSOLETE } +// OBSOLETE else if ((insn & 0xff00) == 0x0f00) /* enter */ +// OBSOLETE { +// OBSOLETE fp_offset = fi->fsr.regs[FP_REGNUM] = sp_offset - 4; +// OBSOLETE sp_offset -= 4 * (insn & 0xff); +// OBSOLETE fi->framereg = FP_REGNUM; +// OBSOLETE } +// OBSOLETE else if (insn == 0x1781) /* st rp,@-sp */ +// OBSOLETE { +// OBSOLETE sp_offset -= 4; +// OBSOLETE fi->fsr.regs[RP_REGNUM] = sp_offset; +// OBSOLETE } +// OBSOLETE else if (insn == 0x170e) /* st fp,@-sp */ +// OBSOLETE { +// OBSOLETE sp_offset -= 4; +// OBSOLETE fi->fsr.regs[FP_REGNUM] = sp_offset; +// OBSOLETE } +// OBSOLETE else if (insn == 0x8bfe) /* mov sp,fp */ +// OBSOLETE { +// OBSOLETE fi->framereg = FP_REGNUM; +// OBSOLETE } +// OBSOLETE else if ((insn & 0xff00) == 0xa300) /* addsp xx */ +// OBSOLETE { +// OBSOLETE sp_offset += 4 * (signed char) (insn & 0xff); +// OBSOLETE } +// OBSOLETE else if ((insn & 0xff0f) == 0x9b00 && /* ldi:20 xx,r0 */ +// OBSOLETE read_memory_unsigned_integer (current_pc + 4, 2) +// OBSOLETE == 0xac0f) /* sub r0,sp */ +// OBSOLETE { +// OBSOLETE /* large stack adjustment */ +// OBSOLETE sp_offset -= (((insn & 0xf0) << 12) | read_memory_unsigned_integer (current_pc + 2, 2)); +// OBSOLETE current_pc += 4; +// OBSOLETE } +// OBSOLETE else if (insn == 0x9f80 && /* ldi:32 xx,r0 */ +// OBSOLETE read_memory_unsigned_integer (current_pc + 6, 2) +// OBSOLETE == 0xac0f) /* sub r0,sp */ +// OBSOLETE { +// OBSOLETE /* large stack adjustment */ +// OBSOLETE sp_offset -= +// OBSOLETE (read_memory_unsigned_integer (current_pc + 2, 2) << 16 | +// OBSOLETE read_memory_unsigned_integer (current_pc + 4, 2)); +// OBSOLETE current_pc += 6; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* The frame size is just the negative of the offset (from the original SP) +// OBSOLETE of the last thing thing we pushed on the stack. The frame offset is +// OBSOLETE [new FP] - [new SP]. */ +// OBSOLETE fi->framesize = -sp_offset; +// OBSOLETE fi->frameoffset = fp_offset - sp_offset; +// OBSOLETE +// OBSOLETE save_prologue_cache (fi); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: init_extra_frame_info +// OBSOLETE Setup the frame's frame pointer, pc, and frame addresses for saved +// OBSOLETE registers. Most of the work is done in scan_prologue(). +// OBSOLETE +// OBSOLETE Note that when we are called for the last frame (currently active frame), +// OBSOLETE that fi->pc and fi->frame will already be setup. However, fi->frame will +// OBSOLETE be valid only if this routine uses FP. For previous frames, fi-frame will +// OBSOLETE always be correct (since that is derived from fr30_frame_chain ()). +// OBSOLETE +// OBSOLETE We can be called with the PC in the call dummy under two circumstances. +// OBSOLETE First, during normal backtracing, second, while figuring out the frame +// OBSOLETE pointer just prior to calling the target function (see run_stack_dummy). */ +// OBSOLETE +// OBSOLETE void +// OBSOLETE fr30_init_extra_frame_info (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE int reg; +// OBSOLETE +// OBSOLETE if (fi->next) +// OBSOLETE fi->pc = FRAME_SAVED_PC (fi->next); +// OBSOLETE +// OBSOLETE memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); +// OBSOLETE +// OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE { +// OBSOLETE /* We need to setup fi->frame here because run_stack_dummy gets it wrong +// OBSOLETE by assuming it's always FP. */ +// OBSOLETE fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); +// OBSOLETE fi->framesize = 0; +// OBSOLETE fi->frameoffset = 0; +// OBSOLETE return; +// OBSOLETE } +// OBSOLETE fr30_scan_prologue (fi); +// OBSOLETE +// OBSOLETE if (!fi->next) /* this is the innermost frame? */ +// OBSOLETE fi->frame = read_register (fi->framereg); +// OBSOLETE else +// OBSOLETE /* not the innermost frame */ +// OBSOLETE /* If we have an FP, the callee saved it. */ +// OBSOLETE if (fi->framereg == FP_REGNUM) +// OBSOLETE if (fi->next->fsr.regs[fi->framereg] != 0) +// OBSOLETE fi->frame = read_memory_integer (fi->next->fsr.regs[fi->framereg], 4); +// OBSOLETE +// OBSOLETE /* Calculate actual addresses of saved registers using offsets determined +// OBSOLETE by fr30_scan_prologue. */ +// OBSOLETE for (reg = 0; reg < NUM_REGS; reg++) +// OBSOLETE if (fi->fsr.regs[reg] != 0) +// OBSOLETE { +// OBSOLETE fi->fsr.regs[reg] += fi->frame + fi->framesize - fi->frameoffset; +// OBSOLETE } +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: find_callers_reg +// OBSOLETE Find REGNUM on the stack. Otherwise, it's in an active register. +// OBSOLETE One thing we might want to do here is to check REGNUM against the +// OBSOLETE clobber mask, and somehow flag it as invalid if it isn't saved on +// OBSOLETE the stack somewhere. This would provide a graceful failure mode +// OBSOLETE when trying to get the value of caller-saves registers for an inner +// OBSOLETE frame. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE fr30_find_callers_reg (struct frame_info *fi, int regnum) +// OBSOLETE { +// OBSOLETE for (; fi; fi = fi->next) +// OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE return generic_read_register_dummy (fi->pc, fi->frame, regnum); +// OBSOLETE else if (fi->fsr.regs[regnum] != 0) +// OBSOLETE return read_memory_unsigned_integer (fi->fsr.regs[regnum], +// OBSOLETE REGISTER_RAW_SIZE (regnum)); +// OBSOLETE +// OBSOLETE return read_register (regnum); +// OBSOLETE } +// OBSOLETE +// OBSOLETE +// OBSOLETE /* Function: frame_chain +// OBSOLETE Figure out the frame prior to FI. Unfortunately, this involves +// OBSOLETE scanning the prologue of the caller, which will also be done +// OBSOLETE shortly by fr30_init_extra_frame_info. For the dummy frame, we +// OBSOLETE just return the stack pointer that was in use at the time the +// OBSOLETE function call was made. */ +// OBSOLETE +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE fr30_frame_chain (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE CORE_ADDR fn_start, callers_pc, fp; +// OBSOLETE struct frame_info caller_fi; +// OBSOLETE int framereg; +// OBSOLETE +// OBSOLETE /* is this a dummy frame? */ +// OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE return fi->frame; /* dummy frame same as caller's frame */ +// OBSOLETE +// OBSOLETE /* is caller-of-this a dummy frame? */ +// OBSOLETE callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */ +// OBSOLETE fp = fr30_find_callers_reg (fi, FP_REGNUM); +// OBSOLETE if (PC_IN_CALL_DUMMY (callers_pc, fp, fp)) +// OBSOLETE return fp; /* dummy frame's frame may bear no relation to ours */ +// OBSOLETE +// OBSOLETE if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) +// OBSOLETE if (fn_start == entry_point_address ()) +// OBSOLETE return 0; /* in _start fn, don't chain further */ +// OBSOLETE +// OBSOLETE framereg = fi->framereg; +// OBSOLETE +// OBSOLETE /* If the caller is the startup code, we're at the end of the chain. */ +// OBSOLETE if (find_pc_partial_function (callers_pc, 0, &fn_start, 0)) +// OBSOLETE if (fn_start == entry_point_address ()) +// OBSOLETE return 0; +// OBSOLETE +// OBSOLETE memset (&caller_fi, 0, sizeof (caller_fi)); +// OBSOLETE caller_fi.pc = callers_pc; +// OBSOLETE fr30_scan_prologue (&caller_fi); +// OBSOLETE framereg = caller_fi.framereg; +// OBSOLETE +// OBSOLETE /* If the caller used a frame register, return its value. +// OBSOLETE Otherwise, return the caller's stack pointer. */ +// OBSOLETE if (framereg == FP_REGNUM) +// OBSOLETE return fr30_find_callers_reg (fi, framereg); +// OBSOLETE else +// OBSOLETE return fi->frame + fi->framesize; +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: frame_saved_pc +// OBSOLETE Find the caller of this frame. We do this by seeing if RP_REGNUM +// OBSOLETE is saved in the stack anywhere, otherwise we get it from the +// OBSOLETE registers. If the inner frame is a dummy frame, return its PC +// OBSOLETE instead of RP, because that's where "caller" of the dummy-frame +// OBSOLETE will be found. */ +// OBSOLETE +// OBSOLETE CORE_ADDR +// OBSOLETE fr30_frame_saved_pc (struct frame_info *fi) +// OBSOLETE { +// OBSOLETE if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) +// OBSOLETE return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM); +// OBSOLETE else +// OBSOLETE return fr30_find_callers_reg (fi, RP_REGNUM); +// OBSOLETE } +// OBSOLETE +// OBSOLETE /* Function: fix_call_dummy +// OBSOLETE Pokes the callee function's address into the CALL_DUMMY assembly stub. +// OBSOLETE Assumes that the CALL_DUMMY looks like this: +// OBSOLETE jarl <offset24>, r31 +// OBSOLETE trap +// OBSOLETE */ +// OBSOLETE +// OBSOLETE int +// OBSOLETE fr30_fix_call_dummy (char *dummy, CORE_ADDR sp, CORE_ADDR fun, int nargs, +// OBSOLETE struct value **args, struct type *type, int gcc_p) +// OBSOLETE { +// OBSOLETE long offset24; +// OBSOLETE +// OBSOLETE offset24 = (long) fun - (long) entry_point_address (); +// OBSOLETE offset24 &= 0x3fffff; +// OBSOLETE offset24 |= 0xff800000; /* jarl <offset24>, r31 */ +// OBSOLETE +// OBSOLETE store_unsigned_integer ((unsigned int *) &dummy[2], 2, offset24 & 0xffff); +// OBSOLETE store_unsigned_integer ((unsigned int *) &dummy[0], 2, offset24 >> 16); +// OBSOLETE return 0; +// OBSOLETE } |