static int handle_lcmain ( vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, vki_size_t requested_size ) { if (requested_size == 0) { requested_size = default_stack_size(); } requested_size = VG_PGROUNDUP(requested_size); const vki_size_t HACK = 64 * 1024 * 1024; requested_size += HACK; SysRes res = VG_(am_mmap_anon_float_client)(requested_size, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC); check_mmap_float(res, requested_size, "handle_lcmain"); vg_assert(!sr_isError(res)); *out_stack_start = (vki_uint8_t*)sr_Res(res); *out_stack_end = *out_stack_start + requested_size - 1; Bool need_discard = False; res = VG_(am_munmap_client)(&need_discard, (Addr)*out_stack_start, HACK); if (sr_isError(res)) return -1; vg_assert(!need_discard); // True == wtf? *out_stack_start += HACK; return 0; }
/* Get the dev, inode and mode info for a file descriptor, if possible. Returns True on success. */ Bool ML_(am_get_fd_d_i_m)( Int fd, /*OUT*/ULong* dev, /*OUT*/ULong* ino, /*OUT*/UInt* mode ) { SysRes res; struct vki_stat buf; # if defined(VGO_linux) && defined(__NR_fstat64) /* Try fstat64 first as it can cope with minor and major device numbers outside the 0-255 range and it works properly for x86 binaries on amd64 systems where fstat seems to be broken. */ struct vki_stat64 buf64; res = VG_(do_syscall2)(__NR_fstat64, fd, (UWord)&buf64); if (!sr_isError(res)) { *dev = (ULong)buf64.st_dev; *ino = (ULong)buf64.st_ino; *mode = (UInt) buf64.st_mode; return True; } # endif res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf); if (!sr_isError(res)) { *dev = (ULong)buf.st_dev; *ino = (ULong)buf.st_ino; *mode = (UInt) buf.st_mode; return True; } return False; }
Bool ML_(am_get_fd_d_i_m)( Int fd, ULong* dev, ULong* ino, UInt* mode ) { SysRes res; struct vki_stat buf; # if defined(VGO_linux) && defined(__NR_fstat64) struct vki_stat64 buf64; res = VG_(do_syscall2)(__NR_fstat64, fd, (UWord)&buf64); if (!sr_isError(res)) { *dev = (ULong)buf64.st_dev; *ino = (ULong)buf64.st_ino; *mode = (UInt) buf64.st_mode; return True; } # endif res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf); if (!sr_isError(res)) { *dev = (ULong)buf.st_dev; *ino = (ULong)buf.st_ino; *mode = (UInt) buf.st_mode; return True; } return False; }
static void mv_post_clo_init(void) { if (clo_shared_mem) { SysRes o = VG_(open)(clo_shared_mem, VKI_O_RDWR, 0666); if (sr_isError(o)) { VG_(umsg)("cannot open shared memory file \"%s\"\n", clo_shared_mem); VG_(exit)(1); } SysRes res = VG_(am_shared_mmap_file_float_valgrind) (sizeof(MV_SharedData), VKI_PROT_READ|VKI_PROT_WRITE, sr_Res(o), (Off64T)0); if (sr_isError(res)) { VG_(umsg)("mmap failed\n"); VG_(exit)(1); } theSharedData = (MV_SharedData *)(Addr)sr_Res(res); //VG_(dmsg)("got memory %p\n", theSharedData); theBlockIndex = 0; theBlock = &theSharedData->myData[theBlockIndex]; } else { theBlock = &theBlockData; } }
static void load_client ( /*OUT*/ExeInfo* info, /*OUT*/Addr* client_ip) { HChar* exe_name; Int ret; SysRes res; vg_assert( VG_(args_the_exename) != NULL); exe_name = ML_(find_executable)( VG_(args_the_exename) ); if (!exe_name) { VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename)); VG_(exit)(127); // 127 is Posix NOTFOUND } VG_(memset)(info, 0, sizeof(*info)); ret = VG_(do_exec)(exe_name, info); // The client was successfully loaded! Continue. /* Get hold of a file descriptor which refers to the client executable. This is needed for attaching to GDB. */ res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); if (!sr_isError(res)) VG_(cl_exec_fd) = sr_Res(res); /* Copy necessary bits of 'info' that were filled in */ *client_ip = info->init_ip; }
SysRes ML_(am_do_munmap_NO_NOTIFY)(Addr start, SizeT length) { #if defined(VGO_l4re) SysRes res; Int val; if (0) VG_(debugLog)(1, "aspacem", "%s: munmap start=%p, length=0x%x\n", __func__, (void *)start, (int) length); val = munmap((void *)start, length); if (0) VG_(debugLog)(1, "aspacem", "%s: munmap %s ret=%d\n", __func__, val == -1 ? "failed" : "successful", val); res._isError = (val == -1); if (sr_isError(res)) { // error case res._err = -val; res._res = 0; } else { // no error res._err = 0; res._res = val; } return res; #else return VG_(do_syscall2)(__NR_munmap, (UWord)start, length ); #endif }
static void write_snapshots_to_file(void) { Int i; Char* elune_out_file = VG_(expand_file_name)("--output-filename", clo_outputfilename); sres = VG_(open)(clo_outputfilename, VKI_O_CREAT|VKI_O_TRUNC|VKI_O_WRONLY, VKI_S_IRUSR|VKI_S_IWUSR); if (sr_isError(sres)) { // If the file can't be opened for whatever reason (conflict // between multiple cachegrinded processes?), give up now. VG_(umsg)("error: can't open output file '%s'\n", elune_out_file ); VG_(umsg)(" ... so the log will be missing.\n"); VG_(free)(elune_out_file); return; } else { fd = sr_Res(sres); VG_(free)(elune_out_file); } // Print elune-specific options that were used. if (VG_(args_the_exename)) { /*FP("%s", VG_(args_the_exename));*/ for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i ); if (arg) FP(" %s", arg); } } /*FP("\n");*/ }
static void lk_write_results(VgHashTable table,const char* path) { int fd; SysRes res; res = VG_(open) (path, VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, 0); if (sr_isError(res)) { VG_(printf)("Error opening file!\n"); return; } fd = (int) sr_Res(res); //Go through the hashtable VG_(HT_ResetIter) (table); CountNode* first = (CountNode*)VG_(HT_Next)(table); while(first!=NULL) { char buffer [1000]; int cx = VG_(snprintf)(buffer, 1000, "%08lx,%lu\n",first->key,first->data); VG_(write) (fd, buffer,cx); //move iterator first = (CountNode*)VG_(HT_Next)(table); } /* ar buffer [50]; int n, a=5, b=3; n=sprintf (buffer, "%d plus %d is %d", a, b, a+b); */ //Close file VG_(close)(fd); }
void FZ_(syscall_lseek)(ThreadId tid, UWord *args, UInt nArgs, SysRes res) { if(fengSysFlag){VG_(printf)("feng:entered syscall_lseek\n");} printArgs(args,nArgs,"lseek"); Int fd; //populate_guest_args(tid); fd = ((Int)args[0])/*guest_args[tid].args[3]*/; if (fd < 0 || sr_isError(res) || !tainted_fds[tid][fd]) { return; } position_fds[tid][fd] = sr_Res(res); //// Nothing to do if no file tainting //// But, if stdin tainting, always taint fd 0... /* //if (!FZ_(clo_taint_file)/* && (fd != 0 || !FL_(clo_taint_stdin))*/) { // return; //} //if (fd > -1 && fd < MAXIMUM_FDS) { // resolve_fd(fd, fdpath, MAX_PATH-1); // tainted_fds[tid][res.res] = (VG_(strncmp)(fdpath, FZ_(clo_file_filter), VG_(strlen)(FZ_(clo_file_filter))) == 0); // if (tainted_fds[tid][res.res]) { // position_fds[tid][res.res] = 0; // } // /*if (tainted_fds[tid][res.res]) { // VG_(printf)("tainting file %d\n", res.res); // } // else { // VG_(printf)("not tainting file %d\n", res.res); // }*/ //} }
void FZ_(syscall_munmap)(ThreadId tid, UWord *args, UInt nArgs, SysRes res) { if(fengSysFlag){VG_(printf)("feng:entered syscall_munmap\n");} printArgs(args,nArgs,"munmap"); UInt i, start, length; //populate_guest_args(tid); length = ((UInt)args[1])/*guest_args[tid].args[1]*/; start = ((UInt)args[0])/*guest_args[tid].args[2]*/; //VG_(printf)("[+] munmap(0x%08x, 0x%x)\n", start, length); if (sr_isError(res)) { return; } for (i = 0; i < depaddr8.count; i++) { paddr=getDep(&depaddr8,i); if (paddr->value.addr == start) { break; } } if (i == depaddr8.count) { return; } for (i = 0; i < length; i++) { del_dependency_addr(start + i, 8); } }
static HChar* read_dot_valgrindrc ( HChar* dir ) { Int n; SysRes fd; struct vg_stat stat_buf; HChar* f_clo = NULL; HChar filename[VKI_PATH_MAX]; VG_(snprintf)(filename, VKI_PATH_MAX, "%s/.valgrindrc", ( NULL == dir ? "" : dir ) ); fd = VG_(open)(filename, 0, VKI_S_IRUSR); if ( !sr_isError(fd) ) { Int res = VG_(fstat)( sr_Res(fd), &stat_buf ); // Ignore if not owned by current user or world writeable (CVE-2008-4865) if (!res && stat_buf.uid == VG_(geteuid)() && (!(stat_buf.mode & VKI_S_IWOTH))) { if ( stat_buf.size > 0 ) { f_clo = VG_(malloc)("commandline.rdv.1", stat_buf.size+1); vg_assert(f_clo); n = VG_(read)(sr_Res(fd), f_clo, stat_buf.size); if (n == -1) n = 0; vg_assert(n >= 0 && n <= stat_buf.size+1); f_clo[n] = '\0'; } } else VG_(message)(Vg_UserMsg, "%s was not read as it is world writeable or not owned by the " "current user\n", filename); VG_(close)(sr_Res(fd)); } return f_clo; }
/* * Release a ticket lock by incrementing the head of the queue. Only generate * a thread wakeup signal if at least one thread is waiting. If the queue tail * matches the wakeup_ticket value, no threads have to be woken up. * * Note: tail will only be read after head has been incremented since both are * declared as volatile and since the __sync...() functions imply a memory * barrier. */ static void release_sched_lock(struct sched_lock *p, ThreadId tid, SchedLockKind slk) { unsigned wakeup_ticket, futex_value; volatile unsigned *futex; SysRes sres; vg_assert(p->owner != 0); p->owner = 0; INNER_REQUEST(ANNOTATE_RWLOCK_RELEASED(p, /*is_w*/1)); wakeup_ticket = __sync_fetch_and_add(&p->head, 1) + 1; if (p->tail != wakeup_ticket) { futex = &p->futex[wakeup_ticket & TL_FUTEX_MASK]; futex_value = __sync_fetch_and_add(futex, 1); if (s_debug) VG_(printf)("[%d/%d] release: waking up ticket %d (futex[%ld] = %d)" "\n", VG_(getpid)(), VG_(gettid)(), wakeup_ticket, (long)(futex - p->futex), futex_value); sres = VG_(do_syscall3)(__NR_futex, (UWord)futex, VKI_FUTEX_WAKE | VKI_FUTEX_PRIVATE_FLAG, 0x7fffffff); vg_assert(!sr_isError(sres)); } else { if (s_debug) VG_(printf)("[%d/%d] release: no thread is waiting for ticket %d\n", VG_(getpid)(), VG_(gettid)(), wakeup_ticket); } }
/* Load a Mach-O executable or dylinker. The file may be fat or thin. */ static int load_mach_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, const char *filename, vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry) { vki_uint32_t magic; SysRes res; if (size < sizeof(magic)) { print("bad executable (no Mach-O magic)\n"); return -1; } res = VG_(pread)(fd, &magic, sizeof(magic), offset); if (sr_isError(res) || sr_Res(res) != sizeof(magic)) { print("bad executable (no Mach-O magic)\n"); return -1; } if (magic == MAGIC) { // thin return load_thin_file(fd, offset, size, filetype, filename, out_stack_start, out_stack_end, out_text, out_entry, out_linker_entry); } else if (magic == VG_(htonl)(FAT_MAGIC)) { // fat return load_fat_file(fd, offset, size, filetype, filename, out_stack_start, out_stack_end, out_text, out_entry, out_linker_entry); } else { // huh? print("bad executable (bad Mach-O magic)\n"); return -1; } }
void FZ_(syscall_write)(ThreadId tid, UWord *args, UInt nArgs, SysRes res) { if(fengSysFlag){VG_(printf)("feng:entered syscall_write\n");} printArgs(args,nArgs,"write"); UInt i, k; Int fd = -1; Char *data = NULL; //populate_guest_args(tid); fd = ((Int)args[0])/*guest_args[tid].args[3]*/; data = (Char *)(args[1]/*guest_args[tid].args[1]*/); if (fd < 0 || sr_isError(res)) { return; } k = position_fds[tid][fd]; for (i = 0; i < sr_Res(res); i++) { #ifdef FENG_AMD64 char * cons = depend_on_addr((Addr)(ULong)(data + i), 8); VG_(printf)("[+] tid %d write(%d) tainted byte %d (0x%08x) %s\n", tid, fd, k + i, (Addr)(ULong)(data + i), cons); #else char * cons = depend_on_addr((Addr)(UInt)(data + i), 8); VG_(printf)("[+] tid %d write(%d) tainted byte %d (0x%08x) %s\n", tid, fd, k + i, (Addr)(UInt)(data + i), cons); #endif // FENG_AMD64 } }
/* * Acquire ticket lock. Increment the tail of the queue and use the original * value as the ticket value. Wait until the head of the queue equals the * ticket value. The futex used to wait depends on the ticket value in order * to avoid that all threads get woken up every time a ticket lock is * released. That last effect is sometimes called the "thundering herd" * effect. * * See also Nick Piggin, x86: FIFO ticket spinlocks, Linux kernel mailing list * (http://lkml.org/lkml/2007/11/1/125) for more info. */ static void acquire_sched_lock(struct sched_lock *p, ThreadId tid, SchedLockKind slk) { unsigned ticket, futex_value; volatile unsigned *futex; SysRes sres; ticket = __sync_fetch_and_add(&p->tail, 1); futex = &p->futex[ticket & TL_FUTEX_MASK]; if (s_debug) VG_(printf)("[%d/%d] acquire: ticket %d\n", VG_(getpid)(), VG_(gettid)(), ticket); for (;;) { futex_value = *futex; __sync_synchronize(); if (ticket == p->head) break; if (s_debug) VG_(printf)("[%d/%d] acquire: ticket %d - waiting until" " futex[%ld] != %d\n", VG_(getpid)(), VG_(gettid)(), ticket, (long)(futex - p->futex), futex_value); sres = VG_(do_syscall3)(__NR_futex, (UWord)futex, VKI_FUTEX_WAIT | VKI_FUTEX_PRIVATE_FLAG, futex_value); if (sr_isError(sres) && sres._val != VKI_EAGAIN) { VG_(printf)("futex_wait() returned error code %ld\n", sres._val); vg_assert(False); } } __sync_synchronize(); INNER_REQUEST(ANNOTATE_RWLOCK_ACQUIRED(p, /*is_w*/1)); vg_assert(p->owner == 0); p->owner = VG_(gettid)(); }
void FZ_(syscall_mmap2)(ThreadId tid, UWord *args, UInt nArgs, SysRes res) { if (fengSysFlag){VG_(printf)("feng:entered syscall_mmap2\n");} printArgs(args,nArgs,"mmap2"); UInt i, j, length, offset; Int fd = -1; Char *data = NULL; //populate_guest_args(tid); fd = ((Int)args[4])/*guest_args[tid].args[5]*/; length = ((UInt)args[1])/*guest_args[tid].args[1]*/; data = ((Char *)args[0]); offset = ((UInt)args[5])/*guest_args[tid].args[6]*/; //VG_(printf)("[+] mmap2(0x%08x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) = 0x%08x\n", guest_args[tid].args[3], length, guest_args[tid].args[2], guest_args[tid].args[4], fd, offset, data); if (fd < 0 || sr_isError(res) || !tainted_fds[tid][fd]) { return; } for (i = 0; i < length; i++) { #ifdef FENG_AMD64 if(fengSysFlag){VG_(printf)("feng:addr:%x\n",((ULong)data + i));} j = add_dependency_addr((Addr)((ULong)data + i), 8); VG_(printf)("[+] mmap2() tainting byte %d (0x%08x)\n", offset + i, (ULong)(data + i)); pj=getDep(&depaddr8,j); VG_(snprintf)(pj->cons, XXX_MAX_BUF, "input(%d)", offset + i); #else if(fengSysFlag){VG_(printf)("feng:addr:%x\n",((UInt)data + i));} j = add_dependency_addr((Addr)((UInt)data + i), 8); VG_(printf)("[+] mmap2() tainting byte %d (0x%08x)\n", offset + i, (UInt)(data + i)); pj=getDep(&depaddr8,j); VG_(snprintf)(pj->cons, XXX_MAX_BUF, "input(%d)", offset + i); #endif // FENG_AMD64 } }
void FZ_(syscall_open)(ThreadId tid, UWord *args, UInt nArgs, SysRes res) { if(fengSysFlag){VG_(printf)("feng:entered syscall_open\n");} printArgs(args,nArgs,"open"); Char fdpath[MAX_PATH]={0}; Int fd = sr_Res(res); // Nothing to do if no file tainting // But, if stdin tainting, always taint fd 0... if (!FZ_(clo_taint_file)/* && (fd != 0 || !FL_(clo_taint_stdin))*/) { return; } //populate_guest_args(tid); if (!sr_isError(res) && fd < MAXIMUM_FDS) { resolve_fd(fd, fdpath, MAX_PATH-1); tainted_fds[tid][sr_Res(res)] = (VG_(strncmp)(fdpath, FZ_(clo_file_filter), VG_(strlen)(FZ_(clo_file_filter))) == 0); VG_(printf)("[?] tid %d open(%d) fdpath=%s clo_file_filter=%s\n", tid, fd, fdpath, FZ_(clo_file_filter)); if (tainted_fds[tid][sr_Res(res)]) { VG_(printf)("[+] tid %d open(%d)\n", tid, fd); position_fds[tid][sr_Res(res)] = 0; } /*if (tainted_fds[tid][sr_Res(res)]) { VG_(printf)("tainting file %d\n", sr_Res(res)); } else { VG_(printf)("not tainting file %d\n", sr_Res(res)); }*/ } }
static void give_control_back_to_vgdb(void) { #if !defined(VGO_solaris) /* cause a SIGSTOP to be sent to ourself, so that vgdb takes control. vgdb will then restore the stack so as to resume the activity before the ptrace (typically do_syscall_WRK). */ if (VG_(kill)(VG_(getpid)(), VKI_SIGSTOP) != 0) vg_assert2(0, "SIGSTOP for vgdb could not be generated\n"); /* If we arrive here, it means a call was pushed on the stack by vgdb, but during this call, vgdb and/or connection died. Alternatively, it is a bug in the vgdb<=>Valgrind gdbserver ptrace handling. */ vg_assert2(0, "vgdb did not took control. Did you kill vgdb ?\n" "busy %d vgdb_interrupted_tid %u\n", busy, vgdb_interrupted_tid); #else /* defined(VGO_solaris) */ /* On Solaris, this code is run within the context of an agent thread (see vgdb-invoker-solaris.c and "PCAGENT" control message in proc(4)). Exit the agent thread now. */ SysRes sres = VG_(do_syscall0)(SYS_lwp_exit); if (sr_isError(sres)) vg_assert2(0, "The agent thread could not be exited\n"); #endif /* !defined(VGO_solaris) */ }
static void check_mmap(SysRes res, Addr base, SizeT len, HChar* who) { if (sr_isError(res)) { VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME (%s).\n", (ULong)base, (Long)len, who); VG_(exit)(1); } }
static void check_mmap_float(SysRes res, SizeT len, const HChar* who) { if (sr_isError(res)) { VG_(printf)("valgrind: mmap-FLOAT(size=%lld) failed in UME (%s).\n", (Long)len, who); VG_(exit)(1); } }
Int ML_(am_read) ( Int fd, void* buf, Int count) { #if defined(VGO_l4re) VG_(unimplemented)((char*)__func__); return -1; #else SysRes res = VG_(do_syscall3)(__NR_read, fd, (UWord)buf, count); return sr_isError(res) ? -1 : sr_Res(res); #endif }
Int ML_(am_getpid)( void ) { #if defined(VGO_l4re) VG_(unimplemented)((char*)__func__); #else SysRes sres = VG_(do_syscall0)(__NR_getpid); aspacem_assert(!sr_isError(sres)); return sr_Res(sres); #endif }
/* Get the dev, inode and mode info for a file descriptor, if possible. Returns True on success. */ Bool ML_(am_get_fd_d_i_m)( Int fd, /*OUT*/ULong* dev, /*OUT*/ULong* ino, /*OUT*/UInt* mode ) { SysRes res; struct vki_stat buf; # if defined(VGO_linux) && defined(__NR_fstat64) /* Try fstat64 first as it can cope with minor and major device numbers outside the 0-255 range and it works properly for x86 binaries on amd64 systems where fstat seems to be broken. */ struct vki_stat64 buf64; res = VG_(do_syscall2)(__NR_fstat64, fd, (UWord)&buf64); if (!sr_isError(res)) { *dev = (ULong)buf64.st_dev; *ino = (ULong)buf64.st_ino; *mode = (UInt) buf64.st_mode; return True; } # elif defined(VGO_l4re) int ret; struct stat buf2; // VG_(debugLog)(0, "aspacem", " dev %p, ino %p, mode %p\n", dev, ino, mode); // VG_(debugLog)(0, "aspacem", "before fstat()\n"); ret = fstat(fd, &buf2); // VG_(debugLog)(0, "aspacem", " ...fstat() = %d\n", ret); if (ret == 0) { *dev = buf2.st_dev; *ino = buf2.st_ino; *mode = buf2.st_mode; return True; } return False; # else res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf); if (!sr_isError(res)) { *dev = (ULong)buf.st_dev; *ino = (ULong)buf.st_ino; *mode = (UInt) buf.st_mode; return True; } return False; # endif }
Int ML_(am_fcntl) ( Int fd, Int cmd, Addr arg ) { # if defined(VGO_linux) SysRes res = VG_(do_syscall3)(__NR_fcntl, fd, cmd, arg); # elif defined(VGO_darwin) SysRes res = VG_(do_syscall3)(__NR_fcntl_nocancel, fd, cmd, arg); # else # error "Unknown OS" # endif return sr_isError(res) ? -1 : sr_Res(res); }
/* Unmap an image mapped in by map_image_aboard. */ static void unmap_image ( /*MOD*/ImageInfo* ii ) { SysRes sres; vg_assert(ii->img); vg_assert(ii->img_szB > 0); sres = VG_(am_munmap_valgrind)( (Addr)ii->img, ii->img_szB ); /* Do we care if this fails? I suppose so; it would indicate some fairly serious snafu with the mapping of the file. */ vg_assert( !sr_isError(sres) ); VG_(memset)(ii, 0, sizeof(*ii)); }
Int ML_(am_readlink)(HChar* path, HChar* buf, UInt bufsiz) { #if defined(VGO_l4re) VG_(unimplemented)((char*)__func__); return -1; #else SysRes res; res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz); return sr_isError(res) ? -1 : sr_Res(res); #endif }
Int ML_(am_readlink)(const HChar* path, HChar* buf, UInt bufsiz) { SysRes res; # if defined(VGP_arm64_linux) res = VG_(do_syscall4)(__NR_readlinkat, VKI_AT_FDCWD, (UWord)path, (UWord)buf, bufsiz); # else res = VG_(do_syscall3)(__NR_readlink, (UWord)path, (UWord)buf, bufsiz); # endif return sr_isError(res) ? -1 : sr_Res(res); }
static Region_map *vrm_determine_local_rm_address() { /* * Determine the address of the RE kernel's local RM. */ /* * 1. Try to find symbol in ELF image file */ if (dbg_elf) VG_(printf)("opening rom/l4re\n"); SysRes res = VG_(open)((const Char*)"rom/l4re", VKI_O_RDONLY, 0); if (dbg_elf) VG_(printf)("opened: %ld\n", sr_Res(res)); if (sr_isError(res)) { VG_(printf)("Error opening file: %ld\n", sr_Err(res)); enter_kdebug(); } int fd = sr_Res(res); struct vg_stat statbuf; int err = VG_(fstat)(fd, &statbuf); if (dbg_elf) VG_(printf)("stat: %d, size %d\n", err, (int)statbuf.size); if (err) { VG_(printf)("error on fstat(): %d\n", err); enter_kdebug(); } void *a = 0; a = mmap(a, statbuf.size, VKI_PROT_READ, VKI_MAP_PRIVATE, fd, 0); if (dbg_elf) VG_(printf)("mmap to %p\n", a); melf_global_elf_info i; err = melf_parse_elf(a, &i); if (dbg_elf) VG_(printf)("parsed: %d\n", err); char *rm_addr = melf_find_symbol_by_name(&i, (char*)"__local_rm"); if (dbg_elf) VG_(printf)("Found symbol %s @ %p\n", (char*)"__local_rm", rm_addr); munmap(a, VG_PGROUNDUP(statbuf.size)); VG_(close)(fd); if (rm_addr) return reinterpret_cast<Region_map*>(rm_addr); /* * 2. If not successful parsing binary, try hard-coded value */ VG_(printf)("Did not find local-rm, aborting\n"); VG_(exit)(1); /* Not found? */ }
static Bool is_hash_bang_file(Char* f) { SysRes res = VG_(open)(f, VKI_O_RDONLY, 0); if (!sr_isError(res)) { Char buf[3] = {0,0,0}; Int fd = sr_Res(res); Int n = VG_(read)(fd, buf, 2); if (n == 2 && VG_STREQ("#!", buf)) return True; } return False; }
static void check_mmap(SysRes res, Addr base, SizeT len) { if (sr_isError(res)) { VG_(printf)("valgrind: mmap(0x%llx, %lld) failed in UME " "with error %lu (%s).\n", (ULong)base, (Long)len, sr_Err(res), VG_(strerror)(sr_Err(res)) ); if (sr_Err(res) == VKI_EINVAL) { VG_(printf)("valgrind: this can be caused by executables with " "very large text, data or bss segments.\n"); } VG_(exit)(1); } }