add qemu with suse patches

git-svn-id: https://svn.disconnected-by-peer.at/svn/linamh/trunk/vmware@1952 6952d904-891a-0410-993b-d76249ca496b
This commit is contained in:
geos_one
2010-02-08 17:17:01 +00:00
parent dee2639e63
commit 32e37f2492
40 changed files with 7410 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
From 827af866df5674253ef563bd244277d31a93ba32 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:17:39 +0200
Subject: [PATCH 01/33] qemu-0.7.0-amd64
No clue why this is necessary or useful, nothing found in any changelogs.
---
x86_64.ld | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/x86_64.ld b/x86_64.ld
index 878dafb..142e641 100644
--- a/x86_64.ld
+++ b/x86_64.ld
@@ -59,8 +59,6 @@ SECTIONS
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
- .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
@@ -86,8 +84,8 @@ SECTIONS
.data1 : { *(.data1) }
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
- .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
- .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
+ .eh_frame : { KEEP (*(.eh_frame)) }
+ .gcc_except_table : { *(.gcc_except_table) }
.dynamic : { *(.dynamic) }
.ctors :
{
--
1.6.2.1

View File

@@ -0,0 +1,85 @@
From 496da9d6ffd6f42570cbed52adba37fea769d2ab Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:18:44 +0200
Subject: [PATCH 02/33] qemu-0.9.0.cvs-binfmt
Fixes binfmt_misc setup script:
- x86_64 is i386-compatible
- m68k signature fixed
- path to QEMU
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
qemu-binfmt-conf.sh | 33 ++++++++++++++++++---------------
1 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/qemu-binfmt-conf.sh b/qemu-binfmt-conf.sh
index 941f0cf..67d6728 100644
--- a/qemu-binfmt-conf.sh
+++ b/qemu-binfmt-conf.sh
@@ -12,7 +12,7 @@ fi
# probe cpu type
cpu=`uname -m`
case "$cpu" in
- i386|i486|i586|i686|i86pc|BePC)
+ i386|i486|i586|i686|i86pc|BePC|x86_64)
cpu="i386"
;;
m68k)
@@ -24,36 +24,39 @@ case "$cpu" in
"Power Macintosh"|ppc|ppc64)
cpu="ppc"
;;
- armv4l)
+ armv[4-9]*l)
cpu="arm"
;;
+ sparc*)
+ cpu="sparc"
+ ;;
esac
# register the interpreter for each cpu except for the native one
if [ $cpu != "i386" ] ; then
- echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
- echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+ echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+ echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "arm" ] ; then
- echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
- echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
+ echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
+ echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "sparc" ] ; then
- echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
+ echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "ppc" ] ; then
- echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
+ echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "m68k" ] ; then
echo 'Please check cpu value and header information for m68k!'
- echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
+ echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "mips" ] ; then
# FIXME: We could use the other endianness on a MIPS host.
- echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
- echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
- echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
- echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
- echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
- echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
+ echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
fi
--
1.6.2.1

View File

