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