/* Target-dependent code for OpenBSD. Copyright (C) 2005-2017 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" #include "frame.h" #include "symtab.h" #include "objfiles.h" #include "obsd-tdep.h" CORE_ADDR obsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { struct bound_minimal_symbol msym; msym = lookup_minimal_symbol("_dl_bind", NULL, NULL); if (msym.minsym && BMSYMBOL_VALUE_ADDRESS (msym) == pc) return frame_unwind_caller_pc (get_current_frame ()); else return find_solib_trampoline_target (get_current_frame (), pc); } /* OpenBSD signal numbers. From <sys/signal.h>. */ enum { OBSD_SIGHUP = 1, OBSD_SIGINT = 2, OBSD_SIGQUIT = 3, OBSD_SIGILL = 4, OBSD_SIGTRAP = 5, OBSD_SIGABRT = 6, OBSD_SIGEMT = 7, OBSD_SIGFPE = 8, OBSD_SIGKILL = 9, OBSD_SIGBUS = 10, OBSD_SIGSEGV = 11, OBSD_SIGSYS = 12, OBSD_SIGPIPE = 13, OBSD_SIGALRM = 14, OBSD_SIGTERM = 15, OBSD_SIGURG = 16, OBSD_SIGSTOP = 17, OBSD_SIGTSTP = 18, OBSD_SIGCONT = 19, OBSD_SIGCHLD = 20, OBSD_SIGTTIN = 21, OBSD_SIGTTOU = 22, OBSD_SIGIO = 23, OBSD_SIGXCPU = 24, OBSD_SIGXFSZ = 25, OBSD_SIGVTALRM = 26, OBSD_SIGPROF = 27, OBSD_SIGWINCH = 28, OBSD_SIGINFO = 29, OBSD_SIGUSR1 = 30, OBSD_SIGUSR2 = 31, OBSD_SIGTHR = 32, }; /* Implement the "gdb_signal_from_target" gdbarch method. */ static enum gdb_signal obsd_gdb_signal_from_target (struct gdbarch *gdbarch, int signal) { switch (signal) { case 0: return GDB_SIGNAL_0; case OBSD_SIGHUP: return GDB_SIGNAL_HUP; case OBSD_SIGINT: return GDB_SIGNAL_INT; case OBSD_SIGQUIT: return GDB_SIGNAL_QUIT; case OBSD_SIGILL: return GDB_SIGNAL_ILL; case OBSD_SIGTRAP: return GDB_SIGNAL_TRAP; case OBSD_SIGABRT: return GDB_SIGNAL_ABRT; case OBSD_SIGEMT: return GDB_SIGNAL_EMT; case OBSD_SIGFPE: return GDB_SIGNAL_FPE; case OBSD_SIGKILL: return GDB_SIGNAL_KILL; case OBSD_SIGBUS: return GDB_SIGNAL_BUS; case OBSD_SIGSEGV: return GDB_SIGNAL_SEGV; case OBSD_SIGSYS: return GDB_SIGNAL_SYS; case OBSD_SIGPIPE: return GDB_SIGNAL_PIPE; case OBSD_SIGALRM: return GDB_SIGNAL_ALRM; case OBSD_SIGTERM: return GDB_SIGNAL_TERM; case OBSD_SIGURG: return GDB_SIGNAL_URG; case OBSD_SIGSTOP: return GDB_SIGNAL_STOP; case OBSD_SIGTSTP: return GDB_SIGNAL_TSTP; case OBSD_SIGCONT: return GDB_SIGNAL_CONT; case OBSD_SIGCHLD: return GDB_SIGNAL_CHLD; case OBSD_SIGTTIN: return GDB_SIGNAL_TTIN; case OBSD_SIGTTOU: return GDB_SIGNAL_TTOU; case OBSD_SIGIO: return GDB_SIGNAL_IO; case OBSD_SIGXCPU: return GDB_SIGNAL_XCPU; case OBSD_SIGXFSZ: return GDB_SIGNAL_XFSZ; case OBSD_SIGVTALRM: return GDB_SIGNAL_VTALRM; case OBSD_SIGPROF: return GDB_SIGNAL_PROF; case OBSD_SIGWINCH: return GDB_SIGNAL_WINCH; case OBSD_SIGINFO: return GDB_SIGNAL_INFO; case OBSD_SIGUSR1: return GDB_SIGNAL_USR1; case OBSD_SIGUSR2: return GDB_SIGNAL_USR2; } return GDB_SIGNAL_UNKNOWN; } /* Implement the "gdb_signal_to_target" gdbarch method. */ static int obsd_gdb_signal_to_target (struct gdbarch *gdbarch, enum gdb_signal signal) { switch (signal) { case GDB_SIGNAL_0: return 0; case GDB_SIGNAL_HUP: return OBSD_SIGHUP; case GDB_SIGNAL_INT: return OBSD_SIGINT; case GDB_SIGNAL_QUIT: return OBSD_SIGQUIT; case GDB_SIGNAL_ILL: return OBSD_SIGILL; case GDB_SIGNAL_TRAP: return OBSD_SIGTRAP; case GDB_SIGNAL_ABRT: return OBSD_SIGABRT; case GDB_SIGNAL_EMT: return OBSD_SIGEMT; case GDB_SIGNAL_FPE: return OBSD_SIGFPE; case GDB_SIGNAL_KILL: return OBSD_SIGKILL; case GDB_SIGNAL_BUS: return OBSD_SIGBUS; case GDB_SIGNAL_SEGV: return OBSD_SIGSEGV; case GDB_SIGNAL_SYS: return OBSD_SIGSYS; case GDB_SIGNAL_PIPE: return OBSD_SIGPIPE; case GDB_SIGNAL_ALRM: return OBSD_SIGALRM; case GDB_SIGNAL_TERM: return OBSD_SIGTERM; case GDB_SIGNAL_URG: return OBSD_SIGURG; case GDB_SIGNAL_STOP: return OBSD_SIGSTOP; case GDB_SIGNAL_TSTP: return OBSD_SIGTSTP; case GDB_SIGNAL_CONT: return OBSD_SIGCONT; case GDB_SIGNAL_CHLD: return OBSD_SIGCHLD; case GDB_SIGNAL_TTIN: return OBSD_SIGTTIN; case GDB_SIGNAL_TTOU: return OBSD_SIGTTOU; case GDB_SIGNAL_IO: return OBSD_SIGIO; case GDB_SIGNAL_XCPU: return OBSD_SIGXCPU; case GDB_SIGNAL_XFSZ: return OBSD_SIGXFSZ; case GDB_SIGNAL_VTALRM: return OBSD_SIGVTALRM; case GDB_SIGNAL_PROF: return OBSD_SIGPROF; case GDB_SIGNAL_WINCH: return OBSD_SIGWINCH; case GDB_SIGNAL_USR1: return OBSD_SIGUSR1; case GDB_SIGNAL_USR2: return OBSD_SIGUSR2; case GDB_SIGNAL_INFO: return OBSD_SIGINFO; } return -1; } static int obsd_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) { struct type *int_type = builtin_type (gdbarch)->builtin_int; struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; const int sizeof_auxv_type = TYPE_LENGTH (int_type); const int sizeof_auxv_val = TYPE_LENGTH (ptr_type); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte *ptr = *readptr; if (endptr == ptr) return 0; if (endptr - ptr < 2 * sizeof_auxv_val) return -1; *typep = extract_unsigned_integer (ptr, sizeof_auxv_type, byte_order); ptr += sizeof_auxv_val; /* Alignment. */ *valp = extract_unsigned_integer (ptr, sizeof_auxv_val, byte_order); ptr += sizeof_auxv_val; *readptr = ptr; return 1; } void obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { set_gdbarch_gdb_signal_from_target (gdbarch, obsd_gdb_signal_from_target); set_gdbarch_gdb_signal_to_target (gdbarch, obsd_gdb_signal_to_target); /* Unlike Linux, OpenBSD actually follows the ELF standard. */ set_gdbarch_auxv_parse (gdbarch, obsd_auxv_parse); }