1/* Target-dependent code for GNU/Linux on OpenRISC processors. 2 Copyright (C) 2018-2020 Free Software Foundation, Inc. 3 4 This file is part of GDB. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19#include "defs.h" 20#include "or1k-tdep.h" 21#include "osabi.h" 22#include "glibc-tdep.h" 23#include "linux-tdep.h" 24#include "solib-svr4.h" 25#include "regset.h" 26#include "tramp-frame.h" 27#include "trad-frame.h" 28#include "gdbarch.h" 29 30/* Define the general register mapping. The kernel puts the PC at offset 0, 31 gdb puts it at offset 32. Register x0 is always 0 and can be ignored. 32 Registers x1 to x31 are in the same place. */ 33 34static const struct regcache_map_entry or1k_linux_gregmap[] = 35{ 36 { 32, OR1K_ZERO_REGNUM, 4 }, /* r0 to r31 */ 37 { 1, OR1K_NPC_REGNUM, 4 }, 38 { 0 } 39}; 40 41/* Define the general register regset. */ 42 43static const struct regset or1k_linux_gregset = 44{ 45 or1k_linux_gregmap, regcache_supply_regset, regcache_collect_regset 46}; 47 48/* Define hook for core file support. */ 49 50static void 51or1k_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, 52 iterate_over_regset_sections_cb *cb, 53 void *cb_data, 54 const struct regcache *regcache) 55{ 56 cb (".reg", (33 * 4), (33 * 4), &or1k_linux_gregset, NULL, cb_data); 57} 58 59/* Signal trampoline support. */ 60 61static void or1k_linux_sigframe_init (const struct tramp_frame *self, 62 struct frame_info *this_frame, 63 struct trad_frame_cache *this_cache, 64 CORE_ADDR func); 65 66#define OR1K_RT_SIGRETURN 139 67 68#define OR1K_INST_L_ORI_R11_R0_IMM 0xa9600000 69#define OR1K_INST_L_SYS_1 0x20000001 70#define OR1K_INST_L_NOP 0x15000000 71 72static const struct tramp_frame or1k_linux_sigframe = { 73 SIGTRAMP_FRAME, 74 4, 75 { 76 { OR1K_INST_L_ORI_R11_R0_IMM | OR1K_RT_SIGRETURN, ULONGEST_MAX }, 77 { OR1K_INST_L_SYS_1, ULONGEST_MAX }, 78 { OR1K_INST_L_NOP, ULONGEST_MAX }, 79 { TRAMP_SENTINEL_INSN } 80 }, 81 or1k_linux_sigframe_init, 82 NULL 83}; 84 85/* Runtime signal frames look like this: 86 struct rt_sigframe { 87 struct siginfo info; 88 struct ucontext uc; 89 unsigned char retcode[16]; 90 }; 91 92 struct ucontext { 93 unsigned long uc_flags; - 4 94 struct ucontext *uc_link; - 4 95 stack_t uc_stack; - 4 * 3 96 struct sigcontext uc_mcontext; 97 sigset_t uc_sigmask; 98 }; 99 100 struct sigcontext { 101 struct user_regs_struct regs; 102 unsigned long oldmask; 103 }; 104 105 struct user_regs_struct { 106 unsigned long gpr[32]; 107 unsigned long pc; 108 unsigned long sr; 109 }; */ 110 111#define SIGFRAME_SIGINFO_SIZE 128 112#define UCONTEXT_MCONTEXT_OFFSET 20 113 114static void 115or1k_linux_sigframe_init (const struct tramp_frame *self, 116 struct frame_info *this_frame, 117 struct trad_frame_cache *this_cache, 118 CORE_ADDR func) 119{ 120 CORE_ADDR frame_sp = get_frame_sp (this_frame); 121 CORE_ADDR mcontext_base; 122 CORE_ADDR regs_base; 123 124 mcontext_base = frame_sp + SIGFRAME_SIGINFO_SIZE + UCONTEXT_MCONTEXT_OFFSET; 125 126 /* Handle the general registers 0-31 followed by the PC. */ 127 regs_base = mcontext_base; 128 for (int i = 0; i < 32; i++) 129 trad_frame_set_reg_addr (this_cache, OR1K_ZERO_REGNUM + i, 130 regs_base + (i * 4)); 131 trad_frame_set_reg_addr (this_cache, OR1K_NPC_REGNUM, regs_base + (32 * 4)); 132 trad_frame_set_reg_addr (this_cache, OR1K_SR_REGNUM, regs_base + (33 * 4)); 133 134 /* Choice of the bottom of the sigframe is somewhat arbitrary. */ 135 trad_frame_set_id (this_cache, frame_id_build (frame_sp, func)); 136} 137 138/* Initialize OpenRISC Linux ABI info. */ 139 140static void 141or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 142{ 143 linux_init_abi (info, gdbarch); 144 145 set_solib_svr4_fetch_link_map_offsets (gdbarch, 146 svr4_ilp32_fetch_link_map_offsets); 147 148 /* GNU/Linux uses SVR4-style shared libraries. */ 149 set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); 150 151 /* GNU/Linux uses the dynamic linker included in the GNU C Library. */ 152 set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); 153 154 /* Enable TLS support. */ 155 set_gdbarch_fetch_tls_load_module_address (gdbarch, 156 svr4_fetch_objfile_link_map); 157 158 set_gdbarch_iterate_over_regset_sections 159 (gdbarch, or1k_linux_iterate_over_regset_sections); 160 161 tramp_frame_prepend_unwinder (gdbarch, &or1k_linux_sigframe); 162} 163 164/* Initialize OpenRISC Linux target support. */ 165 166void _initialize_or1k_linux_tdep (); 167void 168_initialize_or1k_linux_tdep () 169{ 170 gdbarch_register_osabi (bfd_arch_or1k, 0, GDB_OSABI_LINUX, 171 or1k_linux_init_abi); 172} 173