1*6881a400Schristos /* Target-dependent code for NetBSD/i386. 2*6881a400Schristos 3*6881a400Schristos Copyright (C) 1988-2023 Free Software Foundation, Inc. 4*6881a400Schristos 5*6881a400Schristos This file is part of GDB. 6*6881a400Schristos 7*6881a400Schristos This program is free software; you can redistribute it and/or modify 8*6881a400Schristos it under the terms of the GNU General Public License as published by 9*6881a400Schristos the Free Software Foundation; either version 3 of the License, or 10*6881a400Schristos (at your option) any later version. 11*6881a400Schristos 12*6881a400Schristos This program is distributed in the hope that it will be useful, 13*6881a400Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14*6881a400Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*6881a400Schristos GNU General Public License for more details. 16*6881a400Schristos 17*6881a400Schristos You should have received a copy of the GNU General Public License 18*6881a400Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19*6881a400Schristos 20*6881a400Schristos #include "defs.h" 21*6881a400Schristos #include "arch-utils.h" 22*6881a400Schristos #include "frame.h" 23*6881a400Schristos #include "gdbcore.h" 24*6881a400Schristos #include "regcache.h" 25*6881a400Schristos #include "regset.h" 26*6881a400Schristos #include "osabi.h" 27*6881a400Schristos #include "symtab.h" 28*6881a400Schristos #include "trad-frame.h" 29*6881a400Schristos #include "tramp-frame.h" 30*6881a400Schristos #include "frame-unwind.h" 31*6881a400Schristos 32*6881a400Schristos #include "i386-tdep.h" 33*6881a400Schristos #include "i387-tdep.h" 34*6881a400Schristos #include "netbsd-tdep.h" 35*6881a400Schristos #include "solib-svr4.h" 36*6881a400Schristos 37*6881a400Schristos /* From <machine/reg.h>. */ 38*6881a400Schristos static int i386nbsd_r_reg_offset[] = 39*6881a400Schristos { 40*6881a400Schristos 0 * 4, /* %eax */ 41*6881a400Schristos 1 * 4, /* %ecx */ 42*6881a400Schristos 2 * 4, /* %edx */ 43*6881a400Schristos 3 * 4, /* %ebx */ 44*6881a400Schristos 4 * 4, /* %esp */ 45*6881a400Schristos 5 * 4, /* %ebp */ 46*6881a400Schristos 6 * 4, /* %esi */ 47*6881a400Schristos 7 * 4, /* %edi */ 48*6881a400Schristos 8 * 4, /* %eip */ 49*6881a400Schristos 9 * 4, /* %eflags */ 50*6881a400Schristos 10 * 4, /* %cs */ 51*6881a400Schristos 11 * 4, /* %ss */ 52*6881a400Schristos 12 * 4, /* %ds */ 53*6881a400Schristos 13 * 4, /* %es */ 54*6881a400Schristos 14 * 4, /* %fs */ 55*6881a400Schristos 15 * 4 /* %gs */ 56*6881a400Schristos }; 57*6881a400Schristos 58*6881a400Schristos /* From <machine/signal.h>. */ 59*6881a400Schristos static int i386nbsd_sc_reg_offset[] = 60*6881a400Schristos { 61*6881a400Schristos 10 * 4, /* %eax */ 62*6881a400Schristos 9 * 4, /* %ecx */ 63*6881a400Schristos 8 * 4, /* %edx */ 64*6881a400Schristos 7 * 4, /* %ebx */ 65*6881a400Schristos 14 * 4, /* %esp */ 66*6881a400Schristos 6 * 4, /* %ebp */ 67*6881a400Schristos 5 * 4, /* %esi */ 68*6881a400Schristos 4 * 4, /* %edi */ 69*6881a400Schristos 11 * 4, /* %eip */ 70*6881a400Schristos 13 * 4, /* %eflags */ 71*6881a400Schristos 12 * 4, /* %cs */ 72*6881a400Schristos 15 * 4, /* %ss */ 73*6881a400Schristos 3 * 4, /* %ds */ 74*6881a400Schristos 2 * 4, /* %es */ 75*6881a400Schristos 1 * 4, /* %fs */ 76*6881a400Schristos 0 * 4 /* %gs */ 77*6881a400Schristos }; 78*6881a400Schristos 79*6881a400Schristos /* From <machine/mcontext.h>. */ 80*6881a400Schristos static int i386nbsd_mc_reg_offset[] = 81*6881a400Schristos { 82*6881a400Schristos 11 * 4, /* %eax */ 83*6881a400Schristos 10 * 4, /* %ecx */ 84*6881a400Schristos 9 * 4, /* %edx */ 85*6881a400Schristos 8 * 4, /* %ebx */ 86*6881a400Schristos 7 * 4, /* %esp */ 87*6881a400Schristos 6 * 4, /* %ebp */ 88*6881a400Schristos 5 * 4, /* %esi */ 89*6881a400Schristos 4 * 4, /* %edi */ 90*6881a400Schristos 14 * 4, /* %eip */ 91*6881a400Schristos 16 * 4, /* %eflags */ 92*6881a400Schristos 15 * 4, /* %cs */ 93*6881a400Schristos 18 * 4, /* %ss */ 94*6881a400Schristos 3 * 4, /* %ds */ 95*6881a400Schristos 2 * 4, /* %es */ 96*6881a400Schristos 1 * 4, /* %fs */ 97*6881a400Schristos 0 * 4 /* %gs */ 98*6881a400Schristos }; 99*6881a400Schristos 100*6881a400Schristos static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *, 101*6881a400Schristos frame_info_ptr, 102*6881a400Schristos struct trad_frame_cache *, 103*6881a400Schristos CORE_ADDR); 104*6881a400Schristos 105*6881a400Schristos static const struct tramp_frame i386nbsd_sigtramp_sc16 = 106*6881a400Schristos { 107*6881a400Schristos SIGTRAMP_FRAME, 108*6881a400Schristos 1, 109*6881a400Schristos { 110*6881a400Schristos /* leal 0x10(%esp), %eax */ 111*6881a400Schristos { 0x8d, ULONGEST_MAX }, 112*6881a400Schristos { 0x44, ULONGEST_MAX }, 113*6881a400Schristos { 0x24, ULONGEST_MAX }, 114*6881a400Schristos { 0x10, ULONGEST_MAX }, 115*6881a400Schristos 116*6881a400Schristos /* pushl %eax */ 117*6881a400Schristos { 0x50, ULONGEST_MAX }, 118*6881a400Schristos 119*6881a400Schristos /* pushl %eax */ 120*6881a400Schristos { 0x50, ULONGEST_MAX }, 121*6881a400Schristos 122*6881a400Schristos /* movl $0x127, %eax # __sigreturn14 */ 123*6881a400Schristos { 0xb8, ULONGEST_MAX }, 124*6881a400Schristos { 0x27, ULONGEST_MAX }, 125*6881a400Schristos {0x01, ULONGEST_MAX }, 126*6881a400Schristos {0x00, ULONGEST_MAX }, 127*6881a400Schristos {0x00, ULONGEST_MAX }, 128*6881a400Schristos 129*6881a400Schristos /* int $0x80 */ 130*6881a400Schristos { 0xcd, ULONGEST_MAX }, 131*6881a400Schristos { 0x80, ULONGEST_MAX}, 132*6881a400Schristos 133*6881a400Schristos /* movl $0x1, %eax # exit */ 134*6881a400Schristos { 0xb8, ULONGEST_MAX }, 135*6881a400Schristos { 0x01, ULONGEST_MAX }, 136*6881a400Schristos {0x00, ULONGEST_MAX }, 137*6881a400Schristos {0x00, ULONGEST_MAX }, 138*6881a400Schristos {0x00, ULONGEST_MAX }, 139*6881a400Schristos 140*6881a400Schristos /* int $0x80 */ 141*6881a400Schristos { 0xcd, ULONGEST_MAX }, 142*6881a400Schristos { 0x80, ULONGEST_MAX}, 143*6881a400Schristos 144*6881a400Schristos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 145*6881a400Schristos }, 146*6881a400Schristos i386nbsd_sigtramp_cache_init 147*6881a400Schristos }; 148*6881a400Schristos 149*6881a400Schristos static const struct tramp_frame i386nbsd_sigtramp_sc2 = 150*6881a400Schristos { 151*6881a400Schristos SIGTRAMP_FRAME, 152*6881a400Schristos 1, 153*6881a400Schristos { 154*6881a400Schristos /* leal 0x0c(%esp), %eax */ 155*6881a400Schristos { 0x8d, ULONGEST_MAX }, 156*6881a400Schristos { 0x44, ULONGEST_MAX }, 157*6881a400Schristos { 0x24, ULONGEST_MAX }, 158*6881a400Schristos { 0x0c, ULONGEST_MAX }, 159*6881a400Schristos /* movl %eax, 0x4(%esp) */ 160*6881a400Schristos { 0x89, ULONGEST_MAX }, 161*6881a400Schristos { 0x44, ULONGEST_MAX }, 162*6881a400Schristos { 0x24, ULONGEST_MAX }, 163*6881a400Schristos { 0x04, ULONGEST_MAX }, 164*6881a400Schristos /* movl $0x127, %eax # __sigreturn14 */ 165*6881a400Schristos { 0xb8, ULONGEST_MAX }, 166*6881a400Schristos { 0x27, ULONGEST_MAX }, 167*6881a400Schristos {0x01, ULONGEST_MAX }, 168*6881a400Schristos {0x00, ULONGEST_MAX }, 169*6881a400Schristos {0x00, ULONGEST_MAX }, 170*6881a400Schristos /* int $0x80 */ 171*6881a400Schristos { 0xcd, ULONGEST_MAX }, 172*6881a400Schristos { 0x80, ULONGEST_MAX}, 173*6881a400Schristos /* movl %eax, 0x4(%esp) */ 174*6881a400Schristos { 0x89, ULONGEST_MAX }, 175*6881a400Schristos { 0x44, ULONGEST_MAX }, 176*6881a400Schristos { 0x24, ULONGEST_MAX }, 177*6881a400Schristos { 0x04, ULONGEST_MAX }, 178*6881a400Schristos /* movl $0x1, %eax */ 179*6881a400Schristos { 0xb8, ULONGEST_MAX }, 180*6881a400Schristos { 0x01, ULONGEST_MAX }, 181*6881a400Schristos {0x00, ULONGEST_MAX }, 182*6881a400Schristos {0x00, ULONGEST_MAX }, 183*6881a400Schristos {0x00, ULONGEST_MAX }, 184*6881a400Schristos /* int $0x80 */ 185*6881a400Schristos { 0xcd, ULONGEST_MAX }, 186*6881a400Schristos { 0x80, ULONGEST_MAX}, 187*6881a400Schristos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 188*6881a400Schristos }, 189*6881a400Schristos i386nbsd_sigtramp_cache_init 190*6881a400Schristos }; 191*6881a400Schristos 192*6881a400Schristos static const struct tramp_frame i386nbsd_sigtramp_si2 = 193*6881a400Schristos { 194*6881a400Schristos SIGTRAMP_FRAME, 195*6881a400Schristos 1, 196*6881a400Schristos { 197*6881a400Schristos /* movl 8(%esp),%eax */ 198*6881a400Schristos { 0x8b, ULONGEST_MAX }, 199*6881a400Schristos { 0x44, ULONGEST_MAX }, 200*6881a400Schristos { 0x24, ULONGEST_MAX }, 201*6881a400Schristos { 0x08, ULONGEST_MAX }, 202*6881a400Schristos /* movl %eax, 0x4(%esp) */ 203*6881a400Schristos { 0x89, ULONGEST_MAX }, 204*6881a400Schristos { 0x44, ULONGEST_MAX }, 205*6881a400Schristos { 0x24, ULONGEST_MAX }, 206*6881a400Schristos { 0x04, ULONGEST_MAX }, 207*6881a400Schristos /* movl $0x134, %eax # setcontext */ 208*6881a400Schristos { 0xb8, ULONGEST_MAX }, 209*6881a400Schristos { 0x34, ULONGEST_MAX }, 210*6881a400Schristos { 0x01, ULONGEST_MAX }, 211*6881a400Schristos { 0x00, ULONGEST_MAX }, 212*6881a400Schristos { 0x00, ULONGEST_MAX }, 213*6881a400Schristos /* int $0x80 */ 214*6881a400Schristos { 0xcd, ULONGEST_MAX }, 215*6881a400Schristos { 0x80, ULONGEST_MAX }, 216*6881a400Schristos /* movl %eax, 0x4(%esp) */ 217*6881a400Schristos { 0x89, ULONGEST_MAX }, 218*6881a400Schristos { 0x44, ULONGEST_MAX }, 219*6881a400Schristos { 0x24, ULONGEST_MAX }, 220*6881a400Schristos { 0x04, ULONGEST_MAX }, 221*6881a400Schristos /* movl $0x1, %eax */ 222*6881a400Schristos { 0xb8, ULONGEST_MAX }, 223*6881a400Schristos { 0x01, ULONGEST_MAX }, 224*6881a400Schristos { 0x00, ULONGEST_MAX }, 225*6881a400Schristos { 0x00, ULONGEST_MAX }, 226*6881a400Schristos { 0x00, ULONGEST_MAX }, 227*6881a400Schristos /* int $0x80 */ 228*6881a400Schristos { 0xcd, ULONGEST_MAX }, 229*6881a400Schristos { 0x80, ULONGEST_MAX }, 230*6881a400Schristos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 231*6881a400Schristos }, 232*6881a400Schristos i386nbsd_sigtramp_cache_init 233*6881a400Schristos }; 234*6881a400Schristos 235*6881a400Schristos static const struct tramp_frame i386nbsd_sigtramp_si31 = 236*6881a400Schristos { 237*6881a400Schristos SIGTRAMP_FRAME, 238*6881a400Schristos 1, 239*6881a400Schristos { 240*6881a400Schristos /* leal 0x8c(%esp), %eax */ 241*6881a400Schristos { 0x8d, ULONGEST_MAX }, 242*6881a400Schristos { 0x84, ULONGEST_MAX }, 243*6881a400Schristos { 0x24, ULONGEST_MAX }, 244*6881a400Schristos { 0x8c, ULONGEST_MAX }, 245*6881a400Schristos { 0x00, ULONGEST_MAX }, 246*6881a400Schristos { 0x00, ULONGEST_MAX }, 247*6881a400Schristos { 0x00, ULONGEST_MAX }, 248*6881a400Schristos /* movl %eax, 0x4(%esp) */ 249*6881a400Schristos { 0x89, ULONGEST_MAX }, 250*6881a400Schristos { 0x44, ULONGEST_MAX }, 251*6881a400Schristos { 0x24, ULONGEST_MAX }, 252*6881a400Schristos { 0x04, ULONGEST_MAX }, 253*6881a400Schristos /* movl $0x134, %eax # setcontext */ 254*6881a400Schristos { 0xb8, ULONGEST_MAX }, 255*6881a400Schristos { 0x34, ULONGEST_MAX }, 256*6881a400Schristos { 0x01, ULONGEST_MAX }, 257*6881a400Schristos { 0x00, ULONGEST_MAX }, 258*6881a400Schristos { 0x00, ULONGEST_MAX }, 259*6881a400Schristos /* int $0x80 */ 260*6881a400Schristos { 0xcd, ULONGEST_MAX }, 261*6881a400Schristos { 0x80, ULONGEST_MAX}, 262*6881a400Schristos /* movl %eax, 0x4(%esp) */ 263*6881a400Schristos { 0x89, ULONGEST_MAX }, 264*6881a400Schristos { 0x44, ULONGEST_MAX }, 265*6881a400Schristos { 0x24, ULONGEST_MAX }, 266*6881a400Schristos { 0x04, ULONGEST_MAX }, 267*6881a400Schristos /* movl $0x1, %eax */ 268*6881a400Schristos { 0xb8, ULONGEST_MAX }, 269*6881a400Schristos { 0x01, ULONGEST_MAX }, 270*6881a400Schristos {0x00, ULONGEST_MAX }, 271*6881a400Schristos {0x00, ULONGEST_MAX }, 272*6881a400Schristos {0x00, ULONGEST_MAX }, 273*6881a400Schristos /* int $0x80 */ 274*6881a400Schristos { 0xcd, ULONGEST_MAX }, 275*6881a400Schristos { 0x80, ULONGEST_MAX}, 276*6881a400Schristos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 277*6881a400Schristos }, 278*6881a400Schristos i386nbsd_sigtramp_cache_init 279*6881a400Schristos }; 280*6881a400Schristos 281*6881a400Schristos static const struct tramp_frame i386nbsd_sigtramp_si4 = 282*6881a400Schristos { 283*6881a400Schristos SIGTRAMP_FRAME, 284*6881a400Schristos 1, 285*6881a400Schristos { 286*6881a400Schristos /* leal 0x8c(%esp), %eax */ 287*6881a400Schristos { 0x8d, ULONGEST_MAX }, 288*6881a400Schristos { 0x84, ULONGEST_MAX }, 289*6881a400Schristos { 0x24, ULONGEST_MAX }, 290*6881a400Schristos { 0x8c, ULONGEST_MAX }, 291*6881a400Schristos { 0x00, ULONGEST_MAX }, 292*6881a400Schristos { 0x00, ULONGEST_MAX }, 293*6881a400Schristos { 0x00, ULONGEST_MAX }, 294*6881a400Schristos /* movl %eax, 0x4(%esp) */ 295*6881a400Schristos { 0x89, ULONGEST_MAX }, 296*6881a400Schristos { 0x44, ULONGEST_MAX }, 297*6881a400Schristos { 0x24, ULONGEST_MAX }, 298*6881a400Schristos { 0x04, ULONGEST_MAX }, 299*6881a400Schristos /* movl $0x134, %eax # setcontext */ 300*6881a400Schristos { 0xb8, ULONGEST_MAX }, 301*6881a400Schristos { 0x34, ULONGEST_MAX }, 302*6881a400Schristos { 0x01, ULONGEST_MAX }, 303*6881a400Schristos { 0x00, ULONGEST_MAX }, 304*6881a400Schristos { 0x00, ULONGEST_MAX }, 305*6881a400Schristos /* int $0x80 */ 306*6881a400Schristos { 0xcd, ULONGEST_MAX }, 307*6881a400Schristos { 0x80, ULONGEST_MAX}, 308*6881a400Schristos /* movl $0xffffffff,0x4(%esp) */ 309*6881a400Schristos { 0xc7, ULONGEST_MAX }, 310*6881a400Schristos { 0x44, ULONGEST_MAX }, 311*6881a400Schristos { 0x24, ULONGEST_MAX }, 312*6881a400Schristos { 0x04, ULONGEST_MAX }, 313*6881a400Schristos { 0xff, ULONGEST_MAX }, 314*6881a400Schristos { 0xff, ULONGEST_MAX }, 315*6881a400Schristos { 0xff, ULONGEST_MAX }, 316*6881a400Schristos { 0xff, ULONGEST_MAX }, 317*6881a400Schristos /* movl $0x1, %eax */ 318*6881a400Schristos { 0xb8, ULONGEST_MAX }, 319*6881a400Schristos { 0x01, ULONGEST_MAX }, 320*6881a400Schristos {0x00, ULONGEST_MAX }, 321*6881a400Schristos {0x00, ULONGEST_MAX }, 322*6881a400Schristos {0x00, ULONGEST_MAX }, 323*6881a400Schristos /* int $0x80 */ 324*6881a400Schristos { 0xcd, ULONGEST_MAX }, 325*6881a400Schristos { 0x80, ULONGEST_MAX}, 326*6881a400Schristos { TRAMP_SENTINEL_INSN, ULONGEST_MAX } 327*6881a400Schristos }, 328*6881a400Schristos i386nbsd_sigtramp_cache_init 329*6881a400Schristos }; 330*6881a400Schristos 331*6881a400Schristos static void 332*6881a400Schristos i386nbsd_sigtramp_cache_init (const struct tramp_frame *self, 333*6881a400Schristos frame_info_ptr this_frame, 334*6881a400Schristos struct trad_frame_cache *this_cache, 335*6881a400Schristos CORE_ADDR func) 336*6881a400Schristos { 337*6881a400Schristos struct gdbarch *gdbarch = get_frame_arch (this_frame); 338*6881a400Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 339*6881a400Schristos CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); 340*6881a400Schristos CORE_ADDR base; 341*6881a400Schristos int *reg_offset; 342*6881a400Schristos int num_regs; 343*6881a400Schristos int i; 344*6881a400Schristos 345*6881a400Schristos if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2) 346*6881a400Schristos { 347*6881a400Schristos reg_offset = i386nbsd_sc_reg_offset; 348*6881a400Schristos num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset); 349*6881a400Schristos 350*6881a400Schristos /* Read in the sigcontext address. */ 351*6881a400Schristos base = read_memory_unsigned_integer (sp + 8, 4, byte_order); 352*6881a400Schristos } 353*6881a400Schristos else 354*6881a400Schristos { 355*6881a400Schristos reg_offset = i386nbsd_mc_reg_offset; 356*6881a400Schristos num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset); 357*6881a400Schristos 358*6881a400Schristos /* Read in the ucontext address. */ 359*6881a400Schristos base = read_memory_unsigned_integer (sp + 8, 4, byte_order); 360*6881a400Schristos /* offsetof(ucontext_t, uc_mcontext) == 36 */ 361*6881a400Schristos base += 36; 362*6881a400Schristos } 363*6881a400Schristos 364*6881a400Schristos for (i = 0; i < num_regs; i++) 365*6881a400Schristos if (reg_offset[i] != -1) 366*6881a400Schristos trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]); 367*6881a400Schristos 368*6881a400Schristos /* Construct the frame ID using the function start. */ 369*6881a400Schristos trad_frame_set_id (this_cache, frame_id_build (sp, func)); 370*6881a400Schristos } 371*6881a400Schristos 372*6881a400Schristos 373*6881a400Schristos /* From <machine/frame.h>. Note that %esp and %ess are only saved in 374*6881a400Schristos a trap frame when entering the kernel from user space. */ 375*6881a400Schristos static int i386nbsd_tf_reg_offset[] = 376*6881a400Schristos { 377*6881a400Schristos 10 * 4, /* %eax */ 378*6881a400Schristos 9 * 4, /* %ecx */ 379*6881a400Schristos 8 * 4, /* %edx */ 380*6881a400Schristos 7 * 4, /* %ebx */ 381*6881a400Schristos -1, /* %esp */ 382*6881a400Schristos 6 * 4, /* %ebp */ 383*6881a400Schristos 5 * 4, /* %esi */ 384*6881a400Schristos 4 * 4, /* %edi */ 385*6881a400Schristos 13 * 4, /* %eip */ 386*6881a400Schristos 15 * 4, /* %eflags */ 387*6881a400Schristos 14 * 4, /* %cs */ 388*6881a400Schristos -1, /* %ss */ 389*6881a400Schristos 3 * 4, /* %ds */ 390*6881a400Schristos 2 * 4, /* %es */ 391*6881a400Schristos 1 * 4, /* %fs */ 392*6881a400Schristos 0 * 4 /* %gs */ 393*6881a400Schristos }; 394*6881a400Schristos 395*6881a400Schristos static struct trad_frame_cache * 396*6881a400Schristos i386nbsd_trapframe_cache(frame_info_ptr this_frame, void **this_cache) 397*6881a400Schristos { 398*6881a400Schristos struct trad_frame_cache *cache; 399*6881a400Schristos CORE_ADDR func, sp, addr, tmp; 400*6881a400Schristos ULONGEST cs; 401*6881a400Schristos const char *name; 402*6881a400Schristos int i; 403*6881a400Schristos struct gdbarch *gdbarch = get_frame_arch (this_frame); 404*6881a400Schristos enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 405*6881a400Schristos 406*6881a400Schristos if (*this_cache) 407*6881a400Schristos return (struct trad_frame_cache *)*this_cache; 408*6881a400Schristos 409*6881a400Schristos cache = trad_frame_cache_zalloc (this_frame); 410*6881a400Schristos *this_cache = cache; 411*6881a400Schristos 412*6881a400Schristos func = get_frame_func (this_frame); 413*6881a400Schristos sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); 414*6881a400Schristos 415*6881a400Schristos find_pc_partial_function (func, &name, NULL, NULL); 416*6881a400Schristos if (name && (strncmp (name, "Xintr", 5) == 0 || 417*6881a400Schristos strncmp (name, "Xhandle", 7) == 0)) 418*6881a400Schristos { 419*6881a400Schristos /* It's an interrupt frame. */ 420*6881a400Schristos tmp = read_memory_unsigned_integer (sp + 4, 4, byte_order); 421*6881a400Schristos if (tmp < 15) 422*6881a400Schristos { 423*6881a400Schristos /* Reasonable value for 'ppl': already on interrupt stack. */ 424*6881a400Schristos addr = sp + 8; 425*6881a400Schristos } 426*6881a400Schristos else 427*6881a400Schristos { 428*6881a400Schristos /* Switch to previous stack. */ 429*6881a400Schristos addr = tmp + 4; 430*6881a400Schristos } 431*6881a400Schristos } 432*6881a400Schristos else 433*6881a400Schristos { 434*6881a400Schristos /* It's a trap frame. */ 435*6881a400Schristos addr = sp + 4; 436*6881a400Schristos } 437*6881a400Schristos 438*6881a400Schristos for (i = 0; i < ARRAY_SIZE (i386nbsd_tf_reg_offset); i++) 439*6881a400Schristos if (i386nbsd_tf_reg_offset[i] != -1) 440*6881a400Schristos trad_frame_set_reg_addr (cache, i, addr + i386nbsd_tf_reg_offset[i]); 441*6881a400Schristos 442*6881a400Schristos /* Read %cs from trap frame. */ 443*6881a400Schristos addr += i386nbsd_tf_reg_offset[I386_CS_REGNUM]; 444*6881a400Schristos cs = read_memory_unsigned_integer (addr, 4, byte_order); 445*6881a400Schristos if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 446*6881a400Schristos { 447*6881a400Schristos /* Trap from user space; terminate backtrace. */ 448*6881a400Schristos trad_frame_set_id (cache, outer_frame_id); 449*6881a400Schristos } 450*6881a400Schristos else 451*6881a400Schristos { 452*6881a400Schristos /* Construct the frame ID using the function start. */ 453*6881a400Schristos trad_frame_set_id (cache, frame_id_build (sp + 8, func)); 454*6881a400Schristos } 455*6881a400Schristos 456*6881a400Schristos return cache; 457*6881a400Schristos } 458*6881a400Schristos 459*6881a400Schristos static void 460*6881a400Schristos i386nbsd_trapframe_this_id (frame_info_ptr this_frame, 461*6881a400Schristos void **this_cache, struct frame_id *this_id) 462*6881a400Schristos { 463*6881a400Schristos struct trad_frame_cache *cache = 464*6881a400Schristos i386nbsd_trapframe_cache (this_frame, this_cache); 465*6881a400Schristos 466*6881a400Schristos trad_frame_get_id (cache, this_id); 467*6881a400Schristos } 468*6881a400Schristos 469*6881a400Schristos static struct value * 470*6881a400Schristos i386nbsd_trapframe_prev_register (frame_info_ptr this_frame, 471*6881a400Schristos void **this_cache, int regnum) 472*6881a400Schristos { 473*6881a400Schristos struct trad_frame_cache *cache = 474*6881a400Schristos i386nbsd_trapframe_cache (this_frame, this_cache); 475*6881a400Schristos 476*6881a400Schristos return trad_frame_get_register (cache, this_frame, regnum); 477*6881a400Schristos } 478*6881a400Schristos 479*6881a400Schristos static int 480*6881a400Schristos i386nbsd_trapframe_sniffer (const struct frame_unwind *self, 481*6881a400Schristos frame_info_ptr this_frame, 482*6881a400Schristos void **this_prologue_cache) 483*6881a400Schristos { 484*6881a400Schristos ULONGEST cs; 485*6881a400Schristos const char *name; 486*6881a400Schristos 487*6881a400Schristos /* Check Current Privilege Level and bail out if we're not executing 488*6881a400Schristos in kernel space. */ 489*6881a400Schristos cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM); 490*6881a400Schristos if ((cs & I386_SEL_RPL) == I386_SEL_UPL) 491*6881a400Schristos return 0; 492*6881a400Schristos 493*6881a400Schristos 494*6881a400Schristos find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL); 495*6881a400Schristos return (name && ((strcmp (name, "alltraps") == 0) 496*6881a400Schristos || (strcmp (name, "calltrap") == 0) 497*6881a400Schristos || (strcmp (name, "syscall1") == 0) 498*6881a400Schristos || (strcmp (name, "Xdoreti") == 0) 499*6881a400Schristos || (strncmp (name, "Xintr", 5) == 0) 500*6881a400Schristos || (strncmp (name, "Xhandle", 7) == 0) 501*6881a400Schristos || (strncmp (name, "Xpreempt", 8) == 0) 502*6881a400Schristos || (strncmp (name, "Xrecurse", 8) == 0) 503*6881a400Schristos || (strncmp (name, "Xresume", 7) == 0) 504*6881a400Schristos || (strncmp (name, "Xsoft", 5) == 0) 505*6881a400Schristos || (strncmp (name, "Xstray", 6) == 0) 506*6881a400Schristos || (strncmp (name, "Xsyscall", 8) == 0) 507*6881a400Schristos || (strncmp (name, "Xtrap", 5) == 0) 508*6881a400Schristos )); 509*6881a400Schristos } 510*6881a400Schristos 511*6881a400Schristos const struct frame_unwind i386nbsd_trapframe_unwind = { 512*6881a400Schristos /* FIXME: kettenis/20051219: This really is more like an interrupt 513*6881a400Schristos frame, but SIGTRAMP_FRAME would print <signal handler called>, 514*6881a400Schristos which really is not what we want here. */ 515*6881a400Schristos "i386 trapframe", 516*6881a400Schristos NORMAL_FRAME, 517*6881a400Schristos default_frame_unwind_stop_reason, 518*6881a400Schristos i386nbsd_trapframe_this_id, 519*6881a400Schristos i386nbsd_trapframe_prev_register, 520*6881a400Schristos NULL, 521*6881a400Schristos i386nbsd_trapframe_sniffer 522*6881a400Schristos }; 523*6881a400Schristos 524*6881a400Schristos static void 525*6881a400Schristos i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 526*6881a400Schristos { 527*6881a400Schristos i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); 528*6881a400Schristos 529*6881a400Schristos /* Obviously NetBSD is BSD-based. */ 530*6881a400Schristos i386bsd_init_abi (info, gdbarch); 531*6881a400Schristos 532*6881a400Schristos nbsd_init_abi (info, gdbarch); 533*6881a400Schristos 534*6881a400Schristos /* NetBSD has a different `struct reg'. */ 535*6881a400Schristos tdep->gregset_reg_offset = i386nbsd_r_reg_offset; 536*6881a400Schristos tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset); 537*6881a400Schristos tdep->sizeof_gregset = 16 * 4; 538*6881a400Schristos 539*6881a400Schristos /* NetBSD uses -freg-struct-return by default. */ 540*6881a400Schristos tdep->struct_return = reg_struct_return; 541*6881a400Schristos 542*6881a400Schristos /* NetBSD uses tramp_frame sniffers for signal trampolines. */ 543*6881a400Schristos tdep->sigcontext_addr= 0; 544*6881a400Schristos tdep->sigtramp_start = 0; 545*6881a400Schristos tdep->sigtramp_end = 0; 546*6881a400Schristos tdep->sigtramp_p = 0; 547*6881a400Schristos tdep->sc_reg_offset = 0; 548*6881a400Schristos tdep->sc_num_regs = 0; 549*6881a400Schristos 550*6881a400Schristos tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16); 551*6881a400Schristos tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2); 552*6881a400Schristos tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2); 553*6881a400Schristos tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31); 554*6881a400Schristos tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4); 555*6881a400Schristos 556*6881a400Schristos /* Unwind kernel trap frames correctly. */ 557*6881a400Schristos frame_unwind_prepend_unwinder (gdbarch, &i386nbsd_trapframe_unwind); 558*6881a400Schristos } 559*6881a400Schristos 560*6881a400Schristos /* NetBSD ELF. */ 561*6881a400Schristos 562*6881a400Schristos static void 563*6881a400Schristos i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 564*6881a400Schristos { 565*6881a400Schristos i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch); 566*6881a400Schristos 567*6881a400Schristos /* It's still NetBSD. */ 568*6881a400Schristos i386nbsd_init_abi (info, gdbarch); 569*6881a400Schristos 570*6881a400Schristos /* But ELF-based. */ 571*6881a400Schristos i386_elf_init_abi (info, gdbarch); 572*6881a400Schristos 573*6881a400Schristos /* NetBSD ELF uses SVR4-style shared libraries. */ 574*6881a400Schristos set_solib_svr4_fetch_link_map_offsets 575*6881a400Schristos (gdbarch, svr4_ilp32_fetch_link_map_offsets); 576*6881a400Schristos 577*6881a400Schristos /* NetBSD ELF uses -fpcc-struct-return by default. */ 578*6881a400Schristos tdep->struct_return = pcc_struct_return; 579*6881a400Schristos } 580*6881a400Schristos 581*6881a400Schristos void _initialize_i386nbsd_tdep (); 582*6881a400Schristos void 583*6881a400Schristos _initialize_i386nbsd_tdep () 584*6881a400Schristos { 585*6881a400Schristos gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_NETBSD, 586*6881a400Schristos i386nbsdelf_init_abi); 587*6881a400Schristos } 588