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