OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [config/] [a29k/] [tm-vx29k.h] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.