GDB (API)
/home/stan/gdb/src/gdb/nto-tdep.c
Go to the documentation of this file.
00001 /* nto-tdep.c - general QNX Neutrino target functionality.
00002 
00003    Copyright (C) 2003-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by QNX Software Systems Ltd.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 #include "gdb_stat.h"
00024 #include "gdb_string.h"
00025 #include "nto-tdep.h"
00026 #include "top.h"
00027 #include "inferior.h"
00028 #include "gdbarch.h"
00029 #include "bfd.h"
00030 #include "elf-bfd.h"
00031 #include "solib-svr4.h"
00032 #include "gdbcore.h"
00033 #include "objfiles.h"
00034 
00035 #include <string.h>
00036 
00037 #ifdef __CYGWIN__
00038 #include <sys/cygwin.h>
00039 #endif
00040 
00041 #ifdef __CYGWIN__
00042 static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
00043 #elif defined(__sun__) || defined(linux)
00044 static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
00045 #else
00046 static char default_nto_target[] = "";
00047 #endif
00048 
00049 struct nto_target_ops current_nto_target;
00050 
00051 static char *
00052 nto_target (void)
00053 {
00054   char *p = getenv ("QNX_TARGET");
00055 
00056 #ifdef __CYGWIN__
00057   static char buf[PATH_MAX];
00058   if (p)
00059     cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
00060   else
00061     cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
00062   return buf;
00063 #else
00064   return p ? p : default_nto_target;
00065 #endif
00066 }
00067 
00068 /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
00069    CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h.  */
00070 int
00071 nto_map_arch_to_cputype (const char *arch)
00072 {
00073   if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
00074     return CPUTYPE_X86;
00075   if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
00076     return CPUTYPE_PPC;
00077   if (!strcmp (arch, "mips"))
00078     return CPUTYPE_MIPS;
00079   if (!strcmp (arch, "arm"))
00080     return CPUTYPE_ARM;
00081   if (!strcmp (arch, "sh"))
00082     return CPUTYPE_SH;
00083   return CPUTYPE_UNKNOWN;
00084 }
00085 
00086 int
00087 nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
00088 {
00089   char *buf, *arch_path, *nto_root, *endian;
00090   const char *base;
00091   const char *arch;
00092   int arch_len, len, ret;
00093 #define PATH_FMT \
00094   "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
00095 
00096   nto_root = nto_target ();
00097   if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
00098     {
00099       arch = "x86";
00100       endian = "";
00101     }
00102   else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
00103                    "rs6000") == 0
00104            || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
00105                    "powerpc") == 0)
00106     {
00107       arch = "ppc";
00108       endian = "be";
00109     }
00110   else
00111     {
00112       arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
00113       endian = gdbarch_byte_order (target_gdbarch ())
00114                == BFD_ENDIAN_BIG ? "be" : "le";
00115     }
00116 
00117   /* In case nto_root is short, add strlen(solib)
00118      so we can reuse arch_path below.  */
00119 
00120   arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
00121               + strlen (solib));
00122   arch_path = alloca (arch_len);
00123   xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
00124 
00125   len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
00126   buf = alloca (len);
00127   xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
00128              arch_path);
00129 
00130   base = lbasename (solib);
00131   ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
00132                temp_pathname);
00133   if (ret < 0 && base != solib)
00134     {
00135       xsnprintf (arch_path, arch_len, "/%s", solib);
00136       ret = open (arch_path, o_flags, 0);
00137       if (temp_pathname)
00138         {
00139           if (ret >= 0)
00140             *temp_pathname = gdb_realpath (arch_path);
00141           else
00142             *temp_pathname = NULL;
00143         }
00144     }
00145   return ret;
00146 }
00147 
00148 void
00149 nto_init_solib_absolute_prefix (void)
00150 {
00151   char buf[PATH_MAX * 2], arch_path[PATH_MAX];
00152   char *nto_root, *endian;
00153   const char *arch;
00154 
00155   nto_root = nto_target ();
00156   if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
00157     {
00158       arch = "x86";
00159       endian = "";
00160     }
00161   else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
00162                    "rs6000") == 0
00163            || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
00164                    "powerpc") == 0)
00165     {
00166       arch = "ppc";
00167       endian = "be";
00168     }
00169   else
00170     {
00171       arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
00172       endian = gdbarch_byte_order (target_gdbarch ())
00173                == BFD_ENDIAN_BIG ? "be" : "le";
00174     }
00175 
00176   xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
00177 
00178   xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
00179   execute_command (buf, 0);
00180 }
00181 
00182 char **
00183 nto_parse_redirection (char *pargv[], const char **pin, const char **pout, 
00184                        const char **perr)
00185 {
00186   char **argv;
00187   char *in, *out, *err, *p;
00188   int argc, i, n;
00189 
00190   for (n = 0; pargv[n]; n++);
00191   if (n == 0)
00192     return NULL;
00193   in = "";
00194   out = "";
00195   err = "";
00196 
00197   argv = xcalloc (n + 1, sizeof argv[0]);
00198   argc = n;
00199   for (i = 0, n = 0; n < argc; n++)
00200     {
00201       p = pargv[n];
00202       if (*p == '>')
00203         {
00204           p++;
00205           if (*p)
00206             out = p;
00207           else
00208             out = pargv[++n];
00209         }
00210       else if (*p == '<')
00211         {
00212           p++;
00213           if (*p)
00214             in = p;
00215           else
00216             in = pargv[++n];
00217         }
00218       else if (*p++ == '2' && *p++ == '>')
00219         {
00220           if (*p == '&' && *(p + 1) == '1')
00221             err = out;
00222           else if (*p)
00223             err = p;
00224           else
00225             err = pargv[++n];
00226         }
00227       else
00228         argv[i++] = pargv[n];
00229     }
00230   *pin = in;
00231   *pout = out;
00232   *perr = err;
00233   return argv;
00234 }
00235 
00236 /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
00237    solib-svr4.c to support nto_relocate_section_addresses
00238    which is different from the svr4 version.  */
00239 
00240 /* Link map info to include in an allocated so_list entry */
00241 
00242 struct lm_info
00243   {
00244     /* Pointer to copy of link map from inferior.  The type is char *
00245        rather than void *, so that we may use byte offsets to find the
00246        various fields without the need for a cast.  */
00247     gdb_byte *lm;
00248 
00249     /* Amount by which addresses in the binary should be relocated to
00250        match the inferior.  This could most often be taken directly
00251        from lm, but when prelinking is involved and the prelink base
00252        address changes, we may need a different offset, we want to
00253        warn about the difference and compute it only once.  */
00254     CORE_ADDR l_addr;
00255 
00256     /* The target location of lm.  */
00257     CORE_ADDR lm_addr;
00258   };
00259 
00260 
00261 static CORE_ADDR
00262 lm_addr (struct so_list *so)
00263 {
00264   if (so->lm_info->l_addr == (CORE_ADDR)-1)
00265     {
00266       struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
00267       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
00268 
00269       so->lm_info->l_addr =
00270         extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
00271     }
00272   return so->lm_info->l_addr;
00273 }
00274 
00275 static CORE_ADDR
00276 nto_truncate_ptr (CORE_ADDR addr)
00277 {
00278   if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
00279     /* We don't need to truncate anything, and the bit twiddling below
00280        will fail due to overflow problems.  */
00281     return addr;
00282   else
00283     return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
00284 }
00285 
00286 static Elf_Internal_Phdr *
00287 find_load_phdr (bfd *abfd)
00288 {
00289   Elf_Internal_Phdr *phdr;
00290   unsigned int i;
00291 
00292   if (!elf_tdata (abfd))
00293     return NULL;
00294 
00295   phdr = elf_tdata (abfd)->phdr;
00296   for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
00297     {
00298       if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
00299         return phdr;
00300     }
00301   return NULL;
00302 }
00303 
00304 void
00305 nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
00306 {
00307   /* Neutrino treats the l_addr base address field in link.h as different than
00308      the base address in the System V ABI and so the offset needs to be
00309      calculated and applied to relocations.  */
00310   Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
00311   unsigned vaddr = phdr ? phdr->p_vaddr : 0;
00312 
00313   sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
00314   sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
00315 }
00316 
00317 /* This is cheating a bit because our linker code is in libc.so.  If we
00318    ever implement lazy linking, this may need to be re-examined.  */
00319 int
00320 nto_in_dynsym_resolve_code (CORE_ADDR pc)
00321 {
00322   if (in_plt_section (pc))
00323     return 1;
00324   return 0;
00325 }
00326 
00327 void
00328 nto_dummy_supply_regset (struct regcache *regcache, char *regs)
00329 {
00330   /* Do nothing.  */
00331 }
00332 
00333 enum gdb_osabi
00334 nto_elf_osabi_sniffer (bfd *abfd)
00335 {
00336   if (nto_is_nto_target)
00337     return nto_is_nto_target (abfd);
00338   return GDB_OSABI_UNKNOWN;
00339 }
00340 
00341 static const char *nto_thread_state_str[] =
00342 {
00343   "DEAD",               /* 0  0x00 */
00344   "RUNNING",    /* 1  0x01 */
00345   "READY",      /* 2  0x02 */
00346   "STOPPED",    /* 3  0x03 */
00347   "SEND",               /* 4  0x04 */
00348   "RECEIVE",    /* 5  0x05 */
00349   "REPLY",      /* 6  0x06 */
00350   "STACK",      /* 7  0x07 */
00351   "WAITTHREAD", /* 8  0x08 */
00352   "WAITPAGE",   /* 9  0x09 */
00353   "SIGSUSPEND", /* 10 0x0a */
00354   "SIGWAITINFO",        /* 11 0x0b */
00355   "NANOSLEEP",  /* 12 0x0c */
00356   "MUTEX",      /* 13 0x0d */
00357   "CONDVAR",    /* 14 0x0e */
00358   "JOIN",               /* 15 0x0f */
00359   "INTR",               /* 16 0x10 */
00360   "SEM",                /* 17 0x11 */
00361   "WAITCTX",    /* 18 0x12 */
00362   "NET_SEND",   /* 19 0x13 */
00363   "NET_REPLY"   /* 20 0x14 */
00364 };
00365 
00366 char *
00367 nto_extra_thread_info (struct thread_info *ti)
00368 {
00369   if (ti && ti->private
00370       && ti->private->state < ARRAY_SIZE (nto_thread_state_str))
00371     return (char *)nto_thread_state_str [ti->private->state];
00372   return "";
00373 }
00374 
00375 void
00376 nto_initialize_signals (void)
00377 {
00378   /* We use SIG45 for pulses, or something, so nostop, noprint
00379      and pass them.  */
00380   signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
00381   signal_print_update (gdb_signal_from_name ("SIG45"), 0);
00382   signal_pass_update (gdb_signal_from_name ("SIG45"), 1);
00383 
00384   /* By default we don't want to stop on these two, but we do want to pass.  */
00385 #if defined(SIGSELECT)
00386   signal_stop_update (SIGSELECT, 0);
00387   signal_print_update (SIGSELECT, 0);
00388   signal_pass_update (SIGSELECT, 1);
00389 #endif
00390 
00391 #if defined(SIGPHOTON)
00392   signal_stop_update (SIGPHOTON, 0);
00393   signal_print_update (SIGPHOTON, 0);
00394   signal_pass_update (SIGPHOTON, 1);
00395 #endif
00396 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines