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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [nto-tdep.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* nto-tdep.c - general QNX Neutrino target functionality.
2
 
3
   Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   Contributed by QNX Software Systems Ltd.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
#include "defs.h"
24
#include "gdb_stat.h"
25
#include "gdb_string.h"
26
#include "nto-tdep.h"
27
#include "top.h"
28
#include "cli/cli-decode.h"
29
#include "cli/cli-cmds.h"
30
#include "inferior.h"
31
#include "gdbarch.h"
32
#include "bfd.h"
33
#include "elf-bfd.h"
34
#include "solib-svr4.h"
35
#include "gdbcore.h"
36
#include "objfiles.h"
37
 
38
#include <string.h>
39
 
40
#ifdef __CYGWIN__
41
#include <sys/cygwin.h>
42
#endif
43
 
44
#ifdef __CYGWIN__
45
static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
46
#elif defined(__sun__) || defined(linux)
47
static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
48
#else
49
static char default_nto_target[] = "";
50
#endif
51
 
52
struct nto_target_ops current_nto_target;
53
 
54
static char *
55
nto_target (void)
56
{
57
  char *p = getenv ("QNX_TARGET");
58
 
59
#ifdef __CYGWIN__
60
  static char buf[PATH_MAX];
61
  if (p)
62
    cygwin_conv_to_posix_path (p, buf);
63
  else
64
    cygwin_conv_to_posix_path (default_nto_target, buf);
65
  return buf;
66
#else
67
  return p ? p : default_nto_target;
68
#endif
69
}
70
 
71
/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
72
   CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h.  */
73
int
74
nto_map_arch_to_cputype (const char *arch)
75
{
76
  if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
77
    return CPUTYPE_X86;
78
  if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
79
    return CPUTYPE_PPC;
80
  if (!strcmp (arch, "mips"))
81
    return CPUTYPE_MIPS;
82
  if (!strcmp (arch, "arm"))
83
    return CPUTYPE_ARM;
84
  if (!strcmp (arch, "sh"))
85
    return CPUTYPE_SH;
86
  return CPUTYPE_UNKNOWN;
87
}
88
 
89
int
90
nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
91
{
92
  char *buf, *arch_path, *nto_root, *endian, *base;
93
  const char *arch;
94
  int ret;
95
#define PATH_FMT "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
96
 
97
  nto_root = nto_target ();
98
  if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name, "i386") == 0)
99
    {
100
      arch = "x86";
101
      endian = "";
102
    }
103
  else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
104
                   "rs6000") == 0
105
           || strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
106
                   "powerpc") == 0)
107
    {
108
      arch = "ppc";
109
      endian = "be";
110
    }
111
  else
112
    {
113
      arch = gdbarch_bfd_arch_info (target_gdbarch)->arch_name;
114
      endian = gdbarch_byte_order (target_gdbarch)
115
               == BFD_ENDIAN_BIG ? "be" : "le";
116
    }
117
 
118
  /* In case nto_root is short, add strlen(solib)
119
     so we can reuse arch_path below.  */
120
  arch_path =
121
    alloca (strlen (nto_root) + strlen (arch) + strlen (endian) + 2 +
122
            strlen (solib));
123
  sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
124
 
125
  buf = alloca (strlen (PATH_FMT) + strlen (arch_path) * 5 + 1);
126
  sprintf (buf, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
127
           arch_path);
128
 
129
  /* Don't assume basename() isn't destructive.  */
130
  base = strrchr (solib, '/');
131
  if (!base)
132
    base = solib;
133
  else
134
    base++;                     /* Skip over '/'.  */
135
 
136
  ret = openp (buf, 1, base, o_flags, temp_pathname);
137
  if (ret < 0 && base != solib)
138
    {
139
      sprintf (arch_path, "/%s", solib);
140
      ret = open (arch_path, o_flags, 0);
141
      if (temp_pathname)
142
        {
143
          if (ret >= 0)
144
            *temp_pathname = gdb_realpath (arch_path);
145
          else
146
            **temp_pathname = '\0';
147
        }
148
    }
149
  return ret;
150
}
151
 
152
void
153
nto_init_solib_absolute_prefix (void)
154
{
155
  char buf[PATH_MAX * 2], arch_path[PATH_MAX];
156
  char *nto_root, *endian;
157
  const char *arch;
158
 
159
  nto_root = nto_target ();
160
  if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name, "i386") == 0)
