gdb/i386nbsd-tdep.c - gdb

Global variables defined

Functions defined

Source code

  1. /* Target-dependent code for NetBSD/i386.

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

  3.    This file is part of GDB.

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

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

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

  14. #include "defs.h"
  15. #include "arch-utils.h"
  16. #include "frame.h"
  17. #include "gdbcore.h"
  18. #include "regcache.h"
  19. #include "regset.h"
  20. #include "osabi.h"
  21. #include "symtab.h"
  22. #include "trad-frame.h"
  23. #include "tramp-frame.h"

  24. #include "i386-tdep.h"
  25. #include "i387-tdep.h"
  26. #include "nbsd-tdep.h"
  27. #include "solib-svr4.h"

  28. /* From <machine/reg.h>.  */
  29. static int i386nbsd_r_reg_offset[] =
  30. {
  31.   0 * 4,                        /* %eax */
  32.   1 * 4,                        /* %ecx */
  33.   2 * 4,                        /* %edx */
  34.   3 * 4,                        /* %ebx */
  35.   4 * 4,                        /* %esp */
  36.   5 * 4,                        /* %ebp */
  37.   6 * 4,                        /* %esi */
  38.   7 * 4,                        /* %edi */
  39.   8 * 4,                        /* %eip */
  40.   9 * 4,                        /* %eflags */
  41.   10 * 4,                        /* %cs */
  42.   11 * 4,                        /* %ss */
  43.   12 * 4,                        /* %ds */
  44.   13 * 4,                        /* %es */
  45.   14 * 4,                        /* %fs */
  46.   15 * 4                        /* %gs */
  47. };

  48. /* From <machine/signal.h>.  */
  49. int i386nbsd_sc_reg_offset[] =
  50. {
  51.   10 * 4,                        /* %eax */
  52.   9 * 4,                        /* %ecx */
  53.   8 * 4,                        /* %edx */
  54.   7 * 4,                        /* %ebx */
  55.   14 * 4,                        /* %esp */
  56.   6 * 4,                        /* %ebp */
  57.   5 * 4,                        /* %esi */
  58.   4 * 4,                        /* %edi */
  59.   11 * 4,                        /* %eip */
  60.   13 * 4,                        /* %eflags */
  61.   12 * 4,                        /* %cs */
  62.   15 * 4,                        /* %ss */
  63.   3 * 4,                        /* %ds */
  64.   2 * 4,                        /* %es */
  65.   1 * 4,                        /* %fs */
  66.   0 * 4                                /* %gs */
  67. };

  68. /* From <machine/mcontext.h>.  */
  69. int i386nbsd_mc_reg_offset[] =
  70. {
  71.   11 * 4,                        /* %eax */
  72.   10 * 4,                        /* %ecx */
  73.   9 * 4,                        /* %edx */
  74.   8 * 4,                        /* %ebx */
  75.   7 * 4,                        /* %esp */
  76.   6 * 4,                        /* %ebp */
  77.   5 * 4,                        /* %esi */
  78.   4 * 4,                        /* %edi */
  79.   14 * 4,                        /* %eip */
  80.   16 * 4,                        /* %eflags */
  81.   15 * 4,                        /* %cs */
  82.   18 * 4,                        /* %ss */
  83.   3 * 4,                        /* %ds */
  84.   2 * 4,                        /* %es */
  85.   1 * 4,                        /* %fs */
  86.   0 * 4                                /* %gs */
  87. };

  88. static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
  89.                                           struct frame_info *,
  90.                                           struct trad_frame_cache *,
  91.                                           CORE_ADDR);

  92. static const struct tramp_frame i386nbsd_sigtramp_sc16 =
  93. {
  94.   SIGTRAMP_FRAME,
  95.   1,
  96.   {
  97.     { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x10, -1 },
  98.                         /* leal  0x10(%esp), %eax */
  99.     { 0x50, -1 },        /* pushl %eax */
  100.     { 0x50, -1 },        /* pushl %eax */
  101.     { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
  102.                         /* movl  $0x127, %eax                # __sigreturn14 */
  103.     { 0xcd, -1 }, { 0x80, -1},
  104.                         /* int   $0x80 */
  105.     { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
  106.                         /* movl  $0x1, %eax                # exit */
  107.     { 0xcd, -1 }, { 0x80, -1},
  108.                         /* int   $0x80 */
  109.     { TRAMP_SENTINEL_INSN, -1 }
  110.   },
  111.   i386nbsd_sigtramp_cache_init
  112. };

  113. static const struct tramp_frame i386nbsd_sigtramp_sc2 =
  114. {
  115.   SIGTRAMP_FRAME,
  116.   1,
  117.   {
  118.     { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x0c, -1 },
  119.                         /* leal  0x0c(%esp), %eax */
  120.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  121.                         /* movl  %eax, 0x4(%esp) */
  122.     { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
  123.                         /* movl  $0x127, %eax                # __sigreturn14 */
  124.     { 0xcd, -1 }, { 0x80, -1},
  125.                         /* int   $0x80 */
  126.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  127.                         /* movl  %eax, 0x4(%esp) */
  128.     { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
  129.                         /* movl  $0x1, %eax */
  130.     { 0xcd, -1 }, { 0x80, -1},
  131.                         /* int   $0x80 */
  132.     { TRAMP_SENTINEL_INSN, -1 }
  133.   },
  134.   i386nbsd_sigtramp_cache_init
  135. };

  136. static const struct tramp_frame i386nbsd_sigtramp_si2 =
  137. {
  138.   SIGTRAMP_FRAME,
  139.   1,
  140.   {
  141.     { 0x8b, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x08, -1 },
  142.                         /* movl  8(%esp),%eax */
  143.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  144.                         /* movl  %eax, 0x4(%esp) */
  145.     { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
  146.                         /* movl  $0x134, %eax            # setcontext */
  147.     { 0xcd, -1 }, { 0x80, -1 },
  148.                         /* int   $0x80 */
  149.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  150.                         /* movl  %eax, 0x4(%esp) */
  151.     { 0xb8, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
  152.                         /* movl  $0x1, %eax */
  153.     { 0xcd, -1 }, { 0x80, -1 },
  154.                         /* int   $0x80 */
  155.     { TRAMP_SENTINEL_INSN, -1 }
  156.   },
  157.   i386nbsd_sigtramp_cache_init
  158. };

  159. static const struct tramp_frame i386nbsd_sigtramp_si31 =
  160. {
  161.   SIGTRAMP_FRAME,
  162.   1,
  163.   {
  164.     { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
  165.         { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
  166.                         /* leal  0x8c(%esp), %eax */
  167.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  168.                         /* movl  %eax, 0x4(%esp) */
  169.     { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
  170.                         /* movl  $0x134, %eax            # setcontext */
  171.     { 0xcd, -1 }, { 0x80, -1},
  172.                         /* int   $0x80 */
  173.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  174.                         /* movl  %eax, 0x4(%esp) */
  175.     { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
  176.                         /* movl  $0x1, %eax */
  177.     { 0xcd, -1 }, { 0x80, -1},
  178.                         /* int   $0x80 */
  179.     { TRAMP_SENTINEL_INSN, -1 }
  180.   },
  181.   i386nbsd_sigtramp_cache_init
  182. };

  183. static const struct tramp_frame i386nbsd_sigtramp_si4 =
  184. {
  185.   SIGTRAMP_FRAME,
  186.   1,
  187.   {
  188.     { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
  189.         { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
  190.                         /* leal  0x8c(%esp), %eax */
  191.     { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  192.                         /* movl  %eax, 0x4(%esp) */
  193.     { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
  194.                         /* movl  $0x134, %eax            # setcontext */
  195.     { 0xcd, -1 }, { 0x80, -1},
  196.                         /* int   $0x80 */
  197.     { 0xc7, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
  198.         { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 },
  199.                         /* movl   $0xffffffff,0x4(%esp) */
  200.     { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
  201.                         /* movl  $0x1, %eax */
  202.     { 0xcd, -1 }, { 0x80, -1},
  203.                         /* int   $0x80 */
  204.     { TRAMP_SENTINEL_INSN, -1 }
  205.   },
  206.   i386nbsd_sigtramp_cache_init
  207. };

  208. static void
  209. i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
  210.                               struct frame_info *this_frame,
  211.                               struct trad_frame_cache *this_cache,
  212.                               CORE_ADDR func)
  213. {
  214.   struct gdbarch *gdbarch = get_frame_arch (this_frame);
  215.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  216.   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  217.   CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
  218.   CORE_ADDR base;
  219.   int *reg_offset;
  220.   int num_regs;
  221.   int i;

  222.   if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
  223.     {
  224.       reg_offset = i386nbsd_sc_reg_offset;
  225.       num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);

  226.       /* Read in the sigcontext address.  */
  227.       base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
  228.     }
  229.   else
  230.     {
  231.       reg_offset = i386nbsd_mc_reg_offset;
  232.       num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);

  233.       /* Read in the ucontext address.  */
  234.       base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
  235.       /* offsetof(ucontext_t, uc_mcontext) == 36 */
  236.       base += 36;
  237.     }

  238.   for (i = 0; i < num_regs; i++)
  239.     if (reg_offset[i] != -1)
  240.       trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);

  241.   /* Construct the frame ID using the function start.  */
  242.   trad_frame_set_id (this_cache, frame_id_build (sp, func));
  243. }


  244. static void
  245. i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  246. {
  247.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  248.   /* Obviously NetBSD is BSD-based.  */
  249.   i386bsd_init_abi (info, gdbarch);

  250.   /* NetBSD has a different `struct reg'.  */
  251.   tdep->gregset_reg_offset = i386nbsd_r_reg_offset;
  252.   tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
  253.   tdep->sizeof_gregset = 16 * 4;

  254.   /* NetBSD uses -freg-struct-return by default.  */
  255.   tdep->struct_return = reg_struct_return;

  256.   /* NetBSD uses tramp_frame sniffers for signal trampolines.  */
  257.   tdep->sigcontext_addr= 0;
  258.   tdep->sigtramp_start = 0;
  259.   tdep->sigtramp_end = 0;
  260.   tdep->sigtramp_p = 0;
  261.   tdep->sc_reg_offset = 0;
  262.   tdep->sc_num_regs = 0;

  263.   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
  264.   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
  265.   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
  266.   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
  267.   tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
  268. }

  269. /* NetBSD ELF.  */

  270. static void
  271. i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  272. {
  273.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  274.   /* It's still NetBSD.  */
  275.   i386nbsd_init_abi (info, gdbarch);

  276.   /* But ELF-based.  */
  277.   i386_elf_init_abi (info, gdbarch);

  278.   /* NetBSD ELF uses SVR4-style shared libraries.  */
  279.   set_solib_svr4_fetch_link_map_offsets
  280.     (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  281.   /* NetBSD ELF uses -fpcc-struct-return by default.  */
  282.   tdep->struct_return = pcc_struct_return;
  283. }

  284. /* Provide a prototype to silence -Wmissing-prototypes.  */
  285. extern initialize_file_ftype _initialize_i386nbsd_tdep;

  286. void
  287. _initialize_i386nbsd_tdep (void)
  288. {
  289.   gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD_ELF,
  290.                           i386nbsdelf_init_abi);
  291. }