gdb/nto-tdep.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* nto-tdep.c - general QNX Neutrino target functionality.

  2.    Copyright (C) 2003-2015 Free Software Foundation, Inc.

  3.    Contributed by QNX Software Systems Ltd.

  4.    This file is part of GDB.

  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 3 of the License, or
  8.    (at your option) any later version.

  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.

  13.    You should have received a copy of the GNU General Public License
  14.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  15. #include "defs.h"
  16. #include <sys/stat.h>
  17. #include "nto-tdep.h"
  18. #include "top.h"
  19. #include "inferior.h"
  20. #include "infrun.h"
  21. #include "gdbarch.h"
  22. #include "bfd.h"
  23. #include "elf-bfd.h"
  24. #include "solib-svr4.h"
  25. #include "gdbcore.h"
  26. #include "objfiles.h"

  27. #ifdef __CYGWIN__
  28. #include <sys/cygwin.h>
  29. #endif

  30. #ifdef __CYGWIN__
  31. static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
  32. #elif defined(__sun__) || defined(linux)
  33. static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
  34. #else
  35. static char default_nto_target[] = "";
  36. #endif

  37. struct nto_target_ops current_nto_target;

  38. static char *
  39. nto_target (void)
  40. {
  41.   char *p = getenv ("QNX_TARGET");

  42. #ifdef __CYGWIN__
  43.   static char buf[PATH_MAX];
  44.   if (p)
  45.     cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
  46.   else
  47.     cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
  48.   return buf;
  49. #else
  50.   return p ? p : default_nto_target;
  51. #endif
  52. }

  53. /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
  54.    CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h.  */
  55. int
  56. nto_map_arch_to_cputype (const char *arch)
  57. {
  58.   if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
  59.     return CPUTYPE_X86;
  60.   if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc"))
  61.     return CPUTYPE_PPC;
  62.   if (!strcmp (arch, "mips"))
  63.     return CPUTYPE_MIPS;
  64.   if (!strcmp (arch, "arm"))
  65.     return CPUTYPE_ARM;
  66.   if (!strcmp (arch, "sh"))
  67.     return CPUTYPE_SH;
  68.   return CPUTYPE_UNKNOWN;
  69. }

  70. int
  71. nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
  72. {
  73.   char *buf, *arch_path, *nto_root, *endian;
  74.   const char *base;
  75.   const char *arch;
  76.   int arch_len, len, ret;
  77. #define PATH_FMT \
  78.   "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"

  79.   nto_root = nto_target ();
  80.   if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
  81.     {
  82.       arch = "x86";
  83.       endian = "";
  84.     }
  85.   else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
  86.                    "rs6000") == 0
  87.            || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
  88.                    "powerpc") == 0)
  89.     {
  90.       arch = "ppc";
  91.       endian = "be";
  92.     }
  93.   else
  94.     {
  95.       arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
  96.       endian = gdbarch_byte_order (target_gdbarch ())
  97.                == BFD_ENDIAN_BIG ? "be" : "le";
  98.     }

  99.   /* In case nto_root is short, add strlen(solib)
  100.      so we can reuse arch_path below.  */

  101.   arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
  102.               + strlen (solib));
  103.   arch_path = alloca (arch_len);
  104.   xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);

  105.   len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
  106.   buf = alloca (len);
  107.   xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
  108.              arch_path);

  109.   base = lbasename (solib);
  110.   ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
  111.                temp_pathname);
  112.   if (ret < 0 && base != solib)
  113.     {
  114.       xsnprintf (arch_path, arch_len, "/%s", solib);
  115.       ret = open (arch_path, o_flags, 0);
  116.       if (temp_pathname)
  117.         {
  118.           if (ret >= 0)
  119.             *temp_pathname = gdb_realpath (arch_path);
  120.           else
  121.             *temp_pathname = NULL;
  122.         }
  123.     }
  124.   return ret;
  125. }

  126. void
  127. nto_init_solib_absolute_prefix (void)
  128. {
  129.   char buf[PATH_MAX * 2], arch_path[PATH_MAX];
  130.   char *nto_root, *endian;
  131.   const char *arch;

  132.   nto_root = nto_target ();
  133.   if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0)
  134.     {
  135.       arch = "x86";
  136.       endian = "";
  137.     }
  138.   else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
  139.                    "rs6000") == 0
  140.            || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name,
  141.                    "powerpc") == 0)
  142.     {
  143.       arch = "ppc";
  144.       endian = "be";
  145.     }
  146.   else
  147.     {
  148.       arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name;
  149.       endian = gdbarch_byte_order (target_gdbarch ())
  150.                == BFD_ENDIAN_BIG ? "be" : "le";
  151.     }

  152.   xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);

  153.   xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
  154.   execute_command (buf, 0);
  155. }

  156. char **
  157. nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
  158.                        const char **perr)
  159. {
  160.   char **argv;
  161.   char *in, *out, *err, *p;
  162.   int argc, i, n;

  163.   for (n = 0; pargv[n]; n++);
  164.   if (n == 0)
  165.     return NULL;
  166.   in = "";
  167.   out = "";
  168.   err = "";

  169.   argv = xcalloc (n + 1, sizeof argv[0]);
  170.   argc = n;
  171.   for (i = 0, n = 0; n < argc; n++)
  172.     {
  173.       p = pargv[n];
  174.       if (*p == '>')
  175.         {
  176.           p++;
  177.           if (*p)
  178.             out = p;
  179.           else
  180.             out = pargv[++n];
  181.         }
  182.       else if (*p == '<')
  183.         {
  184.           p++;
  185.           if (*p)
  186.             in = p;
  187.           else
  188.             in = pargv[++n];
  189.         }
  190.       else if (*p++ == '2' && *p++ == '>')
  191.         {
  192.           if (*p == '&' && *(p + 1) == '1')
  193.             err = out;
  194.           else if (*p)
  195.             err = p;
  196.           else
  197.             err = pargv[++n];
  198.         }
  199.       else
  200.         argv[i++] = pargv[n];
  201.     }
  202.   *pin = in;
  203.   *pout = out;
  204.   *perr = err;
  205.   return argv;
  206. }

  207. /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from
  208.    solib-svr4.c to support nto_relocate_section_addresses
  209.    which is different from the svr4 version.  */

  210. /* Link map info to include in an allocated so_list entry */

  211. struct lm_info
  212.   {
  213.     /* Pointer to copy of link map from inferior.  The type is char *
  214.        rather than void *, so that we may use byte offsets to find the
  215.        various fields without the need for a cast.  */
  216.     gdb_byte *lm;

  217.     /* Amount by which addresses in the binary should be relocated to
  218.        match the inferior.  This could most often be taken directly
  219.        from lm, but when prelinking is involved and the prelink base
  220.        address changes, we may need a different offset, we want to
  221.        warn about the difference and compute it only once.  */
  222.     CORE_ADDR l_addr;

  223.     /* The target location of lm.  */
  224.     CORE_ADDR lm_addr;
  225.   };


  226. static CORE_ADDR
  227. lm_addr (struct so_list *so)
  228. {
  229.   if (so->lm_info->l_addr == (CORE_ADDR)-1)
  230.     {
  231.       struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
  232.       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;

  233.       so->lm_info->l_addr =
  234.         extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type);
  235.     }
  236.   return so->lm_info->l_addr;
  237. }

  238. static CORE_ADDR
  239. nto_truncate_ptr (CORE_ADDR addr)
  240. {
  241.   if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8)
  242.     /* We don't need to truncate anything, and the bit twiddling below
  243.        will fail due to overflow problems.  */
  244.     return addr;
  245.   else
  246.     return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1);
  247. }

  248. static Elf_Internal_Phdr *
  249. find_load_phdr (bfd *abfd)
  250. {
  251.   Elf_Internal_Phdr *phdr;
  252.   unsigned int i;

  253.   if (!elf_tdata (abfd))
  254.     return NULL;

  255.   phdr = elf_tdata (abfd)->phdr;
  256.   for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
  257.     {
  258.       if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
  259.         return phdr;
  260.     }
  261.   return NULL;
  262. }

  263. void
  264. nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
  265. {
  266.   /* Neutrino treats the l_addr base address field in link.h as different than
  267.      the base address in the System V ABI and so the offset needs to be
  268.      calculated and applied to relocations.  */
  269.   Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner);
  270.   unsigned vaddr = phdr ? phdr->p_vaddr : 0;

  271.   sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr);
  272.   sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr);
  273. }

  274. /* This is cheating a bit because our linker code is in libc.so.  If we
  275.    ever implement lazy linking, this may need to be re-examined.  */
  276. int
  277. nto_in_dynsym_resolve_code (CORE_ADDR pc)
  278. {
  279.   if (in_plt_section (pc))
  280.     return 1;
  281.   return 0;
  282. }

  283. void
  284. nto_dummy_supply_regset (struct regcache *regcache, char *regs)
  285. {
  286.   /* Do nothing.  */
  287. }

  288. enum gdb_osabi
  289. nto_elf_osabi_sniffer (bfd *abfd)
  290. {
  291.   if (nto_is_nto_target)
  292.     return nto_is_nto_target (abfd);
  293.   return GDB_OSABI_UNKNOWN;
  294. }

  295. static const char *nto_thread_state_str[] =
  296. {
  297.   "DEAD",                /* 0  0x00 */
  298.   "RUNNING",        /* 1  0x01 */
  299.   "READY",        /* 2  0x02 */
  300.   "STOPPED",        /* 3  0x03 */
  301.   "SEND",                /* 4  0x04 */
  302.   "RECEIVE",        /* 5  0x05 */
  303.   "REPLY",        /* 6  0x06 */
  304.   "STACK",        /* 7  0x07 */
  305.   "WAITTHREAD",        /* 8  0x08 */
  306.   "WAITPAGE",        /* 9  0x09 */
  307.   "SIGSUSPEND",        /* 10 0x0a */
  308.   "SIGWAITINFO",        /* 11 0x0b */
  309.   "NANOSLEEP",        /* 12 0x0c */
  310.   "MUTEX",        /* 13 0x0d */
  311.   "CONDVAR",        /* 14 0x0e */
  312.   "JOIN",                /* 15 0x0f */
  313.   "INTR",                /* 16 0x10 */
  314.   "SEM",                /* 17 0x11 */
  315.   "WAITCTX",        /* 18 0x12 */
  316.   "NET_SEND",        /* 19 0x13 */
  317.   "NET_REPLY"        /* 20 0x14 */
  318. };

  319. char *
  320. nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
  321. {
  322.   if (ti && ti->private
  323.       && ti->private->state < ARRAY_SIZE (nto_thread_state_str))
  324.     return (char *)nto_thread_state_str [ti->private->state];
  325.   return "";
  326. }

  327. void
  328. nto_initialize_signals (void)
  329. {
  330.   /* We use SIG45 for pulses, or something, so nostop, noprint
  331.      and pass them.  */
  332.   signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
  333.   signal_print_update (gdb_signal_from_name ("SIG45"), 0);
  334.   signal_pass_update (gdb_signal_from_name ("SIG45"), 1);

  335.   /* By default we don't want to stop on these two, but we do want to pass.  */
  336. #if defined(SIGSELECT)
  337.   signal_stop_update (SIGSELECT, 0);
  338.   signal_print_update (SIGSELECT, 0);
  339.   signal_pass_update (SIGSELECT, 1);
  340. #endif

  341. #if defined(SIGPHOTON)
  342.   signal_stop_update (SIGPHOTON, 0);
  343.   signal_print_update (SIGPHOTON, 0);
  344.   signal_pass_update (SIGPHOTON, 1);
  345. #endif
  346. }