Exemplo n.º 1
0
func (k *CgcKernel) Random(buf co.Obuf, size uint32, ret co.Obuf) {
	tmp := make([]byte, size)
	n, _ := rand.Read(tmp)
	tmp = tmp[:n]
	buf.Pack(tmp)
	ret.Pack(uint32(n))
}
Exemplo n.º 2
0
func (k *PosixKernel) Time(out co.Obuf) uint64 {
	t := time.Now().Unix()
	if out.Addr != 0 {
		out.Pack(struc.Size_t(t))
	}
	return uint64(t)
}
Exemplo n.º 3
0
func (k *PosixKernel) ClockGettime(_ int, out co.Obuf) uint64 {
	ts := syscall.NsecToTimespec(time.Now().UnixNano())
	err := out.Pack(&native.Timespec{int64(ts.Sec), int64(ts.Nsec)})
	if err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 4
0
func (k *CgcKernel) Transmit(fd co.Fd, buf co.Buf, size co.Len, ret co.Obuf) int {
	mem, _ := k.U.MemRead(buf.Addr, uint64(size))
	n, err := syscall.Write(int(fd), mem)
	if err != nil {
		return -1 // FIXME
	}
	ret.Pack(int32(n))
	return 0
}
Exemplo n.º 5
0
func (k *CgcKernel) Allocate(size uint32, executable int32, ret co.Obuf) int {
	mmap, _ := k.U.Mmap(0, uint64(size))
	mmap.Desc = "heap"
	if executable != 0 {
		k.U.MemProtect(mmap.Addr, mmap.Size, uc.PROT_ALL)
	}
	ret.Pack(uint32(mmap.Addr))
	return 0
}
Exemplo n.º 6
0
func (k *PosixKernel) Fstatfs(fd co.Fd, statfs co.Obuf) uint64 {
	var tmp syscall.Statfs_t
	if err := syscall.Fstatfs(int(fd), &tmp); err != nil {
		return Errno(err)
	}
	if err := statfs.Pack(&tmp); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 7
0
func (k *CgcKernel) Receive(fd co.Fd, buf co.Obuf, size co.Len, ret co.Obuf) int {
	tmp := make([]byte, size)
	n, err := syscall.Read(int(fd), tmp)
	if err != nil {
		return -1 // FIXME
	}
	buf.Pack(tmp[:n])
	ret.Pack(int32(n))
	return 0
}
Exemplo n.º 8
0
func (k *PosixKernel) Socketpair(domain, typ, proto int, vector co.Obuf) uint64 {
	pair, err := syscall.Socketpair(domain, typ, proto)
	if err != nil {
		return Errno(err)
	}
	if err := vector.Pack(pair); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 9
0
func (k *PosixKernel) Statfs(path string, statfs co.Obuf) uint64 {
	var tmp syscall.Statfs_t
	if err := syscall.Statfs(path, &tmp); err != nil {
		return Errno(err)
	}
	if err := statfs.Pack(&tmp); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 10
0
func (k *LinuxKernel) Gettimeofday(tp co.Obuf, tz *native.Timespec) uint64 {
	now := time.Now()
	res := native.Timespec{
		Sec:  int64(now.Unix()),
		Nsec: int64(now.Nanosecond()),
	}
	if err := tp.Pack(&res); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 11
0
func (k *PosixKernel) Lstat(path string, buf co.Obuf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Lstat(path, &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}
Exemplo n.º 12
0
func (k *PosixKernel) Pread64(fd co.Fd, buf co.Obuf, size co.Len, offset int64) uint64 {
	p := make([]byte, size)
	n, err := syscall.Pread(int(fd), p, offset)
	if err != nil {
		return Errno(err)
	}
	if err := buf.Pack(p); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(n)
}
Exemplo n.º 13
0
func (k *PosixKernel) Getcwd(buf co.Obuf, size co.Len) uint64 {
	wd, _ := os.Getwd()
	size -= 1
	if co.Len(len(wd)) > size {
		wd = wd[:size]
	}
	if err := buf.Pack(wd + "\x00"); err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 14
0
func (k *PosixKernel) Read(fd co.Fd, buf co.Obuf, size co.Len) uint64 {
	tmp := make([]byte, size)
	n, err := syscall.Read(int(fd), tmp)
	if err != nil {
		return Errno(err)
	}
	if err := buf.Pack(tmp[:n]); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(n)
}
Exemplo n.º 15
0
func (k *PosixKernel) Fstat(fd co.Fd, buf co.Obuf) uint64 {
	var stat syscall.Stat_t
	if err := syscall.Fstat(int(fd), &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}
Exemplo n.º 16
0
func (k *PosixKernel) ClockGettime(_ int, out co.Obuf) uint64 {
	var err error
	ts := syscall.NsecToTimespec(time.Now().UnixNano())
	if k.U.Bits() == 64 {
		err = out.Pack(&Timespec64{ts.Sec, ts.Nsec})
	} else {
		err = out.Pack(&Timespec{int32(ts.Sec), int32(ts.Nsec)})
	}
	if err != nil {
		return UINT64_MAX // FIXME
	}
	return 0
}
Exemplo n.º 17
0
func (k *PosixKernel) ClockGetres(clockid int, out co.Obuf) uint64 {
	// TODO: I'm just assuming you have a nanosecond-accurate clock available
	if out.Addr != 0 {
		res := native.Timespec{
			Sec:  0,
			Nsec: 1,
		}
		if err := out.Pack(&res); err != nil {
			return UINT64_MAX // FIXME
		}
	}
	return 0
}
Exemplo n.º 18
0
func (k *PosixKernel) Stat(path string, buf co.Obuf) uint64 {
	// TODO: centralize path hook
	if strings.HasPrefix(path, "/") {
		path = k.U.PrefixPath(path, false)
	}
	var stat syscall.Stat_t
	if err := syscall.Stat(path, &stat); err != nil {
		return Errno(err)
	}
	targetStat := NewTargetStat(&stat, k.U.OS(), k.U.Bits())
	if err := buf.Pack(targetStat); err != nil {
		panic(err)
	}
	return 0
}
Exemplo n.º 19
0
func (k *CgcKernel) Fdwait(nfds int, reads, writes, timeoutBuf co.Buf, readyFds co.Obuf) int {
	var readSet, writeSet *native.Fdset32
	var timeout native.Timespec
	reads.Unpack(&readSet)
	writes.Unpack(&writeSet)
	timeoutBuf.Unpack(&timeout)

	readNative := readSet.Native()
	writeNative := writeSet.Native()

	n, err := native.Select(nfds, readNative, writeNative, &timeout)
	if err != nil {
		return -1 // FIXME?
	} else {
		readyFds.Pack(int32(n))
	}
	return 0
}
Exemplo n.º 20
0
func (k *PosixKernel) Readlink(path string, buf co.Obuf, size co.Len) uint64 {
	// TODO: full proc emulation layer
	// maybe have a syscall pre-hook for this after ghostrace makes it generic
	// or specifically have path hooks and use that to implement prefix as well
	var name string
	var err error
	if path == "/proc/self/exe" && k.U.OS() == "linux" {
		name = k.U.Exe()
	} else {
		name, err = os.Readlink(path)
		if err != nil {
			return UINT64_MAX // FIXME
		}
	}
	if len(name) > int(size) {
		name = name[:size]
	}
	if err := buf.Pack([]byte(name)); err != nil {
		return UINT64_MAX // FIXME
	}
	return uint64(len(name))
}
Exemplo n.º 21
0
func (k *LinuxKernel) getdents(dirfd co.Fd, buf co.Obuf, count uint64, bits uint) uint64 {
	dir, ok := k.Files[dirfd]
	if !ok {
		return UINT64_MAX // FIXME
	}
	dents := dir.Dirents
	if dents == nil {
		dent, err := os.Lstat(path.Join(dir.Path, ".."))
		if err == nil {
			dents = append(dents, fileInfoProxy{dent, ".."})
		}
		dent, err = os.Lstat(dir.Path)
		if err == nil {
			dents = append(dents, fileInfoProxy{dent, "."})
		}
		contents, err := ioutil.ReadDir(dir.Path)
		if err != nil {
			return UINT64_MAX // FIXME
		}
		dents = append(dents, contents...)
		dir.Dirents = dents
	}
	if dir.Offset >= uint64(len(dents)) {
		return 0
	}
	dents = dents[dir.Offset:]
	written := 0
	offset := dir.Offset
	out := buf.Struc()
	for i, f := range dents {
		// TODO: syscall.Stat_t portability?
		inode := f.Sys().(*syscall.Stat_t).Ino
		// figure out file mode
		mode := f.Mode()
		fileType := DT_REG
		if f.IsDir() {
			fileType = DT_DIR
		} else if mode&os.ModeNamedPipe > 0 {
			fileType = DT_FIFO
		} else if mode&os.ModeSymlink > 0 {
			fileType = DT_LNK
		} else if mode&os.ModeDevice > 0 {
			if mode&os.ModeCharDevice > 0 {
				fileType = DT_CHR
			} else {
				fileType = DT_BLK
			}
		} else if mode&os.ModeSocket > 0 {
			fileType = DT_SOCK
		}
		// TODO: does inode get truncated? guess it depends on guest LFS support
		var ent interface{}
		if bits == 64 {
			ent = &Dirent64{inode, dir.Offset + uint64(i), 0, fileType, f.Name() + "\x00"}
		} else {
			ent = &Dirent{inode, dir.Offset + uint64(i), 0, f.Name() + "\x00", fileType}
		}
		size, _ := struc.Sizeof(ent)
		if uint64(written+size) > count {
			break
		}
		offset++
		if bits == 64 {
			ent.(*Dirent64).Len = size
		} else {
			ent.(*Dirent).Len = size
		}
		written += size
		if err := out.Pack(ent); err != nil {
			return UINT64_MAX // FIXME
		}
	}
	dir.Offset = offset
	return uint64(written)
}
Exemplo n.º 22
0
func (k *LinuxKernel) Getdents(dirfd co.Fd, buf co.Obuf, count uint64) uint64 {
	dirPath, err := posix.PathFromFd(int(dirfd))
	if err != nil {
		return UINT64_MAX // FIXME
	}
	dents, err := ioutil.ReadDir(dirPath)
	if err != nil {
		return UINT64_MAX // FIXME
	}
	// figure out our offset
	// TODO: maybe figure out how a real kernel does this
	in := k.U.StrucAt(buf.Addr)
	var offset, read uint64
	// TODO: DRY? :(
	var ent interface{}
	if k.U.Bits() == 64 {
		ent = &Dirent64{}
	} else {
		ent = &Dirent{}
	}
	for {
		tmp := ent.(*Dirent64)
		if err := in.Unpack(ent); err != nil {
			break
		}
		size, _ := struc.Sizeof(ent)
		if read+uint64(size) > count {
			break
		}
		if tmp.Off > 0 {
			offset = tmp.Off
		}
		if tmp.Len == 0 {
			break
		}
	}
	if offset >= uint64(len(dents)) {
		return 0
	}
	dents = dents[offset:]
	written := 0
	for i, f := range dents {
		// TODO: syscall.Stat_t portability?
		inode := f.Sys().(*syscall.Stat_t).Ino
		// figure out file mode
		mode := f.Mode()
		fileType := DT_REG
		if f.IsDir() {
			fileType = DT_DIR
		} else if mode&os.ModeNamedPipe > 0 {
			fileType = DT_FIFO
		} else if mode&os.ModeSymlink > 0 {
			fileType = DT_LNK
		} else if mode&os.ModeDevice > 0 {
			if mode&os.ModeCharDevice > 0 {
				fileType = DT_CHR
			} else {
				fileType = DT_BLK
			}
		} else if mode&os.ModeSocket > 0 {
			fileType = DT_SOCK
		}
		// TODO: does inode get truncated? I guess there's getdents64
		var ent interface{}
		if k.U.Bits() == 64 {
			ent = &Dirent64{inode, uint64(i), 0, f.Name() + "\x00", fileType}
		} else {
			ent = &Dirent{inode, uint64(i), 0, f.Name() + "\x00", fileType}
		}
		size, _ := struc.Sizeof(ent)
		if uint64(written+size) > count {
			break
		}
		if k.U.Bits() == 64 {
			ent.(*Dirent64).Len = size
		} else {
			ent.(*Dirent).Len = size
		}
		written += size
		if err := buf.Pack(ent); err != nil {
			return UINT64_MAX // FIXME
		}
	}
	return uint64(written)
}
Exemplo n.º 23
0
func putfdset(b co.Obuf, fdset *syscall.FdSet) error {
	if fdset != nil && b.Addr != 0 {
		return b.Pack(fdset)
	}
	return nil
}