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