161
    {
162
      arch = "x86";
163
      endian = "";
164
    }
165
  else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
166
                   "rs6000") == 0
167
           || strcmp (gdbarch_bfd_arch_info (target_gdbarch)->arch_name,
168
                   "powerpc") == 0)
169
    {
170
      arch = "ppc";
171
      endian = "be";
172
    }
173
  else
174
    {
175
      arch = gdbarch_bfd_arch_info (target_gdbarch)->arch_name;
176
      endian = gdbarch_byte_order (target_gdbarch)
177
               == BFD_ENDIAN_BIG ? "be" : "le";
178
    }
179
 
180
  sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
181
 
182
  sprintf (buf, "set solib-absolute-prefix %s", arch_path);
183
  execute_command (buf, 0);
184
}
185
 
186
char **
187
nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
188
                       const char **perr)
189
{
190
  char **argv;
191
  char *in, *out, *err, *p;
192
  int argc, i, n;
193
 
194
  for (n = 0; pargv[n]; n++);
195
  if (n == 0)
196
    return NULL;
197
  in = "";
198
  out = "";
199
  err = "";
200
 
201
  argv = xcalloc (n + 1, sizeof argv[0]);
202
  argc = n;
203
  for (i = 0, n = 0; n < argc; n++)
204
    {
205
      p = pargv[n];
206
      if (*p == '>')
207
        {
208
          p++;
209
          if (*p)
210
            out = p;
211
          else
212
            out = pargv[++n];
213
        }
214
      else if (*p == '<')
215
        {
216
          p++;
217
          if (*p)
218
            in = p;
219
          else
220
            in = pargv[++n];
221
        }
222
      else if (*p++ == '2' && *p++ == '>')
223
        {
224
          if (*p == '&' && *(p + 1) == '1')
225
            err = out;
226
          else if (*p)
227
            err = p;
228
          else
229
            err = pargv[++n];
230
        }
231
      else
232
        argv[i++] = pargv[n];
233
    }
234
  *pin = in;
235
  *pout = out;
236
  *perr = err;
237
  return argv;
238
}
239
 
240
/* The struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from
241
   solib-svr4.c to support nto_relocate_section_addresses
242
   which is different from the svr4 version.  */
243
 
244
/* Link map info to include in an allocated so_list entry */
245
 
246
struct lm_info
247
  {
248
    /* Pointer to copy of link map from inferior.  The type is char *
249
       rather than void *, so that we may use byte offsets to find the
250
       various fields without the need for a cast.  */
251
    gdb_byte *lm;
252
 
253
    /* Amount by which addresses in the binary should be relocated to
254
       match the inferior.  This could most often be taken directly
255
       from lm, but when prelinking is involved and the prelink base
256
       address changes, we may need a different offset, we want to
257
       warn about the difference and compute it only once.  */
258
    CORE_ADDR l_addr;
259
 
260
    /* The target location of lm.  */
261
    CORE_ADDR lm_addr;
262
  };
263
 
264
 
265
static CORE_ADDR
266
LM_ADDR (struct so_list *so)
267
{
268
  if (so->lm_info->l_addr == (CORE_ADDR)-1)
269
    {
270
      struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
271
      struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
272
 
273
      so->lm_info->l_addr =
274
        extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
275
    }
276
  return so->lm_info->l_addr;
277
}
278
 
279
static CORE_ADDR
280
nto_truncate_ptr (CORE_ADDR addr)
281
{
282
  if (gdbarch_ptr_bit (target_gdbarch) == sizeof (CORE_ADDR) * 8)
283
    /* We don't need to truncate anything, and the bit twiddling below
284
       will fail due to overflow problems.  */
285
    return addr;
286
  else
287
    return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch)) - 1);
288
}
289
 
290
static Elf_Internal_Phdr *
291
find_load_phdr (bfd *abfd)
292
{
293
  Elf_Internal_Phdr *phdr;
294
  unsigned int i;
295
 
296
  if (!elf_tdata (abfd))
297
    return NULL;
298
 
299
  phdr = elf_tdata (abfd)->phdr;
300
  for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
301
    {
302
      if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
303
        return phdr;
304
    }
305
  return NULL;
306
}
307
 
