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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [gdb/] [i386-nto-tdep.c] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 jlechner
/* Target-dependent code for QNX Neutrino x86.
2
 
3
   Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
4
 
5
   Contributed by QNX Software Systems Ltd.
6
 
7
   This file is part of GDB.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
#include "defs.h"
23
#include "frame.h"
24
#include "osabi.h"
25
#include "regcache.h"
26
#include "target.h"
27
 
28
#include "gdb_assert.h"
29
#include "gdb_string.h"
30
 
31
#include "i386-tdep.h"
32
#include "i387-tdep.h"
33
#include "nto-tdep.h"
34
#include "solib.h"
35
#include "solib-svr4.h"
36
 
37
/* Target vector for QNX NTO x86.  */
38
static struct nto_target_ops i386_nto_target;
39
 
40
#ifndef X86_CPU_FXSR
41
#define X86_CPU_FXSR (1L << 12)
42
#endif
43
 
44
/* Why 13?  Look in our /usr/include/x86/context.h header at the
45
   x86_cpu_registers structure and you'll see an 'exx' junk register
46
   that is just filler.  Don't ask me, ask the kernel guys.  */
47
#define NUM_GPREGS 13
48
 
49
/* Mapping between the general-purpose registers in `struct xxx'
50
   format and GDB's register cache layout.  */
51
 
52
/* From <x86/context.h>.  */
53
static int i386nto_gregset_reg_offset[] =
54
{
55
  7 * 4,                        /* %eax */
56
  6 * 4,                        /* %ecx */
57
  5 * 4,                        /* %edx */
58
  4 * 4,                        /* %ebx */
59
  11 * 4,                       /* %esp */
60
  2 * 4,                        /* %epb */
61
  1 * 4,                        /* %esi */
62
 
63
  8 * 4,                        /* %eip */
64
  10 * 4,                       /* %eflags */
65
  9 * 4,                        /* %cs */
66
  12 * 4,                       /* %ss */
67
  -1                            /* filler */
68
};
69
 
70
/* Given a GDB register number REGNUM, return the offset into
71
   Neutrino's register structure or -1 if the register is unknown.  */
72
 
73
static int
74
nto_reg_offset (int regnum)
75
{
76
  if (regnum >= 0 && regnum < ARRAY_SIZE (i386nto_gregset_reg_offset))
77
    return i386nto_gregset_reg_offset[regnum];
78
 
79
  return -1;
80
}
81
 
82
static void
83
i386nto_supply_gregset (struct regcache *regcache, char *gpregs)
84
{
85
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
86
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
87
 
88
  if(tdep->gregset == NULL)
89
    tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,
90
                                  i386_collect_gregset);
91
 
92
  gdb_assert (tdep->gregset_reg_offset == i386nto_gregset_reg_offset);
93
  tdep->gregset->supply_regset (tdep->gregset, regcache, -1,
94
                                gpregs, NUM_GPREGS * 4);
95
}
96
 
97
static void
98
i386nto_supply_fpregset (struct regcache *regcache, char *fpregs)
99
{
100
  if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
101
    i387_supply_fxsave (regcache, -1, fpregs);
102
  else
103
    i387_supply_fsave (regcache, -1, fpregs);
104
}
105
 
106
static void
107
i386nto_supply_regset (struct regcache *regcache, int regset, char *data)
108
{
109
  switch (regset)
110
    {
111
    case NTO_REG_GENERAL:
112
      i386nto_supply_gregset (regcache, data);
113
      break;
114
    case NTO_REG_FLOAT:
115
      i386nto_supply_fpregset (regcache, data);
116
      break;
117
    }
118
}
119
 
120
static int
121
i386nto_regset_id (int regno)
122
{
123
  if (regno == -1)
124
    return NTO_REG_END;
125
  else if (regno < I386_NUM_GREGS)
126
    return NTO_REG_GENERAL;
127
  else if (regno < I386_NUM_GREGS + I386_NUM_FREGS)
128
    return NTO_REG_FLOAT;
129
 
130
  return -1;                    /* Error.  */
131
}
132
 
133
static int
134
i386nto_register_area (int regno, int regset, unsigned *off)
135
{
136
  int len;
137
 
138
  *off = 0;
139
  if (regset == NTO_REG_GENERAL)
140
    {
141
      if (regno == -1)
142
        return NUM_GPREGS * 4;
143
 
144
      *off = nto_reg_offset (regno);
145
      if (*off == -1)
146
        return 0;
147
      return 4;
148
    }
149
  else if (regset == NTO_REG_FLOAT)
150
    {
151
      unsigned off_adjust, regsize, regset_size;
152
 
153
      if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
154
        {
155
          off_adjust = 32;
156
          regsize = 16;
157
          regset_size = 512;
158
        }
159
      else
160
        {
161
          off_adjust = 28;
162
          regsize = 10;
163
          regset_size = 128;
164
        }
165
 
166
      if (regno == -1)
167
        return regset_size;
168
 
169
      *off = (regno - gdbarch_fp0_regnum (current_gdbarch))
170
             * regsize + off_adjust;
171
      return 10;
172
      /* Why 10 instead of regsize?  GDB only stores 10 bytes per FP
173
         register so if we're sending a register back to the target,
174
         we only want pdebug to write 10 bytes so as not to clobber
175
         the reserved 6 bytes in the fxsave structure.  */
176
    }
177
  return -1;
178
}
179
 
