diff options
author | Mike Frysinger <vapier@gentoo.org> | 2010-12-29 16:11:49 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-12-29 16:11:49 +0000 |
commit | 9102122396b6b977eb2e283a6c092d1ab510e788 (patch) | |
tree | 8363a4c175ef9433c81f1e61afd4f0635deace85 | |
parent | abc1f4cd130f48697c535e0d64580721d181d3d1 (diff) | |
download | gdb-9102122396b6b977eb2e283a6c092d1ab510e788.zip gdb-9102122396b6b977eb2e283a6c092d1ab510e788.tar.gz gdb-9102122396b6b977eb2e283a6c092d1ab510e788.tar.bz2 |
gdb: bfin: new port
Initial support for Blackfin processors. This supports the standard ABI.
Signed-off-by: Jie Zhang <jie.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/Makefile.in | 4 | ||||
-rw-r--r-- | gdb/NEWS | 4 | ||||
-rw-r--r-- | gdb/bfin-linux-tdep.c | 175 | ||||
-rw-r--r-- | gdb/bfin-tdep.c | 862 | ||||
-rw-r--r-- | gdb/bfin-tdep.h | 102 | ||||
-rw-r--r-- | gdb/configure.tgt | 9 | ||||
-rw-r--r-- | gdb/syscalls/bfin-linux.xml | 326 |
8 files changed, 1492 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e57926c..88cdd75 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2010-12-29 Jie Zhang <jie.zhang@analog.com> + Mike Frysinger <vapier@gentoo.org> + + * Makefile.in (ALLDEPFILES): Add bfin-linux-tdep.c and bfin-tdep.c. + (HFILES_NO_SRCDIR): Add bfin-tdep.h. + (ALL_TARGET_OBS): Add bfin-linux-tdep.o and bfin-tdep.o. + * NEWS: Mention new Blackfin port. + * bfin-tdep.c, bfin-tdep.h, bfin-linux-tdep.c, + syscalls/bfin-linux.xml: New files. + * configure.tgt (bfin-*-*): Handle bfin targets. + 2010-12-29 Hui Zhu <teawater@gmail.com> * ax-gdb.c (gen_expr): Change error message. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ff10039..e0f6636 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -508,6 +508,7 @@ ALL_TARGET_OBS = \ armnbsd-tdep.o armobsd-tdep.o \ arm-tdep.o arm-wince-tdep.o \ avr-tdep.o \ + bfin-linux-tdep.o bfin-tdep.o \ cris-tdep.o \ dicos-tdep.o \ frv-linux-tdep.o frv-tdep.o \ @@ -782,7 +783,7 @@ annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h \ remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \ sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \ gdb_usleep.h jit.h xml-syscall.h ada-operator.inc microblaze-tdep.h \ -psymtab.h psympriv.h progspace.h +psymtab.h psympriv.h progspace.h bfin-tdep.h # Header files that already have srcdir in them, or which are in objdir. @@ -1420,6 +1421,7 @@ ALLDEPFILES = \ arm-linux-nat.c arm-linux-tdep.c arm-symbian-tdep.c arm-tdep.c \ armnbsd-nat.c armbsd-tdep.c armnbsd-tdep.c armobsd-tdep.c \ avr-tdep.c \ + bfin-linux-tdep.c bfin-tdep.c \ bsd-uthread.c bsd-kvm.c \ core-regset.c corelow.c \ dcache.c dicos-tdep.c darwin-nat.c \ @@ -111,6 +111,10 @@ ** GDBserver is now supported on PowerPC LynxOS (versions 4.x and 5.x), and i686 LynxOS (version 5.x). +* New targets: + +Analog Devices, Inc. Blackfin Processor bfin-* + * Ada task switching is now supported on sparc-elf targets when debugging a program using the Ravenscar Profile. For more information, see the "Tasking Support when using the Ravenscar Profile" section diff --git a/gdb/bfin-linux-tdep.c b/gdb/bfin-linux-tdep.c new file mode 100644 index 0000000..545bdcf --- /dev/null +++ b/gdb/bfin-linux-tdep.c @@ -0,0 +1,175 @@ +/* Target-dependent code for Analog Devices Blackfin processor, for GDB. + + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + + Contributed by Analog Devices, 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 "arch-utils.h" +#include "regcache.h" +#include "tramp-frame.h" +#include "trad-frame.h" +#include "osabi.h" +#include "xml-syscall.h" +#include "linux-tdep.h" +#include "bfin-tdep.h" + +/* From <asm/sigcontext.h>. */ + +#define SIGCONTEXT_OFFSET 168 + +static const int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] = +{ + 0 * 4, /* %r0 */ + 1 * 4, /* %r1 */ + 2 * 4, /* %r2 */ + 3 * 4, /* %r3 */ + 4 * 4, /* %r4 */ + 5 * 4, /* %r5 */ + 6 * 4, /* %r6 */ + 7 * 4, /* %r7 */ + 8 * 4, /* %p0 */ + 9 * 4, /* %p1 */ + 10 * 4, /* %p2 */ + 11 * 4, /* %p3 */ + 12 * 4, /* %p4 */ + 13 * 4, /* %p5 */ + 14 * 4, /* %sp */ + 23 * 4, /* %fp */ + 24 * 4, /* %i0 */ + 25 * 4, /* %i1 */ + 26 * 4, /* %i2 */ + 27 * 4, /* %i3 */ + 28 * 4, /* %m0 */ + 29 * 4, /* %m1 */ + 30 * 4, /* %m2 */ + 31 * 4, /* %m3 */ + 36 * 4, /* %b0 */ + 37 * 4, /* %b1 */ + 38 * 4, /* %b2 */ + 39 * 4, /* %b3 */ + 32 * 4, /* %l0 */ + 33 * 4, /* %l1 */ + 34 * 4, /* %l2 */ + 35 * 4, /* %l3 */ + 17 * 4, /* %a0x */ + 15 * 4, /* %a0w */ + 18 * 4, /* %a1x */ + 16 * 4, /* %a1w */ + 19 * 4, /* %astat */ + 20 * 4, /* %rets */ + 40 * 4, /* %lc0 */ + 42 * 4, /* %lt0 */ + 44 * 4, /* %lb0 */ + 41 * 4, /* %lc1 */ + 43 * 4, /* %lt1 */ + 45 * 4, /* %lb1 */ + -1, /* %cycles */ + -1, /* %cycles2 */ + -1, /* %usp */ + 46 * 4, /* %seqstat */ + -1, /* syscfg */ + 21 * 4, /* %reti */ + 22 * 4, /* %retx */ + -1, /* %retn */ + -1, /* %rete */ + 21 * 4, /* %pc */ +}; + +/* Signal trampolines. */ + +static void +bfin_linux_sigframe_init (const struct tramp_frame *self, + struct frame_info *this_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + CORE_ADDR sp = get_frame_sp (this_frame); + CORE_ADDR pc = get_frame_pc (this_frame); + CORE_ADDR sigcontext = sp + SIGCONTEXT_OFFSET; + struct frame_id this_id; + const int *reg_offset = bfin_linux_sigcontext_reg_offset; + int i; + + for (i = 0; i < BFIN_NUM_REGS; i++) + if (reg_offset[i] != -1) + trad_frame_set_reg_addr (this_cache, i, sigcontext + reg_offset[i]); + + /* This would come after the LINK instruction in the ret_from_signal + function, hence the frame id would be SP + 8. */ + trad_frame_set_id (this_cache, frame_id_build (sp + 8, pc)); +} + +static const struct tramp_frame bfin_linux_sigframe = +{ + SIGTRAMP_FRAME, + 4, + { + { 0x00ADE128, 0xffffffff }, /* P0 = __NR_rt_sigreturn; */ + { 0x00A0, 0xffff }, /* EXCPT 0; */ + { TRAMP_SENTINEL_INSN, -1 }, + }, + bfin_linux_sigframe_init, +}; + +static LONGEST +bfin_linux_get_syscall_number (struct gdbarch *gdbarch, + ptid_t ptid) +{ + struct regcache *regcache = get_thread_regcache (ptid); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + /* The content of a register. */ + gdb_byte buf[4]; + /* The result. */ + LONGEST ret; + + /* Getting the system call number from the register. + When dealing with Blackfin architecture, this information + is stored at %p0 register. */ + regcache_cooked_read (regcache, BFIN_P0_REGNUM, buf); + + ret = extract_signed_integer (buf, 4, byte_order); + + return ret; +} + +static void +bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + linux_init_abi (info, gdbarch); + + /* Set the sigtramp frame sniffer. */ + tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe); + + /* Functions for 'catch syscall'. */ + set_xml_syscall_file_name ("syscalls/bfin-linux.xml"); + set_gdbarch_get_syscall_number (gdbarch, + bfin_linux_get_syscall_number); +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_bfin_linux_tdep; + +void +_initialize_bfin_linux_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_bfin, 0, GDB_OSABI_LINUX, + bfin_linux_init_abi); +} diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c new file mode 100644 index 0000000..ddebdf9 --- /dev/null +++ b/gdb/bfin-tdep.c @@ -0,0 +1,862 @@ +/* Target-dependent code for Analog Devices Blackfin processor, for GDB. + + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + + Contributed by Analog Devices, 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 "gdb_string.h" +#include "inferior.h" +#include "gdbcore.h" +#include "arch-utils.h" +#include "regcache.h" +#include "frame.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "trad-frame.h" +#include "dis-asm.h" +#include "gdb_assert.h" +#include "dwarf2-frame.h" +#include "symtab.h" +#include "elf-bfd.h" +#include "elf/bfin.h" +#include "osabi.h" +#include "infcall.h" +#include "xml-syscall.h" +#include "bfin-tdep.h" + +/* Macros used by prologue functions. */ +#define P_LINKAGE 0xE800 +#define P_MINUS_SP1 0x0140 +#define P_MINUS_SP2 0x05C0 +#define P_MINUS_SP3 0x0540 +#define P_MINUS_SP4 0x04C0 +#define P_SP_PLUS 0x6C06 +#define P_P2_LOW 0xE10A +#define P_P2_HIGH 0XE14A +#define P_SP_EQ_SP_PLUS_P2 0X5BB2 +#define P_SP_EQ_P2_PLUS_SP 0x5B96 +#define P_MINUS_MINUS_SP_EQ_RETS 0x0167 + +/* Macros used for program flow control. */ +/* 16 bit instruction, max */ +#define P_16_BIT_INSR_MAX 0xBFFF +/* 32 bit instruction, min */ +#define P_32_BIT_INSR_MIN 0xC000 +/* 32 bit instruction, max */ +#define P_32_BIT_INSR_MAX 0xE801 +/* jump (preg), 16-bit, min */ +#define P_JUMP_PREG_MIN 0x0050 +/* jump (preg), 16-bit, max */ +#define P_JUMP_PREG_MAX 0x0057 +/* jump (pc+preg), 16-bit, min */ +#define P_JUMP_PC_PLUS_PREG_MIN 0x0080 +/* jump (pc+preg), 16-bit, max */ +#define P_JUMP_PC_PLUS_PREG_MAX 0x0087 +/* jump.s pcrel13m2, 16-bit, min */ +#define P_JUMP_S_MIN 0x2000 +/* jump.s pcrel13m2, 16-bit, max */ +#define P_JUMP_S_MAX 0x2FFF +/* jump.l pcrel25m2, 32-bit, min */ +#define P_JUMP_L_MIN 0xE200 +/* jump.l pcrel25m2, 32-bit, max */ +#define P_JUMP_L_MAX 0xE2FF +/* conditional jump pcrel11m2, 16-bit, min */ +#define P_IF_CC_JUMP_MIN 0x1800 +/* conditional jump pcrel11m2, 16-bit, max */ +#define P_IF_CC_JUMP_MAX 0x1BFF +/* conditional jump(bp) pcrel11m2, 16-bit, min */ +#define P_IF_CC_JUMP_BP_MIN 0x1C00 +/* conditional jump(bp) pcrel11m2, 16-bit, max */ +#define P_IF_CC_JUMP_BP_MAX 0x1FFF +/* conditional !jump pcrel11m2, 16-bit, min */ +#define P_IF_NOT_CC_JUMP_MIN 0x1000 +/* conditional !jump pcrel11m2, 16-bit, max */ +#define P_IF_NOT_CC_JUMP_MAX 0x13FF +/* conditional jump(bp) pcrel11m2, 16-bit, min */ +#define P_IF_NOT_CC_JUMP_BP_MIN 0x1400 +/* conditional jump(bp) pcrel11m2, 16-bit, max */ +#define P_IF_NOT_CC_JUMP_BP_MAX 0x17FF +/* call (preg), 16-bit, min */ +#define P_CALL_PREG_MIN 0x0060 +/* call (preg), 16-bit, max */ +#define P_CALL_PREG_MAX 0x0067 +/* call (pc+preg), 16-bit, min */ +#define P_CALL_PC_PLUS_PREG_MIN 0x0070 +/* call (pc+preg), 16-bit, max */ +#define P_CALL_PC_PLUS_PREG_MAX 0x0077 +/* call pcrel25m2, 32-bit, min */ +#define P_CALL_MIN 0xE300 +/* call pcrel25m2, 32-bit, max */ +#define P_CALL_MAX 0xE3FF +/* RTS */ +#define P_RTS 0x0010 +/* MNOP */ +#define P_MNOP 0xC803 +/* EXCPT, 16-bit, min */ +#define P_EXCPT_MIN 0x00A0 +/* EXCPT, 16-bit, max */ +#define P_EXCPT_MAX 0x00AF +/* multi instruction mask 1, 16-bit */ +#define P_BIT_MULTI_INS_1 0xC000 +/* multi instruction mask 2, 16-bit */ +#define P_BIT_MULTI_INS_2 0x0800 + +/* The maximum bytes we search to skip the prologue. */ +#define UPPER_LIMIT 40 + +/* ASTAT bits */ +#define ASTAT_CC_POS 5 +#define ASTAT_CC (1 << ASTAT_CC_POS) + +/* Initial value: Register names used in BFIN's ISA documentation. */ + +static const char * const bfin_register_name_strings[] = +{ + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "p0", "p1", "p2", "p3", "p4", "p5", "sp", "fp", + "i0", "i1", "i2", "i3", "m0", "m1", "m2", "m3", + "b0", "b1", "b2", "b3", "l0", "l1", "l2", "l3", + "a0x", "a0w", "a1x", "a1w", "astat", "rets", + "lc0", "lt0", "lb0", "lc1", "lt1", "lb1", "cycles", "cycles2", + "usp", "seqstat", "syscfg", "reti", "retx", "retn", "rete", + "pc", "cc", +}; + +#define NUM_BFIN_REGNAMES ARRAY_SIZE (bfin_register_name_strings) + + +/* In this diagram successive memory locations increase downwards or the + stack grows upwards with negative indices. (PUSH analogy for stack.) + + The top frame is the "frame" of the current function being executed. + + +--------------+ SP - + | local vars | ^ + +--------------+ | + | save regs | | + +--------------+ FP | + | old FP -|-- top + +--------------+ | frame + | RETS | | | + +--------------+ | | + | param 1 | | | + | param 2 | | | + | ... | | V + +--------------+ | - + | local vars | | ^ + +--------------+ | | + | save regs | | | + +--------------+<- | + | old FP -|-- next + +--------------+ | frame + | RETS | | | + +--------------+ | | + | param 1 | | | + | param 2 | | | + | ... | | V + +--------------+ | - + | local vars | | ^ + +--------------+ | | + | save regs | | | + +--------------+<- next frame + | old FP | | + +--------------+ | + | RETS | V + +--------------+ - + + The frame chain is formed as following: + + FP has the topmost frame. + FP + 4 has the previous FP and so on. */ + + +/* Map from DWARF2 register number to GDB register number. */ + +static const int map_gcc_gdb[] = +{ + BFIN_R0_REGNUM, + BFIN_R1_REGNUM, + BFIN_R2_REGNUM, + BFIN_R3_REGNUM, + BFIN_R4_REGNUM, + BFIN_R5_REGNUM, + BFIN_R6_REGNUM, + BFIN_R7_REGNUM, + BFIN_P0_REGNUM, + BFIN_P1_REGNUM, + BFIN_P2_REGNUM, + BFIN_P3_REGNUM, + BFIN_P4_REGNUM, + BFIN_P5_REGNUM, + BFIN_SP_REGNUM, + BFIN_FP_REGNUM, + BFIN_I0_REGNUM, + BFIN_I1_REGNUM, + BFIN_I2_REGNUM, + BFIN_I3_REGNUM, + BFIN_B0_REGNUM, + BFIN_B1_REGNUM, + BFIN_B2_REGNUM, + BFIN_B3_REGNUM, + BFIN_L0_REGNUM, + BFIN_L1_REGNUM, + BFIN_L2_REGNUM, + BFIN_L3_REGNUM, + BFIN_M0_REGNUM, + BFIN_M1_REGNUM, + BFIN_M2_REGNUM, + BFIN_M3_REGNUM, + BFIN_A0_DOT_X_REGNUM, + BFIN_A1_DOT_X_REGNUM, + BFIN_CC_REGNUM, + BFIN_RETS_REGNUM, + BFIN_RETI_REGNUM, + BFIN_RETX_REGNUM, + BFIN_RETN_REGNUM, + BFIN_RETE_REGNUM, + BFIN_ASTAT_REGNUM, + BFIN_SEQSTAT_REGNUM, + BFIN_USP_REGNUM, + BFIN_LT0_REGNUM, + BFIN_LT1_REGNUM, + BFIN_LC0_REGNUM, + BFIN_LC1_REGNUM, + BFIN_LB0_REGNUM, + BFIN_LB1_REGNUM +}; + + +struct bfin_frame_cache +{ + /* Base address. */ + CORE_ADDR base; + CORE_ADDR sp_offset; + CORE_ADDR pc; + int frameless_pc_value; + + /* Saved registers. */ + CORE_ADDR saved_regs[BFIN_NUM_REGS]; + CORE_ADDR saved_sp; + + /* Stack space reserved for local variables. */ + long locals; +}; + +/* Allocate and initialize a frame cache. */ + +static struct bfin_frame_cache * +bfin_alloc_frame_cache (void) +{ + struct bfin_frame_cache *cache; + int i; + + cache = FRAME_OBSTACK_ZALLOC (struct bfin_frame_cache); + + /* Base address. */ + cache->base = 0; + cache->sp_offset = -4; + cache->pc = 0; + cache->frameless_pc_value = 0; + + /* Saved registers. We initialize these to -1 since zero is a valid + offset (that's where fp is supposed to be stored). */ + for (i = 0; i < BFIN_NUM_REGS; i++) + cache->saved_regs[i] = -1; + + /* Frameless until proven otherwise. */ + cache->locals = -1; + + return cache; +} + +static struct bfin_frame_cache * +bfin_frame_cache (struct frame_info *this_frame, void **this_cache) +{ + struct bfin_frame_cache *cache; + int i; + + if (*this_cache) + return *this_cache; + + cache = bfin_alloc_frame_cache (); + *this_cache = cache; + + cache->base = get_frame_register_unsigned (this_frame, BFIN_FP_REGNUM); + if (cache->base == 0) + return cache; + + /* For normal frames, PC is stored at [FP + 4]. */ + cache->saved_regs[BFIN_PC_REGNUM] = 4; + cache->saved_regs[BFIN_FP_REGNUM] = 0; + + /* Adjust all the saved registers such that they contain addresses + instead of offsets. */ + for (i = 0; i < BFIN_NUM_REGS; i++) + if (cache->saved_regs[i] != -1) + cache->saved_regs[i] += cache->base; + + cache->pc = get_frame_func (this_frame) ; + if (cache->pc == 0 || cache->pc == get_frame_pc (this_frame)) + { + /* Either there is no prologue (frameless function) or we are at + the start of a function. In short we do not have a frame. + PC is stored in rets register. FP points to previous frame. */ + + cache->saved_regs[BFIN_PC_REGNUM] = + get_frame_register_unsigned (this_frame, BFIN_RETS_REGNUM); + cache->frameless_pc_value = 1; + cache->base = get_frame_register_unsigned (this_frame, BFIN_FP_REGNUM); + cache->saved_regs[BFIN_FP_REGNUM] = cache->base; + cache->saved_sp = cache->base; + } + else + { + cache->frameless_pc_value = 0; + + /* Now that we have the base address for the stack frame we can + calculate the value of SP in the calling frame. */ + cache->saved_sp = cache->base + 8; + } + + return cache; +} + +static void +bfin_frame_this_id (struct frame_info *this_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) + return; + + /* See the end of bfin_push_dummy_call. */ + *this_id = frame_id_build (cache->base + 8, cache->pc); +} + +static struct value * +bfin_frame_prev_register (struct frame_info *this_frame, + void **this_cache, + int regnum) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache); + + if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp) + return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp); + + if (regnum < BFIN_NUM_REGS && cache->saved_regs[regnum] != -1) + return frame_unwind_got_memory (this_frame, regnum, + cache->saved_regs[regnum]); + + return frame_unwind_got_register (this_frame, regnum, regnum); +} + +static const struct frame_unwind bfin_frame_unwind = +{ + NORMAL_FRAME, + bfin_frame_this_id, + bfin_frame_prev_register, + NULL, + default_frame_sniffer +}; + +/* Check for "[--SP] = <reg>;" insns. These are appear in function + prologues to save misc registers onto the stack. */ + +static int +is_minus_minus_sp (int op) +{ + op &= 0xFFC0; + + if ((op == P_MINUS_SP1) || (op == P_MINUS_SP2) + || (op == P_MINUS_SP3) || (op == P_MINUS_SP4)) + return 1; + + return 0; +} + +/* Skip all the insns that appear in generated function prologues. */ + +static CORE_ADDR +bfin_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + int op = read_memory_unsigned_integer (pc, 2, byte_order); + CORE_ADDR orig_pc = pc; + int done = 0; + + /* The new gcc prologue generates the register saves BEFORE the link + or RETS saving instruction. + So, our job is to stop either at those instructions or some upper + limit saying there is no frame! */ + + while (!done) + { + if (is_minus_minus_sp (op)) + { + while (is_minus_minus_sp (op)) + { + pc += 2; + op = read_memory_unsigned_integer (pc, 2, byte_order); + } + + if (op == P_LINKAGE) + pc += 4; + + done = 1; + } + else if (op == P_LINKAGE) + { + pc += 4; + done = 1; + } + else if (op == P_MINUS_MINUS_SP_EQ_RETS) + { + pc += 2; + done = 1; + } + else if (op == P_RTS) + { + done = 1; + } + else if ((op >= P_JUMP_PREG_MIN && op <= P_JUMP_PREG_MAX) + || (op >= P_JUMP_PC_PLUS_PREG_MIN + && op <= P_JUMP_PC_PLUS_PREG_MAX) + || (op == P_JUMP_S_MIN && op <= P_JUMP_S_MAX)) + { + done = 1; + } + else if (pc - orig_pc >= UPPER_LIMIT) + { + warning (_("Function Prologue not recognised; " + "pc will point to ENTRY_POINT of the function")); + pc = orig_pc + 2; + done = 1; + } + else + { + pc += 2; /* Not a terminating instruction go on. */ + op = read_memory_unsigned_integer (pc, 2, byte_order); + } + } + + /* TODO: + Dwarf2 uses entry point value AFTER some register initializations. + We should perhaps skip such asssignments as well (R6 = R1, ...). */ + + return pc; +} + +/* Return the GDB type object for the "standard" data type of data in + register N. This should be void pointer for P0-P5, SP, FP; + void pointer to function for PC; int otherwise. */ + +static struct type * +bfin_register_type (struct gdbarch *gdbarch, int regnum) +{ + if ((regnum >= BFIN_P0_REGNUM && regnum <= BFIN_FP_REGNUM) + || regnum == BFIN_USP_REGNUM) + return builtin_type (gdbarch)->builtin_data_ptr; + + if (regnum == BFIN_PC_REGNUM || regnum == BFIN_RETS_REGNUM || + regnum == BFIN_RETI_REGNUM || regnum == BFIN_RETX_REGNUM || + regnum == BFIN_RETN_REGNUM || regnum == BFIN_RETE_REGNUM || + regnum == BFIN_LT0_REGNUM || regnum == BFIN_LB0_REGNUM || + regnum == BFIN_LT1_REGNUM || regnum == BFIN_LB1_REGNUM) + return builtin_type (gdbarch)->builtin_func_ptr; + + return builtin_type (gdbarch)->builtin_int32; +} + +static CORE_ADDR +bfin_push_dummy_call (struct gdbarch *gdbarch, + struct value *function, + struct regcache *regcache, + CORE_ADDR bp_addr, + int nargs, + struct value **args, + CORE_ADDR sp, + int struct_return, + CORE_ADDR struct_addr) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + char buf[4]; + int i; + long reg_r0, reg_r1, reg_r2; + int total_len = 0; + enum bfin_abi abi = bfin_abi (gdbarch); + CORE_ADDR func_addr = find_function_addr (function, NULL); + + for (i = nargs - 1; i >= 0; i--) + { + struct type *value_type = value_enclosing_type (args[i]); + int len = TYPE_LENGTH (value_type); + + total_len += (len + 3) & ~3; + } + + /* At least twelve bytes of stack space must be allocated for the function's + arguments, even for functions that have less than 12 bytes of argument + data. */ + + if (total_len < 12) + sp -= 12 - total_len; + + /* Push arguments in reverse order. */ + + for (i = nargs - 1; i >= 0; i--) + { + struct type *value_type = value_enclosing_type (args[i]); + struct type *arg_type = check_typedef (value_type); + int len = TYPE_LENGTH (value_type); + int container_len = (len + 3) & ~3; + + sp -= container_len; + write_memory (sp, value_contents_writeable (args[i]), container_len); + } + + /* Initialize R0, R1, and R2 to the first 3 words of parameters. */ + + reg_r0 = read_memory_integer (sp, 4, byte_order); + regcache_cooked_write_unsigned (regcache, BFIN_R0_REGNUM, reg_r0); + reg_r1 = read_memory_integer (sp + 4, 4, byte_order); + regcache_cooked_write_unsigned (regcache, BFIN_R1_REGNUM, reg_r1); + reg_r2 = read_memory_integer (sp + 8, 4, byte_order); + regcache_cooked_write_unsigned (regcache, BFIN_R2_REGNUM, reg_r2); + + /* Store struct value address. */ + + if (struct_return) + regcache_cooked_write_unsigned (regcache, BFIN_P0_REGNUM, struct_addr); + + /* Set the dummy return value to bp_addr. + A dummy breakpoint will be setup to execute the call. */ + + regcache_cooked_write_unsigned (regcache, BFIN_RETS_REGNUM, bp_addr); + + /* Finally, update the stack pointer. */ + + regcache_cooked_write_unsigned (regcache, BFIN_SP_REGNUM, sp); + + return sp; +} + +/* Convert DWARF2 register number REG to the appropriate register number + used by GDB. */ + +static int +bfin_reg_to_regnum (struct gdbarch *gdbarch, int reg) +{ + if (reg > ARRAY_SIZE (map_gcc_gdb)) + return 0; + + return map_gcc_gdb[reg]; +} + +/* This function implements the BREAKPOINT_FROM_PC macro. It returns + a pointer to a string of bytes that encode a breakpoint instruction, + stores the length of the string to *lenptr, and adjusts the program + counter (if necessary) to point to the actual memory location where + the breakpoint should be inserted. */ + +static const unsigned char * +bfin_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + unsigned short iw; + static unsigned char bfin_breakpoint[] = {0xa1, 0x00, 0x00, 0x00}; + static unsigned char bfin_sim_breakpoint[] = {0x25, 0x00, 0x00, 0x00}; + + iw = read_memory_unsigned_integer (*pcptr, 2, byte_order); + + if ((iw & 0xf000) >= 0xc000) + /* 32-bit instruction. */ + *lenptr = 4; + else + *lenptr = 2; + + if (strcmp (target_shortname, "sim") == 0) + return bfin_sim_breakpoint; + else + return bfin_breakpoint; +} + +static void +bfin_extract_return_value (struct type *type, + struct regcache *regs, + gdb_byte *dst) +{ + struct gdbarch *gdbarch = get_regcache_arch (regs); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + bfd_byte *valbuf = dst; + int len = TYPE_LENGTH (type); + ULONGEST tmp; + int regno = BFIN_R0_REGNUM; + + gdb_assert (len <= 8); + + while (len > 0) + { + regcache_cooked_read_unsigned (regs, regno++, &tmp); + store_unsigned_integer (valbuf, (len > 4 ? 4 : len), tmp, byte_order); + len -= 4; + valbuf += 4; + } +} + +/* Write into appropriate registers a function return value of type + TYPE, given in virtual format. */ + +static void +bfin_store_return_value (struct type *type, + struct regcache *regs, + const gdb_byte *src) +{ + const bfd_byte *valbuf = src; + + /* Integral values greater than one word are stored in consecutive + registers starting with R0. This will always be a multiple of + the register size. */ + + int len = TYPE_LENGTH (type); + int regno = BFIN_R0_REGNUM; + + gdb_assert (len <= 8); + + while (len > 0) + { + regcache_cooked_write (regs, regno++, valbuf); + len -= 4; + valbuf += 4; + } +} + +/* Determine, for architecture GDBARCH, how a return value of TYPE + should be returned. If it is supposed to be returned in registers, + and READBUF is nonzero, read the appropriate value from REGCACHE, + and copy it into READBUF. If WRITEBUF is nonzero, write the value + from WRITEBUF into REGCACHE. */ + +static enum return_value_convention +bfin_return_value (struct gdbarch *gdbarch, + struct type *func_type, + struct type *type, + struct regcache *regcache, + gdb_byte *readbuf, + const gdb_byte *writebuf) +{ + if (TYPE_LENGTH (type) > 8) + return RETURN_VALUE_STRUCT_CONVENTION; + + if (readbuf) + bfin_extract_return_value (type, regcache, readbuf); + + if (writebuf) + bfin_store_return_value (type, regcache, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; +} + +/* Return the BFIN register name corresponding to register I. */ + +static const char * +bfin_register_name (struct gdbarch *gdbarch, int i) +{ + return bfin_register_name_strings[i]; +} + +static void +bfin_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, gdb_byte *buffer) +{ + gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE); + + if (regnum != BFIN_CC_REGNUM) + internal_error (__FILE__, __LINE__, + _("invalid register number %d"), regnum); + + /* Extract the CC bit from the ASTAT register. */ + regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf); + buffer[1] = buffer[2] = buffer[3] = 0; + buffer[0] = !!(buf[0] & ASTAT_CC); +} + +static void +bfin_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, + int regnum, const gdb_byte *buffer) +{ + gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE); + + if (regnum != BFIN_CC_REGNUM) + internal_error (__FILE__, __LINE__, + _("invalid register number %d"), regnum); + + /* Overlay the CC bit in the ASTAT register. */ + regcache_raw_read (regcache, BFIN_ASTAT_REGNUM, buf); + buf[0] = (buf[0] & ~ASTAT_CC) | ((buffer[0] & 1) << ASTAT_CC_POS); + regcache_raw_write (regcache, BFIN_ASTAT_REGNUM, buf); +} + +static CORE_ADDR +bfin_frame_base_address (struct frame_info *this_frame, void **this_cache) +{ + struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache); + + return cache->base; +} + +static CORE_ADDR +bfin_frame_local_address (struct frame_info *this_frame, void **this_cache) +{ + struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache); + + return cache->base - 4; +} + +static CORE_ADDR +bfin_frame_args_address (struct frame_info *this_frame, void **this_cache) +{ + struct bfin_frame_cache *cache = bfin_frame_cache (this_frame, this_cache); + + return cache->base + 8; +} + +static const struct frame_base bfin_frame_base = +{ + &bfin_frame_unwind, + bfin_frame_base_address, + bfin_frame_local_address, + bfin_frame_args_address +}; + +static struct frame_id +bfin_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + CORE_ADDR sp; + + sp = get_frame_register_unsigned (this_frame, BFIN_SP_REGNUM); + + return frame_id_build (sp, get_frame_pc (this_frame)); +} + +static CORE_ADDR +bfin_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + return frame_unwind_register_unsigned (next_frame, BFIN_PC_REGNUM); +} + +static CORE_ADDR +bfin_frame_align (struct gdbarch *gdbarch, CORE_ADDR address) +{ + return (address & ~0x3); +} + +enum bfin_abi +bfin_abi (struct gdbarch *gdbarch) +{ + return gdbarch_tdep (gdbarch)->bfin_abi; +} + +/* Initialize the current architecture based on INFO. If possible, + re-use an architecture from ARCHES, which is a list of + architectures already created during this debugging session. + + Called e.g. at program startup, when reading a core file, and when + reading a binary file. */ + +static struct gdbarch * +bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + struct gdbarch_tdep *tdep; + struct gdbarch *gdbarch; + int elf_flags; + enum bfin_abi abi; + + /* Extract the ELF flags, if available. */ + if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) + elf_flags = elf_elfheader (info.abfd)->e_flags; + else + elf_flags = 0; + + abi = BFIN_ABI_FLAT; + + /* If there is already a candidate, use it. */ + + for (arches = gdbarch_list_lookup_by_info (arches, &info); + arches != NULL; + arches = gdbarch_list_lookup_by_info (arches->next, &info)) + { + if (gdbarch_tdep (arches->gdbarch)->bfin_abi != abi) + continue; + return arches->gdbarch; + } + + tdep = XMALLOC (struct gdbarch_tdep); + gdbarch = gdbarch_alloc (&info, tdep); + + tdep->bfin_abi = abi; + + set_gdbarch_num_regs (gdbarch, BFIN_NUM_REGS); + set_gdbarch_pseudo_register_read (gdbarch, bfin_pseudo_register_read); + set_gdbarch_pseudo_register_write (gdbarch, bfin_pseudo_register_write); + set_gdbarch_num_pseudo_regs (gdbarch, BFIN_NUM_PSEUDO_REGS); + set_gdbarch_sp_regnum (gdbarch, BFIN_SP_REGNUM); + set_gdbarch_pc_regnum (gdbarch, BFIN_PC_REGNUM); + set_gdbarch_ps_regnum (gdbarch, BFIN_ASTAT_REGNUM); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, bfin_reg_to_regnum); + set_gdbarch_register_name (gdbarch, bfin_register_name); + set_gdbarch_register_type (gdbarch, bfin_register_type); + set_gdbarch_dummy_id (gdbarch, bfin_dummy_id); + set_gdbarch_push_dummy_call (gdbarch, bfin_push_dummy_call); + set_gdbarch_believe_pcc_promotion (gdbarch, 1); + set_gdbarch_return_value (gdbarch, bfin_return_value); + set_gdbarch_skip_prologue (gdbarch, bfin_skip_prologue); + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + set_gdbarch_breakpoint_from_pc (gdbarch, bfin_breakpoint_from_pc); + set_gdbarch_decr_pc_after_break (gdbarch, 2); + set_gdbarch_frame_args_skip (gdbarch, 8); + set_gdbarch_unwind_pc (gdbarch, bfin_unwind_pc); + set_gdbarch_frame_align (gdbarch, bfin_frame_align); + set_gdbarch_print_insn (gdbarch, print_insn_bfin); + + /* Hook in ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + dwarf2_append_unwinders (gdbarch); + + frame_base_set_default (gdbarch, &bfin_frame_base); + + frame_unwind_append_unwinder (gdbarch, &bfin_frame_unwind); + + return gdbarch; +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_bfin_tdep; + +void +_initialize_bfin_tdep (void) +{ + register_gdbarch_init (bfd_arch_bfin, bfin_gdbarch_init); +} diff --git a/gdb/bfin-tdep.h b/gdb/bfin-tdep.h new file mode 100644 index 0000000..ecc46d2 --- /dev/null +++ b/gdb/bfin-tdep.h @@ -0,0 +1,102 @@ +/* Target-dependent code for Analog Devices Blackfin processor, for GDB. + + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + + Contributed by Analog Devices, 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/>. */ + +enum gdb_regnum { + /* Core Registers */ + BFIN_R0_REGNUM = 0, + BFIN_R1_REGNUM, + BFIN_R2_REGNUM, + BFIN_R3_REGNUM, + BFIN_R4_REGNUM, + BFIN_R5_REGNUM, + BFIN_R6_REGNUM, + BFIN_R7_REGNUM, + BFIN_P0_REGNUM, + BFIN_P1_REGNUM, + BFIN_P2_REGNUM, + BFIN_P3_REGNUM, + BFIN_P4_REGNUM, + BFIN_P5_REGNUM, + BFIN_SP_REGNUM, + BFIN_FP_REGNUM, + BFIN_I0_REGNUM, + BFIN_I1_REGNUM, + BFIN_I2_REGNUM, + BFIN_I3_REGNUM, + BFIN_M0_REGNUM, + BFIN_M1_REGNUM, + BFIN_M2_REGNUM, + BFIN_M3_REGNUM, + BFIN_B0_REGNUM, + BFIN_B1_REGNUM, + BFIN_B2_REGNUM, + BFIN_B3_REGNUM, + BFIN_L0_REGNUM, + BFIN_L1_REGNUM, + BFIN_L2_REGNUM, + BFIN_L3_REGNUM, + BFIN_A0_DOT_X_REGNUM, + BFIN_AO_DOT_W_REGNUM, + BFIN_A1_DOT_X_REGNUM, + BFIN_A1_DOT_W_REGNUM, + BFIN_ASTAT_REGNUM, + BFIN_RETS_REGNUM, + BFIN_LC0_REGNUM, + BFIN_LT0_REGNUM, + BFIN_LB0_REGNUM, + BFIN_LC1_REGNUM, + BFIN_LT1_REGNUM, + BFIN_LB1_REGNUM, + BFIN_CYCLES_REGNUM, + BFIN_CYCLES2_REGNUM, + BFIN_USP_REGNUM, + BFIN_SEQSTAT_REGNUM, + BFIN_SYSCFG_REGNUM, + BFIN_RETI_REGNUM, + BFIN_RETX_REGNUM, + BFIN_RETN_REGNUM, + BFIN_RETE_REGNUM, + + /* Pseudo Registers managed remotely. */ + BFIN_PC_REGNUM, + + /* Pseudo Registers managed locally. */ + BFIN_CC_REGNUM +}; +#define BFIN_NUM_REGS (BFIN_PC_REGNUM + 1) +#define BFIN_NUM_PSEUDO_REGS (1) + +/* The ABIs for Blackfin. */ +enum bfin_abi +{ + BFIN_ABI_FLAT +}; + +/* Target-dependent structure in gdbarch. */ +struct gdbarch_tdep +{ + /* Which ABI is in use? */ + enum bfin_abi bfin_abi; +}; + +/* Return the Blackfin ABI associated with GDBARCH. */ +extern enum bfin_abi bfin_abi (struct gdbarch *gdbarch); diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 161cbdc..ef9b783 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -106,6 +106,15 @@ avr-*-*) gdb_sim=../sim/avr/libsim.a ;; +bfin-*-*linux*) + # Target: Blackfin Linux + gdb_target_obs="bfin-tdep.o bfin-linux-tdep.o linux-tdep.o" + ;; +bfin-*-*) + # Target: Blackfin processor + gdb_target_obs="bfin-tdep.o" + ;; + cris*) # Target: CRIS gdb_target_obs="cris-tdep.o corelow.o solib.o solib-svr4.o" diff --git a/gdb/syscalls/bfin-linux.xml b/gdb/syscalls/bfin-linux.xml new file mode 100644 index 0000000..0fd3a96 --- /dev/null +++ b/gdb/syscalls/bfin-linux.xml @@ -0,0 +1,326 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2010 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. --> + +<!DOCTYPE feature SYSTEM "gdb-syscalls.dtd"> + +<!-- This file was generated using the following file: + + gawk '$2 ~ /^__NR_/ { gsub(/__NR_/,""); print " <syscall name=\"" $2 "\" number=\"" $3 "\"/>" }' + /usr/src/linux/arch/blackfin/include/asm/unistd.h + + The file mentioned above belongs to the Linux Kernel. --> + +<syscalls_info> + <syscall name="restart_syscall" number="0"/> + <syscall name="exit" number="1"/> + <syscall name="fork" number="2"/> + <syscall name="read" number="3"/> + <syscall name="write" number="4"/> + <syscall name="open" number="5"/> + <syscall name="close" number="6"/> + <syscall name="creat" number="8"/> + <syscall name="link" number="9"/> + <syscall name="unlink" number="10"/> + <syscall name="execve" number="11"/> + <syscall name="chdir" number="12"/> + <syscall name="time" number="13"/> + <syscall name="mknod" number="14"/> + <syscall name="chmod" number="15"/> + <syscall name="chown" number="16"/> + <syscall name="lseek" number="19"/> + <syscall name="getpid" number="20"/> + <syscall name="mount" number="21"/> + <syscall name="setuid" number="23"/> + <syscall name="getuid" number="24"/> + <syscall name="stime" number="25"/> + <syscall name="ptrace" number="26"/> + <syscall name="alarm" number="27"/> + <syscall name="pause" number="29"/> + <syscall name="access" number="33"/> + <syscall name="nice" number="34"/> + <syscall name="sync" number="36"/> + <syscall name="kill" number="37"/> + <syscall name="rename" number="38"/> + <syscall name="mkdir" number="39"/> + <syscall name="rmdir" number="40"/> + <syscall name="dup" number="41"/> + <syscall name="pipe" number="42"/> + <syscall name="times" number="43"/> + <syscall name="brk" number="45"/> + <syscall name="setgid" number="46"/> + <syscall name="getgid" number="47"/> + <syscall name="geteuid" number="49"/> + <syscall name="getegid" number="50"/> + <syscall name="acct" number="51"/> + <syscall name="umount2" number="52"/> + <syscall name="ioctl" number="54"/> + <syscall name="fcntl" number="55"/> + <syscall name="setpgid" number="57"/> + <syscall name="umask" number="60"/> + <syscall name="chroot" number="61"/> + <syscall name="ustat" number="62"/> + <syscall name="dup2" number="63"/> + <syscall name="getppid" number="64"/> + <syscall name="getpgrp" number="65"/> + <syscall name="setsid" number="66"/> + <syscall name="sgetmask" number="68"/> + <syscall name="ssetmask" number="69"/> + <syscall name="setreuid" number="70"/> + <syscall name="setregid" number="71"/> + <syscall name="sethostname" number="74"/> + <syscall name="setrlimit" number="75"/> + <syscall name="getrusage" number="77"/> + <syscall name="gettimeofday" number="78"/> + <syscall name="settimeofday" number="79"/> + <syscall name="getgroups" number="80"/> + <syscall name="setgroups" number="81"/> + <syscall name="symlink" number="83"/> + <syscall name="readlink" number="85"/> + <syscall name="reboot" number="88"/> + <syscall name="munmap" number="91"/> + <syscall name="truncate" number="92"/> + <syscall name="ftruncate" number="93"/> + <syscall name="fchmod" number="94"/> + <syscall name="fchown" number="95"/> + <syscall name="getpriority" number="96"/> + <syscall name="setpriority" number="97"/> + <syscall name="statfs" number="99"/> + <syscall name="fstatfs" number="100"/> + <syscall name="syslog" number="103"/> + <syscall name="setitimer" number="104"/> + <syscall name="getitimer" number="105"/> + <syscall name="stat" number="106"/> + <syscall name="lstat" number="107"/> + <syscall name="fstat" number="108"/> + <syscall name="vhangup" number="111"/> + <syscall name="wait4" number="114"/> + <syscall name="sysinfo" number="116"/> + <syscall name="fsync" number="118"/> + <syscall name="clone" number="120"/> + <syscall name="setdomainname" number="121"/> + <syscall name="uname" number="122"/> + <syscall name="adjtimex" number="124"/> + <syscall name="mprotect" number="125"/> + <syscall name="init_module" number="128"/> + <syscall name="delete_module" number="129"/> + <syscall name="quotactl" number="131"/> + <syscall name="getpgid" number="132"/> + <syscall name="fchdir" number="133"/> + <syscall name="bdflush" number="134"/> + <syscall name="personality" number="136"/> + <syscall name="setfsuid" number="138"/> + <syscall name="setfsgid" number="139"/> + <syscall name="_llseek" number="140"/> + <syscall name="getdents" number="141"/> + <syscall name="flock" number="143"/> + <syscall name="readv" number="145"/> + <syscall name="writev" number="146"/> + <syscall name="getsid" number="147"/> + <syscall name="fdatasync" number="148"/> + <syscall name="_sysctl" number="149"/> + <syscall name="sched_setparam" number="154"/> + <syscall name="sched_getparam" number="155"/> + <syscall name="sched_setscheduler" number="156"/> + <syscall name="sched_getscheduler" number="157"/> + <syscall name="sched_yield" number="158"/> + <syscall name="sched_get_priority_max" number="159"/> + <syscall name="sched_get_priority_min" number="160"/> + <syscall name="sched_rr_get_interval" number="161"/> + <syscall name="nanosleep" number="162"/> + <syscall name="mremap" number="163"/> + <syscall name="setresuid" number="164"/> + <syscall name="getresuid" number="165"/> + <syscall name="nfsservctl" number="169"/> + <syscall name="setresgid" number="170"/> + <syscall name="getresgid" number="171"/> + <syscall name="prctl" number="172"/> + <syscall name="rt_sigreturn" number="173"/> + <syscall name="rt_sigaction" number="174"/> + <syscall name="rt_sigprocmask" number="175"/> + <syscall name="rt_sigpending" number="176"/> + <syscall name="rt_sigtimedwait" number="177"/> + <syscall name="rt_sigqueueinfo" number="178"/> + <syscall name="rt_sigsuspend" number="179"/> + <syscall name="pread" number="180"/> + <syscall name="pwrite" number="181"/> + <syscall name="lchown" number="182"/> + <syscall name="getcwd" number="183"/> + <syscall name="capget" number="184"/> + <syscall name="capset" number="185"/> + <syscall name="sigaltstack" number="186"/> + <syscall name="sendfile" number="187"/> + <syscall name="vfork" number="190"/> + <syscall name="getrlimit" number="191"/> + <syscall name="mmap2" number="192"/> + <syscall name="truncate64" number="193"/> + <syscall name="ftruncate64" number="194"/> + <syscall name="stat64" number="195"/> + <syscall name="lstat64" number="196"/> + <syscall name="fstat64" number="197"/> + <syscall name="chown32" number="198"/> + <syscall name="getuid32" number="199"/> + <syscall name="getgid32" number="200"/> + <syscall name="geteuid32" number="201"/> + <syscall name="getegid32" number="202"/> + <syscall name="setreuid32" number="203"/> + <syscall name="setregid32" number="204"/> + <syscall name="getgroups32" number="205"/> + <syscall name="setgroups32" number="206"/> + <syscall name="fchown32" number="207"/> + <syscall name="setresuid32" number="208"/> + <syscall name="getresuid32" number="209"/> + <syscall name="setresgid32" number="210"/> + <syscall name="getresgid32" number="211"/> + <syscall name="lchown32" number="212"/> + <syscall name="setuid32" number="213"/> + <syscall name="setgid32" number="214"/> + <syscall name="setfsuid32" number="215"/> + <syscall name="setfsgid32" number="216"/> + <syscall name="pivot_root" number="217"/> + <syscall name="getdents64" number="220"/> + <syscall name="fcntl64" number="221"/> + <syscall name="gettid" number="224"/> + <syscall name="readahead" number="225"/> + <syscall name="setxattr" number="226"/> + <syscall name="lsetxattr" number="227"/> + <syscall name="fsetxattr" number="228"/> + <syscall name="getxattr" number="229"/> + <syscall name="lgetxattr" number="230"/> + <syscall name="fgetxattr" number="231"/> + <syscall name="listxattr" number="232"/> + <syscall name="llistxattr" number="233"/> + <syscall name="flistxattr" number="234"/> + <syscall name="removexattr" number="235"/> + <syscall name="lremovexattr" number="236"/> + <syscall name="fremovexattr" number="237"/> + <syscall name="tkill" number="238"/> + <syscall name="sendfile64" number="239"/> + <syscall name="futex" number="240"/> + <syscall name="sched_setaffinity" number="241"/> + <syscall name="sched_getaffinity" number="242"/> + <syscall name="io_setup" number="245"/> + <syscall name="io_destroy" number="246"/> + <syscall name="io_getevents" number="247"/> + <syscall name="io_submit" number="248"/> + <syscall name="io_cancel" number="249"/> + <syscall name="exit_group" number="252"/> + <syscall name="lookup_dcookie" number="253"/> + <syscall name="bfin_spinlock" number="254"/> + <syscall name="epoll_create" number="255"/> + <syscall name="epoll_ctl" number="256"/> + <syscall name="epoll_wait" number="257"/> + <syscall name="set_tid_address" number="259"/> + <syscall name="timer_create" number="260"/> + <syscall name="timer_settime" number="261"/> + <syscall name="timer_gettime" number="262"/> + <syscall name="timer_getoverrun" number="263"/> + <syscall name="timer_delete" number="264"/> + <syscall name="clock_settime" number="265"/> + <syscall name="clock_gettime" number="266"/> + <syscall name="clock_getres" number="267"/> + <syscall name="clock_nanosleep" number="268"/> + <syscall name="statfs64" number="269"/> + <syscall name="fstatfs64" number="270"/> + <syscall name="tgkill" number="271"/> + <syscall name="utimes" number="272"/> + <syscall name="fadvise64_64" number="273"/> + <syscall name="mq_open" number="278"/> + <syscall name="mq_unlink" number="279"/> + <syscall name="mq_timedsend" number="280"/> + <syscall name="mq_timedreceive" number="281"/> + <syscall name="mq_notify" number="282"/> + <syscall name="mq_getsetattr" number="283"/> + <syscall name="kexec_load" number="284"/> + <syscall name="waitid" number="285"/> + <syscall name="add_key" number="286"/> + <syscall name="request_key" number="287"/> + <syscall name="keyctl" number="288"/> + <syscall name="ioprio_set" number="289"/> + <syscall name="ioprio_get" number="290"/> + <syscall name="inotify_init" number="291"/> + <syscall name="inotify_add_watch" number="292"/> + <syscall name="inotify_rm_watch" number="293"/> + <syscall name="openat" number="295"/> + <syscall name="mkdirat" number="296"/> + <syscall name="mknodat" number="297"/> + <syscall name="fchownat" number="298"/> + <syscall name="futimesat" number="299"/> + <syscall name="fstatat64" number="300"/> + <syscall name="unlinkat" number="301"/> + <syscall name="renameat" number="302"/> + <syscall name="linkat" number="303"/> + <syscall name="symlinkat" number="304"/> + <syscall name="readlinkat" number="305"/> + <syscall name="fchmodat" number="306"/> + <syscall name="faccessat" number="307"/> + <syscall name="pselect6" number="308"/> + <syscall name="ppoll" number="309"/> + <syscall name="unshare" number="310"/> + <syscall name="sram_alloc" number="311"/> + <syscall name="sram_free" number="312"/> + <syscall name="dma_memcpy" number="313"/> + <syscall name="accept" number="314"/> + <syscall name="bind" number="315"/> + <syscall name="connect" number="316"/> + <syscall name="getpeername" number="317"/> + <syscall name="getsockname" number="318"/> + <syscall name="getsockopt" number="319"/> + <syscall name="listen" number="320"/> + <syscall name="recv" number="321"/> + <syscall name="recvfrom" number="322"/> + <syscall name="recvmsg" number="323"/> + <syscall name="send" number="324"/> + <syscall name="sendmsg" number="325"/> + <syscall name="sendto" number="326"/> + <syscall name="setsockopt" number="327"/> + <syscall name="shutdown" number="328"/> + <syscall name="socket" number="329"/> + <syscall name="socketpair" number="330"/> + <syscall name="semctl" number="331"/> + <syscall name="semget" number="332"/> + <syscall name="semop" number="333"/> + <syscall name="msgctl" number="334"/> + <syscall name="msgget" number="335"/> + <syscall name="msgrcv" number="336"/> + <syscall name="msgsnd" number="337"/> + <syscall name="shmat" number="338"/> + <syscall name="shmctl" number="339"/> + <syscall name="shmdt" number="340"/> + <syscall name="shmget" number="341"/> + <syscall name="splice" number="342"/> + <syscall name="sync_file_range" number="343"/> + <syscall name="tee" number="344"/> + <syscall name="vmsplice" number="345"/> + <syscall name="epoll_pwait" number="346"/> + <syscall name="utimensat" number="347"/> + <syscall name="signalfd" number="348"/> + <syscall name="timerfd_create" number="349"/> + <syscall name="eventfd" number="350"/> + <syscall name="pread64" number="351"/> + <syscall name="pwrite64" number="352"/> + <syscall name="fadvise64" number="353"/> + <syscall name="set_robust_list" number="354"/> + <syscall name="get_robust_list" number="355"/> + <syscall name="fallocate" number="356"/> + <syscall name="semtimedop" number="357"/> + <syscall name="timerfd_settime" number="358"/> + <syscall name="timerfd_gettime" number="359"/> + <syscall name="signalfd4" number="360"/> + <syscall name="eventfd2" number="361"/> + <syscall name="epoll_create1" number="362"/> + <syscall name="dup3" number="363"/> + <syscall name="pipe2" number="364"/> + <syscall name="inotify_init1" number="365"/> + <syscall name="preadv" number="366"/> + <syscall name="pwritev" number="367"/> + <syscall name="rt_tgsigqueueinfo" number="368"/> + <syscall name="perf_event_open" number="369"/> + <syscall name="recvmmsg" number="370"/> + <syscall name="fanotify_init" number="371"/> + <syscall name="fanotify_mark" number="372"/> + <syscall name="prlimit64" number="373"/> +</syscalls_info> |