@@ -0,0 +1,83 @@
From 4675ae349f0d4e489f1298f1cbf246dfa7124d79 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:20:50 +0200
Subject: [PATCH 03/33] qemu-cvs-alsa_bitfield
Implements TYPE_INTBITFIELD partially. (required for ALSA support)
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
thunk.c | 21 +++++++++++++++++++++
thunk.h | 3 +++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/thunk.c b/thunk.c
index 0657188..5638b2c 100644
--- a/thunk.c
+++ b/thunk.c
@@ -41,6 +41,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
case TYPE_CHAR:
case TYPE_SHORT:
case TYPE_INT:
+ case TYPE_INTBITFIELD:
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
case TYPE_LONG:
@@ -139,6 +140,26 @@ const argtype *thunk_convert(void *dst, const void *src,
case TYPE_INT:
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
break;
+ case TYPE_INTBITFIELD:
+#if defined(TARGET_I386) && defined(__powerpc__)
+ /* powerpc uses the MSB, whereas i386 uses the LSB
+ * to store the first bit in a field */
+ {
+ unsigned char byte = *(uint8_t *)src;
+ *(uint8_t *)dst = ((byte >> 7) & 1)
+ | ((byte >> 5) & 2)
+ | ((byte >> 3) & 4)
+ | ((byte >> 1) & 8)
+ | ((byte << 1) & 16)
+ | ((byte << 3) & 32)
+ | ((byte << 5) & 64)
+ | ((byte << 7) & 128);
+ /* FIXME: implement for bitfields > 1 byte and other archs */
+ }
+#else
+ *(uint32_t *)dst = tswap32(*(uint32_t *)src);
+#endif
+ break;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
*(uint64_t *)dst = tswap64(*(uint64_t *)src);
diff --git a/thunk.h b/thunk.h
index 109c541..55890f3 100644
--- a/thunk.h
+++ b/thunk.h
@@ -37,6 +37,7 @@ typedef enum argtype {
TYPE_PTR,
TYPE_ARRAY,
TYPE_STRUCT,
+ TYPE_INTBITFIELD,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
@@ -90,6 +91,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
case TYPE_SHORT:
return 2;
case TYPE_INT:
+ case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
@@ -127,6 +129,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
case TYPE_SHORT:
return 2;
case TYPE_INT:
+ case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
--
1.6.2.1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
From ed5099e1cc655c77344863855abe5c20c1b6eb0b Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:24:15 +0200
Subject: [PATCH 05/33] qemu-cvs-alsa_mmap
Hack to prevent ALSA from using mmap() interface to simplify emulation.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/mmap.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index e05caa0..c33e5fe 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -321,6 +321,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
return addr;
}
+#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
+#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000
+
/* NOTE: all the constants are the HOST ones */
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
int flags, int fd, abi_ulong offset)
@@ -356,6 +359,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
}
#endif
+ /* Alsa tries to communcate with the kernel via mmap. This usually
+ * is a good idea when user- and kernelspace are running on the
+ * same architecture but does not work out when not. To make alsa
+ * not to use mmap, we can just have it fail on the mmap calls that
+ * would initiate this.
+ */
+ if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (offset & ~TARGET_PAGE_MASK) {
errno = EINVAL;
goto fail;
--
1.6.2.1

View File

@@ -0,0 +1,26 @@
From 69aca2fcdf61fbd4a5c0123a7e64cf99862076ff Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:25:41 +0200
Subject: [PATCH 06/33] qemu-cvs-gettimeofday
No clue what this is for.
---
linux-user/syscall.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7b57323..70d3b2d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5063,6 +5063,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_gettimeofday:
{
struct timeval tv;
+ if(copy_from_user_timeval(&tv, arg1))
+ goto efault;
ret = get_errno(gettimeofday(&tv, NULL));
if (!is_error(ret)) {
if (copy_to_user_timeval(arg1, &tv))
--
1.6.2.1

View File

@@ -0,0 +1,33 @@
From 4ec256fd6d555ec61f0a1bd530ff66860937b232 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:26:33 +0200
Subject: [PATCH 07/33] qemu-cvs-ioctl_debug
Extends unsupported ioctl debug output.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 70d3b2d..ce5283c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2890,7 +2890,12 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
ie = ioctl_entries;
for(;;) {
if (ie->target_cmd == 0) {
- gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
+ int i;
+ gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
+ for(i=0;ioctl_entries[i].target_cmd;i++) {
+ if((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
+ gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
+ }
return -TARGET_ENOSYS;
}
if (ie->target_cmd == cmd)
--
1.6.2.1

View File

@@ -0,0 +1,42 @@
From 5a0ba0e95920618c8ae38f4842d9dd56943f4343 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:27:36 +0200
Subject: [PATCH 08/33] qemu-cvs-ioctl_nodirection
the direction given in the ioctl should be correct so we can assume the
communication is uni-directional. The alsa developers did not like this
concept though and declared ioctls IOC_R and IOC_W even though they were
IOC_RW.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ce5283c..b7230c7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2920,6 +2920,11 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
arg_type++;
target_size = thunk_type_size(arg_type, 0);
switch(ie->access) {
+ /* FIXME: actually the direction given in the ioctl should be
+ * correct so we can assume the communication is uni-directional.
+ * The alsa developers did not like this concept though and
+ * declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
+/*
case IOC_R:
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
@@ -2938,6 +2943,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
unlock_user(argptr, arg, 0);
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
break;
+*/
default:
case IOC_RW:
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
--
1.6.2.1

View File

@@ -0,0 +1,235 @@
From bc376b5848fef44ed9a56ec2e0e9bfd22aa1b24d Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:28:45 +0200
Subject: [PATCH 09/33] qemu-cvs-newpath
fast path mangling patch by Kirill A. Shutemov
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/path.c | 190 ++++++++++++++++-------------------------------------
1 files changed, 56 insertions(+), 134 deletions(-)
diff --git a/linux-user/path.c b/linux-user/path.c
index 06b1f5f..aedff50 100644
--- a/linux-user/path.c
+++ b/linux-user/path.c
@@ -1,159 +1,81 @@
/* Code to mangle pathnames into those matching a given prefix.
eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
-
- The assumption is that this area does not change.
*/
#include <sys/types.h>
-#include <dirent.h>
+#include <sys/stat.h>
#include <unistd.h>
-#include <stdlib.h>
#include <string.h>
-#include <errno.h>
#include <stdio.h>
#include "qemu.h"
-struct pathelem
-{
- /* Name of this, eg. lib */
- char *name;
- /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
- char *pathname;
- struct pathelem *parent;
- /* Children */
- unsigned int num_entries;
- struct pathelem *entries[0];
+struct path_list_head {
+ struct path_list_head *next;
+ char* path;
};
-static struct pathelem *base;
-
-/* First N chars of S1 match S2, and S2 is N chars long. */
-static int strneq(const char *s1, unsigned int n, const char *s2)
-{
- unsigned int i;
-
- for (i = 0; i < n; i++)
- if (s1[i] != s2[i])
- return 0;
- return s2[i] == 0;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name);
-
-static struct pathelem *new_entry(const char *root,
- struct pathelem *parent,
- const char *name)
-{
- struct pathelem *new = malloc(sizeof(*new));
- new->name = strdup(name);
- asprintf(&new->pathname, "%s/%s", root, name);
- new->num_entries = 0;
- return new;
-}
-
-#define streq(a,b) (strcmp((a), (b)) == 0)
-
-static struct pathelem *add_dir_maybe(struct pathelem *path)
-{
- DIR *dir;
-
- if ((dir = opendir(path->pathname)) != NULL) {
- struct dirent *dirent;
-
- while ((dirent = readdir(dir)) != NULL) {
- if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
- path = add_entry(path, dirent->d_name);
- }
- }
- closedir(dir);
- }
- return path;
-}
-
-static struct pathelem *add_entry(struct pathelem *root, const char *name)
-{
- root->num_entries++;
-
- root = realloc(root, sizeof(*root)
- + sizeof(root->entries[0])*root->num_entries);
-
- root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);
- root->entries[root->num_entries-1]
- = add_dir_maybe(root->entries[root->num_entries-1]);
- return root;
-}
-
-/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
-static void set_parents(struct pathelem *child, struct pathelem *parent)
-{
- unsigned int i;
-
- child->parent = parent;
- for (i = 0; i < child->num_entries; i++)
- set_parents(child->entries[i], child);
-}
-
-/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
-static const char *
-follow_path(const struct pathelem *cursor, const char *name)
-{
- unsigned int i, namelen;
-
- name += strspn(name, "/");
- namelen = strcspn(name, "/");
-
- if (namelen == 0)
- return cursor->pathname;
-
- if (strneq(name, namelen, ".."))
- return follow_path(cursor->parent, name + namelen);
-
- if (strneq(name, namelen, "."))
- return follow_path(cursor, name + namelen);
-
- for (i = 0; i < cursor->num_entries; i++)
- if (strneq(name, namelen, cursor->entries[i]->name))
- return follow_path(cursor->entries[i], name + namelen);
-
- /* Not found */
- return NULL;
-}
+static struct path_list_head* list_head;
void init_paths(const char *prefix)
{
- char pref_buf[PATH_MAX];
-
- if (prefix[0] == '\0' ||
- !strcmp(prefix, "/"))
+ if (prefix[0] != '/' ||
+ prefix[0] == '\0' ||
+ !strcmp(prefix, "/"))
return;
- if (prefix[0] != '/') {
- char *cwd = get_current_dir_name();
- if (!cwd)
- abort();
- strcpy(pref_buf, cwd);
- strcat(pref_buf, "/");
- strcat(pref_buf, prefix);
- free(cwd);
- } else
- strcpy(pref_buf,prefix + 1);
+ list_head = malloc(sizeof(struct path_list_head));
- base = new_entry("", NULL, pref_buf);
- base = add_dir_maybe(base);
- if (base->num_entries == 0) {
- free (base);
- base = NULL;
- } else {
- set_parents(base, base);
- }
+ /* first element of list is prefix */
+ list_head->path = strdup(prefix);
+ list_head->next = NULL;
}
/* Look for path in emulation dir, otherwise return name. */
const char *path(const char *name)
{
+ struct path_list_head *list = list_head;
+ int path_length = strlen(list_head->path) + strlen(name) + 1;
+ char *newname = malloc(path_length);
+ struct stat buf;
+ const char * result = name;
+
/* Only do absolute paths: quick and dirty, but should mostly be OK.
Could do relative by tracking cwd. */
- if (!base || !name || name[0] != '/')
- return name;
-
- return follow_path(base, name) ?: name;
+ if (!list_head || result[0] != '/')
+ goto exit;
+
+ strncpy(newname, list_head->path, path_length);
+ strncat(newname, name, path_length);
+
+ /* look for place where path should be present */
+ while ( list->next && (strcmp(list->next->path, newname) < 0) )
+ list = list->next;
+
+ /* if there is no path in list */
+ if ( !list->next || strcmp(list->next->path, newname) ) {
+ /* add element to list if path exist in emulation dir */
+ if ( !stat(newname, &buf) )
+ {
+ struct path_list_head *new;
+
+ new = malloc(sizeof(struct path_list_head));
+ new->path = strdup(newname);
+ new->next = list->next;
+ list->next = new;
+ result = new->path;
+ }
+
+ } else if ( stat(list->next->path, &buf) ) {
+ /* remove element from list if path doesn't exist in emulation dir */
+ struct path_list_head* tmp;
+
+ tmp = list->next;
+ list->next = tmp->next;
+ free(tmp->path);
+ free(tmp);
+ } else
+ result = list->next->path;
+
+exit:
+ free(newname);
+ return result;
}
--
1.6.2.1

View File

@@ -0,0 +1,56 @@
From 72e306e63740a51a1c82f39cabb65df65ce2c215 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:30:16 +0200
Subject: [PATCH 10/33] qemu-cvs-sched_getaffinity
Implements sched_getaffinity syscall.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b7230c7..faf41b1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -152,6 +152,7 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
}
+#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
#define __NR_sys_uname __NR_uname
#define __NR_sys_faccessat __NR_faccessat
#define __NR_sys_fchmodat __NR_fchmodat
@@ -213,6 +214,9 @@ _syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
_syscall2(int,sys_tkill,int,tid,int,sig)
#endif
+#ifdef __NR_sys_sched_getaffinity
+_syscall3(int,sys_sched_getaffinity,pid_t,pid,unsigned int,cpusetsize,void*,mask)
+#endif
#ifdef __NR_exit_group
_syscall1(int,exit_group,int,error_code)
#endif
@@ -6979,6 +6983,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
#endif /* CONFIG_SPLICE */
+
+#ifdef TARGET_NR_sched_getaffinity
+ case TARGET_NR_sched_getaffinity:
+ {
+ cpu_set_t *mask;
+ lock_user_struct(VERIFY_READ, mask, arg3, 1);
+ ret = get_errno(sys_sched_getaffinity((pid_t)arg1, (unsigned int)arg2, mask));
+ unlock_user_struct(mask, arg3, 0);
+ break;
+ }
+#endif
+
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
--
1.6.2.1

View File

@@ -0,0 +1,41 @@
From 5c8849d886cafd1626c1d36c572c3ccee5c88d5d Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:34:05 +0200
Subject: [PATCH 11/33] qemu-cvs-mmap-amd64
Map stuff to address space < 4GB on AMD64. This patch got continually smaller
as most cases were this was an issue were dealt with in other ways. May
already be fully obsolete.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/mmap.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index c33e5fe..9ca8f6f 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -31,6 +31,10 @@
#include "qemu.h"
#include "qemu-common.h"
+#if !defined(MAP_32BIT)
+#define MAP_32BIT 0
+#endif
+
//#define DEBUG_MMAP
#if defined(USE_NPTL)
@@ -230,7 +234,7 @@ static int mmap_frag(abi_ulong real_start,
if (prot1 == 0) {
/* no page was there, so we allocate one */
void *p = mmap(host_start, qemu_host_page_size, prot,
- flags | MAP_ANONYMOUS, -1, 0);
+ flags | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
if (p == MAP_FAILED)
return -1;
prot1 = prot;
--
1.6.2.1

View File

@@ -0,0 +1,28 @@
From 9e89bde7061d46a60dfe895450053360427a32f0 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:34:36 +0200
Subject: [PATCH 12/33] qemu-cvs-pthread
Link with libpthread. Not sure if still necessary.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index e4f9498..be55d3d 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ VPATH=$(SRC_PATH):$(SRC_PATH)/hw
CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP -MT $@
CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
CPPFLAGS += -U_FORTIFY_SOURCE
-LIBS=
+LIBS=-lpthread
ifdef CONFIG_STATIC
LDFLAGS += -static
endif
--
1.6.2.1

View File

@@ -0,0 +1,142 @@
From 75e8da1c5ca1b61a9a97fcc385eb5c6b9f83130f Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:37:42 +0200
Subject: [PATCH 13/33] qemu-img-vmdk-scsi
Support creation of SCSI VMDK images in qemu-img.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
block/vmdk.c | 5 +++--
block_int.h | 1 +
qemu-img-cmds.hx | 8 ++++----
qemu-img.c | 15 +++++++++++++--
4 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/block/vmdk.c b/block/vmdk.c
index 4e48622..b7a15c7 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -710,7 +710,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
"ddb.geometry.cylinders = \"%" PRId64 "\"\n"
"ddb.geometry.heads = \"16\"\n"
"ddb.geometry.sectors = \"63\"\n"
- "ddb.adapterType = \"ide\"\n";
+ "ddb.adapterType = \"%s\"\n";
char desc[1024];
const char *real_filename, *temp_str;
int64_t total_size = 0;
@@ -800,7 +800,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL),
total_size, real_filename,
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
- total_size / (int64_t)(63 * 16));
+ total_size / (int64_t)(63 * 16),
+ flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide");
/* write the descriptor */
lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
diff --git a/block_int.h b/block_int.h
index 8898d91..d482050 100644
--- a/block_int.h
+++ b/block_int.h
@@ -30,6 +30,7 @@
#define BLOCK_FLAG_ENCRYPT 1
#define BLOCK_FLAG_COMPRESS 2
#define BLOCK_FLAG_COMPAT6 4
+#define BLOCK_FLAG_SCSI 8
#define BLOCK_OPT_SIZE "size"
#define BLOCK_OPT_ENCRYPT "encryption"
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index ddb86f0..be94d22 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -16,9 +16,9 @@ STEXI
ETEXI
DEF("create", img_create,
- "create [-F fmt] [-b base_image] [-f fmt] [-o options] filename [size]")
+ "create [-s] [-F fmt] [-b base_image] [-f fmt] [-o options] filename [size]")
STEXI
-@item create [-F @var{base_fmt}] [-b @var{base_image}] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]
+@item create [-s] [-F @var{base_fmt}] [-b @var{base_image}] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]
ETEXI
DEF("commit", img_commit,
@@ -28,9 +28,9 @@ STEXI
ETEXI
DEF("convert", img_convert,
- "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-B output_base_image] filename [filename2 [...]] output_filename")
+ "convert [-c] [-s] [-f fmt] [-O output_fmt] [-o options] [-B output_base_image] filename [filename2 [...]] output_filename")
STEXI
-@item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-s] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-B @var{output_base_image}] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI
DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 070fe2e..2adeb56 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -259,7 +259,7 @@ static int img_create(int argc, char **argv)
flags = 0;
for(;;) {
- c = getopt(argc, argv, "F:b:f:he6o:");
+ c = getopt(argc, argv, "F:b:f:hes6o:");
if (c == -1)
break;
switch(c) {
@@ -278,6 +278,9 @@ static int img_create(int argc, char **argv)
case 'e':
flags |= BLOCK_FLAG_ENCRYPT;
break;
+ case 's':
+ flags |= BLOCK_FLAG_SCSI;
+ break;
case '6':
flags |= BLOCK_FLAG_COMPAT6;
break;
@@ -357,6 +360,8 @@ static int img_create(int argc, char **argv)
printf("Formatting '%s', fmt=%s ", filename, fmt);
print_option_parameters(param);
+ if (flags & BLOCK_FLAG_SCSI)
+ printf(", SCSI");
puts("");
ret = bdrv_create(drv, filename, param);
@@ -551,7 +556,7 @@ static int img_convert(int argc, char **argv)
out_baseimg = NULL;
flags = 0;
for(;;) {
- c = getopt(argc, argv, "f:O:B:hce6o:");
+ c = getopt(argc, argv, "f:O:B:hces6o:");
if (c == -1)
break;
switch(c) {
@@ -573,6 +578,9 @@ static int img_convert(int argc, char **argv)
case 'e':
flags |= BLOCK_FLAG_ENCRYPT;
break;
+ case 's':
+ flags |= BLOCK_FLAG_SCSI;
+ break;
case '6':
flags |= BLOCK_FLAG_COMPAT6;
break;
@@ -639,6 +647,9 @@ static int img_convert(int argc, char **argv)
}
}
+ if (flags & BLOCK_FLAG_SCSI && strcmp(drv->format_name, "vmdk"))
+ error("SCSI devices not supported for this file format");
+
/* Create the new image */
ret = bdrv_create(drv, out_filename, param);
free_option_parameters(param);
--
1.6.2.1

View File

@@ -0,0 +1,40 @@
From 29b517b3811d8745eb73e95fe18552eb1f0153af Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:38:20 +0200
Subject: [PATCH 14/33] qemu-nonvoid_return
Squelches GCC warnings about undefined return values.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
hw/mpcore.c | 1 +
target-m68k/translate.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/hw/mpcore.c b/hw/mpcore.c
index 907bd99..a682695 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -108,6 +108,7 @@ static uint32_t mpcore_timer_read(mpcore_timer_state *s, int offset)
default:
return 0;
}
+ return 0;
}
static void mpcore_timer_write(mpcore_timer_state *s, int offset,
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index b37578b..feaa155 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -440,6 +440,7 @@ static inline int opsize_bytes(int opsize)
qemu_assert(0, "bad operand size");
return 0;
}
+ return 0;
}
/* Assign value to a register. If the width is less than the register width
--
1.6.2.1

View File

@@ -0,0 +1,205 @@
From 99759e033ea960b86828657682f8382538c4ccb7 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Tue, 14 Apr 2009 16:52:51 +0200
Subject: [PATCH 15/33] pcap network emulation
Implements network emulation using libpcap; useful for direct Ethernet access.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
Makefile.target | 3 ++
configure | 7 ++++
net.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
qemu-options.hx | 4 ++
4 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index f9cd42a..9c9304c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -618,6 +618,9 @@ endif
ifdef CONFIG_SLIRP
CPPFLAGS+=-I$(SRC_PATH)/slirp
endif
+ifdef CONFIG_PCAP
+LIBS+=-lpcap
+endif
# specific flags are needed for non soft mmu emulator
ifdef CONFIG_STATIC
diff --git a/configure b/configure
index cac4198..4ce7bc1 100755
--- a/configure
+++ b/configure
@@ -169,6 +169,7 @@ mingw32="no"
EXESUF=""
slirp="yes"
vde="yes"
+pcap="yes"
fmod_lib=""
fmod_inc=""
oss_lib=""
@@ -432,6 +433,8 @@ for opt do
;;
--disable-vde) vde="no"
;;
+ --disable-pcap) pcap="no"
+ ;;
--disable-kqemu) kqemu="no"
;;
--disable-xen) xen="no"
@@ -1598,6 +1601,10 @@ if test "$vde" = "yes" ; then
echo "#define CONFIG_VDE 1" >> $config_host_h
echo "VDE_LIBS=-lvdeplug" >> $config_host_mak
fi
+if test "$pcap" = "yes" ; then
+ echo "CONFIG_PCAP=yes" >> $config_host_mak
+ echo "#define CONFIG_PCAP 1" >> $config_host_h
+fi
for card in $audio_card_list; do
def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'`
echo "$def=y" >> $config_host_mak
diff --git a/net.c b/net.c
index 3d3829d..595f7bc 100644
--- a/net.c
+++ b/net.c
@@ -1264,6 +1264,105 @@ void do_info_usernet(Monitor *mon)
#endif /* CONFIG_SLIRP */
+#if defined(CONFIG_PCAP)
+#include <pcap.h>
+typedef struct PCAPState {
+ VLANClientState *vc;
+ pcap_t *handle;
+} PCAPState;
+
+static ssize_t pcap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+{
+ PCAPState *s = (PCAPState *)(vc->opaque);
+
+ pcap_sendpacket(s->handle, (u_char*)buf, size);
+ return size;
+}
+
+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata)
+{
+ VLANClientState *vc = (VLANClientState *)user;
+
+ qemu_send_packet(vc, pdata, phdr->len);
+}
+
+static void pcap_send(void *opaque)
+{
+ PCAPState *s = (PCAPState *)opaque;
+
+ pcap_dispatch(s->handle, 1, (pcap_handler)&pcap_callback, (u_char *)s->vc);
+}
+
+static int net_pcap_init(VLANState *vlan, const char *model, const char *name, char *ifname)
+{
+ PCAPState *s;
+ char errbuf[PCAP_ERRBUF_SIZE];
+ int fd;
+
+ s = qemu_mallocz(sizeof(PCAPState));
+ if (!s)
+ return -1;
+
+ if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) {
+ fprintf(stderr, "qemu: pcap_lookupdev: %s\n", errbuf);
+ goto fail;
+ }
+
+ /* Attempt to connect device. */
+ s->handle = (void*)pcap_open_live(ifname, 65535, 1, 0, errbuf);
+ if (!s->handle) {
+ fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf);
+ goto fail;
+ }
+
+ /* Check non-blocking mode. */
+ if (pcap_setnonblock(s->handle, 1, errbuf) < 0) {
+ fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf);
+ goto fail;
+ }
+
+#if defined(BIOCSHDRCMPLT)
+ /*
+ * Tell the kernel that the header is fully-formed when it gets it.
+ * This is required in order to fake the src address.
+ */
+ {
+ unsigned int one = 1;
+ ioctl(pcap_fileno(s->handle), BIOCSHDRCMPLT, &one);
+ }
+#endif /* BIOCSHDRCMPLT */
+
+#if defined(BIOCIMMEDIATE)
+ /*
+ * Tell the kernel that the packet has to be processed immediately.
+ */
+ {
+ unsigned int one = 1;
+ ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one);
+ }
+#endif /* BIOCIMMEDIATE */
+
+ s->vc = qemu_new_vlan_client(vlan, model, name, NULL, pcap_receive, NULL, NULL, s);
+ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap redirector");
+ if ((fd = pcap_get_selectable_fd(s->handle)) < 0) {
+ fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n");
+ goto fail;
+ }
+ qemu_set_fd_handler(fd, pcap_send, NULL, s);
+
+ return 0;
+
+fail:
+ if (s) {
+ if (s->handle)
+ pcap_close(s->handle);
+ qemu_free(s);
+ }
+
+ return -1;
+}
+#endif /* CONFIG_PCAP */
+
#if !defined(_WIN32)
typedef struct TAPState {
@@ -2631,6 +2730,15 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
ret = 0;
} else
#endif
+#ifdef CONFIG_PCAP
+ if (!strcmp(device, "pcap")) {
+ char ifname[64];
+ if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0)
+ ret = net_pcap_init(vlan, device, name, NULL);
+ else
+ ret = net_pcap_init(vlan, device, name, ifname);
+ } else
+#endif
#ifdef _WIN32
if (!strcmp(device, "tap")) {
static const char * const tap_params[] = {
diff --git a/qemu-options.hx b/qemu-options.hx
index a58287c..4d46d6c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -801,6 +801,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
" default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
#endif
#endif
+#ifdef CONFIG_PCAP
+ "-net pcap[,vlan=n][,ifname=name]\n"
+ " connect the host network interface using PCAP to VLAN 'n'\n"
+#endif
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
"-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
--
1.6.2.1

View File

@@ -0,0 +1,64 @@
From e770ff83915791d048ca88da6c3877cb54bf063e Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 16 Apr 2009 15:14:12 +0200
Subject: [PATCH 16/33] i386-linux-user NPTL support
Makes NPTL binaries run by implementing TLS.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
configure | 1 +
linux-user/syscall.c | 16 ++++++++++++++--
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 4ce7bc1..4f79498 100755
--- a/configure
+++ b/configure
@@ -1904,6 +1904,7 @@ TARGET_ABI_DIR=""
case "$target_arch2" in
i386)
target_phys_bits=32
+ target_nptl="yes"
;;
x86_64)
TARGET_BASE_ARCH=i386
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index faf41b1..87ceac7 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3575,8 +3575,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
ts->child_tidptr = child_tidptr;
}
- if (nptl_flags & CLONE_SETTLS)
+ if (nptl_flags & CLONE_SETTLS) {
+#if defined(TARGET_I386) && defined(TARGET_ABI32)
+ do_set_thread_area(new_env, newtls);
+ cpu_x86_load_seg(new_env, R_GS, new_env->segs[R_GS].selector);
+#else
cpu_set_tls (new_env, newtls);
+#endif
+ }
/* Grab a mutex so that thread setup appears atomic. */
pthread_mutex_lock(&clone_lock);
@@ -3648,8 +3654,14 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
if (flags & CLONE_PARENT_SETTID)
put_user_u32(gettid(), parent_tidptr);
ts = (TaskState *)env->opaque;
- if (flags & CLONE_SETTLS)
+ if (flags & CLONE_SETTLS) {
+#if defined(TARGET_I386) && defined(TARGET_ABI32)
+ do_set_thread_area(env, newtls);
+ cpu_x86_load_seg(env, R_GS, env->segs[R_GS].selector);
+#else
cpu_set_tls (env, newtls);
+#endif
+ }
if (flags & CLONE_CHILD_CLEARTID)
ts->child_tidptr = child_tidptr;
#endif
--
1.6.2.1

