blob: 627f5f0d0da84653cbedfdfb982c26952d0d7839 [file] [log] [blame]
njn9abd6082005-06-17 21:31:45 +00001
2/*--------------------------------------------------------------------*/
3/*--- Doing syscalls. m_syscall.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardj4d474d02008-02-11 11:34:59 +000010 Copyright (C) 2000-2008 Julian Seward
njn9abd6082005-06-17 21:31:45 +000011 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
sewardj17edf032006-10-17 01:53:34 +000033#include "pub_core_vkiscnums.h"
njn9abd6082005-06-17 21:31:45 +000034#include "pub_core_syscall.h"
35
36/* ---------------------------------------------------------------------
37 Building syscall return values.
38 ------------------------------------------------------------------ */
39
40/* Make a SysRes value from an syscall return value. This is
41 Linux-specific.
42
43 From:
44 http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/sysdeps/unix/sysv/
45 linux/i386/sysdep.h?
46 rev=1.28&content-type=text/x-cvsweb-markup&cvsroot=glibc
47
48 Linux uses a negative return value to indicate syscall errors,
49 unlike most Unices, which use the condition codes' carry flag.
50
51 Since version 2.1 the return value of a system call might be
52 negative even if the call succeeded. E.g., the 'lseek' system call
53 might return a large offset. Therefore we must not anymore test
54 for < 0, but test for a real error by making sure the value in %eax
55 is a real error number. Linus said he will make sure the no
56 syscall returns a value in -1 .. -4095 as a valid result so we can
57 safely test with -4095.
58*/
sewardj2c48c7b2005-11-29 13:05:56 +000059SysRes VG_(mk_SysRes_x86_linux) ( UInt val ) {
njn9abd6082005-06-17 21:31:45 +000060 SysRes res;
njn9abd6082005-06-17 21:31:45 +000061 res.isError = val >= -4095 && val <= -1;
sewardj17edf032006-10-17 01:53:34 +000062 if (res.isError) {
63 res.err = -val;
64 res.res = 0;
65 } else {
66 res.err = 0;
67 res.res = val;
68 }
njn9abd6082005-06-17 21:31:45 +000069 return res;
70}
71
cerion85665ca2005-06-20 15:51:07 +000072/* Similarly .. */
sewardj2c48c7b2005-11-29 13:05:56 +000073SysRes VG_(mk_SysRes_amd64_linux) ( ULong val ) {
cerion85665ca2005-06-20 15:51:07 +000074 SysRes res;
75 res.isError = val >= -4095 && val <= -1;
sewardj17edf032006-10-17 01:53:34 +000076 if (res.isError) {
77 res.err = -val;
78 res.res = 0;
79 } else {
80 res.err = 0;
81 res.res = val;
82 }
cerion85665ca2005-06-20 15:51:07 +000083 return res;
84}
85
sewardj17edf032006-10-17 01:53:34 +000086/* PPC uses the CR7.SO bit to flag an error (CR0 in IBM-speak) */
sewardj39a7c1d2005-11-24 03:54:38 +000087/* Note this must be in the bottom bit of the second arg */
88SysRes VG_(mk_SysRes_ppc32_linux) ( UInt val, UInt cr0so ) {
cerion85665ca2005-06-20 15:51:07 +000089 SysRes res;
sewardj39a7c1d2005-11-24 03:54:38 +000090 res.isError = (cr0so & 1) != 0;
sewardj17edf032006-10-17 01:53:34 +000091 if (res.isError) {
92 res.err = val;
93 res.res = 0;
94 } else {
95 res.err = 0;
96 res.res = val;
97 }
cerion85665ca2005-06-20 15:51:07 +000098 return res;
99}
100
sewardj38a88b72006-01-02 16:32:10 +0000101/* As per ppc32 version, cr0.so must be in l.s.b. of 2nd arg */
102SysRes VG_(mk_SysRes_ppc64_linux) ( ULong val, ULong cr0so ) {
sewardj2c48c7b2005-11-29 13:05:56 +0000103 SysRes res;
sewardj38a88b72006-01-02 16:32:10 +0000104 res.isError = (cr0so & 1) != 0;
sewardj17edf032006-10-17 01:53:34 +0000105 if (res.isError) {
106 res.err = val;
107 res.res = 0;
108 } else {
109 res.err = 0;
110 res.res = val;
111 }
sewardj2c48c7b2005-11-29 13:05:56 +0000112 return res;
113}
114
sewardj17edf032006-10-17 01:53:34 +0000115/* AIX scheme: we have to record both 'res' (r3) and 'err' (r4). If
116 'err' is nonzero then the call has failed, but it could still be
117 that AIX userspace will ignore 'err' and instead consult 'res' to
118 determine if the call failed. So we have to record both. */
119SysRes VG_(mk_SysRes_ppc32_aix5) ( UInt res, UInt err ) {
120 SysRes r;
121 r.res = res;
122 r.err = err;
123 r.isError = r.err != 0;
njn9abd6082005-06-17 21:31:45 +0000124 return r;
125}
126
sewardj17edf032006-10-17 01:53:34 +0000127SysRes VG_(mk_SysRes_ppc64_aix5) ( ULong res, ULong err ) {
128 SysRes r;
129 r.res = res;
130 r.err = err;
131 r.isError = r.err != 0;
132 return r;
133}
134
135/* Generic constructors. */
136SysRes VG_(mk_SysRes_Error) ( UWord err ) {
137 SysRes r;
138 r.res = 0;
139 r.err = err;
140 r.isError = True;
141 return r;
142}
143
144SysRes VG_(mk_SysRes_Success) ( UWord res ) {
145 SysRes r;
146 r.res = res;
147 r.err = 0;
148 r.isError = False;
njn9abd6082005-06-17 21:31:45 +0000149 return r;
150}
151
152
153/* ---------------------------------------------------------------------
154 A function for doing syscalls.
155 ------------------------------------------------------------------ */
156
njn9abd6082005-06-17 21:31:45 +0000157#if defined(VGP_x86_linux)
158/* Incoming args (syscall number + up to 6 args) come on the stack.
159 (ie. the C calling convention).
160
161 The syscall number goes in %eax. The args are passed to the syscall in
162 the regs %ebx, %ecx, %edx, %esi, %edi, %ebp, ie. the kernel's syscall
163 calling convention.
164
165 %eax gets the return value. Not sure which registers the kernel
166 clobbers, so we preserve all the callee-save regs (%esi, %edi, %ebx,
167 %ebp).
168*/
sewardj03d8aa82005-10-14 11:25:49 +0000169extern UWord do_syscall_WRK (
cerion85665ca2005-06-20 15:51:07 +0000170 UWord syscall_no,
171 UWord a1, UWord a2, UWord a3,
172 UWord a4, UWord a5, UWord a6
173 );
njn9abd6082005-06-17 21:31:45 +0000174asm(
sewardjd9fc3822005-11-18 23:50:43 +0000175".text\n"
njn9abd6082005-06-17 21:31:45 +0000176"do_syscall_WRK:\n"
177" push %esi\n"
178" push %edi\n"
179" push %ebx\n"
180" push %ebp\n"
181" movl 16+ 4(%esp),%eax\n"
182" movl 16+ 8(%esp),%ebx\n"
183" movl 16+12(%esp),%ecx\n"
184" movl 16+16(%esp),%edx\n"
185" movl 16+20(%esp),%esi\n"
186" movl 16+24(%esp),%edi\n"
187" movl 16+28(%esp),%ebp\n"
188" int $0x80\n"
189" popl %ebp\n"
190" popl %ebx\n"
191" popl %edi\n"
192" popl %esi\n"
193" ret\n"
sewardj2fedc642005-11-19 02:02:57 +0000194".previous\n"
njn9abd6082005-06-17 21:31:45 +0000195);
sewardj2c48c7b2005-11-29 13:05:56 +0000196
njn9abd6082005-06-17 21:31:45 +0000197#elif defined(VGP_amd64_linux)
198/* Incoming args (syscall number + up to 6 args) come in %rdi, %rsi,
199 %rdx, %rcx, %r8, %r9, and the last one on the stack (ie. the C
200 calling convention).
201
202 The syscall number goes in %rax. The args are passed to the syscall in
203 the regs %rdi, %rsi, %rdx, %r10, %r8, %r9 (yes, really %r10, not %rcx),
204 ie. the kernel's syscall calling convention.
205
206 %rax gets the return value. %rcx and %r11 are clobbered by the syscall;
207 no matter, they are caller-save (the syscall clobbers no callee-save
208 regs, so we don't have to do any register saving/restoring).
209*/
sewardj03d8aa82005-10-14 11:25:49 +0000210extern UWord do_syscall_WRK (
cerion85665ca2005-06-20 15:51:07 +0000211 UWord syscall_no,
212 UWord a1, UWord a2, UWord a3,
213 UWord a4, UWord a5, UWord a6
214 );
njn9abd6082005-06-17 21:31:45 +0000215asm(
sewardjd9fc3822005-11-18 23:50:43 +0000216".text\n"
njn9abd6082005-06-17 21:31:45 +0000217"do_syscall_WRK:\n"
218 /* Convert function calling convention --> syscall calling
219 convention */
220" movq %rdi, %rax\n"
221" movq %rsi, %rdi\n"
222" movq %rdx, %rsi\n"
223" movq %rcx, %rdx\n"
224" movq %r8, %r10\n"
225" movq %r9, %r8\n"
226" movq 8(%rsp), %r9\n" /* last arg from stack */
227" syscall\n"
228" ret\n"
sewardj2fedc642005-11-19 02:02:57 +0000229".previous\n"
njn9abd6082005-06-17 21:31:45 +0000230);
sewardj2c48c7b2005-11-29 13:05:56 +0000231
cerion85665ca2005-06-20 15:51:07 +0000232#elif defined(VGP_ppc32_linux)
sewardj39a7c1d2005-11-24 03:54:38 +0000233/* Incoming args (syscall number + up to 6 args) come in %r3:%r9.
cerion85665ca2005-06-20 15:51:07 +0000234
235 The syscall number goes in %r0. The args are passed to the syscall in
236 the regs %r3:%r8, i.e. the kernel's syscall calling convention.
237
238 The %cr0.so bit flags an error.
sewardj39a7c1d2005-11-24 03:54:38 +0000239 We return the syscall return value in %r3, and the %cr0.so in
240 the lowest bit of %r4.
cerion85665ca2005-06-20 15:51:07 +0000241 We return a ULong, of which %r3 is the high word, and %r4 the low.
242 No callee-save regs are clobbered, so no saving/restoring is needed.
243*/
sewardj03d8aa82005-10-14 11:25:49 +0000244extern ULong do_syscall_WRK (
cerion85665ca2005-06-20 15:51:07 +0000245 UWord syscall_no,
246 UWord a1, UWord a2, UWord a3,
247 UWord a4, UWord a5, UWord a6
248 );
249asm(
sewardjd9fc3822005-11-18 23:50:43 +0000250".text\n"
cerion85665ca2005-06-20 15:51:07 +0000251"do_syscall_WRK:\n"
252" mr 0,3\n"
253" mr 3,4\n"
254" mr 4,5\n"
255" mr 5,6\n"
256" mr 6,7\n"
257" mr 7,8\n"
258" mr 8,9\n"
259" sc\n" /* syscall: sets %cr0.so on error */
260" mfcr 4\n" /* %cr -> low word of return var */
261" rlwinm 4,4,4,31,31\n" /* rotate flag bit so to lsb, and mask it */
262" blr\n" /* and return */
sewardj2fedc642005-11-19 02:02:57 +0000263".previous\n"
cerion85665ca2005-06-20 15:51:07 +0000264);
sewardj2c48c7b2005-11-29 13:05:56 +0000265
266#elif defined(VGP_ppc64_linux)
267/* Due to the need to return 65 bits of result, this is completely
268 different from the ppc32 case. The single arg register points to a
269 7-word block containing the syscall # and the 6 args. The syscall
270 result proper is put in [0] of the block, and %cr0.so is in the
271 bottom but of [1]. */
272extern void do_syscall_WRK ( ULong* argblock );
273asm(
cerion297c88f2005-12-22 15:53:12 +0000274".align 2\n"
275".globl do_syscall_WRK\n"
276".section \".opd\",\"aw\"\n"
277".align 3\n"
278"do_syscall_WRK:\n"
279".quad .do_syscall_WRK,.TOC.@tocbase,0\n"
280".previous\n"
281".type .do_syscall_WRK,@function\n"
282".globl .do_syscall_WRK\n"
sewardj2c48c7b2005-11-29 13:05:56 +0000283".do_syscall_WRK:\n"
284" std 3,-16(1)\n" /* stash arg */
285" ld 8, 48(3)\n" /* sc arg 6 */
286" ld 7, 40(3)\n" /* sc arg 5 */
287" ld 6, 32(3)\n" /* sc arg 4 */
288" ld 5, 24(3)\n" /* sc arg 3 */
289" ld 4, 16(3)\n" /* sc arg 2 */
290" ld 0, 0(3)\n" /* sc number */
291" ld 3, 8(3)\n" /* sc arg 1 */
292" sc\n" /* result in r3 and cr0.so */
293" ld 5,-16(1)\n" /* reacquire argblock ptr (r5 is caller-save) */
294" std 3,0(5)\n" /* argblock[0] = r3 */
sewardj2c48c7b2005-11-29 13:05:56 +0000295" mfcr 3\n"
296" srwi 3,3,28\n"
297" andi. 3,3,1\n"
298" std 3,8(5)\n" /* argblock[1] = cr0.s0 & 1 */
299" blr\n"
sewardj2c48c7b2005-11-29 13:05:56 +0000300);
sewardj17edf032006-10-17 01:53:34 +0000301
302#elif defined(VGP_ppc32_aix5)
303static void do_syscall_WRK ( UWord* res_r3, UWord* res_r4,
304 UWord sysno,
305 UWord a1, UWord a2, UWord a3,
306 UWord a4, UWord a5, UWord a6,
307 UWord a7, UWord a8 )
308{
309 /* Syscalls on AIX are very similar to function calls:
310 - up to 8 args in r3-r10
311 - syscall number in r2
312 - kernel resumes at 'lr', so must set it appropriately beforehand
313 - r3 holds the result and r4 any applicable error code
314 See http://www.cs.utexas.edu/users/cart/publications/tr00-04.ps
315 and also 'man truss'.
316 */
317 /* For some reason gcc-3.3.2 doesn't preserve r31 across the asm
318 even though we state it to be trashed. So use r27 instead. */
319 UWord args[9];
320 args[0] = sysno;
321 args[1] = a1; args[2] = a2;
322 args[3] = a3; args[4] = a4;
323 args[5] = a5; args[6] = a6;
324 args[7] = a7; args[8] = a8;
325
326 __asm__ __volatile__(
327
328 // establish base ptr
329 "mr 28,%0\n\t"
330
331 // save r2, lr
332 "mr 27,2\n\t" // save r2 in r27
333 "mflr 30\n\t" // save lr in r30
334
335 // set syscall number and args
336 "lwz 2, 0(28)\n\t"
337 "lwz 3, 4(28)\n\t"
338 "lwz 4, 8(28)\n\t"
339 "lwz 5, 12(28)\n\t"
340 "lwz 6, 16(28)\n\t"
341 "lwz 7, 20(28)\n\t"
342 "lwz 8, 24(28)\n\t"
343 "lwz 9, 28(28)\n\t"
344 "lwz 10, 32(28)\n\t"
345
sewardj17edf032006-10-17 01:53:34 +0000346 // set bit 3 of CR1 otherwise AIX 5.1 returns to the
347 // wrong address after the sc instruction
348 "crorc 6,6,6\n\t"
349
sewardj13552642006-11-10 22:47:27 +0000350 // set up LR to point just after the sc insn
351 ".long 0x48000005\n\t" // "bl here+4" -- lr := & next insn
352 "mflr 29\n\t"
353 "addi 29,29,16\n\t"
354 "mtlr 29\n\t"
355
sewardj17edf032006-10-17 01:53:34 +0000356 // do it!
357 "sc\n\t"
358
359 // result is now in r3; save it in args[0]
360 "stw 3,0(28)\n\t"
361 // error code in r4; save it in args[1]
362 "stw 4,4(28)\n\t"
363
364 // restore
365 "mr 2,27\n\t"
366 "mtlr 30\n\t"
367
368 : /*out*/
369 : /*in*/ "b" (&args[0])
370 : /*trash*/
371 /*temps*/ "r31","r30","r29","r28","r27",
372 /*args*/ "r3","r4","r5","r6","r7","r8","r9","r10",
373 /*paranoia*/ "memory","cc","r0","r1","r11","r12","r13",
374 "xer","ctr","cr0","cr1","cr2","cr3",
375 "cr4","cr5","cr6","cr7"
376 );
377
378 *res_r3 = args[0];
379 *res_r4 = args[1];
380}
381
382#elif defined(VGP_ppc64_aix5)
383static void do_syscall_WRK ( UWord* res_r3, UWord* res_r4,
384 UWord sysno,
385 UWord a1, UWord a2, UWord a3,
386 UWord a4, UWord a5, UWord a6,
387 UWord a7, UWord a8 )
388{
389 /* Same scheme as ppc32-aix5. */
390 UWord args[9];
391 args[0] = sysno;
392 args[1] = a1; args[2] = a2;
393 args[3] = a3; args[4] = a4;
394 args[5] = a5; args[6] = a6;
395 args[7] = a7; args[8] = a8;
396
397 __asm__ __volatile__(
398
399 // establish base ptr
400 "mr 28,%0\n\t"
401
402 // save r2, lr
403 "mr 27,2\n\t" // save r2 in r27
404 "mflr 30\n\t" // save lr in r30
405
406 // set syscall number and args
407 "ld 2, 0(28)\n\t"
408 "ld 3, 8(28)\n\t"
409 "ld 4, 16(28)\n\t"
410 "ld 5, 24(28)\n\t"
411 "ld 6, 32(28)\n\t"
412 "ld 7, 40(28)\n\t"
413 "ld 8, 48(28)\n\t"
414 "ld 9, 56(28)\n\t"
415 "ld 10, 64(28)\n\t"
416
sewardj17edf032006-10-17 01:53:34 +0000417 // set bit 3 of CR1 otherwise AIX 5.1 returns to the
418 // wrong address after the sc instruction
419 "crorc 6,6,6\n\t"
420
sewardj13552642006-11-10 22:47:27 +0000421 // set up LR to point just after the sc insn
422 ".long 0x48000005\n\t" // "bl here+4" -- lr := & next insn
423 "mflr 29\n\t"
424 "addi 29,29,16\n\t"
425 "mtlr 29\n\t"
426
sewardj17edf032006-10-17 01:53:34 +0000427 // do it!
428 "sc\n\t"
429
430 // result is now in r3; save it in args[0]
431 "std 3,0(28)\n\t"
432 // error code in r4; save it in args[1]
433 "std 4,8(28)\n\t"
434
435 // restore
436 "mr 2,27\n\t"
437 "mtlr 30\n\t"
438
439 : /*out*/
440 : /*in*/ "b" (&args[0])
441 : /*trash*/
442 /*temps*/ "r31","r30","r29","r28","r27",
443 /*args*/ "r3","r4","r5","r6","r7","r8","r9","r10",
444 /*paranoia*/ "memory","cc","r0","r1","r11","r12","r13",
445 "xer","ctr","cr0","cr1","cr2","cr3",
446 "cr4","cr5","cr6","cr7"
447 );
448
449 *res_r3 = args[0];
450 *res_r4 = args[1];
451}
452
njn9abd6082005-06-17 21:31:45 +0000453#else
454# error Unknown platform
455#endif
456
sewardj17edf032006-10-17 01:53:34 +0000457
njn9abd6082005-06-17 21:31:45 +0000458SysRes VG_(do_syscall) ( UWord sysno, UWord a1, UWord a2, UWord a3,
sewardj17edf032006-10-17 01:53:34 +0000459 UWord a4, UWord a5, UWord a6,
460 UWord a7, UWord a8 )
njn9abd6082005-06-17 21:31:45 +0000461{
cerion85665ca2005-06-20 15:51:07 +0000462#if defined(VGP_x86_linux)
463 UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
464 return VG_(mk_SysRes_x86_linux)( val );
sewardj17edf032006-10-17 01:53:34 +0000465
cerion85665ca2005-06-20 15:51:07 +0000466#elif defined(VGP_amd64_linux)
467 UWord val = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
468 return VG_(mk_SysRes_amd64_linux)( val );
sewardj17edf032006-10-17 01:53:34 +0000469
cerion85665ca2005-06-20 15:51:07 +0000470#elif defined(VGP_ppc32_linux)
471 ULong ret = do_syscall_WRK(sysno,a1,a2,a3,a4,a5,a6);
472 UInt val = (UInt)(ret>>32);
sewardj39a7c1d2005-11-24 03:54:38 +0000473 UInt cr0so = (UInt)(ret);
474 return VG_(mk_SysRes_ppc32_linux)( val, cr0so );
sewardj17edf032006-10-17 01:53:34 +0000475
sewardj2c48c7b2005-11-29 13:05:56 +0000476#elif defined(VGP_ppc64_linux)
477 ULong argblock[7];
478 argblock[0] = sysno;
479 argblock[1] = a1;
480 argblock[2] = a2;
481 argblock[3] = a3;
482 argblock[4] = a4;
483 argblock[5] = a5;
484 argblock[6] = a6;
485 do_syscall_WRK( &argblock[0] );
486 return VG_(mk_SysRes_ppc64_linux)( argblock[0], argblock[1] );
sewardj17edf032006-10-17 01:53:34 +0000487
488#elif defined(VGP_ppc32_aix5)
489 UWord res;
490 UWord err;
491 do_syscall_WRK( &res, &err,
492 sysno, a1, a2, a3, a4, a5, a6, a7, a8);
493 /* Try to set the error number to zero if the syscall hasn't
494 really failed. */
495 if (sysno == __NR_AIX5_kread
496 || sysno == __NR_AIX5_kwrite) {
497 if (res != (UWord)-1L)
498 err = 0;
499 }
500 else if (sysno == __NR_AIX5_sigprocmask
501 || sysno == __NR_AIX5__sigpending) {
502 if (res == 0)
503 err = 0;
504 }
505
506 return VG_(mk_SysRes_ppc32_aix5)( res, err );
507
508#elif defined(VGP_ppc64_aix5)
509 UWord res;
510 UWord err;
511 do_syscall_WRK( &res, &err,
512 sysno, a1, a2, a3, a4, a5, a6, a7, a8);
513 /* Try to set the error number to zero if the syscall hasn't
514 really failed. */
515 if (sysno == __NR_AIX5_kread
516 || sysno == __NR_AIX5_kwrite) {
517 if (res != (UWord)-1L)
518 err = 0;
519 }
520 else if (sysno == __NR_AIX5_sigprocmask
521 || sysno == __NR_AIX5__sigpending) {
522 if (res == 0)
523 err = 0;
524 }
525
526 return VG_(mk_SysRes_ppc64_aix5)( res, err );
527
cerion85665ca2005-06-20 15:51:07 +0000528#else
529# error Unknown platform
530#endif
njn9abd6082005-06-17 21:31:45 +0000531}
532
sewardj45f4e7c2005-09-27 19:20:21 +0000533/* ---------------------------------------------------------------------
534 Names of errors.
535 ------------------------------------------------------------------ */
536
537/* Return a string which gives the name of an error value. Note,
538 unlike the standard C syserror fn, the returned string is not
539 malloc-allocated or writable -- treat it as a constant.
540 TODO: implement this properly. */
541
542const HChar* VG_(strerror) ( UWord errnum )
543{
544 switch (errnum) {
545 case VKI_EPERM: return "Operation not permitted";
546 case VKI_ENOENT: return "No such file or directory";
547 case VKI_ESRCH: return "No such process";
548 case VKI_EINTR: return "Interrupted system call";
549 case VKI_EBADF: return "Bad file number";
550 case VKI_EAGAIN: return "Try again";
551 case VKI_ENOMEM: return "Out of memory";
552 case VKI_EACCES: return "Permission denied";
553 case VKI_EFAULT: return "Bad address";
554 case VKI_EEXIST: return "File exists";
555 case VKI_EINVAL: return "Invalid argument";
556 case VKI_EMFILE: return "Too many open files";
557 case VKI_ENOSYS: return "Function not implemented";
tomaf8a6a82006-05-24 12:51:17 +0000558 case VKI_EOVERFLOW: return "Value too large for defined data type";
sewardj45f4e7c2005-09-27 19:20:21 +0000559 case VKI_ERESTARTSYS: return "ERESTARTSYS";
560 default: return "VG_(strerror): unknown error";
561 }
562}
563
564
njn9abd6082005-06-17 21:31:45 +0000565/*--------------------------------------------------------------------*/
566/*--- end ---*/
567/*--------------------------------------------------------------------*/