308
void
309
nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
310
{
311
  /* Neutrino treats the l_addr base address field in link.h as different than
312
     the base address in the System V ABI and so the offset needs to be
313
     calculated and applied to relocations.  */
314
  Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
315
  unsigned vaddr = phdr ? phdr->p_vaddr : 0;
316
 
317
  sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);
318
  sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);
319
}
320
 
321
/* This is cheating a bit because our linker code is in libc.so.  If we
322
   ever implement lazy linking, this may need to be re-examined.  */
323
int
324
nto_in_dynsym_resolve_code (CORE_ADDR pc)
325
{
326
  if (in_plt_section (pc, NULL))
327
    return 1;
328
  return 0;
329
}
330
 
331
void
332
nto_dummy_supply_regset (struct regcache *regcache, char *regs)
333
{
334
  /* Do nothing.  */
335
}
336
 
337
enum gdb_osabi
338
nto_elf_osabi_sniffer (bfd *abfd)
339
{
340
  if (nto_is_nto_target)
341
    return nto_is_nto_target (abfd);
342
  return GDB_OSABI_UNKNOWN;
343
}
344
 
345
static const char *nto_thread_state_str[] =
346
{
347
  "DEAD",               /* 0  0x00 */
348
  "RUNNING",    /* 1  0x01 */
349
  "READY",      /* 2  0x02 */
350
  "STOPPED",    /* 3  0x03 */
351
  "SEND",               /* 4  0x04 */
352
  "RECEIVE",    /* 5  0x05 */
353
  "REPLY",      /* 6  0x06 */
354
  "STACK",      /* 7  0x07 */
355
  "WAITTHREAD", /* 8  0x08 */
356
  "WAITPAGE",   /* 9  0x09 */
357
  "SIGSUSPEND", /* 10 0x0a */
358
  "SIGWAITINFO",        /* 11 0x0b */
359
  "NANOSLEEP",  /* 12 0x0c */
360
  "MUTEX",      /* 13 0x0d */
361
  "CONDVAR",    /* 14 0x0e */
362
  "JOIN",               /* 15 0x0f */
363
  "INTR",               /* 16 0x10 */
364
  "SEM",                /* 17 0x11 */
365
  "WAITCTX",    /* 18 0x12 */
366
  "NET_SEND",   /* 19 0x13 */
367
  "NET_REPLY"   /* 20 0x14 */
368
};
369
 
370
char *
371
nto_extra_thread_info (struct thread_info *ti)
372
{
373
  if (ti && ti->private
374
      && ti->private->state < ARRAY_SIZE (nto_thread_state_str))
375
    return (char *)nto_thread_state_str [ti->private->state];
376
  return "";
377
}
378
 
379
void
380
nto_initialize_signals (void)
381
{
382
  /* We use SIG45 for pulses, or something, so nostop, noprint
383
     and pass them.  */
384
  signal_stop_update (target_signal_from_name ("SIG45"), 0);
385
  signal_print_update (target_signal_from_name ("SIG45"), 0);
386
  signal_pass_update (target_signal_from_name ("SIG45"), 1);
387
 
388
  /* By default we don't want to stop on these two, but we do want to pass.  */
389
#if defined(SIGSELECT)
390
  signal_stop_update (SIGSELECT, 0);
391
  signal_print_update (SIGSELECT, 0);
392
  signal_pass_update (SIGSELECT, 1);
393
#endif
394
 
395
#if defined(SIGPHOTON)
396
  signal_stop_update (SIGPHOTON, 0);
397
  signal_print_update (SIGPHOTON, 0);
398
  signal_pass_update (SIGPHOTON, 1);
399
#endif
400
}
401
 
402
/* Provide a prototype to silence -Wmissing-prototypes.  */
403
extern initialize_file_ftype _initialize_nto_tdep;
404
 
405
void
406
_initialize_nto_tdep (void)
407
{
408
  add_setshow_zinteger_cmd ("nto-debug", class_maintenance,
409
                            &nto_internal_debugging, _("\
410
Set QNX NTO internal debugging."), _("\
411
Show QNX NTO internal debugging."), _("\
412
When non-zero, nto specific debug info is\n\
413
displayed. Different information is displayed\n\
414
for different positive values."),
415
                            NULL,
416
                            NULL, /* FIXME: i18n: QNX NTO internal debugging is %s.  */
417
                            &setdebuglist, &showdebuglist);
418
}

powered by: WebSVN 2.1.0

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