View File

@@ -0,0 +1,25 @@
From df6df89350799107b3395665943c4df7eeba87e0 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Wed, 17 Jun 2009 14:54:48 +0200
Subject: [PATCH 17/33] qemu-0.11-git-ioctl_mount
---
linux-user/ioctls.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index aee5a88..a0fb052 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -310,7 +310,7 @@
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
IOCTL(LOOP_GET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
-#if 0 /* These have some problems - not fully tested */
+#if 1 /* These have some problems - not fully tested */
IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
#endif
--
1.6.2.1

View File

@@ -0,0 +1,116 @@
From 015bd9be8314b3ce6d97d1bc9614874aee9b0e52 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Wed, 17 Jun 2009 15:08:38 +0200
Subject: [PATCH 18/33] qemu-0.11-git-user-linux-ppc-uid16_fix
---
linux-user/ppc/syscall_nr.h | 30 +++++++++++++++---------------
linux-user/syscall_defs.h | 2 +-
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/linux-user/ppc/syscall_nr.h b/linux-user/ppc/syscall_nr.h
index f54276b..cc84a4c 100644
--- a/linux-user/ppc/syscall_nr.h
+++ b/linux-user/ppc/syscall_nr.h
@@ -17,15 +17,15 @@
#define TARGET_NR_time 13
#define TARGET_NR_mknod 14
#define TARGET_NR_chmod 15
-#define TARGET_NR_lchown32 16
+#define TARGET_NR_lchown 16
#define TARGET_NR_break 17
#define TARGET_NR_oldstat 18
#define TARGET_NR_lseek 19
#define TARGET_NR_getpid 20
#define TARGET_NR_mount 21
#define TARGET_NR_umount 22
-#define TARGET_NR_setuid32 23
-#define TARGET_NR_getuid32 24
+#define TARGET_NR_setuid 23
+#define TARGET_NR_getuid 24
#define TARGET_NR_stime 25
#define TARGET_NR_ptrace 26
#define TARGET_NR_alarm 27
@@ -47,11 +47,11 @@
#define TARGET_NR_times 43
#define TARGET_NR_prof 44
#define TARGET_NR_brk 45
-#define TARGET_NR_setgid32 46
-#define TARGET_NR_getgid32 47
+#define TARGET_NR_setgid 46
+#define TARGET_NR_getgid 47
#define TARGET_NR_signal 48
-#define TARGET_NR_geteuid32 49
-#define TARGET_NR_getegid32 50
+#define TARGET_NR_geteuid 49
+#define TARGET_NR_getegid 50
#define TARGET_NR_acct 51
#define TARGET_NR_umount2 52
#define TARGET_NR_lock 53
@@ -71,8 +71,8 @@
#define TARGET_NR_sigaction 67
#define TARGET_NR_sgetmask 68
#define TARGET_NR_ssetmask 69
-#define TARGET_NR_setreuid32 70
-#define TARGET_NR_setregid32 71
+#define TARGET_NR_setreuid 70
+#define TARGET_NR_setregid 71
#define TARGET_NR_sigsuspend 72
#define TARGET_NR_sigpending 73
#define TARGET_NR_sethostname 74
@@ -81,8 +81,8 @@
#define TARGET_NR_getrusage 77
#define TARGET_NR_gettimeofday 78
#define TARGET_NR_settimeofday 79
-#define TARGET_NR_getgroups32 80
-#define TARGET_NR_setgroups32 81
+#define TARGET_NR_getgroups 80
+#define TARGET_NR_setgroups 81
#define TARGET_NR_select 82
#define TARGET_NR_symlink 83
#define TARGET_NR_oldlstat 84
@@ -96,7 +96,7 @@
#define TARGET_NR_truncate 92
#define TARGET_NR_ftruncate 93
#define TARGET_NR_fchmod 94
-#define TARGET_NR_fchown32 95
+#define TARGET_NR_fchown 95
#define TARGET_NR_getpriority 96
#define TARGET_NR_setpriority 97
#define TARGET_NR_profil 98
@@ -139,8 +139,8 @@
#define TARGET_NR_sysfs 135
#define TARGET_NR_personality 136
#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define TARGET_NR_setfsuid32 138
-#define TARGET_NR_setfsgid32 139
+#define TARGET_NR_setfsuid 138
+#define TARGET_NR_setfsgid 139
#define TARGET_NR__llseek 140
#define TARGET_NR_getdents 141
#define TARGET_NR__newselect 142
@@ -182,7 +182,7 @@
#define TARGET_NR_rt_sigsuspend 178
#define TARGET_NR_pread64 179
#define TARGET_NR_pwrite64 180
-#define TARGET_NR_chown32 181
+#define TARGET_NR_chown 181
#define TARGET_NR_getcwd 182
#define TARGET_NR_capget 183
#define TARGET_NR_capset 184
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 78c6488..0cbe396 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -49,7 +49,7 @@
#define TARGET_IOC_TYPEBITS 8
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
- || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
+ || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) || defined(TARGET_PPC)
/* 16 bit uid wrappers emulation */
#define USE_UID16
#endif
--
1.6.2.1

