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