1/* Target-dependent code for Analog Devices Blackfin processor, for GDB. 2 3 Copyright (C) 2005-2020 Free Software Foundation, Inc. 4 5 Contributed by Analog Devices, Inc. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22#include "defs.h" 23#include "arch-utils.h" 24#include "regcache.h" 25#include "tramp-frame.h" 26#include "trad-frame.h" 27#include "osabi.h" 28#include "xml-syscall.h" 29#include "linux-tdep.h" 30#include "bfin-tdep.h" 31 32/* From <asm/sigcontext.h>. */ 33 34#define SIGCONTEXT_OFFSET 168 35 36static const int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] = 37{ 38 0 * 4, /* %r0 */ 39 1 * 4, /* %r1 */ 40 2 * 4, /* %r2 */ 41 3 * 4, /* %r3 */ 42 4 * 4, /* %r4 */ 43 5 * 4, /* %r5 */ 44 6 * 4, /* %r6 */ 45 7 * 4, /* %r7 */ 46 8 * 4, /* %p0 */ 47 9 * 4, /* %p1 */ 48 10 * 4, /* %p2 */ 49 11 * 4, /* %p3 */ 50 12 * 4, /* %p4 */ 51 13 * 4, /* %p5 */ 52 14 * 4, /* %sp */ 53 23 * 4, /* %fp */ 54 24 * 4, /* %i0 */ 55 25 * 4, /* %i1 */ 56 26 * 4, /* %i2 */ 57 27 * 4, /* %i3 */ 58 28 * 4, /* %m0 */ 59 29 * 4, /* %m1 */ 60 30 * 4, /* %m2 */ 61 31 * 4, /* %m3 */ 62 36 * 4, /* %b0 */ 63 37 * 4, /* %b1 */ 64 38 * 4, /* %b2 */ 65 39 * 4, /* %b3 */ 66 32 * 4, /* %l0 */ 67 33 * 4, /* %l1 */ 68 34 * 4, /* %l2 */ 69 35 * 4, /* %l3 */ 70 17 * 4, /* %a0x */ 71 15 * 4, /* %a0w */ 72 18 * 4, /* %a1x */ 73 16 * 4, /* %a1w */ 74 19 * 4, /* %astat */ 75 20 * 4, /* %rets */ 76 40 * 4, /* %lc0 */ 77 42 * 4, /* %lt0 */ 78 44 * 4, /* %lb0 */ 79 41 * 4, /* %lc1 */ 80 43 * 4, /* %lt1 */ 81 45 * 4, /* %lb1 */ 82 -1, /* %cycles */ 83 -1, /* %cycles2 */ 84 -1, /* %usp */ 85 46 * 4, /* %seqstat */ 86 -1, /* syscfg */ 87 21 * 4, /* %reti */ 88 22 * 4, /* %retx */ 89 -1, /* %retn */ 90 -1, /* %rete */ 91 21 * 4, /* %pc */ 92}; 93 94/* Signal trampolines. */ 95 96static void 97bfin_linux_sigframe_init (const struct tramp_frame *self, 98 struct frame_info *this_frame, 99 struct trad_frame_cache *this_cache, 100 CORE_ADDR func) 101{ 102 CORE_ADDR sp = get_frame_sp (this_frame); 103 CORE_ADDR pc = get_frame_pc (this_frame); 104 CORE_ADDR sigcontext = sp + SIGCONTEXT_OFFSET; 105 const int *reg_offset = bfin_linux_sigcontext_reg_offset; 106 int i; 107 108 for (i = 0; i < BFIN_NUM_REGS; i++) 109 if (reg_offset[i] != -1) 110 trad_frame_set_reg_addr (this_cache, i, sigcontext + reg_offset[i]); 111 112 /* This would come after the LINK instruction in the ret_from_signal 113 function, hence the frame id would be SP + 8. */ 114 trad_frame_set_id (this_cache, frame_id_build (sp + 8, pc)); 115} 116 117static const struct tramp_frame bfin_linux_sigframe = 118{ 119 SIGTRAMP_FRAME, 120 4, 121 { 122 { 0x00ADE128, 0xffffffff }, /* P0 = __NR_rt_sigreturn; */ 123 { 0x00A0, 0xffff }, /* EXCPT 0; */ 124 { TRAMP_SENTINEL_INSN, ULONGEST_MAX }, 125 }, 126 bfin_linux_sigframe_init, 127}; 128 129static LONGEST 130bfin_linux_get_syscall_number (struct gdbarch *gdbarch, 131 thread_info *thread) 132{ 133 struct regcache *regcache = get_thread_regcache (thread); 134 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 135 /* The content of a register. */ 136 gdb_byte buf[4]; 137 /* The result. */ 138 LONGEST ret; 139 140 /* Getting the system call number from the register. 141 When dealing with Blackfin architecture, this information 142 is stored at %p0 register. */ 143 regcache->cooked_read (BFIN_P0_REGNUM, buf); 144 145 ret = extract_signed_integer (buf, 4, byte_order); 146 147 return ret; 148} 149 150static void 151bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 152{ 153 linux_init_abi (info, gdbarch); 154 155 /* Set the sigtramp frame sniffer. */ 156 tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe); 157 158 /* Functions for 'catch syscall'. */ 159 set_xml_syscall_file_name (gdbarch, "syscalls/bfin-linux.xml"); 160 set_gdbarch_get_syscall_number (gdbarch, 161 bfin_linux_get_syscall_number); 162} 163 164void _initialize_bfin_linux_tdep (); 165void 166_initialize_bfin_linux_tdep () 167{ 168 gdbarch_register_osabi (bfd_arch_bfin, 0, GDB_OSABI_LINUX, 169 bfin_linux_init_abi); 170} 171