View File

@@ -0,0 +1,125 @@
From d7f01e455acae19ef780e29417ffba50ca90ffde Mon Sep 17 00:00:00 2001
From: Kirill A. Shutemov <kirill@shutemov.name>
Date: Wed, 17 Jun 2009 15:14:43 +0200
Subject: [PATCH 19/33] Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets
From: Kirill A. Shutemov <kirill@shutemov.name>
qemu's page table can be incomple if /proc/self/maps is unavailable or
host allocating a memory with mmap(), so we can't use it to find free
memory area.
New version mmap_find_vma() uses mmap() without MAP_FIXED to find free
memory.
From: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
linux-user/mmap.c | 79 +++++++++++++++++++++++++++++------------------------
1 files changed, 43 insertions(+), 36 deletions(-)
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 9ca8f6f..8d94783 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -277,52 +277,59 @@ static abi_ulong mmap_next_start = 0x40000000;
unsigned long last_brk;
-/* find a free memory area of size 'size'. The search starts at
- 'start'. If 'start' == 0, then a default start address is used.
- Return -1 if error.
-*/
-/* page_init() marks pages used by the host as reserved to be sure not
- to use them. */
+/*
+ * Find and reserve a free memory area of size 'size'. The search
+ * starts at 'start'.
+ * It must be called with mmap_lock() held.
+ * Return -1 if error.
+ */
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
{
- abi_ulong addr, addr1, addr_start;
- int prot;
- unsigned long new_brk;
-
- new_brk = (unsigned long)sbrk(0);
- if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) {
- /* This is a hack to catch the host allocating memory with brk().
- If it uses mmap then we loose.
- FIXME: We really want to avoid the host allocating memory in
- the first place, and maybe leave some slack to avoid switching
- to mmap. */
- page_set_flags(last_brk & TARGET_PAGE_MASK,
- TARGET_PAGE_ALIGN(new_brk),
- PAGE_RESERVED);
- }
- last_brk = new_brk;
+ void *ptr;
+ abi_ulong addr;
size = HOST_PAGE_ALIGN(size);
- start = start & qemu_host_page_mask;
+ start &= qemu_host_page_mask;
+
+ /* If 'start' == 0, then a default start address is used. */
+ if (start == 0)
+ start = mmap_next_start;
+
addr = start;
- if (addr == 0)
- addr = mmap_next_start;
- addr_start = addr;
+
for(;;) {
- prot = 0;
- for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) {
- prot |= page_get_flags(addr1);
- }
- if (prot == 0)
+ /*
+ * Reserve needed memory area to avoid a race.
+ * It should be discarded using:
+ * - mmap() with MAP_FIXED flag
+ * - mremap() with MREMAP_FIXED flag
+ * - shmat() with SHM_REMAP flag
+ */
+ ptr = mmap((void *)(unsigned long)addr, size, PROT_NONE,
+ MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+
+ /* ENOMEM, if host address space has no memory */
+ if (ptr == MAP_FAILED)
+ return (abi_ulong)-1;
+
+ /* If address fits target address space we've found what we need */
+ if ((unsigned long)ptr + size - 1 <= (abi_ulong)-1)
break;
+
+ /* Unmap and try again with new page */
+ munmap(ptr, size);
addr += qemu_host_page_size;
- /* we found nothing */
- if (addr == addr_start)
+
+ /* ENOMEM if we check whole of target address space */
+ if (addr == start)
return (abi_ulong)-1;
}
- if (start == 0)
- mmap_next_start = addr + size;
- return addr;
+
+ /* Update default start address */
+ if (start == mmap_next_start)
+ mmap_next_start = (unsigned long)ptr + size;
+
+ return h2g(ptr);
}
#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
--
1.6.2.1

View File

@@ -0,0 +1,82 @@
From ea0b70265614b950d1e2ed48a9581ecd5e63ac97 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Fri, 24 Jul 2009 17:25:37 +0200
Subject: [PATCH 20/33] TCG "sync" op (32-bit targets fixed)
sync allows concurrent accesses to locations in memory through different TCG
variables. This comes in handy when you are emulating CPU registers that can
be used as either 32 or 64 bit, as TCG doesn't know anything about aliases.
See the s390x target for an example.
Fixed to not break 32-bit target builds.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
tcg/tcg-op.h | 12 ++++++++++++
tcg/tcg-opc.h | 2 ++
tcg/tcg.c | 6 ++++++
3 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 7cb6934..cfd6160 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -316,6 +316,18 @@ static inline void tcg_gen_br(int label)
tcg_gen_op1i(INDEX_op_br, label);
}
+static inline void tcg_gen_sync_i32(TCGv_i32 arg)
+{
+ tcg_gen_op1_i32(INDEX_op_sync_i32, arg);
+}
+
+#if TCG_TARGET_REG_BITS == 64
+static inline void tcg_gen_sync_i64(TCGv_i64 arg)
+{
+ tcg_gen_op1_i64(INDEX_op_sync_i64, arg);
+}
+#endif
+
static inline void tcg_gen_mov_i32(TCGv_i32 ret, TCGv_i32 arg)
{
if (!TCGV_EQUAL_I32(ret, arg))
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 3a095fc..654a45f 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -40,6 +40,7 @@ DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF2(sync_i32, 0, 1, 0, 0)
DEF2(mov_i32, 1, 1, 0, 0)
DEF2(movi_i32, 1, 0, 1, 0)
/* load/store */
@@ -103,6 +104,7 @@ DEF2(neg_i32, 1, 1, 0, 0)
#endif
#if TCG_TARGET_REG_BITS == 64
+DEF2(sync_i64, 0, 1, 0, 0)
DEF2(mov_i64, 1, 1, 0, 0)
DEF2(movi_i64, 1, 0, 1, 0)
/* load/store */
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 299bff6..86e16fa 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1927,6 +1927,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
// dump_regs(s);
#endif
switch(opc) {
+ case INDEX_op_sync_i32:
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_sync_i64:
+#endif
+ temp_save(s, args[0], s->reserved_regs);
+ break;
case INDEX_op_mov_i32:
#if TCG_TARGET_REG_BITS == 64
case INDEX_op_mov_i64:
--
1.6.2.1

View File

@@ -0,0 +1,96 @@
From 603d882c9c1c61475a69f657a9550bb335bf3ca9 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Wed, 22 Jul 2009 14:03:19 +0200
Subject: [PATCH 25/33] linux-user: don't do locking in single-threaded processes
Skips setting the tb_lock if a process doesn't have more than one thread,
which is usually the case. Results in about 20% performance gain (measured
with the s390x target, but the effect should be similar with other targets).
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
cpu-defs.h | 8 ++++++++
cpu-exec.c | 14 ++++++++++++--
linux-user/syscall.c | 1 +
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/cpu-defs.h b/cpu-defs.h
index d73ec0a..27e5bb2 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -135,6 +135,13 @@ typedef struct CPUWatchpoint {
} CPUWatchpoint;
#define CPU_TEMP_BUF_NLONGS 128
+
+#ifdef CONFIG_USER_ONLY
+#define MULTITHREAD uint32_t multithreaded;
+#else
+#define MULTITHREAD
+#endif
+
#define CPU_COMMON \
struct TranslationBlock *current_tb; /* currently executing TB */ \
/* soft mmu support */ \
@@ -149,6 +156,7 @@ typedef struct CPUWatchpoint {
uint32_t stop; /* Stop request */ \
uint32_t stopped; /* Artificially stopped */ \
uint32_t interrupt_request; \
+ MULTITHREAD /* needs locking when accessing TBs */ \
volatile sig_atomic_t exit_request; \
/* The meaning of the MMU modes is defined in the target code. */ \
CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
diff --git a/cpu-exec.c b/cpu-exec.c
index 855ea3e..1371ce4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -219,6 +219,9 @@ int cpu_exec(CPUState *env1)
TranslationBlock *tb;
uint8_t *tc_ptr;
unsigned long next_tb;
+#ifdef CONFIG_USER_ONLY
+ uint32_t multithreaded;
+#endif
if (cpu_halted(env1) == EXCP_HALTED)
return EXCP_HALTED;
@@ -604,7 +607,11 @@ int cpu_exec(CPUState *env1)
#endif
}
#endif
- spin_lock(&tb_lock);
+#ifdef CONFIG_USER_ONLY
+ multithreaded = env->multithreaded;
+ if (multithreaded)
+#endif
+ spin_lock(&tb_lock);
tb = tb_find_fast();
/* Note: we do it here to avoid a gcc bug on Mac OS X when
doing it in tb_find_slow */
@@ -632,7 +639,10 @@ int cpu_exec(CPUState *env1)
tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
}
}
- spin_unlock(&tb_lock);
+#ifdef CONFIG_USER_ONLY
+ if (multithreaded)
+#endif
+ spin_unlock(&tb_lock);
env->current_tb = tb;
/* cpu_interrupt might be called while translating the
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e9b07df..f7a411d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3560,6 +3560,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
init_task_state(ts);
new_stack = ts->stack;
+ env->multithreaded = 1;
/* we create a new CPU instance. */
new_env = cpu_copy(env);
/* Init regs that differ from the parent. */
--
1.6.2.1

View File

@@ -0,0 +1,80 @@
From ad0b7fcf697651a156c0e4a2911dd9fa69fd011c Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 23 Jul 2009 14:33:36 +0200
Subject: [PATCH 26/33] linux-user: dup3, fallocate syscalls
implementations of dup3 and fallocate that are good enough to fool LTP
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
configure | 18 ++++++++++++++++++
linux-user/syscall.c | 10 ++++++++++
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/configure b/configure
index e0874b5..4be25f6 100755
--- a/configure
+++ b/configure
@@ -1355,6 +1355,21 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
splice=yes
fi
+# check for fallocate
+fallocate=no
+cat > $TMPC << EOF
+#include <fcntl.h>
+
+int main(void)
+{
+ fallocate(0, 0, 0, 0);
+ return 0;
+}
+EOF
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+ fallocate=yes
+fi
+
# Check if tools are available to build documentation.
if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then
build_docs="no"
@@ -1707,6 +1722,9 @@ fi
if test "$splice" = "yes" ; then
echo "#define CONFIG_SPLICE 1" >> $config_host_h
fi
+if test "$fallocate" = "yes" ; then
+ echo "#define CONFIG_FALLOCATE 1" >> $config_host_h
+fi
if test "$inotify" = "yes" ; then
echo "#define CONFIG_INOTIFY 1" >> $config_host_h
fi
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f7a411d..4fb7998 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4750,6 +4750,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_dup2:
ret = get_errno(dup2(arg1, arg2));
break;
+#ifdef TARGET_NR_dup3
+ case TARGET_NR_dup3:
+ ret = get_errno(dup3(arg1, arg2, arg3));
+ break;
+#endif
#ifdef TARGET_NR_getppid /* not on alpha */
case TARGET_NR_getppid:
ret = get_errno(getppid());
@@ -7016,6 +7021,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
#endif
+#if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
+ case TARGET_NR_fallocate:
+ ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
+ break;
+#endif
default:
unimplemented:
gemu_log("qemu: Unsupported syscall: %d\n", num);
--
1.6.2.1

