From: Julian Seward Date: Thu, 7 Jun 2012 09:23:23 +0000 (+0000) Subject: Merge in a port for mips32-linux, by Petar Jovanovic and Dejan Jevtic, X-Git-Tag: svn/VALGRIND_3_8_0~251 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d971e9300ff91294b5f49dfa23a2ded625cb277b;p=thirdparty%2Fvalgrind.git Merge in a port for mips32-linux, by Petar Jovanovic and Dejan Jevtic, mips-valgrind@rt-rk.com, Bug 270777. Valgrind: new non-test files for mips32-linux. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12617 --- diff --git a/cachegrind/cg-mips32.c b/cachegrind/cg-mips32.c new file mode 100644 index 0000000000..5ad69c2e51 --- /dev/null +++ b/cachegrind/cg-mips32.c @@ -0,0 +1,59 @@ + +/*--------------------------------------------------------------------*/ +/*--- MIPS-specific definitions. cg-mips32.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Cachegrind, a Valgrind tool for cache + profiling programs. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#if defined(VGA_mips32) + +#include "pub_tool_basics.h" +#include "pub_tool_libcbase.h" +#include "pub_tool_libcassert.h" +#include "pub_tool_libcprint.h" + +#include "cg_arch.h" + +void VG_(configure_caches)(cache_t* I1c, cache_t* D1c, cache_t* L2c, + Bool all_caches_clo_defined) +{ + // Set caches to default (for MIPS32-r2(mips 74kc)) + *I1c = (cache_t) { 32768, 4, 32 }; + *D1c = (cache_t) { 32768, 4, 32 }; + *L2c = (cache_t) { 524288, 8, 32 }; + + if (!all_caches_clo_defined) { + VG_(message)(Vg_DebugMsg, + "Warning: Cannot auto-detect cache config on MIPS32, using one " + "or more defaults\n"); + } +} + +#endif // #if defined(VGA_mips32) + +/*--------------------------------------------------------------------*/ +/*--- end cg-mips32.c ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_dispatch/dispatch-mips32-linux.S b/coregrind/m_dispatch/dispatch-mips32-linux.S new file mode 100644 index 0000000000..4fcba08d99 --- /dev/null +++ b/coregrind/m_dispatch/dispatch-mips32-linux.S @@ -0,0 +1,249 @@ + +/*--------------------------------------------------------------------*/ +/*--- The core dispatch loop, for jumping to a code address. ---*/ +/*--- dispatch-mips-linux.S ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2000-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + + +#if defined(VGP_mips32_linux) + +#include "pub_core_basics_asm.h" +#include "pub_core_dispatch_asm.h" +#include "pub_core_transtab_asm.h" +#include "libvex_guest_offsets.h" /* for OFFSET_mips_PC */ + + +/*------------------------------------------------------------*/ +/*--- ---*/ +/*--- The dispatch loop. VG_(disp_run_translations) is ---*/ +/*--- used to run all translations, ---*/ +/*--- including no-redir ones. ---*/ +/*--- ---*/ +/*------------------------------------------------------------*/ + +/*----------------------------------------------------*/ +/*--- Entry and preamble (set everything up) ---*/ +/*----------------------------------------------------*/ + +/* signature: +void VG_(disp_run_translations)( UWord* two_words, + void* guest_state, + Addr host_addr ); +*/ + +.text +.globl VG_(disp_run_translations) +VG_(disp_run_translations): + /* a0 ($4) holds two_words */ + /* a1 ($5) holds guest_state */ + /* a2 ($6) holds host_addr */ + + /* New stack frame. Stack must remain 8 aligned (at least) */ + addiu $29, -56 + + /* Save ra */ + sw $31, 0($29) + + /* ... and orig guest state*/ + sw $5, 4($29) + + /* ... and s0 - s7 */ + sw $16, 8($29) + sw $17, 12($29) + sw $18, 16($29) + sw $19, 20($29) + sw $20, 24($29) + sw $21, 28($29) + sw $22, 32($29) + sw $23, 36($29) + + /* ... and gp, fp/s8 */ + sw $28, 40($29) + sw $30, 44($29) + + /* Save a0 ($4) on stack. In postamble it will be restored such that the + return values can be written */ + sw $4, 48($29) + + /* Load address of guest state into guest state register (r10) */ + move $10, $5 + + /* and jump into the code cache. Chained translations in + the code cache run, until for whatever reason, they can't + continue. When that happens, the translation in question + will jump (or call) to one of the continuation points + VG_(cp_...) below. */ + jr $6 + /*NOTREACHED*/ + +/*----------------------------------------------------*/ +/*--- Postamble and exit. ---*/ +/*----------------------------------------------------*/ + +postamble: + /* At this point, r2 and r3 contain two + words to be returned to the caller. r2 + holds a TRC value, and r3 optionally may + hold another word (for CHAIN_ME exits, the + address of the place to patch.) */ + + /* Restore $4 from stack; holds address of two_words */ + lw $4, 48($29) + sw $2, 0($4) /* Store $2 to two_words[0] */ + sw $3, 4($4) /* Store $3 to two_words[1] */ + + /* Restore callee-saved registers... */ + + /* Restore ra */ + lw $31, 0($29) + + /* ... and s0 - s7 */ + lw $16, 8($29) + lw $17, 12($29) + lw $18, 16($29) + lw $19, 20($29) + lw $20, 24($29) + lw $21, 28($29) + lw $22, 32($29) + lw $23, 36($29) + + /* ... and gp, fp/s8 */ + lw $28, 40($29) + lw $30, 44($29) + + + addiu $29, 56 /* stack_size */ + jr $31 + nop + +/*----------------------------------------------------*/ +/*--- Continuation points ---*/ +/*----------------------------------------------------*/ + +/* ------ Chain me to slow entry point ------ */ +.global VG_(disp_cp_chain_me_to_slowEP) +VG_(disp_cp_chain_me_to_slowEP): + /* We got called. The return address indicates + where the patching needs to happen. Collect + the return address and, exit back to C land, + handing the caller the pair (Chain_me_S, RA) */ + li $2, VG_TRC_CHAIN_ME_TO_SLOW_EP + move $3, $31 + /* 8 = mkLoadImm_EXACTLY2or5 + 4 = jalr $9 + 4 = nop */ + addiu $3, $3, -16 + b postamble + +/* ------ Chain me to slow entry point ------ */ +.global VG_(disp_cp_chain_me_to_fastEP) +VG_(disp_cp_chain_me_to_fastEP): + /* We got called. The return address indicates + where the patching needs to happen. Collect + the return address and, exit back to C land, + handing the caller the pair (Chain_me_S, RA) */ + li $2, VG_TRC_CHAIN_ME_TO_FAST_EP + move $3, $31 + /* 8 = mkLoadImm_EXACTLY2or5 + 4 = jalr $9 + 4 = nop */ + addiu $3, $3, -16 + b postamble + +/* ------ Indirect but boring jump ------ */ +.global VG_(disp_cp_xindir) +VG_(disp_cp_xindir): + /* Where are we going? */ + lw $11, OFFSET_mips32_PC($10) + + lw $13, vgPlain_stats__n_xindirs_32 + addiu $13, $13, 0x1 + sw $13, vgPlain_stats__n_xindirs_32 + + /* try a fast lookup in the translation cache */ + /* t1 = VG_TT_FAST_HASH(addr) * sizeof(ULong*) + = (t8 >> 2 & VG_TT_FAST_MASK) << 3 */ + + move $14, $11 + li $12, VG_TT_FAST_MASK + srl $14, $14, 2 + and $14, $14, $12 + sll $14, $14, 3 + + /* t2 = (addr of VG_(tt_fast)) + t1 */ + la $13, VG_(tt_fast) + addu $13, $13, $14 + + lw $12, 0($13) /* t3 = VG_(tt_fast)[hash] :: ULong* */ + addi $13, $13, 4 + lw $25, 0($13) /* little-endian, so comparing 1st 32bit word */ + nop + +check: + bne $12, $11, fast_lookup_failed + /* run the translation */ + jr $25 + .long 0x0 /* persuade insn decoders not to speculate past here */ + +fast_lookup_failed: + /* %PC is up to date */ + /* back out decrement of the dispatch counter */ + /* hold dispatch_ctr in t0 (r8) */ + lw $13, vgPlain_stats__n_xindirs_32 + addiu $13, $13, 0x1 + sw $13, vgPlain_stats__n_xindirs_32 + li $2, VG_TRC_INNER_FASTMISS + li $3, 0 + b postamble + +/* ------ Assisted jump ------ */ + .global VG_(disp_cp_xassisted) +VG_(disp_cp_xassisted): + /* guest-state-pointer contains the TRC. Put the value into the + return register */ + move $2, $10 + move $3, $0 + b postamble + +/* ------ Event check failed ------ */ + .global VG_(disp_cp_evcheck_fail) +VG_(disp_cp_evcheck_fail): + li $2, VG_TRC_INNER_COUNTERZERO + move $3, $0 + b postamble + +.size VG_(disp_run_translations), .-VG_(disp_run_translations) + + +/* Let the linker know we do not need an executable stack */ +.section .note.GNU-stack,"",@progbits + +#endif // defined(VGP_mips32_linux) +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_gdbserver/mips-cp0-valgrind-s1.xml b/coregrind/m_gdbserver/mips-cp0-valgrind-s1.xml new file mode 100644 index 0000000000..b7751947ad --- /dev/null +++ b/coregrind/m_gdbserver/mips-cp0-valgrind-s1.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-cp0-valgrind-s2.xml b/coregrind/m_gdbserver/mips-cp0-valgrind-s2.xml new file mode 100644 index 0000000000..fc57afa16b --- /dev/null +++ b/coregrind/m_gdbserver/mips-cp0-valgrind-s2.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-cp0.xml b/coregrind/m_gdbserver/mips-cp0.xml new file mode 100644 index 0000000000..2555b1d6d4 --- /dev/null +++ b/coregrind/m_gdbserver/mips-cp0.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-cpu-valgrind-s1.xml b/coregrind/m_gdbserver/mips-cpu-valgrind-s1.xml new file mode 100644 index 0000000000..3404b433fb --- /dev/null +++ b/coregrind/m_gdbserver/mips-cpu-valgrind-s1.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-cpu-valgrind-s2.xml b/coregrind/m_gdbserver/mips-cpu-valgrind-s2.xml new file mode 100644 index 0000000000..13b1640997 --- /dev/null +++ b/coregrind/m_gdbserver/mips-cpu-valgrind-s2.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-cpu.xml b/coregrind/m_gdbserver/mips-cpu.xml new file mode 100644 index 0000000000..62bfe035c9 --- /dev/null +++ b/coregrind/m_gdbserver/mips-cpu.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-fpu-valgrind-s1.xml b/coregrind/m_gdbserver/mips-fpu-valgrind-s1.xml new file mode 100644 index 0000000000..3c84e9d1ac --- /dev/null +++ b/coregrind/m_gdbserver/mips-fpu-valgrind-s1.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-fpu-valgrind-s2.xml b/coregrind/m_gdbserver/mips-fpu-valgrind-s2.xml new file mode 100644 index 0000000000..3a50143721 --- /dev/null +++ b/coregrind/m_gdbserver/mips-fpu-valgrind-s2.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-fpu.xml b/coregrind/m_gdbserver/mips-fpu.xml new file mode 100644 index 0000000000..fc371c6be8 --- /dev/null +++ b/coregrind/m_gdbserver/mips-fpu.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-linux-valgrind.xml b/coregrind/m_gdbserver/mips-linux-valgrind.xml new file mode 100644 index 0000000000..b18c623658 --- /dev/null +++ b/coregrind/m_gdbserver/mips-linux-valgrind.xml @@ -0,0 +1,25 @@ + + + + + + mips + GNU/Linux + + + + + + + + + + + + + + diff --git a/coregrind/m_gdbserver/mips-linux.xml b/coregrind/m_gdbserver/mips-linux.xml new file mode 100644 index 0000000000..73fb432a17 --- /dev/null +++ b/coregrind/m_gdbserver/mips-linux.xml @@ -0,0 +1,19 @@ + + + + + + mips + GNU/Linux + + + + + + + + diff --git a/coregrind/m_gdbserver/valgrind-low-mips32.c b/coregrind/m_gdbserver/valgrind-low-mips32.c new file mode 100644 index 0000000000..de7de88bd1 --- /dev/null +++ b/coregrind/m_gdbserver/valgrind-low-mips32.c @@ -0,0 +1,258 @@ +/* Low level interface to valgrind, for the remote server for GDB integrated + in valgrind. + Copyright (C) 2012 + Free Software Foundation, Inc. + + This file is part of VALGRIND. + It has been inspired from a file from gdbserver in gdb 6.6. + + 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#include "server.h" +#include "target.h" +#include "regdef.h" +#include "regcache.h" + +#include "pub_core_aspacemgr.h" +#include "pub_tool_machine.h" +#include "pub_core_threadstate.h" +#include "pub_core_transtab.h" +#include "pub_core_gdbserver.h" + +#include "valgrind_low.h" + +#include "libvex_guest_mips32.h" + +struct reg regs[] = { + { "r0", 0, 32 }, + { "r1", 32, 32 }, + { "r2", 64, 32 }, + { "r3", 96, 32 }, + { "r4", 128, 32 }, + { "r5", 160, 32 }, + { "r6", 192, 32 }, + { "r7", 224, 32 }, + { "r8", 256, 32 }, + { "r9", 288, 32 }, + { "r10", 320, 32 }, + { "r11", 352, 32 }, + { "r12", 384, 32 }, + { "r13", 416, 32 }, + { "r14", 448, 32 }, + { "r15", 480, 32 }, + { "r16", 512, 32 }, + { "r17", 544, 32 }, + { "r18", 576, 32 }, + { "r19", 608, 32 }, + { "r20", 640, 32 }, + { "r21", 672, 32 }, + { "r22", 704, 32 }, + { "r23", 736, 32 }, + { "r24", 768, 32 }, + { "r25", 800, 32 }, + { "r26", 832, 32 }, + { "r27", 864, 32 }, + { "r28", 896, 32 }, + { "r29", 928, 32 }, + { "r30", 960, 32 }, + { "r31", 992, 32 }, + { "status", 1024, 32 }, + { "lo", 1056, 32 }, + { "hi", 1088, 32 }, + { "badvaddr", 1120, 32 }, + { "cause", 1152, 32 }, + { "pc", 1184, 32 }, + { "f0", 1216, 32 }, + { "f1", 1248, 32 }, + { "f2", 1280, 32 }, + { "f3", 1312, 32 }, + { "f4", 1344, 32 }, + { "f5", 1376, 32 }, + { "f6", 1408, 32 }, + { "f7", 1440, 32 }, + { "f8", 1472, 32 }, + { "f9", 1504, 32 }, + { "f10", 1536, 32 }, + { "f11", 1568, 32 }, + { "f12", 1600, 32 }, + { "f13", 1632, 32 }, + { "f14", 1664, 32 }, + { "f15", 1696, 32 }, + { "f16", 1728, 32 }, + { "f17", 1760, 32 }, + { "f18", 1792, 32 }, + { "f19", 1824, 32 }, + { "f20", 1856, 32 }, + { "f21", 1888, 32 }, + { "f22", 1920, 32 }, + { "f23", 1952, 32 }, + { "f24", 1984, 32 }, + { "f25", 2016, 32 }, + { "f26", 2048, 32 }, + { "f27", 2080, 32 }, + { "f28", 2112, 32 }, + { "f29", 2144, 32 }, + { "f30", 2176, 32 }, + { "f31", 2208, 32 }, + { "fcsr", 2240, 32 }, + { "fir", 2272, 32 }, + { "restart", 2304, 32 }, +}; + +#define num_regs (sizeof (regs) / sizeof (regs[0])) + +static const char *expedite_regs[] = { "r29", "pc", 0 }; + +static +CORE_ADDR get_pc (void) +{ + unsigned long pc; + + collect_register_by_name ("pc", &pc); + + dlog(1, "stop pc is %p\n", (void *) pc); + return pc; +} + +static +void set_pc (CORE_ADDR newpc) +{ + Bool mod; + supply_register_by_name ("pc", &newpc, &mod); + if (mod) + dlog(1, "set pc to %p\n", C2v (newpc)); + else + dlog(1, "set pc not changed %p\n", C2v (newpc)); +} + +/* store registers in the guest state (gdbserver_to_valgrind) + or fetch register from the guest state (valgrind_to_gdbserver). */ +static +void transfer_register (ThreadId tid, int abs_regno, void * buf, + transfer_direction dir, int size, Bool *mod) +{ + ThreadState* tst = VG_(get_ThreadState)(tid); + int set = abs_regno / num_regs; + int regno = abs_regno % num_regs; + *mod = False; + + VexGuestMIPS32State* mips1 = (VexGuestMIPS32State*) get_arch (set, tst); + + switch (regno) { + case 0: VG_(transfer) (&mips1->guest_r0, buf, dir, size, mod); break; + case 1: VG_(transfer) (&mips1->guest_r1, buf, dir, size, mod); break; + case 2: VG_(transfer) (&mips1->guest_r2, buf, dir, size, mod); break; + case 3: VG_(transfer) (&mips1->guest_r3, buf, dir, size, mod); break; + case 4: VG_(transfer) (&mips1->guest_r4, buf, dir, size, mod); break; + case 5: VG_(transfer) (&mips1->guest_r5, buf, dir, size, mod); break; + case 6: VG_(transfer) (&mips1->guest_r6, buf, dir, size, mod); break; + case 7: VG_(transfer) (&mips1->guest_r7, buf, dir, size, mod); break; + case 8: VG_(transfer) (&mips1->guest_r8, buf, dir, size, mod); break; + case 9: VG_(transfer) (&mips1->guest_r9, buf, dir, size, mod); break; + case 10: VG_(transfer) (&mips1->guest_r10, buf, dir, size, mod); break; + case 11: VG_(transfer) (&mips1->guest_r11, buf, dir, size, mod); break; + case 12: VG_(transfer) (&mips1->guest_r12, buf, dir, size, mod); break; + case 13: VG_(transfer) (&mips1->guest_r13, buf, dir, size, mod); break; + case 14: VG_(transfer) (&mips1->guest_r14, buf, dir, size, mod); break; + case 15: VG_(transfer) (&mips1->guest_r15, buf, dir, size, mod); break; + case 16: VG_(transfer) (&mips1->guest_r16, buf, dir, size, mod); break; + case 17: VG_(transfer) (&mips1->guest_r17, buf, dir, size, mod); break; + case 18: VG_(transfer) (&mips1->guest_r18, buf, dir, size, mod); break; + case 19: VG_(transfer) (&mips1->guest_r19, buf, dir, size, mod); break; + case 20: VG_(transfer) (&mips1->guest_r20, buf, dir, size, mod); break; + case 21: VG_(transfer) (&mips1->guest_r21, buf, dir, size, mod); break; + case 22: VG_(transfer) (&mips1->guest_r22, buf, dir, size, mod); break; + case 23: VG_(transfer) (&mips1->guest_r23, buf, dir, size, mod); break; + case 24: VG_(transfer) (&mips1->guest_r24, buf, dir, size, mod); break; + case 25: VG_(transfer) (&mips1->guest_r25, buf, dir, size, mod); break; + case 26: VG_(transfer) (&mips1->guest_r26, buf, dir, size, mod); break; + case 27: VG_(transfer) (&mips1->guest_r27, buf, dir, size, mod); break; + case 28: VG_(transfer) (&mips1->guest_r28, buf, dir, size, mod); break; + case 29: VG_(transfer) (&mips1->guest_r29, buf, dir, size, mod); break; + case 30: VG_(transfer) (&mips1->guest_r30, buf, dir, size, mod); break; + case 31: VG_(transfer) (&mips1->guest_r31, buf, dir, size, mod); break; + case 32: *mod = False; break; // GDBTD???? VEX { "status", 1024, 32 }, + case 33: VG_(transfer) (&mips1->guest_LO, buf, dir, size, mod); break; + case 34: VG_(transfer) (&mips1->guest_HI, buf, dir, size, mod); break; + case 35: *mod = False; break; // GDBTD???? VEX { "badvaddr", 1120, 32 }, + case 36: *mod = False; break; // GDBTD???? VEX { "cause", 1152, 32 }, + case 37: VG_(transfer) (&mips1->guest_PC, buf, dir, size, mod); break; + case 38: VG_(transfer) (&mips1->guest_f0, buf, dir, size, mod); break; + case 39: VG_(transfer) (&mips1->guest_f1, buf, dir, size, mod); break; + case 40: VG_(transfer) (&mips1->guest_f2, buf, dir, size, mod); break; + case 41: VG_(transfer) (&mips1->guest_f3, buf, dir, size, mod); break; + case 42: VG_(transfer) (&mips1->guest_f4, buf, dir, size, mod); break; + case 43: VG_(transfer) (&mips1->guest_f5, buf, dir, size, mod); break; + case 44: VG_(transfer) (&mips1->guest_f6, buf, dir, size, mod); break; + case 45: VG_(transfer) (&mips1->guest_f7, buf, dir, size, mod); break; + case 46: VG_(transfer) (&mips1->guest_f8, buf, dir, size, mod); break; + case 47: VG_(transfer) (&mips1->guest_f9, buf, dir, size, mod); break; + case 48: VG_(transfer) (&mips1->guest_f10, buf, dir, size, mod); break; + case 49: VG_(transfer) (&mips1->guest_f11, buf, dir, size, mod); break; + case 50: VG_(transfer) (&mips1->guest_f12, buf, dir, size, mod); break; + case 51: VG_(transfer) (&mips1->guest_f13, buf, dir, size, mod); break; + case 52: VG_(transfer) (&mips1->guest_f14, buf, dir, size, mod); break; + case 53: VG_(transfer) (&mips1->guest_f15, buf, dir, size, mod); break; + case 54: VG_(transfer) (&mips1->guest_f16, buf, dir, size, mod); break; + case 55: VG_(transfer) (&mips1->guest_f17, buf, dir, size, mod); break; + case 56: VG_(transfer) (&mips1->guest_f18, buf, dir, size, mod); break; + case 57: VG_(transfer) (&mips1->guest_f19, buf, dir, size, mod); break; + case 58: VG_(transfer) (&mips1->guest_f20, buf, dir, size, mod); break; + case 59: VG_(transfer) (&mips1->guest_f21, buf, dir, size, mod); break; + case 60: VG_(transfer) (&mips1->guest_f22, buf, dir, size, mod); break; + case 61: VG_(transfer) (&mips1->guest_f23, buf, dir, size, mod); break; + case 62: VG_(transfer) (&mips1->guest_f24, buf, dir, size, mod); break; + case 63: VG_(transfer) (&mips1->guest_f25, buf, dir, size, mod); break; + case 64: VG_(transfer) (&mips1->guest_f26, buf, dir, size, mod); break; + case 65: VG_(transfer) (&mips1->guest_f27, buf, dir, size, mod); break; + case 66: VG_(transfer) (&mips1->guest_f28, buf, dir, size, mod); break; + case 67: VG_(transfer) (&mips1->guest_f29, buf, dir, size, mod); break; + case 68: VG_(transfer) (&mips1->guest_f30, buf, dir, size, mod); break; + case 69: VG_(transfer) (&mips1->guest_f31, buf, dir, size, mod); break; + case 70: VG_(transfer) (&mips1->guest_FCSR, buf, dir, size, mod); break; + case 71: VG_(transfer) (&mips1->guest_FIR, buf, dir, size, mod); break; + case 72: *mod = False; break; // GDBTD???? VEX{ "restart", 2304, 32 }, + default: VG_(printf)("regno: %d\n", regno); vg_assert(0); + } +} + +static +char* target_xml (Bool shadow_mode) +{ + if (shadow_mode) { + return "mips-linux-valgrind.xml"; + } else { + return "mips-linux.xml"; + } +} + +static struct valgrind_target_ops low_target = { + num_regs, + regs, + 29, //sp = r29, which is register offset 29 in regs + transfer_register, + get_pc, + set_pc, + "mips", + target_xml +}; + +void mips32_init_architecture (struct valgrind_target_ops *target) +{ + *target = low_target; + set_register_cache (regs, num_regs); + gdbserver_expedite_regs = expedite_regs; +} diff --git a/coregrind/m_sigframe/sigframe-mips32-linux.c b/coregrind/m_sigframe/sigframe-mips32-linux.c new file mode 100644 index 0000000000..c711a6a455 --- /dev/null +++ b/coregrind/m_sigframe/sigframe-mips32-linux.c @@ -0,0 +1,398 @@ + +/*--------------------------------------------------------------------*/ +/*--- Create/destroy signal delivery frames. ---*/ +/*--- sigframe-mips32-linux.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#if defined(VGP_mips32_linux) + +#include "pub_core_basics.h" +#include "pub_core_vki.h" +#include "pub_core_vkiscnums.h" +#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy +#include "pub_core_threadstate.h" +#include "pub_core_aspacemgr.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcprint.h" +#include "pub_core_machine.h" +#include "pub_core_options.h" +#include "pub_core_sigframe.h" +#include "pub_core_signals.h" +#include "pub_core_tooliface.h" +#include "pub_core_trampoline.h" +#include "pub_core_transtab.h" // VG_(discard_translations) + +struct vg_sig_private +{ + UInt magicPI; + UInt sigNo_private; + VexGuestMIPS32State vex_shadow1; + VexGuestMIPS32State vex_shadow2; +}; + +struct sigframe +{ + UInt sf_ass[4]; /* argument save space for o32 */ + UInt sf_pad[2]; /* Was: signal trampoline */ + struct vki_sigcontext sf_sc; + vki_sigset_t sf_mask; + struct vg_sig_private priv; +}; + +struct rt_sigframe +{ + UInt rs_ass[4]; /* argument save space for o32 */ + UInt rs_pad[2]; /* Was: signal trampoline */ + vki_siginfo_t rs_info; + struct vki_ucontext rs_uc; + struct vg_sig_private priv; +}; + +/* Extend the stack segment downwards if needed so as to ensure the + new signal frames are mapped to something. Return a Bool + indicating whether or not the operation was successful. +*/ +static Bool extend ( ThreadState *tst, Addr addr, SizeT size ) +{ + ThreadId tid = tst->tid; + NSegment const* stackseg = NULL; + + if (VG_(extend_stack)(addr, tst->client_stack_szB)) + { + stackseg = VG_(am_find_nsegment)(addr); + } + + if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) + { + VG_(message)(Vg_UserMsg, + "Can't extend stack to %#lx during signal delivery for thread %d:\n", + addr, tid ); + if (stackseg == NULL) + VG_(message)( Vg_UserMsg, " no stack segment\n" ); + else + VG_(message)( Vg_UserMsg, " too small or bad protection modes\n" ); + + /* set SIGSEGV to default handler */ + VG_(set_default_handler)( VKI_SIGSEGV ); + VG_(synth_fault_mapping)( tid, addr ); + + /* The whole process should be about to die, since the default + action of SIGSEGV to kill the whole process. */ + return False; + } + + /* For tracking memory events, indicate the entire frame has been + allocated. */ + VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, + size + VG_STACK_REDZONE_SZB, tid ); + + return True; +} + +static +void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1, const vki_siginfo_t *si) +{ + + struct vki_sigcontext *sc = *sc1; + + VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext", + (Addr)sc, sizeof(unsigned long long)*34 ); + sc->sc_regs[1] = tst->arch.vex.guest_r1; + sc->sc_regs[2] = tst->arch.vex.guest_r2; + sc->sc_regs[3] = tst->arch.vex.guest_r3; + sc->sc_regs[4] = tst->arch.vex.guest_r4; + sc->sc_regs[5] = tst->arch.vex.guest_r5; + sc->sc_regs[6] = tst->arch.vex.guest_r6; + sc->sc_regs[7] = tst->arch.vex.guest_r7; + sc->sc_regs[8] = tst->arch.vex.guest_r8; + sc->sc_regs[9] = tst->arch.vex.guest_r9; + sc->sc_regs[10] = tst->arch.vex.guest_r10; + sc->sc_regs[11] = tst->arch.vex.guest_r11; + sc->sc_regs[12] = tst->arch.vex.guest_r12; + sc->sc_regs[13] = tst->arch.vex.guest_r13; + sc->sc_regs[14] = tst->arch.vex.guest_r14; + sc->sc_regs[15] = tst->arch.vex.guest_r15; + sc->sc_regs[16] = tst->arch.vex.guest_r16; + sc->sc_regs[17] = tst->arch.vex.guest_r17; + sc->sc_regs[18] = tst->arch.vex.guest_r18; + sc->sc_regs[19] = tst->arch.vex.guest_r19; + sc->sc_regs[20] = tst->arch.vex.guest_r20; + sc->sc_regs[21] = tst->arch.vex.guest_r21; + sc->sc_regs[22] = tst->arch.vex.guest_r22; + sc->sc_regs[23] = tst->arch.vex.guest_r23; + sc->sc_regs[24] = tst->arch.vex.guest_r24; + sc->sc_regs[25] = tst->arch.vex.guest_r25; + sc->sc_regs[26] = tst->arch.vex.guest_r26; + sc->sc_regs[27] = tst->arch.vex.guest_r27; + sc->sc_regs[28] = tst->arch.vex.guest_r28; + sc->sc_regs[29] = tst->arch.vex.guest_r29; + sc->sc_regs[30] = tst->arch.vex.guest_r30; + sc->sc_regs[31] = tst->arch.vex.guest_r31; + sc->sc_pc = tst->arch.vex.guest_PC; + sc->sc_mdhi = tst->arch.vex.guest_HI; + sc->sc_mdlo = tst->arch.vex.guest_LO; +} + +/* EXPORTED */ +void VG_(sigframe_create)( ThreadId tid, + Addr sp_top_of_frame, + const vki_siginfo_t *siginfo, + const struct vki_ucontext *siguc, + void *handler, + UInt flags, + const vki_sigset_t *mask, + void *restorer ) +{ + Addr sp; + ThreadState* tst = VG_(get_ThreadState)(tid); + Addr faultaddr; + Int sigNo = siginfo->si_signo; + struct vg_sig_private *priv; + + /* Stack must be 8-byte aligned */ + sp_top_of_frame &= ~0xf; + + if (flags & VKI_SA_SIGINFO) + { + sp = sp_top_of_frame - sizeof(struct rt_sigframe); + } + else + { + sp = sp_top_of_frame - sizeof(struct sigframe); + } + + tst = VG_(get_ThreadState)(tid); + if (!extend(tst, sp, sp_top_of_frame - sp)) + return; + + vg_assert(VG_IS_8_ALIGNED(sp)); + + /* SIGILL defines addr to be the faulting address */ + + faultaddr = (Addr)siginfo->_sifields._sigfault._addr; + if (sigNo == VKI_SIGILL && siginfo->si_code > 0) + faultaddr = tst->arch.vex.guest_PC; + + if (flags & VKI_SA_SIGINFO) + { + struct rt_sigframe *frame = (struct rt_sigframe *) sp; + struct vki_ucontext *ucp = &frame->rs_uc; + if (VG_(clo_trace_signals)) + VG_(printf)("rt_sigframe\n"); + /* Create siginfo. */ + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo", + (Addr)&frame->rs_info, sizeof(frame->rs_info) ); + + VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo)); + + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, + (Addr)&frame->rs_info, sizeof(frame->rs_info) ); + + /* Create the ucontext. */ + VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext", + (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) ); + + ucp->uc_flags = 0; + ucp->uc_link = 0; + ucp->uc_stack = tst->altstack; + + VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp, + offsetof(struct vki_ucontext, uc_mcontext) ); + + struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext); + setup_sigcontext2(tst, &(scp), siginfo); + + ucp->uc_sigmask = tst->sig_mask; + + priv = &frame->priv; + + /* + * Arguments to signal handler: + * + * a0 = signal number + * a1 = 0 (should be cause) + * a2 = pointer to ucontext + * + * $25 and c0_epc point to the signal handler, $29 points to + * the struct rt_sigframe. + */ + + tst->arch.vex.guest_r4 = siginfo->si_signo; + tst->arch.vex.guest_r5 = (Addr) &frame->rs_info; + tst->arch.vex.guest_r6 = (Addr) &frame->rs_uc; + tst->arch.vex.guest_r29 = (Addr) frame; + tst->arch.vex.guest_r25 = (Addr) handler; + + if (flags & VKI_SA_RESTORER) + { + tst->arch.vex.guest_r31 = (Addr) restorer; + } + else + { + tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_rt_sigreturn); + } + + } + else + { + if (VG_(clo_trace_signals)) + VG_(printf)("sigframe\n"); + struct sigframe *frame = (struct sigframe *) sp; + struct vki_sigcontext *scp = &(frame->sf_sc); + setup_sigcontext2(tst, &(scp), siginfo); + frame->sf_mask = tst->sig_mask; + priv = &frame->priv; + /* + * Arguments to signal handler: + * + * a0 = signal number + * a1 = 0 (should be cause) + * a2 = pointer to struct sigcontext + * + * $25 and c0_epc point to the signal handler, $29 points to the + * struct sigframe. + */ + tst->arch.vex.guest_r4 = siginfo->si_signo; + tst->arch.vex.guest_r5 = 0; + tst->arch.vex.guest_r6 = (Addr) &frame->sf_sc; + tst->arch.vex.guest_r29 = (Addr) frame; + tst->arch.vex.guest_r25 = (Addr) handler; + + if (flags & VKI_SA_RESTORER) + { + tst->arch.vex.guest_r31 = (Addr) restorer; + } + else + { + tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_sigreturn); + } + } + + priv->magicPI = 0x31415927; + priv->sigNo_private = sigNo; + priv->vex_shadow1 = tst->arch.vex_shadow1; + priv->vex_shadow2 = tst->arch.vex_shadow2; + /* Set the thread so it will next run the handler. */ + /* tst->m_sp = sp; also notify the tool we've updated SP */ + VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); + if (VG_(clo_trace_signals)) + VG_(printf)("handler = %p\n", handler); + tst->arch.vex.guest_PC = (Addr) handler; + /* This thread needs to be marked runnable, but we leave that the + caller to do. */ +} + +/* EXPORTED */ +void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) +{ + ThreadState *tst; + struct vg_sig_private *priv1; + Addr sp; + UInt frame_size; + struct vki_sigcontext *mc; + Int sigNo; + Bool has_siginfo = isRT; + + vg_assert(VG_(is_valid_tid)(tid)); + tst = VG_(get_ThreadState)(tid); + sp = tst->arch.vex.guest_r29; + if (has_siginfo) + { + struct rt_sigframe *frame = (struct rt_sigframe *)sp; + struct vki_ucontext *ucp = &frame->rs_uc; + frame_size = sizeof(*frame); + mc = &ucp->uc_mcontext; + priv1 = &frame->priv; + vg_assert(priv1->magicPI == 0x31415927); + sigNo = priv1->sigNo_private; + } + else + { + struct sigframe *frame = (struct sigframe *)sp; + frame_size = sizeof(*frame); + mc = &(frame->sf_sc); + priv1 = &frame->priv; + vg_assert(priv1->magicPI == 0x31415927); + tst->sig_mask = frame->sf_mask; + tst->tmp_sig_mask = tst->sig_mask; + sigNo = priv1->sigNo_private; + } + //restore regs + tst->arch.vex.guest_r1 = mc->sc_regs[1]; + tst->arch.vex.guest_r2 = mc->sc_regs[2]; + tst->arch.vex.guest_r3 = mc->sc_regs[3]; + tst->arch.vex.guest_r4 = mc->sc_regs[4]; + tst->arch.vex.guest_r5 = mc->sc_regs[5]; + tst->arch.vex.guest_r6 = mc->sc_regs[6]; + tst->arch.vex.guest_r7 = mc->sc_regs[7]; + tst->arch.vex.guest_r8 = mc->sc_regs[8]; + tst->arch.vex.guest_r9 = mc->sc_regs[9]; + tst->arch.vex.guest_r10 = mc->sc_regs[10]; + tst->arch.vex.guest_r11 = mc->sc_regs[11]; + tst->arch.vex.guest_r12 = mc->sc_regs[12]; + tst->arch.vex.guest_r13= mc->sc_regs[13]; + tst->arch.vex.guest_r14 = mc->sc_regs[14]; + tst->arch.vex.guest_r15 = mc->sc_regs[15]; + tst->arch.vex.guest_r16 = mc->sc_regs[16]; + tst->arch.vex.guest_r17 = mc->sc_regs[17]; + tst->arch.vex.guest_r18 = mc->sc_regs[18]; + tst->arch.vex.guest_r19 = mc->sc_regs[19]; + tst->arch.vex.guest_r20 = mc->sc_regs[20]; + tst->arch.vex.guest_r21 = mc->sc_regs[21]; + tst->arch.vex.guest_r22 = mc->sc_regs[22]; + tst->arch.vex.guest_r23 = mc->sc_regs[23]; + tst->arch.vex.guest_r24 = mc->sc_regs[24]; + tst->arch.vex.guest_r25 = mc->sc_regs[25]; + tst->arch.vex.guest_r26 = mc->sc_regs[26]; + tst->arch.vex.guest_r27 = mc->sc_regs[27]; + tst->arch.vex.guest_r28 = mc->sc_regs[28]; + tst->arch.vex.guest_r30 = mc->sc_regs[30]; + tst->arch.vex.guest_PC = mc->sc_pc; + tst->arch.vex.guest_r31 = mc->sc_regs[31]; + tst->arch.vex.guest_r29 = mc->sc_regs[29]; + + tst->arch.vex.guest_HI = mc->sc_mdhi; + tst->arch.vex.guest_LO = mc->sc_mdlo; + tst->arch.vex_shadow1 = priv1->vex_shadow1; + tst->arch.vex_shadow2 = priv1->vex_shadow2; + + VG_TRACK(die_mem_stack_signal, sp, frame_size); + if (VG_(clo_trace_signals)) + VG_(message)( Vg_DebugMsg, + "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n", + tid, isRT, tst->arch.vex.guest_PC); + /* tell the tools */ + VG_TRACK( post_deliver_signal, tid, sigNo ); +} + +#endif // defined(VGP_mips32_linux) + +/*--------------------------------------------------------------------*/ +/*--- end sigframe-mips32-linux.c ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_syswrap/syscall-mips32-linux.S b/coregrind/m_syswrap/syscall-mips32-linux.S new file mode 100644 index 0000000000..6a550aa74f --- /dev/null +++ b/coregrind/m_syswrap/syscall-mips32-linux.S @@ -0,0 +1,215 @@ + +/*--------------------------------------------------------------------*/ +/*--- Support for doing system calls. syscall-mips32-linux.S ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#if defined(VGP_mips32_linux) + +#include "pub_core_basics_asm.h" +#include "pub_core_vkiscnums_asm.h" +#include "libvex_guest_offsets.h" + + +/*----------------------------------------------------------------*/ +/* + Perform a syscall for the client. This will run a syscall + with the client's specific per-thread signal mask. + + The structure of this function is such that, if the syscall is + interrupted by a signal, we can determine exactly what + execution state we were in with respect to the execution of + the syscall by examining the value of IP in the signal + handler. This means that we can always do the appropriate + thing to precisely emulate the kernel's signal/syscall + interactions. + + The syscall number is taken from the argument, even though it + should also be in regs->v0. The syscall result is written + back to regs->v0 on completion. + + Returns 0 if the syscall was successfully called (even if the + syscall itself failed), or a nonzero error code in the lowest + 8 bits if one of the sigprocmasks failed (there's no way to + determine which one failed). And there's no obvious way to + recover from that either, but nevertheless we want to know. + + VG_(fixup_guest_state_after_syscall_interrupted) does the + thread state fixup in the case where we were interrupted by a + signal. + + Prototype: + + UWord ML_(do_syscall_for_client_WRK)( + Int syscallno, // $4 - a0 + void* guest_state, // $5 - a1 + const vki_sigset_t *sysmask, // $6 - a2 + const vki_sigset_t *postmask, // $7 - a3 + Int nsigwords) // stack +*/ +/* from vki_arch.h */ +#define VKI_SIG_SETMASK 3 + +.globl ML_(do_syscall_for_client_WRK) +ML_(do_syscall_for_client_WRK): + + subu $29, $29, 56 #set up the steck frame, + sw $4, 52($29) + sw $5, 48($29) + sw $6, 44($29) + sw $7, 40($29) + sw $31, 36($29) + sw $30, 32($29) + sw $16, 28($29) + sw $17, 24($29) + sw $18, 20($29) + sw $19, 16($29) + sw $20, 12($29) + sw $21, 8($29) + sw $22, 4($29) + sw $23, 0($29) + addu $30, $29, 56 + + + /* Set the signal mask which should be current during the syscall. */ + +1: li $2, __NR_rt_sigprocmask + li $4, VKI_SIG_SETMASK + move $5, $6 /* sysmask */ + move $6, $7 /* postmask */ + lw $7, 72($29) /* nsigwords */ + syscall + nop + +# TODO: this should remain, keep it just for now + bnez $7, 7f + nop + + lw $8, 48($29) /* t0 == ThreadState */ + + lw $2, 52($29) /* v0 == syscallno */ + lw $4, OFFSET_mips32_r4($8) + lw $5, OFFSET_mips32_r5($8) + lw $6, OFFSET_mips32_r6($8) + lw $7, OFFSET_mips32_r7($8) + subu $29, $29, 24 #set up the steck frame, + lw $9, OFFSET_mips32_r29($8) + lw $10, 16($9) + sw $10, 16($29) + lw $10, 20($9) + sw $10, 20($29) + +2: syscall + +3: addu $29, $29, 24 #set up the steck frame, + + lw $8, 48($29) /* t0 == ThreadState */ + sw $2, OFFSET_mips32_r2($8) + sw $3, OFFSET_mips32_r3($8) + sw $7, OFFSET_mips32_r7($8) + +4: li $2, __NR_rt_sigprocmask + li $4, VKI_SIG_SETMASK + lw $5, 40($29) + li $6, 0 + lw $7, 72($29) /* nsigwords */ + syscall + nop + + bnez $7, 7f + nop + + /* Success */ + li $2, 0 + +5: lw $4, 52($29) + lw $5, 48($29) + lw $6, 44($29) + lw $7, 40($29) + lw $31, 36($29) + lw $30, 32($29) + lw $16, 28($29) + lw $17, 24($29) + lw $18, 20($29) + lw $19, 16($29) + lw $20, 12($29) + lw $21, 8($29) + lw $22, 4($29) + lw $23, 0($29) + addu $29, $29, 56 #release the stack frame. + + jr $31 + nop + +7: /* Failure: return 0x8000 | error code */ + li $2, 0x8000 + + lw $4, 52($29) + lw $5, 48($29) + lw $6, 44($29) + lw $7, 40($29) + lw $31, 36($29) + lw $30, 32($29) + lw $16, 28($29) + lw $17, 24($29) + lw $18, 20($29) + lw $19, 16($29) + lw $20, 12($29) + lw $21, 8($29) + lw $22, 4($29) + lw $23, 0($29) + addu $29, $29, 56 #release the stack frame. + + jr $31 + nop + +.section .rodata +/* export the ranges so that + VG_(fixup_guest_state_after_syscall_interrupted) can do the + right thing */ + +.globl ML_(blksys_setup) +.globl ML_(blksys_restart) +.globl ML_(blksys_complete) +.globl ML_(blksys_committed) +.globl ML_(blksys_finished) +ML_(blksys_setup): .long 1b +ML_(blksys_restart): .long 2b +ML_(blksys_complete): .long 3b +ML_(blksys_committed): .long 4b +ML_(blksys_finished): .long 5b +.previous +/* Let the linker know we don't need an executable stack */ +.section .note.GNU-stack,"",%progbits + + + +#endif // defined(VGP_mips32_linux) + +/*--------------------------------------------------------------------*/ +/*--- end ---*/ +/*--------------------------------------------------------------------*/ diff --git a/coregrind/m_syswrap/syswrap-mips32-linux.c b/coregrind/m_syswrap/syswrap-mips32-linux.c new file mode 100644 index 0000000000..804066a962 --- /dev/null +++ b/coregrind/m_syswrap/syswrap-mips32-linux.c @@ -0,0 +1,1759 @@ + +/*--------------------------------------------------------------------*/ +/*--- Platform-specific syscalls stuff. syswrap-mips32-linux.c ----*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#if defined(VGP_mips32_linux) +#include "pub_core_basics.h" +#include "pub_core_vki.h" +#include "pub_core_vkiscnums.h" +#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy +#include "pub_core_threadstate.h" +#include "pub_core_aspacemgr.h" +#include "pub_core_debuglog.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcprint.h" +#include "pub_core_libcproc.h" +#include "pub_core_libcsignal.h" +#include "pub_core_options.h" +#include "pub_core_scheduler.h" +#include "pub_core_sigframe.h" // For VG_(sigframe_destroy)() +#include "pub_core_signals.h" +#include "pub_core_syscall.h" +#include "pub_core_syswrap.h" +#include "pub_core_tooliface.h" +#include "pub_core_stacks.h" // VG_(register_stack) +#include "pub_core_transtab.h" // VG_(discard_translations) +#include "priv_types_n_macros.h" +#include "priv_syswrap-generic.h" /* for decls of generic wrappers */ +#include "priv_syswrap-linux.h" /* for decls of linux-ish wrappers */ +#include "priv_syswrap-main.h" + +#include "pub_core_debuginfo.h" // VG_(di_notify_*) +#include "pub_core_xarray.h" +#include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit) +#include "pub_core_errormgr.h" +#include "pub_tool_gdbserver.h" // VG_(gdbserver) +#include "pub_core_libcfile.h" +#include "pub_core_machine.h" // VG_(get_SP) +#include "pub_core_mallocfree.h" +#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)() +#include "pub_core_ume.h" + +#include "priv_syswrap-generic.h" + +#include "config.h" + +#include + +/* --------------------------------------------------------------------- + clone() handling + ------------------------------------------------------------------ */ +/* Call f(arg1), but first switch stacks, using 'stack' as the new + stack, and use 'retaddr' as f's return-to address. Also, clear all + the integer registers before entering f.*/ + +__attribute__ ((noreturn)) +void ML_ (call_on_new_stack_0_1) (Addr stack, Addr retaddr, + void (*f) (Word), Word arg1); +// a0 = stack +// a1 = retaddr +// a2 = f +// a3 = arg1 +asm ( +".text\n" +".globl vgModuleLocal_call_on_new_stack_0_1\n" +"vgModuleLocal_call_on_new_stack_0_1:\n" +" move $29, $4\n\t" // stack to %sp +" move $25, $6\n\t" // f to t9/$25 +" move $4, $7\n\t" // arg1 to $a0 +" li $2, 0\n\t" // zero all GP regs +" li $3, 0\n\t" +" li $5, 0\n\t" +" li $6, 0\n\t" +" li $7, 0\n\t" + +" li $12, 0\n\t" +" li $13, 0\n\t" +" li $14, 0\n\t" +" li $15, 0\n\t" +" li $16, 0\n\t" +" li $17, 0\n\t" +" li $18, 0\n\t" +" li $19, 0\n\t" +" li $20, 0\n\t" +" li $21, 0\n\t" +" li $22, 0\n\t" +" li $23, 0\n\t" +" li $24, 0\n\t" +" jr $25\n\t" // jump to dst +" break 0x7\n" // should never get here +".previous\n" +); + +/* + Perform a clone system call. clone is strange because it has + fork()-like return-twice semantics, so it needs special + handling here. + Upon entry, we have: + int (fn)(void*) in $a0 0 + void* child_stack in $a1 4 + int flags in $a2 8 + void* arg in $a3 12 + pid_t* child_tid in stack 16 + pid_t* parent_tid in stack 20 + void* tls_ptr in stack 24 + + System call requires: + int $__NR_clone in $v0 + int flags in $a0 0 + void* child_stack in $a1 4 + pid_t* parent_tid in $a2 8 + void* tls_ptr in $a3 12 + pid_t* child_tid in stack 16 + + int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + void *parent_tidptr, void *tls, void *child_tidptr) + + Returns an Int encoded in the linux-mips way, not a SysRes. + */ +#define __NR_CLONE VG_STRINGIFY(__NR_clone) +#define __NR_EXIT VG_STRINGIFY(__NR_exit) + +//extern +UInt do_syscall_clone_mips_linux (Word (*fn) (void *), //a0 0 32 + void *stack, //a1 4 36 + Int flags, //a2 8 40 + void *arg, //a3 12 44 + Int * child_tid, //stack 16 48 + Int * parent_tid, //stack 20 52 + Int tls); //stack 24 56 +asm ( +".text\n" +" .globl do_syscall_clone_mips_linux\n" +" do_syscall_clone_mips_linux:\n" +" subu $29,$29,32\n\t" +" sw $31, 0($29)\n\t" +" sw $2, 4($29)\n\t" +" sw $3, 8($29)\n\t" +" sw $30, 12($29)\n\t" +" sw $28, 28($29)\n\t" + /* set up child stack with function and arg */ + /* syscall arg 2 child_stack is already in a1 */ +" subu $5, $5, 32\n\t" /* make space on stack */ +" sw $4, 0($5)\n\t" /* fn */ +" sw $7, 4($5)\n\t" /* fn arg */ +" sw $6, 8($5)\n\t" + /* get other args to clone */ + +" move $4, $a2\n\t" /* a0 = flags */ +" lw $6, 52($29)\n\t" /* a2 = parent_tid */ +" lw $7, 48($29)\n\t" /* a3 = child_tid */ +" sw $7, 16($29)\n\t" /* 16(sp) = child_tid */ +" lw $7, 56($29)\n\t" /* a3 = tls_ptr */ + /* do the system call */ + +" li $2, " __NR_CLONE "\n\t" /* __NR_clone */ +" syscall\n\t" +" nop\n\t" + +" bnez $7, .Lerror\n\t" +" nop\n\t" +" beqz $2, .Lstart\n\t" +" nop\n\t" + +" lw $31, 0($sp)\n\t" +" nop\n\t" +" lw $30, 12($sp)\n\t" +" nop\n\t" +" addu $29,$29,32\n\t" /* free stack */ +" nop\n\t" +" jr $31\n\t" +" nop\n\t" + +".Lerror:\n\t" +" li $31, 5\n\t" +" jr $31\n\t" +" nop\n\t" + +".Lstart:\n\t" +" lw $4, 4($29)\n\t" +" nop\n\t" +" lw $25, 0($29)\n\t" +" nop\n\t" +" jalr $25\n\t" +" nop\n\t" + +" move $4, $2\n\t" /* retval from fn is in $v0 */ +" li $2, " __NR_EXIT "\n\t" /* NR_exit */ +" syscall\n\t" +" nop\n\t" +" .previous\n" +); + +#undef __NR_CLONE +#undef __NR_EXIT + +// forward declarations + +static void setup_child (ThreadArchState *, ThreadArchState *); +static SysRes sys_set_tls (ThreadId tid, Addr tlsptr); +/* + When a client clones, we need to keep track of the new thread. This means: + 1. allocate a ThreadId+ThreadState+stack for the the thread + 2. initialize the thread's new VCPU state + 3. create the thread using the same args as the client requested, + but using the scheduler entrypoint for IP, and a separate stack + for SP. + */ + +static SysRes do_clone (ThreadId ptid, + UInt flags, Addr sp, + Int * parent_tidptr, + Int * child_tidptr, + Addr child_tls) +{ + const Bool debug = False; + ThreadId ctid = VG_ (alloc_ThreadState) (); + ThreadState * ptst = VG_ (get_ThreadState) (ptid); + ThreadState * ctst = VG_ (get_ThreadState) (ctid); + UInt ret = 0; + UWord * stack; + NSegment const *seg; + SysRes res; + vki_sigset_t blockall, savedmask; + + VG_ (sigfillset) (&blockall); + vg_assert (VG_ (is_running_thread) (ptid)); + vg_assert (VG_ (is_valid_tid) (ctid)); + stack = (UWord *) ML_ (allocstack) (ctid); + if (stack == NULL) { + res = VG_ (mk_SysRes_Error) (VKI_ENOMEM); + goto out; + } + setup_child (&ctst->arch, &ptst->arch); + + /* on MIPS we need to set V0 and A3 to zero */ + ctst->arch.vex.guest_r2 = 0; + ctst->arch.vex.guest_r7 = 0; + if (sp != 0) + ctst->arch.vex.guest_r29 = sp; + + ctst->os_state.parent = ptid; + ctst->sig_mask = ptst->sig_mask; + ctst->tmp_sig_mask = ptst->sig_mask; + + /* Start the child with its threadgroup being the same as the + parent's. This is so that any exit_group calls that happen + after the child is created but before it sets its + os_state.threadgroup field for real (in thread_wrapper in + syswrap-linux.c), really kill the new thread. a.k.a this avoids + a race condition in which the thread is unkillable (via + exit_group) because its threadgroup is not set. The race window + is probably only a few hundred or a few thousand cycles long. + See #226116. */ + + ctst->os_state.threadgroup = ptst->os_state.threadgroup; + seg = VG_ (am_find_nsegment) ((Addr) sp); + + if (seg && seg->kind != SkResvn) { + ctst->client_stack_highest_word = (Addr) VG_PGROUNDUP (sp); + ctst->client_stack_szB = ctst->client_stack_highest_word - seg->start; + VG_ (register_stack) (seg->start, ctst->client_stack_highest_word); + if (debug) + VG_ (printf) ("tid %d: guessed client stack range %#lx-%#lx\n", + + ctid, seg->start, VG_PGROUNDUP (sp)); + } else { + VG_ (message) (Vg_UserMsg, + "!? New thread %d starts with sp+%#lx) unmapped\n", + ctid, sp); + ctst->client_stack_szB = 0; + } + + VG_TRACK (pre_thread_ll_create, ptid, ctid); + if (flags & VKI_CLONE_SETTLS) { + if (debug) + VG_(printf)("clone child has SETTLS: tls at %#lx\n", child_tls); + ctst->arch.vex.guest_r27 = child_tls; + res = sys_set_tls(ctid, child_tls); + if (sr_isError(res)) + goto out; + ctst->arch.vex.guest_r27 = child_tls; + } + + flags &= ~VKI_CLONE_SETTLS; + VG_ (sigprocmask) (VKI_SIG_SETMASK, &blockall, &savedmask); + /* Create the new thread */ + ret = do_syscall_clone_mips_linux (ML_ (start_thread_NORETURN), + stack, flags, &VG_ (threads)[ctid], + child_tidptr, parent_tidptr, + 0 /*child_tls*/); + + /* High half word64 is syscall return value. Low half is + the entire CR, from which we need to extract CR0.SO. */ + if (debug) + VG_(printf)("ret: 0x%x\n", ret); + + res = VG_ (mk_SysRes_mips32_linux) (/*val */ ret, 0, /*errflag */ 0); + + VG_ (sigprocmask) (VKI_SIG_SETMASK, &savedmask, NULL); + + out: + if (sr_isError (res)) { + VG_(cleanup_thread) (&ctst->arch); + ctst->status = VgTs_Empty; + VG_TRACK (pre_thread_ll_exit, ctid); + } + ptst->arch.vex.guest_r2 = 0; + + return res; +} + +/* --------------------------------------------------------------------- + More thread stuff + ------------------------------------------------------------------ */ + +// MIPS doesn't have any architecture specific thread stuff that +// needs to be cleaned up da li ????!!!!??? +void +VG_ (cleanup_thread) (ThreadArchState * arch) { } + +void +setup_child ( /*OUT*/ ThreadArchState * child, + /*IN*/ ThreadArchState * parent) +{ + /* We inherit our parent's guest state. */ + child->vex = parent->vex; + child->vex_shadow1 = parent->vex_shadow1; + child->vex_shadow2 = parent->vex_shadow2; +} + +SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ) +{ + VG_(threads)[tid].arch.vex.guest_ULR = tlsptr; + return VG_(mk_SysRes_Success)( 0 ); +} + +/* --------------------------------------------------------------------- + PRE/POST wrappers for mips/Linux-specific syscalls + ------------------------------------------------------------------ */ +#define PRE(name) DEFN_PRE_TEMPLATE(mips_linux, name) +#define POST(name) DEFN_POST_TEMPLATE(mips_linux, name) + +/* Add prototypes for the wrappers declared here, so that gcc doesn't + harass us for not having prototypes. Really this is a kludge -- + the right thing to do is to make these wrappers 'static' since they + aren't visible outside this file, but that requires even more macro + magic. */ +//DECL_TEMPLATE (mips_linux, sys_syscall); +DECL_TEMPLATE (mips_linux, sys_socketcall); +DECL_TEMPLATE (mips_linux, sys_socket); +DECL_TEMPLATE (mips_linux, sys_setsockopt); +DECL_TEMPLATE (mips_linux, sys_getsockopt); +DECL_TEMPLATE (mips_linux, sys_connect); +DECL_TEMPLATE (mips_linux, sys_accept); +DECL_TEMPLATE (mips_linux, sys_sendto); +DECL_TEMPLATE (mips_linux, sys_recvfrom); +DECL_TEMPLATE (mips_linux, sys_ipc); +DECL_TEMPLATE (mips_linux, sys_semget); +DECL_TEMPLATE (mips_linux, sys_semop); +DECL_TEMPLATE (mips_linux, sys_semctl); +DECL_TEMPLATE (mips_linux, sys_semtimedop); +DECL_TEMPLATE (mips_linux, wrap_sys_shmat); +DECL_TEMPLATE (mips_linux, sys_shmget); +DECL_TEMPLATE (mips_linux, sys_shmdt); +DECL_TEMPLATE (mips_linux, sys_shmctl); +DECL_TEMPLATE (mips_linux, sys_sendmsg); +DECL_TEMPLATE (mips_linux, sys_recvmsg); +DECL_TEMPLATE (mips_linux, sys_msgget); +DECL_TEMPLATE (mips_linux, sys_msgrcv); +DECL_TEMPLATE (mips_linux, sys_msgsnd); +DECL_TEMPLATE (mips_linux, sys_msgctl); +DECL_TEMPLATE (mips_linux, sys_shutdown); +DECL_TEMPLATE (mips_linux, sys_bind); +DECL_TEMPLATE (mips_linux, sys_listen); +DECL_TEMPLATE (mips_linux, sys_getsockname); +DECL_TEMPLATE (mips_linux, sys_getpeername); +DECL_TEMPLATE (mips_linux, sys_socketpair); +DECL_TEMPLATE (mips_linux, sys_send); +DECL_TEMPLATE (mips_linux, sys_recv); +DECL_TEMPLATE (mips_linux, sys_mmap); +DECL_TEMPLATE (mips_linux, sys_mmap2); +DECL_TEMPLATE (mips_linux, sys_stat64); +DECL_TEMPLATE (mips_linux, sys_lstat64); +DECL_TEMPLATE (mips_linux, sys_fstatat64); +DECL_TEMPLATE (mips_linux, sys_fstat64); +DECL_TEMPLATE (mips_linux, sys_clone); +DECL_TEMPLATE (mips_linux, sys_sigreturn); +DECL_TEMPLATE (mips_linux, sys_rt_sigreturn); +DECL_TEMPLATE (mips_linux, sys_cacheflush); +DECL_TEMPLATE (mips_linux, sys_set_thread_area); + +PRE (sys_socketcall) +{ +# define ARG2_0 (((UWord*)ARG2)[0]) +# define ARG2_1 (((UWord*)ARG2)[1]) +# define ARG2_2 (((UWord*)ARG2)[2]) +# define ARG2_3 (((UWord*)ARG2)[3]) +# define ARG2_4 (((UWord*)ARG2)[4]) +# define ARG2_5 (((UWord*)ARG2)[5]) + *flags |= SfMayBlock; + PRINT ("sys_socketcall ( %ld, %#lx )", ARG1, ARG2); + PRE_REG_READ2 (long, "socketcall", int, call, unsigned long *, args); + switch (ARG1 /* request */ ) + { + case VKI_SYS_SOCKETPAIR: + /* int socketpair(int d, int type, int protocol, int sv[2]); */ + PRE_MEM_READ ("socketcall.socketpair(args)", ARG2, + 4 * sizeof (Addr)); + ML_ (generic_PRE_sys_socketpair) (tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3); + break; + case VKI_SYS_SOCKET: + /* int socket(int domain, int type, int protocol); */ + PRE_MEM_READ ("socketcall.socket(args)", ARG2, 3 * sizeof (Addr)); + break; + case VKI_SYS_BIND: + /* int bind(int sockfd, struct sockaddr *my_addr, + int addrlen); */ + PRE_MEM_READ ("socketcall.bind(args)", ARG2, 3 * sizeof (Addr)); + ML_ (generic_PRE_sys_bind) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_LISTEN: + /* int listen(int s, int backlog); */ + PRE_MEM_READ ("socketcall.listen(args)", ARG2, 2 * sizeof (Addr)); + break; + case VKI_SYS_ACCEPT: + { + /* int accept(int s, struct sockaddr *addr, int *addrlen); */ + PRE_MEM_READ ("socketcall.accept(args)", ARG2, 3 * sizeof (Addr)); + ML_ (generic_PRE_sys_accept) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + } + case VKI_SYS_SENDTO: + /* int sendto(int s, const void *msg, int len, + unsigned int flags, + const struct sockaddr *to, int tolen); */ + PRE_MEM_READ ("socketcall.sendto(args)", ARG2, 6 * sizeof (Addr)); + ML_ (generic_PRE_sys_sendto) (tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3, + ARG2_4, ARG2_5); + break; + case VKI_SYS_SEND: + /* int send(int s, const void *msg, size_t len, int flags); */ + PRE_MEM_READ ("socketcall.send(args)", ARG2, 4 * sizeof (Addr)); + ML_ (generic_PRE_sys_send) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_RECVFROM: + /* int recvfrom(int s, void *buf, int len, unsigned int flags, + struct sockaddr *from, int *fromlen); */ + PRE_MEM_READ ("socketcall.recvfrom(args)", ARG2, 6 * sizeof (Addr)); + ML_ (generic_PRE_sys_recvfrom) (tid, ARG2_0, ARG2_1, ARG2_2, + ARG2_3, ARG2_4, ARG2_5); + break; + case VKI_SYS_RECV: + /* int recv(int s, void *buf, int len, unsigned int flags); */ + /* man 2 recv says: + The recv call is normally used only on a connected socket + (see connect(2)) and is identical to recvfrom with a NULL + from parameter. + */ + PRE_MEM_READ ("socketcall.recv(args)", ARG2, 4 * sizeof (Addr)); + ML_ (generic_PRE_sys_recv) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_CONNECT: + /* int connect(int sockfd, + struct sockaddr *serv_addr, int addrlen ); */ + PRE_MEM_READ ("socketcall.connect(args)", ARG2, 3 * sizeof (Addr)); + ML_ (generic_PRE_sys_connect) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_SETSOCKOPT: + /* int setsockopt(int s, int level, int optname, + const void *optval, int optlen); */ + PRE_MEM_READ ("socketcall.setsockopt(args)", ARG2, 5 * sizeof (Addr)); + ML_ (generic_PRE_sys_setsockopt) (tid, ARG2_0, ARG2_1, ARG2_2, + ARG2_3, ARG2_4); + break; + case VKI_SYS_GETSOCKOPT: + /* int getsockopt(int s, int level, int optname, + void *optval, socklen_t *optlen); */ + PRE_MEM_READ ("socketcall.getsockopt(args)", ARG2, 5 * sizeof (Addr)); + ML_ (linux_PRE_sys_getsockopt) (tid, ARG2_0, ARG2_1, ARG2_2, ARG2_3, ARG2_4); + break; + case VKI_SYS_GETSOCKNAME: + /* int getsockname(int s, struct sockaddr* name, int* namelen) */ + PRE_MEM_READ ("socketcall.getsockname(args)", ARG2, 3 * sizeof (Addr)); + ML_ (generic_PRE_sys_getsockname) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_GETPEERNAME: + /* int getpeername(int s, struct sockaddr* name, int* namelen) */ + PRE_MEM_READ ("socketcall.getpeername(args)", ARG2, 3 * sizeof (Addr)); + ML_ (generic_PRE_sys_getpeername) (tid, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_SHUTDOWN: + /* int shutdown(int s, int how); */ + PRE_MEM_READ ("socketcall.shutdown(args)", ARG2, 2 * sizeof (Addr)); + break; + case VKI_SYS_SENDMSG: + { + /* int sendmsg(int s, const struct msghdr *msg, int flags); */ + /* this causes warnings, and I don't get why. glibc bug? + * (after all it's glibc providing the arguments array) + PRE_MEM_READ( "socketcall.sendmsg(args)", ARG2, 3*sizeof(Addr) ); + */ + ML_ (generic_PRE_sys_sendmsg) (tid, (UChar *)ARG2_0, (struct vki_msghdr *)ARG2_1); + break; + } + case VKI_SYS_RECVMSG: + { + /* int recvmsg(int s, struct msghdr *msg, int flags); */ + /* this causes warnings, and I don't get why. glibc bug? + * (after all it's glibc providing the arguments array) + PRE_MEM_READ("socketcall.recvmsg(args)", ARG2, 3*sizeof(Addr) ); + */ + ML_ (generic_PRE_sys_recvmsg) (tid, (UChar *)ARG2_0, + (struct vki_msghdr *)ARG2_1); + break; + } + default: + VG_ (message) (Vg_DebugMsg, "Warning: unhandled socketcall 0x%lx", ARG1); + SET_STATUS_Failure (VKI_EINVAL); + break; + } +# undef ARG2_0 +# undef ARG2_1 +# undef ARG2_2 +# undef ARG2_3 +# undef ARG2_4 +# undef ARG2_5 +} + +POST (sys_socketcall) +{ +# define ARG2_0 (((UWord*)ARG2)[0]) +# define ARG2_1 (((UWord*)ARG2)[1]) +# define ARG2_2 (((UWord*)ARG2)[2]) +# define ARG2_3 (((UWord*)ARG2)[3]) +# define ARG2_4 (((UWord*)ARG2)[4]) +# define ARG2_5 (((UWord*)ARG2)[5]) + SysRes r; + vg_assert (SUCCESS); + switch (ARG1 /* request */ ) + { + case VKI_SYS_SOCKETPAIR: + r = ML_ (generic_POST_sys_socketpair) ( tid, + VG_ (mk_SysRes_Success) (RES), + ARG2_0, ARG2_1, ARG2_2, ARG2_3); + SET_STATUS_from_SysRes (r); + break; + case VKI_SYS_SOCKET: + r = ML_ (generic_POST_sys_socket) (tid, VG_ (mk_SysRes_Success) (RES)); + SET_STATUS_from_SysRes (r); + break; + case VKI_SYS_BIND: + /* int bind(int sockfd, struct sockaddr *my_addr, int addrlen); */ + break; + case VKI_SYS_LISTEN: + /* int listen(int s, int backlog); */ + break; + case VKI_SYS_ACCEPT: + /* int accept(int s, struct sockaddr *addr, int *addrlen); */ + r = ML_ (generic_POST_sys_accept) (tid, VG_ (mk_SysRes_Success) (RES), + ARG2_0, ARG2_1, ARG2_2); + SET_STATUS_from_SysRes (r); + break; + case VKI_SYS_SENDTO: + break; + case VKI_SYS_SEND: + break; + case VKI_SYS_RECVFROM: + ML_ (generic_POST_sys_recvfrom) (tid, VG_ (mk_SysRes_Success) (RES), + ARG2_0, ARG2_1, ARG2_2, ARG2_3, + ARG2_4, ARG2_5); + break; + case VKI_SYS_RECV: + ML_ (generic_POST_sys_recv) (tid, RES, ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_CONNECT: + break; + case VKI_SYS_SETSOCKOPT: + break; + case VKI_SYS_GETSOCKOPT: + ML_ (linux_POST_sys_getsockopt) (tid, VG_ (mk_SysRes_Success) (RES), + ARG2_0, ARG2_1, ARG2_2, + ARG2_3, ARG2_4); + break; + case VKI_SYS_GETSOCKNAME: + ML_ (generic_POST_sys_getsockname) (tid, VG_ (mk_SysRes_Success) (RES), + ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_GETPEERNAME: + ML_ (generic_POST_sys_getpeername) (tid, VG_ (mk_SysRes_Success) (RES), + ARG2_0, ARG2_1, ARG2_2); + break; + case VKI_SYS_SHUTDOWN: + break; + case VKI_SYS_SENDMSG: + break; + case VKI_SYS_RECVMSG: + ML_(generic_PRE_sys_recvmsg)( tid, "msg", (struct vki_msghdr *)ARG2_1 ); + break; + default: + VG_ (message) (Vg_DebugMsg, "FATAL: unhandled socketcall 0x%lx", ARG1); + VG_ (core_panic) ("... bye!\n"); + break; + /*NOTREACHED*/ + } +# undef ARG2_0 +# undef ARG2_1 +# undef ARG2_2 +# undef ARG2_3 +# undef ARG2_4 +# undef ARG2_5 +} + +PRE (sys_socket) +{ + PRINT ("sys_socket ( %ld, %ld, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "socket", int, domain, int, type, int, protocol); +} + +POST (sys_socket) +{ + SysRes r; + vg_assert (SUCCESS); + r = ML_ (generic_POST_sys_socket) (tid, VG_ (mk_SysRes_Success) (RES)); + SET_STATUS_from_SysRes (r); +} + +PRE (sys_setsockopt) +{ + PRINT ("sys_setsockopt ( %ld, %ld, %ld, %#lx, %ld )", ARG1, ARG2, ARG3, + ARG4, ARG5); + PRE_REG_READ5 (long, "setsockopt", int, s, int, level, int, optname, + const void *, optval, int, optlen); + ML_ (generic_PRE_sys_setsockopt) (tid, ARG1, ARG2, ARG3, ARG4, ARG5); +} + +PRE (sys_getsockopt) +{ + PRINT ("sys_getsockopt ( %ld, %ld, %ld, %#lx, %#lx )", ARG1, ARG2, ARG3, + ARG4, ARG5); + PRE_REG_READ5 (long, "getsockopt", int, s, int, level, int, optname, + void *, optval, int, *optlen); + ML_ (linux_PRE_sys_getsockopt) (tid, ARG1, ARG2, ARG3, ARG4, ARG5); +} + +POST (sys_getsockopt) +{ + vg_assert (SUCCESS); + ML_ (linux_POST_sys_getsockopt) (tid, VG_ (mk_SysRes_Success) (RES), + ARG1, ARG2, ARG3, ARG4, ARG5); +} + +PRE(sys_connect) +{ + *flags |= SfMayBlock; + PRINT("sys_connect ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); + PRE_REG_READ3(long, "connect", + int, sockfd, struct sockaddr *, serv_addr, int, addrlen); + ML_(generic_PRE_sys_connect)(tid, ARG1,ARG2,ARG3); +} + +PRE (sys_accept) +{ + *flags |= SfMayBlock; + PRINT ("sys_accept ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "accept", int, s, struct sockaddr *, addr, int, + *addrlen); + ML_ (generic_PRE_sys_accept) (tid, ARG1, ARG2, ARG3); +} + +POST (sys_accept) +{ + SysRes r; + vg_assert (SUCCESS); + r = + ML_ (generic_POST_sys_accept) (tid, VG_ (mk_SysRes_Success) (RES), + ARG1, ARG2, ARG3); + SET_STATUS_from_SysRes (r); +} + +PRE (sys_sendto) +{ + *flags |= SfMayBlock; + PRINT ("sys_sendto ( %ld, %#lx, %ld, %lu, %#lx, %ld )", ARG1, ARG2, ARG3, + ARG4, ARG5, ARG6); + PRE_REG_READ6 (long, "sendto", int, s, const void *, msg, int, len, + unsigned int, flags, const struct sockaddr *, to, int, + tolen); + ML_ (generic_PRE_sys_sendto) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); +} + +PRE (sys_recvfrom) +{ + *flags |= SfMayBlock; + PRINT ("sys_recvfrom ( %ld, %#lx, %ld, %lu, %#lx, %#lx )", ARG1, ARG2, + ARG3, ARG4, ARG5, ARG6); + PRE_REG_READ6 (long, "recvfrom", int, s, void *, buf, int, len, + unsigned int, flags, + struct sockaddr *, from, int *, fromlen); + ML_ (generic_PRE_sys_recvfrom) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); +} + +POST (sys_recvfrom) +{ + vg_assert (SUCCESS); + ML_ (generic_POST_sys_recvfrom) (tid, VG_ (mk_SysRes_Success) (RES), + ARG1, ARG2, ARG3, ARG4, ARG5, ARG6); +} + +PRE(sys_sendmsg) +{ + *flags |= SfMayBlock; + PRINT("sys_sendmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); + PRE_REG_READ3(long, "sendmsg", + int, s, const struct msghdr *, msg, int, flags); + ML_(generic_PRE_sys_sendmsg)(tid, "msg", (struct vki_msghdr *)ARG2); +} + +PRE(sys_recvmsg) +{ + *flags |= SfMayBlock; + PRINT("sys_recvmsg ( %ld, %#lx, %ld )",ARG1,ARG2,ARG3); + PRE_REG_READ3(long, "recvmsg", int, s, struct msghdr *, msg, int, flags); + ML_(generic_PRE_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2); +} +POST(sys_recvmsg) +{ + ML_(generic_POST_sys_recvmsg)(tid, "msg", (struct vki_msghdr *)ARG2, RES); +} + +PRE (sys_semget) +{ + PRINT ("sys_semget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "semget", vki_key_t, key, int, nsems, int, semflg); +} + +PRE (sys_semop) +{ + *flags |= SfMayBlock; + PRINT ("sys_semop ( %ld, %#lx, %lu )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "semop", int, semid, struct sembuf *, sops, + unsigned, nsoops); + ML_ (generic_PRE_sys_semop) (tid, ARG1, ARG2, ARG3); +} + +PRE (sys_semctl) +{ + switch (ARG3 & ~VKI_IPC_64) + { + case VKI_IPC_INFO: + case VKI_SEM_INFO: + PRINT ("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "semctl", + int, semid, int, semnum, int, cmd, + struct seminfo *, arg); + break; + case VKI_IPC_STAT: + case VKI_SEM_STAT: + case VKI_IPC_SET: + PRINT ("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "semctl", int, semid, int, semnum, int, cmd, + struct semid_ds *, arg); + break; + case VKI_GETALL: + case VKI_SETALL: + PRINT ("sys_semctl ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "semctl", int, semid, int, semnum, int, cmd, + unsigned short *, arg); + break; + default: + PRINT ("sys_semctl ( %ld, %ld, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "semctl", int, semid, int, semnum, int, cmd); + break; + } + ML_ (generic_PRE_sys_semctl) (tid, ARG1, ARG2, ARG3, ARG4); +} + +POST (sys_semctl) +{ + ML_ (generic_POST_sys_semctl) (tid, RES, ARG1, ARG2, ARG3, ARG4); +} + +PRE (sys_semtimedop) +{ + *flags |= SfMayBlock; + PRINT ("sys_semtimedop ( %ld, %#lx, %lu, %#lx )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "semtimedop", int, semid, struct sembuf *, sops, + unsigned, nsoops, + struct timespec *, timeout); + ML_ (generic_PRE_sys_semtimedop) (tid, ARG1, ARG2, ARG3, ARG4); +} + +PRE (sys_msgget) +{ + PRINT ("sys_msgget ( %ld, %ld )", ARG1, ARG2); + PRE_REG_READ2 (long, "msgget", vki_key_t, key, int, msgflg); +} + +PRE (sys_msgsnd) +{ + PRINT ("sys_msgsnd ( %ld, %#lx, %ld, %ld )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "msgsnd", int, msqid, struct msgbuf *, msgp, + vki_size_t, msgsz, int, msgflg); + ML_ (linux_PRE_sys_msgsnd) (tid, ARG1, ARG2, ARG3, ARG4); + if ((ARG4 & VKI_IPC_NOWAIT) == 0) + *flags |= SfMayBlock; +} + +PRE (sys_msgrcv) +{ + PRINT ("sys_msgrcv ( %ld, %#lx, %ld, %ld, %ld )", ARG1, ARG2, ARG3, ARG4, + ARG5); + PRE_REG_READ5 (long, "msgrcv", int, msqid, struct msgbuf *, msgp, + vki_size_t, msgsz, long, msgytp, int, msgflg); + ML_ (linux_PRE_sys_msgrcv) (tid, ARG1, ARG2, ARG3, ARG4, ARG5); + if ((ARG4 & VKI_IPC_NOWAIT) == 0) + *flags |= SfMayBlock; +} + +POST (sys_msgrcv) +{ + ML_ (linux_POST_sys_msgrcv) (tid, RES, ARG1, ARG2, ARG3, ARG4, ARG5); +} + +PRE (sys_msgctl) +{ + PRINT ("sys_msgctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "msgctl", int, msqid, int, cmd, struct msqid_ds *, buf); + ML_ (linux_PRE_sys_msgctl) (tid, ARG1, ARG2, ARG3); +} + +POST (sys_msgctl) +{ + ML_ (linux_POST_sys_msgctl) (tid, RES, ARG1, ARG2, ARG3); +} + +PRE (sys_shmget) +{ + PRINT ("sys_shmget ( %ld, %ld, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "shmget", vki_key_t, key, vki_size_t, size, int, + shmflg); +} + +PRE (wrap_sys_shmat) +{ + UWord arg2tmp; + PRINT ("wrap_sys_shmat ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "shmat", int, shmid, const void *, shmaddr, int, + shmflg); + arg2tmp = ML_ (generic_PRE_sys_shmat) (tid, ARG1, ARG2, ARG3); + if (arg2tmp == 0) + SET_STATUS_Failure (VKI_EINVAL); + else + ARG2 = arg2tmp; +} + +POST (wrap_sys_shmat) +{ + ML_ (generic_POST_sys_shmat) (tid, RES, ARG1, ARG2, ARG3); +} + +PRE (sys_shmdt) +{ + PRINT ("sys_shmdt ( %#lx )", ARG1); + PRE_REG_READ1 (long, "shmdt", const void *, shmaddr); + if (!ML_ (generic_PRE_sys_shmdt) (tid, ARG1)) + SET_STATUS_Failure (VKI_EINVAL); +} + +POST (sys_shmdt) + +{ + ML_ (generic_POST_sys_shmdt) (tid, RES, ARG1); +} + +PRE (sys_shmctl) +{ + PRINT ("sys_shmctl ( %ld, %ld, %#lx )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "shmctl", int, shmid, int, cmd, struct shmid_ds *, buf); + ML_ (generic_PRE_sys_shmctl) (tid, ARG1, ARG2, ARG3); +} + +POST (sys_shmctl) +{ + ML_ (generic_POST_sys_shmctl) (tid, RES, ARG1, ARG2, ARG3); +} + +PRE (sys_shutdown) +{ + *flags |= SfMayBlock; + PRINT ("sys_shutdown ( %ld, %ld )", ARG1, ARG2); + PRE_REG_READ2 (int, "shutdown", int, s, int, how); +} + +PRE (sys_bind) +{ + PRINT ("sys_bind ( %ld, %#lx, %ld )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "bind", int, sockfd, struct sockaddr *, my_addr, + int, addrlen); + ML_ (generic_PRE_sys_bind) (tid, ARG1, ARG2, ARG3); +} + +PRE (sys_listen) +{ + PRINT ("sys_listen ( %ld, %ld )", ARG1, ARG2); + PRE_REG_READ2 (long, "listen", int, s, int, backlog); +} + +PRE (sys_getsockname) +{ + PRINT ("sys_getsockname ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "getsockname", int, s, struct sockaddr *, name, + int *, namelen); + ML_ (generic_PRE_sys_getsockname) (tid, ARG1, ARG2, ARG3); +} + +POST (sys_getsockname) +{ + vg_assert (SUCCESS); + ML_ (generic_POST_sys_getsockname) (tid, VG_ (mk_SysRes_Success) (RES), + ARG1, ARG2, ARG3); +} + +PRE (sys_getpeername) +{ + PRINT ("sys_getpeername ( %ld, %#lx, %#lx )", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "getpeername", int, s, struct sockaddr *, name, + int *, namelen); + ML_ (generic_PRE_sys_getpeername) (tid, ARG1, ARG2, ARG3); +} + +POST (sys_getpeername) +{ + vg_assert (SUCCESS); + ML_ (generic_POST_sys_getpeername) (tid, VG_ (mk_SysRes_Success) (RES), + ARG1, ARG2, ARG3); +} + +PRE (sys_socketpair) +{ + PRINT ("sys_socketpair ( %ld, %ld, %ld, %#lx )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "socketpair", int, d, int, type, int, + protocol, int *, sv); + ML_ (generic_PRE_sys_socketpair) (tid, ARG1, ARG2, ARG3, ARG4); +} + +POST (sys_socketpair) +{ + vg_assert (SUCCESS); + ML_ (generic_POST_sys_socketpair) (tid, VG_ (mk_SysRes_Success) (RES), + ARG1, ARG2, ARG3, ARG4); +} + +PRE (sys_send) +{ + *flags |= SfMayBlock; + PRINT ("sys_send ( %ld, %#lx, %ld, %lu )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "send", int, s, const void *, msg, int, len, + unsigned int, flags); + ML_ (generic_PRE_sys_send) (tid, ARG1, ARG2, ARG3); +} + +PRE (sys_recv) +{ + *flags |= SfMayBlock; + PRINT ("sys_recv ( %ld, %#lx, %ld, %lu )", ARG1, ARG2, ARG3, ARG4); + PRE_REG_READ4 (long, "recv", int, s, void *, buf, int, len, + unsigned int, flags); + ML_ (generic_PRE_sys_recv) (tid, ARG1, ARG2, ARG3); +} + +POST (sys_recv) +{ + ML_ (generic_POST_sys_recv) (tid, RES, ARG1, ARG2, ARG3); +} + +PRE (sys_mmap2) +{ + SysRes r; + // Exactly like old_mmap() except: + // - all 6 args are passed in regs, rather than in a memory-block. + // - the file offset is specified in pagesize units rather than bytes, + // so that it can be used for files bigger than 2^32 bytes. + // pagesize or 4K-size units in offset? + vg_assert (VKI_PAGE_SIZE == 4096 || VKI_PAGE_SIZE == 4096 * 4 + || VKI_PAGE_SIZE == 4096 * 16); + PRINT ("sys_mmap2 ( %#lx, %llu, %ld, %ld, %ld, %ld )", ARG1, (ULong) ARG2, + ARG3, ARG4, + ARG5, ARG6); + PRE_REG_READ6 (long, "mmap2", unsigned long, start, unsigned long, length, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, offset); + r = + ML_ (generic_PRE_sys_mmap) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, + VKI_PAGE_SIZE * (Off64T) ARG6); + SET_STATUS_from_SysRes (r); +} + +PRE (sys_mmap) +{ + SysRes r; + //vg_assert(VKI_PAGE_SIZE == 4096); + PRINT ("sys_mmap ( %#lx, %llu, %lu, %lu, %lu, %ld )", ARG1, (ULong) ARG2, + ARG3, ARG4, ARG5, ARG6); + PRE_REG_READ6 (long, "mmap", unsigned long, start, vki_size_t, length, + int, prot, int, flags, int, fd, unsigned long, offset); + r = + ML_ (generic_PRE_sys_mmap) (tid, ARG1, ARG2, ARG3, ARG4, ARG5, + (Off64T) ARG6); + SET_STATUS_from_SysRes (r); +} + +// XXX: lstat64/fstat64/stat64 are generic, but not necessarily +// applicable to every architecture -- I think only to 32-bit archs. +// We're going to need something like linux/core_os32.h for such +// things, eventually, I think. --njn + +PRE (sys_lstat64) +{ + PRINT ("sys_lstat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2); + PRE_REG_READ2 (long, "lstat64", char *, file_name, struct stat64 *, buf); + PRE_MEM_RASCIIZ ("lstat64(file_name)", ARG1); + PRE_MEM_WRITE ("lstat64(buf)", ARG2, sizeof (struct vki_stat64)); +} + +POST (sys_lstat64) +{ + vg_assert (SUCCESS); + if (RES == 0) + { + POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64)); + } +} + +PRE (sys_stat64) +{ + PRINT ("sys_stat64 ( %#lx(%s), %#lx )", ARG1, (char *) ARG1, ARG2); + PRE_REG_READ2 (long, "stat64", char *, file_name, struct stat64 *, buf); + PRE_MEM_RASCIIZ ("stat64(file_name)", ARG1); + PRE_MEM_WRITE ("stat64(buf)", ARG2, sizeof (struct vki_stat64)); +} + +POST (sys_stat64) +{ + POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64)); +} + +PRE (sys_fstatat64) +{ + PRINT ("sys_fstatat64 ( %ld, %#lx(%s), %#lx )", ARG1, ARG2, (char *) ARG2, + ARG3); + PRE_REG_READ3 (long, "fstatat64", int, dfd, char *, file_name, + struct stat64 *, buf); + PRE_MEM_RASCIIZ ("fstatat64(file_name)", ARG2); + PRE_MEM_WRITE ("fstatat64(buf)", ARG3, sizeof (struct vki_stat64)); +} + +POST (sys_fstatat64) +{ + POST_MEM_WRITE (ARG3, sizeof (struct vki_stat64)); +} + +PRE (sys_fstat64) +{ + PRINT ("sys_fstat64 ( %ld, %#lx )", ARG1, ARG2); + PRE_REG_READ2 (long, "fstat64", unsigned long, fd, struct stat64 *, buf); + PRE_MEM_WRITE ("fstat64(buf)", ARG2, sizeof (struct vki_stat64)); +} + +POST (sys_fstat64) +{ + POST_MEM_WRITE (ARG2, sizeof (struct vki_stat64)); +} + +static Addr +deref_Addr (ThreadId tid, Addr a, Char * s) +{ + Addr * a_p = (Addr *) a; + PRE_MEM_READ (s, (Addr) a_p, sizeof (Addr)); + return *a_p; +} + +PRE (sys_ipc) +{ + PRINT ("sys_ipc ( %ld, %ld, %ld, %ld, %#lx, %ld )", ARG1, ARG2, ARG3, + ARG4, ARG5, ARG6); + // XXX: this is simplistic -- some args are not used in all circumstances. + PRE_REG_READ6 (int, "ipc", vki_uint, call, int, first, int, second, int, + third, void *, ptr, long, fifth) + switch (ARG1 /* call */ ) + { + case VKI_SEMOP: + ML_ (generic_PRE_sys_semop) (tid, ARG2, ARG5, ARG3); + *flags |= SfMayBlock; + break; + case VKI_SEMGET: + break; + case VKI_SEMCTL: + { + UWord arg = deref_Addr (tid, ARG5, "semctl(arg)"); + ML_ (generic_PRE_sys_semctl) (tid, ARG2, ARG3, ARG4, arg); + break; + } + case VKI_SEMTIMEDOP: + ML_ (generic_PRE_sys_semtimedop) (tid, ARG2, ARG5, ARG3, ARG6); + *flags |= SfMayBlock; + break; + case VKI_MSGSND: + ML_ (linux_PRE_sys_msgsnd) (tid, ARG2, ARG5, ARG3, ARG4); + if ((ARG4 & VKI_IPC_NOWAIT) == 0) + *flags |= SfMayBlock; + break; + case VKI_MSGRCV: + { + Addr msgp; + Word msgtyp; + msgp = deref_Addr (tid, + (Addr)(&((struct vki_ipc_kludge *)ARG5)->msgp), + "msgrcv(msgp)"); + msgtyp = deref_Addr (tid, + (Addr) (&((struct vki_ipc_kludge *)ARG5)->msgtyp), + "msgrcv(msgp)"); + ML_ (linux_PRE_sys_msgrcv) (tid, ARG2, msgp, ARG3, msgtyp, ARG4); + if ((ARG4 & VKI_IPC_NOWAIT) == 0) + *flags |= SfMayBlock; + break; + } + case VKI_MSGGET: + break; + case VKI_MSGCTL: + ML_ (linux_PRE_sys_msgctl) (tid, ARG2, ARG3, ARG5); + break; + case VKI_SHMAT: + { + UWord w; + PRE_MEM_WRITE ("shmat(raddr)", ARG4, sizeof (Addr)); + w = ML_ (generic_PRE_sys_shmat) (tid, ARG2, ARG5, ARG3); + if (w == 0) + SET_STATUS_Failure (VKI_EINVAL); + else + ARG5 = w; + break; + } + case VKI_SHMDT: + if (!ML_ (generic_PRE_sys_shmdt) (tid, ARG5)) + SET_STATUS_Failure (VKI_EINVAL); + break; + case VKI_SHMGET: + break; + case VKI_SHMCTL: /* IPCOP_shmctl */ + ML_ (generic_PRE_sys_shmctl) (tid, ARG2, ARG3, ARG5); + break; + default: + VG_ (message) (Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", + ARG1); + VG_ (core_panic) ("... bye!\n"); + break; + /*NOTREACHED*/ + } +} + +POST (sys_ipc) +{ + vg_assert (SUCCESS); + switch (ARG1 /* call */ ) + { + case VKI_SEMOP: + case VKI_SEMGET: + break; + case VKI_SEMCTL: + { + UWord arg = deref_Addr (tid, ARG5, "semctl(arg)"); + ML_ (generic_PRE_sys_semctl) (tid, ARG2, ARG3, ARG4, arg); + break; + } + case VKI_SEMTIMEDOP: + case VKI_MSGSND: + break; + case VKI_MSGRCV: + { + Addr msgp; + Word msgtyp; + msgp = deref_Addr (tid, (Addr) (&((struct vki_ipc_kludge *) + ARG5)->msgp), + "msgrcv(msgp)"); + msgtyp = deref_Addr (tid, + (Addr) (&((struct vki_ipc_kludge *) ARG5)->msgtyp), + "msgrcv(msgp)"); + ML_ (linux_POST_sys_msgrcv)(tid, RES, ARG2, msgp, ARG3, msgtyp, ARG4); + break; + } + case VKI_MSGGET: + break; + case VKI_MSGCTL: + ML_ (linux_POST_sys_msgctl) (tid, RES, ARG2, ARG3, ARG5); + break; + case VKI_SHMAT: + { + Addr addr; + /* force readability. before the syscall it is + * indeed uninitialized, as can be seen in + * glibc/sysdeps/unix/sysv/linux/shmat.c */ + POST_MEM_WRITE (ARG4, sizeof (Addr)); + addr = deref_Addr (tid, ARG4, "shmat(addr)"); + ML_ (generic_POST_sys_shmat) (tid, addr, ARG2, ARG5, ARG3); + break; + } + case VKI_SHMDT: + ML_ (generic_POST_sys_shmdt) (tid, RES, ARG5); + break; + case VKI_SHMGET: + break; + case VKI_SHMCTL: + ML_ (generic_POST_sys_shmctl) (tid, RES, ARG2, ARG3, ARG5); + break; + default: + VG_ (message) (Vg_DebugMsg, "FATAL: unhandled syscall(ipc) %ld\n", + ARG1); + VG_ (core_panic) ("... bye!\n"); + break; + /*NOTREACHED*/ + } +} + +PRE (sys_clone) + { + Bool badarg = False; + UInt cloneflags; + PRINT ("sys_clone ( %lx, %#lx, %#lx, %#lx, %#lx )", ARG1, ARG2, ARG3, + ARG4, ARG5); + PRE_REG_READ2 (int, "clone", unsigned long, flags, void *, child_stack); + if (ARG1 & VKI_CLONE_PARENT_SETTID) + { + if (VG_ (tdict).track_pre_reg_read) + { + PRA3 ("clone", int *, parent_tidptr); + } + PRE_MEM_WRITE ("clone(parent_tidptr)", ARG3, sizeof (Int)); + if (!VG_ (am_is_valid_for_client)(ARG3, sizeof (Int), VKI_PROT_WRITE)) + { + badarg = True; + } + } + if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) + { + if (VG_ (tdict).track_pre_reg_read) + { + PRA5 ("clone", int *, child_tidptr); + } + PRE_MEM_WRITE ("clone(child_tidptr)", ARG5, sizeof (Int)); + if (!VG_ (am_is_valid_for_client)(ARG5, sizeof (Int), VKI_PROT_WRITE)) + { + badarg = True; + } + } + if (badarg) + { + SET_STATUS_Failure (VKI_EFAULT); + return; + } + cloneflags = ARG1; + if (!ML_ (client_signal_OK) (ARG1 & VKI_CSIGNAL)) + { + SET_STATUS_Failure (VKI_EINVAL); + return; + } + /* Only look at the flags we really care about */ + switch (cloneflags & (VKI_CLONE_VM | VKI_CLONE_FS + |VKI_CLONE_FILES | VKI_CLONE_VFORK)) + { + case VKI_CLONE_VM | VKI_CLONE_FS | VKI_CLONE_FILES: + /* thread creation */ + PRINT ("sys_clone1 ( %#lx, %#lx, %#lx, %#lx, %#lx )", + ARG1, ARG2, ARG3, ARG4, ARG5); + SET_STATUS_from_SysRes (do_clone (tid, + ARG1, /* flags */ + (Addr) ARG2, /* child SP */ + (Int *) ARG3, /* parent_tidptr */ + (Int *) ARG5, /* child_tidptr */ + (Addr) ARG4)); /* child_tls */ + + break; + case VKI_CLONE_VFORK | VKI_CLONE_VM: /* vfork */ + /* FALLTHROUGH - assume vfork == fork */ + cloneflags &= ~(VKI_CLONE_VFORK | VKI_CLONE_VM); + case 0: /* plain fork */ + SET_STATUS_from_SysRes (ML_ (do_fork_clone) (tid, + cloneflags, /* flags */ + (Int *) ARG3, /* parent_tidptr */ + (Int *) ARG5)); /* child_tidptr */ + break; + default: + /* should we just ENOSYS? */ + VG_ (message) (Vg_UserMsg, "Unsupported clone() flags: 0x%lx\n", ARG1); + VG_ (message) (Vg_UserMsg, "\n"); + VG_ (message) (Vg_UserMsg, "The only supported clone() uses are:\n"); + VG_ (message) (Vg_UserMsg, + " - via a threads library (LinuxThreads or NPTL)\n"); + VG_ (message) (Vg_UserMsg, + " - via the implementation of fork or vfork\n"); + VG_ (unimplemented)("Valgrind does not support general clone()."); + } + if (SUCCESS) + { + if (ARG1 & VKI_CLONE_PARENT_SETTID) + POST_MEM_WRITE (ARG3, sizeof (Int)); + if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) + POST_MEM_WRITE (ARG5, sizeof (Int)); + /* Thread creation was successful; let the child have the chance + * to run */ + *flags |= SfYieldAfter; + } +} + +PRE (sys_sigreturn) +{ + ThreadState * tst; + PRINT ("sys_sigreturn ( )"); + vg_assert (VG_ (is_valid_tid) (tid)); + vg_assert (tid >= 1 && tid < VG_N_THREADS); + vg_assert (VG_ (is_running_thread) (tid)); + tst = VG_ (get_ThreadState) (tid); + VG_ (sigframe_destroy) (tid, False); + /* Tell the driver not to update the guest state with the "result", + and set a bogus result to keep it happy. */ + *flags |= SfNoWriteResult; + SET_STATUS_Success (0); + /* Check to see if any signals arose as a result of this. */ + *flags |= SfPollAfter; +} + +PRE (sys_rt_sigreturn) +{ + PRINT ("rt_sigreturn ( )"); + vg_assert (VG_ (is_valid_tid) (tid)); + vg_assert (tid >= 1 && tid < VG_N_THREADS); + vg_assert (VG_ (is_running_thread) (tid)); + /* Restore register state from frame and remove it */ + VG_ (sigframe_destroy) (tid, True); + /* Tell the driver not to update the guest state with the "result", + and set a bogus result to keep it happy. */ + *flags |= SfNoWriteResult; + SET_STATUS_Success (0); + /* Check to see if any signals arose as a result of this. */ + *flags |= SfPollAfter; +} + +PRE (sys_set_thread_area) +{ + PRINT ("set_thread_area (%lx)", ARG1); + PRE_REG_READ1(long, "set_thread_area", unsigned long, addr); + SET_STATUS_from_SysRes( sys_set_tls( tid, ARG1 ) ); +} + +/* Very much MIPS specific */ +PRE (sys_cacheflush) +{ + PRINT ("cacheflush (%lx, %#lx, %#lx)", ARG1, ARG2, ARG3); + PRE_REG_READ3 (long, "cacheflush", void *, addrlow, void *, addrhigh, int, + flags); + VG_ (discard_translations) ((Addr64) ARG1, ((ULong) ARG2) - ((ULong) ARG1) + + 1ULL /*paranoia */ , "PRE(sys_cacheflush)"); + SET_STATUS_Success (0); +} + +#undef PRE +#undef POST + +/* --------------------------------------------------------------------- + The mips/Linux syscall table + ------------------------------------------------------------------ */ +#define PLAX_(sysno, name) WRAPPER_ENTRY_X_(mips_linux, sysno, name) +#define PLAXY(sysno, name) WRAPPER_ENTRY_XY(mips_linux, sysno, name) + +// This table maps from __NR_xxx syscall numbers (from +// linux/include/asm-mips/unistd.h) to the appropriate PRE/POST sys_foo() +// wrappers on mips (as per sys_call_table in linux/arch/mips/kernel/entry.S). +// + +// For those syscalls not handled by Valgrind, the annotation indicate its +// arch/OS combination, eg. */* (generic), */Linux (Linux only), ?/? +// (unknown). + +static SyscallTableEntry syscall_main_table[] = { + //PLAXY (__NR_syscall, sys_syscall), // 0 + GENX_ (__NR_exit, sys_exit), // 1 + GENX_ (__NR_fork, sys_fork), // 2 + GENXY (__NR_read, sys_read), // 3 + GENX_ (__NR_write, sys_write), // 4 + GENXY (__NR_open, sys_open), // 5 + GENXY (__NR_close, sys_close), // 6 + GENXY (__NR_waitpid, sys_waitpid), // 7 + GENXY (__NR_creat, sys_creat), // 8 + GENX_ (__NR_link, sys_link), // 9 + GENX_ (__NR_unlink, sys_unlink), // 10 + GENX_ (__NR_execve, sys_execve), // 11 + GENX_ (__NR_chdir, sys_chdir), // 12 + GENXY (__NR_time, sys_time), // 13 + GENX_ (__NR_mknod, sys_mknod), // 14 + GENX_ (__NR_chmod, sys_chmod), // 15 + GENX_ (__NR_lchown, sys_lchown), // 16 + LINX_ (__NR_lseek, sys_lseek), // 19 + GENX_ (__NR_getpid, sys_getpid), // 20 + LINX_ (__NR_mount, sys_mount), // 21 + LINX_ (__NR_umount, sys_oldumount), // 22 + GENX_ (__NR_setuid, sys_setuid), // 23 ## P + GENX_ (__NR_getuid, sys_getuid), // 24 ## P + //.. // (__NR_stime, sys_stime), + //.. PLAXY(__NR_ptrace, sys_ptrace), // 26 + GENX_ (__NR_alarm, sys_alarm), // 27 + //.. // (__NR_oldfstat, sys_fstat), + GENX_ (__NR_pause, sys_pause), // 29 + LINX_ (__NR_utime, sys_utime), // 30 + //.. GENX_(__NR_stty, sys_ni_syscall), // 31 + //.. GENX_(__NR_gtty, sys_ni_syscall), // 32 + GENX_ (__NR_access, sys_access), // 33 + //.. GENX_(__NR_nice, sys_nice), // 34 + //.. GENX_(__NR_ftime, sys_ni_syscall), // 35 + //.. GENX_(__NR_sync, sys_sync), // 36 + GENX_ (__NR_kill, sys_kill), // 37 + GENX_ (__NR_rename, sys_rename), // 38 + GENX_ (__NR_mkdir, sys_mkdir), // 39 + GENX_ (__NR_rmdir, sys_rmdir), // 40 + GENXY (__NR_dup, sys_dup), // 41 + LINXY (__NR_pipe, sys_pipe), // 42 + GENXY (__NR_times, sys_times), // 43 + //.. GENX_(__NR_prof, sys_ni_syscall), // 44 + //.. + GENX_ (__NR_brk, sys_brk), // 45 + GENX_ (__NR_setgid, sys_setgid), // 46 + GENX_ (__NR_getgid, sys_getgid), // 47 + //.. // (__NR_signal, sys_signal), // 48 */* (ANSI C) + GENX_ (__NR_geteuid, sys_geteuid), // 49 + GENX_ (__NR_getegid, sys_getegid), // 50 + //.. GENX_(__NR_acct, sys_acct), // 51 + LINX_ (__NR_umount2, sys_umount), // 52 + //.. GENX_(__NR_lock, sys_ni_syscall), // 53 + LINXY (__NR_ioctl, sys_ioctl), // 54 + LINXY (__NR_fcntl, sys_fcntl), // 55 + //.. GENX_(__NR_mpx, sys_ni_syscall), // 56 + GENX_ (__NR_setpgid, sys_setpgid), // 57 + //.. GENX_(__NR_ulimit, sys_ni_syscall), // 58 + //.. // (__NR_oldolduname, sys_olduname), // 59 + GENX_ (__NR_umask, sys_umask), // 60 + GENX_ (__NR_chroot, sys_chroot), // 61 + //.. // (__NR_ustat, sys_ustat) // 62 SVr4 -- deprecated + GENXY (__NR_dup2, sys_dup2), // 63 + GENX_ (__NR_getppid, sys_getppid), // 64 + GENX_ (__NR_getpgrp, sys_getpgrp), // 65 + GENX_ (__NR_setsid, sys_setsid), // 66 + // PLAXY(__NR_sigaction, sys_sigaction), // 67 + //.. // (__NR_sgetmask, sys_sgetmask), // 68 */* (ANSI C) + //.. // (__NR_ssetmask, sys_ssetmask), // 69 */* (ANSI C) + //.. + GENX_ (__NR_setreuid, sys_setreuid), // 70 + GENX_ (__NR_setregid, sys_setregid), // 71 + // PLAX_(__NR_sigsuspend, sys_sigsuspend), // 72 + LINXY (__NR_sigpending, sys_sigpending), // 73 + //.. // (__NR_sethostname, sys_sethostname), // 74 */* + //.. + GENX_ (__NR_setrlimit, sys_setrlimit), // 75 + //.. GENXY(__NR_getrlimit, sys_old_getrlimit), // 76 + GENXY (__NR_getrusage, sys_getrusage), // 77 + GENXY (__NR_gettimeofday, sys_gettimeofday), // 78 + //.. GENX_(__NR_settimeofday, sys_settimeofday), // 79 + //.. + GENXY (__NR_getgroups, sys_getgroups), // 80 + GENX_ (__NR_setgroups, sys_setgroups), // 81 + //.. PLAX_(__NR_select, old_select), // 82 + GENX_ (__NR_symlink, sys_symlink), // 83 + //.. // (__NR_oldlstat, sys_lstat), // 84 -- obsolete + //.. + GENX_ (__NR_readlink, sys_readlink), // 85 + //.. // (__NR_uselib, sys_uselib), // 86 */Linux + //.. // (__NR_swapon, sys_swapon), // 87 */Linux + //.. // (__NR_reboot, sys_reboot), // 88 */Linux + //.. // (__NR_readdir, old_readdir), // 89 -- superseded + PLAX_ (__NR_mmap, sys_mmap), // 90 + GENXY (__NR_munmap, sys_munmap), // 91 + GENX_ (__NR_truncate, sys_truncate), // 92 + GENX_ (__NR_ftruncate, sys_ftruncate), // 93 + GENX_ (__NR_fchmod, sys_fchmod), // 94 + GENX_ (__NR_fchown, sys_fchown), // 95 + GENX_ (__NR_getpriority, sys_getpriority), // 96 + GENX_ (__NR_setpriority, sys_setpriority), // 97 + //.. GENX_(__NR_profil, sys_ni_syscall), // 98 + GENXY (__NR_statfs, sys_statfs), // 99 + //.. + GENXY (__NR_fstatfs, sys_fstatfs), // 100 + //.. LINX_(__NR_ioperm, sys_ioperm), // 101 + PLAXY (__NR_socketcall, sys_socketcall), // 102 + LINXY (__NR_syslog, sys_syslog), // 103 + GENXY (__NR_setitimer, sys_setitimer), // 104 + //.. + //.. GENXY(__NR_getitimer, sys_getitimer), // 105 + GENXY (__NR_stat, sys_newstat), // 106 + GENXY (__NR_lstat, sys_newlstat), // 107 + GENXY (__NR_fstat, sys_newfstat), // 108 + //.. // (__NR_olduname, sys_uname), // 109 -- obsolete + //.. + //.. GENX_(__NR_iopl, sys_iopl), // 110 + //.. LINX_(__NR_vhangup, sys_vhangup), // 111 + //.. GENX_(__NR_idle, sys_ni_syscall), // 112 + //.. // (__NR_vm86old, sys_vm86old), // 113 x86/Linux-only + GENXY (__NR_wait4, sys_wait4), // 114 + //.. + //.. // (__NR_swapoff, sys_swapoff), // 115 */Linux + LINXY (__NR_sysinfo, sys_sysinfo), // 116 + PLAXY (__NR_ipc, sys_ipc), // 117 + GENX_ (__NR_fsync, sys_fsync), // 118 + PLAX_ (__NR_sigreturn, sys_sigreturn), // 119 ?/Linux + //.. + PLAX_ (__NR_clone, sys_clone), // 120 + //.. // (__NR_setdomainname, sys_setdomainname), // 121 */*(?) + GENXY (__NR_uname, sys_newuname), // 122 + //.. PLAX_(__NR_modify_ldt, sys_modify_ldt), // 123 + //.. LINXY(__NR_adjtimex, sys_adjtimex), // 124 + //.. + GENXY (__NR_mprotect, sys_mprotect), // 125 + // LINXY(__NR_sigprocmask, sys_sigprocmask), // 126 + //.. // Nb: create_module() was removed 2.4-->2.6 + //.. GENX_(__NR_create_module, sys_ni_syscall), // 127 + //.. GENX_(__NR_init_module, sys_init_module), // 128 + //.. // (__NR_delete_module, sys_delete_module), // 129 (*/Linux)? + //.. + //.. // Nb: get_kernel_syms() was removed 2.4-->2.6 + //.. GENX_(__NR_get_kernel_syms, sys_ni_syscall), // 130 + //.. LINX_(__NR_quotactl, sys_quotactl), // 131 + GENX_ (__NR_getpgid, sys_getpgid), // 132 + GENX_ (__NR_fchdir, sys_fchdir), // 133 + //.. // (__NR_bdflush, sys_bdflush), // 134 */Linux + //.. + //.. // (__NR_sysfs, sys_sysfs), // 135 SVr4 + LINX_ (__NR_personality, sys_personality), // 136 + //.. GENX_(__NR_afs_syscall, sys_ni_syscall), // 137 + LINX_ (__NR_setfsuid, sys_setfsuid), // 138 + LINX_ (__NR_setfsgid, sys_setfsgid), // 139 + LINXY (__NR__llseek, sys_llseek), // 140 + GENXY (__NR_getdents, sys_getdents), // 141 + GENX_ (__NR__newselect, sys_select), // 142 + GENX_ (__NR_flock, sys_flock), // 143 + GENX_ (__NR_msync, sys_msync), // 144 + //.. + GENXY (__NR_readv, sys_readv), // 145 + GENX_ (__NR_writev, sys_writev), // 146 + PLAX_ (__NR_cacheflush, sys_cacheflush), // 147 + GENX_ (__NR_getsid, sys_getsid), // 151 + GENX_ (__NR_fdatasync, sys_fdatasync), // 152 + LINXY (__NR__sysctl, sys_sysctl), // 153 + //.. + GENX_ (__NR_mlock, sys_mlock), // 154 + GENX_ (__NR_munlock, sys_munlock), // 155 + GENX_ (__NR_mlockall, sys_mlockall), // 156 + LINX_ (__NR_munlockall, sys_munlockall), // 157 + //.. LINXY(__NR_sched_setparam, sys_sched_setparam), // 158 + //.. + LINXY (__NR_sched_getparam, sys_sched_getparam), // 159 + LINX_ (__NR_sched_setscheduler, sys_sched_setscheduler), // 160 + LINX_ (__NR_sched_getscheduler, sys_sched_getscheduler), // 161 + LINX_ (__NR_sched_yield, sys_sched_yield), // 162 + LINX_ (__NR_sched_get_priority_max, sys_sched_get_priority_max), // 163 + LINX_ (__NR_sched_get_priority_min, sys_sched_get_priority_min), // 164 + //.. //LINX?(__NR_sched_rr_get_interval, sys_sched_rr_get_interval), // 165 */* + GENXY (__NR_nanosleep, sys_nanosleep), // 166 + GENX_ (__NR_mremap, sys_mremap), // 167 + PLAXY (__NR_accept, sys_accept), // 168 + PLAX_ (__NR_bind, sys_bind), // 169 + PLAX_ (__NR_connect, sys_connect), // 170 + PLAXY (__NR_getpeername, sys_getpeername), // 171 + PLAXY (__NR_getsockname, sys_getsockname), // 172 + PLAXY (__NR_getsockopt, sys_getsockopt), // 173 + PLAX_ (__NR_listen, sys_listen), // 174 + PLAXY (__NR_recv, sys_recv), // 175 + PLAXY (__NR_recvfrom, sys_recvfrom), // 176 + PLAXY (__NR_recvmsg, sys_recvmsg), // 177 + PLAX_ (__NR_send, sys_send), // 178 + PLAX_ (__NR_sendmsg, sys_sendmsg), // 179 + PLAX_ (__NR_sendto, sys_sendto), // 180 + PLAX_ (__NR_setsockopt, sys_setsockopt), // 181 + PLAXY (__NR_socket, sys_socket), // 183 + PLAXY (__NR_socketpair, sys_socketpair), // 184 + LINX_ (__NR_setresuid, sys_setresuid), // 185 + LINXY (__NR_getresuid, sys_getresuid), // 186 + //.. GENX_(__NR_query_module, sys_ni_syscall), // + GENXY (__NR_poll, sys_poll), // 188 + //.. // (__NR_nfsservctl, sys_nfsservctl), // 168 */Linux + //.. + LINX_ (__NR_setresgid, sys_setresgid), // 190 + LINXY (__NR_getresgid, sys_getresgid), // 191 + LINXY (__NR_prctl, sys_prctl), // 192 + PLAX_ (__NR_rt_sigreturn, sys_rt_sigreturn), // 193 + LINXY (__NR_rt_sigaction, sys_rt_sigaction), // 194 + LINXY (__NR_rt_sigprocmask, sys_rt_sigprocmask), // 195 + LINXY (__NR_rt_sigpending, sys_rt_sigpending), // 196 + LINXY (__NR_rt_sigtimedwait, sys_rt_sigtimedwait), // 197 + LINXY (__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo), // 198 + LINX_ (__NR_rt_sigsuspend, sys_rt_sigsuspend), // 199 + GENXY (__NR_pread64, sys_pread64), // 200 + GENX_ (__NR_pwrite64, sys_pwrite64), // 201 + GENX_ (__NR_chown, sys_chown), // 202 + GENXY (__NR_getcwd, sys_getcwd), // 203 + LINXY (__NR_capget, sys_capget), // 204 + //.. + //.. LINX_(__NR_capset, sys_capset), // 205 + GENXY (__NR_sigaltstack, sys_sigaltstack), // 206 + LINXY (__NR_sendfile, sys_sendfile), // 207 + //.. GENXY(__NR_getpmsg, sys_getpmsg), // 208 + //.. GENX_(__NR_putpmsg, sys_putpmsg), // 209 + // Nb: we treat vfork as fork + // GENX_(__NR_vfork, sys_fork), // + GENXY (__NR_getrlimit, sys_getrlimit), // 76 + //__NR_readahead // 191 ppc/Linux only? + PLAX_ (__NR_mmap2, sys_mmap2), // 210 + // GENX_(__NR_truncate64, sys_truncate64), // 211 + GENX_ (__NR_ftruncate64, sys_ftruncate64), // 212 + //.. + PLAXY (__NR_stat64, sys_stat64), // 213 + PLAXY (__NR_lstat64, sys_lstat64), // 214 + PLAXY (__NR_fstat64, sys_fstat64), // 215 + GENXY (__NR_getdents64, sys_getdents64), // 219 + //.. // (__NR_pivot_root, sys_pivot_root), // + LINXY (__NR_fcntl64, sys_fcntl64), // 220 + GENX_ (__NR_madvise, sys_madvise), // 218 + GENXY (__NR_mincore, sys_mincore), // 217 + LINX_ (__NR_gettid, sys_gettid), // 222 + //.. LINX_(__NR_tkill, sys_tkill), // 208 */Linux + //.. LINX_(__NR_setxattr, sys_setxattr), // 209 + //.. LINX_(__NR_lsetxattr, sys_lsetxattr), // 210 + //.. LINX_(__NR_fsetxattr, sys_fsetxattr), // 211 + LINXY (__NR_getxattr, sys_getxattr), // 227 + LINXY (__NR_lgetxattr, sys_lgetxattr), // 228 + LINXY (__NR_fgetxattr, sys_fgetxattr), // 229 + LINXY (__NR_listxattr, sys_listxattr), // 230 + LINXY (__NR_llistxattr, sys_llistxattr), // 231 + LINXY (__NR_flistxattr, sys_flistxattr), // 232 + LINX_ (__NR_removexattr, sys_removexattr), // 233 + LINX_ (__NR_lremovexattr, sys_lremovexattr), // 234 + LINX_ (__NR_fremovexattr, sys_fremovexattr), // 235 + LINXY (__NR_futex, sys_futex), // 238 + LINX_ (__NR_sched_setaffinity, sys_sched_setaffinity), // 239 + LINXY (__NR_sched_getaffinity, sys_sched_getaffinity), // 240 + /* 224 currently unused */ + // __NR_tuxcall // + LINXY (__NR_sendfile64, sys_sendfile64), // 237 + //.. + LINX_ (__NR_io_setup, sys_io_setup), // 241 + LINX_ (__NR_io_destroy, sys_io_destroy), // 242 + LINXY (__NR_io_getevents, sys_io_getevents), // 243 + LINX_ (__NR_io_submit, sys_io_submit), // 244 + LINXY (__NR_io_cancel, sys_io_cancel), // 245 + //.. + LINX_ (__NR_set_tid_address, sys_set_tid_address), // 252 + LINX_ (__NR_fadvise64, sys_fadvise64), // 254 + LINX_ (__NR_exit_group, sys_exit_group), // 246 + //.. GENXY(__NR_lookup_dcookie, sys_lookup_dcookie), // 247 + LINXY (__NR_epoll_create, sys_epoll_create), // 248 + LINX_ (__NR_epoll_ctl, sys_epoll_ctl), // 249 + LINXY (__NR_epoll_wait, sys_epoll_wait), // 250 + //.. // (__NR_remap_file_pages, sys_remap_file_pages), // 239 */Linux + LINXY (__NR_timer_create, sys_timer_create), // 257 + LINXY (__NR_timer_settime, sys_timer_settime), // 258 + LINXY (__NR_timer_gettime, sys_timer_gettime), // 259 + LINX_ (__NR_timer_getoverrun, sys_timer_getoverrun), // 260 + LINX_ (__NR_timer_delete, sys_timer_delete), // 261 + LINX_ (__NR_clock_settime, sys_clock_settime), // 262 + LINXY (__NR_clock_gettime, sys_clock_gettime), // 263 + LINXY (__NR_clock_getres, sys_clock_getres), // 264 + LINXY (__NR_clock_nanosleep, sys_clock_nanosleep), // 265 + // __NR_swapcontext // + LINXY (__NR_tgkill, sys_tgkill), // 266 */Linux + //.. GENX_(__NR_utimes, sys_utimes), // 267 + GENXY (__NR_statfs64, sys_statfs64), // 255 + GENXY (__NR_fstatfs64, sys_fstatfs64), // 256 + LINXY (__NR_get_mempolicy, sys_get_mempolicy), // 269 + LINX_ (__NR_set_mempolicy, sys_set_mempolicy), // 270 + LINXY (__NR_mq_open, sys_mq_open), // 271 + LINX_ (__NR_mq_unlink, sys_mq_unlink), // 272 + LINX_ (__NR_mq_timedsend, sys_mq_timedsend), // 273 + LINXY (__NR_mq_timedreceive, sys_mq_timedreceive), // 274 + LINX_ (__NR_mq_notify, sys_mq_notify), // 275 + LINXY (__NR_mq_getsetattr, sys_mq_getsetattr), // 276 + // __NR_kexec_load // + LINX_ (__NR_inotify_init, sys_inotify_init), // 275 + LINX_ (__NR_inotify_add_watch, sys_inotify_add_watch), // 276 + LINX_ (__NR_inotify_rm_watch, sys_inotify_rm_watch), // 277 + PLAX_ (__NR_set_thread_area, sys_set_thread_area), // 283 + LINXY (__NR_openat, sys_openat), // 288 + LINX_ (__NR_mkdirat, sys_mkdirat), // 289 + LINX_ (__NR_mknodat, sys_mknodat), // 290 + LINX_ (__NR_fchownat, sys_fchownat), // 291 + LINX_ (__NR_futimesat, sys_futimesat), // 292 + PLAXY (__NR_fstatat64, sys_fstatat64), // 293 + LINX_ (__NR_unlinkat, sys_unlinkat), // 294 + LINX_ (__NR_renameat, sys_renameat), // 295 + LINX_ (__NR_linkat, sys_linkat), // 296 + LINX_ (__NR_symlinkat, sys_symlinkat), // 297 + LINX_ (__NR_readlinkat, sys_readlinkat), // 298 + LINX_ (__NR_fchmodat, sys_fchmodat), // 299 + LINX_ (__NR_faccessat, sys_faccessat), // 300 + LINXY (__NR_ppoll, sys_ppoll), // 302 + LINX_ (__NR_set_robust_list, sys_set_robust_list), // 309 + LINXY (__NR_get_robust_list, sys_get_robust_list), // 310 + LINXY (__NR_epoll_pwait, sys_epoll_pwait), // 313 + LINX_ (__NR_utimensat, sys_utimensat), // 316 + LINX_ (__NR_fallocate, sys_fallocate), // 320 + LINXY (__NR_signalfd4, sys_signalfd4), // 324 + LINX_ (__NR_eventfd2, sys_eventfd2), // 325 + LINXY (__NR_pipe2, sys_pipe2), // 328 + LINXY (__NR_inotify_init1, sys_inotify_init1) // 329 +}; + +SyscallTableEntry* ML_(get_linux_syscall_entry) (UInt sysno) +{ + const UInt syscall_main_table_size + = sizeof (syscall_main_table) / sizeof (syscall_main_table[0]); + /* Is it in the contiguous initial section of the table? */ + if (sysno < syscall_main_table_size) + { + SyscallTableEntry * sys = &syscall_main_table[sysno]; + if (sys->before == NULL) + return NULL; /* no entry */ + else + return sys; + } + /* Can't find a wrapper */ + return NULL; +} + +#endif // defined(VGP_mips32_linux) + +/*--------------------------------------------------------------------*/ +/*--- end syswrap-mips-linux.c ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-mips32-linux.h b/include/vki/vki-mips32-linux.h new file mode 100644 index 0000000000..fa042dd82e --- /dev/null +++ b/include/vki/vki-mips32-linux.h @@ -0,0 +1,973 @@ + +/*--------------------------------------------------------------------*/ +/*--- mips/Linux-specific kernel interface. vki-mips32-linux.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __VKI_MIPS32_LINUX_H +#define __VKI_MIPS32_LINUX_H + +#include + +// mips endian +#if defined (_MIPSEL) +#define VKI_LITTLE_ENDIAN 1 +#elif defined (_MIPSEB) +#define VKI_BIG_ENDIAN 1 +#endif + + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-generic/int-ll64.h +//---------------------------------------------------------------------- + +typedef __signed__ char __vki_s8; +typedef unsigned char __vki_u8; + +typedef __signed__ short __vki_s16; +typedef unsigned short __vki_u16; + +typedef __signed__ int __vki_s32; +typedef unsigned int __vki_u32; + +typedef __signed char vki_s8; +typedef unsigned char vki_u8; + +typedef __signed short vki_s16; +typedef unsigned short vki_u16; + +typedef __signed int vki_s32; +typedef unsigned int vki_u32; + +typedef __signed__ long long __vki_s64; +typedef unsigned long long __vki_u64; + + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/page.h +//---------------------------------------------------------------------- + +/* PAGE_SHIFT determines the page size */ +#define VKI_PAGE_SHIFT MIPS_PAGE_SHIFT +#define VKI_PAGE_SIZE (1UL << VKI_PAGE_SHIFT) +#define VKI_PAGE_MASK (~(VKI_PAGE_SIZE-1)) +#define VKI_MAX_PAGE_SHIFT VKI_PAGE_SHIFT +#define VKI_MAX_PAGE_SIZE VKI_PAGE_SIZE + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/arch/mips/include/asm-generic/shmparam.h +//---------------------------------------------------------------------- + +#define VKI_SHMLBA SHM_ALIGNMENT + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm/signal.h +//---------------------------------------------------------------------- + +#define VKI_MINSIGSTKSZ 2048 + +#define VKI_SIG_BLOCK 1 /* for blocking signals */ +#define VKI_SIG_UNBLOCK 2 /* for unblocking signals */ +#define VKI_SIG_SETMASK 3 /* for setting the signal mask */ + +/* Type of a signal handler. */ +typedef void (*__vki_signalfn_t)(int); +typedef __vki_signalfn_t __user *__vki_sighandler_t; + +typedef void __vki_restorefn_t(void); +typedef __vki_restorefn_t __user *__vki_sigrestore_t; + +/* Fake signal functions */ +#define VKI_SIG_DFL ((__vki_signalfn_t)0) /* default signal handling */ +#define VKI_SIG_IGN ((__vki_signalfn_t)1) /* ignore signal */ +#define VKI_SIG_ERR ((__vki_signalfn_t)-1) /* error return from signal */ + +#define _VKI_NSIG 128 +#define _VKI_NSIG_BPW 32 +#define _VKI_NSIG_WORDS (_VKI_NSIG / _VKI_NSIG_BPW) + +typedef unsigned long vki_old_sigset_t; /* at least 32 bits */ + +typedef struct { + unsigned long sig[_VKI_NSIG_WORDS]; +} vki_sigset_t; + +#define VKI_SIGHUP 1 /* Hangup (POSIX). */ +#define VKI_SIGINT 2 /* Interrupt (ANSI). */ +#define VKI_SIGQUIT 3 /* Quit (POSIX). */ +#define VKI_SIGILL 4 /* Illegal instruction (ANSI). */ +#define VKI_SIGTRAP 5 /* Trace trap (POSIX). */ +#define VKI_SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define VKI_SIGABRT VKI_SIGIOT /* Abort (ANSI). */ +#define VKI_SIGEMT 7 +#define VKI_SIGFPE 8 /* Floating-point exception (ANSI). */ +#define VKI_SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define VKI_SIGBUS 10 /* BUS error (4.2 BSD). */ +#define VKI_SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define VKI_SIGSYS 12 +#define VKI_SIGPIPE 13 /* Broken pipe (POSIX). */ +#define VKI_SIGALRM 14 /* Alarm clock (POSIX). */ +#define VKI_SIGTERM 15 /* Termination (ANSI). */ +#define VKI_SIGUSR1 16 /* User-defined signal 1 (POSIX). */ +#define VKI_SIGUSR2 17 /* User-defined signal 2 (POSIX). */ +#define VKI_SIGCHLD 18 /* Child status has changed (POSIX). */ +#define VKI_SIGCLD VKI_SIGCHLD /* Same as SIGCHLD (System V). */ +#define VKI_SIGPWR 19 /* Power failure restart (System V). */ +#define VKI_SIGWINCH 20 /* Window size change (4.3 BSD, Sun). */ +#define VKI_SIGURG 21 /* Urgent condition on socket (4.2 BSD). */ +#define VKI_SIGIO 22 /* I/O now possible (4.2 BSD). */ +#define VKI_SIGPOLL VKI_SIGIO /* Pollable event occurred (System V). */ +#define VKI_SIGSTOP 23 /* Stop, unblockable (POSIX). */ +#define VKI_SIGTSTP 24 /* Keyboard stop (POSIX). */ +#define VKI_SIGCONT 25 /* Continue (POSIX). */ +#define VKI_SIGTTIN 26 /* Background read from tty (POSIX). */ +#define VKI_SIGTTOU 27 /* Background write to tty (POSIX). */ +#define VKI_SIGVTALRM 28 /* Virtual alarm clock (4.2 BSD). */ +#define VKI_SIGPROF 29 /* Profiling alarm clock (4.2 BSD). */ +#define VKI_SIGXCPU 30 /* CPU limit exceeded (4.2 BSD). */ +#define VKI_SIGXFSZ 31 /* File size limit exceeded (4.2 BSD). */ + +/* These should not be considered constants from userland. */ +#define VKI_SIGRTMIN 32 +// [[This was (_NSIG-1) in 2.4.X... not sure if it matters.]] +#define VKI_SIGRTMAX _VKI_NSIG + +#define VKI_SA_ONSTACK 0x08000000 +#define VKI_SA_RESETHAND 0x80000000 +#define VKI_SA_RESTART 0x10000000 +#define VKI_SA_SIGINFO 0x00000008 +#define VKI_SA_NODEFER 0x40000000 +#define VKI_SA_NOCLDWAIT 0x00010000 +#define VKI_SA_NOCLDSTOP 0x00000001 + +#define VKI_SA_NOMASK VKI_SA_NODEFER +#define VKI_SA_ONESHOT VKI_SA_RESETHAND +//#define VKI_SA_INTERRUPT 0x20000000 /* dummy -- ignored */ + +#define VKI_SA_RESTORER 0x04000000 + +#define VKI_SS_ONSTACK 1 +#define VKI_SS_DISABLE 2 + +struct vki_old_sigaction { + // [[Nb: a 'k' prefix is added to "sa_handler" because + // bits/sigaction.h (which gets dragged in somehow via signal.h) + // #defines it as something else. Since that is done for glibc's + // purposes, which we don't care about here, we use our own name.]] + unsigned long sa_flags; + __vki_sighandler_t ksa_handler; + vki_old_sigset_t sa_mask; + __vki_sigrestore_t sa_restorer; +}; + +struct vki_sigaction { + unsigned int sa_flags; + __vki_sighandler_t sa_handler; + vki_sigset_t sa_mask; +}; + + +struct vki_sigaction_base { + // [[See comment about extra 'k' above]] + unsigned long sa_flags; + __vki_sighandler_t ksa_handler; + + vki_sigset_t sa_mask; /* mask last for extensibility */ + __vki_sigrestore_t sa_restorer; +}; + +/* On Linux we use the same type for passing sigactions to + and from the kernel. Hence: */ +typedef struct vki_sigaction_base vki_sigaction_toK_t; +typedef struct vki_sigaction_base vki_sigaction_fromK_t; + +typedef struct vki_sigaltstack { + void __user *ss_sp; + vki_size_t ss_size; + int ss_flags; + +} vki_stack_t; + + +//---------------------------------------------------------------------- +// From 2.6.35.5/include/asm-mips/sigcontext.h +//---------------------------------------------------------------------- + +struct _vki_fpreg { + unsigned short significand[4]; + unsigned short exponent; +}; + +struct _vki_fpxreg { + unsigned short significand[4]; + unsigned short exponent; + unsigned short padding[3]; +}; + +struct _vki_xmmreg { + unsigned long element[4]; +}; + +struct _vki_fpstate { + /* Regular FPU environment */ + unsigned long cw; + unsigned long sw; + unsigned long tag; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; + struct _vki_fpreg _st[8]; + unsigned short status; + unsigned short magic; /* 0xffff = regular FPU data only */ + + /* FXSR FPU environment */ + unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ + unsigned long mxcsr; + unsigned long reserved; + struct _vki_fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ + struct _vki_xmmreg _xmm[8]; + unsigned long padding[56]; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/sigcontext.h +//---------------------------------------------------------------------- + +struct vki_sigcontext { + unsigned int sc_regmask; /* Unused */ + unsigned int sc_status; /* Unused */ + unsigned long long sc_pc; + unsigned long long sc_regs[32]; + unsigned long long sc_fpregs[32]; + unsigned int sc_acx; /* Was sc_ownedfp */ + unsigned int sc_fpc_csr; + unsigned int sc_fpc_eir; /* Unused */ + unsigned int sc_used_math; + unsigned int sc_dsp; /* dsp status, was sc_ssflags */ + unsigned long long sc_mdhi; + unsigned long long sc_mdlo; + unsigned long sc_hi1; /* Was sc_cause */ + unsigned long sc_lo1; /* Was sc_badvaddr */ + unsigned long sc_hi2; /* Was sc_sigset[4] */ + unsigned long sc_lo2; + unsigned long sc_hi3; + unsigned long sc_lo3; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/mman.h +//---------------------------------------------------------------------- + +#define VKI_PROT_NONE 0x0 /* No page permissions */ +#define VKI_PROT_READ 0x1 /* page can be read */ +#define VKI_PROT_WRITE 0x2 /* page can be written */ +#define VKI_PROT_EXEC 0x4 /* page can be executed */ +#define VKI_PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define VKI_PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define VKI_MAP_SHARED 0x001 /* Share changes */ +#define VKI_MAP_PRIVATE 0x002 /* Changes are private */ +#define VKI_MAP_FIXED 0x010 /* Interpret addr exactly */ + +#define VKI_MAP_NORESERVE 0x0400 /* don't reserve swap pages */ + +/* These are linux-specific */ +#define VKI_MAP_NORESERVE 0x0400 /* don't check for reservations */ +#define VKI_MAP_ANONYMOUS 0x0800 /* don't use a file */ +#define VKI_MAP_GROWSDOWN 0x1000 /* stack-like segment */ +#define VKI_MAP_DENYWRITE 0x2000 /* ETXTBSY */ +#define VKI_MAP_EXECUTABLE 0x4000 /* mark it as an executable */ +#define VKI_MAP_LOCKED 0x8000 /* pages are locked */ +#define VKI_MAP_POPULATE 0x10000 /* populate (prefault) pagetables */ +#define VKI_MAP_NONBLOCK 0x20000 /* do not block on IO */ + + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/fcntl.h +//---------------------------------------------------------------------- + +#define VKI_O_RDONLY 00 +#define VKI_O_WRONLY 01 +#define VKI_O_RDWR 02 + +#define VKI_O_CREAT 0x0100 /* not fcntl */ +#define VKI_O_EXCL 0x0400 /* not fcntl */ + +#define VKI_O_TRUNC 0x0200 /* not fcntl */ + +#define VKI_O_APPEND 0x0008 +#define VKI_O_NONBLOCK 0x0080 +#define VKI_O_LARGEFILE 0x2000 + +#define VKI_AT_FDCWD -100 + +#define VKI_F_DUPFD 0 /* dup */ +#define VKI_F_GETFD 1 /* get close_on_exec */ +#define VKI_F_SETFD 2 /* set/clear close_on_exec */ +#define VKI_F_GETFL 3 /* get file->f_flags */ +#define VKI_F_SETFL 4 /* set file->f_flags */ + +#define VKI_F_GETLK 14 +#define VKI_F_SETLK 6 +#define VKI_F_SETLKW 7 + +#define VKI_F_SETOWN 24 /* for sockets. */ +#define VKI_F_GETOWN 23 /* for sockets. */ +#define VKI_F_SETSIG 10 /* for sockets. */ +#define VKI_F_GETSIG 11 /* for sockets. */ + +#define VKI_F_SETOWN_EX 15 +#define VKI_F_GETOWN_EX 16 + +#define VKI_F_GETLK64 33 /* using 'struct flock64' */ +#define VKI_F_SETLK64 34 +#define VKI_F_SETLKW64 35 + +/* for F_[GET|SET]FL */ +#define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */ + +#define VKI_F_LINUX_SPECIFIC_BASE 1024 + +struct vki_f_owner_ex { + int type; + __vki_kernel_pid_t pid; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/resource.h +//---------------------------------------------------------------------- + +#define VKI_RLIMIT_DATA 2 /* max data size */ +#define VKI_RLIMIT_STACK 3 /* max stack size */ +#define VKI_RLIMIT_CORE 4 /* max core file size */ +#define VKI_RLIMIT_NOFILE 5 /* max number of open files */ + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/socket.h +//---------------------------------------------------------------------- + +#define VKI_SOL_SOCKET 0xffff +#define VKI_SO_TYPE 0x1008 + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-i386/sockios.h +//---------------------------------------------------------------------- + +#define VKI_SIOCSPGRP 0x8902 +#define VKI_SIOCGPGRP 0x8904 +#define VKI_SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ +#define VKI_SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/stat.h +//---------------------------------------------------------------------- + +struct vki_stat { + unsigned st_dev; + long st_pad1[3]; /* Reserved for network id */ + unsigned long st_ino; + unsigned int st_mode; + unsigned long st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned st_rdev; + long st_pad2[2]; + long st_size; + long st_pad3; + /* + * Actually this should be timestruc_t st_atime, st_mtime and st_ctime + * but we don't have it under Linux. + */ + long st_atime; + long st_atime_nsec; + long st_mtime; + long st_mtime_nsec; + long st_ctime; + long st_ctime_nsec; + long st_blksize; + long st_blocks; + long st_pad4[14]; +}; + +/* + * This matches struct stat64 in glibc2.1, hence the absolutely insane + * amounts of padding around dev_t's. The memory layout is the same as of + * struct stat of the 64-bit kernel. + */ + +struct vki_stat64 { + unsigned long st_dev; + unsigned long st_pad0[3]; /* Reserved for st_dev expansion */ + + unsigned long long st_ino; + + unsigned int st_mode; + unsigned long st_nlink; + + unsigned int st_uid; + unsigned int st_gid; + + unsigned long st_rdev; + unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */ + + long long st_size; + + /* + * Actually this should be timestruc_t st_atime, st_mtime and st_ctime + * but we don't have it under Linux. + */ + long st_atime; + unsigned long st_atime_nsec; /* Reserved for st_atime expansion */ + + long st_mtime; + unsigned long st_mtime_nsec; /* Reserved for st_mtime expansion */ + + long st_ctime; + unsigned long st_ctime_nsec; /* Reserved for st_ctime expansion */ + + unsigned long st_blksize; + unsigned long st_pad2; + + long long st_blocks; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/statfs.h +//---------------------------------------------------------------------- + +struct vki_statfs { + long f_type; + long f_bsize; + long f_frsize; /* Fragment size - unsupported */ + long f_blocks; + long f_bfree; + long f_files; + long f_ffree; + long f_bavail; + + /* Linux specials */ + __vki_kernel_fsid_t f_fsid; + long f_namelen; + long f_spare[6]; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/termios.h +//---------------------------------------------------------------------- + +struct vki_winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; + unsigned short ws_ypixel; +}; + +#define NCC 8 +#define NCCS 23 +struct vki_termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + char c_line; /* line discipline */ + unsigned char c_cc[NCCS]; /* control characters */ +}; + + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/termbits.h +//---------------------------------------------------------------------- + +typedef unsigned char vki_cc_t; +typedef unsigned long vki_speed_t; +typedef unsigned long vki_tcflag_t; + +struct vki_termios { + vki_tcflag_t c_iflag; /* input mode flags */ + vki_tcflag_t c_oflag; /* output mode flags */ + vki_tcflag_t c_cflag; /* control mode flags */ + vki_tcflag_t c_lflag; /* local mode flags */ + vki_cc_t c_line; /* line discipline */ + vki_cc_t c_cc[NCCS]; /* control characters */ +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/ioctl.h +//---------------------------------------------------------------------- + +#define _VKI_IOC_NRBITS 8 +#define _VKI_IOC_TYPEBITS 8 +#define _VKI_IOC_SIZEBITS 14 +#define _VKI_IOC_DIRBITS 2 + +#define _VKI_IOC_NRMASK ((1 << _VKI_IOC_NRBITS)-1) +#define _VKI_IOC_TYPEMASK ((1 << _VKI_IOC_TYPEBITS)-1) +#define _VKI_IOC_SIZEMASK ((1 << _VKI_IOC_SIZEBITS)-1) +#define _VKI_IOC_DIRMASK ((1 << _VKI_IOC_DIRBITS)-1) + +#define _VKI_IOC_NRSHIFT 0 +#define _VKI_IOC_TYPESHIFT (_VKI_IOC_NRSHIFT+_VKI_IOC_NRBITS) +#define _VKI_IOC_SIZESHIFT (_VKI_IOC_TYPESHIFT+_VKI_IOC_TYPEBITS) +#define _VKI_IOC_DIRSHIFT (_VKI_IOC_SIZESHIFT+_VKI_IOC_SIZEBITS) + +#define _VKI_IOC_NONE 1U +#define _VKI_IOC_WRITE 2U +#define _VKI_IOC_READ 4U + +#define _VKI_IOC(dir,type,nr,size) \ + (((dir) << _VKI_IOC_DIRSHIFT) | \ + ((type) << _VKI_IOC_TYPESHIFT) | \ + ((nr) << _VKI_IOC_NRSHIFT) | \ + ((size) << _VKI_IOC_SIZESHIFT)) + +/* provoke compile error for invalid uses of size argument */ +extern unsigned int __VKI_invalid_size_argument_for_IOC; +/* used to create numbers */ +#define _VKI_IO(type,nr) _VKI_IOC(_VKI_IOC_NONE,(type),(nr),0) +#define _VKI_IOR(type,nr,size) _VKI_IOC(_VKI_IOC_READ,(type),(nr),(_VKI_IOC_TYPECHECK(size))) +#define _VKI_IOW(type,nr,size) _VKI_IOC(_VKI_IOC_WRITE,(type),(nr),(_VKI_IOC_TYPECHECK(size))) +#define _VKI_IOWR(type,nr,size) _VKI_IOC(_VKI_IOC_READ|_VKI_IOC_WRITE,(type),(nr),(_VKI_IOC_TYPECHECK(size))) + +/* used to decode ioctl numbers.. */ +#define _VKI_IOC_DIR(nr) (((nr) >> _VKI_IOC_DIRSHIFT) & _VKI_IOC_DIRMASK) +#define _VKI_IOC_TYPE(nr) (((nr) >> _VKI_IOC_TYPESHIFT) & _VKI_IOC_TYPEMASK) +#define _VKI_IOC_NR(nr) (((nr) >> _VKI_IOC_NRSHIFT) & _VKI_IOC_NRMASK) +#define _VKI_IOC_SIZE(nr) (((nr) >> _VKI_IOC_SIZESHIFT) & _VKI_IOC_SIZEMASK) + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/ioctls.h +//---------------------------------------------------------------------- + +#define VKI_TCGETA 0x5401 +#define VKI_TCSETA 0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */ +#define VKI_TCSETAW 0x5403 +#define VKI_TCSETAF 0x5404 + +#define VKI_TCSBRK 0x5405 +#define VKI_TCXONC 0x5406 +#define VKI_TCFLSH 0x5407 + +#define VKI_TCGETS 0x540d +#define VKI_TCSETS 0x540e +#define VKI_TCSETSW 0x540f +#define VKI_TCSETSF 0x5410 + +#define VKI_TIOCEXCL 0x740d /* set exclusive use of tty */ +#define VKI_TIOCNXCL 0x740e /* reset exclusive use of tty */ +#define VKI_TIOCOUTQ 0x7472 /* output queue size */ +#define VKI_TIOCSTI 0x5472 /* simulate terminal input */ +#define VKI_TIOCMGET 0x741d /* get all modem bits */ +#define VKI_TIOCMBIS 0x741b /* bis modem bits */ +#define VKI_TIOCMBIC 0x741c /* bic modem bits */ +#define VKI_TIOCMSET 0x741a /* set all modem bits */ +#define VKI_TIOCPKT 0x5470 /* pty: set/clear packet mode */ +#define VKI_TIOCPKT_DATA 0x00 /* data packet */ +#define VKI_TIOCPKT_FLUSHREAD 0x01 /* flush packet */ +#define VKI_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ +#define VKI_TIOCPKT_STOP 0x04 /* stop output */ +#define VKI_TIOCPKT_START 0x08 /* start output */ +#define VKI_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ +#define VKI_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ +/* #define TIOCPKT_IOCTL 0x40 state change of pty driver */ +#define VKI_TIOCSWINSZ _VKI_IOW('t', 103, struct vki_winsize) /* set window size */ +#define VKI_TIOCGWINSZ _VKI_IOR('t', 104, struct vki_winsize) /* get window size */ +#define VKI_TIOCNOTTY 0x5471 /* void tty association */ +#define VKI_TIOCSETD 0x7401 +#define VKI_TIOCGETD 0x7400 + +#define VKI_FIOCLEX 0x6601 +#define VKI_FIONCLEX 0x6602 +#define VKI_FIOASYNC 0x667d +#define VKI_FIONBIO 0x667e +#define VKI_FIOQSIZE 0x667f + +#define VKI_TIOCGLTC 0x7474 /* get special local chars */ +#define VKI_TIOCSLTC 0x7475 /* set special local chars */ +#define VKI_TIOCSPGRP _VKI_IOW('t', 118, int) /* set pgrp of tty */ +#define VKI_TIOCGPGRP _VKI_IOR('t', 119, int) /* get pgrp of tty */ +#define VKI_TIOCCONS _VKI_IOW('t', 120, int) /* become virtual console */ + +#define VKI_FIONREAD 0x467f +#define VKI_TIOCINQ FIONREAD + +#define VKI_TIOCGETP 0x7408 +#define VKI_TIOCSETP 0x7409 +#define VKI_TIOCSETN 0x740a /* TIOCSETP wo flush */ + +#define VKI_TIOCSBRK 0x5427 /* BSD compatibility */ +#define VKI_TIOCCBRK 0x5428 /* BSD compatibility */ +#define VKI_TIOCGSID 0x7416 /* Return the session ID of FD */ +#define VKI_TIOCGPTN _VKI_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define VKI_TIOCSPTLCK _VKI_IOW('T',0x31, int) /* Lock/unlock Pty */ + +/* I hope the range from 0x5480 on is free ... */ +#define VKI_TIOCSCTTY 0x5480 /* become controlling tty */ +#define VKI_TIOCGSOFTCAR 0x5481 +#define VKI_TIOCSSOFTCAR 0x5482 +#define VKI_TIOCLINUX 0x5483 +#define VKI_TIOCGSERIAL 0x5484 +#define VKI_TIOCSSERIAL 0x5485 +#define VKI_TCSBRKP 0x5486 /* Needed for POSIX tcsendbreak() */ +#define VKI_TIOCSERCONFIG 0x5488 +#define VKI_TIOCSERGWILD 0x5489 +#define VKI_TIOCSERSWILD 0x548a +#define VKI_TIOCGLCKTRMIOS 0x548b +#define VKI_TIOCSLCKTRMIOS 0x548c +#define VKI_TIOCSERGSTRUCT 0x548d /* For debugging only */ +#define VKI_TIOCSERGETLSR 0x548e /* Get line status register */ +#define VKI_TIOCSERGETMULTI 0x548f /* Get multiport config */ +#define VKI_TIOCSERSETMULTI 0x5490 /* Set multiport config */ +#define VKI_TIOCMIWAIT 0x5491 /* wait for a change on serial input line(s) */ +#define VKI_TIOCGICOUNT 0x5492 /* read serial port inline interrupt counts */ +#define VKI_TIOCGHAYESESP 0x5493 /* Get Hayes ESP configuration */ +#define VKI_TIOCSHAYESESP 0x5494 /* Set Hayes ESP configuration */ + +//---------------------------------------------------------------------- +// From asm-generic/poll.h +//---------------------------------------------------------------------- + +/* These are specified by iBCS2 */ +#define VKI_POLLIN 0x0001 + +struct vki_pollfd { + int fd; + short events; + short revents; +}; +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/elf.h +//---------------------------------------------------------------------- + +#define VKI_ELF_NGREG 45 /* includes nip, msr, lr, etc. */ +#define VKI_ELF_NFPREG 33 /* includes fpscr */ + +typedef unsigned long vki_elf_greg_t; +typedef vki_elf_greg_t vki_elf_gregset_t[VKI_ELF_NGREG]; + +typedef double vki_elf_fpreg_t; +typedef vki_elf_fpreg_t vki_elf_fpregset_t[VKI_ELF_NFPREG]; + +typedef struct vki_user_fxsr_struct vki_elf_fpxregset_t; + +#define VKI_AT_SYSINFO 32 +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/ucontext.h +//---------------------------------------------------------------------- + +struct vki_ucontext { + unsigned long uc_flags; + struct vki_ucontext *uc_link; + vki_stack_t uc_stack; + struct vki_sigcontext uc_mcontext; + vki_sigset_t uc_sigmask; /* mask last for extensibility */ +}; + +// CAB: TODO +typedef void vki_modify_ldt_t; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/ipcbuf.h +//---------------------------------------------------------------------- + +struct vki_ipc64_perm +{ + __vki_kernel_key_t key; + __vki_kernel_uid_t uid; + __vki_kernel_gid_t gid; + __vki_kernel_uid_t cuid; + __vki_kernel_gid_t cgid; + __vki_kernel_mode_t mode; + unsigned short seq; + unsigned short __pad1; + unsigned long __unused1; + unsigned long __unused2; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/sembuf.h +//---------------------------------------------------------------------- + +struct vki_semid64_ds { + struct vki_ipc64_perm sem_perm; /* permissions .. see ipc.h */ + __vki_kernel_time_t sem_otime; /* last semop time */ + __vki_kernel_time_t sem_ctime; /* last change time */ + unsigned long sem_nsems; /* no. of semaphores in array */ + unsigned long __unused1; + unsigned long __unused2; +}; + + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/msgbuf.h +//---------------------------------------------------------------------- + +struct vki_msqid64_ds { + struct vki_ipc64_perm msg_perm; + __vki_kernel_time_t msg_stime; /* last msgsnd time */ + unsigned long __unused1; + __vki_kernel_time_t msg_rtime; /* last msgrcv time */ + unsigned long __unused2; + __vki_kernel_time_t msg_ctime; /* last change time */ + unsigned long __unused3; + unsigned long msg_cbytes; /* current number of bytes on queue */ + unsigned long msg_qnum; /* number of messages in queue */ + unsigned long msg_qbytes; /* max number of bytes on queue */ + __vki_kernel_pid_t msg_lspid; /* pid of last msgsnd */ + __vki_kernel_pid_t msg_lrpid; /* last receive pid */ + unsigned long __unused4; + unsigned long __unused5; +}; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/ipc.h +//---------------------------------------------------------------------- + +struct vki_ipc_kludge { + struct vki_msgbuf __user *msgp; + long msgtyp; +}; + +#define VKI_SEMOP 1 +#define VKI_SEMGET 2 +#define VKI_SEMCTL 3 +#define VKI_SEMTIMEDOP 4 +#define VKI_MSGSND 11 +#define VKI_MSGRCV 12 +#define VKI_MSGGET 13 +#define VKI_MSGCTL 14 +#define VKI_SHMAT 21 +#define VKI_SHMDT 22 +#define VKI_SHMGET 23 +#define VKI_SHMCTL 24 + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/shmbuf.h +//---------------------------------------------------------------------- + +struct vki_shmid64_ds { + struct vki_ipc64_perm shm_perm; /* operation perms */ + vki_size_t shm_segsz; /* size of segment (bytes) */ + __vki_kernel_time_t shm_atime; /* last attach time */ + __vki_kernel_time_t shm_dtime; /* last detach time */ + __vki_kernel_time_t shm_ctime; /* last change time */ + __vki_kernel_pid_t shm_cpid; /* pid of creator */ + __vki_kernel_pid_t shm_lpid; /* pid of last operator */ + unsigned long shm_nattch; /* no. of current attaches */ + unsigned long __unused1; + unsigned long __unused2; +}; + +struct vki_shminfo64 { + unsigned long shmmax; + unsigned long shmmin; + unsigned long shmmni; + unsigned long shmseg; + unsigned long shmall; + unsigned long __unused1; + unsigned long __unused2; + unsigned long __unused3; + unsigned long __unused4; +}; +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/ptrace.h +//---------------------------------------------------------------------- + +struct vki_pt_regs { +#ifdef CONFIG_32BIT + /* Pad bytes for argument save space on the stack. */ + unsigned long pad0[6]; +#endif + /* Saved main processor registers. */ + unsigned long regs[32]; + + /* Saved special registers. */ + unsigned long cp0_status; + unsigned long hi; + unsigned long lo; +#ifdef CONFIG_CPU_HAS_SMARTMIPS + unsigned long acx; +#endif + unsigned long cp0_badvaddr; + unsigned long cp0_cause; + unsigned long cp0_epc; +#ifdef CONFIG_MIPS_MT_SMTC + unsigned long cp0_tcstatus; +#endif /* CONFIG_MIPS_MT_SMTC */ +#ifdef CONFIG_CPU_CAVIUM_OCTEON + unsigned long long mpl[3]; /* MTM{0,1,2} */ + unsigned long long mtp[3]; /* MTP{0,1,2} */ +#endif +} __attribute__ ((aligned (8))); + + +#define vki_user_regs_struct vki_pt_regs + +#define MIPS_lo lo +#define MIPS_hi hi +//#define MIPS_pc regs[32] +#define MIPS_r31 regs[31] +#define MIPS_r30 regs[30] +#define MIPS_r29 regs[29] +#define MIPS_r28 regs[28] +#define MIPS_r27 regs[27] +#define MIPS_r26 regs[26] +#define MIPS_r25 regs[25] +#define MIPS_r24 regs[24] +#define MIPS_r23 regs[23] +#define MIPS_r22 regs[22] +#define MIPS_r21 regs[21] +#define MIPS_r20 regs[20] +#define MIPS_r19 regs[19] +#define MIPS_r18 regs[18] +#define MIPS_r17 regs[17] +#define MIPS_r16 regs[16] +#define MIPS_r15 regs[15] +#define MIPS_r14 regs[14] +#define MIPS_r13 regs[13] +#define MIPS_r12 regs[12] +#define MIPS_r11 regs[11] +#define MIPS_r10 regs[10] +#define MIPS_r9 regs[9] +#define MIPS_r8 regs[8] +#define MIPS_r7 regs[7] +#define MIPS_r6 regs[6] +#define MIPS_r5 regs[5] +#define MIPS_r4 regs[4] +#define MIPS_r3 regs[3] +#define MIPS_r2 regs[2] +#define MIPS_r1 regs[1] +#define MIPS_r0 regs[0] + +#define VKI_PTRACE_GETREGS 12 +#define VKI_PTRACE_SETREGS 13 +#define VKI_PTRACE_GETFPREGS 14 +#define VKI_PTRACE_SETFPREGS 15 +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-generic/siginfo.h +//---------------------------------------------------------------------- +#define HAVE_ARCH_SIGINFO_T + +typedef union vki_sigval { + int sival_int; + void __user *sival_ptr; +} vki_sigval_t; + +#ifndef __VKI_ARCH_SI_PREAMBLE_SIZE +#define __VKI_ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int)) +#endif + +#define VKI_SI_MAX_SIZE 128 + +#ifndef VKI_SI_PAD_SIZE +#define VKI_SI_PAD_SIZE ((VKI_SI_MAX_SIZE - __VKI_ARCH_SI_PREAMBLE_SIZE) / sizeof(int)) +#endif + +#ifndef __VKI_ARCH_SI_UID_T +#define __VKI_ARCH_SI_UID_T vki_uid_t +#endif + +#ifndef __VKI_ARCH_SI_BAND_T +#define __VKI_ARCH_SI_BAND_T long +#endif + +typedef struct vki_siginfo { + int si_signo; + int si_code; + int si_errno; + int __pad0[VKI_SI_MAX_SIZE / sizeof(int) - VKI_SI_PAD_SIZE - 3]; + + union { + int _pad[VKI_SI_PAD_SIZE]; + + /* kill() */ + struct { + vki_pid_t _pid; /* sender's pid */ + __VKI_ARCH_SI_UID_T _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + vki_timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __VKI_ARCH_SI_UID_T) - sizeof(int)]; + vki_sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + vki_pid_t _pid; /* sender's pid */ + __VKI_ARCH_SI_UID_T _uid; /* sender's uid */ + vki_sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + vki_pid_t _pid; /* which child */ + __VKI_ARCH_SI_UID_T _uid; /* sender's uid */ + int _status; /* exit code */ + vki_clock_t _utime; + vki_clock_t _stime; + } _sigchld; + + /* IRIX SIGCHLD */ + struct { + vki_pid_t _pid; /* which child */ + vki_clock_t _utime; + int _status; /* exit code */ + vki_clock_t _stime; + } _irix_sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void __user *_addr; /* faulting insn/memory ref. */ +#ifdef __ARCH_SI_TRAPNO + int _trapno; /* TRAP # which caused the signal */ +#endif + } _sigfault; + + /* SIGPOLL, SIGXFSZ (To do ...) */ + struct { + __VKI_ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} vki_siginfo_t; + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm/break.h +//---------------------------------------------------------------------- +#define VKI_BRK_OVERFLOW 6 /* Overflow check */ +#define VKI_BRK_DIVZERO 7 /* Divide by zero check */ + +#endif // __VKI_MIPS32_LINUX_H + + +/*--------------------------------------------------------------------*/ +/*--- end vki-mips32-linux.h ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-posixtypes-mips32-linux.h b/include/vki/vki-posixtypes-mips32-linux.h new file mode 100644 index 0000000000..45d3ebfe94 --- /dev/null +++ b/include/vki/vki-posixtypes-mips32-linux.h @@ -0,0 +1,68 @@ + +/*--------------------------------------------------------------------*/ +/*--- mips/Linux-specific kernel interface: posix types. ---*/ +/*--- vki-posixtypes-mips32-linux.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __VKI_POSIXTYPES_MIPS32_LINUX_H +#define __VKI_POSIXTYPES_MIPS32_LINUX_H + +//---------------------------------------------------------------------- +// From linux-2.6.35.5/include/asm-mips/posix_types.h +//---------------------------------------------------------------------- + +typedef unsigned int __vki_kernel_mode_t; +typedef long __vki_kernel_off_t; +typedef int __vki_kernel_pid_t; +typedef int __vki_kernel_ipc_pid_t; +typedef unsigned int __vki_kernel_uid_t; +typedef unsigned int __vki_kernel_gid_t; +typedef unsigned int __vki_kernel_size_t; +typedef long __vki_kernel_time_t; +typedef long __vki_kernel_suseconds_t; +typedef long __vki_kernel_clock_t; +typedef int __vki_kernel_timer_t; +typedef int __vki_kernel_clockid_t; +typedef char * __vki_kernel_caddr_t; +typedef unsigned int __vki_kernel_uid32_t; +typedef unsigned int __vki_kernel_gid32_t; + +typedef unsigned int __vki_kernel_old_uid_t; +typedef unsigned int __vki_kernel_old_gid_t; + +typedef long long __vki_kernel_loff_t; + +typedef struct { + int val[2]; +} __vki_kernel_fsid_t; + +#endif // __VKI_POSIXTYPES_MIPS32_LINUX_H + +/*--------------------------------------------------------------------*/ +/*--- end vki-posixtypes-mips32-linux.h ---*/ +/*--------------------------------------------------------------------*/ diff --git a/include/vki/vki-scnums-mips32-linux.h b/include/vki/vki-scnums-mips32-linux.h new file mode 100644 index 0000000000..49c24a1a71 --- /dev/null +++ b/include/vki/vki-scnums-mips32-linux.h @@ -0,0 +1,390 @@ + +/*--------------------------------------------------------------------*/ +/*--- System call numbers for mips32-linux. ---*/ +/*--- vki-scnums-mips32-linux.h ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2010-2012 RT-RK + mips-valgrind@rt-rk.com + + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +#ifndef __VKI_SCNUMS_MIPS32_LINUX_H +#define __VKI_SCNUMS_MIPS32_LINUX_H + +// From linux-2.6.35.5/include/asm-mips/unistd.h +/* + * Linux o32 style syscalls are in the range from 4000 to 4999. + */ +#define __NR_Linux 4000 +#define __NR_syscall (__NR_Linux + 0) +#define __NR_exit (__NR_Linux + 1) +#define __NR_fork (__NR_Linux + 2) +#define __NR_read (__NR_Linux + 3) +#define __NR_write (__NR_Linux + 4) +#define __NR_open (__NR_Linux + 5) +#define __NR_close (__NR_Linux + 6) +#define __NR_waitpid (__NR_Linux + 7) +#define __NR_creat (__NR_Linux + 8) +#define __NR_link (__NR_Linux + 9) +#define __NR_unlink (__NR_Linux + 10) +#define __NR_execve (__NR_Linux + 11) +#define __NR_chdir (__NR_Linux + 12) +#define __NR_time (__NR_Linux + 13) +#define __NR_mknod (__NR_Linux + 14) +#define __NR_chmod (__NR_Linux + 15) +#define __NR_lchown (__NR_Linux + 16) +#define __NR_break (__NR_Linux + 17) +#define __NR_unused18 (__NR_Linux + 18) +#define __NR_lseek (__NR_Linux + 19) +#define __NR_getpid (__NR_Linux + 20) +#define __NR_mount (__NR_Linux + 21) +#define __NR_umount (__NR_Linux + 22) +#define __NR_setuid (__NR_Linux + 23) +#define __NR_getuid (__NR_Linux + 24) +#define __NR_stime (__NR_Linux + 25) +#define __NR_ptrace (__NR_Linux + 26) +#define __NR_alarm (__NR_Linux + 27) +#define __NR_unused28 (__NR_Linux + 28) +#define __NR_pause (__NR_Linux + 29) +#define __NR_utime (__NR_Linux + 30) +#define __NR_stty (__NR_Linux + 31) +#define __NR_gtty (__NR_Linux + 32) +#define __NR_access (__NR_Linux + 33) +#define __NR_nice (__NR_Linux + 34) +#define __NR_ftime (__NR_Linux + 35) +#define __NR_sync (__NR_Linux + 36) +#define __NR_kill (__NR_Linux + 37) +#define __NR_rename (__NR_Linux + 38) +#define __NR_mkdir (__NR_Linux + 39) +#define __NR_rmdir (__NR_Linux + 40) +#define __NR_dup (__NR_Linux + 41) +#define __NR_pipe (__NR_Linux + 42) +#define __NR_times (__NR_Linux + 43) +#define __NR_prof (__NR_Linux + 44) +#define __NR_brk (__NR_Linux + 45) +#define __NR_setgid (__NR_Linux + 46) +#define __NR_getgid (__NR_Linux + 47) +#define __NR_signal (__NR_Linux + 48) +#define __NR_geteuid (__NR_Linux + 49) +#define __NR_getegid (__NR_Linux + 50) +#define __NR_acct (__NR_Linux + 51) +#define __NR_umount2 (__NR_Linux + 52) +#define __NR_lock (__NR_Linux + 53) +#define __NR_ioctl (__NR_Linux + 54) +#define __NR_fcntl (__NR_Linux + 55) +#define __NR_mpx (__NR_Linux + 56) +#define __NR_setpgid (__NR_Linux + 57) +#define __NR_ulimit (__NR_Linux + 58) +#define __NR_unused59 (__NR_Linux + 59) +#define __NR_umask (__NR_Linux + 60) +#define __NR_chroot (__NR_Linux + 61) +#define __NR_ustat (__NR_Linux + 62) +#define __NR_dup2 (__NR_Linux + 63) +#define __NR_getppid (__NR_Linux + 64) +#define __NR_getpgrp (__NR_Linux + 65) +#define __NR_setsid (__NR_Linux + 66) +#define __NR_sigaction (__NR_Linux + 67) +#define __NR_sgetmask (__NR_Linux + 68) +#define __NR_ssetmask (__NR_Linux + 69) +#define __NR_setreuid (__NR_Linux + 70) +#define __NR_setregid (__NR_Linux + 71) +#define __NR_sigsuspend (__NR_Linux + 72) +#define __NR_sigpending (__NR_Linux + 73) +#define __NR_sethostname (__NR_Linux + 74) +#define __NR_setrlimit (__NR_Linux + 75) +#define __NR_getrlimit (__NR_Linux + 76) +#define __NR_getrusage (__NR_Linux + 77) +#define __NR_gettimeofday (__NR_Linux + 78) +#define __NR_settimeofday (__NR_Linux + 79) +#define __NR_getgroups (__NR_Linux + 80) +#define __NR_setgroups (__NR_Linux + 81) +#define __NR_reserved82 (__NR_Linux + 82) +#define __NR_symlink (__NR_Linux + 83) +#define __NR_unused84 (__NR_Linux + 84) +#define __NR_readlink (__NR_Linux + 85) +#define __NR_uselib (__NR_Linux + 86) +#define __NR_swapon (__NR_Linux + 87) +#define __NR_reboot (__NR_Linux + 88) +#define __NR_readdir (__NR_Linux + 89) +#define __NR_mmap (__NR_Linux + 90) +#define __NR_munmap (__NR_Linux + 91) +#define __NR_truncate (__NR_Linux + 92) +#define __NR_ftruncate (__NR_Linux + 93) +#define __NR_fchmod (__NR_Linux + 94) +#define __NR_fchown (__NR_Linux + 95) +#define __NR_getpriority (__NR_Linux + 96) +#define __NR_setpriority (__NR_Linux + 97) +#define __NR_profil (__NR_Linux + 98) +#define __NR_statfs (__NR_Linux + 99) +#define __NR_fstatfs (__NR_Linux + 100) +#define __NR_ioperm (__NR_Linux + 101) +#define __NR_socketcall (__NR_Linux + 102) +#define __NR_syslog (__NR_Linux + 103) +#define __NR_setitimer (__NR_Linux + 104) +#define __NR_getitimer (__NR_Linux + 105) +#define __NR_stat (__NR_Linux + 106) +#define __NR_lstat (__NR_Linux + 107) +#define __NR_fstat (__NR_Linux + 108) +#define __NR_unused109 (__NR_Linux + 109) +#define __NR_iopl (__NR_Linux + 110) +#define __NR_vhangup (__NR_Linux + 111) +#define __NR_idle (__NR_Linux + 112) +#define __NR_vm86 (__NR_Linux + 113) +#define __NR_wait4 (__NR_Linux + 114) +#define __NR_swapoff (__NR_Linux + 115) +#define __NR_sysinfo (__NR_Linux + 116) +#define __NR_ipc (__NR_Linux + 117) +#define __NR_fsync (__NR_Linux + 118) +#define __NR_sigreturn (__NR_Linux + 119) +#define __NR_clone (__NR_Linux + 120) +#define __NR_setdomainname (__NR_Linux + 121) +#define __NR_uname (__NR_Linux + 122) +#define __NR_modify_ldt (__NR_Linux + 123) +#define __NR_adjtimex (__NR_Linux + 124) +#define __NR_mprotect (__NR_Linux + 125) +#define __NR_sigprocmask (__NR_Linux + 126) +#define __NR_create_module (__NR_Linux + 127) +#define __NR_init_module (__NR_Linux + 128) +#define __NR_delete_module (__NR_Linux + 129) +#define __NR_get_kernel_syms (__NR_Linux + 130) +#define __NR_quotactl (__NR_Linux + 131) +#define __NR_getpgid (__NR_Linux + 132) +#define __NR_fchdir (__NR_Linux + 133) +#define __NR_bdflush (__NR_Linux + 134) +#define __NR_sysfs (__NR_Linux + 135) +#define __NR_personality (__NR_Linux + 136) +#define __NR_afs_syscall (__NR_Linux + 137) +#define __NR_setfsuid (__NR_Linux + 138) +#define __NR_setfsgid (__NR_Linux + 139) +#define __NR__llseek (__NR_Linux + 140) +#define __NR_getdents (__NR_Linux + 141) +#define __NR__newselect (__NR_Linux + 142) +#define __NR_flock (__NR_Linux + 143) +#define __NR_msync (__NR_Linux + 144) +#define __NR_readv (__NR_Linux + 145) +#define __NR_writev (__NR_Linux + 146) +#define __NR_cacheflush (__NR_Linux + 147) +#define __NR_cachectl (__NR_Linux + 148) +#define __NR_sysmips (__NR_Linux + 149) +#define __NR_unused150 (__NR_Linux + 150) +#define __NR_getsid (__NR_Linux + 151) +#define __NR_fdatasync (__NR_Linux + 152) +#define __NR__sysctl (__NR_Linux + 153) +#define __NR_mlock (__NR_Linux + 154) +#define __NR_munlock (__NR_Linux + 155) +#define __NR_mlockall (__NR_Linux + 156) +#define __NR_munlockall (__NR_Linux + 157) +#define __NR_sched_setparam (__NR_Linux + 158) +#define __NR_sched_getparam (__NR_Linux + 159) +#define __NR_sched_setscheduler (__NR_Linux + 160) +#define __NR_sched_getscheduler (__NR_Linux + 161) +#define __NR_sched_yield (__NR_Linux + 162) +#define __NR_sched_get_priority_max (__NR_Linux + 163) +#define __NR_sched_get_priority_min (__NR_Linux + 164) +#define __NR_sched_rr_get_interval (__NR_Linux + 165) +#define __NR_nanosleep (__NR_Linux + 166) +#define __NR_mremap (__NR_Linux + 167) +#define __NR_accept (__NR_Linux + 168) +#define __NR_bind (__NR_Linux + 169) +#define __NR_connect (__NR_Linux + 170) +#define __NR_getpeername (__NR_Linux + 171) +#define __NR_getsockname (__NR_Linux + 172) +#define __NR_getsockopt (__NR_Linux + 173) +#define __NR_listen (__NR_Linux + 174) +#define __NR_recv (__NR_Linux + 175) +#define __NR_recvfrom (__NR_Linux + 176) +#define __NR_recvmsg (__NR_Linux + 177) +#define __NR_send (__NR_Linux + 178) +#define __NR_sendmsg (__NR_Linux + 179) +#define __NR_sendto (__NR_Linux + 180) +#define __NR_setsockopt (__NR_Linux + 181) +#define __NR_shutdown (__NR_Linux + 182) +#define __NR_socket (__NR_Linux + 183) +#define __NR_socketpair (__NR_Linux + 184) +#define __NR_setresuid (__NR_Linux + 185) +#define __NR_getresuid (__NR_Linux + 186) +#define __NR_query_module (__NR_Linux + 187) +#define __NR_poll (__NR_Linux + 188) +#define __NR_nfsservctl (__NR_Linux + 189) +#define __NR_setresgid (__NR_Linux + 190) +#define __NR_getresgid (__NR_Linux + 191) +#define __NR_prctl (__NR_Linux + 192) +#define __NR_rt_sigreturn (__NR_Linux + 193) +#define __NR_rt_sigaction (__NR_Linux + 194) +#define __NR_rt_sigprocmask (__NR_Linux + 195) +#define __NR_rt_sigpending (__NR_Linux + 196) +#define __NR_rt_sigtimedwait (__NR_Linux + 197) +#define __NR_rt_sigqueueinfo (__NR_Linux + 198) +#define __NR_rt_sigsuspend (__NR_Linux + 199) +#define __NR_pread64 (__NR_Linux + 200) +#define __NR_pwrite64 (__NR_Linux + 201) +#define __NR_chown (__NR_Linux + 202) +#define __NR_getcwd (__NR_Linux + 203) +#define __NR_capget (__NR_Linux + 204) +#define __NR_capset (__NR_Linux + 205) +#define __NR_sigaltstack (__NR_Linux + 206) +#define __NR_sendfile (__NR_Linux + 207) +#define __NR_getpmsg (__NR_Linux + 208) +#define __NR_putpmsg (__NR_Linux + 209) +#define __NR_mmap2 (__NR_Linux + 210) +#define __NR_truncate64 (__NR_Linux + 211) +#define __NR_ftruncate64 (__NR_Linux + 212) +#define __NR_stat64 (__NR_Linux + 213) +#define __NR_lstat64 (__NR_Linux + 214) +#define __NR_fstat64 (__NR_Linux + 215) +#define __NR_pivot_root (__NR_Linux + 216) +#define __NR_mincore (__NR_Linux + 217) +#define __NR_madvise (__NR_Linux + 218) +#define __NR_getdents64 (__NR_Linux + 219) +#define __NR_fcntl64 (__NR_Linux + 220) +#define __NR_reserved221 (__NR_Linux + 221) +#define __NR_gettid (__NR_Linux + 222) +#define __NR_readahead (__NR_Linux + 223) +#define __NR_setxattr (__NR_Linux + 224) +#define __NR_lsetxattr (__NR_Linux + 225) +#define __NR_fsetxattr (__NR_Linux + 226) +#define __NR_getxattr (__NR_Linux + 227) +#define __NR_lgetxattr (__NR_Linux + 228) +#define __NR_fgetxattr (__NR_Linux + 229) +#define __NR_listxattr (__NR_Linux + 230) +#define __NR_llistxattr (__NR_Linux + 231) +#define __NR_flistxattr (__NR_Linux + 232) +#define __NR_removexattr (__NR_Linux + 233) +#define __NR_lremovexattr (__NR_Linux + 234) +#define __NR_fremovexattr (__NR_Linux + 235) +#define __NR_tkill (__NR_Linux + 236) +#define __NR_sendfile64 (__NR_Linux + 237) +#define __NR_futex (__NR_Linux + 238) +#define __NR_sched_setaffinity (__NR_Linux + 239) +#define __NR_sched_getaffinity (__NR_Linux + 240) +#define __NR_io_setup (__NR_Linux + 241) +#define __NR_io_destroy (__NR_Linux + 242) +#define __NR_io_getevents (__NR_Linux + 243) +#define __NR_io_submit (__NR_Linux + 244) +#define __NR_io_cancel (__NR_Linux + 245) +#define __NR_exit_group (__NR_Linux + 246) +#define __NR_lookup_dcookie (__NR_Linux + 247) +#define __NR_epoll_create (__NR_Linux + 248) +#define __NR_epoll_ctl (__NR_Linux + 249) +#define __NR_epoll_wait (__NR_Linux + 250) +#define __NR_remap_file_pages (__NR_Linux + 251) +#define __NR_set_tid_address (__NR_Linux + 252) +#define __NR_restart_syscall (__NR_Linux + 253) +#define __NR_fadvise64 (__NR_Linux + 254) +#define __NR_statfs64 (__NR_Linux + 255) +#define __NR_fstatfs64 (__NR_Linux + 256) +#define __NR_timer_create (__NR_Linux + 257) +#define __NR_timer_settime (__NR_Linux + 258) +#define __NR_timer_gettime (__NR_Linux + 259) +#define __NR_timer_getoverrun (__NR_Linux + 260) +#define __NR_timer_delete (__NR_Linux + 261) +#define __NR_clock_settime (__NR_Linux + 262) +#define __NR_clock_gettime (__NR_Linux + 263) +#define __NR_clock_getres (__NR_Linux + 264) +#define __NR_clock_nanosleep (__NR_Linux + 265) +#define __NR_tgkill (__NR_Linux + 266) +#define __NR_utimes (__NR_Linux + 267) +#define __NR_mbind (__NR_Linux + 268) +#define __NR_get_mempolicy (__NR_Linux + 269) +#define __NR_set_mempolicy (__NR_Linux + 270) +#define __NR_mq_open (__NR_Linux + 271) +#define __NR_mq_unlink (__NR_Linux + 272) +#define __NR_mq_timedsend (__NR_Linux + 273) +#define __NR_mq_timedreceive (__NR_Linux + 274) +#define __NR_mq_notify (__NR_Linux + 275) +#define __NR_mq_getsetattr (__NR_Linux + 276) +#define __NR_vserver (__NR_Linux + 277) +#define __NR_waitid (__NR_Linux + 278) +/* #define __NR_sys_setaltroot (__NR_Linux + 279) */ +#define __NR_add_key (__NR_Linux + 280) +#define __NR_request_key (__NR_Linux + 281) +#define __NR_keyctl (__NR_Linux + 282) +#define __NR_set_thread_area (__NR_Linux + 283) +#define __NR_inotify_init (__NR_Linux + 284) +#define __NR_inotify_add_watch (__NR_Linux + 285) +#define __NR_inotify_rm_watch (__NR_Linux + 286) +#define __NR_migrate_pages (__NR_Linux + 287) +#define __NR_openat (__NR_Linux + 288) +#define __NR_mkdirat (__NR_Linux + 289) +#define __NR_mknodat (__NR_Linux + 290) +#define __NR_fchownat (__NR_Linux + 291) +#define __NR_futimesat (__NR_Linux + 292) +#define __NR_fstatat64 (__NR_Linux + 293) +#define __NR_unlinkat (__NR_Linux + 294) +#define __NR_renameat (__NR_Linux + 295) +#define __NR_linkat (__NR_Linux + 296) +#define __NR_symlinkat (__NR_Linux + 297) +#define __NR_readlinkat (__NR_Linux + 298) +#define __NR_fchmodat (__NR_Linux + 299) +#define __NR_faccessat (__NR_Linux + 300) +#define __NR_pselect6 (__NR_Linux + 301) +#define __NR_ppoll (__NR_Linux + 302) +#define __NR_unshare (__NR_Linux + 303) +#define __NR_splice (__NR_Linux + 304) +#define __NR_sync_file_range (__NR_Linux + 305) +#define __NR_tee (__NR_Linux + 306) +#define __NR_vmsplice (__NR_Linux + 307) +#define __NR_move_pages (__NR_Linux + 308) +#define __NR_set_robust_list (__NR_Linux + 309) +#define __NR_get_robust_list (__NR_Linux + 310) +#define __NR_kexec_load (__NR_Linux + 311) +#define __NR_getcpu (__NR_Linux + 312) +#define __NR_epoll_pwait (__NR_Linux + 313) +#define __NR_ioprio_set (__NR_Linux + 314) +#define __NR_ioprio_get (__NR_Linux + 315) +#define __NR_utimensat (__NR_Linux + 316) +#define __NR_signalfd (__NR_Linux + 317) +#define __NR_timerfd (__NR_Linux + 318) +#define __NR_eventfd (__NR_Linux + 319) +#define __NR_fallocate (__NR_Linux + 320) +#define __NR_timerfd_create (__NR_Linux + 321) +#define __NR_timerfd_gettime (__NR_Linux + 322) +#define __NR_timerfd_settime (__NR_Linux + 323) +#define __NR_signalfd4 (__NR_Linux + 324) +#define __NR_eventfd2 (__NR_Linux + 325) +#define __NR_epoll_create1 (__NR_Linux + 326) +#define __NR_dup3 (__NR_Linux + 327) +#define __NR_pipe2 (__NR_Linux + 328) +#define __NR_inotify_init1 (__NR_Linux + 329) +#define __NR_preadv (__NR_Linux + 330) +#define __NR_pwritev (__NR_Linux + 331) +#define __NR_rt_tgsigqueueinfo (__NR_Linux + 332) +#define __NR_perf_event_open (__NR_Linux + 333) +#define __NR_accept4 (__NR_Linux + 334) + +/* + * Offset of the last Linux o32 flavoured syscall + */ +#define __NR_Linux_syscalls 334 + + +#define __NR_O32_Linux 4000 +#define __NR_O32_Linux_syscalls 334 + + +#endif /* __VKI_SCNUMS_MIPS32_LINUX_H */ + +/*--------------------------------------------------------------------*/ +/*--- end vki-scnums-mips32-linux.h ---*/ +/*--------------------------------------------------------------------*/