Bug 338445 amd64 vbit-test fails with unknown opcodes used by arm64 VEX.
[valgrind.git] / coregrind / m_libcfile.c
blobccac5bb5311bb6e0706958aa0d20116fc4cb7d5f
2 /*--------------------------------------------------------------------*/
3 /*--- File- and socket-related libc stuff. m_libcfile.c ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2000-2013 Julian Seward
11 jseward@acm.org
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.
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.
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.
28 The GNU General Public License is contained in the file COPYING.
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_debuglog.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_libcassert.h"
37 #include "pub_core_libcfile.h"
38 #include "pub_core_libcprint.h" // VG_(sprintf)
39 #include "pub_core_libcproc.h" // VG_(getpid), VG_(getppid)
40 #include "pub_core_xarray.h"
41 #include "pub_core_clientstate.h" // VG_(fd_hard_limit)
42 #include "pub_core_syscall.h"
44 /* IMPORTANT: on Darwin it is essential to use the _nocancel versions
45 of syscalls rather than the vanilla version, if a _nocancel version
46 is available. See docs/internals/Darwin-notes.txt for the reason
47 why. */
49 /* ---------------------------------------------------------------------
50 File stuff
51 ------------------------------------------------------------------ */
53 /* Move an fd into the Valgrind-safe range */
54 Int VG_(safe_fd)(Int oldfd)
56 Int newfd;
58 vg_assert(VG_(fd_hard_limit) != -1);
60 newfd = VG_(fcntl)(oldfd, VKI_F_DUPFD, VG_(fd_hard_limit));
61 if (newfd != -1)
62 VG_(close)(oldfd);
64 /* Set the close-on-exec flag for this fd. */
65 VG_(fcntl)(newfd, VKI_F_SETFD, VKI_FD_CLOEXEC);
67 vg_assert(newfd >= VG_(fd_hard_limit));
68 return newfd;
71 /* Given a file descriptor, attempt to deduce its filename. To do
72 this, we use /proc/self/fd/<FD>. If this doesn't point to a file,
73 or if it doesn't exist, we return False. */
74 Bool VG_(resolve_filename) ( Int fd, HChar* buf, Int n_buf )
76 # if defined(VGO_linux)
77 HChar tmp[64];
78 VG_(sprintf)(tmp, "/proc/self/fd/%d", fd);
79 VG_(memset)(buf, 0, n_buf);
80 if (VG_(readlink)(tmp, buf, n_buf) > 0 && buf[0] == '/')
81 return True;
82 else
83 return False;
85 # elif defined(VGO_darwin)
86 HChar tmp[VKI_MAXPATHLEN+1];
87 if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) {
88 if (n_buf > 0) {
89 VG_(strncpy)( buf, tmp, n_buf < sizeof(tmp) ? n_buf : sizeof(tmp) );
90 buf[n_buf-1] = 0;
92 if (tmp[0] == '/') return True;
94 return False;
96 # else
97 # error Unknown OS
98 # endif
101 SysRes VG_(mknod) ( const HChar* pathname, Int mode, UWord dev )
103 # if defined(VGP_arm64_linux)
104 /* ARM64 wants to use __NR_mknodat rather than __NR_mknod. */
105 SysRes res = VG_(do_syscall4)(__NR_mknodat,
106 VKI_AT_FDCWD, (UWord)pathname, mode, dev);
107 # elif defined(VGO_linux) || defined(VGO_darwin)
108 SysRes res = VG_(do_syscall3)(__NR_mknod,
109 (UWord)pathname, mode, dev);
110 # else
111 # error Unknown OS
112 # endif
113 return res;
116 SysRes VG_(open) ( const HChar* pathname, Int flags, Int mode )
118 # if defined(VGP_arm64_linux)
119 /* ARM64 wants to use __NR_openat rather than __NR_open. */
120 SysRes res = VG_(do_syscall4)(__NR_openat,
121 VKI_AT_FDCWD, (UWord)pathname, flags, mode);
122 # elif defined(VGO_linux)
123 SysRes res = VG_(do_syscall3)(__NR_open,
124 (UWord)pathname, flags, mode);
125 # elif defined(VGO_darwin)
126 SysRes res = VG_(do_syscall3)(__NR_open_nocancel,
127 (UWord)pathname, flags, mode);
128 # else
129 # error Unknown OS
130 # endif
131 return res;
134 Int VG_(fd_open) (const HChar* pathname, Int flags, Int mode)
136 SysRes sr;
137 sr = VG_(open) (pathname, flags, mode);
138 if (sr_isError (sr))
139 return -1;
140 else
141 return sr_Res (sr);
144 void VG_(close) ( Int fd )
146 /* Hmm. Return value is not checked. That's uncool. */
147 # if defined(VGO_linux)
148 (void)VG_(do_syscall1)(__NR_close, fd);
149 # elif defined(VGO_darwin)
150 (void)VG_(do_syscall1)(__NR_close_nocancel, fd);
151 # else
152 # error Unknown OS
153 # endif
156 Int VG_(read) ( Int fd, void* buf, Int count)
158 Int ret;
159 # if defined(VGO_linux)
160 SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count);
161 # elif defined(VGO_darwin)
162 SysRes res = VG_(do_syscall3)(__NR_read_nocancel, fd, (UWord)buf, count);
163 # else
164 # error Unknown OS
165 # endif
166 if (sr_isError(res)) {
167 ret = - (Int)(Word)sr_Err(res);
168 vg_assert(ret < 0);
169 } else {
170 ret = (Int)(Word)sr_Res(res);
171 vg_assert(ret >= 0);
173 return ret;
176 Int VG_(write) ( Int fd, const void* buf, Int count)
178 Int ret;
179 # if defined(VGO_linux)
180 SysRes res = VG_(do_syscall3)(__NR_write, fd, (UWord)buf, count);
181 # elif defined(VGO_darwin)
182 SysRes res = VG_(do_syscall3)(__NR_write_nocancel, fd, (UWord)buf, count);
183 # else
184 # error "Unknown OS"
185 # endif
186 if (sr_isError(res)) {
187 ret = - (Int)(Word)sr_Err(res);
188 vg_assert(ret < 0);
189 } else {
190 ret = (Int)(Word)sr_Res(res);
191 vg_assert(ret >= 0);
193 return ret;
197 Int VG_(pipe) ( Int fd[2] )
199 # if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
200 /* __NR_pipe has a strange return convention on mips32-linux. */
201 SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
202 if (!sr_isError(res)) {
203 fd[0] = (Int)sr_Res(res);
204 fd[1] = (Int)sr_ResEx(res);
205 return 0;
206 } else {
207 return -1;
209 # elif defined(VGP_arm64_linux)
210 SysRes res = VG_(do_syscall2)(__NR_pipe2, (UWord)fd, 0);
211 return sr_isError(res) ? -1 : 0;
212 # elif defined(VGO_linux)
213 SysRes res = VG_(do_syscall1)(__NR_pipe, (UWord)fd);
214 return sr_isError(res) ? -1 : 0;
215 # elif defined(VGO_darwin)
216 /* __NR_pipe is UX64, so produces a double-word result */
217 SysRes res = VG_(do_syscall0)(__NR_pipe);
218 if (!sr_isError(res)) {
219 fd[0] = (Int)sr_Res(res);
220 fd[1] = (Int)sr_ResHI(res);
222 return sr_isError(res) ? -1 : 0;
223 # else
224 # error "Unknown OS"
225 # endif
228 Off64T VG_(lseek) ( Int fd, Off64T offset, Int whence )
230 # if defined(VGO_linux) || defined(VGP_amd64_darwin)
231 # if defined(__NR__llseek)
232 Off64T result;
233 SysRes res = VG_(do_syscall5)(__NR__llseek, fd,
234 offset >> 32, offset & 0xffffffff,
235 (UWord)&result, whence);
236 return sr_isError(res) ? (-1) : result;
237 # else
238 SysRes res = VG_(do_syscall3)(__NR_lseek, fd, offset, whence);
239 vg_assert(sizeof(Off64T) == sizeof(Word));
240 return sr_isError(res) ? (-1) : sr_Res(res);
241 # endif
242 # elif defined(VGP_x86_darwin)
243 SysRes res = VG_(do_syscall4)(__NR_lseek, fd,
244 offset & 0xffffffff, offset >> 32, whence);
245 return sr_isError(res) ? (-1) : sr_Res(res);
246 # else
247 # error "Unknown plat"
248 # endif
249 /* if you change the error-reporting conventions of this, also
250 change all usage points. */
254 /* stat/fstat support. It's uggerly. We have impedance-match into a
255 'struct vg_stat' in order to have a single structure that callers
256 can use consistently on all platforms. */
258 #define TRANSLATE_TO_vg_stat(_p_vgstat, _p_vkistat) \
259 do { \
260 (_p_vgstat)->dev = (ULong)( (_p_vkistat)->st_dev ); \
261 (_p_vgstat)->ino = (ULong)( (_p_vkistat)->st_ino ); \
262 (_p_vgstat)->nlink = (ULong)( (_p_vkistat)->st_nlink ); \
263 (_p_vgstat)->mode = (UInt) ( (_p_vkistat)->st_mode ); \
264 (_p_vgstat)->uid = (UInt) ( (_p_vkistat)->st_uid ); \
265 (_p_vgstat)->gid = (UInt) ( (_p_vkistat)->st_gid ); \
266 (_p_vgstat)->rdev = (ULong)( (_p_vkistat)->st_rdev ); \
267 (_p_vgstat)->size = (Long) ( (_p_vkistat)->st_size ); \
268 (_p_vgstat)->blksize = (ULong)( (_p_vkistat)->st_blksize ); \
269 (_p_vgstat)->blocks = (ULong)( (_p_vkistat)->st_blocks ); \
270 (_p_vgstat)->atime = (ULong)( (_p_vkistat)->st_atime ); \
271 (_p_vgstat)->atime_nsec = (ULong)( (_p_vkistat)->st_atime_nsec ); \
272 (_p_vgstat)->mtime = (ULong)( (_p_vkistat)->st_mtime ); \
273 (_p_vgstat)->mtime_nsec = (ULong)( (_p_vkistat)->st_mtime_nsec ); \
274 (_p_vgstat)->ctime = (ULong)( (_p_vkistat)->st_ctime ); \
275 (_p_vgstat)->ctime_nsec = (ULong)( (_p_vkistat)->st_ctime_nsec ); \
276 } while (0)
278 SysRes VG_(stat) ( const HChar* file_name, struct vg_stat* vgbuf )
280 SysRes res;
281 VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
283 # if defined(VGO_linux) || defined(VGO_darwin)
284 /* First try with stat64. If that doesn't work out, fall back to
285 the vanilla version. */
286 # if defined(__NR_stat64)
287 { struct vki_stat64 buf64;
288 res = VG_(do_syscall2)(__NR_stat64, (UWord)file_name, (UWord)&buf64);
289 if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
290 /* Success, or any failure except ENOSYS */
291 if (!sr_isError(res))
292 TRANSLATE_TO_vg_stat(vgbuf, &buf64);
293 return res;
296 # endif /* defined(__NR_stat64) */
297 /* This is the fallback ("vanilla version"). */
298 { struct vki_stat buf;
299 # if defined(VGP_arm64_linux)
300 res = VG_(do_syscall3)(__NR3264_fstatat, VKI_AT_FDCWD,
301 (UWord)file_name, (UWord)&buf);
302 # else
303 res = VG_(do_syscall2)(__NR_stat, (UWord)file_name, (UWord)&buf);
304 # endif
305 if (!sr_isError(res))
306 TRANSLATE_TO_vg_stat(vgbuf, &buf);
307 return res;
310 # else
311 # error Unknown OS
312 # endif
315 Int VG_(fstat) ( Int fd, struct vg_stat* vgbuf )
317 SysRes res;
318 VG_(memset)(vgbuf, 0, sizeof(*vgbuf));
320 # if defined(VGO_linux) || defined(VGO_darwin)
321 /* First try with fstat64. If that doesn't work out, fall back to
322 the vanilla version. */
323 # if defined(__NR_fstat64)
324 { struct vki_stat64 buf64;
325 res = VG_(do_syscall2)(__NR_fstat64, (UWord)fd, (UWord)&buf64);
326 if (!(sr_isError(res) && sr_Err(res) == VKI_ENOSYS)) {
327 /* Success, or any failure except ENOSYS */
328 if (!sr_isError(res))
329 TRANSLATE_TO_vg_stat(vgbuf, &buf64);
330 return sr_isError(res) ? (-1) : 0;
333 # endif /* if defined(__NR_fstat64) */
334 { struct vki_stat buf;
335 res = VG_(do_syscall2)(__NR_fstat, (UWord)fd, (UWord)&buf);
336 if (!sr_isError(res))
337 TRANSLATE_TO_vg_stat(vgbuf, &buf);
338 return sr_isError(res) ? (-1) : 0;
341 # else
342 # error Unknown OS
343 # endif
346 #undef TRANSLATE_TO_vg_stat
349 Long VG_(fsize) ( Int fd )
351 struct vg_stat buf;
352 Int res = VG_(fstat)( fd, &buf );
353 return (res == -1) ? (-1LL) : buf.size;
356 SysRes VG_(getxattr) ( const HChar* file_name, const HChar* attr_name, Addr attr_value, SizeT attr_value_len )
358 SysRes res;
359 #if defined(VGO_linux)
360 res = VG_(do_syscall4)(__NR_getxattr, (UWord)file_name, (UWord)attr_name,
361 attr_value, attr_value_len);
362 #else
363 res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
364 #endif
365 return res;
368 Bool VG_(is_dir) ( const HChar* f )
370 struct vg_stat buf;
371 SysRes res = VG_(stat)(f, &buf);
372 return sr_isError(res) ? False
373 : VKI_S_ISDIR(buf.mode) ? True : False;
376 SysRes VG_(dup) ( Int oldfd )
378 return VG_(do_syscall1)(__NR_dup, oldfd);
381 SysRes VG_(dup2) ( Int oldfd, Int newfd )
383 # if defined(VGO_linux) || defined(VGO_darwin)
384 return VG_(do_syscall2)(__NR_dup2, oldfd, newfd);
385 # else
386 # error Unknown OS
387 # endif
390 /* Returns -1 on error. */
391 Int VG_(fcntl) ( Int fd, Int cmd, Addr arg )
393 # if defined(VGO_linux)
394 SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg);
395 # elif defined(VGO_darwin)
396 SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg);
397 # else
398 # error "Unknown OS"
399 # endif
400 return sr_isError(res) ? -1 : sr_Res(res);
403 Int VG_(rename) ( const HChar* old_name, const HChar* new_name )
405 SysRes res = VG_(do_syscall2)(__NR_rename, (UWord)old_name, (UWord)new_name);
406 return sr_isError(res) ? (-1) : 0;
409 Int VG_(unlink) ( const HChar* file_name )
411 # if defined(VGP_arm64_linux)
412 SysRes res = VG_(do_syscall2)(__NR_unlinkat, VKI_AT_FDCWD,
413 (UWord)file_name);
414 # else
415 SysRes res = VG_(do_syscall1)(__NR_unlink, (UWord)file_name);
416 # endif
417 return sr_isError(res) ? (-1) : 0;
420 /* The working directory at startup. AIX doesn't provide an easy
421 system call to do getcwd, but fortunately we don't need arbitrary
422 getcwd support. All that is really needed is to note the cwd at
423 process startup. Hence VG_(record_startup_wd) notes it (in a
424 platform dependent way) and VG_(get_startup_wd) produces the noted
425 value. Hence: */
426 static HChar startup_wd[VKI_PATH_MAX];
427 static Bool startup_wd_acquired = False;
429 /* Record the process' working directory at startup. Is intended to
430 be called exactly once, at startup, before the working directory
431 changes. Return True for success, False for failure, so that the
432 caller can bomb out suitably without creating module cycles if
433 there is a problem. */
434 Bool VG_(record_startup_wd) ( void )
436 const Int szB = sizeof(startup_wd);
437 vg_assert(!startup_wd_acquired);
438 vg_assert(szB >= 512 && szB <= 16384/*let's say*/); /* stay sane */
439 VG_(memset)(startup_wd, 0, szB);
440 # if defined(VGO_linux)
441 /* Simple: just ask the kernel */
442 { SysRes res
443 = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
444 vg_assert(startup_wd[szB-1] == 0);
445 if (sr_isError(res)) {
446 return False;
447 } else {
448 startup_wd_acquired = True;
449 return True;
452 # elif defined(VGO_darwin)
453 /* We can't ask the kernel, so instead rely on launcher-*.c to
454 tell us the startup path. Note the env var is keyed to the
455 parent's PID, not ours, since our parent is the launcher
456 process. */
457 { HChar envvar[100];
458 HChar* wd = NULL;
459 VG_(memset)(envvar, 0, sizeof(envvar));
460 VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY",
461 (Int)VG_(getppid)());
462 wd = VG_(getenv)( envvar );
463 if (wd == NULL || (1+VG_(strlen)(wd) >= szB))
464 return False;
465 VG_(strncpy_safely)(startup_wd, wd, szB);
466 vg_assert(startup_wd[szB-1] == 0);
467 startup_wd_acquired = True;
468 return True;
470 # else
471 # error Unknown OS
472 # endif
475 /* Copy the previously acquired startup_wd into buf[0 .. size-1],
476 or return False if buf isn't big enough. */
477 Bool VG_(get_startup_wd) ( HChar* buf, SizeT size )
479 vg_assert(startup_wd_acquired);
480 vg_assert(startup_wd[ sizeof(startup_wd)-1 ] == 0);
481 if (1+VG_(strlen)(startup_wd) >= size)
482 return False;
483 VG_(strncpy_safely)(buf, startup_wd, size);
484 return True;
487 SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
489 SysRes res;
490 # if defined(VGP_arm64_linux)
491 /* ARM64 wants to use __NR_ppoll rather than __NR_poll. */
492 struct vki_timespec timeout_ts;
493 if (timeout >= 0) {
494 timeout_ts.tv_sec = timeout / 1000;
495 timeout_ts.tv_nsec = ((long)timeout % 1000) * 1000000;
497 res = VG_(do_syscall4)(__NR_ppoll,
498 (UWord)fds, nfds,
499 (UWord)(timeout >= 0 ? &timeout_ts : NULL),
500 (UWord)NULL);
501 # elif defined(VGO_linux)
502 res = VG_(do_syscall3)(__NR_poll, (UWord)fds, nfds, timeout);
503 # elif defined(VGO_darwin)
504 res = VG_(do_syscall3)(__NR_poll_nocancel, (UWord)fds, nfds, timeout);
505 # else
506 # error "Unknown OS"
507 # endif
508 return res;
512 Int VG_(readlink) (const HChar* path, HChar* buf, UInt bufsiz)
514 SysRes res;
515 /* res = readlink( path, buf, bufsiz ); */
516 # if defined(VGP_arm64_linux)
517 res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD,
518 (UWord)path, (UWord)buf, bufsiz);
519 # else
520 res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz);
521 # endif
522 return sr_isError(res) ? -1 : sr_Res(res);
525 Int VG_(getdents) (Int fd, struct vki_dirent *dirp, UInt count)
527 # if defined(VGO_linux)
528 SysRes res;
529 /* res = getdents( fd, dirp, count ); */
530 res = VG_(do_syscall3)(__NR_getdents, fd, (UWord)dirp, count);
531 return sr_isError(res) ? -1 : sr_Res(res);
532 # elif defined(VGO_darwin)
533 I_die_here;
534 # else
535 # error "Unknown OS"
536 # endif
539 /* Check accessibility of a file. Returns zero for access granted,
540 nonzero otherwise. */
541 Int VG_(access) ( const HChar* path, Bool irusr, Bool iwusr, Bool ixusr )
543 # if defined(VGO_linux)
544 /* Very annoyingly, I cannot find any definition for R_OK et al in
545 the kernel interfaces. Therefore I reluctantly resort to
546 hardwiring in these magic numbers that I determined by
547 experimentation. */
548 # define VKI_R_OK 4
549 # define VKI_W_OK 2
550 # define VKI_X_OK 1
551 # endif
553 UWord w = (irusr ? VKI_R_OK : 0)
554 | (iwusr ? VKI_W_OK : 0)
555 | (ixusr ? VKI_X_OK : 0);
556 # if defined(VGP_arm64_linux)
557 SysRes res = VG_(do_syscall3)(__NR_faccessat, VKI_AT_FDCWD, (UWord)path, w);
558 # else
559 SysRes res = VG_(do_syscall2)(__NR_access, (UWord)path, w);
560 # endif
561 return sr_isError(res) ? 1 : 0;
563 # if defined(VGO_linux)
564 # undef VKI_R_OK
565 # undef VKI_W_OK
566 # undef VKI_X_OK
567 # endif
571 Emulate the normal Unix permissions checking algorithm.
573 If owner matches, then use the owner permissions, else
574 if group matches, then use the group permissions, else
575 use other permissions.
577 Note that we can't deal properly with SUID/SGID. By default
578 (allow_setuid == False), we refuse to run them (otherwise the
579 executable may misbehave if it doesn't have the permissions it
580 thinks it does). However, the caller may indicate that setuid
581 executables are allowed, for example if we are going to exec them
582 but not trace into them (iow, client sys_execve when
583 clo_trace_children == False).
585 If VKI_EACCES is returned (iow, permission was refused), then
586 *is_setuid is set to True iff permission was refused because the
587 executable is setuid.
589 /* returns: 0 = success, non-0 is failure */
590 Int VG_(check_executable)(/*OUT*/Bool* is_setuid,
591 const HChar* f, Bool allow_setuid)
593 struct vg_stat st;
594 SysRes res = VG_(stat)(f, &st);
596 if (is_setuid)
597 *is_setuid = False;
599 if (sr_isError(res)) {
600 return sr_Err(res);
603 if ( (st.mode & (VKI_S_ISUID | VKI_S_ISGID)) && !allow_setuid ) {
604 if (is_setuid)
605 *is_setuid = True;
606 return VKI_EACCES;
609 res = VG_(getxattr)(f, "security.capability", (Addr)0, 0);
610 if (!sr_isError(res) && !allow_setuid) {
611 if (is_setuid)
612 *is_setuid = True;
613 return VKI_EACCES;
616 if (VG_(geteuid)() == st.uid) {
617 if (!(st.mode & VKI_S_IXUSR))
618 return VKI_EACCES;
619 } else {
620 Int grpmatch = 0;
622 if (VG_(getegid)() == st.gid)
623 grpmatch = 1;
624 else {
625 UInt groups[32];
626 Int ngrp = VG_(getgroups)(32, groups);
627 Int i;
628 /* ngrp will be -1 if VG_(getgroups) failed. */
629 for (i = 0; i < ngrp; i++) {
630 if (groups[i] == st.gid) {
631 grpmatch = 1;
632 break;
637 if (grpmatch) {
638 if (!(st.mode & VKI_S_IXGRP)) {
639 return VKI_EACCES;
641 } else if (!(st.mode & VKI_S_IXOTH)) {
642 return VKI_EACCES;
646 return 0;
649 SysRes VG_(pread) ( Int fd, void* buf, Int count, OffT offset )
651 SysRes res;
652 // on 32 bits platforms, we receive a 32 bits OffT but
653 // we must extend it to pass a long long 64 bits.
654 # if defined(VGP_x86_linux)
655 vg_assert(sizeof(OffT) == 4);
656 res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
657 offset, 0); // Little endian long long
658 return res;
659 # elif defined(VGP_arm_linux)
660 vg_assert(sizeof(OffT) == 4);
661 res = VG_(do_syscall5)(__NR_pread64, fd, (UWord)buf, count,
662 0, offset); // Big endian long long
663 return res;
664 # elif defined(VGP_ppc32_linux)
665 vg_assert(sizeof(OffT) == 4);
666 res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
667 0, // Padding needed on PPC32
668 0, offset); // Big endian long long
669 return res;
670 # elif defined(VGP_mips32_linux) && (VKI_LITTLE_ENDIAN)
671 vg_assert(sizeof(OffT) == 4);
672 res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
673 0, offset, 0);
674 return res;
675 # elif defined(VGP_mips32_linux) && (VKI_BIG_ENDIAN)
676 vg_assert(sizeof(OffT) == 4);
677 res = VG_(do_syscall6)(__NR_pread64, fd, (UWord)buf, count,
678 0, 0, offset);
679 return res;
680 # elif defined(VGP_amd64_linux) || defined(VGP_s390x_linux) \
681 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
682 || defined(VGP_mips64_linux) \
683 || defined(VGP_arm64_linux)
684 res = VG_(do_syscall4)(__NR_pread64, fd, (UWord)buf, count, offset);
685 return res;
686 # elif defined(VGP_amd64_darwin)
687 vg_assert(sizeof(OffT) == 8);
688 res = VG_(do_syscall4)(__NR_pread_nocancel, fd, (UWord)buf, count, offset);
689 return res;
690 # elif defined(VGP_x86_darwin)
691 vg_assert(sizeof(OffT) == 8);
692 res = VG_(do_syscall5)(__NR_pread_nocancel, fd, (UWord)buf, count,
693 offset & 0xffffffff, offset >> 32);
694 return res;
695 # else
696 # error "Unknown platform"
697 # endif
700 /* Return the name of a directory for temporary files. */
701 const HChar *VG_(tmpdir)(void)
703 const HChar *tmpdir;
705 tmpdir = VG_(getenv)("TMPDIR");
706 if (tmpdir == NULL || *tmpdir == '\0') tmpdir = VG_TMPDIR;
707 if (tmpdir == NULL || *tmpdir == '\0') tmpdir = "/tmp"; /* fallback */
709 return tmpdir;
712 static const HChar mkstemp_format[] = "%s/valgrind_%s_%08x";
714 SizeT VG_(mkstemp_fullname_bufsz) ( SizeT part_of_name_len )
716 return VG_(strlen)(mkstemp_format)
717 + VG_(strlen)(VG_(tmpdir)()) - 2 // %s tmpdir
718 + part_of_name_len - 2 // %s part_of_name
719 + 8 - 4 // %08x
720 + 1; // trailing 0
724 Int VG_(mkstemp) ( const HChar* part_of_name, /*OUT*/HChar* fullname )
726 HChar buf[VG_(mkstemp_fullname_bufsz)(VG_(strlen)(part_of_name))];
727 Int n, tries, fd;
728 UInt seed;
729 SysRes sres;
730 const HChar *tmpdir;
732 vg_assert(part_of_name);
733 n = VG_(strlen)(part_of_name);
734 vg_assert(n > 0 && n < 100);
736 seed = (VG_(getpid)() << 9) ^ VG_(getppid)();
738 /* Determine sensible location for temporary files */
739 tmpdir = VG_(tmpdir)();
741 tries = 0;
742 while (True) {
743 if (tries++ > 10)
744 return -1;
745 VG_(sprintf)( buf, mkstemp_format,
746 tmpdir, part_of_name, VG_(random)( &seed ));
747 if (0)
748 VG_(printf)("VG_(mkstemp): trying: %s\n", buf);
750 sres = VG_(open)(buf,
751 VKI_O_CREAT|VKI_O_RDWR|VKI_O_EXCL|VKI_O_TRUNC,
752 VKI_S_IRUSR|VKI_S_IWUSR);
753 if (sr_isError(sres)) {
754 VG_(umsg)("VG_(mkstemp): failed to create temp file: %s\n", buf);
755 continue;
757 /* VG_(safe_fd) doesn't return if it fails. */
758 fd = VG_(safe_fd)( sr_Res(sres) );
759 if (fullname)
760 VG_(strcpy)( fullname, buf );
761 return fd;
763 /* NOTREACHED */
767 /* ---------------------------------------------------------------------
768 Socket-related stuff.
769 ------------------------------------------------------------------ */
771 static
772 Int parse_inet_addr_and_port ( const HChar* str, UInt* ip_addr, UShort* port );
774 static
775 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen );
777 UInt VG_(htonl) ( UInt x )
779 # if defined(VG_BIGENDIAN)
780 return x;
781 # else
782 return
783 (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
784 | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
785 # endif
788 UInt VG_(ntohl) ( UInt x )
790 # if defined(VG_BIGENDIAN)
791 return x;
792 # else
793 return
794 (((x >> 24) & 0xFF) << 0) | (((x >> 16) & 0xFF) << 8)
795 | (((x >> 8) & 0xFF) << 16) | (((x >> 0) & 0xFF) << 24);
796 # endif
799 UShort VG_(htons) ( UShort x )
801 # if defined(VG_BIGENDIAN)
802 return x;
803 # else
804 return
805 (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
806 # endif
809 UShort VG_(ntohs) ( UShort x )
811 # if defined(VG_BIGENDIAN)
812 return x;
813 # else
814 return
815 (((x >> 8) & 0xFF) << 0) | (((x >> 0) & 0xFF) << 8);
816 # endif
820 /* The main function.
822 Supplied string contains either an ip address "192.168.0.1" or
823 an ip address and port pair, "192.168.0.1:1500". Parse these,
824 and return:
825 -1 if there is a parse error
826 -2 if no parse error, but specified host:port cannot be opened
827 the relevant file (socket) descriptor, otherwise.
828 is used.
830 Int VG_(connect_via_socket)( const HChar* str )
832 # if defined(VGO_linux) || defined(VGO_darwin)
833 Int sd, res;
834 struct vki_sockaddr_in servAddr;
835 UInt ip = 0;
836 UShort port = VG_CLO_DEFAULT_LOGPORT;
837 Bool ok = parse_inet_addr_and_port(str, &ip, &port);
838 if (!ok)
839 return -1;
841 //if (0)
842 // VG_(printf)("ip = %d.%d.%d.%d, port %d\n",
843 // (ip >> 24) & 0xFF, (ip >> 16) & 0xFF,
844 // (ip >> 8) & 0xFF, ip & 0xFF,
845 // (UInt)port );
847 servAddr.sin_family = VKI_AF_INET;
848 servAddr.sin_addr.s_addr = VG_(htonl)(ip);
849 servAddr.sin_port = VG_(htons)(port);
851 /* create socket */
852 sd = VG_(socket)(VKI_AF_INET, VKI_SOCK_STREAM, 0 /* IPPROTO_IP ? */);
853 if (sd < 0) {
854 /* this shouldn't happen ... nevertheless */
855 return -2;
858 /* connect to server */
859 res = my_connect(sd, &servAddr, sizeof(servAddr));
860 if (res < 0) {
861 /* connection failed */
862 return -2;
865 return sd;
867 # else
868 # error "Unknown OS"
869 # endif
873 /* Let d = one or more digits. Accept either:
874 d.d.d.d or d.d.d.d:d
876 static Int parse_inet_addr_and_port ( const HChar* str, UInt* ip_addr, UShort* port )
878 # define GET_CH ((*str) ? (*str++) : 0)
879 UInt ipa, i, j, c, any;
880 ipa = 0;
881 for (i = 0; i < 4; i++) {
882 j = 0;
883 any = 0;
884 while (1) {
885 c = GET_CH;
886 if (c < '0' || c > '9') break;
887 j = 10 * j + (int)(c - '0');
888 any = 1;
890 if (any == 0 || j > 255) goto syntaxerr;
891 ipa = (ipa << 8) + j;
892 if (i <= 2 && c != '.') goto syntaxerr;
894 if (c == 0 || c == ':')
895 *ip_addr = ipa;
896 if (c == 0) goto ok;
897 if (c != ':') goto syntaxerr;
898 j = 0;
899 any = 0;
900 while (1) {
901 c = GET_CH;
902 if (c < '0' || c > '9') break;
903 j = j * 10 + (int)(c - '0');
904 any = 1;
905 if (j > 65535) goto syntaxerr;
907 if (any == 0 || c != 0) goto syntaxerr;
908 if (j < 1024) goto syntaxerr;
909 *port = (UShort)j;
911 return 1;
912 syntaxerr:
913 return 0;
914 # undef GET_CH
917 // GrP fixme safe_fd?
918 Int VG_(socket) ( Int domain, Int type, Int protocol )
920 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
921 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
922 || defined(VGP_s390x_linux)
923 SysRes res;
924 UWord args[3];
925 args[0] = domain;
926 args[1] = type;
927 args[2] = protocol;
928 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SOCKET, (UWord)&args);
929 return sr_isError(res) ? -1 : sr_Res(res);
931 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
932 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
933 || defined(VGP_arm64_linux)
934 SysRes res;
935 res = VG_(do_syscall3)(__NR_socket, domain, type, protocol );
936 return sr_isError(res) ? -1 : sr_Res(res);
938 # elif defined(VGO_darwin)
939 SysRes res;
940 res = VG_(do_syscall3)(__NR_socket, domain, type, protocol);
941 if (!sr_isError(res)) {
942 // Set SO_NOSIGPIPE so write() returns EPIPE instead of raising SIGPIPE
943 Int optval = 1;
944 SysRes res2;
945 res2 = VG_(do_syscall5)(__NR_setsockopt, sr_Res(res), VKI_SOL_SOCKET,
946 VKI_SO_NOSIGPIPE, (UWord)&optval,
947 sizeof(optval));
948 // ignore setsockopt() error
950 return sr_isError(res) ? -1 : sr_Res(res);
952 # else
953 # error "Unknown arch"
954 # endif
958 static
959 Int my_connect ( Int sockfd, struct vki_sockaddr_in* serv_addr, Int addrlen )
961 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
962 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
963 || defined(VGP_s390x_linux)
964 SysRes res;
965 UWord args[3];
966 args[0] = sockfd;
967 args[1] = (UWord)serv_addr;
968 args[2] = addrlen;
969 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_CONNECT, (UWord)&args);
970 return sr_isError(res) ? -1 : sr_Res(res);
972 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
973 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
974 || defined(VGP_arm64_linux)
975 SysRes res;
976 res = VG_(do_syscall3)(__NR_connect, sockfd, (UWord)serv_addr, addrlen);
977 return sr_isError(res) ? -1 : sr_Res(res);
979 # elif defined(VGO_darwin)
980 SysRes res;
981 res = VG_(do_syscall3)(__NR_connect_nocancel,
982 sockfd, (UWord)serv_addr, addrlen);
983 return sr_isError(res) ? -1 : sr_Res(res);
985 # else
986 # error "Unknown arch"
987 # endif
990 Int VG_(write_socket)( Int sd, const void *msg, Int count )
992 /* This is actually send(). */
994 /* For Linux, VKI_MSG_NOSIGNAL is a request not to send SIGPIPE on
995 errors on stream oriented sockets when the other end breaks the
996 connection. The EPIPE error is still returned.
998 For Darwin, VG_(socket)() sets SO_NOSIGPIPE to get EPIPE instead of
999 SIGPIPE */
1001 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1002 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1003 || defined(VGP_s390x_linux)
1004 SysRes res;
1005 UWord args[4];
1006 args[0] = sd;
1007 args[1] = (UWord)msg;
1008 args[2] = count;
1009 args[3] = VKI_MSG_NOSIGNAL;
1010 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SEND, (UWord)&args);
1011 return sr_isError(res) ? -1 : sr_Res(res);
1013 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1014 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1015 || defined(VGP_arm64_linux)
1016 SysRes res;
1017 res = VG_(do_syscall6)(__NR_sendto, sd, (UWord)msg,
1018 count, VKI_MSG_NOSIGNAL, 0,0);
1019 return sr_isError(res) ? -1 : sr_Res(res);
1021 # elif defined(VGP_x86_darwin) || defined(VGP_amd64_darwin)
1022 SysRes res;
1023 res = VG_(do_syscall3)(__NR_write_nocancel, sd, (UWord)msg, count);
1024 return sr_isError(res) ? -1 : sr_Res(res);
1026 # else
1027 # error "Unknown platform"
1028 # endif
1031 Int VG_(getsockname) ( Int sd, struct vki_sockaddr *name, Int *namelen)
1033 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1034 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1035 || defined(VGP_s390x_linux) \
1036 || defined(VGP_mips32_linux)
1037 SysRes res;
1038 UWord args[3];
1039 args[0] = sd;
1040 args[1] = (UWord)name;
1041 args[2] = (UWord)namelen;
1042 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKNAME, (UWord)&args);
1043 return sr_isError(res) ? -1 : sr_Res(res);
1045 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1046 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1047 SysRes res;
1048 res = VG_(do_syscall3)( __NR_getsockname,
1049 (UWord)sd, (UWord)name, (UWord)namelen );
1050 return sr_isError(res) ? -1 : sr_Res(res);
1052 # elif defined(VGO_darwin)
1053 SysRes res;
1054 res = VG_(do_syscall3)( __NR_getsockname,
1055 (UWord)sd, (UWord)name, (UWord)namelen );
1056 return sr_isError(res) ? -1 : sr_Res(res);
1058 # else
1059 # error "Unknown platform"
1060 # endif
1063 Int VG_(getpeername) ( Int sd, struct vki_sockaddr *name, Int *namelen)
1065 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1066 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1067 || defined(VGP_s390x_linux) \
1068 || defined(VGP_mips32_linux)
1069 SysRes res;
1070 UWord args[3];
1071 args[0] = sd;
1072 args[1] = (UWord)name;
1073 args[2] = (UWord)namelen;
1074 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETPEERNAME, (UWord)&args);
1075 return sr_isError(res) ? -1 : sr_Res(res);
1077 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1078 || defined(VGP_mips64_linux) || defined(VGP_arm64_linux)
1079 SysRes res;
1080 res = VG_(do_syscall3)( __NR_getpeername,
1081 (UWord)sd, (UWord)name, (UWord)namelen );
1082 return sr_isError(res) ? -1 : sr_Res(res);
1084 # elif defined(VGO_darwin)
1085 SysRes res;
1086 res = VG_(do_syscall3)( __NR_getpeername,
1087 (UWord)sd, (UWord)name, (UWord)namelen );
1088 return sr_isError(res) ? -1 : sr_Res(res);
1090 # else
1091 # error "Unknown platform"
1092 # endif
1095 Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
1096 Int *optlen)
1098 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1099 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1100 || defined(VGP_s390x_linux)
1101 SysRes res;
1102 UWord args[5];
1103 args[0] = sd;
1104 args[1] = level;
1105 args[2] = optname;
1106 args[3] = (UWord)optval;
1107 args[4] = (UWord)optlen;
1108 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_GETSOCKOPT, (UWord)&args);
1109 return sr_isError(res) ? -1 : sr_Res(res);
1111 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1112 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1113 || defined(VGP_arm64_linux)
1114 SysRes res;
1115 res = VG_(do_syscall5)( __NR_getsockopt,
1116 (UWord)sd, (UWord)level, (UWord)optname,
1117 (UWord)optval, (UWord)optlen );
1118 return sr_isError(res) ? -1 : sr_Res(res);
1120 # elif defined(VGO_darwin)
1121 SysRes res;
1122 res = VG_(do_syscall5)( __NR_getsockopt,
1123 (UWord)sd, (UWord)level, (UWord)optname,
1124 (UWord)optval, (UWord)optlen );
1125 return sr_isError(res) ? -1 : sr_Res(res);
1127 # else
1128 # error "Unknown platform"
1129 # endif
1133 Int VG_(setsockopt) ( Int sd, Int level, Int optname, void *optval,
1134 Int optlen)
1136 # if defined(VGP_x86_linux) || defined(VGP_ppc32_linux) \
1137 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
1138 || defined(VGP_s390x_linux)
1139 SysRes res;
1140 UWord args[5];
1141 args[0] = sd;
1142 args[1] = level;
1143 args[2] = optname;
1144 args[3] = (UWord)optval;
1145 args[4] = (UWord)optlen;
1146 res = VG_(do_syscall2)(__NR_socketcall, VKI_SYS_SETSOCKOPT, (UWord)&args);
1147 return sr_isError(res) ? -1 : sr_Res(res);
1149 # elif defined(VGP_amd64_linux) || defined(VGP_arm_linux) \
1150 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
1151 || defined(VGP_arm64_linux)
1152 SysRes res;
1153 res = VG_(do_syscall5)( __NR_setsockopt,
1154 (UWord)sd, (UWord)level, (UWord)optname,
1155 (UWord)optval, (UWord)optlen );
1156 return sr_isError(res) ? -1 : sr_Res(res);
1158 # elif defined(VGO_darwin)
1159 SysRes res;
1160 res = VG_(do_syscall5)( __NR_setsockopt,
1161 (UWord)sd, (UWord)level, (UWord)optname,
1162 (UWord)optval, (UWord)optlen );
1163 return sr_isError(res) ? -1 : sr_Res(res);
1165 # else
1166 # error "Unknown platform"
1167 # endif
1171 const HChar *VG_(basename)(const HChar *path)
1173 static HChar buf[VKI_PATH_MAX];
1175 const HChar *p, *end;
1177 if (path == NULL ||
1178 0 == VG_(strcmp)(path, ""))
1180 return ".";
1183 p = path + VG_(strlen)(path);
1184 while (p > path && *p == '/') {
1185 // skip all trailing '/'
1186 p--;
1189 if (p == path && *p == '/') return "/"; // all slashes
1191 end = p;
1193 while (p > path && *p != '/') {
1194 // now skip non '/'
1195 p--;
1198 if (*p == '/') p++;
1200 VG_(strncpy)(buf, p, end-p+1);
1201 buf[end-p+1] = '\0';
1203 return buf;
1207 const HChar *VG_(dirname)(const HChar *path)
1209 static HChar buf[VKI_PATH_MAX];
1211 const HChar *p;
1213 if (path == NULL ||
1214 0 == VG_(strcmp)(path, "") ||
1215 0 == VG_(strcmp)(path, "/"))
1217 return ".";
1220 p = path + VG_(strlen)(path);
1221 while (p > path && *p == '/') {
1222 // skip all trailing '/'
1223 p--;
1226 while (p > path && *p != '/') {
1227 // now skip non '/'
1228 p--;
1231 if (p == path) {
1232 if (*p == '/') return "/"; // all slashes
1233 else return "."; // no slashes
1236 while (p > path && *p == '/') {
1237 // skip '/' again
1238 p--;
1241 VG_(strncpy)(buf, path, p-path+1);
1242 buf[p-path+1] = '\0';
1244 return buf;
1248 /*--------------------------------------------------------------------*/
1249 /*--- end ---*/
1250 /*--------------------------------------------------------------------*/