提交 70680858 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-bsd-user-20140611' into staging

bsd-user queue:
 * build fixes
 * improvements to strace

# gpg: Signature made Wed 11 Jun 2014 15:23:40 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-bsd-user-20140611:
  bsd-user: Fix syscall format, add strace support for more syscalls
  bsd-user: Implement strace support for thr_* syscalls
  bsd-user: Implement strace support for extattr_* syscalls
  bsd-user: Implement strace support for __acl_* syscalls
  bsd-user: Implement strace support for print_ioctl syscall
  bsd-user: Implement strace support for print_sysctl syscall
  bsd-user: GPL v2 attribution update and style
  bsd-user: add HOST_VARIANT_DIR for various *BSD dependent code
  exec: replace ffsl with ctzl
  vhost: replace ffsl with ctzl
  xen: replace ffsl with ctzl
  util/qemu-openpty: fix build with musl libc by include termios.h as fallback
  bsd-user/mmap.c: Don't try to override g_malloc/g_free
  util/hbitmap.c: Use ctpopl rather than reimplementing a local equivalent
  bsd-user: refresh freebsd system call numbers
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -102,7 +102,8 @@ endif #CONFIG_LINUX_USER
ifdef CONFIG_BSD_USER
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR)
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \
-I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR)
obj-y += bsd-user/
obj-y += gdbstub.o user-exec.o
......
{ TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL },
/*
* FreeBSD strace list
*
*
* 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, see <http://www.gnu.org/licenses/>.
*/
{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_aclcheck_fd", "%s(%d, %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_aclcheck_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_aclcheck_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_set_fd", "%s(%d, %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_set_file, "__acl_set_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_set_link, "__acl_set_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL },
{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL },
......@@ -20,24 +50,41 @@
{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(\"%s\",%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL },
{ TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL },
{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL },
{ TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL },
{ TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_getcontext, "getcontext", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL },
......@@ -63,7 +110,7 @@
{ TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL },
{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL },
{ TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL },
{ TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL },
......@@ -72,6 +119,7 @@
{ TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL },
{ TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL },
......@@ -96,7 +144,8 @@
{ TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_pathconf, "pathconf", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL },
......@@ -116,6 +165,7 @@
{ TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL },
{ TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
......@@ -123,6 +173,7 @@
{ TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_setcontext, "setcontext", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL },
......@@ -151,7 +202,7 @@
{ TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL },
......@@ -160,6 +211,15 @@
{ TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_thr_create, "thr_create", "%s(%#x, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", "%s(%d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", "%s(%d, %d, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_new, "thr_new", "%s(%#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_self, "thr_self", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", "%s(%d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", "%s(%d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", "%s(%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL },
......
此差异已折叠。
......@@ -74,66 +74,6 @@ void mmap_unlock(void)
}
#endif
static void *bsd_vmalloc(size_t size)
{
void *p;
mmap_lock();
/* Use map and mark the pages as used. */
p = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (h2g_valid(p)) {
/* Allocated region overlaps guest address space.
This may recurse. */
abi_ulong addr = h2g(p);
page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size),
PAGE_RESERVED);
}
mmap_unlock();
return p;
}
void *g_malloc(size_t size)
{
char * p;
size += 16;
p = bsd_vmalloc(size);
*(size_t *)p = size;
return p + 16;
}
/* We use map, which is always zero initialized. */
void * g_malloc0(size_t size)
{
return g_malloc(size);
}
void g_free(void *ptr)
{
/* FIXME: We should unmark the reserved pages here. However this gets
complicated when one target page spans multiple host pages, so we
don't bother. */
size_t *p;
p = (size_t *)((char *)ptr - 16);
munmap(p, *p);
}
void *g_realloc(void *ptr, size_t size)
{
size_t old_size, copy;
void *new_ptr;
if (!ptr)
return g_malloc(size);
old_size = *(size_t *)((char *)ptr - 16);
copy = old_size < size ? old_size : size;
new_ptr = g_malloc(size);
memcpy(new_ptr, ptr, copy);
g_free(ptr);
return new_ptr;
}
/* NOTE: all the constants are the HOST ones, but addresses are target. */
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
{
......
/*
* qemu bsd user mode definition
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_H
#define QEMU_H
......@@ -150,6 +166,16 @@ void fork_end(int child);
#include "qemu/log.h"
/* strace.c */
struct syscallname {
int nr;
const char *name;
const char *format;
void (*call)(const struct syscallname *,
abi_long, abi_long, abi_long,
abi_long, abi_long, abi_long);
void (*result)(const struct syscallname *, abi_long);
};
void
print_freebsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
......
/*
* System call tracing and debugging
*
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/ioccom.h>
#include <ctype.h>
#include "qemu.h"
int do_strace=0;
struct syscallname {
int nr;
const char *name;
const char *format;
void (*call)(const struct syscallname *,
abi_long, abi_long, abi_long,
abi_long, abi_long, abi_long);
void (*result)(const struct syscallname *, abi_long);
};
int do_strace;
/*
* Utility functions
*/
static void
print_execve(const struct syscallname *name,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
static void print_sysctl(const struct syscallname *name, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
abi_long arg6)
{
uint32_t i;
int32_t *namep;
gemu_log("%s({ ", name->name);
namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1);
if (namep) {
int32_t *p = namep;
for (i = 0; i < (uint32_t)arg2; i++) {
gemu_log("%d ", tswap32(*p++));
}
unlock_user(namep, arg1, 0);
}
gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x"
TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")",
(uint32_t)arg2, arg3, arg4, arg5, arg6);
}
static void print_execve(const struct syscallname *name, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
abi_long arg6)
{
abi_ulong arg_ptr_addr;
char *s;
if (!(s = lock_user_string(arg1)))
s = lock_user_string(arg1);
if (s == NULL) {
return;
}
gemu_log("%s(\"%s\",{", name->name, s);
unlock_user(s, arg1, 0);
......@@ -39,29 +73,48 @@ print_execve(const struct syscallname *name,
abi_ulong *arg_ptr, arg_addr;
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
if (!arg_ptr)
if (!arg_ptr) {
return;
}
arg_addr = tswapl(*arg_ptr);
unlock_user(arg_ptr, arg_ptr_addr, 0);
if (!arg_addr)
if (!arg_addr) {
break;
}
if ((s = lock_user_string(arg_addr))) {
gemu_log("\"%s\",", s);
unlock_user(s, arg_addr, 0);
}
}
gemu_log("NULL})");
}
static void print_ioctl(const struct syscallname *name,
abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6)
{
/* Decode the ioctl request */
gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x"
TARGET_ABI_FMT_lx ", ...)",
name->name,
(int)arg1,
(unsigned long)arg2,
arg2 & IOC_OUT ? "R" : "",
arg2 & IOC_IN ? "W" : "",
(unsigned)IOCGROUP(arg2),
isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?',
(int)arg2 & 0xFF,
(int)IOCPARM_LEN(arg2),
arg3);
}
/*
* Variants for the return value output function
*/
static void
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
{
if( ret == -1 ) {
if (ret == -1) {
gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
} else {
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
......@@ -90,10 +143,9 @@ static const struct syscallname openbsd_scnames[] = {
#include "openbsd/strace.list"
};
static void
print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
static void print_syscall(int num, const struct syscallname *scnames,
unsigned int nscnames, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
unsigned int i;
const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
......@@ -102,36 +154,37 @@ print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
gemu_log("%d ", getpid() );
for (i = 0; i < nscnames; i++)
for (i = 0; i < nscnames; i++) {
if (scnames[i].nr == num) {
if (scnames[i].call != NULL) {
scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
arg6);
arg6);
} else {
/* XXX: this format system is broken because it uses
host types and host pointers for strings */
if (scnames[i].format != NULL)
if (scnames[i].format != NULL) {
format = scnames[i].format;
gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4,
arg5, arg6);
}
gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, arg5,
arg6);
}
return;
}
}
gemu_log("Unknown syscall %d\n", num);
}
static void
print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
unsigned int nscnames)
static void print_syscall_ret(int num, abi_long ret,
const struct syscallname *scnames, unsigned int nscnames)
{
unsigned int i;
for (i = 0; i < nscnames; i++)
for (i = 0; i < nscnames; i++) {
if (scnames[i].nr == num) {
if (scnames[i].result != NULL) {
scnames[i].result(&scnames[i], ret);
} else {
if( ret < 0 ) {
if (ret < 0) {
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
strerror(-ret));
} else {
......@@ -140,52 +193,50 @@ print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
}
break;
}
}
}
/*
* The public interface to this module.
*/
void
print_freebsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
arg1, arg2, arg3, arg4, arg5, arg6);
print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2,
arg3, arg4, arg5, arg6);
}
void
print_freebsd_syscall_ret(int num, abi_long ret)
void print_freebsd_syscall_ret(int num, abi_long ret)
{
print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
}
void
print_netbsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
void print_netbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
arg1, arg2, arg3, arg4, arg5, arg6);
}
void
print_netbsd_syscall_ret(int num, abi_long ret)
void print_netbsd_syscall_ret(int num, abi_long ret)
{
print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
}
void
print_openbsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
void print_openbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames),
arg1, arg2, arg3, arg4, arg5, arg6);
print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), arg1, arg2,
arg3, arg4, arg5, arg6);
}
void
print_openbsd_syscall_ret(int num, abi_long ret)
void print_openbsd_syscall_ret(int num, abi_long ret)
{
print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
}
......@@ -546,6 +546,9 @@ fi
# OS specific
# host *BSD for user mode
HOST_VARIANT_DIR=""
case $targetos in
CYGWIN*)
mingw32="yes"
......@@ -571,12 +574,14 @@ FreeBSD)
# needed for kinfo_getvmmap(3) in libutil.h
LIBS="-lutil $LIBS"
netmap="" # enable netmap autodetect
HOST_VARIANT_DIR="freebsd"
;;
DragonFly)
bsd="yes"
make="${MAKE-gmake}"
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd pa"
HOST_VARIANT_DIR="dragonfly"
;;
NetBSD)
bsd="yes"
......@@ -584,12 +589,14 @@ NetBSD)
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd"
oss_lib="-lossaudio"
HOST_VARIANT_DIR="netbsd"
;;
OpenBSD)
bsd="yes"
make="${MAKE-gmake}"
audio_drv_list="sdl"
audio_possible_drivers="sdl esd"
HOST_VARIANT_DIR="openbsd"
;;
Darwin)
bsd="yes"
......@@ -607,6 +614,7 @@ Darwin)
# Disable attempts to use ObjectiveC features in os/object.h since they
# won't work when we're compiling with gcc as a C compiler.
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
HOST_VARIANT_DIR="darwin"
;;
SunOS)
solaris="yes"
......@@ -4986,6 +4994,9 @@ if [ "$TARGET_ABI_DIR" = "" ]; then
TARGET_ABI_DIR=$TARGET_ARCH
fi
echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
if [ "$HOST_VARIANT_DIR" != "" ]; then
echo "HOST_VARIANT_DIR=$HOST_VARIANT_DIR" >> $config_target_mak
fi
case "$target_name" in
i386|x86_64)
if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
......
......@@ -41,7 +41,6 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
for (;from < to; ++from) {
vhost_log_chunk_t log;
int bit;
/* We first check with non-atomic: much cheaper,
* and we expect non-dirty to be the common case. */
if (!*from) {
......@@ -51,12 +50,11 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
/* Data must be read atomically. We don't really need barrier semantics
* but it's easier to use atomic_* than roll our own. */
log = atomic_xchg(from, 0);
while ((bit = sizeof(log) > sizeof(int) ?
ffsll(log) : ffs(log))) {
while (log) {
int bit = ctzl(log);
hwaddr page_addr;
hwaddr section_offset;
hwaddr mr_offset;
bit -= 1;
page_addr = addr + bit * VHOST_LOG_PAGE;
section_offset = page_addr - section->offset_within_address_space;
mr_offset = section_offset + section->offset_within_region;
......
......@@ -117,7 +117,7 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
if (bitmap[i] != 0) {
c = leul_to_cpu(bitmap[i]);
do {
j = ffsl(c) - 1;
j = ctzl(c);
c &= ~(1ul << j);
page_number = (i * HOST_LONG_BITS + j) * hpratio;
addr = page_number * TARGET_PAGE_SIZE;
......
......@@ -92,11 +92,6 @@ struct HBitmap {
unsigned long *levels[HBITMAP_LEVELS];
};
static inline int popcountl(unsigned long l)
{
return BITS_PER_LONG == 32 ? ctpop32(l) : ctpop64(l);
}
/* Advance hbi to the next nonzero word and return it. hbi->pos
* is updated. Returns zero if we reach the end of the bitmap.
*/
......@@ -200,14 +195,14 @@ static uint64_t hb_count_between(HBitmap *hb, uint64_t start, uint64_t last)
if (pos >= (end >> BITS_PER_LEVEL)) {
break;
}
count += popcountl(cur);
count += ctpopl(cur);
}
if (pos == (end >> BITS_PER_LEVEL)) {
/* Drop bits representing the END-th and subsequent items. */
int bit = end & (BITS_PER_LONG - 1);
cur &= (1UL << bit) - 1;
count += popcountl(cur);
count += ctpopl(cur);
}
return count;
......
......@@ -47,6 +47,8 @@
#elif defined CONFIG_SOLARIS
# include <termios.h>
# include <stropts.h>
#else
# include <termios.h>
#endif
#ifdef __sun__
......
......@@ -511,7 +511,7 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
for (i = 0; i < ARRAY_SIZE(bitmap); i++) {
unsigned long map = bitmap[i];
while (map != 0) {
j = ffsl(map) - 1;
j = ctzl(map);
map &= ~(1ul << j);
memory_region_set_dirty(framebuffer,
(i * width + j) * TARGET_PAGE_SIZE,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册