180
static int
181
i386nto_regset_fill (const struct regcache *regcache, int regset, char *data)
182
{
183
  if (regset == NTO_REG_GENERAL)
184
    {
185
      int regno;
186
 
187
      for (regno = 0; regno < NUM_GPREGS; regno++)
188
        {
189
          int offset = nto_reg_offset (regno);
190
          if (offset != -1)
191
            regcache_raw_collect (regcache, regno, data + offset);
192
        }
193
    }
194
  else if (regset == NTO_REG_FLOAT)
195
    {
196
      if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
197
        i387_collect_fxsave (regcache, -1, data);
198
      else
199
        i387_collect_fsave (regcache, -1, data);
200
    }
201
  else
202
    return -1;
203
 
204
  return 0;
205
}
206
 
207
/* Return whether the frame preceding NEXT_FRAME corresponds to a QNX
208
   Neutrino sigtramp routine.  */
209
 
210
static int
211
i386nto_sigtramp_p (struct frame_info *next_frame)
212
{
213
  CORE_ADDR pc = frame_pc_unwind (next_frame);
214
  char *name;
215
 
216
  find_pc_partial_function (pc, &name, NULL, NULL);
217
  return name && strcmp ("__signalstub", name) == 0;
218
}
219
 
220
#define I386_NTO_SIGCONTEXT_OFFSET 136
221
 
222
/* Assuming NEXT_FRAME is a frame following a QNX Neutrino sigtramp
223
   routine, return the address of the associated sigcontext structure.  */
224
 
225
static CORE_ADDR
226
i386nto_sigcontext_addr (struct frame_info *next_frame)
227
{
228
  char buf[4];
229
  CORE_ADDR sp;
230
 
231
  frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
232
  sp = extract_unsigned_integer (buf, 4);
233
 
234
  return sp + I386_NTO_SIGCONTEXT_OFFSET;
235
}
236
 
237
static void
238
init_i386nto_ops (void)
239
{
240
  i386_nto_target.regset_id = i386nto_regset_id;
241
  i386_nto_target.supply_gregset = i386nto_supply_gregset;
242
  i386_nto_target.supply_fpregset = i386nto_supply_fpregset;
243
  i386_nto_target.supply_altregset = nto_dummy_supply_regset;
244
  i386_nto_target.supply_regset = i386nto_supply_regset;
245
  i386_nto_target.register_area = i386nto_register_area;
246
  i386_nto_target.regset_fill = i386nto_regset_fill;
247
  i386_nto_target.fetch_link_map_offsets =
248
    svr4_ilp32_fetch_link_map_offsets;
249
}
250
 
251
static void
252
i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
253
{
254
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
255
  static struct target_so_ops nto_svr4_so_ops;
256
 
257
  /* Deal with our strange signals.  */
258
  nto_initialize_signals ();
259
 
260
  /* NTO uses ELF.  */
261
  i386_elf_init_abi (info, gdbarch);
262
 
263
  /* Neutrino rewinds to look more normal.  Need to override the i386
264
     default which is [unfortunately] to decrement the PC.  */
265
  set_gdbarch_decr_pc_after_break (gdbarch, 0);
266
 
267
  tdep->gregset_reg_offset = i386nto_gregset_reg_offset;
268
  tdep->gregset_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset);
269
  tdep->sizeof_gregset = NUM_GPREGS * 4;
270
 
271
  tdep->sigtramp_p = i386nto_sigtramp_p;
272
  tdep->sigcontext_addr = i386nto_sigcontext_addr;
273
  tdep->sc_pc_offset = 56;
274
  tdep->sc_sp_offset = 68;
275
 
276
  /* Setjmp()'s return PC saved in EDX (5).  */
277
  tdep->jb_pc_offset = 20;      /* 5x32 bit ints in.  */
278
 
279
  set_solib_svr4_fetch_link_map_offsets
280
    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
281
 
282
  /* Initialize this lazily, to avoid an initialization order
283
     dependency on solib-svr4.c's _initialize routine.  */
284
  if (nto_svr4_so_ops.in_dynsym_resolve_code == NULL)
285
    {
286
      nto_svr4_so_ops = svr4_so_ops;
287
 
288
      /* Our loader handles solib relocations differently than svr4.  */
289
      nto_svr4_so_ops.relocate_section_addresses
290
        = nto_relocate_section_addresses;
291
 
292
      /* Supply a nice function to find our solibs.  */
293
      nto_svr4_so_ops.find_and_open_solib
294
        = nto_find_and_open_solib;
295
 
296
      /* Our linker code is in libc.  */
297
      nto_svr4_so_ops.in_dynsym_resolve_code
298
        = nto_in_dynsym_resolve_code;
299
    }
300
  set_solib_ops (gdbarch, &nto_svr4_so_ops);
301
 
302
  nto_set_target (&i386_nto_target);
303
}
304
 
305
void
306
_initialize_i386nto_tdep (void)
307
{
308
  init_i386nto_ops ();
309
  gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
310
                          i386nto_init_abi);
311
  gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
312
                                  nto_elf_osabi_sniffer);
313
}

powered by: WebSVN 2.1.0

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