View File

@@ -0,0 +1,171 @@
From e4f2e031fe5b5f9f11560a51ce607ffdd3090c05 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 23 Jul 2009 15:10:30 +0200
Subject: [PATCH 27/33] linux-user: fcntl fixes for LTP
Fixes swaps on l_pid which were pretty much of random size. Implements
F_SETLEASE, F_GETLEASE. Now passes all LTP fcntl tests.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 34 ++++++++++++++++++++++------------
linux-user/syscall_defs.h | 7 +++++++
2 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 4fb7998..86754f1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3705,6 +3705,14 @@ static int target_to_host_fcntl_cmd(int cmd)
case TARGET_F_SETLKW64:
return F_SETLKW64;
#endif
+ case TARGET_F_SETLEASE:
+ return F_SETLEASE;
+ case TARGET_F_GETLEASE:
+ return F_GETLEASE;
+ case TARGET_F_DUPFD_CLOEXEC:
+ return F_DUPFD_CLOEXEC;
+ case TARGET_F_NOTIFY:
+ return F_NOTIFY;
default:
return -TARGET_EINVAL;
}
@@ -3731,7 +3739,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapl(target_fl->l_start);
fl.l_len = tswapl(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl));
if (ret == 0) {
@@ -3741,7 +3749,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswapl(fl.l_start);
target_fl->l_len = tswapl(fl.l_len);
- target_fl->l_pid = tswapl(fl.l_pid);
+ target_fl->l_pid = tswap32(fl.l_pid);
unlock_user_struct(target_fl, arg, 1);
}
break;
@@ -3754,7 +3762,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswapl(target_fl->l_start);
fl.l_len = tswapl(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl));
break;
@@ -3766,7 +3774,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswapl(target_fl64->l_start);
fl64.l_len = tswapl(target_fl64->l_len);
- fl64.l_pid = tswap16(target_fl64->l_pid);
+ fl64.l_pid = tswap32(target_fl64->l_pid);
unlock_user_struct(target_fl64, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl64));
if (ret == 0) {
@@ -3776,7 +3784,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
target_fl64->l_whence = tswap16(fl64.l_whence);
target_fl64->l_start = tswapl(fl64.l_start);
target_fl64->l_len = tswapl(fl64.l_len);
- target_fl64->l_pid = tswapl(fl64.l_pid);
+ target_fl64->l_pid = tswap32(fl64.l_pid);
unlock_user_struct(target_fl64, arg, 1);
}
break;
@@ -3788,7 +3796,7 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
fl64.l_whence = tswap16(target_fl64->l_whence);
fl64.l_start = tswapl(target_fl64->l_start);
fl64.l_len = tswapl(target_fl64->l_len);
- fl64.l_pid = tswap16(target_fl64->l_pid);
+ fl64.l_pid = tswap32(target_fl64->l_pid);
unlock_user_struct(target_fl64, arg, 0);
ret = get_errno(fcntl(fd, host_cmd, &fl64));
break;
@@ -3808,6 +3816,8 @@ static abi_long do_fcntl(int fd, int cmd, abi_ulong arg)
case TARGET_F_GETOWN:
case TARGET_F_SETSIG:
case TARGET_F_GETSIG:
+ case TARGET_F_SETLEASE:
+ case TARGET_F_GETLEASE:
ret = get_errno(fcntl(fd, host_cmd, arg));
break;
@@ -6630,7 +6640,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_efl->l_whence);
fl.l_start = tswap64(target_efl->l_start);
fl.l_len = tswap64(target_efl->l_len);
- fl.l_pid = tswapl(target_efl->l_pid);
+ fl.l_pid = tswap32(target_efl->l_pid);
unlock_user_struct(target_efl, arg3, 0);
} else
#endif
@@ -6641,7 +6651,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswap64(target_fl->l_start);
fl.l_len = tswap64(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg3, 0);
}
ret = get_errno(fcntl(arg1, cmd, &fl));
@@ -6654,7 +6664,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
target_efl->l_whence = tswap16(fl.l_whence);
target_efl->l_start = tswap64(fl.l_start);
target_efl->l_len = tswap64(fl.l_len);
- target_efl->l_pid = tswapl(fl.l_pid);
+ target_efl->l_pid = tswap32(fl.l_pid);
unlock_user_struct(target_efl, arg3, 1);
} else
#endif
@@ -6665,7 +6675,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
target_fl->l_whence = tswap16(fl.l_whence);
target_fl->l_start = tswap64(fl.l_start);
target_fl->l_len = tswap64(fl.l_len);
- target_fl->l_pid = tswapl(fl.l_pid);
+ target_fl->l_pid = tswap32(fl.l_pid);
unlock_user_struct(target_fl, arg3, 1);
}
}
@@ -6681,7 +6691,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_efl->l_whence);
fl.l_start = tswap64(target_efl->l_start);
fl.l_len = tswap64(target_efl->l_len);
- fl.l_pid = tswapl(target_efl->l_pid);
+ fl.l_pid = tswap32(target_efl->l_pid);
unlock_user_struct(target_efl, arg3, 0);
} else
#endif
@@ -6692,7 +6702,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
fl.l_whence = tswap16(target_fl->l_whence);
fl.l_start = tswap64(target_fl->l_start);
fl.l_len = tswap64(target_fl->l_len);
- fl.l_pid = tswapl(target_fl->l_pid);
+ fl.l_pid = tswap32(target_fl->l_pid);
unlock_user_struct(target_fl, arg3, 0);
}
ret = get_errno(fcntl(arg1, cmd, &fl));
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 0f4fbd7..481ce59 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1824,6 +1824,13 @@ struct target_statfs64 {
#define TARGET_F_SETLK64 13
#define TARGET_F_SETLKW64 14
#endif
+
+#define TARGET_F_LINUX_SPECIFIC_BASE 1024
+#define TARGET_F_SETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 0)
+#define TARGET_F_GETLEASE (TARGET_F_LINUX_SPECIFIC_BASE + 1)
+#define TARGET_F_DUPFD_CLOEXEC (TARGET_F_LINUX_SPECIFIC_BASE + 6)
+#define TARGET_F_NOTIFY (TARGET_F_LINUX_SPECIFIC_BASE+2)
+
#if defined (TARGET_ARM)
#define TARGET_O_ACCMODE 0003
#define TARGET_O_RDONLY 00
--
1.6.2.1

View File

@@ -0,0 +1,41 @@
From 0a1fc6cfd1798da391335a37ce7f3fd6141c7ff5 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 23 Jul 2009 17:17:32 +0200
Subject: [PATCH 28/33] linux-user: enable getdents for > 32-bit systems
works perfectly fine with the example from getdents(2) and passes the LTP
tests (tested with s390x on x86_64 emulation)
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 86754f1..49dfb40 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -195,9 +195,7 @@ static int gettid(void) {
return -ENOSYS;
}
#endif
-#if TARGET_ABI_BITS == 32
_syscall3(int, sys_getdents, uint, fd, struct linux_dirent *, dirp, uint, count);
-#endif
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
_syscall3(int, sys_getdents64, uint, fd, struct linux_dirent64 *, dirp, uint, count);
#endif
@@ -5820,9 +5818,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
case TARGET_NR_getdents:
-#if TARGET_ABI_BITS != 32
- goto unimplemented;
-#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
+#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
{
struct target_dirent *target_dirp;
struct linux_dirent *dirp;
--
1.6.2.1

View File

@@ -0,0 +1,271 @@
From d9c50cda4f12fc4c64b8b494a298659b8ad341ed Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 23 Jul 2009 17:41:57 +0200
Subject: [PATCH 29/33] linux-user: define a couple of syscalls for non-uid16 targets
Quite a number of syscalls are only defined on systems with USE_UID16
defined; this patch defines them on other systems as well.
Fixes a large number of uid/gid-related testcases on the s390x target
(and most likely on other targets as well)
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 125 ++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 105 insertions(+), 20 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 49dfb40..b1ef3c9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -309,7 +309,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
return (fchmodat(dirfd, pathname, mode, 0));
}
#endif
-#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat)
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
gid_t group, int flags)
{
@@ -418,7 +418,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
#endif
-#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
uid_t,owner,gid_t,group,int,flags)
#endif
@@ -6382,18 +6382,35 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_setfsgid:
ret = get_errno(setfsgid(arg1));
break;
+#else /* USE_UID16 */
+#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
+ case TARGET_NR_fchownat:
+ if (!(p = lock_user_string(arg2)))
+ goto efault;
+ ret = get_errno(sys_fchownat(arg1, p, arg3, arg4, arg5));
+ unlock_user(p, arg2, 0);
+ break;
+#endif
#endif /* USE_UID16 */
-#ifdef TARGET_NR_lchown32
+#if defined(TARGET_NR_lchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_lchown32)
case TARGET_NR_lchown32:
+#else
+ case TARGET_NR_lchown:
+#endif
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(lchown(p, arg2, arg3));
unlock_user(p, arg1, 0);
break;
#endif
-#ifdef TARGET_NR_getuid32
+#if defined(TARGET_NR_getuid32) || (defined(TARGET_NR_getuid) && !defined(USE_UID16))
+#if defined(TARGET_NR_getuid32)
case TARGET_NR_getuid32:
+#else
+ case TARGET_NR_getuid:
+#endif
ret = get_errno(getuid());
break;
#endif
@@ -6421,33 +6438,57 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
-#ifdef TARGET_NR_getgid32
+#if defined(TARGET_NR_getgid32) || (defined(TARGET_NR_getgid) && !defined(USE_UID16))
+#if defined(TARGET_NR_getgid32)
case TARGET_NR_getgid32:
+#else
+ case TARGET_NR_getgid:
+#endif
ret = get_errno(getgid());
break;
#endif
-#ifdef TARGET_NR_geteuid32
+#if defined(TARGET_NR_geteuid32) || (defined(TARGET_NR_geteuid) && !defined(USE_UID16))
+#if defined(TARGET_NR_geteuid32)
case TARGET_NR_geteuid32:
+#else
+ case TARGET_NR_geteuid:
+#endif
ret = get_errno(geteuid());
break;
#endif
-#ifdef TARGET_NR_getegid32
+#if defined(TARGET_NR_getegid32) || (defined(TARGET_NR_getegid) && !defined(USE_UID16))
+#if defined(TARGET_NR_getegid32)
case TARGET_NR_getegid32:
+#else
+ case TARGET_NR_getegid:
+#endif
ret = get_errno(getegid());
break;
#endif
-#ifdef TARGET_NR_setreuid32
+#if defined(TARGET_NR_setreuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setreuid32)
case TARGET_NR_setreuid32:
+#else
+ case TARGET_NR_setreuid:
+#endif
ret = get_errno(setreuid(arg1, arg2));
break;
#endif
-#ifdef TARGET_NR_setregid32
+#if defined(TARGET_NR_setregid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setregid32)
case TARGET_NR_setregid32:
+#else
+ case TARGET_NR_setregid:
+#endif
ret = get_errno(setregid(arg1, arg2));
break;
#endif
-#ifdef TARGET_NR_getgroups32
+#if defined(TARGET_NR_getgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_getgroups32)
case TARGET_NR_getgroups32:
+#else
+ case TARGET_NR_getgroups:
+#endif
{
int gidsetsize = arg1;
uint32_t *target_grouplist;
@@ -6471,8 +6512,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
-#ifdef TARGET_NR_setgroups32
+#if defined(TARGET_NR_setgroups32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setgroups32)
case TARGET_NR_setgroups32:
+#else
+ case TARGET_NR_setgroups:
+#endif
{
int gidsetsize = arg1;
uint32_t *target_grouplist;
@@ -6492,18 +6537,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
-#ifdef TARGET_NR_fchown32
+#if defined(TARGET_NR_fchown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_fchown32)
case TARGET_NR_fchown32:
+#else
+ case TARGET_NR_fchown:
+#endif
ret = get_errno(fchown(arg1, arg2, arg3));
break;
#endif
-#ifdef TARGET_NR_setresuid32
+#if defined(TARGET_NR_setresuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setresuid32)
case TARGET_NR_setresuid32:
+#else
+ case TARGET_NR_setresuid:
+#endif
ret = get_errno(setresuid(arg1, arg2, arg3));
break;
#endif
-#ifdef TARGET_NR_getresuid32
+#if defined(TARGET_NR_getresuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_getresuid32)
case TARGET_NR_getresuid32:
+#else
+ case TARGET_NR_getresuid:
+#endif
{
uid_t ruid, euid, suid;
ret = get_errno(getresuid(&ruid, &euid, &suid));
@@ -6516,13 +6573,21 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
-#ifdef TARGET_NR_setresgid32
+#if defined(TARGET_NR_setresgid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setresgid32)
case TARGET_NR_setresgid32:
+#else
+ case TARGET_NR_setresgid:
+#endif
ret = get_errno(setresgid(arg1, arg2, arg3));
break;
#endif
+#if defined(TARGET_NR_getresgid32) || !defined(USE_UID16)
#ifdef TARGET_NR_getresgid32
case TARGET_NR_getresgid32:
+#else
+ case TARGET_NR_getresgid:
+#endif
{
gid_t rgid, egid, sgid;
ret = get_errno(getresgid(&rgid, &egid, &sgid));
@@ -6535,31 +6600,51 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
}
break;
#endif
-#ifdef TARGET_NR_chown32
+#if defined(TARGET_NR_chown32) || !defined(USE_UID16)
+#if defined(TARGET_NR_chown32)
case TARGET_NR_chown32:
+#else
+ case TARGET_NR_chown:
+#endif
if (!(p = lock_user_string(arg1)))
goto efault;
ret = get_errno(chown(p, arg2, arg3));
unlock_user(p, arg1, 0);
break;
#endif
-#ifdef TARGET_NR_setuid32
+#if defined(TARGET_NR_setuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setuid32)
case TARGET_NR_setuid32:
+#else
+ case TARGET_NR_setuid:
+#endif
ret = get_errno(setuid(arg1));
break;
#endif
-#ifdef TARGET_NR_setgid32
+#if defined(TARGET_NR_setgid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setgid32)
case TARGET_NR_setgid32:
+#else
+ case TARGET_NR_setgid:
+#endif
ret = get_errno(setgid(arg1));
break;
#endif
-#ifdef TARGET_NR_setfsuid32
+#if defined(TARGET_NR_setfsuid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setfsuid32)
case TARGET_NR_setfsuid32:
+#else
+ case TARGET_NR_setfsuid:
+#endif
ret = get_errno(setfsuid(arg1));
break;
#endif
-#ifdef TARGET_NR_setfsgid32
+#if defined(TARGET_NR_setfsgid32) || !defined(USE_UID16)
+#if defined(TARGET_NR_setfsgid32)
case TARGET_NR_setfsgid32:
+#else
+ case TARGET_NR_setfsgid:
+#endif
ret = get_errno(setfsgid(arg1));
break;
#endif
--
1.6.2.1

View File

@@ -0,0 +1,28 @@
From 03004ec00de3f29699a6bb9458942ea111f528ed Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 23 Jul 2009 17:55:41 +0200
Subject: [PATCH 30/33] linux-user: getpriority errno fix
getpriority returned wrong errno; fixes LTP test getpriority02.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b1ef3c9..30fb4ab 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5327,7 +5327,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
/* libc does special remapping of the return value of
* sys_getpriority() so it's just easiest to call
* sys_getpriority() directly rather than through libc. */
- ret = sys_getpriority(arg1, arg2);
+ ret = get_errno(sys_getpriority(arg1, arg2));
break;
case TARGET_NR_setpriority:
ret = get_errno(setpriority(arg1, arg2, arg3));
--
1.6.2.1

View File

@@ -0,0 +1,46 @@
From 51e609fc6a4a6ff29cd463babfe14032aea18254 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 23 Jul 2009 14:56:59 +0200
Subject: [PATCH 31/33] linux-user: fadvise64 implementation
good enough to pass all LTP fadvise64 tests
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 17 ++++++++++++++---
1 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 30fb4ab..c4b7001 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6680,12 +6680,23 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
arg4 = temp;
}
#endif
-#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64)
+#if defined(TARGET_NR_fadvise64_64) || defined(TARGET_NR_arm_fadvise64_64) || defined(TARGET_NR_fadvise64)
#ifdef TARGET_NR_fadvise64_64
case TARGET_NR_fadvise64_64:
#endif
- /* This is a hint, so ignoring and returning success is ok. */
- ret = get_errno(0);
+#ifdef TARGET_NR_fadvise64
+ case TARGET_NR_fadvise64:
+#endif
+#ifdef TARGET_S390X
+ switch (arg4) {
+ case 4: arg4 = POSIX_FADV_NOREUSE + 1; break; /* make sure it's an invalid value */
+ case 5: arg4 = POSIX_FADV_NOREUSE + 2; break; /* ditto */
+ case 6: arg4 = POSIX_FADV_DONTNEED; break;
+ case 7: arg4 = POSIX_FADV_NOREUSE; break;
+ default: break;
+ }
+#endif
+ ret = -posix_fadvise(arg1, arg2, arg3, arg4);
break;
#endif
#ifdef TARGET_NR_madvise
--
1.6.2.1

View File

@@ -0,0 +1,31 @@
From 50a2b3b61b897ada12c267538e9f65578c256880 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Fri, 10 Jul 2009 16:43:26 +0200
Subject: [PATCH 32/33] linux-user: zero fstat buffer to initialize nsec fields
The fstat implementation does not initialize the nanosecond fields in the
stat buffer; this caused funny values to turn up there, preventing, for
instance, cp -p from preserving timestamps because utimensat rejected
the out-of-bounds nanosecond values. Resetting the entire structure
to zero fixes that.
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
linux-user/syscall.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c4b7001..ef76537 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5552,6 +5552,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (!lock_user_struct(VERIFY_WRITE, target_st, arg2, 0))
goto efault;
+ memset(target_st, 0, sizeof(*target_st));
__put_user(st.st_dev, &target_st->st_dev);
__put_user(st.st_ino, &target_st->st_ino);
__put_user(st.st_mode, &target_st->st_mode);
--
1.6.2.1

View File

@@ -0,0 +1,76 @@
From 1e8223836a2e09899cd946db4e4ee99b64ceb7a4 Mon Sep 17 00:00:00 2001
From: Ulrich Hecht <uli@suse.de>
Date: Thu, 30 Jul 2009 16:02:52 +0200
Subject: [PATCH 33/33] dup3 check, fallocate check fixed
Signed-off-by: Ulrich Hecht <uli@suse.de>
---
configure | 20 +++++++++++++++++++-
linux-user/syscall.c | 4 +++-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index 4be25f6..8d3967d 100755
--- a/configure
+++ b/configure
@@ -1370,6 +1370,21 @@ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
fallocate=yes
fi
+# check for dup3
+dup3=no
+cat > $TMPC << EOF
+#include <unistd.h>
+
+int main(void)
+{
+ dup3(0, 0, 0);
+ return 0;
+}
+EOF
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
+ dup3=yes
+fi
+
# Check if tools are available to build documentation.
if test "$build_docs" = "yes" -a \( ! -x "`which texi2html 2>/dev/null`" -o ! -x "`which pod2man 2>/dev/null`" \) ; then
build_docs="no"
@@ -1723,7 +1738,10 @@ if test "$splice" = "yes" ; then
echo "#define CONFIG_SPLICE 1" >> $config_host_h
fi
if test "$fallocate" = "yes" ; then
- echo "#define CONFIG_FALLOCATE 1" >> $config_host_h
+ echo "CONFIG_FALLOCATE=y" >> $config_host_mak
+fi
+if test "$dup3" = "yes" ; then
+ echo "CONFIG_DUP3=y" >> $config_host_mak
fi
if test "$inotify" = "yes" ; then
echo "#define CONFIG_INOTIFY 1" >> $config_host_h
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ef76537..6c109de 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3707,8 +3707,10 @@ static int target_to_host_fcntl_cmd(int cmd)
return F_SETLEASE;
case TARGET_F_GETLEASE:
return F_GETLEASE;
+#ifdef F_DUPFD_CLOEXEC
case TARGET_F_DUPFD_CLOEXEC:
return F_DUPFD_CLOEXEC;
+#endif
case TARGET_F_NOTIFY:
return F_NOTIFY;
default:
@@ -4758,7 +4760,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_dup2:
ret = get_errno(dup2(arg1, arg2));
break;
-#ifdef TARGET_NR_dup3
+#if defined(TARGET_NR_dup3) && defined(CONFIG_DUP3)
case TARGET_NR_dup3:
ret = get_errno(dup3(arg1, arg2, arg3));
break;
--
1.6.2.1

View File

@@ -0,0 +1,32 @@
--- i386-dis.c 2009-03-22 00:05:48.000000000 +0100
+++ i386-dis_new.c 2009-04-21 08:31:08.000000000 +0200
@@ -784,13 +784,13 @@
{ "movhpX", EX, XM, SIMD_Fixup, 'l' },
/* 18 */
{ GRP14 },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
- { "(bad)", XX, XX, XX },
+ { "nopQ", Ev, XX, XX },
+ { "nopQ", Ev, XX, XX },
+ { "nopQ", Ev, XX, XX },
+ { "nopQ", Ev, XX, XX },
+ { "nopQ", Ev, XX, XX },
+ { "nopQ", Ev, XX, XX },
+ { "nopQ", Ev, XX, XX },
/* 20 */
{ "movL", Rm, Cm, XX },
{ "movL", Rm, Dm, XX },
@@ -1072,7 +1072,7 @@
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/* ------------------------------- */
/* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
- /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
+ /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
/* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
/* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
/* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */

View File

@@ -0,0 +1,11 @@
--- qemu-0.11.0.orig/linux-user/main.c 2009-10-23 02:19:57.000000000 +0200
+++ qemu-0.11.0/linux-user/main.c 2009-10-23 02:47:09.000000000 +0200
@@ -1469,6 +1469,8 @@
#ifdef TARGET_MIPS
+#define TARGET_QEMU_ESIGRETURN 255
+
#define MIPS_SYS(name, args) args,
static const uint8_t mips_syscall_args[] = {

View File

@@ -0,0 +1,620 @@
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/ioctls.h ./linux-user/ioctls.h
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/ioctls.h 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/ioctls.h 2009-07-17 08:28:45.000000000 +0200
@@ -74,7 +74,7 @@
IOCTL(FIGETBSZ, IOC_R, MK_PTR(TYPE_LONG))
#endif
- IOCTL(SIOCATMARK, 0, TYPE_NULL)
+ IOCTL(SIOCATMARK, 0, MK_PTR(TYPE_INT))
IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL(SIOCDELRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/main.c ./linux-user/main.c
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/main.c 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/main.c 2009-07-17 08:29:22.000000000 +0200
@@ -1004,7 +1004,7 @@
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
- exit (1);
+ _exit (1);
}
process_pending_signals (env);
}
@@ -1933,7 +1933,7 @@
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
- exit (1);
+ _exit (1);
}
process_pending_signals (env);
}
@@ -2240,6 +2240,7 @@
TaskState ts1, *ts = &ts1;
CPUState *env;
int optind;
+ int argskip=0;
const char *r;
int gdbstub_port = 0;
char **target_environ, **wrk;
@@ -2289,7 +2290,7 @@
for(item = cpu_log_items; item->mask != 0; item++) {
printf("%-10s %s\n", item->name, item->help);
}
- exit(1);
+ _exit(1);
}
cpu_set_log(mask);
} else if (!strcmp(r, "E")) {
@@ -2320,8 +2321,10 @@
if (qemu_host_page_size == 0 ||
(qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
fprintf(stderr, "page size must be a power of two\n");
- exit(1);
+ _exit(1);
}
+ } else if (!strcmp(r,"-sbox-call")) {
+ argskip++;
} else if (!strcmp(r, "g")) {
if (optind >= argc)
break;
@@ -2368,7 +2371,7 @@
cpu_model = "qemu32";
#endif
#elif defined(TARGET_ARM)
- cpu_model = "arm926";
+ cpu_model = "any";
#elif defined(TARGET_M68K)
cpu_model = "any";
#elif defined(TARGET_SPARC)
@@ -2410,7 +2413,7 @@
target_environ = envlist_to_environ(envlist, NULL);
envlist_free(envlist);
- if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+ if (loader_exec(filename, argv+optind+argskip, target_environ, regs, info) != 0) {
printf("Error loading %s\n", filename);
_exit(1);
}
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/signal.c ./linux-user/signal.c
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/signal.c 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/signal.c 2009-07-17 08:28:54.000000000 +0200
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <signal.h>
#include <errno.h>
+#include <assert.h>
#include <sys/ucontext.h>
#include "qemu.h"
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall.c ./linux-user/syscall.c
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall.c 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/syscall.c 2009-07-17 08:28:51.000000000 +0200
@@ -44,12 +44,14 @@
#include <sched.h>
#include <sys/socket.h>
#include <sys/uio.h>
+#include <sys/un.h>
#include <sys/poll.h>
#include <sys/times.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/statfs.h>
#include <utime.h>
+#include <sys/sysctl.h>
#include <sys/sysinfo.h>
//#include <sys/user.h>
#include <netinet/ip.h>
@@ -299,6 +301,7 @@
extern int setfsuid(int);
extern int setfsgid(int);
extern int setgroups(int, gid_t *);
+extern int uselib(const char*);
#define ERRNO_TABLE_SIZE 1200
@@ -690,14 +693,17 @@
static inline abi_long target_to_host_sockaddr(struct sockaddr *addr,
abi_ulong target_addr,
- socklen_t len)
+ socklen_t *target_len)
{
+ const socklen_t len = sizeof (struct sockaddr_un);
struct target_sockaddr *target_saddr;
- target_saddr = lock_user(VERIFY_READ, target_addr, len, 1);
+ target_saddr = lock_user(VERIFY_READ, target_addr, *target_len, 1);
if (!target_saddr)
return -TARGET_EFAULT;
- memcpy(addr, target_saddr, len);
+ if (target_saddr->sa_family == AF_UNIX && *target_len > len)
+ *target_len = len;
+ memcpy(addr, target_saddr, *target_len);
addr->sa_family = tswap16(target_saddr->sa_family);
unlock_user(target_saddr, target_addr, 0);
@@ -833,6 +839,32 @@
return 0;
}
+static inline abi_long host_to_target_linger(target_ulong target_addr,
+ struct linger *host_l)
+{
+ struct target_linger *target_l;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_l, target_addr, 0))
+ return -TARGET_EFAULT;
+ target_l->l_onoff = tswapl(host_l->l_onoff);
+ target_l->l_linger = tswapl(host_l->l_linger);
+ unlock_user_struct(target_l, target_addr, 1);
+ return 0;
+}
+
+static inline abi_long target_to_host_linger(struct linger *host_l,
+ target_ulong target_addr)
+{
+ struct target_linger *target_l;
+
+ if (!lock_user_struct(VERIFY_WRITE, target_l, target_addr, 1))
+ return -TARGET_EFAULT;
+ host_l->l_onoff = tswapl(target_l->l_onoff);
+ host_l->l_linger = tswapl(target_l->l_linger);
+ unlock_user_struct(target_l, target_addr, 0);
+ return 0;
+}
+
/* do_setsockopt() Must return target values and target errnos. */
static abi_long do_setsockopt(int sockfd, int level, int optname,
abi_ulong optval_addr, socklen_t optlen)
@@ -883,7 +915,6 @@
break;
case TARGET_SOL_SOCKET:
switch (optname) {
- /* Options with 'int' argument. */
case TARGET_SO_DEBUG:
optname = SO_DEBUG;
break;
@@ -940,16 +971,44 @@
case TARGET_SO_SNDTIMEO:
optname = SO_SNDTIMEO;
break;
- break;
+ case TARGET_SO_LINGER:
+ optname = SO_LINGER;
+ break;
default:
goto unimplemented;
}
- if (optlen < sizeof(uint32_t))
- return -TARGET_EINVAL;
-
- if (get_user_u32(val, optval_addr))
- return -TARGET_EFAULT;
- ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
+ switch (optname) {
+ /* Options with non-'int' argument. */
+ case SO_RCVTIMEO:
+ case SO_SNDTIMEO:
+ {
+ struct timeval tval;
+ if(optlen < sizeof(struct target_timeval))
+ return -TARGET_EINVAL;
+ copy_from_user_timeval(&tval,optval_addr);
+ ret = get_errno(setsockopt(sockfd, level, optname, &tval,sizeof(tval)));
+ }
+ break;
+ case SO_LINGER:
+ {
+ struct linger tmp;
+ if (optlen < sizeof(struct target_linger))
+ return -TARGET_EINVAL;
+ optname = SO_LINGER;
+ target_to_host_linger(&tmp,optval_addr);
+ ret = get_errno(setsockopt(sockfd, level, optname, &tmp, sizeof(tmp)));
+ }
+ break;
+ /* All remaning options take an 'int' argument. */
+ default:
+ {
+ if (optlen < sizeof(uint32_t))
+ return -TARGET_EINVAL;
+ val = get_user_u32(val, optval_addr);
+ ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val)));
+ }
+ break;
+ }
break;
default:
unimplemented:
@@ -971,10 +1030,55 @@
case TARGET_SOL_SOCKET:
level = SOL_SOCKET;
switch (optname) {
- case TARGET_SO_LINGER:
+ case TARGET_SO_LINGER: {
+ if (get_user_u32(len, optlen))
+ return -TARGET_EFAULT;
+ if(len < sizeof(struct target_linger))
+ return -TARGET_EINVAL;
+ struct linger l;
+ len=sizeof(l);
+
+ ret = get_errno(getsockopt(sockfd, level, optname, &l, &len));
+ host_to_target_linger(optval_addr,&l);
+ if (put_user_u32(sizeof(struct target_linger), optlen))
+ return -TARGET_EFAULT;
+ }
+ break;
+
case TARGET_SO_RCVTIMEO:
- case TARGET_SO_SNDTIMEO:
- case TARGET_SO_PEERCRED:
+ case TARGET_SO_SNDTIMEO: {
+ if (get_user_u32(len, optlen))
+ return -TARGET_EFAULT;
+
+ if(len < sizeof(struct target_timeval))
+ return -TARGET_EINVAL;
+ struct timeval tval;
+ len=sizeof(tval);
+
+ ret = get_errno(getsockopt(sockfd, level, optname, &tval, &len));
+ if (copy_to_user_timeval(optval_addr,&tval))
+ return -TARGET_EFAULT;
+
+ if (put_user_u32(sizeof(struct target_timeval), optlen))
+ return -TARGET_EFAULT;
+ }
+ break;
+
+ case TARGET_SO_PEERCRED: {
+ struct ucred caller;
+ socklen_t optlen = sizeof (caller);
+ ret = get_errno(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED,
+ &caller, &optlen));
+
+ if (optlen != 0 && optval_addr != 0) {
+ if (put_user_u32(caller.pid, optval_addr + 0) ||
+ put_user_u32(caller.uid, optval_addr + 4) ||
+ put_user_u32(caller.gid, optval_addr + 8))
+ return -TARGET_EFAULT;
+ }
+ }
+ break;
+
case TARGET_SO_PEERNAME:
/* These don't just return a single integer */
goto unimplemented;
@@ -1154,7 +1258,7 @@
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ target_to_host_sockaddr(addr, target_addr, &addrlen);
return get_errno(bind(sockfd, addr, addrlen));
}
@@ -1169,7 +1273,7 @@
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
+ target_to_host_sockaddr(addr, target_addr, &addrlen);
return get_errno(connect(sockfd, addr, addrlen));
}
@@ -1193,8 +1297,10 @@
if (msgp->msg_name) {
msg.msg_namelen = tswap32(msgp->msg_namelen);
msg.msg_name = alloca(msg.msg_namelen);
- target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
- msg.msg_namelen);
+ ret = target_to_host_sockaddr(msg.msg_name, tswapl(msgp->msg_name),
+ &msg.msg_namelen);
+ if (is_error(ret))
+ goto fail;
} else {
msg.msg_name = NULL;
msg.msg_namelen = 0;
@@ -1224,6 +1330,7 @@
}
}
unlock_iovec(vec, target_vec, count, !send);
+fail:
unlock_user_struct(msgp, target_msg, send ? 0 : 1);
return ret;
}
@@ -1237,7 +1344,10 @@
abi_long ret;
if (get_user_u32(addrlen, target_addrlen_addr))
- return -TARGET_EFAULT;
+ return -TARGET_EINVAL;
+
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
+ return -TARGET_EINVAL;
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
return -TARGET_EINVAL;
@@ -1267,12 +1377,15 @@
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
return -TARGET_EINVAL;
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
+ return -TARGET_EINVAL;
+
addr = alloca(addrlen);
ret = get_errno(getpeername(fd, addr, &addrlen));
if (!is_error(ret)) {
- host_to_target_sockaddr(target_addr, addr, addrlen);
- if (put_user_u32(addrlen, target_addrlen_addr))
+ if ((host_to_target_sockaddr(target_addr, addr, addrlen) < 0) ||
+ (put_user_u32(addrlen, target_addrlen_addr)))
ret = -TARGET_EFAULT;
}
return ret;
@@ -1299,8 +1412,8 @@
ret = get_errno(getsockname(fd, addr, &addrlen));
if (!is_error(ret)) {
- host_to_target_sockaddr(target_addr, addr, addrlen);
- if (put_user_u32(addrlen, target_addrlen_addr))
+ if ((host_to_target_sockaddr(target_addr, addr, addrlen) < 0) ||
+ (put_user_u32(addrlen, target_addrlen_addr)))
ret = -TARGET_EFAULT;
}
return ret;
@@ -1333,13 +1446,17 @@
if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
return -TARGET_EINVAL;
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR)
+ return -TARGET_EINVAL;
+
host_msg = lock_user(VERIFY_READ, msg, len, 1);
if (!host_msg)
return -TARGET_EFAULT;
if (target_addr) {
addr = alloca(addrlen);
- target_to_host_sockaddr(addr, target_addr, addrlen);
- ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
+ ret = target_to_host_sockaddr(addr, target_addr, &addrlen);
+ if (!is_error(ret))
+ ret = get_errno(sendto(fd, host_msg, len, flags, addr, addrlen));
} else {
ret = get_errno(send(fd, host_msg, len, flags));
}
@@ -1369,6 +1486,10 @@
ret = -TARGET_EINVAL;
goto fail;
}
+ if (addrlen < 0 || addrlen > MAX_SOCK_ADDR) {
+ ret = -TARGET_EINVAL;
+ goto fail;
+ }
addr = alloca(addrlen);
ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, &addrlen));
} else {
@@ -2856,6 +2977,7 @@
pthread_cond_t cond;
pthread_t thread;
uint32_t tid;
+ unsigned int flags;
abi_ulong child_tidptr;
abi_ulong parent_tidptr;
sigset_t sigmask;
@@ -2869,9 +2991,11 @@
env = info->env;
thread_env = env;
info->tid = gettid();
- if (info->child_tidptr)
+ if (info->flags & CLONE_CHILD_SETTID)
put_user_u32(info->tid, info->child_tidptr);
- if (info->parent_tidptr)
+ if (info->flags & CLONE_CHILD_CLEARTID)
+ set_tid_address(g2h(info->child_tidptr));
+ if (info->flags & CLONE_PARENT_SETTID)
put_user_u32(info->tid, info->parent_tidptr);
/* Enable signals. */
sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
@@ -2936,7 +3060,6 @@
nptl_flags = flags;
flags &= ~CLONE_NPTL_FLAGS2;
- /* TODO: Implement CLONE_CHILD_CLEARTID. */
if (nptl_flags & CLONE_SETTLS)
cpu_set_tls (new_env, newtls);
@@ -2948,7 +3071,9 @@
pthread_mutex_lock(&info.mutex);
pthread_cond_init(&info.cond, NULL);
info.env = new_env;
- if (nptl_flags & CLONE_CHILD_SETTID)
+ info.flags = nptl_flags;
+ if (nptl_flags & CLONE_CHILD_SETTID ||
+ nptl_flags & CLONE_CHILD_CLEARTID)
info.child_tidptr = child_tidptr;
if (nptl_flags & CLONE_PARENT_SETTID)
info.parent_tidptr = parent_tidptr;
@@ -4446,7 +4571,8 @@
#endif
#ifdef TARGET_NR_uselib
case TARGET_NR_uselib:
- goto unimplemented;
+ ret = get_errno(uselib(path((const char*)arg1)));
+ break;
#endif
#ifdef TARGET_NR_swapon
case TARGET_NR_swapon:
@@ -5191,9 +5317,35 @@
break;
#endif
case TARGET_NR__sysctl:
- /* We don't implement this, but ENOTDIR is always a safe
- return value. */
- ret = -TARGET_ENOTDIR;
+ {
+ struct __sysctl_args *args = (struct __sysctl_args *) arg1;
+ int *name_target, *name, nlen, *oldlenp, oldlen, newlen, i;
+ void *oldval, *newval;
+
+ name_target = (int *) tswapl((long) args->name);
+ nlen = tswapl(args->nlen);
+ oldval = (void *) tswapl((long) args->oldval);
+ oldlenp = (int *) tswapl((long) args->oldlenp);
+ oldlen = tswapl(*oldlenp);
+ newval = (void *) tswapl((long) args->newval);
+ newlen = tswapl(args->newlen);
+
+ name = alloca(nlen * sizeof (int));
+ for (i = 0; i < nlen; i++)
+ name[i] = tswapl(name_target[i]);
+
+ if (nlen == 2 && name[0] == CTL_KERN && name[1] == KERN_VERSION) {
+ ret = get_errno(
+ sysctl(name, nlen, oldval, &oldlen, newval, newlen));
+ if (!is_error(ret)) {
+ *oldlenp = tswapl(oldlen);
+ }
+ } else {
+ gemu_log("qemu: Unsupported sysctl name\n");
+ ret = -ENOSYS;
+ }
+ }
+ break;
break;
case TARGET_NR_sched_setparam:
{
@@ -6051,9 +6203,15 @@
#if defined(TARGET_NR_utimensat) && defined(__NR_utimensat)
case TARGET_NR_utimensat:
{
- struct timespec ts[2];
- target_to_host_timespec(ts, arg3);
- target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
+ struct timespec * ts = NULL;
+
+ if (arg3) {
+ struct timespec ts_[2];
+ ts = ts_;
+ target_to_host_timespec(ts, arg3);
+ target_to_host_timespec(ts+1, arg3+sizeof(struct target_timespec));
+ }
+
if (!arg2)
ret = get_errno(sys_utimensat(arg1, NULL, ts, arg4));
else {
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall_defs.h ./linux-user/syscall_defs.h
--- /home/ogra/Devel/packages/qemu-0.10.5/linux-user/syscall_defs.h 2009-05-20 22:46:59.000000000 +0200
+++ ./linux-user/syscall_defs.h 2009-07-17 08:28:13.000000000 +0200
@@ -114,6 +114,11 @@
abi_long tv_nsec;
};
+struct target_linger {
+ target_long l_onoff;
+ target_long l_linger;
+};
+
struct target_itimerval {
struct target_timeval it_interval;
struct target_timeval it_value;
diff -ruN /home/ogra/Devel/packages/qemu-0.10.5/target-arm/translate.c ./target-arm/translate.c
--- /home/ogra/Devel/packages/qemu-0.10.5/target-arm/translate.c 2009-05-20 22:47:00.000000000 +0200
+++ ./target-arm/translate.c 2009-07-17 08:28:13.000000000 +0200
@@ -5757,7 +5757,7 @@
}
} else if ((insn & 0x0e5fffe0) == 0x084d0500) {
/* srs */
- uint32_t offset;
+ int32_t offset;
if (IS_USER(s))
goto illegal_op;
ARCH(6);
@@ -5771,8 +5771,8 @@
i = (insn >> 23) & 3;
switch (i) {
case 0: offset = -4; break; /* DA */
- case 1: offset = -8; break; /* DB */
- case 2: offset = 0; break; /* IA */
+ case 1: offset = 0; break; /* IA */
+ case 2: offset = -8; break; /* DB */
case 3: offset = 4; break; /* IB */
default: abort();
}
@@ -5780,32 +5780,33 @@
tcg_gen_addi_i32(addr, addr, offset);
tmp = load_reg(s, 14);
gen_st32(tmp, addr, 0);
- tmp = new_tmp();
- gen_helper_cpsr_read(tmp);
+ tmp = load_cpu_field(spsr);
tcg_gen_addi_i32(addr, addr, 4);
gen_st32(tmp, addr, 0);
if (insn & (1 << 21)) {
/* Base writeback. */
switch (i) {
case 0: offset = -8; break;
- case 1: offset = -4; break;
- case 2: offset = 4; break;
+ case 1: offset = 4; break;
+ case 2: offset = -4; break;
case 3: offset = 0; break;
default: abort();
}
if (offset)
- tcg_gen_addi_i32(addr, tmp, offset);
+ tcg_gen_addi_i32(addr, addr, offset);
if (op1 == (env->uncached_cpsr & CPSR_M)) {
- gen_movl_reg_T1(s, 13);
+ store_reg(s, 13, addr);
} else {
- gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
+ gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), addr);
+ dead_tmp(addr);
}
} else {
dead_tmp(addr);
}
+ return;
} else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
/* rfe */
- uint32_t offset;
+ int32_t offset;
if (IS_USER(s))
goto illegal_op;
ARCH(6);
@@ -5814,8 +5815,8 @@
i = (insn >> 23) & 3;
switch (i) {
case 0: offset = -4; break; /* DA */
- case 1: offset = -8; break; /* DB */
- case 2: offset = 0; break; /* IA */
+ case 1: offset = 0; break; /* IA */
+ case 2: offset = -8; break; /* DB */
case 3: offset = 4; break; /* IB */
default: abort();
}
@@ -5829,8 +5830,8 @@
/* Base writeback. */
switch (i) {
case 0: offset = -8; break;
- case 1: offset = -4; break;
- case 2: offset = 4; break;
+ case 1: offset = 4; break;
+ case 2: offset = -4; break;
case 3: offset = 0; break;
default: abort();
}
@@ -5841,6 +5842,7 @@
dead_tmp(addr);
}
gen_rfe(s, tmp, tmp2);
+ return;
} else if ((insn & 0x0e000000) == 0x0a000000) {
/* branch link and change to thumb (blx <offset>) */
int32_t offset;

View File

@@ -0,0 +1,46 @@
diff --git a/linux-user/main.c b/linux-user/main.c
index 124b98c..b010fd2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1905,6 +1905,10 @@ void usage(void)
"-cpu model select CPU (-cpu ? for list)\n"
"-drop-ld-preload drop LD_PRELOAD for target process\n"
"\n"
+ "Root options:\n"
+ "-chroot dir chroot to dir\n"
+ "-su uid:gid set numeric user and group IDs\n"
+ "\n"
"Debug options:\n"
"-d options activate log (logfile=%s)\n"
"-p pagesize set the host page size to 'pagesize'\n"
@@ -2011,6 +2015,28 @@ int main(int argc, char **argv)
drop_ld_preload = 1;
} else if (!strcmp(r, "strace")) {
do_strace = 1;
+ } else if (!strcmp(r, "chroot")) {
+ if (chdir(argv[optind++]) || chroot(".")) {
+ fprintf(stderr, "Can't chroot to '%s' (are you root?)\n",
+ argv[--optind]);
+ _exit(1);
+ }
+ } else if (!strcmp(r, "su")) {
+ int temp;
+ char *gid = strchr(argv[optind], ':');
+ if (gid) {
+ temp = atoi(++gid);
+ if (setresgid(temp, temp, temp)) {
+ fprintf(stderr, "Can't set gid to %d (are you root?)\n",
+ temp);
+ _exit(1);
+ }
+ }
+ temp = atoi(argv[optind++]);
+ if (setresuid(temp, temp, temp)) {
+ fprintf(stderr, "Can't set uid to %d (are you root?)\n", temp);
+ _exit(1);
+ }
} else
{
usage();

View File

@@ -0,0 +1,20 @@
#!/bin/sh
if [ -x /sbin/brctl ]; then
BRCTL="/sbin/brctl"
elif [ -x /usr/sbin/brctl ]; then
BRCTL="/usr/sbin/brctl"
else
echo "no bridge utils installed"
exit 1
fi
if [ -x /sbin/ip ]; then
switch=( $(/sbin/ip route list | awk '/^default / { sub(/.* dev /, ""); print $1 }') )
${BRCTL} delif ${switch} $1
/sbin/ip link set $1 down
else
switch=( $(/bin/netstat -rn | awk '/^0\.0\.0\.0/ { print $NF }') )
${BRCTL} delif ${switch} $1
/sbin/ifconfig $1 down
fi

View File

@@ -0,0 +1,22 @@
#!/bin/sh
if [ -x /sbin/brctl ]; then
BRCTL="/sbin/brctl"
elif [ -x /usr/sbin/brctl ]; then
BRCTL="/usr/sbin/brctl"
else
echo "no bridge utils installed"
exit 1
fi
if [ -x /sbin/ip ]; then
switch=( $(/sbin/ip route list | awk '/^default / { sub(/.* dev /, ""); print $1 }') )
/sbin/ip link set $1 up
else
switch=( $(/bin/netstat -rn | awk '/^0\.0\.0\.0/ { print $NF }') )
/sbin/ifconfig $1 0.0.0.0 up
fi
[[ ${switch#} -ne "1" ]] && logger -t qemu "$0 found more than one bridge connecting $1 to ${switch}"
${BRCTL} addif ${switch} $1