]> Git Repo - binutils.git/blob - gdb/config/a29k/tm-vx29k.h
Delete HOST_BYTE_ORDER.
[binutils.git] / gdb / config / a29k / tm-vx29k.h
1 /* Target machine description for VxWorks on the 29k, for GDB, the GNU debugger.
2    Copyright 1994, 1995, 1998, 1999, 2000 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "regcache.h"
23 #include "value.h"
24 #include "a29k/tm-a29k.h"
25 #include "tm-vxworks.h"
26
27 /* Number of registers in a ptrace_getregs call. */
28
29 #define VX_NUM_REGS (NUM_REGS)
30
31 /* Number of registers in a ptrace_getfpregs call. */
32
33 /* #define VX_SIZE_FPREGS */
34
35 /* This is almost certainly the wrong place for this: */
36 #define LR2_REGNUM 34
37 \f
38
39 /* Vxworks has its own CALL_DUMMY since it manages breakpoints in the kernel */
40
41 #undef CALL_DUMMY
42
43 /* Replace the breakpoint instruction in the CALL_DUMMY with a nop.
44    For Vxworks, the breakpoint is set and deleted by calls to
45    CALL_DUMMY_BREAK_SET and CALL_DUMMY_BREAK_DELETE.  */
46
47 #error "This file is broken.  GDB does not define HOST_BYTE_ORDER."
48 #if TARGET_BYTE_ORDER == HOST_BYTE_ORDER
49 #define CALL_DUMMY {0x0400870f,\
50                 0x36008200|(MSP_HW_REGNUM), \
51                 0x15000040|(MSP_HW_REGNUM<<8)|(MSP_HW_REGNUM<<16), \
52                 0x03ff80ff, 0x02ff80ff, 0xc8008080, 0x70400101, 0x70400101}
53 #else /* Byte order differs.  */
54 #define CALL_DUMMY {0x0f870004,\
55                 0x00820036|(MSP_HW_REGNUM << 24), \
56                 0x40000015|(MSP_HW_REGNUM<<8)|(MSP_HW_REGNUM<<16), \
57                 0xff80ff03, 0xff80ff02, 0x808000c8, 0x01014070, 0x01014070}
58 #endif /* Byte order differs.  */
59
60
61 /* For the basic CALL_DUMMY definitions, see "tm-29k.h."  We use the
62    same CALL_DUMMY code, but define FIX_CALL_DUMMY (and related macros)
63    locally to handle remote debugging of VxWorks targets.  The difference
64    is in the setting and clearing of the breakpoint at the end of the
65    CALL_DUMMY code fragment; under VxWorks, we can't simply insert a
66    breakpoint instruction into the code, since that would interfere with
67    the breakpoint management mechanism on the target.
68    Note that CALL_DUMMY is a piece of code that is used to call any C function
69    thru VxGDB */
70
71 /* The offset of the instruction within the CALL_DUMMY code where we
72    want the inferior to stop after the function call has completed.
73    call_function_by_hand () sets a breakpoint here (via CALL_DUMMY_BREAK_SET),
74    which POP_FRAME later deletes (via CALL_DUMMY_BREAK_DELETE).  */
75
76 #define CALL_DUMMY_STOP_OFFSET (7 * 4)
77
78 /* The offset of the first instruction of the CALL_DUMMY code fragment
79    relative to the frame pointer for a dummy frame.  This is equal to
80    the size of the CALL_DUMMY plus the arg_slop area size (see the diagram
81    in "tm-29k.h").  */
82 /* PAD : the arg_slop area size doesn't appear to me to be useful since, the
83    call dummy code no longer modify the msp. See below. This must be checked. */
84
85 #define CALL_DUMMY_OFFSET_IN_FRAME (CALL_DUMMY_LENGTH + 16 * 4)
86
87 /* Insert the specified number of args and function address
88    into a CALL_DUMMY sequence stored at DUMMYNAME, replace the third
89    instruction (add msp, msp, 16*4) with a nop, and leave the final nop.
90    We can't keep using a CALL_DUMMY that modify the msp since, for VxWorks,
91    CALL_DUMMY is stored in the Memory Stack. Adding 16 words to the msp
92    would then make possible for the inferior to overwrite the CALL_DUMMY code,
93    thus creating a lot of trouble when exiting the inferior to come back in
94    a CALL_DUMMY code that no longer exists... Furthermore, ESF are also stored
95    from the msp in the memory stack. If msp is set higher than the dummy code,
96    an ESF may clobber this code. */
97
98 #if TARGET_BYTE_ORDER == BIG_ENDIAN
99 #define NOP_INSTR  0x70400101
100 #else /* Target is little endian */
101 #define NOP_INSTR  0x01014070
102 #endif
103
104 #undef FIX_CALL_DUMMY
105 #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)  \
106   {                                                                   \
107     *(int *)((char *)dummyname + 8) = NOP_INSTR;                      \
108     STUFF_I16((char *)dummyname + CONST_INSN, fun);                   \
109     STUFF_I16((char *)dummyname + CONST_INSN + 4, fun >> 16);         \
110   }
111
112 /* For VxWorks, CALL_DUMMY must be stored in the stack of the task that is
113    being debugged and executed "in the context of" this task */
114
115 #undef CALL_DUMMY_LOCATION
116 #define CALL_DUMMY_LOCATION     ON_STACK
117
118 /* Set or delete a breakpoint at the location within a CALL_DUMMY code
119    fragment where we want the target program to stop after the function
120    call is complete.  CALL_DUMMY_ADDR is the address of the first
121    instruction in the CALL_DUMMY.  DUMMY_FRAME_ADDR is the value of the
122    frame pointer in the dummy frame.
123
124    NOTE: in the both of the following definitions, we take advantage of
125    knowledge of the implementation of the target breakpoint operation,
126    in that we pass a null pointer as the second argument.  It seems
127    reasonable to assume that any target requiring the use of 
128    CALL_DUMMY_BREAK_{SET,DELETE} will not store the breakpoint
129    shadow contents in GDB; in any case, this assumption is vaild
130    for all VxWorks-related targets.  */
131
132 #define CALL_DUMMY_BREAK_SET(call_dummy_addr) \
133   target_insert_breakpoint ((call_dummy_addr) + CALL_DUMMY_STOP_OFFSET, \
134                             (char *) 0)
135
136 #define CALL_DUMMY_BREAK_DELETE(dummy_frame_addr) \
137   target_remove_breakpoint ((dummy_frame_addr) - (CALL_DUMMY_OFFSET_IN_FRAME \
138                                                   - CALL_DUMMY_STOP_OFFSET), \
139                             (char *) 0)
140
141 /* Return nonzero if the pc is executing within a CALL_DUMMY frame.  */
142
143 #define PC_IN_CALL_DUMMY(pc, sp, frame_address) \
144   ((pc) >= (sp) \
145     && (pc) <= (sp) + CALL_DUMMY_OFFSET_IN_FRAME + CALL_DUMMY_LENGTH)
146
147 /* Defining this prevents us from trying to pass a structure-valued argument
148    to a function called via the CALL_DUMMY mechanism.  This is not handled
149    properly in call_function_by_hand (), and the fix might require re-writing
150    the CALL_DUMMY handling for all targets (at least, a clean solution
151    would probably require this).  Arguably, this should go in "tm-29k.h"
152    rather than here.  */
153
154 #define STRUCT_VAL_ARGS_UNSUPPORTED
155
156 #define BKPT_OFFSET     (7 * 4)
157 #define BKPT_INSTR      0x72500101
158
159 #undef FIX_CALL_DUMMY
160 #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)   \
161   {\
162     STUFF_I16((char *)dummyname + CONST_INSN, fun);\
163     STUFF_I16((char *)dummyname + CONST_INSN + 4, fun >> 16);\
164     *(int *)((char *)dummyname + BKPT_OFFSET) = BKPT_INSTR;\
165   }
166 \f
167
168 /* Offsets into jmp_buf.  They are derived from VxWorks' REG_SET struct
169    (see VxWorks' setjmp.h). Note that Sun2, Sun3 and SunOS4 and VxWorks have
170    different REG_SET structs, hence different layouts for the jmp_buf struct.
171    Only JB_PC is needed for getting the saved PC value.  */
172
173 #define JB_ELEMENT_SIZE 4       /* size of each element in jmp_buf */
174 #define JB_PC           3       /* offset of pc (pc1) in jmp_buf */
175
176 /* Figure out where the longjmp will land.  We expect that we have just entered
177    longjmp and haven't yet setup the stack frame, so the args are still in the
178    output regs.  lr2 (LR2_REGNUM) points at the jmp_buf structure from which we
179    extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
180    This routine returns true on success */
181
182 #define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
183 extern int get_longjmp_target (CORE_ADDR *);
184
185 /* VxWorks adjusts the PC after a breakpoint has been hit.  */
186
187 #undef DECR_PC_AFTER_BREAK
188 #define DECR_PC_AFTER_BREAK 0
189
190 /* Do whatever promotions are appropriate on a value being returned
191    from a function.  VAL is the user-supplied value, and FUNC_TYPE
192    is the return type of the function if known, else 0.
193
194    For the Am29k, as far as I understand, if the function return type is known,
195    cast the value to that type; otherwise, ensure that integer return values
196    fill all of gr96.
197
198    This definition really belongs in "tm-29k.h", since it applies
199    to most Am29K-based systems; but once moved into that file, it might
200    need to be redefined for all Am29K-based targets that also redefine
201    STORE_RETURN_VALUE.  For now, to be safe, we define it here.  */
202
203 #define PROMOTE_RETURN_VALUE(val, func_type) \
204   do {                                                                  \
205       if (func_type)                                                    \
206         val = value_cast (func_type, val);                              \
207       if ((TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT                \
208            || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ENUM)           \
209           && TYPE_LENGTH (VALUE_TYPE (val)) < REGISTER_RAW_SIZE (0))    \
210         val = value_cast (builtin_type_int, val);                       \
211   } while (0)
212
213 extern int vx29k_frame_chain_valid (CORE_ADDR, struct frame_info *);
214 #define FRAME_CHAIN_VALID(chain, thisframe) vx29k_frame_chain_valid (chain, thisframe)
215
216 extern CORE_ADDR frame_saved_call_site ();
217
218 #undef PREPARE_TO_INIT_FRAME_INFO
219 #define PREPARE_TO_INIT_FRAME_INFO(fci) do {                                  \
220   long current_msp = read_register (MSP_REGNUM);                              \
221   if (PC_IN_CALL_DUMMY (fci->pc, current_msp, 0))                             \
222     {                                                                         \
223       fci->rsize = DUMMY_FRAME_RSIZE;                                         \
224       fci->msize = 0;                                                         \
225       fci->saved_msp =                                                        \
226         read_register_stack_integer (fci->frame + DUMMY_FRAME_RSIZE - 4, 4);  \
227       fci->flags |= (TRANSPARENT|MFP_USED);                                   \
228       return;                                                                 \
229     }                                                                         \
230   } while (0)
This page took 0.0664 seconds and 4 git commands to generate.