diff options
author | nox <nox@FreeBSD.org> | 2013-08-21 06:03:10 +0800 |
---|---|---|
committer | nox <nox@FreeBSD.org> | 2013-08-21 06:03:10 +0800 |
commit | f6778dafa20da92cc8f351d9ece83f08f78b861f (patch) | |
tree | 6e410f147aab5715db036270b661a814dc7a0536 /emulators/qemu-devel | |
parent | 56dbf33d9709d4715052274bb42f9780709b1398 (diff) | |
download | freebsd-ports-gnome-f6778dafa20da92cc8f351d9ece83f08f78b861f.tar.gz freebsd-ports-gnome-f6778dafa20da92cc8f351d9ece83f08f78b861f.tar.zst freebsd-ports-gnome-f6778dafa20da92cc8f351d9ece83f08f78b861f.zip |
- Update to 1.6.0 - announce message is here:
https://lists.gnu.org/archive/html/qemu-devel/2013-08/msg02245.html
- Remove bsd-user support as sson's patches no longer apply, you can still
use his (older) git tree or my port of it on redports as described here:
https://wiki.freebsd.org/QemuUserModeHowTo
Diffstat (limited to 'emulators/qemu-devel')
33 files changed, 8 insertions, 23333 deletions
diff --git a/emulators/qemu-devel/Makefile b/emulators/qemu-devel/Makefile index ed5182d86cbf..8017d281e739 100644 --- a/emulators/qemu-devel/Makefile +++ b/emulators/qemu-devel/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PORTNAME= qemu -PORTVERSION= 1.5.2 +PORTVERSION= 1.6.0 CATEGORIES= emulators MASTER_SITES= http://wiki.qemu.org/download/:release \ LOCAL/nox:snapshot @@ -17,7 +17,7 @@ LIB_DEPENDS= pixman-1:${PORTSDIR}/x11/pixman HAS_CONFIGURE= yes USE_BZIP2= yes -USES= gmake pkgconfig +USES= gmake pkgconfig bison USE_PERL5_BUILD= yes USE_PYTHON_BUILD= -2.7 USE_GNOME+= glib20 @@ -29,7 +29,7 @@ ONLY_FOR_ARCHS= amd64 i386 powerpc # XXX someone wants to debug sparc64 hosts? CONFLICTS_INSTALL= qemu-[0-9]* OPTIONS_DEFINE= SAMBA X11 GTK2 OPENGL GNUTLS SASL JPEG PNG CURL \ - CDROM_DMA PCAP USBREDIR GNS3 X86_TARGETS BSD_USER \ + CDROM_DMA PCAP USBREDIR GNS3 X86_TARGETS \ STATIC_LINK DOCS SAMBA_DESC= samba dependency (for -smb) GNUTLS_DESC= gnutls dependency (vnc encryption) diff --git a/emulators/qemu-devel/distinfo b/emulators/qemu-devel/distinfo index 97cffe81c6d8..1b30bbdb5c3b 100644 --- a/emulators/qemu-devel/distinfo +++ b/emulators/qemu-devel/distinfo @@ -1,2 +1,2 @@ -SHA256 (qemu/1.5.2/qemu-1.5.2.tar.bz2) = f661147d190ab8432045058a660d810f13dc528fe7017ce578e9f2da2997a250 -SIZE (qemu/1.5.2/qemu-1.5.2.tar.bz2) = 11932902 +SHA256 (qemu/1.6.0/qemu-1.6.0.tar.bz2) = 3132e58ada26d43b6924e8c2f07db80aa1e5022f3dcf03dee7d8bb9194b2cb48 +SIZE (qemu/1.6.0/qemu-1.6.0.tar.bz2) = 12040196 diff --git a/emulators/qemu-devel/files/patch-bsd-user-qemu.h b/emulators/qemu-devel/files/patch-bsd-user-qemu.h deleted file mode 100644 index 6ea43c7ca49b..000000000000 --- a/emulators/qemu-devel/files/patch-bsd-user-qemu.h +++ /dev/null @@ -1,31 +0,0 @@ ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -50,6 +50,10 @@ struct image_info { - abi_ulong entry; - abi_ulong code_offset; - abi_ulong data_offset; -+#if 1 -+ abi_ulong arg_start; -+ abi_ulong arg_end; -+#endif - int personality; - }; - -@@ -72,6 +76,17 @@ struct emulated_sigtable { - typedef struct TaskState { - struct TaskState *next; - int used; /* non zero if used */ -+#if 1 -+#ifdef TARGET_ARM -+ int swi_errno; -+#endif -+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) -+ /* Extra fields for semihosted binaries. */ -+ uint32_t heap_base; -+ uint32_t heap_limit; -+#endif -+ uint32_t stack_base; -+#endif - struct image_info *info; - - struct emulated_sigtable sigtab[TARGET_NSIG]; diff --git a/emulators/qemu-devel/files/patch-configure b/emulators/qemu-devel/files/patch-configure index 61bffda02f4e..45c561b4be4a 100644 --- a/emulators/qemu-devel/files/patch-configure +++ b/emulators/qemu-devel/files/patch-configure @@ -9,14 +9,6 @@ datadir="\${prefix}/share" qemu_docdir="\${prefix}/share/doc/qemu" bindir="\${prefix}/bin" -@@ -974,6 +974,7 @@ i386-bsd-user \ - x86_64-bsd-user \ - sparc-bsd-user \ - sparc64-bsd-user \ -+arm-bsd-user \ - " - fi - @@ -1756,7 +1756,7 @@ if test "$gtk" != "no"; then gtk_libs=`$pkg_config --libs $gtkpackage 2>/dev/null` vte_cflags=`$pkg_config --cflags $vtepackage 2>/dev/null` diff --git a/emulators/qemu-devel/files/patch-configure-ld b/emulators/qemu-devel/files/patch-configure-ld deleted file mode 100644 index 69c2999eb247..000000000000 --- a/emulators/qemu-devel/files/patch-configure-ld +++ /dev/null @@ -1,2528 +0,0 @@ -diff --git a/configure b/configure ---- a/configure -+++ b/configure -@@ -4198,15 +4198,7 @@ fi - - # generate list of library paths for linker script - --$ld --verbose -v 2> /dev/null | grep SEARCH_DIR > ${config_host_ld} - --if test -f ${config_host_ld}~ ; then -- if cmp -s $config_host_ld ${config_host_ld}~ ; then -- mv ${config_host_ld}~ $config_host_ld -- else -- rm ${config_host_ld}~ -- fi --fi - - # use included Linux headers - if test "$linux" = "yes" ; then -@@ -4578,21 +4578,33 @@ if test "$gprof" = "yes" ; then - fi - fi - --if test "$ARCH" = "tci"; then -- linker_script="" --else -- linker_script="-Wl,-T../config-host.ld -Wl,-T,\$(SRC_PATH)/ldscripts/\$(ARCH).ld" --fi -- - if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then -+ textseg_addr= - case "$ARCH" in -- alpha | s390x) -- # The default placement of the application is fine. -- ;; -- *) -- ldflags="$linker_script $ldflags" -+ arm | hppa | i386 | ia64 | m68k | ppc | ppc64 | s390 | sparc | sparc64 | x86_64) -+ default_textseg_addr=0x400000 -+ textseg_addr=0x60000000 -+ ;; -+ mips) -+ default_textseg_addr=0x120000000 -+ textseg_addr=0x400000 - ;; - esac -+ if [ -n "$textseg_addr" ]; then -+ try_ldflags="-Ttext-segment=$textseg_addr" -+ if $ld $try_ldflags /dev/null >/dev/null 2>&1; then -+ ldflags="$ldflags $try_ldflags" -+ else -+ # In case ld does not support -Ttext-segment, edit the default linker -+ # script via sed to set the .text start addr. This is needed on FreeBSD -+ # at least. -+ $ld --verbose | sed \ -+ -e '1,/==================================================/d' \ -+ -e '/==================================================/,$d' \ -+ -e "s/$default_textseg_addr/$textseg_addr/g" > config-host.ld -+ ldflags="$ldflags -Wl,-T../config-host.ld" -+ fi -+ fi - fi - - echo "LDFLAGS+=$ldflags" >> $config_target_mak -diff --git a/ldscripts/alpha.ld b/ldscripts/alpha.ld -deleted file mode 100644 -index 906d76b..0000000 ---- a/ldscripts/alpha.ld -+++ /dev/null -@@ -1,127 +0,0 @@ --OUTPUT_FORMAT("elf64-alpha", "elf64-alpha", -- "elf64-alpha") --OUTPUT_ARCH(alpha) --ENTRY(__start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.text : -- { *(.rel.text) *(.rel.gnu.linkonce.t*) } -- .rela.text : -- { *(.rela.text) *(.rela.gnu.linkonce.t*) } -- .rel.data : -- { *(.rel.data) *(.rel.gnu.linkonce.d*) } -- .rela.data : -- { *(.rela.data) *(.rela.gnu.linkonce.d*) } -- .rel.rodata : -- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } -- .rela.rodata : -- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.bss : { *(.rel.bss) } -- .rela.bss : { *(.rela.bss) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : { *(.init) } =0x47ff041f -- .text : -- { -- *(.text) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.gnu.linkonce.t*) -- } =0x47ff041f -- _etext = .; -- PROVIDE (etext = .); -- .fini : { *(.fini) } =0x47ff041f -- .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -- .rodata1 : { *(.rodata1) } -- .reginfo : { *(.reginfo) } -- /* 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 - 1)); -- .data : -- { -- *(.data) -- *(.gnu.linkonce.d*) -- CONSTRUCTORS -- } -- .data1 : { *(.data1) } -- .ctors : -- { -- *(.ctors) -- } -- .dtors : -- { -- *(.dtors) -- } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- .dynamic : { *(.dynamic) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : { *(.sdata) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : { *(.sbss) *(.scommon) } -- .bss : -- { -- *(.dynbss) -- *(.bss) -- *(COMMON) -- } -- _end = . ; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ --} -diff --git a/ldscripts/arm.ld b/ldscripts/arm.ld -deleted file mode 100644 -index 7f13da9..0000000 ---- a/ldscripts/arm.ld -+++ /dev/null -@@ -1,153 +0,0 @@ --OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", -- "elf32-littlearm") --OUTPUT_ARCH(arm) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.text : -- { *(.rel.text) *(.rel.gnu.linkonce.t*) } -- .rela.text : -- { *(.rela.text) *(.rela.gnu.linkonce.t*) } -- .rel.data : -- { *(.rel.data) *(.rel.gnu.linkonce.d*) } -- .rela.data : -- { *(.rela.data) *(.rela.gnu.linkonce.d*) } -- .rel.rodata : -- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } -- .rela.rodata : -- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.bss : { *(.rel.bss) } -- .rela.bss : { *(.rela.bss) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : { *(.init) } =0x47ff041f -- .text : -- { -- *(.text) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.gnu.linkonce.t*) -- } =0x47ff041f -- _etext = .; -- PROVIDE (etext = .); -- .fini : { *(.fini) } =0x47ff041f -- .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -- .rodata1 : { *(.rodata1) } -- .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } -- __exidx_start = .; -- .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } -- __exidx_end = .; -- .reginfo : { *(.reginfo) } -- /* 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 - 1)); -- .data : -- { -- *(.gen_code) -- *(.data) -- *(.gnu.linkonce.d*) -- CONSTRUCTORS -- } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .data1 : { *(.data1) } -- .preinit_array : -- { -- PROVIDE (__preinit_array_start = .); -- KEEP (*(.preinit_array)) -- PROVIDE (__preinit_array_end = .); -- } -- .init_array : -- { -- PROVIDE (__init_array_start = .); -- KEEP (*(SORT(.init_array.*))) -- KEEP (*(.init_array)) -- PROVIDE (__init_array_end = .); -- } -- .fini_array : -- { -- PROVIDE (__fini_array_start = .); -- KEEP (*(.fini_array)) -- KEEP (*(SORT(.fini_array.*))) -- PROVIDE (__fini_array_end = .); -- } -- .ctors : -- { -- *(.ctors) -- } -- .dtors : -- { -- *(.dtors) -- } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- .dynamic : { *(.dynamic) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : { *(.sdata) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : { *(.sbss) *(.scommon) } -- .bss : -- { -- *(.dynbss) -- *(.bss) -- *(COMMON) -- } -- _end = . ; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ --} -diff --git a/ldscripts/hppa.ld b/ldscripts/hppa.ld -deleted file mode 100644 -index 3555b3e..0000000 ---- a/ldscripts/hppa.ld -+++ /dev/null -@@ -1,211 +0,0 @@ --/* Default linker script, for normal executables */ --OUTPUT_FORMAT("elf32-hppa-linux", "elf32-hppa-linux", -- "elf32-hppa-linux") --OUTPUT_ARCH(hppa:hppa1.1) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -- .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } -- .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } -- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } -- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } -- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } -- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } -- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } -- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } -- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } -- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } -- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : -- { -- KEEP (*(.init)) -- } =0x08000240 -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- KEEP (*(.text.*personality*)) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- } =0x08000240 -- .fini : -- { -- KEEP (*(.fini)) -- } =0x08000240 -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .sdata2 : -- { -- *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) -- } -- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -- .PARISC.unwind : { *(.PARISC.unwind) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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(0x10000) + (. & (0x10000 - 1)); -- /* Exception handling */ -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } -- /* Thread Local Storage sections */ -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .preinit_array : -- { -- PROVIDE (__preinit_array_start = .); -- KEEP (*(.preinit_array)) -- PROVIDE (__preinit_array_end = .); -- } -- .init_array : -- { -- PROVIDE (__init_array_start = .); -- KEEP (*(SORT(.init_array.*))) -- KEEP (*(.init_array)) -- PROVIDE (__init_array_end = .); -- } -- .fini_array : -- { -- PROVIDE (__fini_array_start = .); -- KEEP (*(.fini_array)) -- KEEP (*(SORT(.fini_array.*))) -- PROVIDE (__fini_array_end = .); -- } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin*.o(.ctors)) -- /* We don't want to include the .ctor section from -- the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin*.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } -- .dynamic : { *(.dynamic) } -- .data : -- { -- PROVIDE ($global$ = .); -- *(.data .data.* .gnu.linkonce.d.*) -- KEEP (*(.gnu.linkonce.d.*personality*)) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : -- { -- *(.sdata .sdata.* .gnu.linkonce.s.*) -- } -- _edata = .; PROVIDE (edata = .); -- __bss_start = .; -- .sbss : -- { -- *(.dynsbss) -- *(.sbss .sbss.* .gnu.linkonce.sb.*) -- *(.scommon) -- } -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. -- FIXME: Why do we need it? When there is no .bss section, we don't -- pad the .data section. */ -- . = ALIGN(. != 0 ? 32 / 8 : 1); -- } -- . = ALIGN(32 / 8); -- . = ALIGN(32 / 8); -- _end = .; PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /DISCARD/ : { *(.note.GNU-stack) } --} -diff --git a/ldscripts/i386.ld b/ldscripts/i386.ld -deleted file mode 100644 -index cc3f160..0000000 ---- a/ldscripts/i386.ld -+++ /dev/null -@@ -1,153 +0,0 @@ --/* ld script to make i386 Linux kernel -- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; -- */ --OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") --OUTPUT_ARCH(i386) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.text : -- { *(.rel.text) *(.rel.gnu.linkonce.t*) } -- .rela.text : -- { *(.rela.text) *(.rela.gnu.linkonce.t*) } -- .rel.data : -- { *(.rel.data) *(.rel.gnu.linkonce.d*) } -- .rela.data : -- { *(.rela.data) *(.rela.gnu.linkonce.d*) } -- .rel.rodata : -- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } -- .rela.rodata : -- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.bss : { *(.rel.bss) } -- .rela.bss : { *(.rela.bss) } -- .rel.plt : -- { -- *(.rel.plt) -- PROVIDE (__rel_iplt_start = .); -- *(.rel.iplt) -- PROVIDE (__rel_iplt_end = .); -- } -- .rela.plt : -- { -- *(.rela.plt) -- PROVIDE (__rela_iplt_start = .); -- *(.rela.iplt) -- PROVIDE (__rela_iplt_end = .); -- } -- .init : { *(.init) } =0x47ff041f -- .text : -- { -- *(.text) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.gnu.linkonce.t*) -- } =0x47ff041f -- _etext = .; -- PROVIDE (etext = .); -- .fini : { *(.fini) } =0x47ff041f -- . = ALIGN(32 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -- .rodata1 : { *(.rodata1) } -- .reginfo : { *(.reginfo) } -- /* 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 - 1)); -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .data : -- { -- *(.data) -- *(.gnu.linkonce.d*) -- CONSTRUCTORS -- } -- .data1 : { *(.data1) } -- .ctors : -- { -- *(.ctors) -- } -- .dtors : -- { -- *(.dtors) -- } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- .dynamic : { *(.dynamic) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : { *(.sdata) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : { *(.sbss) *(.scommon) } -- .bss : -- { -- *(.dynbss) -- *(.bss) -- *(COMMON) -- } -- _end = . ; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ --} -diff --git a/ldscripts/ia64.ld b/ldscripts/ia64.ld -deleted file mode 100644 -index 0c37796..0000000 ---- a/ldscripts/ia64.ld -+++ /dev/null -@@ -1,209 +0,0 @@ --/* Default linker script, for normal executables */ --OUTPUT_FORMAT("elf64-ia64-little", "elf64-ia64-little", -- "elf64-ia64-little") --OUTPUT_ARCH(ia64) --ENTRY(_start) --/* __DYNAMIC = 0; */ --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } -- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } -- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } -- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } -- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } -- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } -- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } -- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } -- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .rela.IA_64.pltoff : { *(.rela.IA_64.pltoff) } -- .init : -- { -- KEEP (*(.init)) -- } =0x00300000010070000002000001000400 -- .plt : { *(.plt) } -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- } =0x00300000010070000002000001000400 -- .fini : -- { -- KEEP (*(.fini)) -- } =0x00300000010070000002000001000400 -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } -- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -- .opd : { *(.opd) } -- .IA_64.unwind_info : { *(.IA_64.unwind_info* .gnu.linkonce.ia64unwi.*) } -- .IA_64.unwind : { *(.IA_64.unwind* .gnu.linkonce.ia64unw.*) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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(0x10000) + (. & (0x10000 - 1)); -- /* Ensure the __preinit_array_start label is properly aligned. We -- could instead move the label definition inside the section, but -- the linker would then create the section even if it turns out to -- be empty, which isn't pretty. */ -- . = ALIGN(64 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .data : -- { -- *(.data .data.* .gnu.linkonce.d.*) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table) } -- .dynamic : { *(.dynamic) } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin*.o(.ctors)) -- /* We don't want to include the .ctor section from -- from the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin*.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- /* Ensure __gp is outside the range of any normal data. We need to -- do this to avoid the linker optimizing the code in op.o and getting -- it out of sync with the relocs that we read when processing that -- file. A better solution might be to ensure that the dynamically -- generated code and static qemu code share a single gp-value. */ -- __gp = . + 0x200000; -- .got : { *(.got.plt) *(.got) } -- .IA_64.pltoff : { *(.IA_64.pltoff) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : -- { -- *(.sdata .sdata.* .gnu.linkonce.s.*) -- } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : -- { -- PROVIDE (__sbss_start = .); -- PROVIDE (___sbss_start = .); -- *(.dynsbss) -- *(.sbss .sbss.* .gnu.linkonce.sb.*) -- *(.scommon) -- PROVIDE (__sbss_end = .); -- PROVIDE (___sbss_end = .); -- } -- .bss : -- { -- . += 0x400000; /* ensure .bss stuff is out of reach of gp */ -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. */ -- . = ALIGN(64 / 8); -- } -- . = ALIGN(64 / 8); -- _end = .; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /DISCARD/ : { *(.note.GNU-stack) } --} -diff --git a/ldscripts/m68k.ld b/ldscripts/m68k.ld -deleted file mode 100644 -index 0e3d9de..0000000 ---- a/ldscripts/m68k.ld -+++ /dev/null -@@ -1,175 +0,0 @@ --/* Script for -z combreloc: combine and sort reloc sections */ --OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", -- "elf32-m68k") --OUTPUT_ARCH(m68k) --ENTRY(_start) --/* __DYNAMIC = 0; */ --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.dyn : -- { -- *(.rel.init) -- *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) -- *(.rel.fini) -- *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) -- *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) -- *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) -- *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) -- *(.rel.ctors) -- *(.rel.dtors) -- *(.rel.got) -- *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) -- } -- .rela.dyn : -- { -- *(.rela.init) -- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) -- *(.rela.fini) -- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) -- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) -- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) -- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) -- *(.rela.ctors) -- *(.rela.dtors) -- *(.rela.got) -- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) -- } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : -- { -- KEEP (*(.init)) -- } =0x4e754e75 -- .plt : { *(.plt) } -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- } =0x4e754e75 -- .fini : -- { -- KEEP (*(.fini)) -- } =0x4e754e75 -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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(0x2000) + (. & (0x2000 - 1)); -- /* Ensure the __preinit_array_start label is properly aligned. We -- could instead move the label definition inside the section, but -- the linker would then create the section even if it turns out to -- be empty, which isn't pretty. */ -- . = ALIGN(32 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .data : -- { -- *(.data .data.* .gnu.linkonce.d.*) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table) } -- .dynamic : { *(.dynamic) } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin.o(.ctors)) -- /* We don't want to include the .ctor section from -- from the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .got : { *(.got.plt) *(.got) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. */ -- . = ALIGN(32 / 8); -- } -- . = ALIGN(32 / 8); -- _end = .; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } --} -diff --git a/ldscripts/mips.ld b/ldscripts/mips.ld -deleted file mode 100644 -index 7b610ce..0000000 ---- a/ldscripts/mips.ld -+++ /dev/null -@@ -1,222 +0,0 @@ --/* Default linker script, for normal executables */ --OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", -- "elf32-tradlittlemips") --OUTPUT_ARCH(mips) --ENTRY(__start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- PROVIDE (__executable_start = 0x0400000); . = 0x0400000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .reginfo : { *(.reginfo) } -- .dynamic : { *(.dynamic) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -- .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } -- .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } -- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } -- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } -- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } -- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } -- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } -- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } -- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } -- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } -- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : -- { -- KEEP (*(.init)) -- } =0x47ff041f -- .plt : { *(.plt) } -- .text : -- { -- _ftext = . ; -- *(.text .stub .text.* .gnu.linkonce.t.*) -- KEEP (*(.text.*personality*)) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.mips16.fn.*) *(.mips16.call.*) -- } =0x47ff041f -- .fini : -- { -- KEEP (*(.fini)) -- } =0x47ff041f -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .sdata2 : -- { -- *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) -- } -- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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 (0x40000) - ((0x40000 - .) & (0x40000 - 1)); . = DATA_SEGMENT_ALIGN (0x40000, 0x1000); -- /* Exception handling */ -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } -- /* Thread Local Storage sections */ -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .preinit_array : -- { -- PROVIDE (__preinit_array_start = .); -- KEEP (*(.preinit_array)) -- PROVIDE (__preinit_array_end = .); -- } -- .init_array : -- { -- PROVIDE (__init_array_start = .); -- KEEP (*(SORT(.init_array.*))) -- KEEP (*(.init_array)) -- PROVIDE (__init_array_end = .); -- } -- .fini_array : -- { -- PROVIDE (__fini_array_start = .); -- KEEP (*(.fini_array)) -- KEEP (*(SORT(.fini_array.*))) -- PROVIDE (__fini_array_end = .); -- } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin*.o(.ctors)) -- /* We don't want to include the .ctor section from -- the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin*.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } -- . = DATA_SEGMENT_RELRO_END (0, .); -- .data : -- { -- _fdata = . ; -- *(.data .data.* .gnu.linkonce.d.*) -- KEEP (*(.gnu.linkonce.d.*personality*)) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- . = .; -- _gp = ALIGN(16) + 0x7ff0; -- .got : { *(.got.plt) *(.got) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : -- { -- *(.sdata .sdata.* .gnu.linkonce.s.*) -- } -- .lit8 : { *(.lit8) } -- .lit4 : { *(.lit4) } -- _edata = .; PROVIDE (edata = .); -- __bss_start = .; -- _fbss = .; -- .sbss : -- { -- *(.dynsbss) -- *(.sbss .sbss.* .gnu.linkonce.sb.*) -- *(.scommon) -- } -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. -- FIXME: Why do we need it? When there is no .bss section, we don't -- pad the .data section. */ -- . = ALIGN(. != 0 ? 32 / 8 : 1); -- } -- . = ALIGN(32 / 8); -- . = ALIGN(32 / 8); -- _end = .; PROVIDE (end = .); -- . = DATA_SEGMENT_END (.); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } -- .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } -- /DISCARD/ : { *(.note.GNU-stack) } --} -diff --git a/ldscripts/ppc.ld b/ldscripts/ppc.ld -deleted file mode 100644 -index 2a0dcad..0000000 ---- a/ldscripts/ppc.ld -+++ /dev/null -@@ -1,237 +0,0 @@ --/* ld script to make i386 Linux kernel -- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; -- */ --OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") --OUTPUT_ARCH(powerpc:common) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -- .rel.data.rel.ro : { *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*) } -- .rela.data.rel.ro : { *(.rela.data.rel.ro* .rela.gnu.linkonce.d.rel.ro.*) } -- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rela.got1 : { *(.rela.got1) } -- .rela.got2 : { *(.rela.got2) } -- .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } -- .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } -- .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } -- .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } -- .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } -- .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } -- .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } -- .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } -- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -- .rel.plt : -- { -- *(.rel.plt) -- PROVIDE (__rel_iplt_start = .); -- *(.rel.iplt) -- PROVIDE (__rel_iplt_end = .); -- } -- .rela.plt : -- { -- *(.rela.plt) -- PROVIDE (__rela_iplt_start = .); -- *(.rela.iplt) -- PROVIDE (__rela_iplt_end = .); -- } -- .init : -- { -- KEEP (*(.init)) -- } =0 -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- KEEP (*(.text.*personality*)) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.glink) -- } =0x47ff041f -- .fini : -- { -- KEEP (*(.fini)) -- } =0x47ff041f -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .sdata2 : -- { -- PROVIDE (_SDA2_BASE_ = 32768); -- *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) -- } -- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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 (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000); -- /* Exception handling */ -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } -- /* Thread Local Storage sections */ -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .preinit_array : -- { -- PROVIDE (__preinit_array_start = .); -- KEEP (*(.preinit_array)) -- PROVIDE (__preinit_array_end = .); -- } -- .init_array : -- { -- PROVIDE (__init_array_start = .); -- KEEP (*(SORT(.init_array.*))) -- KEEP (*(.init_array)) -- PROVIDE (__init_array_end = .); -- } -- .fini_array : -- { -- PROVIDE (__fini_array_start = .); -- KEEP (*(.fini_array)) -- KEEP (*(SORT(.fini_array.*))) -- PROVIDE (__fini_array_end = .); -- } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin*.o(.ctors)) -- /* We don't want to include the .ctor section from -- the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin*.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } -- .got1 : { *(.got1) } -- .got2 : { *(.got2) } -- .dynamic : { *(.dynamic) } -- .got : SPECIAL { *(.got) } -- . = DATA_SEGMENT_RELRO_END (0, .); -- .plt : SPECIAL { *(.plt) } -- .data : -- { -- *(.data .data.* .gnu.linkonce.d.*) -- KEEP (*(.gnu.linkonce.d.*personality*)) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .got : SPECIAL { *(.got) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : -- { -- PROVIDE (_SDA_BASE_ = 32768); -- *(.sdata .sdata.* .gnu.linkonce.s.*) -- } -- _edata = .; PROVIDE (edata = .); -- __bss_start = .; -- .sbss : -- { -- PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .); -- *(.dynsbss) -- *(.sbss .sbss.* .gnu.linkonce.sb.*) -- *(.scommon) -- PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .); -- } -- .plt : SPECIAL { *(.plt) } -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. -- FIXME: Why do we need it? When there is no .bss section, we don't -- pad the .data section. */ -- . = ALIGN(. != 0 ? 32 / 8 : 1); -- } -- . = ALIGN(32 / 8); -- . = ALIGN(32 / 8); -- _end = .; PROVIDE (end = .); -- . = DATA_SEGMENT_END (.); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ -- /DISCARD/ : { *(.fixup) } -- /DISCARD/ : { *(.note.GNU-stack) } --} -diff --git a/ldscripts/ppc64.ld b/ldscripts/ppc64.ld -deleted file mode 100644 -index e2dafa0..0000000 ---- a/ldscripts/ppc64.ld -+++ /dev/null -@@ -1,230 +0,0 @@ --/* Script for -z combreloc: combine and sort reloc sections */ --OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", -- "elf64-powerpc") --OUTPUT_ARCH(powerpc:common64) --ENTRY(_start) --/* __DYNAMIC = 0; */ --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- PROVIDE (__executable_start = 0x60000000); . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.dyn : -- { -- *(.rel.init) -- *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) -- *(.rel.fini) -- *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) -- *(.rel.data.rel.ro*) -- *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) -- *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) -- *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) -- *(.rel.ctors) -- *(.rel.dtors) -- *(.rel.got) -- *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) -- *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) -- *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) -- *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) -- *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) -- } -- .rela.dyn : -- { -- *(.rela.init) -- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) -- *(.rela.fini) -- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) -- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) -- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) -- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) -- *(.rela.ctors) -- *(.rela.dtors) -- *(.rela.got) -- *(.rela.toc) -- *(.rela.opd) -- *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) -- *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) -- *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) -- *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) -- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) -- } -- .rel.plt : -- { -- *(.rel.plt) -- PROVIDE (__rel_iplt_start = .); -- *(.rel.iplt) -- PROVIDE (__rel_iplt_end = .); -- } -- .rela.plt : -- { -- *(.rela.plt) -- PROVIDE (__rela_iplt_start = .); -- *(.rela.iplt) -- PROVIDE (__rela_iplt_end = .); -- } -- .rela.tocbss : { *(.rela.tocbss) } -- .init : -- { -- KEEP (*(.init)) -- } =0x60000000 -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- KEEP (*(.text.*personality*)) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.sfpr .glink) -- } =0x60000000 -- .fini : -- { -- KEEP (*(.fini)) -- } =0x60000000 -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } -- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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 (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN --(0x10000, 0x1000); /* Exception handling */ -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { KEEP (*(.gcc_except_table)) --*(.gcc_except_table.*) } /* Thread Local Storage sections */ -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- /* Ensure the __preinit_array_start label is properly aligned. We -- could instead move the label definition inside the section, but -- the linker would then create the section even if it turns out to -- be empty, which isn't pretty. */ -- . = ALIGN(64 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { KEEP (*(.preinit_array)) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { KEEP (*(.init_array)) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { KEEP (*(.fini_array)) } -- PROVIDE (__fini_array_end = .); -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin*.o(.ctors)) -- /* We don't want to include the .ctor section from -- from the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin*.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } -- .dynamic : { *(.dynamic) } -- . = DATA_SEGMENT_RELRO_END (0, .); -- .data : -- { -- *(.data .data.* .gnu.linkonce.d.*) -- KEEP (*(.gnu.linkonce.d.*personality*)) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .toc1 ALIGN(8) : { *(.toc1) } -- .opd ALIGN(8) : { KEEP (*(.opd)) } -- .got ALIGN(8) : { *(.got .toc) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : -- { -- *(.sdata .sdata.* .gnu.linkonce.s.*) -- } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .tocbss ALIGN(8) : { *(.tocbss)} -- .sbss : -- { -- PROVIDE (__sbss_start = .); -- PROVIDE (___sbss_start = .); -- *(.dynsbss) -- *(.sbss .sbss.* .gnu.linkonce.sb.*) -- *(.scommon) -- PROVIDE (__sbss_end = .); -- PROVIDE (___sbss_end = .); -- } -- .plt : { *(.plt) } -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. */ -- . = ALIGN(64 / 8); -- } -- . = ALIGN(64 / 8); -- _end = .; -- PROVIDE (end = .); -- . = DATA_SEGMENT_END (.); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /DISCARD/ : { *(.note.GNU-stack) } --} -diff --git a/ldscripts/s390.ld b/ldscripts/s390.ld -deleted file mode 100644 -index a9c5370..0000000 ---- a/ldscripts/s390.ld -+++ /dev/null -@@ -1,201 +0,0 @@ --OUTPUT_FORMAT("elf32-s390", "elf32-s390", -- "elf32-s390") --OUTPUT_ARCH(s390:31-bit) --ENTRY(_start) --/* __DYNAMIC = 0; */ --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.dyn : -- { -- *(.rel.init) -- *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) -- *(.rel.fini) -- *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) -- *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) -- *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) -- *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) -- *(.rel.ctors) -- *(.rel.dtors) -- *(.rel.got) -- *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) -- *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) -- *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) -- *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) -- *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) -- } -- .rela.dyn : -- { -- *(.rela.init) -- *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) -- *(.rela.fini) -- *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) -- *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) -- *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) -- *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) -- *(.rela.ctors) -- *(.rela.dtors) -- *(.rela.got) -- *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) -- *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) -- *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) -- *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) -- *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) -- } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : -- { -- KEEP (*(.init)) -- } =0x07070707 -- .plt : { *(.plt) } -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- } =0x07070707 -- .fini : -- { -- KEEP (*(.fini)) -- } =0x07070707 -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } -- .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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(0x1000) + (. & (0x1000 - 1)); -- /* Ensure the __preinit_array_start label is properly aligned. We -- could instead move the label definition inside the section, but -- the linker would then create the section even if it turns out to -- be empty, which isn't pretty. */ -- . = ALIGN(32 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .data : -- { -- *(.data .data.* .gnu.linkonce.d.*) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table) } -- .dynamic : { *(.dynamic) } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin.o(.ctors)) -- /* We don't want to include the .ctor section from -- from the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .got : { *(.got.plt) *(.got) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : -- { -- *(.sdata .sdata.* .gnu.linkonce.s.*) -- } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : -- { -- PROVIDE (__sbss_start = .); -- PROVIDE (___sbss_start = .); -- *(.dynsbss) -- *(.sbss .sbss.* .gnu.linkonce.sb.*) -- *(.scommon) -- PROVIDE (__sbss_end = .); -- PROVIDE (___sbss_end = .); -- } -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. */ -- . = ALIGN(32 / 8); -- } -- . = ALIGN(32 / 8); -- _end = .; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } --} -diff --git a/ldscripts/sparc.ld b/ldscripts/sparc.ld -deleted file mode 100644 -index 56efe34..0000000 ---- a/ldscripts/sparc.ld -+++ /dev/null -@@ -1,150 +0,0 @@ --OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", -- "elf32-sparc") --OUTPUT_ARCH(sparc) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.text : -- { *(.rel.text) *(.rel.gnu.linkonce.t*) } -- .rela.text : -- { *(.rela.text) *(.rela.gnu.linkonce.t*) } -- .rel.data : -- { *(.rel.data) *(.rel.gnu.linkonce.d*) } -- .rela.data : -- { *(.rela.data) *(.rela.gnu.linkonce.d*) } -- .rel.rodata : -- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } -- .rela.rodata : -- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.bss : { *(.rel.bss) } -- .rela.bss : { *(.rela.bss) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : { *(.init) } =0x47ff041f -- .text : -- { -- *(.text) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.gnu.linkonce.t*) -- } =0x47ff041f -- _etext = .; -- PROVIDE (etext = .); -- .fini : { *(.fini) } =0x47ff041f -- .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -- .rodata1 : { *(.rodata1) } -- .reginfo : { *(.reginfo) } -- /* 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 - 1)); -- .data : -- { -- *(.data) -- *(.gnu.linkonce.d*) -- CONSTRUCTORS -- } -- .data1 : { *(.data1) } -- .tdata : { *(.tdata) } -- .tbss : { *(.tbss) } -- .preinit_array : -- { -- PROVIDE (__preinit_array_start = .); -- KEEP (*(.preinit_array)) -- PROVIDE (__preinit_array_end = .); -- } -- .init_array : -- { -- PROVIDE (__init_array_start = .); -- KEEP (*(SORT(.init_array.*))) -- KEEP (*(.init_array)) -- PROVIDE (__init_array_end = .); -- } -- .fini_array : -- { -- PROVIDE (__fini_array_start = .); -- KEEP (*(.fini_array)) -- KEEP (*(SORT(.fini_array.*))) -- PROVIDE (__fini_array_end = .); -- } -- .ctors : -- { -- *(.ctors) -- } -- .dtors : -- { -- *(.dtors) -- } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- .dynamic : { *(.dynamic) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : { *(.sdata) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : { *(.sbss) *(.scommon) } -- .bss : -- { -- *(.dynbss) -- *(.bss) -- *(COMMON) -- } -- _end = . ; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ -- /DISCARD/ : { *(.note.GNU-stack) *(.note.ABI-tag) } --} -diff --git a/ldscripts/sparc64.ld b/ldscripts/sparc64.ld -deleted file mode 100644 -index 9ea4143..0000000 ---- a/ldscripts/sparc64.ld -+++ /dev/null -@@ -1,138 +0,0 @@ --OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", -- "elf64-sparc") --OUTPUT_ARCH(sparc:v9) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.text : -- { *(.rel.text) *(.rel.gnu.linkonce.t*) } -- .rela.text : -- { *(.rela.text) *(.rela.gnu.linkonce.t*) } -- .rel.data : -- { *(.rel.data) *(.rel.gnu.linkonce.d*) } -- .rela.data : -- { *(.rela.data) *(.rela.gnu.linkonce.d*) } -- .rel.rodata : -- { *(.rel.rodata) *(.rel.gnu.linkonce.r*) } -- .rela.rodata : -- { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.bss : { *(.rel.bss) } -- .rela.bss : { *(.rela.bss) } -- .rel.plt : { *(.rel.plt) } -- .rela.plt : { *(.rela.plt) } -- .init : { *(.init) } =0x47ff041f -- .text : -- { -- *(.text) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- *(.gnu.linkonce.t*) -- } =0x47ff041f -- _etext = .; -- PROVIDE (etext = .); -- .fini : { *(.fini) } =0x47ff041f -- .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -- .rodata1 : { *(.rodata1) } -- . = ALIGN(64 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .reginfo : { *(.reginfo) } -- /* 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 - 1)); -- .data : -- { -- *(.gen_code) -- *(.data) -- *(.gnu.linkonce.d*) -- CONSTRUCTORS -- } -- .data1 : { *(.data1) } -- .ctors : -- { -- *(.ctors) -- } -- .dtors : -- { -- *(.dtors) -- } -- .plt : { *(.plt) } -- .got : { *(.got.plt) *(.got) } -- .dynamic : { *(.dynamic) } -- /* We want the small data sections together, so single-instruction offsets -- can access them all, and initialized data all before uninitialized, so -- we can shorten the on-disk segment size. */ -- .sdata : { *(.sdata) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .sbss : { *(.sbss) *(.scommon) } -- .bss : -- { -- *(.dynbss) -- *(.bss) -- *(COMMON) -- } -- _end = . ; -- PROVIDE (end = .); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } -- /* These must appear regardless of . */ --} -diff --git a/ldscripts/x86_64.ld b/ldscripts/x86_64.ld -deleted file mode 100644 -index b7a9f4e..0000000 ---- a/ldscripts/x86_64.ld -+++ /dev/null -@@ -1,180 +0,0 @@ --/* Default linker script, for normal executables */ --OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") --OUTPUT_ARCH(i386:x86-64) --ENTRY(_start) --SECTIONS --{ -- /* Read-only sections, merged into text segment: */ -- . = 0x60000000 + SIZEOF_HEADERS; -- .interp : { *(.interp) } -- .hash : { *(.hash) } -- .dynsym : { *(.dynsym) } -- .dynstr : { *(.dynstr) } -- .gnu.version : { *(.gnu.version) } -- .gnu.version_d : { *(.gnu.version_d) } -- .gnu.version_r : { *(.gnu.version_r) } -- .rel.init : { *(.rel.init) } -- .rela.init : { *(.rela.init) } -- .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -- .rel.fini : { *(.rel.fini) } -- .rela.fini : { *(.rela.fini) } -- .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -- .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -- .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -- .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -- .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -- .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -- .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -- .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -- .rel.ctors : { *(.rel.ctors) } -- .rela.ctors : { *(.rela.ctors) } -- .rel.dtors : { *(.rel.dtors) } -- .rela.dtors : { *(.rela.dtors) } -- .rel.got : { *(.rel.got) } -- .rela.got : { *(.rela.got) } -- .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -- .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -- .rel.plt : -- { -- *(.rel.plt) -- PROVIDE (__rel_iplt_start = .); -- *(.rel.iplt) -- PROVIDE (__rel_iplt_end = .); -- } -- .rela.plt : -- { -- *(.rela.plt) -- PROVIDE (__rela_iplt_start = .); -- *(.rela.iplt) -- PROVIDE (__rela_iplt_end = .); -- } -- .init : -- { -- KEEP (*(.init)) -- } =0x90909090 -- .plt : { *(.plt) } -- .text : -- { -- *(.text .stub .text.* .gnu.linkonce.t.*) -- /* .gnu.warning sections are handled specially by elf32.em. */ -- *(.gnu.warning) -- } =0x90909090 -- .fini : -- { -- KEEP (*(.fini)) -- } =0x90909090 -- PROVIDE (__etext = .); -- PROVIDE (_etext = .); -- PROVIDE (etext = .); -- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -- .rodata1 : { *(.rodata1) } -- .eh_frame_hdr : { *(.eh_frame_hdr) } -- /* 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); -- /* Ensure the __preinit_array_start label is properly aligned. We -- could instead move the label definition inside the section, but -- the linker would then create the section even if it turns out to -- be empty, which isn't pretty. */ -- . = ALIGN(64 / 8); -- PROVIDE (__preinit_array_start = .); -- .preinit_array : { *(.preinit_array) } -- PROVIDE (__preinit_array_end = .); -- PROVIDE (__init_array_start = .); -- .init_array : { *(.init_array) } -- PROVIDE (__init_array_end = .); -- PROVIDE (__fini_array_start = .); -- .fini_array : { *(.fini_array) } -- PROVIDE (__fini_array_end = .); -- .data : -- { -- *(.data .data.* .gnu.linkonce.d.*) -- SORT(CONSTRUCTORS) -- } -- .data1 : { *(.data1) } -- .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -- .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -- .eh_frame : { KEEP (*(.eh_frame)) } -- .gcc_except_table : { *(.gcc_except_table) } -- .dynamic : { *(.dynamic) } -- .ctors : -- { -- /* gcc uses crtbegin.o to find the start of -- the constructors, so we make sure it is -- first. Because this is a wildcard, it -- doesn't matter if the user does not -- actually link against crtbegin.o; the -- linker won't look for a file to match a -- wildcard. The wildcard also means that it -- doesn't matter which directory crtbegin.o -- is in. */ -- KEEP (*crtbegin.o(.ctors)) -- /* We don't want to include the .ctor section from -- from the crtend.o file until after the sorted ctors. -- The .ctor section from the crtend file contains the -- end of ctors marker and it must be last */ -- KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) -- KEEP (*(SORT(.ctors.*))) -- KEEP (*(.ctors)) -- } -- .dtors : -- { -- KEEP (*crtbegin.o(.dtors)) -- KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) -- KEEP (*(SORT(.dtors.*))) -- KEEP (*(.dtors)) -- } -- .jcr : { KEEP (*(.jcr)) } -- .got : { *(.got.plt) *(.got) } -- _edata = .; -- PROVIDE (edata = .); -- __bss_start = .; -- .bss : -- { -- *(.dynbss) -- *(.bss .bss.* .gnu.linkonce.b.*) -- *(COMMON) -- /* Align here to ensure that the .bss section occupies space up to -- _end. Align after .bss to ensure correct alignment even if the -- .bss section disappears because there are no input sections. */ -- . = ALIGN(64 / 8); -- } -- . = ALIGN(64 / 8); -- _end = .; -- PROVIDE (end = .); -- . = DATA_SEGMENT_END (.); -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } -- /* DWARF debug sections. -- Symbols in the DWARF debugging sections are relative to the beginning -- of the section so we begin them at 0. */ -- /* DWARF 1 */ -- .debug 0 : { *(.debug) } -- .line 0 : { *(.line) } -- /* GNU DWARF 1 extensions */ -- .debug_srcinfo 0 : { *(.debug_srcinfo) } -- .debug_sfnames 0 : { *(.debug_sfnames) } -- /* DWARF 1.1 and DWARF 2 */ -- .debug_aranges 0 : { *(.debug_aranges) } -- .debug_pubnames 0 : { *(.debug_pubnames) } -- /* DWARF 2 */ -- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -- .debug_abbrev 0 : { *(.debug_abbrev) } -- .debug_line 0 : { *(.debug_line) } -- .debug_frame 0 : { *(.debug_frame) } -- .debug_str 0 : { *(.debug_str) } -- .debug_loc 0 : { *(.debug_loc) } -- .debug_macinfo 0 : { *(.debug_macinfo) } -- /* SGI/MIPS DWARF 2 extensions */ -- .debug_weaknames 0 : { *(.debug_weaknames) } -- .debug_funcnames 0 : { *(.debug_funcnames) } -- .debug_typenames 0 : { *(.debug_typenames) } -- .debug_varnames 0 : { *(.debug_varnames) } --} diff --git a/emulators/qemu-devel/files/patch-configure-ld-1a1c9ef4d3da2ff1965e8037d7d30b77884c869f b/emulators/qemu-devel/files/patch-configure-ld-1a1c9ef4d3da2ff1965e8037d7d30b77884c869f deleted file mode 100644 index 9aabe0933afe..000000000000 --- a/emulators/qemu-devel/files/patch-configure-ld-1a1c9ef4d3da2ff1965e8037d7d30b77884c869f +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/configure b/configure -index 9d46354..b3025df 100755 ---- a/configure -+++ b/configure -@@ -4438,17 +4438,18 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then - textseg_addr= - case "$ARCH" in - arm | hppa | i386 | ia64 | m68k | ppc | ppc64 | s390 | sparc | sparc64 | x86_64) -- default_textseg_addr=0x400000 - textseg_addr=0x60000000 - ;; - mips) -- default_textseg_addr=0x120000000 - textseg_addr=0x400000 - ;; - esac - if [ -n "$textseg_addr" ]; then -+cat > $TMPC <<EOF -+int main(void) { return 0; } -+EOF - try_ldflags="-Ttext-segment=$textseg_addr" -- if $ld $try_ldflags /dev/null >/dev/null 2>&1; then -+ if compile_prog "" "$try_ldflags"; then - ldflags="$ldflags $try_ldflags" - else - # In case ld does not support -Ttext-segment, edit the default linker -@@ -4457,7 +4458,8 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then - $ld --verbose | sed \ - -e '1,/==================================================/d' \ - -e '/==================================================/,$d' \ -- -e "s/$default_textseg_addr/$textseg_addr/g" > config-host.ld -+ -e "s/[.] = [0-9a-fx]* [+] SIZEOF_HEADERS/. = $textseg_addr + SIZEOF_HEADERS/" \ -+ -e "s/__executable_start = [0-9a-fx]*/__executable_start = $textseg_addr/" > config-host.ld - ldflags="$ldflags -Wl,-T../config-host.ld" - fi - fi diff --git a/emulators/qemu-devel/files/patch-z-arm-bsd-user-001 b/emulators/qemu-devel/files/patch-z-arm-bsd-user-001 deleted file mode 100644 index bf8bdae26823..000000000000 --- a/emulators/qemu-devel/files/patch-z-arm-bsd-user-001 +++ /dev/null @@ -1,380 +0,0 @@ ---- a/bsd-user/elfload.c.orig -+++ b/bsd-user/elfload.c -@@ -190,6 +190,9 @@ static inline void init_thread(struct ta - if (infop->entry & 1) - regs->ARM_cpsr |= CPSR_T; - regs->ARM_pc = infop->entry & 0xfffffffe; -+ if (bsd_type == target_freebsd) { -+ regs->ARM_lr = infop->entry & 0xfffffffe; -+ } - regs->ARM_sp = infop->start_stack; - /* FIXME - what to for failure of get_user()? */ - get_user_ual(regs->ARM_r2, stack + 8); /* envp */ ---- a/bsd-user/main.c.orig -+++ b/bsd-user/main.c -@@ -389,6 +389,259 @@ void cpu_loop(CPUX86State *env) - } - #endif - -+#ifdef TARGET_ARM -+// #define DEBUG_ARM -+ -+void cpu_loop(CPUARMState *env) -+{ -+ int trapnr; -+ unsigned int n, insn; -+ uint32_t addr; -+ -+ for(;;) { -+#ifdef DEBUG_ARM -+ printf("CPU LOOPING\n"); -+#endif -+ cpu_exec_start(env); -+#ifdef DEBUG_ARM -+ printf("EXECUTING...\n"); -+#endif -+ trapnr = cpu_arm_exec(env); -+#ifdef DEBUG_ARM -+ printf("trapnr %d\n", trapnr); -+#endif -+ cpu_exec_end(env); -+ switch(trapnr) { -+ case EXCP_UDEF: -+ { -+#if 0 -+ TaskState *ts = env->opaque; -+ uint32_t opcode; -+ int rc; -+ -+ /* we handle the FPU emulation here, as Linux */ -+ /* we get the opcode */ -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u32(opcode, env->regs[15]); -+ -+ rc = EmulateAll(opcode, &ts->fpa, env); -+ if (rc == 0) { /* illegal instruction */ -+ info.si_signo = SIGILL; -+ info.si_errno = 0; -+ info.si_code = TARGET_ILL_ILLOPN; -+ info._sifields._sigfault._addr = env->regs[15]; -+ queue_signal(env, info.si_signo, &info); -+ -+ } else if (rc < 0) { /* FP exception */ -+ int arm_fpe=0; -+ -+ /* translate softfloat flags to FPSR flags */ -+ if (-rc & float_flag_invalid) -+ arm_fpe |= BIT_IOC; -+ if (-rc & float_flag_divbyzero) -+ arm_fpe |= BIT_DZC; -+ if (-rc & float_flag_overflow) -+ arm_fpe |= BIT_OFC; -+ if (-rc & float_flag_underflow) -+ arm_fpe |= BIT_UFC; -+ if (-rc & float_flag_inexact) -+ arm_fpe |= BIT_IXC; -+ -+ FPSR fpsr = ts->fpa.fpsr; -+ //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe); -+ -+ if (fpsr & (arm_fpe << 16)) { /* exception enabled? */ -+ info.si_signo = SIGFPE; -+ info.si_errno = 0; -+ -+ /* ordered by priority, least first */ -+ if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES; -+ if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND; -+ if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF; -+ if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV; -+ if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV; -+ -+ info._sifields._sigfault._addr = env->regs[15]; -+ queue_signal(env, info.si_signo, &info); -+ } else { -+ env->regs[15] += 4; -+ } -+ -+ /* accumulate unenabled exceptions */ -+ if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC)) -+ fpsr |= BIT_IXC; -+ if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC)) -+ fpsr |= BIT_UFC; -+ if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC)) -+ fpsr |= BIT_OFC; -+ if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC)) -+ fpsr |= BIT_DZC; -+ if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC)) -+ fpsr |= BIT_IOC; -+ ts->fpa.fpsr=fpsr; -+ } else { /* everything OK */ -+ /* increment PC */ -+ env->regs[15] += 4; -+ } -+ } -+#endif -+ break; -+ case EXCP_SWI: -+ case EXCP_BKPT: -+ { -+ env->eabi = 1; -+ /* system call */ -+ if (trapnr == EXCP_BKPT) { -+ if (env->thumb) { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u16(insn, env->regs[15]); -+ n = insn & 0xff; -+ env->regs[15] += 2; -+ } else { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u32(insn, env->regs[15]); -+ n = (insn & 0xf) | ((insn >> 4) & 0xff0); -+ env->regs[15] += 4; -+ } -+ } else { -+ if (env->thumb) { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u16(insn, env->regs[15] - 2); -+ n = insn & 0xff; -+ } else { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u32(insn, env->regs[15] - 4); -+ n = insn & 0xffffff; -+ } -+ } -+ -+#ifdef DEBUG_ARM -+ printf("AVANT CALL %d\n", n); -+#endif -+ if (bsd_type == target_freebsd) { -+ int ret; -+ abi_ulong params = get_sp_from_cpustate(env); -+ int32_t syscall_nr = n; -+ int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; -+ -+#if 0 // XXX FIXME -+ if (syscall_nr == TARGET_FREEBSD_NR_syscall) { -+ get_user_s32(syscall_nr, params); -+ params += sizeof(int32_t); -+ } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) { -+ get_user_s32(syscall_nr, params); -+ params += sizeof(int64_t); -+ } -+#endif -+ arg1 = env->regs[0]; -+ arg2 = env->regs[1]; -+ arg3 = env->regs[2]; -+ arg4 = env->regs[3]; -+ get_user_s32(arg5, params); -+ params += sizeof(int32_t); -+ get_user_s32(arg6, params); -+ params += sizeof(int32_t); -+ get_user_s32(arg7, params); -+ params += sizeof(int32_t); -+ get_user_s32(arg8, params); -+ ret = do_freebsd_syscall(env, -+ syscall_nr, -+ arg1, -+ arg2, -+ arg3, -+ arg4, -+ arg5, -+ arg6, -+ arg7, -+ arg8); -+ if ((unsigned int)ret >= (unsigned int)(-515)) { -+ ret = -ret; -+ cpsr_write(env, CPSR_C, CPSR_C); -+ env->regs[0] = ret; -+ } else { -+ cpsr_write(env, 0, CPSR_C); -+ env->regs[0] = ret; // XXX need to handle lseek()? -+ // env->regs[1] = 0; -+ } -+ } else { -+ // XXX is this correct? -+ env->regs[0] = do_openbsd_syscall(env, -+ n, -+ env->regs[0], -+ env->regs[1], -+ env->regs[2], -+ env->regs[3], -+ env->regs[4], -+ env->regs[5]); -+ } -+#ifdef DEBUG_ARM -+ printf("APRES CALL\n"); -+#endif -+ } -+ } -+ break; -+ case EXCP_INTERRUPT: -+ /* just indicate that signals should be handled asap */ -+ break; -+ case EXCP_PREFETCH_ABORT: -+ addr = env->cp15.c6_insn; -+ goto do_segv; -+ case EXCP_DATA_ABORT: -+ addr = env->cp15.c6_data; -+ do_segv: -+ { -+#if 0 -+# -+ info.si_signo = SIGSEGV; -+ info.si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.si_code = TARGET_SEGV_MAPERR; -+ info._sifields._sigfault._addr = addr; -+ queue_signal(env, info.si_signo, &info); -+#endif -+ } -+ break; -+ case EXCP_DEBUG: -+ { -+ int sig; -+ -+ sig = gdb_handlesig (env, TARGET_SIGTRAP); -+ if (sig) -+ { -+#if 0 -+ info.si_signo = sig; -+ info.si_errno = 0; -+ info.si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.si_signo, &info); -+#endif -+ } -+ } -+ break; -+#if 0 -+ case EXCP_KERNEL_TRAP: -+ if (do_kernel_trap(env)) -+ goto error; -+ break; -+ case EXCP_STREX: -+ if (do_strex(env)) { -+ addr = env->cp15.c6_data; -+ goto do_segv; -+ } -+ break; -+ error: -+#endif -+ default: -+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -+ trapnr); -+ cpu_dump_state(env, stderr, fprintf, 0); -+ abort(); -+ } -+ process_pending_signals(env); -+ } -+} -+ -+#endif -+ - #ifdef TARGET_SPARC - #define SPARC64_STACK_BIAS 2047 - -@@ -1133,6 +1386,14 @@ int main(int argc, char **argv) - for(i = 0; i < 8; i++) - env->regwptr[i] = regs->u_regs[i + 8]; - } -+#elif defined(TARGET_ARM) -+ { -+ int i; -+ cpsr_write(env, regs->uregs[16], 0xffffffff); -+ for (i = 0; i < 16; i++) { -+ env->regs[i] = regs->uregs[i]; -+ } -+ } - #else - #error unsupported target CPU - #endif ---- a/bsd-user/syscall.c.orig -+++ b/bsd-user/syscall.c -@@ -96,6 +96,11 @@ static abi_long do_obreak(abi_ulong new_ - return 0; - } - -+abi_long do_brk(abi_ulong new_brk) -+{ -+ return do_obreak(new_brk); -+} -+ - #if defined(TARGET_I386) - static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms) - { -@@ -157,6 +161,12 @@ static abi_long do_freebsd_sysarch(void - } - #endif - -+#ifdef TARGET_ARM -+static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) -+{ -+ return -TARGET_EINVAL; -+} -+#endif - #ifdef __FreeBSD__ - /* - * XXX this uses the undocumented oidfmt interface to find the kind of -@@ -380,6 +391,9 @@ abi_long do_freebsd_syscall(void *cpu_en - arg5, - arg6)); - break; -+ case TARGET_FREEBSD_NR_munmap: -+ ret = get_errno(target_munmap(arg1, arg2)); -+ break; - case TARGET_FREEBSD_NR_mprotect: - ret = get_errno(target_mprotect(arg1, arg2, arg3)); - break; ---- /dev/null -+++ b/default-configs/arm-bsd-user.mak -@@ -0,0 +1,3 @@ -+# Default configuration for arm-bsd-user -+ -+CONFIG_GDBSTUB_XML=y ---- /dev/null -+++ b/bsd-user/arm/syscall.h -@@ -0,0 +1,23 @@ -+struct target_pt_regs { -+ abi_long uregs[15]; -+}; -+ -+#define ARM_cpsr uregs[16] -+#define ARM_pc uregs[15] -+#define ARM_lr uregs[14] -+#define ARM_sp uregs[13] -+#define ARM_ip uregs[12] -+#define ARM_fp uregs[11] -+#define ARM_r10 uregs[10] -+#define ARM_r9 uregs[9] -+#define ARM_r8 uregs[8] -+#define ARM_r7 uregs[7] -+#define ARM_r6 uregs[6] -+#define ARM_r5 uregs[5] -+#define ARM_r4 uregs[4] -+#define ARM_r3 uregs[3] -+#define ARM_r2 uregs[2] -+#define ARM_r1 uregs[1] -+#define ARM_r0 uregs[0] -+ -+#define ARM_SYSCALL_BASE 0 /* XXX: FreeBSD only */ ---- /dev/null -+++ b/bsd-user/arm/target_signal.h -@@ -0,0 +1,19 @@ -+#ifndef TARGET_SIGNAL_H -+#define TARGET_SIGNAL_H -+ -+#include "cpu.h" -+ -+/* this struct defines a stack used during syscall handling */ -+ -+typedef struct target_sigaltstack { -+ abi_ulong ss_sp; -+ abi_long ss_flags; -+ abi_ulong ss_size; -+} target_stack_t; -+ -+static inline abi_ulong get_sp_from_cpustate(CPUARMState *state) -+{ -+ return state->regs[13]; -+} -+ -+#endif /* TARGET_SIGNAL_H */ diff --git a/emulators/qemu-devel/files/patch-z2-bsd-user-cognet-sson-002 b/emulators/qemu-devel/files/patch-z2-bsd-user-cognet-sson-002 deleted file mode 100644 index b20df377ebde..000000000000 --- a/emulators/qemu-devel/files/patch-z2-bsd-user-cognet-sson-002 +++ /dev/null @@ -1,8355 +0,0 @@ -#diff --git a/Makefile b/Makefile -#index 5fa0f1d..55e151e 100644 -#--- a/Makefile -#+++ b/Makefile -#@@ -65,7 +65,8 @@ CLANG_CFLAGS_AS+= -no-integrated-as -# -# .if ${PORT_OPTIONS:MX86_TARGETS} -# .if ${PORT_OPTIONS:MBSD_USER} -#-CONFIGURE_ARGS+= --target-list=i386-softmmu,x86_64-softmmu,i386-bsd-user,x86_64-bsd-user,sparc-bsd-user,sparc64-bsd-user,arm-bsd-user -#+#CONFIGURE_ARGS+= --target-list=i386-softmmu,x86_64-softmmu,i386-bsd-user,x86_64-bsd-user,sparc-bsd-user,sparc64-bsd-user,arm-bsd-user,armeb-bsd-user,mips-bsd-user,mipsel-bsd-user -#+CONFIGURE_ARGS+= --target-list=arm-bsd-user,armeb-bsd-user,mips-bsd-user,mipsel-bsd-user,mips64-bsd-user -# .else -# CONFIGURE_ARGS+= --target-list=i386-softmmu,x86_64-softmmu -# .endif -#@@ -106,6 +107,8 @@ CONFIGURE_ARGS+= --prefix=${PREFIX} --cc=${CC} --enable-docs \ -# --disable-linux-user --disable-linux-aio \ -# --disable-kvm --disable-xen \ -# --smbd=${LOCALBASE}/sbin/smbd \ -#+ --enable-debug \ -#+ --enable-debug-info \ -# --extra-cflags=-I${WRKSRC}\ -I${LOCALBASE}/include\ -DPREFIX=\\\"${PREFIX}\\\" -# -# .if empty(PORT_OPTIONS:MSDL) -diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h -index 1b644cc..19cc188 100644 ---- a/bsd-user/arm/target_signal.h -+++ b/bsd-user/arm/target_signal.h -@@ -3,17 +3,12 @@ - - #include "cpu.h" - --/* this struct defines a stack used during syscall handling */ -- --typedef struct target_sigaltstack { -- abi_ulong ss_sp; -- abi_long ss_flags; -- abi_ulong ss_size; --} target_stack_t; -- - static inline abi_ulong get_sp_from_cpustate(CPUARMState *state) - { - return state->regs[13]; - } - -+#define TARGET_MINSIGSTKSZ (1024 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h -new file mode 100644 -index 0000000..0427244 ---- /dev/null -+++ b/bsd-user/arm/target_vmparam.h -@@ -0,0 +1,28 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#if defined(__FreeBSD__) -+ /* KERNBASE - 512 MB */ -+#define TARGET_VM_MAXUSER_ADDRESS (0xc0000000 - (512 * 1024 * 1024)) -+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS -+ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#define TARGET_SZSIGCODE 0 -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+#endif -+ -+#endif /* _TARGET_VMPARAM_H_ */ -diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c -index 2abc713..dcf6f66 100644 ---- a/bsd-user/bsdload.c -+++ b/bsd-user/bsdload.c -@@ -53,7 +53,7 @@ static int count(char ** vec) - return(i); - } - --static int prepare_binprm(struct linux_binprm *bprm) -+static int prepare_binprm(struct bsd_binprm *bprm) - { - struct stat st; - int mode; -@@ -155,33 +155,33 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, - } - - int loader_exec(const char * filename, char ** argv, char ** envp, -- struct target_pt_regs * regs, struct image_info *infop) -+ struct target_pt_regs * regs, struct image_info *infop, -+ struct bsd_binprm *bprm) - { -- struct linux_binprm bprm; - int retval; - int i; - -- bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); -+ bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES /*-sizeof(unsigned int) XXX */; - for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ -- bprm.page[i] = NULL; -+ bprm->page[i] = NULL; - retval = open(filename, O_RDONLY); - if (retval < 0) - return retval; -- bprm.fd = retval; -- bprm.filename = (char *)filename; -- bprm.argc = count(argv); -- bprm.argv = argv; -- bprm.envc = count(envp); -- bprm.envp = envp; -+ bprm->fd = retval; -+ bprm->filename = (char *)filename; -+ bprm->argc = count(argv); -+ bprm->argv = argv; -+ bprm->envc = count(envp); -+ bprm->envp = envp; - -- retval = prepare_binprm(&bprm); -+ retval = prepare_binprm(bprm); - - if(retval>=0) { -- if (bprm.buf[0] == 0x7f -- && bprm.buf[1] == 'E' -- && bprm.buf[2] == 'L' -- && bprm.buf[3] == 'F') { -- retval = load_elf_binary(&bprm,regs,infop); -+ if (bprm->buf[0] == 0x7f -+ && bprm->buf[1] == 'E' -+ && bprm->buf[2] == 'L' -+ && bprm->buf[3] == 'F') { -+ retval = load_elf_binary(bprm,regs,infop); - } else { - fprintf(stderr, "Unknown binary format\n"); - return -1; -@@ -196,7 +196,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp, - - /* Something went wrong, return the inode and free the argument pages*/ - for (i=0 ; i<MAX_ARG_PAGES ; i++) { -- g_free(bprm.page[i]); -+ g_free(bprm->page[i]); - } - return(retval); - } -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 993dcf7..15cf3a6 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -9,6 +9,8 @@ - #include <stdlib.h> - #include <string.h> - -+#include <sys/param.h> -+ - #include "qemu.h" - #include "disas.h" - -@@ -93,6 +95,7 @@ enum { - - #ifdef TARGET_I386 - -+#ifndef __FreeBSD__ - #define ELF_PLATFORM get_elf_platform() - - static const char *get_elf_platform(void) -@@ -112,6 +115,7 @@ static uint32_t get_elf_hwcap(void) - { - return thread_env->cpuid_features; - } -+#endif /* ! __FreeBSD__ */ - - #ifdef TARGET_X86_64 - #define ELF_START_MMAP 0x2aaaaab000ULL -@@ -378,13 +382,14 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * - - #ifdef TARGET_MIPS - --#define ELF_START_MMAP 0x80000000 - - #define elf_check_arch(x) ( (x) == EM_MIPS ) - --#ifdef TARGET_MIPS64 -+#if defined(TARGET_MIPS64) -+#define ELF_START_MMAP 0x2aaaaab000ULL - #define ELF_CLASS ELFCLASS64 - #else -+#define ELF_START_MMAP 0x80000000 - #define ELF_CLASS ELFCLASS32 - #endif - #ifdef TARGET_WORDS_BIGENDIAN -@@ -396,9 +401,10 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * - - static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) - { -+ - regs->cp0_status = 2 << CP0St_KSU; -- regs->cp0_epc = infop->entry; -- regs->regs[29] = infop->start_stack; -+ regs->regs[25] = regs->cp0_epc = infop->entry; /* t9 = pc = entry */ -+ regs->regs[4] = regs->regs[29] = infop->start_stack; /* a0 = sp = start_stack */ - } - - #define USE_ELF_CORE_DUMP -@@ -576,30 +582,38 @@ static void bswap_ehdr(struct elfhdr *ehdr) - bswap16s(&ehdr->e_shstrndx); /* Section header string table index */ - } - --static void bswap_phdr(struct elf_phdr *phdr) -+static void bswap_phdr(struct elf_phdr *phdr, int phnum) - { -- bswap32s(&phdr->p_type); /* Segment type */ -- bswaptls(&phdr->p_offset); /* Segment file offset */ -- bswaptls(&phdr->p_vaddr); /* Segment virtual address */ -- bswaptls(&phdr->p_paddr); /* Segment physical address */ -- bswaptls(&phdr->p_filesz); /* Segment size in file */ -- bswaptls(&phdr->p_memsz); /* Segment size in memory */ -- bswap32s(&phdr->p_flags); /* Segment flags */ -- bswaptls(&phdr->p_align); /* Segment alignment */ -+ int i; -+ -+ for (i = 0; i < phnum; ++i, ++phdr) { -+ bswap32s(&phdr->p_type); /* Segment type */ -+ bswap32s(&phdr->p_flags); /* Segment flags */ -+ bswaptls(&phdr->p_offset); /* Segment file offset */ -+ bswaptls(&phdr->p_vaddr); /* Segment virtual address */ -+ bswaptls(&phdr->p_paddr); /* Segment physical address */ -+ bswaptls(&phdr->p_filesz); /* Segment size in file */ -+ bswaptls(&phdr->p_memsz); /* Segment size in memory */ -+ bswaptls(&phdr->p_align); /* Segment alignment */ -+ } - } - --static void bswap_shdr(struct elf_shdr *shdr) -+static void bswap_shdr(struct elf_shdr *shdr, int shnum) - { -- bswap32s(&shdr->sh_name); -- bswap32s(&shdr->sh_type); -- bswaptls(&shdr->sh_flags); -- bswaptls(&shdr->sh_addr); -- bswaptls(&shdr->sh_offset); -- bswaptls(&shdr->sh_size); -- bswap32s(&shdr->sh_link); -- bswap32s(&shdr->sh_info); -- bswaptls(&shdr->sh_addralign); -- bswaptls(&shdr->sh_entsize); -+ int i; -+ -+ for (i = 0; i < shnum; ++i, ++shdr) { -+ bswap32s(&shdr->sh_name); -+ bswap32s(&shdr->sh_type); -+ bswaptls(&shdr->sh_flags); -+ bswaptls(&shdr->sh_addr); -+ bswaptls(&shdr->sh_offset); -+ bswaptls(&shdr->sh_size); -+ bswap32s(&shdr->sh_link); -+ bswap32s(&shdr->sh_info); -+ bswaptls(&shdr->sh_addralign); -+ bswaptls(&shdr->sh_entsize); -+ } - } - - static void bswap_sym(struct elf_sym *sym) -@@ -609,7 +623,14 @@ static void bswap_sym(struct elf_sym *sym) - bswaptls(&sym->st_size); - bswap16s(&sym->st_shndx); - } --#endif -+ -+#else /* ! BSWAP_NEEDED */ -+ -+static inline void bswap_ehdr(struct elfhdr *ehdr) { } -+static inline void bswap_phdr(struct elf_phdr *phdr, int phnum) { } -+static inline void bswap_shdr(struct elf_shdr *shdr, int shnum) { } -+static inline void bswap_sym(struct elf_sym *sym) { } -+#endif /* ! BSWAP_NEEDED */ - - /* - * 'copy_elf_strings()' copies argument/envelope strings from user -@@ -666,7 +687,26 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, - return p; - } - --static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, -+#if defined(TARGET_MIPS64) -+static inline int -+install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned syscall) -+{ -+ int i; -+ uint32_t sigtramp_code[] = { -+ 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -+ 0x24020000 + syscall, /* li $v0, (syscall) */ -+ 0x0000000C, /* syscall */ -+ 0x0000000D /* break */ -+ }; -+ -+ for(i = 0; i < 4; i++) -+ tswap32s(&sigtramp_code[i]); -+ -+ return (memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE)); -+} -+#endif -+ -+static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - struct image_info *info) - { - abi_ulong stack_base, size, error; -@@ -678,7 +718,13 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, - size = x86_stack_size; - if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) - size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; -- error = target_mmap(0, -+ -+#ifdef TARGET_USRSTACK -+ stack_base = TARGET_USRSTACK - size; -+#else -+ stack_base = (abi_ulong)0; -+#endif -+ error = target_mmap(stack_base, - size + qemu_host_page_size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -@@ -690,6 +736,113 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, - /* we reserve one extra page at the top of the stack as guard */ - target_mprotect(error + size, qemu_host_page_size, PROT_NONE); - -+#if defined(__FreeBSD__) -+ /* -+ * The inital FreeBSD stack looks like follows: -+ * (see kern/kern_exec.c exec_copyout_strings() ) -+ * -+ * Hi Address -> char **ps_argvstr (struct ps_strings for ps, w, etc.) -+ * unsigned ps_nargvstr -+ * char **ps_envstr -+ * PS_STRINGS -> unsigned ps_nenvstr -+ * -+ * machine dependent sigcode (sv_sigcode of size -+ * sv_szsigcode) -+ * -+ * execpath (absolute image path for rtld) -+ * -+ * SSP Canary (sizeof(long) * 8) -+ * -+ * page sizes array (usually sizeof(u_long) ) -+ * -+ * "destp" -> argv, env strings (up to 262144 bytes) -+ */ -+ -+ { -+ abi_ulong stack_hi_addr; -+ size_t execpath_len; -+ abi_ulong destp; -+ struct target_ps_strings ps_strs; -+ char canary[sizeof(abi_long) * 8]; -+ char execpath[PATH_MAX]; -+ -+ stack_hi_addr = p = error + size; -+ -+ /* Save some space for ps_strings. */ -+ p -= sizeof(struct target_ps_strings); -+ -+#if TARGET_SZSIGCODE > 0 -+ /* Add machine depedent sigcode. */ -+ p -= TARGET_SZSIGCODE; -+ /* XXX - check return value of memcpy_to_target() for failure */ -+ install_sigtramp( p, (unsigned)offsetof(struct target_sigframe, -+ sf_uc), TARGET_FREEBSD_NR_sigreturn); -+#endif -+ -+ /* Add execpath for rtld. */ -+ if (strlen(bprm->filename)) { -+ /* XXX - check return value of realpath() */ -+ realpath(bprm->filename, execpath); -+ execpath_len = strlen(execpath) + 1; -+ } else -+ execpath_len = 0; -+ -+ if (execpath_len) { -+ p -= roundup(execpath_len, sizeof(abi_ulong)); -+ /* XXX - check return value of memcpy_to_target() */ -+ memcpy_to_target(p, execpath, execpath_len); -+ } -+ -+ /* Add canary for SSP. */ -+ arc4random_buf(canary, sizeof(canary)); -+ p -= roundup(sizeof(canary), sizeof(abi_ulong)); -+ /* XXX - check return value of memcpy_to_target(). */ -+ memcpy_to_target(p, canary, sizeof(canary)); -+ -+ /* Add page sizes array. */ -+ p -= sizeof(abi_ulong); -+ /* XXX - check return value of put_user_ual(). */ -+ put_user_ual(TARGET_PAGE_SIZE, p); -+ -+ p = destp = p - TARGET_SPACE_USRSPACE - TARGET_ARG_MAX; -+ -+ /* XXX should check strlen(argv and envp strings) < TARGET_ARG_MAX */ -+ -+ /* -+ * Add argv strings. Note that the argv[] vectors are added by -+ * loader_build_argptr() -+ */ -+ i = bprm->argc; -+ while (i-- > 0) { -+ size_t len = strlen(bprm->argv[i]) + 1; -+ /* XXX - check return value of memcpy_to_target(). */ -+ memcpy_to_target(destp, bprm->argv[i], len); -+ destp += len; -+ } -+ ps_strs.ps_argvstr = tswapl(destp); -+ ps_strs.ps_nargvstr = tswap32(bprm->argc); -+ -+ /* -+ * Add env strings. Note that the envp[] vectors are added by -+ * loader_build_argptr(). -+ */ -+ i = bprm->envc; -+ while(i-- > 0) { -+ size_t len = strlen(bprm->envp[i]) + 1; -+ /* XXX - check return value of memcpy_to_target(). */ -+ memcpy_to_target(destp, bprm->envp[i], len); -+ destp += len; -+ } -+ ps_strs.ps_envstr = tswapl(destp); -+ ps_strs.ps_nenvstr = tswap32(bprm->envc); -+ -+ /* XXX - check return value of memcpy_to_target(). */ -+ memcpy_to_target(stack_hi_addr - sizeof(ps_strs), &ps_strs, -+ sizeof(ps_strs)); -+ } -+ -+#else -+ - stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE; - p += stack_base; - -@@ -702,6 +855,8 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, - } - stack_base += TARGET_PAGE_SIZE; - } -+#endif -+ - return p; - } - -@@ -769,11 +924,14 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, - { - abi_ulong sp; - int size; -+#ifndef __FreeBSD__ - abi_ulong u_platform; - const char *k_platform; -+#endif - const int n = sizeof(elf_addr_t); - - sp = p; -+#ifndef __FreeBSD__ - u_platform = 0; - k_platform = ELF_PLATFORM; - if (k_platform) { -@@ -783,22 +941,28 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, - /* FIXME - check return value of memcpy_to_target() for failure */ - memcpy_to_target(sp, k_platform, len); - } -+#endif /* ! __FreeBSD__ */ - /* - * Force 16 byte _final_ alignment here for generality. - */ - sp = sp &~ (abi_ulong)15; -+#ifdef __FreeBSD__ -+ size = 0; -+#else - size = (DLINFO_ITEMS + 1) * 2; - if (k_platform) - size += 2; - #ifdef DLINFO_ARCH_ITEMS - size += DLINFO_ARCH_ITEMS * 2; - #endif -+#endif /* ! __FreeBSD__ */ - size += envc + argc + 2; - size += (!ibcs ? 3 : 1); /* argc itself */ - size *= n; - if (size & 15) - sp -= 16 - (size & 15); - -+#ifndef __FreeBSD__ - /* This is correct because Linux defines - * elf_addr_t as Elf32_Off / Elf64_Off - */ -@@ -833,6 +997,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, - ARCH_DLINFO; - #endif - #undef NEW_AUX_ENT -+#endif /* ! __FreeBSD__ */ - - sp = loader_build_argptr(envc, argc, sp, p, !ibcs); - return sp; -@@ -856,9 +1021,7 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - last_bss = 0; - error = 0; - --#ifdef BSWAP_NEEDED - bswap_ehdr(interp_elf_ex); --#endif - /* First of all, some simple consistency checks */ - if ((interp_elf_ex->e_type != ET_EXEC && - interp_elf_ex->e_type != ET_DYN) || -@@ -899,12 +1062,7 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - free (elf_phdata); - return retval; - } --#ifdef BSWAP_NEEDED -- eppnt = elf_phdata; -- for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { -- bswap_phdr(eppnt); -- } --#endif -+ bswap_phdr(elf_phdata, interp_elf_ex->e_phnum); - - if (interp_elf_ex->e_type == ET_DYN) { - /* in order to avoid hardcoding the interpreter load -@@ -1049,9 +1207,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - for (i = 0; i < hdr->e_shnum; i++) { - if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr)) - return; --#ifdef BSWAP_NEEDED -- bswap_shdr(&sechdr); --#endif -+ bswap_shdr(&sechdr, 1); - if (sechdr.sh_type == SHT_SYMTAB) { - symtab = sechdr; - lseek(fd, hdr->e_shoff -@@ -1059,9 +1215,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - if (read(fd, &strtab, sizeof(strtab)) - != sizeof(strtab)) - return; --#ifdef BSWAP_NEEDED -- bswap_shdr(&strtab); --#endif -+ bswap_shdr(&strtab, 1); - goto found; - } - } -@@ -1094,9 +1248,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - - i = 0; - while (i < nsyms) { --#ifdef BSWAP_NEEDED - bswap_sym(syms + i); --#endif - // Throw away entries which we do not need. - if (syms[i].st_shndx == SHN_UNDEF || - syms[i].st_shndx >= SHN_LORESERVE || -@@ -1148,7 +1300,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - syminfos = s; - } - --int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, -+int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info) - { - struct elfhdr elf_ex; -@@ -1178,9 +1330,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - load_addr = 0; - load_bias = 0; - elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ --#ifdef BSWAP_NEEDED - bswap_ehdr(&elf_ex); --#endif - - /* First of all, some simple consistency checks */ - if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || -@@ -1188,12 +1338,14 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - return -ENOEXEC; - } - -+#ifndef __FreeBSD__ - bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p); - bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p); - bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p); - if (!bprm->p) { - retval = -E2BIG; - } -+#endif /* ! __FreeBSD__ */ - - /* Now read in all of the header information */ - elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum); -@@ -1214,12 +1366,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - return -errno; - } - --#ifdef BSWAP_NEEDED -- elf_ppnt = elf_phdata; -- for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) { -- bswap_phdr(elf_ppnt); -- } --#endif -+ bswap_phdr(elf_phdata, elf_ex.e_phnum); - elf_ppnt = elf_phdata; - - elf_bss = 0; -@@ -1229,9 +1376,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - elf_stack = ~((abi_ulong)0UL); - elf_interpreter = NULL; - start_code = ~((abi_ulong)0UL); -- end_code = 0; -- start_data = 0; -- end_data = 0; -+ end_code = (abi_ulong)0UL; -+ start_data = (abi_ulong)0UL; -+ end_data = (abi_ulong)0UL; - interp_ex.a_info = 0; - - for(i=0;i < elf_ex.e_phnum; i++) { -@@ -1431,7 +1578,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - perror("mmap"); - exit(-1); - } -- load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr); -+ load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr); - } - - error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr), -@@ -1541,12 +1688,13 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - padzero(elf_bss, elf_brk); - - #if 0 -- printf("(start_brk) %x\n" , info->start_brk); -- printf("(end_code) %x\n" , info->end_code); -- printf("(start_code) %x\n" , info->start_code); -- printf("(end_data) %x\n" , info->end_data); -- printf("(start_stack) %x\n" , info->start_stack); -- printf("(brk) %x\n" , info->brk); -+ printf("(start_brk) 0x" TARGET_FMT_lx "\n" , info->start_brk); -+ printf("(end_code) 0x" TARGET_FMT_lx "\n" , info->end_code); -+ printf("(start_code) 0x" TARGET_FMT_lx "\n" , info->start_code); -+ printf("(start_data) 0x" TARGET_FMT_lx "\n" , info->start_data); -+ printf("(end_data) 0x" TARGET_FMT_lx "\n" , info->end_data); -+ printf("(start_stack) 0x" TARGET_FMT_lx "\n" , info->start_stack); -+ printf("(brk) 0x" TARGET_FMT_lx "\n" , info->brk); - #endif - - if ( info->personality == PER_SVR4 ) -@@ -1561,6 +1709,11 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - - info->entry = elf_entry; - -+#ifdef USE_ELF_CORE_DUMP -+ /* bprm->core_dump = &elf_core_dump; */ -+ bprm->core_dump = NULL; -+#endif -+ - return 0; - } - -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 36336ab..e46571f 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -1,373 +1,448 @@ - /* - * System call numbers. - * -- * $FreeBSD: src/sys/sys/syscall.h,v 1.224 2008/08/24 21:23:08 rwatson Exp $ -- * created from FreeBSD: head/sys/kern/syscalls.master 182123 2008-08-24 21:20:35Z rwatson -+ * created from FreeBSD: releng/9.1/sys/kern/syscalls.master 229723 2012-01-06 19:29:16Z jhb - */ - --#define TARGET_FREEBSD_NR_syscall 0 --#define TARGET_FREEBSD_NR_exit 1 --#define TARGET_FREEBSD_NR_fork 2 --#define TARGET_FREEBSD_NR_read 3 --#define TARGET_FREEBSD_NR_write 4 --#define TARGET_FREEBSD_NR_open 5 --#define TARGET_FREEBSD_NR_close 6 --#define TARGET_FREEBSD_NR_wait4 7 --#define TARGET_FREEBSD_NR_link 9 --#define TARGET_FREEBSD_NR_unlink 10 --#define TARGET_FREEBSD_NR_chdir 12 --#define TARGET_FREEBSD_NR_fchdir 13 --#define TARGET_FREEBSD_NR_mknod 14 --#define TARGET_FREEBSD_NR_chmod 15 --#define TARGET_FREEBSD_NR_chown 16 --#define TARGET_FREEBSD_NR_break 17 --#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18 --#define TARGET_FREEBSD_NR_getpid 20 --#define TARGET_FREEBSD_NR_mount 21 --#define TARGET_FREEBSD_NR_unmount 22 --#define TARGET_FREEBSD_NR_setuid 23 --#define TARGET_FREEBSD_NR_getuid 24 --#define TARGET_FREEBSD_NR_geteuid 25 --#define TARGET_FREEBSD_NR_ptrace 26 --#define TARGET_FREEBSD_NR_recvmsg 27 --#define TARGET_FREEBSD_NR_sendmsg 28 --#define TARGET_FREEBSD_NR_recvfrom 29 --#define TARGET_FREEBSD_NR_accept 30 --#define TARGET_FREEBSD_NR_getpeername 31 --#define TARGET_FREEBSD_NR_getsockname 32 --#define TARGET_FREEBSD_NR_access 33 --#define TARGET_FREEBSD_NR_chflags 34 --#define TARGET_FREEBSD_NR_fchflags 35 --#define TARGET_FREEBSD_NR_sync 36 --#define TARGET_FREEBSD_NR_kill 37 --#define TARGET_FREEBSD_NR_getppid 39 --#define TARGET_FREEBSD_NR_dup 41 --#define TARGET_FREEBSD_NR_pipe 42 --#define TARGET_FREEBSD_NR_getegid 43 --#define TARGET_FREEBSD_NR_profil 44 --#define TARGET_FREEBSD_NR_ktrace 45 --#define TARGET_FREEBSD_NR_getgid 47 --#define TARGET_FREEBSD_NR_getlogin 49 --#define TARGET_FREEBSD_NR_setlogin 50 --#define TARGET_FREEBSD_NR_acct 51 --#define TARGET_FREEBSD_NR_sigaltstack 53 --#define TARGET_FREEBSD_NR_ioctl 54 --#define TARGET_FREEBSD_NR_reboot 55 --#define TARGET_FREEBSD_NR_revoke 56 --#define TARGET_FREEBSD_NR_symlink 57 --#define TARGET_FREEBSD_NR_readlink 58 --#define TARGET_FREEBSD_NR_execve 59 --#define TARGET_FREEBSD_NR_umask 60 --#define TARGET_FREEBSD_NR_chroot 61 --#define TARGET_FREEBSD_NR_msync 65 --#define TARGET_FREEBSD_NR_vfork 66 --#define TARGET_FREEBSD_NR_sbrk 69 --#define TARGET_FREEBSD_NR_sstk 70 --#define TARGET_FREEBSD_NR_vadvise 72 --#define TARGET_FREEBSD_NR_munmap 73 --#define TARGET_FREEBSD_NR_mprotect 74 --#define TARGET_FREEBSD_NR_madvise 75 --#define TARGET_FREEBSD_NR_mincore 78 --#define TARGET_FREEBSD_NR_getgroups 79 --#define TARGET_FREEBSD_NR_setgroups 80 --#define TARGET_FREEBSD_NR_getpgrp 81 --#define TARGET_FREEBSD_NR_setpgid 82 --#define TARGET_FREEBSD_NR_setitimer 83 --#define TARGET_FREEBSD_NR_swapon 85 --#define TARGET_FREEBSD_NR_getitimer 86 --#define TARGET_FREEBSD_NR_getdtablesize 89 --#define TARGET_FREEBSD_NR_dup2 90 --#define TARGET_FREEBSD_NR_fcntl 92 --#define TARGET_FREEBSD_NR_select 93 --#define TARGET_FREEBSD_NR_fsync 95 --#define TARGET_FREEBSD_NR_setpriority 96 --#define TARGET_FREEBSD_NR_socket 97 --#define TARGET_FREEBSD_NR_connect 98 --#define TARGET_FREEBSD_NR_getpriority 100 --#define TARGET_FREEBSD_NR_bind 104 --#define TARGET_FREEBSD_NR_setsockopt 105 --#define TARGET_FREEBSD_NR_listen 106 --#define TARGET_FREEBSD_NR_gettimeofday 116 --#define TARGET_FREEBSD_NR_getrusage 117 --#define TARGET_FREEBSD_NR_getsockopt 118 --#define TARGET_FREEBSD_NR_readv 120 --#define TARGET_FREEBSD_NR_writev 121 --#define TARGET_FREEBSD_NR_settimeofday 122 --#define TARGET_FREEBSD_NR_fchown 123 --#define TARGET_FREEBSD_NR_fchmod 124 --#define TARGET_FREEBSD_NR_setreuid 126 --#define TARGET_FREEBSD_NR_setregid 127 --#define TARGET_FREEBSD_NR_rename 128 --#define TARGET_FREEBSD_NR_flock 131 --#define TARGET_FREEBSD_NR_mkfifo 132 --#define TARGET_FREEBSD_NR_sendto 133 --#define TARGET_FREEBSD_NR_shutdown 134 --#define TARGET_FREEBSD_NR_socketpair 135 --#define TARGET_FREEBSD_NR_mkdir 136 --#define TARGET_FREEBSD_NR_rmdir 137 --#define TARGET_FREEBSD_NR_utimes 138 --#define TARGET_FREEBSD_NR_adjtime 140 --#define TARGET_FREEBSD_NR_setsid 147 --#define TARGET_FREEBSD_NR_quotactl 148 --#define TARGET_FREEBSD_NR_nlm_syscall 154 --#define TARGET_FREEBSD_NR_nfssvc 155 --#define TARGET_FREEBSD_NR_freebsd4_statfs 157 --#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158 --#define TARGET_FREEBSD_NR_lgetfh 160 --#define TARGET_FREEBSD_NR_getfh 161 --#define TARGET_FREEBSD_NR_getdomainname 162 --#define TARGET_FREEBSD_NR_setdomainname 163 --#define TARGET_FREEBSD_NR_uname 164 --#define TARGET_FREEBSD_NR_sysarch 165 --#define TARGET_FREEBSD_NR_rtprio 166 --#define TARGET_FREEBSD_NR_semsys 169 --#define TARGET_FREEBSD_NR_msgsys 170 --#define TARGET_FREEBSD_NR_shmsys 171 --#define TARGET_FREEBSD_NR_freebsd6_pread 173 --#define TARGET_FREEBSD_NR_freebsd6_pwrite 174 --#define TARGET_FREEBSD_NR_setfib 175 --#define TARGET_FREEBSD_NR_ntp_adjtime 176 --#define TARGET_FREEBSD_NR_setgid 181 --#define TARGET_FREEBSD_NR_setegid 182 --#define TARGET_FREEBSD_NR_seteuid 183 --#define TARGET_FREEBSD_NR_stat 188 --#define TARGET_FREEBSD_NR_fstat 189 --#define TARGET_FREEBSD_NR_lstat 190 --#define TARGET_FREEBSD_NR_pathconf 191 --#define TARGET_FREEBSD_NR_fpathconf 192 --#define TARGET_FREEBSD_NR_getrlimit 194 --#define TARGET_FREEBSD_NR_setrlimit 195 --#define TARGET_FREEBSD_NR_getdirentries 196 --#define TARGET_FREEBSD_NR_freebsd6_mmap 197 --#define TARGET_FREEBSD_NR___syscall 198 --#define TARGET_FREEBSD_NR_freebsd6_lseek 199 --#define TARGET_FREEBSD_NR_freebsd6_truncate 200 --#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201 --#define TARGET_FREEBSD_NR___sysctl 202 --#define TARGET_FREEBSD_NR_mlock 203 --#define TARGET_FREEBSD_NR_munlock 204 --#define TARGET_FREEBSD_NR_undelete 205 --#define TARGET_FREEBSD_NR_futimes 206 --#define TARGET_FREEBSD_NR_getpgid 207 --#define TARGET_FREEBSD_NR_poll 209 --#define TARGET_FREEBSD_NR___semctl 220 --#define TARGET_FREEBSD_NR_semget 221 --#define TARGET_FREEBSD_NR_semop 222 --#define TARGET_FREEBSD_NR_msgctl 224 --#define TARGET_FREEBSD_NR_msgget 225 --#define TARGET_FREEBSD_NR_msgsnd 226 --#define TARGET_FREEBSD_NR_msgrcv 227 --#define TARGET_FREEBSD_NR_shmat 228 --#define TARGET_FREEBSD_NR_shmctl 229 --#define TARGET_FREEBSD_NR_shmdt 230 --#define TARGET_FREEBSD_NR_shmget 231 --#define TARGET_FREEBSD_NR_clock_gettime 232 --#define TARGET_FREEBSD_NR_clock_settime 233 --#define TARGET_FREEBSD_NR_clock_getres 234 --#define TARGET_FREEBSD_NR_ktimer_create 235 --#define TARGET_FREEBSD_NR_ktimer_delete 236 --#define TARGET_FREEBSD_NR_ktimer_settime 237 --#define TARGET_FREEBSD_NR_ktimer_gettime 238 --#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 --#define TARGET_FREEBSD_NR_nanosleep 240 --#define TARGET_FREEBSD_NR_ntp_gettime 248 --#define TARGET_FREEBSD_NR_minherit 250 --#define TARGET_FREEBSD_NR_rfork 251 --#define TARGET_FREEBSD_NR_openbsd_poll 252 --#define TARGET_FREEBSD_NR_issetugid 253 --#define TARGET_FREEBSD_NR_lchown 254 --#define TARGET_FREEBSD_NR_aio_read 255 --#define TARGET_FREEBSD_NR_aio_write 256 --#define TARGET_FREEBSD_NR_lio_listio 257 --#define TARGET_FREEBSD_NR_getdents 272 --#define TARGET_FREEBSD_NR_lchmod 274 --#define TARGET_FREEBSD_NR_netbsd_lchown 275 --#define TARGET_FREEBSD_NR_lutimes 276 --#define TARGET_FREEBSD_NR_netbsd_msync 277 --#define TARGET_FREEBSD_NR_nstat 278 --#define TARGET_FREEBSD_NR_nfstat 279 --#define TARGET_FREEBSD_NR_nlstat 280 --#define TARGET_FREEBSD_NR_preadv 289 --#define TARGET_FREEBSD_NR_pwritev 290 --#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 --#define TARGET_FREEBSD_NR_fhopen 298 --#define TARGET_FREEBSD_NR_fhstat 299 --#define TARGET_FREEBSD_NR_modnext 300 --#define TARGET_FREEBSD_NR_modstat 301 --#define TARGET_FREEBSD_NR_modfnext 302 --#define TARGET_FREEBSD_NR_modfind 303 --#define TARGET_FREEBSD_NR_kldload 304 --#define TARGET_FREEBSD_NR_kldunload 305 --#define TARGET_FREEBSD_NR_kldfind 306 --#define TARGET_FREEBSD_NR_kldnext 307 --#define TARGET_FREEBSD_NR_kldstat 308 --#define TARGET_FREEBSD_NR_kldfirstmod 309 --#define TARGET_FREEBSD_NR_getsid 310 --#define TARGET_FREEBSD_NR_setresuid 311 --#define TARGET_FREEBSD_NR_setresgid 312 --#define TARGET_FREEBSD_NR_aio_return 314 --#define TARGET_FREEBSD_NR_aio_suspend 315 --#define TARGET_FREEBSD_NR_aio_cancel 316 --#define TARGET_FREEBSD_NR_aio_error 317 --#define TARGET_FREEBSD_NR_oaio_read 318 --#define TARGET_FREEBSD_NR_oaio_write 319 --#define TARGET_FREEBSD_NR_olio_listio 320 --#define TARGET_FREEBSD_NR_yield 321 --#define TARGET_FREEBSD_NR_mlockall 324 --#define TARGET_FREEBSD_NR_munlockall 325 --#define TARGET_FREEBSD_NR___getcwd 326 --#define TARGET_FREEBSD_NR_sched_setparam 327 --#define TARGET_FREEBSD_NR_sched_getparam 328 --#define TARGET_FREEBSD_NR_sched_setscheduler 329 --#define TARGET_FREEBSD_NR_sched_getscheduler 330 --#define TARGET_FREEBSD_NR_sched_yield 331 --#define TARGET_FREEBSD_NR_sched_get_priority_max 332 --#define TARGET_FREEBSD_NR_sched_get_priority_min 333 --#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 --#define TARGET_FREEBSD_NR_utrace 335 --#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 --#define TARGET_FREEBSD_NR_kldsym 337 --#define TARGET_FREEBSD_NR_jail 338 --#define TARGET_FREEBSD_NR_sigprocmask 340 --#define TARGET_FREEBSD_NR_sigsuspend 341 --#define TARGET_FREEBSD_NR_freebsd4_sigaction 342 --#define TARGET_FREEBSD_NR_sigpending 343 --#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344 --#define TARGET_FREEBSD_NR_sigtimedwait 345 --#define TARGET_FREEBSD_NR_sigwaitinfo 346 --#define TARGET_FREEBSD_NR___acl_get_file 347 --#define TARGET_FREEBSD_NR___acl_set_file 348 --#define TARGET_FREEBSD_NR___acl_get_fd 349 --#define TARGET_FREEBSD_NR___acl_set_fd 350 --#define TARGET_FREEBSD_NR___acl_delete_file 351 --#define TARGET_FREEBSD_NR___acl_delete_fd 352 --#define TARGET_FREEBSD_NR___acl_aclcheck_file 353 --#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 --#define TARGET_FREEBSD_NR_extattrctl 355 --#define TARGET_FREEBSD_NR_extattr_set_file 356 --#define TARGET_FREEBSD_NR_extattr_get_file 357 --#define TARGET_FREEBSD_NR_extattr_delete_file 358 --#define TARGET_FREEBSD_NR_aio_waitcomplete 359 --#define TARGET_FREEBSD_NR_getresuid 360 --#define TARGET_FREEBSD_NR_getresgid 361 --#define TARGET_FREEBSD_NR_kqueue 362 --#define TARGET_FREEBSD_NR_kevent 363 --#define TARGET_FREEBSD_NR_extattr_set_fd 371 --#define TARGET_FREEBSD_NR_extattr_get_fd 372 --#define TARGET_FREEBSD_NR_extattr_delete_fd 373 --#define TARGET_FREEBSD_NR___setugid 374 --#define TARGET_FREEBSD_NR_nfsclnt 375 --#define TARGET_FREEBSD_NR_eaccess 376 --#define TARGET_FREEBSD_NR_nmount 378 --#define TARGET_FREEBSD_NR___mac_get_proc 384 --#define TARGET_FREEBSD_NR___mac_set_proc 385 --#define TARGET_FREEBSD_NR___mac_get_fd 386 --#define TARGET_FREEBSD_NR___mac_get_file 387 --#define TARGET_FREEBSD_NR___mac_set_fd 388 --#define TARGET_FREEBSD_NR___mac_set_file 389 --#define TARGET_FREEBSD_NR_kenv 390 --#define TARGET_FREEBSD_NR_lchflags 391 --#define TARGET_FREEBSD_NR_uuidgen 392 --#define TARGET_FREEBSD_NR_sendfile 393 --#define TARGET_FREEBSD_NR_mac_syscall 394 --#define TARGET_FREEBSD_NR_getfsstat 395 --#define TARGET_FREEBSD_NR_statfs 396 --#define TARGET_FREEBSD_NR_fstatfs 397 --#define TARGET_FREEBSD_NR_fhstatfs 398 --#define TARGET_FREEBSD_NR_ksem_close 400 --#define TARGET_FREEBSD_NR_ksem_post 401 --#define TARGET_FREEBSD_NR_ksem_wait 402 --#define TARGET_FREEBSD_NR_ksem_trywait 403 --#define TARGET_FREEBSD_NR_ksem_init 404 --#define TARGET_FREEBSD_NR_ksem_open 405 --#define TARGET_FREEBSD_NR_ksem_unlink 406 --#define TARGET_FREEBSD_NR_ksem_getvalue 407 --#define TARGET_FREEBSD_NR_ksem_destroy 408 --#define TARGET_FREEBSD_NR___mac_get_pid 409 --#define TARGET_FREEBSD_NR___mac_get_link 410 --#define TARGET_FREEBSD_NR___mac_set_link 411 --#define TARGET_FREEBSD_NR_extattr_set_link 412 --#define TARGET_FREEBSD_NR_extattr_get_link 413 --#define TARGET_FREEBSD_NR_extattr_delete_link 414 --#define TARGET_FREEBSD_NR___mac_execve 415 --#define TARGET_FREEBSD_NR_sigaction 416 --#define TARGET_FREEBSD_NR_sigreturn 417 --#define TARGET_FREEBSD_NR_getcontext 421 --#define TARGET_FREEBSD_NR_setcontext 422 --#define TARGET_FREEBSD_NR_swapcontext 423 --#define TARGET_FREEBSD_NR_swapoff 424 --#define TARGET_FREEBSD_NR___acl_get_link 425 --#define TARGET_FREEBSD_NR___acl_set_link 426 --#define TARGET_FREEBSD_NR___acl_delete_link 427 --#define TARGET_FREEBSD_NR___acl_aclcheck_link 428 --#define TARGET_FREEBSD_NR_sigwait 429 --#define TARGET_FREEBSD_NR_thr_create 430 --#define TARGET_FREEBSD_NR_thr_exit 431 --#define TARGET_FREEBSD_NR_thr_self 432 --#define TARGET_FREEBSD_NR_thr_kill 433 --#define TARGET_FREEBSD_NR__umtx_lock 434 --#define TARGET_FREEBSD_NR__umtx_unlock 435 --#define TARGET_FREEBSD_NR_jail_attach 436 --#define TARGET_FREEBSD_NR_extattr_list_fd 437 --#define TARGET_FREEBSD_NR_extattr_list_file 438 --#define TARGET_FREEBSD_NR_extattr_list_link 439 --#define TARGET_FREEBSD_NR_ksem_timedwait 441 --#define TARGET_FREEBSD_NR_thr_suspend 442 --#define TARGET_FREEBSD_NR_thr_wake 443 --#define TARGET_FREEBSD_NR_kldunloadf 444 --#define TARGET_FREEBSD_NR_audit 445 --#define TARGET_FREEBSD_NR_auditon 446 --#define TARGET_FREEBSD_NR_getauid 447 --#define TARGET_FREEBSD_NR_setauid 448 --#define TARGET_FREEBSD_NR_getaudit 449 --#define TARGET_FREEBSD_NR_setaudit 450 --#define TARGET_FREEBSD_NR_getaudit_addr 451 --#define TARGET_FREEBSD_NR_setaudit_addr 452 --#define TARGET_FREEBSD_NR_auditctl 453 --#define TARGET_FREEBSD_NR__umtx_op 454 --#define TARGET_FREEBSD_NR_thr_new 455 --#define TARGET_FREEBSD_NR_sigqueue 456 --#define TARGET_FREEBSD_NR_kmq_open 457 --#define TARGET_FREEBSD_NR_kmq_setattr 458 --#define TARGET_FREEBSD_NR_kmq_timedreceive 459 --#define TARGET_FREEBSD_NR_kmq_timedsend 460 --#define TARGET_FREEBSD_NR_kmq_notify 461 --#define TARGET_FREEBSD_NR_kmq_unlink 462 --#define TARGET_FREEBSD_NR_abort2 463 --#define TARGET_FREEBSD_NR_thr_set_name 464 --#define TARGET_FREEBSD_NR_aio_fsync 465 --#define TARGET_FREEBSD_NR_rtprio_thread 466 --#define TARGET_FREEBSD_NR_sctp_peeloff 471 --#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472 --#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473 --#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474 --#define TARGET_FREEBSD_NR_pread 475 --#define TARGET_FREEBSD_NR_pwrite 476 --#define TARGET_FREEBSD_NR_mmap 477 --#define TARGET_FREEBSD_NR_lseek 478 --#define TARGET_FREEBSD_NR_truncate 479 --#define TARGET_FREEBSD_NR_ftruncate 480 --#define TARGET_FREEBSD_NR_thr_kill2 481 --#define TARGET_FREEBSD_NR_shm_open 482 --#define TARGET_FREEBSD_NR_shm_unlink 483 --#define TARGET_FREEBSD_NR_cpuset 484 --#define TARGET_FREEBSD_NR_cpuset_setid 485 --#define TARGET_FREEBSD_NR_cpuset_getid 486 --#define TARGET_FREEBSD_NR_cpuset_getaffinity 487 --#define TARGET_FREEBSD_NR_cpuset_setaffinity 488 --#define TARGET_FREEBSD_NR_faccessat 489 --#define TARGET_FREEBSD_NR_fchmodat 490 --#define TARGET_FREEBSD_NR_fchownat 491 --#define TARGET_FREEBSD_NR_fexecve 492 --#define TARGET_FREEBSD_NR_fstatat 493 --#define TARGET_FREEBSD_NR_futimesat 494 --#define TARGET_FREEBSD_NR_linkat 495 --#define TARGET_FREEBSD_NR_mkdirat 496 --#define TARGET_FREEBSD_NR_mkfifoat 497 --#define TARGET_FREEBSD_NR_mknodat 498 --#define TARGET_FREEBSD_NR_openat 499 --#define TARGET_FREEBSD_NR_readlinkat 500 --#define TARGET_FREEBSD_NR_renameat 501 --#define TARGET_FREEBSD_NR_symlinkat 502 --#define TARGET_FREEBSD_NR_unlinkat 503 --#define TARGET_FREEBSD_NR_posix_openpt 504 -+#define TARGET_FREEBSD_NR_syscall 0 -+#define TARGET_FREEBSD_NR_exit 1 -+#define TARGET_FREEBSD_NR_fork 2 -+#define TARGET_FREEBSD_NR_read 3 -+#define TARGET_FREEBSD_NR_write 4 -+#define TARGET_FREEBSD_NR_open 5 -+#define TARGET_FREEBSD_NR_close 6 -+#define TARGET_FREEBSD_NR_wait4 7 -+ /* 8 is old creat */ -+#define TARGET_FREEBSD_NR_link 9 -+#define TARGET_FREEBSD_NR_unlink 10 -+ /* 11 is obsolete execv */ -+#define TARGET_FREEBSD_NR_chdir 12 -+#define TARGET_FREEBSD_NR_fchdir 13 -+#define TARGET_FREEBSD_NR_mknod 14 -+#define TARGET_FREEBSD_NR_chmod 15 -+#define TARGET_FREEBSD_NR_chown 16 -+#define TARGET_FREEBSD_NR_break 17 -+#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18 -+ /* 19 is old lseek */ -+#define TARGET_FREEBSD_NR_getpid 20 -+#define TARGET_FREEBSD_NR_mount 21 -+#define TARGET_FREEBSD_NR_unmount 22 -+#define TARGET_FREEBSD_NR_setuid 23 -+#define TARGET_FREEBSD_NR_getuid 24 -+#define TARGET_FREEBSD_NR_geteuid 25 -+#define TARGET_FREEBSD_NR_ptrace 26 -+#define TARGET_FREEBSD_NR_recvmsg 27 -+#define TARGET_FREEBSD_NR_sendmsg 28 -+#define TARGET_FREEBSD_NR_recvfrom 29 -+#define TARGET_FREEBSD_NR_accept 30 -+#define TARGET_FREEBSD_NR_getpeername 31 -+#define TARGET_FREEBSD_NR_getsockname 32 -+#define TARGET_FREEBSD_NR_access 33 -+#define TARGET_FREEBSD_NR_chflags 34 -+#define TARGET_FREEBSD_NR_fchflags 35 -+#define TARGET_FREEBSD_NR_sync 36 -+#define TARGET_FREEBSD_NR_kill 37 -+ /* 38 is old stat */ -+#define TARGET_FREEBSD_NR_getppid 39 -+ /* 40 is old lstat */ -+#define TARGET_FREEBSD_NR_dup 41 -+#define TARGET_FREEBSD_NR_pipe 42 -+#define TARGET_FREEBSD_NR_getegid 43 -+#define TARGET_FREEBSD_NR_profil 44 -+#define TARGET_FREEBSD_NR_ktrace 45 -+ /* 46 is old sigaction */ -+#define TARGET_FREEBSD_NR_getgid 47 -+ /* 48 is old sigprocmask */ -+#define TARGET_FREEBSD_NR_getlogin 49 -+#define TARGET_FREEBSD_NR_setlogin 50 -+#define TARGET_FREEBSD_NR_acct 51 -+ /* 52 is old sigpending */ -+#define TARGET_FREEBSD_NR_sigaltstack 53 -+#define TARGET_FREEBSD_NR_ioctl 54 -+#define TARGET_FREEBSD_NR_reboot 55 -+#define TARGET_FREEBSD_NR_revoke 56 -+#define TARGET_FREEBSD_NR_symlink 57 -+#define TARGET_FREEBSD_NR_readlink 58 -+#define TARGET_FREEBSD_NR_execve 59 -+#define TARGET_FREEBSD_NR_umask 60 -+#define TARGET_FREEBSD_NR_chroot 61 -+ /* 62 is old fstat */ -+ /* 63 is old getkerninfo */ -+ /* 64 is old getpagesize */ -+#define TARGET_FREEBSD_NR_msync 65 -+#define TARGET_FREEBSD_NR_vfork 66 -+ /* 67 is obsolete vread */ -+ /* 68 is obsolete vwrite */ -+#define TARGET_FREEBSD_NR_sbrk 69 -+#define TARGET_FREEBSD_NR_sstk 70 -+ /* 71 is old mmap */ -+#define TARGET_FREEBSD_NR_vadvise 72 -+#define TARGET_FREEBSD_NR_munmap 73 -+#define TARGET_FREEBSD_NR_mprotect 74 -+#define TARGET_FREEBSD_NR_madvise 75 -+ /* 76 is obsolete vhangup */ -+ /* 77 is obsolete vlimit */ -+#define TARGET_FREEBSD_NR_mincore 78 -+#define TARGET_FREEBSD_NR_getgroups 79 -+#define TARGET_FREEBSD_NR_setgroups 80 -+#define TARGET_FREEBSD_NR_getpgrp 81 -+#define TARGET_FREEBSD_NR_setpgid 82 -+#define TARGET_FREEBSD_NR_setitimer 83 -+ /* 84 is old wait */ -+#define TARGET_FREEBSD_NR_swapon 85 -+#define TARGET_FREEBSD_NR_getitimer 86 -+ /* 87 is old gethostname */ -+ /* 88 is old sethostname */ -+#define TARGET_FREEBSD_NR_getdtablesize 89 -+#define TARGET_FREEBSD_NR_dup2 90 -+#define TARGET_FREEBSD_NR_fcntl 92 -+#define TARGET_FREEBSD_NR_select 93 -+#define TARGET_FREEBSD_NR_fsync 95 -+#define TARGET_FREEBSD_NR_setpriority 96 -+#define TARGET_FREEBSD_NR_socket 97 -+#define TARGET_FREEBSD_NR_connect 98 -+ /* 99 is old accept */ -+#define TARGET_FREEBSD_NR_getpriority 100 -+ /* 101 is old send */ -+ /* 102 is old recv */ -+ /* 103 is old sigreturn */ -+#define TARGET_FREEBSD_NR_bind 104 -+#define TARGET_FREEBSD_NR_setsockopt 105 -+#define TARGET_FREEBSD_NR_listen 106 -+ /* 107 is obsolete vtimes */ -+ /* 108 is old sigvec */ -+ /* 109 is old sigblock */ -+ /* 110 is old sigsetmask */ -+ /* 111 is old sigsuspend */ -+ /* 112 is old sigstack */ -+ /* 113 is old recvmsg */ -+ /* 114 is old sendmsg */ -+ /* 115 is obsolete vtrace */ -+#define TARGET_FREEBSD_NR_gettimeofday 116 -+#define TARGET_FREEBSD_NR_getrusage 117 -+#define TARGET_FREEBSD_NR_getsockopt 118 -+#define TARGET_FREEBSD_NR_readv 120 -+#define TARGET_FREEBSD_NR_writev 121 -+#define TARGET_FREEBSD_NR_settimeofday 122 -+#define TARGET_FREEBSD_NR_fchown 123 -+#define TARGET_FREEBSD_NR_fchmod 124 -+ /* 125 is old recvfrom */ -+#define TARGET_FREEBSD_NR_setreuid 126 -+#define TARGET_FREEBSD_NR_setregid 127 -+#define TARGET_FREEBSD_NR_rename 128 -+ /* 129 is old truncate */ -+ /* 130 is old ftruncate */ -+#define TARGET_FREEBSD_NR_flock 131 -+#define TARGET_FREEBSD_NR_mkfifo 132 -+#define TARGET_FREEBSD_NR_sendto 133 -+#define TARGET_FREEBSD_NR_shutdown 134 -+#define TARGET_FREEBSD_NR_socketpair 135 -+#define TARGET_FREEBSD_NR_mkdir 136 -+#define TARGET_FREEBSD_NR_rmdir 137 -+#define TARGET_FREEBSD_NR_utimes 138 -+ /* 139 is obsolete 4.2 sigreturn */ -+#define TARGET_FREEBSD_NR_adjtime 140 -+ /* 141 is old getpeername */ -+ /* 142 is old gethostid */ -+ /* 143 is old sethostid */ -+ /* 144 is old getrlimit */ -+ /* 145 is old setrlimit */ -+ /* 146 is old killpg */ -+#define TARGET_FREEBSD_NR_setsid 147 -+#define TARGET_FREEBSD_NR_quotactl 148 -+ /* 149 is old quota */ -+ /* 150 is old getsockname */ -+#define TARGET_FREEBSD_NR_nlm_syscall 154 -+#define TARGET_FREEBSD_NR_nfssvc 155 -+ /* 156 is old getdirentries */ -+#define TARGET_FREEBSD_NR_freebsd4_statfs 157 -+#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158 -+#define TARGET_FREEBSD_NR_lgetfh 160 -+#define TARGET_FREEBSD_NR_getfh 161 -+#define TARGET_FREEBSD_NR_freebsd4_getdomainname 162 -+#define TARGET_FREEBSD_NR_freebsd4_setdomainname 163 -+#define TARGET_FREEBSD_NR_freebsd4_uname 164 -+#define TARGET_FREEBSD_NR_sysarch 165 -+#define TARGET_FREEBSD_NR_rtprio 166 -+#define TARGET_FREEBSD_NR_semsys 169 -+#define TARGET_FREEBSD_NR_msgsys 170 -+#define TARGET_FREEBSD_NR_shmsys 171 -+#define TARGET_FREEBSD_NR_freebsd6_pread 173 -+#define TARGET_FREEBSD_NR_freebsd6_pwrite 174 -+#define TARGET_FREEBSD_NR_setfib 175 -+#define TARGET_FREEBSD_NR_ntp_adjtime 176 -+#define TARGET_FREEBSD_NR_setgid 181 -+#define TARGET_FREEBSD_NR_setegid 182 -+#define TARGET_FREEBSD_NR_seteuid 183 -+#define TARGET_FREEBSD_NR_stat 188 -+#define TARGET_FREEBSD_NR_fstat 189 -+#define TARGET_FREEBSD_NR_lstat 190 -+#define TARGET_FREEBSD_NR_pathconf 191 -+#define TARGET_FREEBSD_NR_fpathconf 192 -+#define TARGET_FREEBSD_NR_getrlimit 194 -+#define TARGET_FREEBSD_NR_setrlimit 195 -+#define TARGET_FREEBSD_NR_getdirentries 196 -+#define TARGET_FREEBSD_NR_freebsd6_mmap 197 -+#define TARGET_FREEBSD_NR___syscall 198 -+#define TARGET_FREEBSD_NR_freebsd6_lseek 199 -+#define TARGET_FREEBSD_NR_freebsd6_truncate 200 -+#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201 -+#define TARGET_FREEBSD_NR___sysctl 202 -+#define TARGET_FREEBSD_NR_mlock 203 -+#define TARGET_FREEBSD_NR_munlock 204 -+#define TARGET_FREEBSD_NR_undelete 205 -+#define TARGET_FREEBSD_NR_futimes 206 -+#define TARGET_FREEBSD_NR_getpgid 207 -+#define TARGET_FREEBSD_NR_poll 209 -+#define TARGET_FREEBSD_NR_freebsd7___semctl 220 -+#define TARGET_FREEBSD_NR_semget 221 -+#define TARGET_FREEBSD_NR_semop 222 -+#define TARGET_FREEBSD_NR_freebsd7_msgctl 224 -+#define TARGET_FREEBSD_NR_msgget 225 -+#define TARGET_FREEBSD_NR_msgsnd 226 -+#define TARGET_FREEBSD_NR_msgrcv 227 -+#define TARGET_FREEBSD_NR_shmat 228 -+#define TARGET_FREEBSD_NR_freebsd7_shmctl 229 -+#define TARGET_FREEBSD_NR_shmdt 230 -+#define TARGET_FREEBSD_NR_shmget 231 -+#define TARGET_FREEBSD_NR_clock_gettime 232 -+#define TARGET_FREEBSD_NR_clock_settime 233 -+#define TARGET_FREEBSD_NR_clock_getres 234 -+#define TARGET_FREEBSD_NR_ktimer_create 235 -+#define TARGET_FREEBSD_NR_ktimer_delete 236 -+#define TARGET_FREEBSD_NR_ktimer_settime 237 -+#define TARGET_FREEBSD_NR_ktimer_gettime 238 -+#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 -+#define TARGET_FREEBSD_NR_nanosleep 240 -+#define TARGET_FREEBSD_NR_ntp_gettime 248 -+#define TARGET_FREEBSD_NR_minherit 250 -+#define TARGET_FREEBSD_NR_rfork 251 -+#define TARGET_FREEBSD_NR_openbsd_poll 252 -+#define TARGET_FREEBSD_NR_issetugid 253 -+#define TARGET_FREEBSD_NR_lchown 254 -+#define TARGET_FREEBSD_NR_aio_read 255 -+#define TARGET_FREEBSD_NR_aio_write 256 -+#define TARGET_FREEBSD_NR_lio_listio 257 -+#define TARGET_FREEBSD_NR_getdents 272 -+#define TARGET_FREEBSD_NR_lchmod 274 -+#define TARGET_FREEBSD_NR_netbsd_lchown 275 -+#define TARGET_FREEBSD_NR_lutimes 276 -+#define TARGET_FREEBSD_NR_netbsd_msync 277 -+#define TARGET_FREEBSD_NR_nstat 278 -+#define TARGET_FREEBSD_NR_nfstat 279 -+#define TARGET_FREEBSD_NR_nlstat 280 -+#define TARGET_FREEBSD_NR_preadv 289 -+#define TARGET_FREEBSD_NR_pwritev 290 -+#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 -+#define TARGET_FREEBSD_NR_fhopen 298 -+#define TARGET_FREEBSD_NR_fhstat 299 -+#define TARGET_FREEBSD_NR_modnext 300 -+#define TARGET_FREEBSD_NR_modstat 301 -+#define TARGET_FREEBSD_NR_modfnext 302 -+#define TARGET_FREEBSD_NR_modfind 303 -+#define TARGET_FREEBSD_NR_kldload 304 -+#define TARGET_FREEBSD_NR_kldunload 305 -+#define TARGET_FREEBSD_NR_kldfind 306 -+#define TARGET_FREEBSD_NR_kldnext 307 -+#define TARGET_FREEBSD_NR_kldstat 308 -+#define TARGET_FREEBSD_NR_kldfirstmod 309 -+#define TARGET_FREEBSD_NR_getsid 310 -+#define TARGET_FREEBSD_NR_setresuid 311 -+#define TARGET_FREEBSD_NR_setresgid 312 -+ /* 313 is obsolete signanosleep */ -+#define TARGET_FREEBSD_NR_aio_return 314 -+#define TARGET_FREEBSD_NR_aio_suspend 315 -+#define TARGET_FREEBSD_NR_aio_cancel 316 -+#define TARGET_FREEBSD_NR_aio_error 317 -+#define TARGET_FREEBSD_NR_oaio_read 318 -+#define TARGET_FREEBSD_NR_oaio_write 319 -+#define TARGET_FREEBSD_NR_olio_listio 320 -+#define TARGET_FREEBSD_NR_yield 321 -+ /* 322 is obsolete thr_sleep */ -+ /* 323 is obsolete thr_wakeup */ -+#define TARGET_FREEBSD_NR_mlockall 324 -+#define TARGET_FREEBSD_NR_munlockall 325 -+#define TARGET_FREEBSD_NR___getcwd 326 -+#define TARGET_FREEBSD_NR_sched_setparam 327 -+#define TARGET_FREEBSD_NR_sched_getparam 328 -+#define TARGET_FREEBSD_NR_sched_setscheduler 329 -+#define TARGET_FREEBSD_NR_sched_getscheduler 330 -+#define TARGET_FREEBSD_NR_sched_yield 331 -+#define TARGET_FREEBSD_NR_sched_get_priority_max 332 -+#define TARGET_FREEBSD_NR_sched_get_priority_min 333 -+#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 -+#define TARGET_FREEBSD_NR_utrace 335 -+#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 -+#define TARGET_FREEBSD_NR_kldsym 337 -+#define TARGET_FREEBSD_NR_jail 338 -+#define TARGET_FREEBSD_NR_nnpfs_syscall 339 -+#define TARGET_FREEBSD_NR_sigprocmask 340 -+#define TARGET_FREEBSD_NR_sigsuspend 341 -+#define TARGET_FREEBSD_NR_freebsd4_sigaction 342 -+#define TARGET_FREEBSD_NR_sigpending 343 -+#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344 -+#define TARGET_FREEBSD_NR_sigtimedwait 345 -+#define TARGET_FREEBSD_NR_sigwaitinfo 346 -+#define TARGET_FREEBSD_NR___acl_get_file 347 -+#define TARGET_FREEBSD_NR___acl_set_file 348 -+#define TARGET_FREEBSD_NR___acl_get_fd 349 -+#define TARGET_FREEBSD_NR___acl_set_fd 350 -+#define TARGET_FREEBSD_NR___acl_delete_file 351 -+#define TARGET_FREEBSD_NR___acl_delete_fd 352 -+#define TARGET_FREEBSD_NR___acl_aclcheck_file 353 -+#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 -+#define TARGET_FREEBSD_NR_extattrctl 355 -+#define TARGET_FREEBSD_NR_extattr_set_file 356 -+#define TARGET_FREEBSD_NR_extattr_get_file 357 -+#define TARGET_FREEBSD_NR_extattr_delete_file 358 -+#define TARGET_FREEBSD_NR_aio_waitcomplete 359 -+#define TARGET_FREEBSD_NR_getresuid 360 -+#define TARGET_FREEBSD_NR_getresgid 361 -+#define TARGET_FREEBSD_NR_kqueue 362 -+#define TARGET_FREEBSD_NR_kevent 363 -+#define TARGET_FREEBSD_NR_extattr_set_fd 371 -+#define TARGET_FREEBSD_NR_extattr_get_fd 372 -+#define TARGET_FREEBSD_NR_extattr_delete_fd 373 -+#define TARGET_FREEBSD_NR___setugid 374 -+#define TARGET_FREEBSD_NR_eaccess 376 -+#define TARGET_FREEBSD_NR_afs3_syscall 377 -+#define TARGET_FREEBSD_NR_nmount 378 -+#define TARGET_FREEBSD_NR___mac_get_proc 384 -+#define TARGET_FREEBSD_NR___mac_set_proc 385 -+#define TARGET_FREEBSD_NR___mac_get_fd 386 -+#define TARGET_FREEBSD_NR___mac_get_file 387 -+#define TARGET_FREEBSD_NR___mac_set_fd 388 -+#define TARGET_FREEBSD_NR___mac_set_file 389 -+#define TARGET_FREEBSD_NR_kenv 390 -+#define TARGET_FREEBSD_NR_lchflags 391 -+#define TARGET_FREEBSD_NR_uuidgen 392 -+#define TARGET_FREEBSD_NR_sendfile 393 -+#define TARGET_FREEBSD_NR_mac_syscall 394 -+#define TARGET_FREEBSD_NR_getfsstat 395 -+#define TARGET_FREEBSD_NR_statfs 396 -+#define TARGET_FREEBSD_NR_fstatfs 397 -+#define TARGET_FREEBSD_NR_fhstatfs 398 -+#define TARGET_FREEBSD_NR_ksem_close 400 -+#define TARGET_FREEBSD_NR_ksem_post 401 -+#define TARGET_FREEBSD_NR_ksem_wait 402 -+#define TARGET_FREEBSD_NR_ksem_trywait 403 -+#define TARGET_FREEBSD_NR_ksem_init 404 -+#define TARGET_FREEBSD_NR_ksem_open 405 -+#define TARGET_FREEBSD_NR_ksem_unlink 406 -+#define TARGET_FREEBSD_NR_ksem_getvalue 407 -+#define TARGET_FREEBSD_NR_ksem_destroy 408 -+#define TARGET_FREEBSD_NR___mac_get_pid 409 -+#define TARGET_FREEBSD_NR___mac_get_link 410 -+#define TARGET_FREEBSD_NR___mac_set_link 411 -+#define TARGET_FREEBSD_NR_extattr_set_link 412 -+#define TARGET_FREEBSD_NR_extattr_get_link 413 -+#define TARGET_FREEBSD_NR_extattr_delete_link 414 -+#define TARGET_FREEBSD_NR___mac_execve 415 -+#define TARGET_FREEBSD_NR_sigaction 416 -+#define TARGET_FREEBSD_NR_sigreturn 417 -+#define TARGET_FREEBSD_NR_getcontext 421 -+#define TARGET_FREEBSD_NR_setcontext 422 -+#define TARGET_FREEBSD_NR_swapcontext 423 -+#define TARGET_FREEBSD_NR_swapoff 424 -+#define TARGET_FREEBSD_NR___acl_get_link 425 -+#define TARGET_FREEBSD_NR___acl_set_link 426 -+#define TARGET_FREEBSD_NR___acl_delete_link 427 -+#define TARGET_FREEBSD_NR___acl_aclcheck_link 428 -+#define TARGET_FREEBSD_NR_sigwait 429 -+#define TARGET_FREEBSD_NR_thr_create 430 -+#define TARGET_FREEBSD_NR_thr_exit 431 -+#define TARGET_FREEBSD_NR_thr_self 432 -+#define TARGET_FREEBSD_NR_thr_kill 433 -+#define TARGET_FREEBSD_NR__umtx_lock 434 -+#define TARGET_FREEBSD_NR__umtx_unlock 435 -+#define TARGET_FREEBSD_NR_jail_attach 436 -+#define TARGET_FREEBSD_NR_extattr_list_fd 437 -+#define TARGET_FREEBSD_NR_extattr_list_file 438 -+#define TARGET_FREEBSD_NR_extattr_list_link 439 -+#define TARGET_FREEBSD_NR_ksem_timedwait 441 -+#define TARGET_FREEBSD_NR_thr_suspend 442 -+#define TARGET_FREEBSD_NR_thr_wake 443 -+#define TARGET_FREEBSD_NR_kldunloadf 444 -+#define TARGET_FREEBSD_NR_audit 445 -+#define TARGET_FREEBSD_NR_auditon 446 -+#define TARGET_FREEBSD_NR_getauid 447 -+#define TARGET_FREEBSD_NR_setauid 448 -+#define TARGET_FREEBSD_NR_getaudit 449 -+#define TARGET_FREEBSD_NR_setaudit 450 -+#define TARGET_FREEBSD_NR_getaudit_addr 451 -+#define TARGET_FREEBSD_NR_setaudit_addr 452 -+#define TARGET_FREEBSD_NR_auditctl 453 -+#define TARGET_FREEBSD_NR__umtx_op 454 -+#define TARGET_FREEBSD_NR_thr_new 455 -+#define TARGET_FREEBSD_NR_sigqueue 456 -+#define TARGET_FREEBSD_NR_kmq_open 457 -+#define TARGET_FREEBSD_NR_kmq_setattr 458 -+#define TARGET_FREEBSD_NR_kmq_timedreceive 459 -+#define TARGET_FREEBSD_NR_kmq_timedsend 460 -+#define TARGET_FREEBSD_NR_kmq_notify 461 -+#define TARGET_FREEBSD_NR_kmq_unlink 462 -+#define TARGET_FREEBSD_NR_abort2 463 -+#define TARGET_FREEBSD_NR_thr_set_name 464 -+#define TARGET_FREEBSD_NR_aio_fsync 465 -+#define TARGET_FREEBSD_NR_rtprio_thread 466 -+#define TARGET_FREEBSD_NR_sctp_peeloff 471 -+#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472 -+#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473 -+#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474 -+#define TARGET_FREEBSD_NR_pread 475 -+#define TARGET_FREEBSD_NR_pwrite 476 -+#define TARGET_FREEBSD_NR_mmap 477 -+#define TARGET_FREEBSD_NR_lseek 478 -+#define TARGET_FREEBSD_NR_truncate 479 -+#define TARGET_FREEBSD_NR_ftruncate 480 -+#define TARGET_FREEBSD_NR_thr_kill2 481 -+#define TARGET_FREEBSD_NR_shm_open 482 -+#define TARGET_FREEBSD_NR_shm_unlink 483 -+#define TARGET_FREEBSD_NR_cpuset 484 -+#define TARGET_FREEBSD_NR_cpuset_setid 485 -+#define TARGET_FREEBSD_NR_cpuset_getid 486 -+#define TARGET_FREEBSD_NR_cpuset_getaffinity 487 -+#define TARGET_FREEBSD_NR_cpuset_setaffinity 488 -+#define TARGET_FREEBSD_NR_faccessat 489 -+#define TARGET_FREEBSD_NR_fchmodat 490 -+#define TARGET_FREEBSD_NR_fchownat 491 -+#define TARGET_FREEBSD_NR_fexecve 492 -+#define TARGET_FREEBSD_NR_fstatat 493 -+#define TARGET_FREEBSD_NR_futimesat 494 -+#define TARGET_FREEBSD_NR_linkat 495 -+#define TARGET_FREEBSD_NR_mkdirat 496 -+#define TARGET_FREEBSD_NR_mkfifoat 497 -+#define TARGET_FREEBSD_NR_mknodat 498 -+#define TARGET_FREEBSD_NR_openat 499 -+#define TARGET_FREEBSD_NR_readlinkat 500 -+#define TARGET_FREEBSD_NR_renameat 501 -+#define TARGET_FREEBSD_NR_symlinkat 502 -+#define TARGET_FREEBSD_NR_unlinkat 503 -+#define TARGET_FREEBSD_NR_posix_openpt 504 -+#define TARGET_FREEBSD_NR_gssd_syscall 505 -+#define TARGET_FREEBSD_NR_jail_get 506 -+#define TARGET_FREEBSD_NR_jail_set 507 -+#define TARGET_FREEBSD_NR_jail_remove 508 -+#define TARGET_FREEBSD_NR_closefrom 509 -+#define TARGET_FREEBSD_NR___semctl 510 -+#define TARGET_FREEBSD_NR_msgctl 511 -+#define TARGET_FREEBSD_NR_shmctl 512 -+#define TARGET_FREEBSD_NR_lpathconf 513 -+#define TARGET_FREEBSD_NR_cap_new 514 -+#define TARGET_FREEBSD_NR_cap_getrights 515 -+#define TARGET_FREEBSD_NR_cap_enter 516 -+#define TARGET_FREEBSD_NR_cap_getmode 517 -+#define TARGET_FREEBSD_NR_pdfork 518 -+#define TARGET_FREEBSD_NR_pdkill 519 -+#define TARGET_FREEBSD_NR_pdgetpid 520 -+#define TARGET_FREEBSD_NR_pselect 522 -+#define TARGET_FREEBSD_NR_getloginclass 523 -+#define TARGET_FREEBSD_NR_setloginclass 524 -+#define TARGET_FREEBSD_NR_rctl_get_racct 525 -+#define TARGET_FREEBSD_NR_rctl_get_rules 526 -+#define TARGET_FREEBSD_NR_rctl_get_limits 527 -+#define TARGET_FREEBSD_NR_rctl_add_rule 528 -+#define TARGET_FREEBSD_NR_rctl_remove_rule 529 -+#define TARGET_FREEBSD_NR_posix_fallocate 530 -+#define TARGET_FREEBSD_NR_posix_fadvise 531 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 532 -diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h -index 2ef36d1..285e7f9 100644 ---- a/bsd-user/i386/target_signal.h -+++ b/bsd-user/i386/target_signal.h -@@ -3,18 +3,12 @@ - - #include "cpu.h" - --/* this struct defines a stack used during syscall handling */ -- --typedef struct target_sigaltstack { -- abi_ulong ss_sp; -- abi_long ss_flags; -- abi_ulong ss_size; --} target_stack_t; -- -- - static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) - { - return state->regs[R_ESP]; - } - -+#define TARGET_MINSIGSTKSZ (512 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/i386/target_vmparam.h b/bsd-user/i386/target_vmparam.h -new file mode 100644 -index 0000000..8fc98d5 ---- /dev/null -+++ b/bsd-user/i386/target_vmparam.h -@@ -0,0 +1,27 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#if defined(__FreeBSD__) -+ -+#define TARGET_USRSTACK (0xbfc00000) -+ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#define TARGET_SZSIGCODE 0 -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+#endif -+ -+#endif /* _TARGET_VMPARAM_H_ */ -diff --git a/bsd-user/main.c b/bsd-user/main.c -index b4e42f3..146f022 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -642,6 +642,243 @@ void cpu_loop(CPUARMState *env) - - #endif - -+#if defined(TARGET_MIPS) || defined(TARGET_MIPS64) -+ -+/* -+ * From sys/mips/mips/trap.c syscalls have the following stored away in the -+ * registers: -+ * -+ * v0(2): if either SYS___syscall (198) or SYS_syscall (0) then indirect syscall -+ * otherwise it is a direct syscall. -+ * -+ * If direct syscall: -+ * -+ * MIPS MIPS64 -+ * v0(2): v0(2) syscall # -+ * a0(4): a0(4) arg0 -+ * a1(5): a1(5) arg1 -+ * a2(6): a2(6) arg2 -+ * a3(7): a3(7) arg3 -+ * t4(12): a4(8) arg4 -+ * t5(13): a5(9) arg5 -+ * t6(14): a6(10) arg6 -+ * t7(15): a7(11) arg7 -+ * -+ * If indirect syscall: -+ * -+ * MIPS MIPS64 -+ * a0(4): a0(4) syscall # -+ * a1(5): a1(5) arg0 -+ * a2(6): a2(6) arg1 -+ * a3(7): a3(7) arg2 -+ * t4(12): a4(8) arg3 -+ * t5(13): a5(9) arg4 -+ * t6(14): a6(10) arg5 -+ * t7(15): a7(11) arg6 -+ * -+ */ -+ -+#include <sys/syscall.h> /* For SYS_[__]syscall, SYS_MAXSYSCALL */ -+ -+static int do_store_exclusive(CPUMIPSState *env) -+{ -+ target_ulong addr; -+ target_ulong page_addr; -+ target_ulong val; -+ int flags; -+ int segv = 0; -+ int reg; -+ int d; -+ -+ addr = env->lladdr; -+ page_addr = addr & TARGET_PAGE_MASK; -+ start_exclusive(); -+ mmap_lock(); -+ flags = page_get_flags(page_addr); -+ if ((flags & PAGE_READ) == 0) { -+ segv = 1; -+ } else { -+ reg = env->llreg & 0x1f; -+ d = (env->llreg & 0x20) != 0; -+ if (d) { -+ segv = get_user_s64(val, addr); -+ } else { -+ segv = get_user_s32(val, addr); -+ } -+ if (!segv) { -+ if (val != env->llval) { -+ env->active_tc.gpr[reg] = 0; -+ } else { -+ if (d) { -+ segv = -+ put_user_u64(env->llnewval, addr); -+ } else { -+ segv = -+ put_user_u32(env->llnewval, addr); -+ } -+ if (!segv) { -+ env->active_tc.gpr[reg] = 1; -+ } -+ } -+ } -+ } -+ env->lladdr = -1; -+ if (!segv) { -+ env->active_tc.PC += 4; -+ } -+ mmap_unlock(); -+ end_exclusive(); -+ return (segv); -+} -+ -+void cpu_loop(CPUMIPSState *env) -+{ -+ target_siginfo_t info; -+ int trapnr; -+ abi_long ret; -+ unsigned int syscall_num; -+ -+ for(;;) { -+ cpu_exec_start(env); -+ trapnr = cpu_mips_exec(env); -+ cpu_exec_end(env); -+ switch(trapnr) { -+ case EXCP_SYSCALL: /* syscall exception */ -+ syscall_num = env->active_tc.gpr[2]; /* v0 */ -+ env->active_tc.PC += 4; -+ if (syscall_num >= SYS_MAXSYSCALL) { -+ ret = -TARGET_ENOSYS; -+ } else { -+ if (SYS_syscall == syscall_num || -+ SYS___syscall == syscall_num) { -+#if defined(TARGET_MIPS64) -+ ret = do_freebsd_syscall(env, -+ env->active_tc.gpr[4],/* syscall #*/ -+ env->active_tc.gpr[5], /* arg0 */ -+ env->active_tc.gpr[6], /* arg1 */ -+ env->active_tc.gpr[7], /* arg2 */ -+ env->active_tc.gpr[8], /* arg3 */ -+ env->active_tc.gpr[9], /* arg4 */ -+ env->active_tc.gpr[10],/* arg5 */ -+ env->active_tc.gpr[11],/* arg6 */ -+ 0 /* no arg 7 */); -+ } else { -+ ret = do_freebsd_syscall(env, -+ syscall_num, -+ env->active_tc.gpr[4], -+ env->active_tc.gpr[5], -+ env->active_tc.gpr[6], -+ env->active_tc.gpr[7], -+ env->active_tc.gpr[8], -+ env->active_tc.gpr[9], -+ env->active_tc.gpr[10], -+ env->active_tc.gpr[11] -+ ); -+ -+#else /* ! TARGET_MIPS64 */ -+ /* indirect syscall */ -+ ret = do_freebsd_syscall(env, -+ env->active_tc.gpr[4],/* syscall #*/ -+ env->active_tc.gpr[5], /* a1/arg0 */ -+ env->active_tc.gpr[6], /* a2/arg1 */ -+ env->active_tc.gpr[7], /* a3/arg2 */ -+ env->active_tc.gpr[12],/* t4/arg3 */ -+ env->active_tc.gpr[13],/* t5/arg4 */ -+ env->active_tc.gpr[14],/* t6/arg5 */ -+ env->active_tc.gpr[15],/* t7/arg6 */ -+ 0 /* no arg7 */ ); -+ } else { -+ /* direct syscall */ -+ ret = do_freebsd_syscall(env, -+ syscall_num, -+ env->active_tc.gpr[4], /* a0/arg0 */ -+ env->active_tc.gpr[5], /* a1/arg1 */ -+ env->active_tc.gpr[6], /* a2/arg2 */ -+ env->active_tc.gpr[7], /* a3/arg3 */ -+ env->active_tc.gpr[12],/* t4/arg4 */ -+ env->active_tc.gpr[13],/* t5/arg5 */ -+ env->active_tc.gpr[14],/* t6/arg6 */ -+ env->active_tc.gpr[15] /* t7/arg7 */ -+ ); -+#endif /* ! TARGET_MIPS64 */ -+ } -+ } -+/* done_syscall: */ -+ if (-TARGET_QEMU_ESIGRETURN == ret) { -+ /* -+ * Returning from a successful sigreturn -+ * syscall. Avoid clobbering register state. -+ */ -+ break; -+ } -+ if ((unsigned int)ret >= (unsigned int)(-1133)) { -+ env->active_tc.gpr[7] = 1; -+ ret = -ret; -+ } else { -+ env->active_tc.gpr[7] = 0; -+ } -+ env->active_tc.gpr[2] = ret; /* v0 <- ret */ -+ break; -+ -+ case EXCP_TLBL: /* TLB miss on load */ -+ case EXCP_TLBS: /* TLB miss on store */ -+ case EXCP_AdEL: /* bad address on load */ -+ case EXCP_AdES: /* bad address on store */ -+ info.si_signo = TARGET_SIGSEGV; -+ info.si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.si_code = TARGET_SEGV_MAPERR; -+ info.si_addr = env->CP0_BadVAddr; -+ queue_signal(env, info.si_signo, &info); -+ break; -+ -+ case EXCP_CpU: /* coprocessor unusable */ -+ case EXCP_RI: /* reserved instruction */ -+ info.si_signo = TARGET_SIGILL; -+ info.si_errno = 0; -+ info.si_code = 0; -+ queue_signal(env, info.si_signo, &info); -+ break; -+ -+ case EXCP_INTERRUPT: /* async interrupt */ -+ /* just indicate that signals should be handled asap */ -+ break; -+ -+ case EXCP_DEBUG: /* cpu stopped after a breakpoint */ -+ { -+ int sig; -+ -+ sig = gdb_handlesig(env, TARGET_SIGTRAP); -+ if (sig) { -+ info.si_signo = sig; -+ info.si_errno = 0; -+ info.si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.si_signo, &info); -+ } -+ } -+ break; -+ -+ case EXCP_SC: -+ if (do_store_exclusive(env)) { -+ info.si_signo = TARGET_SIGSEGV; -+ info.si_errno = 0; -+ info.si_code = TARGET_SEGV_MAPERR; -+ info.si_addr = env->active_tc.PC; -+ queue_signal(env, info.si_signo, &info); -+ } -+ break; -+ -+ default: -+ fprintf(stderr, "qemu: unhandled CPU exception " -+ "0x%x - aborting\n", trapnr); -+ cpu_dump_state(env, stderr, fprintf, 0); -+ abort(); -+ } -+ process_pending_signals(env); -+ } -+} -+#endif /* defined(TARGET_MIPS) */ -+ - #ifdef TARGET_SPARC - #define SPARC64_STACK_BIAS 2047 - -@@ -969,6 +1206,15 @@ static void usage(void) - - THREAD CPUArchState *thread_env; - -+void stop_all_tasks(void) -+{ -+ /* -+ * We trust when using NPTL (pthreads) start_exclusive() handles thread -+ * stopping correctly. -+ */ -+ start_exclusive(); -+} -+ - /* Assumes contents are already zeroed. */ - void init_task_state(TaskState *ts) - { -@@ -990,6 +1236,7 @@ int main(int argc, char **argv) - const char *log_mask = NULL; - struct target_pt_regs regs1, *regs = ®s1; - struct image_info info1, *info = &info1; -+ struct bsd_binprm bprm; - TaskState ts1, *ts = &ts1; - CPUArchState *env; - int optind; -@@ -997,7 +1244,11 @@ int main(int argc, char **argv) - int gdbstub_port = 0; - char **target_environ, **wrk; - envlist_t *envlist = NULL; -+#ifdef __FreeBSD__ -+ bsd_type = target_freebsd; -+#else - bsd_type = target_openbsd; -+#endif - - if (argc <= 1) - usage(); -@@ -1141,6 +1392,8 @@ int main(int argc, char **argv) - /* Zero out image_info */ - memset(info, 0, sizeof(struct image_info)); - -+ memset(&bprm, 0, sizeof(bprm)); -+ - /* Scan interp_prefix dir for replacement files. */ - init_paths(interp_prefix); - -@@ -1151,6 +1404,12 @@ int main(int argc, char **argv) - #else - cpu_model = "qemu32"; - #endif -+#elif defined(TARGET_MIPS) || defined(TARGET_MIPS64) -+#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) -+ cpu_model = "20Kc"; -+#else -+ cpu_model = "24Kf"; -+#endif - #elif defined(TARGET_SPARC) - #ifdef TARGET_SPARC64 - cpu_model = "TI UltraSparc II"; -@@ -1211,7 +1470,8 @@ int main(int argc, char **argv) - } - #endif /* CONFIG_USE_GUEST_BASE */ - -- if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { -+ if (loader_exec(filename, argv+optind, target_environ, regs, info, -+ &bprm)!= 0) { - printf("Error loading %s\n", filename); - _exit(1); - } -@@ -1256,6 +1516,7 @@ int main(int argc, char **argv) - memset(ts, 0, sizeof(TaskState)); - init_task_state(ts); - ts->info = info; -+ ts->bprm = &bprm; - env->opaque = ts; - - #if defined(TARGET_I386) -@@ -1394,6 +1655,20 @@ int main(int argc, char **argv) - env->regs[i] = regs->uregs[i]; - } - } -+#elif defined(TARGET_MIPS) -+ { -+ int i; -+ for(i = 0; i < 32; i++) { -+ env->active_tc.gpr[i] = regs->regs[i]; -+ } -+ env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1; -+ if (regs->cp0_epc & 1) { -+ env->hflags |= MIPS_HFLAG_M16; -+ } -+#if defined(TARGET_MIPS64) -+ env->hflags |= MIPS_HFLAG_UX; -+#endif -+ } - #else - #error unsupported target CPU - #endif -diff --git a/bsd-user/mips/syscall.h b/bsd-user/mips/syscall.h -new file mode 100644 -index 0000000..8923556 ---- /dev/null -+++ b/bsd-user/mips/syscall.h -@@ -0,0 +1,21 @@ -+ -+/* this struct defines the way the registers are stored on the -+ stack during a system call. */ -+ -+struct target_pt_regs { -+ /* Pad bytes for argument save space on the stack. */ -+ abi_ulong pad0[6]; -+ -+ /* Saved main processor registers. */ -+ abi_ulong regs[32]; -+ -+ /* Saved special registers. */ -+ abi_ulong cp0_status; -+ abi_ulong lo; -+ abi_ulong hi; -+ abi_ulong cp0_badvaddr; -+ abi_ulong cp0_cause; -+ abi_ulong cp0_epc; -+}; -+ -+#define UNAME_MACHINE "mips" -diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h -new file mode 100644 -index 0000000..28871c3 ---- /dev/null -+++ b/bsd-user/mips/target_signal.h -@@ -0,0 +1,14 @@ -+#ifndef TARGET_SIGNAL_H -+#define TARGET_SIGNAL_H -+ -+#include "cpu.h" -+ -+#define TARGET_MINSIGSTKSZ (512 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ -+static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) -+{ -+ return state->active_tc.gpr[29]; -+} -+ -+#endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h -new file mode 100644 -index 0000000..9fca7f3 ---- /dev/null -+++ b/bsd-user/mips/target_vmparam.h -@@ -0,0 +1,30 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#if defined(__FreeBSD__) -+#define TARGET_VM_MINUSER_ADDRESS (0x00000000) -+#define TARGET_VM_MAXUSER_ADDRESS (0x80000000) -+ -+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#define TARGET_SZSIGCODE 0 -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+#endif -+ -+ -+#endif /* _TARGET_VMPARAM_H_ */ -diff --git a/bsd-user/mips64/syscall.h b/bsd-user/mips64/syscall.h -new file mode 100644 -index 0000000..fca3634 ---- /dev/null -+++ b/bsd-user/mips64/syscall.h -@@ -0,0 +1,21 @@ -+ -+/* this struct defines the way the registers are stored on the -+ stack during a system call. */ -+ -+struct target_pt_regs { -+ /* Saved main processor registers. */ -+ abi_ulong regs[32]; -+ -+ /* Saved special registers. */ -+ abi_ulong cp0_status; -+ abi_ulong lo; -+ abi_ulong hi; -+ abi_ulong cp0_badvaddr; -+ abi_ulong cp0_cause; -+ abi_ulong cp0_epc; -+}; -+ -+/* Nasty hack: define a fake errno value for use by sigreturn. */ -+#define TARGET_QEMU_ESIGRETURN 255 -+ -+#define UNAME_MACHINE "mips64" -diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h -new file mode 100644 -index 0000000..d671f4e ---- /dev/null -+++ b/bsd-user/mips64/target_signal.h -@@ -0,0 +1,17 @@ -+#ifndef TARGET_SIGNAL_H -+#define TARGET_SIGNAL_H -+ -+#include "cpu.h" -+ -+#define TARGET_MINSIGSTKSZ (512 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+#define TARGET_SZSIGCODE 16 -+ -+#define TARGET_UCONTEXT_MAGIC 0xACEDBADE -+ -+static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) -+{ -+ return state->active_tc.gpr[29]; -+} -+ -+#endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h -new file mode 100644 -index 0000000..47c2267 ---- /dev/null -+++ b/bsd-user/mips64/target_vmparam.h -@@ -0,0 +1,28 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#if defined(__FreeBSD__) -+ -+#define TARGET_VM_MINUSER_ADDRESS (0x0000000000000000UL) -+#define TARGET_VM_MAXUSER_ADDRESS (0x0000008000000000UL) -+ -+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+#endif -+ -+#endif /* _TARGET_VMPARAM_H_ */ -diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c -index 5d6cffc..9f42c27 100644 ---- a/bsd-user/mmap.c -+++ b/bsd-user/mmap.c -@@ -275,7 +275,8 @@ unsigned long last_brk; - */ - /* page_init() marks pages used by the host as reserved to be sure not - to use them. */ --static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) -+abi_ulong -+mmap_find_vma(abi_ulong start, abi_ulong size) - { - abi_ulong addr, addr1, addr_start; - int prot; -@@ -493,7 +494,7 @@ int target_munmap(abi_ulong start, abi_ulong len) - int prot, ret; - - #ifdef DEBUG_MMAP -- printf("munmap: start=0x%lx len=0x%lx\n", start, len); -+ printf("munmap: start=0x" TARGET_FMT_lx " len=0x" TARGET_FMT_lx "\n", start, len); - #endif - if (start & ~TARGET_PAGE_MASK) - return -EINVAL; -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -20,9 +20,13 @@ enum BSDType { - }; - extern enum BSDType bsd_type; - -+abi_long memcpy_to_target(abi_ulong dest, const void *src, -+ unsigned long len); -+ - #include "syscall_defs.h" - #include "syscall.h" -+#include "target_vmparam.h" - #include "target_signal.h" - #include "exec/gdbstub.h" - - #if defined(CONFIG_USE_NPTL) -@@ -61,7 +65,7 @@ struct image_info { - - struct sigqueue { - struct sigqueue *next; -- //target_siginfo_t info; -+ target_siginfo_t info; - }; - - struct emulated_sigtable { -@@ -88,6 +92,7 @@ typedef struct TaskState { - uint32_t stack_base; - #endif - struct image_info *info; -+ struct bsd_binprm *bprm; - - struct emulated_sigtable sigtab[TARGET_NSIG]; - struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ -@@ -98,6 +103,8 @@ typedef struct TaskState { - } __attribute__((aligned(16))) TaskState; - - void init_task_state(TaskState *ts); -+void task_settid(TaskState *); -+void stop_all_tasks(void); - extern const char *qemu_uname_release; - #if defined(CONFIG_USE_GUEST_BASE) - extern unsigned long mmap_min_addr; -@@ -115,7 +122,7 @@ extern unsigned long mmap_min_addr; - * This structure is used to hold the arguments that are - * used when loading binaries. - */ --struct linux_binprm { -+struct bsd_binprm { - char buf[128]; - void *page[MAX_ARG_PAGES]; - abi_ulong p; -@@ -125,21 +132,21 @@ struct linux_binprm { - char **argv; - char **envp; - char * filename; /* Name of binary */ -+ int (*core_dump)(int, const CPUArchState *); /* coredump routine */ - }; - - void do_init_thread(struct target_pt_regs *regs, struct image_info *infop); - abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, - abi_ulong stringp, int push_ptr); - int loader_exec(const char * filename, char ** argv, char ** envp, -- struct target_pt_regs * regs, struct image_info *infop); -+ struct target_pt_regs * regs, struct image_info *infop, -+ struct bsd_binprm *); - --int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, -+int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); --int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, -+int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); - --abi_long memcpy_to_target(abi_ulong dest, const void *src, -- unsigned long len); - void target_set_brk(abi_ulong new_brk); - abi_long do_brk(abi_ulong new_brk); - void syscall_init(void); -@@ -184,10 +191,12 @@ extern int do_strace; - /* signal.c */ - void process_pending_signals(CPUArchState *cpu_env); - void signal_init(void); --//int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info); --//void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); --//void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); --long do_sigreturn(CPUArchState *env); -+int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info); -+void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); -+void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); -+int target_to_host_signal(int sig); -+int host_to_target_signal(int sig); -+long do_sigreturn(CPUArchState *env, abi_ulong uc_addr); - long do_rt_sigreturn(CPUArchState *env); - abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); - -@@ -203,6 +212,7 @@ int target_msync(abi_ulong start, abi_ul - extern unsigned long last_brk; - void mmap_lock(void); - void mmap_unlock(void); -+abi_ulong mmap_find_vma(abi_ulong, abi_ulong); - void cpu_list_lock(void); - void cpu_list_unlock(void); - #if defined(CONFIG_USE_NPTL) -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index 445f69e..0502a6a 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -2,6 +2,7 @@ - * Emulation of BSD signals - * - * Copyright (c) 2003 - 2008 Fabrice Bellard -+ * Copyright (c) 2012 Stacey Son - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -23,16 +24,1218 @@ - #include <unistd.h> - #include <signal.h> - #include <errno.h> -+#include <sys/types.h> -+#include <sys/time.h> -+#include <sys/resource.h> - - #include "qemu.h" - #include "target_signal.h" - --//#define DEBUG_SIGNAL -+// #define DEBUG_SIGNAL - --void signal_init(void) -+#ifndef _NSIG -+#define _NSIG 128 -+#endif -+ -+static target_stack_t target_sigaltstack_used = { -+ .ss_sp = 0, -+ .ss_size = 0, -+ .ss_flags = TARGET_SS_DISABLE, -+}; -+ -+static uint8_t host_to_target_signal_table[_NSIG] = { -+ [SIGHUP] = TARGET_SIGHUP, -+ [SIGINT] = TARGET_SIGINT, -+ [SIGQUIT] = TARGET_SIGQUIT, -+ [SIGILL] = TARGET_SIGILL, -+ [SIGTRAP] = TARGET_SIGTRAP, -+ [SIGABRT] = TARGET_SIGABRT, -+ /* [SIGIOT] = TARGET_SIGIOT, */ -+ [SIGEMT] = TARGET_SIGEMT, -+ [SIGFPE] = TARGET_SIGFPE, -+ [SIGKILL] = TARGET_SIGKILL, -+ [SIGBUS] = TARGET_SIGBUS, -+ [SIGSEGV] = TARGET_SIGSEGV, -+ [SIGSYS] = TARGET_SIGSYS, -+ [SIGPIPE] = TARGET_SIGPIPE, -+ [SIGALRM] = TARGET_SIGALRM, -+ [SIGTERM] = TARGET_SIGTERM, -+ [SIGURG] = TARGET_SIGURG, -+ [SIGSTOP] = TARGET_SIGSTOP, -+ [SIGTSTP] = TARGET_SIGTSTP, -+ [SIGCONT] = TARGET_SIGCONT, -+ [SIGCHLD] = TARGET_SIGCHLD, -+ [SIGTTIN] = TARGET_SIGTTIN, -+ [SIGTTOU] = TARGET_SIGTTOU, -+ [SIGIO] = TARGET_SIGIO, -+ [SIGXCPU] = TARGET_SIGXCPU, -+ [SIGXFSZ] = TARGET_SIGXFSZ, -+ [SIGVTALRM] = TARGET_SIGVTALRM, -+ [SIGPROF] = TARGET_SIGPROF, -+ [SIGWINCH] = TARGET_SIGWINCH, -+ [SIGINFO] = TARGET_SIGINFO, -+ [SIGUSR1] = TARGET_SIGUSR1, -+ [SIGUSR2] = TARGET_SIGUSR2, -+#ifdef SIGTHR -+ [SIGTHR] = TARGET_SIGTHR, -+#endif -+ /* [SIGLWP] = TARGET_SIGLWP, */ -+#ifdef SIGLIBRT -+ [SIGLIBRT] = TARGET_SIGLIBRT, -+#endif -+ -+ /* -+ * The following signals stay the same. -+ * Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with -+ * host libpthread signals. This assumes no one actually uses -+ * SIGRTMAX. To fix this properly we need to manual signal delivery -+ * multiplexed over a single host signal. -+ */ -+ [SIGRTMIN] = SIGRTMAX, -+ [SIGRTMAX] = SIGRTMIN, -+}; -+ -+static uint8_t target_to_host_signal_table[_NSIG]; -+ -+static struct target_sigaction sigact_table[TARGET_NSIG]; -+ -+static void host_signal_handler(int host_signum, siginfo_t *info, void *puc); -+ -+static inline int -+on_sig_stack(unsigned long sp) -+{ -+ return (sp - target_sigaltstack_used.ss_sp -+ < target_sigaltstack_used.ss_size); -+} -+ -+static inline int -+sas_ss_flags(unsigned long sp) -+{ -+ return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE -+ : on_sig_stack(sp) ? SS_ONSTACK : 0); -+} -+ -+int -+host_to_target_signal(int sig) -+{ -+ -+ if (sig >= _NSIG) -+ return (sig); -+ return (host_to_target_signal_table[sig]); -+} -+ -+int -+target_to_host_signal(int sig) -+{ -+ -+ if (sig >= _NSIG) -+ return (sig); -+ return (target_to_host_signal_table[sig]); -+} -+ -+static inline void -+target_sigemptyset(target_sigset_t *set) - { -+ memset(set, 0, sizeof(*set)); - } - --void process_pending_signals(CPUArchState *cpu_env) -+static inline void -+target_sigaddset(target_sigset_t *set, int signum) - { -+ signum--; -+ uint32_t mask = (uint32_t)1 << (signum % TARGET_NSIG_BPW); -+ set->__bits[signum / TARGET_NSIG_BPW] |= mask; -+} -+ -+static inline int -+target_sigismember(const target_sigset_t *set, int signum) -+{ -+ signum--; -+ abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW); -+ return ((set->__bits[signum / TARGET_NSIG_BPW] & mask) != 0); -+} -+ -+static void -+host_to_target_sigset_internal(target_sigset_t *d, const sigset_t *s) -+{ -+ int i; -+ -+ target_sigemptyset(d); -+ for (i = 1; i <= TARGET_NSIG; i++) { -+ if (sigismember(s, i)) { -+ target_sigaddset(d, host_to_target_signal(i)); -+ } -+ } -+} -+ -+void -+host_to_target_sigset(target_sigset_t *d, const sigset_t *s) -+{ -+ target_sigset_t d1; -+ int i; -+ -+ host_to_target_sigset_internal(&d1, s); -+ for(i = 0;i < TARGET_NSIG_WORDS; i++) -+ d->__bits[i] = tswap32(d1.__bits[i]); -+} -+ -+static void -+target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s) -+{ -+ int i; -+ -+ sigemptyset(d); -+ for (i = 1; i <= TARGET_NSIG; i++) { -+ if (target_sigismember(s, i)) { -+ sigaddset(d, target_to_host_signal(i)); -+ } -+ } -+} -+ -+void -+target_to_host_sigset(sigset_t *d, const target_sigset_t *s) -+{ -+ target_sigset_t s1; -+ int i; -+ -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) -+ s1.__bits[i] = tswap32(s->__bits[i]); -+ target_to_host_sigset_internal(d, &s1); -+} -+ -+/* Siginfo conversion. */ -+static inline void -+host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) -+{ -+ int sig; -+ -+ sig = host_to_target_signal(info->si_signo); -+ tinfo->si_signo = sig; -+ tinfo->si_errno = info->si_errno; -+ tinfo->si_code = info->si_code; -+ tinfo->si_pid = info->si_pid; -+ tinfo->si_uid = info->si_uid; -+ tinfo->si_addr = (abi_ulong)(unsigned long)info->si_addr; -+ /* si_value is opaque to kernel */ -+ tinfo->si_value.sival_ptr = -+ (abi_ulong)(unsigned long)info->si_value.sival_ptr; -+ if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || -+ SIGBUS == sig || SIGTRAP == sig) { -+ tinfo->_reason._fault._trapno = info->_reason._fault._trapno; -+#ifdef SIGPOLL -+ } else if (SIGPOLL == sig) { -+ tinfo->_reason._poll._band = info->_reason._poll._band; -+#endif -+ } else { -+ tinfo->_reason._timer._timerid = info->_reason._timer._timerid; -+ tinfo->_reason._timer._overrun = info->_reason._timer._overrun; -+ } -+} -+ -+static void -+tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) -+{ -+ int sig; -+ sig = info->si_signo; -+ tinfo->si_signo = tswap32(sig); -+ tinfo->si_errno = tswap32(info->si_errno); -+ tinfo->si_code = tswap32(info->si_code); -+ tinfo->si_pid = tswap32(info->si_pid); -+ tinfo->si_uid = tswap32(info->si_uid); -+ tinfo->si_addr = tswapal(info->si_addr); -+ if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || -+ SIGBUS == sig || SIGTRAP == sig) { -+ tinfo->_reason._fault._trapno = -+ tswap32(info->_reason._fault._trapno); -+#ifdef SIGPOLL -+ } else if (SIGPOLL == sig) { -+ tinfo->_reason._poll._band = tswap32(info->_reason._poll._band); -+#endif -+ } else { -+ tinfo->_reason._timer._timerid = -+ tswap32(info->_reason._timer._timerid); -+ tinfo->_reason._timer._overrun = -+ tswap32(info->_reason._timer._overrun); -+ } -+} -+ -+void -+host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info) -+{ -+ -+ host_to_target_siginfo_noswap(tinfo, info); -+ tswap_siginfo(tinfo, tinfo); -+} -+ -+/* Returns 1 if given signal should dump core if not handled. */ -+static int -+core_dump_signal(int sig) -+{ -+ switch (sig) { -+ case TARGET_SIGABRT: -+ case TARGET_SIGFPE: -+ case TARGET_SIGILL: -+ case TARGET_SIGQUIT: -+ case TARGET_SIGSEGV: -+ case TARGET_SIGTRAP: -+ case TARGET_SIGBUS: -+ return (1); -+ default: -+ return (0); -+ } -+} -+ -+/* Signal queue handling. */ -+static inline struct sigqueue * -+alloc_sigqueue(CPUArchState *env) -+{ -+ TaskState *ts = env->opaque; -+ struct sigqueue *q = ts->first_free; -+ -+ if (!q) -+ return (NULL); -+ ts->first_free = q->next; -+ return (q); -+} -+ -+static inline void -+free_sigqueue(CPUArchState *env, struct sigqueue *q) -+{ -+ -+ TaskState *ts = env->opaque; -+ q->next = ts->first_free; -+ ts->first_free = q; -+} -+ -+/* Abort execution with signal. */ -+static void QEMU_NORETURN -+force_sig(int target_sig) -+{ -+ TaskState *ts = (TaskState *)thread_env->opaque; -+ int host_sig, core_dumped = 0; -+ struct sigaction act; -+ -+ host_sig = target_to_host_signal(target_sig); -+ gdb_signalled(thread_env, target_sig); -+ -+ /* Dump core if supported by target binary format */ -+ if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) { -+ stop_all_tasks(); -+ core_dumped = -+ ((*ts->bprm->core_dump)(target_sig, thread_env) == 0); -+ } -+ if (core_dumped) { -+ struct rlimit nodump; -+ -+ /* -+ * We already dumped the core of target process, we don't want -+ * a coredump of qemu itself. -+ */ -+ getrlimit(RLIMIT_CORE, &nodump); -+ nodump.rlim_cur = 0; -+ (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) " -+ "- %s\n", target_sig, strsignal(host_sig), "core dumped"); -+ } -+ -+ /* -+ * The proper exit code for dying from an uncaught signal is -+ * -<signal>. The kernel doesn't allow exit() or _exit() to pass -+ * a negative value. To get the proper exit code we need to -+ * actually die from an uncaught signal. Here the default signal -+ * handler is installed, we send ourself a signal and we wait for -+ * it to arrive. -+ */ -+ memset(&act, 0, sizeof(act)); -+ sigfillset(&act.sa_mask); -+ act.sa_handler = SIG_DFL; -+ sigaction(host_sig, &act, NULL); -+ -+ kill(getpid(), host_sig); -+ -+ /* -+ * Make sure the signal isn't masked (just reuse the mask inside -+ * of act). -+ */ -+ sigdelset(&act.sa_mask, host_sig); -+ sigsuspend(&act.sa_mask); -+ -+ /* unreachable */ -+ abort(); -+} -+ -+/* -+ * Queue a signal so that it will be send to the virtual CPU as soon as -+ * possible. -+ */ -+int -+queue_signal(CPUArchState *env, int sig, target_siginfo_t *info) -+{ -+ TaskState *ts = env->opaque; -+ struct emulated_sigtable *k; -+ struct sigqueue *q, **pq; -+ abi_ulong handler; -+ int queue; -+ -+ k = &ts->sigtab[sig - 1]; -+ queue = gdb_queuesig (); -+ handler = sigact_table[sig - 1]._sa_handler; -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "queue_signal: sig=%d handler=0x%lx flags=0x%x\n", sig, -+ handler, (uint32_t)sigact_table[sig - 1].sa_flags); -+#endif -+ if (!queue && (TARGET_SIG_DFL == handler)) { -+ if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || -+ sig == TARGET_SIGTTOU) { -+ kill(getpid(), SIGSTOP); -+ return (0); -+ } else { -+ if (sig != TARGET_SIGCHLD && -+ sig != TARGET_SIGURG && -+ sig != TARGET_SIGWINCH && -+ sig != TARGET_SIGCONT) { -+ force_sig(sig); -+ } else { -+ return (0); /* The signal was ignored. */ -+ } -+ } -+ } else if (!queue && (TARGET_SIG_IGN == handler)) { -+ return (0); /* Ignored signal. */ -+ } else if (!queue && (TARGET_SIG_ERR == handler)) { -+ force_sig(sig); -+ } else { -+ pq = &k->first; -+ -+ /* -+ * FreeBSD signals are always queued. -+ * Linux only queues real time signals. -+ * XXX this code is not thread safe. -+ */ -+ if (!k->pending) { -+ /* first signal */ -+ q = &k->info; -+ } else { -+ q = alloc_sigqueue(env); -+ if (!q) -+ return (-EAGAIN); -+ while (*pq != NULL) -+ pq = &(*pq)->next; -+ } -+ *pq = q; -+ q->info = *info; -+ q->next = NULL; -+ k->pending = 1; -+ /* Signal that a new signal is pending. */ -+ ts->signal_pending = 1; -+ return (1); /* Indicates that the signal was queued. */ -+ } -+} -+ -+static void -+host_signal_handler(int host_signum, siginfo_t *info, void *puc) -+{ -+ int sig; -+ target_siginfo_t tinfo; -+ -+ /* -+ * The CPU emulator uses some host signal to detect exceptions so -+ * we forward to it some signals. -+ */ -+ if ((host_signum == SIGSEGV || host_signum == SIGBUS) && -+ info->si_code > 0) { -+ if (cpu_signal_handler(host_signum, info, puc)) -+ return; -+ } -+ -+ /* Get the target signal number. */ -+ sig = host_to_target_signal(host_signum); -+ if (sig < 1 || sig > TARGET_NSIG) -+ return; -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: got signal %d\n", sig); -+#endif -+ host_to_target_siginfo_noswap(&tinfo, info); -+ if (queue_signal(thread_env, sig, &tinfo) == 1) { -+ /* Interrupt the virtual CPU as soon as possible. */ -+ cpu_exit(thread_env); -+ } -+} -+ -+/* do_sigaltstack() returns target values and errnos. */ -+/* compare to kern/kern_sig.c sys_sigaltstack() and kern_sigaltstack() */ -+abi_long -+do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp) -+{ -+ int ret = 0; -+ target_stack_t ss, oss, *uss; -+ -+ if (uoss_addr) { -+ /* Save current signal stack params */ -+ oss.ss_sp = tswapl(target_sigaltstack_used.ss_sp); -+ oss.ss_size = tswapl(target_sigaltstack_used.ss_size); -+ oss.ss_flags = tswapl(sas_ss_flags(sp)); -+ } -+ -+ if (uss_addr) { -+ -+ if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1) || -+ __get_user(ss.ss_sp, &uss->ss_sp) || -+ __get_user(ss.ss_size, &uss->ss_size) || -+ __get_user(ss.ss_flags, &uss->ss_flags)) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ unlock_user_struct(uss, uss_addr, 0); -+ -+ if (on_sig_stack(sp)) { -+ ret = -TARGET_EPERM; -+ goto out; -+ } -+ -+ if ((ss.ss_flags & ~TARGET_SS_DISABLE) != 0) { -+ ret = -TARGET_EINVAL; -+ goto out; -+ } -+ -+ if (!(ss.ss_flags & ~TARGET_SS_DISABLE)) { -+ if (ss.ss_size < TARGET_MINSIGSTKSZ) { -+ ret = -TARGET_ENOMEM; -+ goto out; -+ } -+ } else { -+ ss.ss_size = 0; -+ ss.ss_sp = 0; -+ } -+ -+ target_sigaltstack_used.ss_sp = ss.ss_sp; -+ target_sigaltstack_used.ss_size = ss.ss_size; -+ } -+ -+ if (uoss_addr) { -+ /* Copy out to user saved signal stack params */ -+ if (copy_to_user(uoss_addr, &oss, sizeof(oss))) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ } -+ -+out: -+ return (ret); -+} -+ -+static int -+fatal_signal(int sig) -+{ -+ -+ switch (sig) { -+ case TARGET_SIGCHLD: -+ case TARGET_SIGURG: -+ case TARGET_SIGWINCH: -+ /* Ignored by default. */ -+ return (0); -+ case TARGET_SIGCONT: -+ case TARGET_SIGSTOP: -+ case TARGET_SIGTSTP: -+ case TARGET_SIGTTIN: -+ case TARGET_SIGTTOU: -+ /* Job control signals. */ -+ return (0); -+ default: -+ return (1); -+ } -+} -+ -+/* do_sigaction() return host values and errnos */ -+int -+do_sigaction(int sig, const struct target_sigaction *act, -+ struct target_sigaction *oact) -+{ -+ struct target_sigaction *k; -+ struct sigaction act1; -+ int host_sig; -+ int ret = 0; -+ -+ if (sig < 1 || sig > TARGET_NSIG || TARGET_SIGKILL == sig || -+ TARGET_SIGSTOP == sig) -+ return (-EINVAL); -+ k = &sigact_table[sig - 1]; -+#if defined(DEBUG_SIGNAL) -+ fprintf(stderr, "do_sigaction sig=%d act=%p, oact=%p\n", -+ sig, act, oact); -+#endif -+ if (oact) { -+ oact->_sa_handler = tswapal(k->_sa_handler); -+ oact->sa_flags = tswap32(k->sa_flags); -+ oact->sa_mask = k->sa_mask; -+ } -+ if (act) { -+ /* XXX: this is most likely not threadsafe. */ -+ k->_sa_handler = tswapal(act->_sa_handler); -+ k->sa_flags = tswap32(act->sa_flags); -+ k->sa_mask = act->sa_mask; -+ -+ /* Update the host signal state. */ -+ host_sig = target_to_host_signal(sig); -+ if (host_sig != SIGSEGV && host_sig != SIGBUS) { -+ memset(&act1, 0, sizeof(struct sigaction)); -+ sigfillset(&act1.sa_mask); -+ if (k->sa_flags & TARGET_SA_RESTART) -+ act1.sa_flags |= SA_RESTART; -+ /* -+ * Note: It is important to update the host kernel -+ * signal mask to avoid getting unexpected interrupted -+ * system calls. -+ */ -+ if (k->_sa_handler == TARGET_SIG_IGN) { -+ act1.sa_sigaction = (void *)SIG_IGN; -+ } else if (k->_sa_handler == TARGET_SIG_DFL) { -+ if (fatal_signal(sig)) -+ act1.sa_sigaction = -+ host_signal_handler; -+ else -+ act1.sa_sigaction = (void *)SIG_DFL; -+ } else { -+ act1.sa_flags = SA_SIGINFO; -+ act1.sa_sigaction = host_signal_handler; -+ } -+ ret = sigaction(host_sig, &act1, NULL); -+#if defined(DEBUG_SIGNAL) -+ fprintf(stderr, "sigaction (action = %p (host_signal_handler = %p)) returned: %d\n", act1.sa_sigaction, host_signal_handler, ret); -+#endif -+ } -+ } -+ return (ret); -+} -+ -+#if defined(TARGET_MIPS64) -+static inline int -+restore_sigmcontext(CPUMIPSState *regs, target_mcontext_t *mc) -+{ -+ int i, err = 0; -+ -+ for(i = 1; i < 32; i++) -+ err |= __get_user(regs->active_tc.gpr[i], -+ &mc->mc_regs[i]); -+ err |= __get_user(regs->CP0_EPC, &mc->mc_pc); -+ err |= __get_user(regs->active_tc.LO[0], &mc->mullo); -+ err |= __get_user(regs->active_tc.HI[0], &mc->mulhi); -+ err |= __get_user(regs->tls_value, &mc->mc_tls); /* XXX thread tls */ -+ -+#if 0 /* XXX */ -+ int used_fp = 0; -+ -+ err |= __get_user(used_fp, &mc->mc_fpused); -+ conditional_used_math(used_fp); -+ -+ preempt_disabled(); -+ if (used_math()) { -+ /* restore fpu context if we have used it before */ -+ own_fpu(); -+ err |= restore_fp_context(mc); -+ } else { -+ /* signal handler may have used FPU. Give it up. */ -+ lose_fpu(); -+ } -+ preempt_enable(); -+#endif -+ -+ return (err); -+} -+ -+static inline int -+setup_sigmcontext(CPUMIPSState *regs, target_mcontext_t *mc, int32_t oonstack) -+{ -+ int i, err = 0; -+ abi_long ucontext_magic = TARGET_UCONTEXT_MAGIC; -+ -+ err = __put_user(oonstack ? 1 : 0, &mc->mc_onstack); -+ err |= __put_user(regs->active_tc.PC, &mc->mc_pc); -+ err |= __put_user(regs->active_tc.LO[0], &mc->mullo); -+ err |= __put_user(regs->active_tc.HI[0], &mc->mulhi); -+ err |= __put_user(regs->tls_value, &mc->mc_tls); /* XXX thread tls */ -+ -+ err |= __put_user(ucontext_magic, &mc->mc_regs[0]); -+ for(i = 1; i < 32; i++) -+ err |= __put_user(regs->active_tc.gpr[i], &mc->mc_regs[i]); -+ -+ err |= __put_user(0, &mc->mc_fpused); -+ -+#if 0 /* XXX */ -+ err |= __put_user(used_math(), &mc->mc_fpused); -+ if (used_math()) -+ goto out; -+ -+ /* -+ * Save FPU state to signal context. Signal handler will "inherit" -+ * current FPU state. -+ */ -+ preempt_disable(); -+ -+ if (!is_fpu_owner()) { -+ own_fpu(); -+ for(i = 0; i < 33; i++) -+ err |= __put_user(regs->active_tc.fpregs[i], &mc->mc_fpregs[i]); -+ } -+ err |= save_fp_context(fg); -+ -+ preempt_enable(); -+out: -+#endif -+ return (err); -+} -+ -+static inline abi_ulong -+get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size) -+{ -+ abi_ulong sp; -+ -+ /* Use default user stack */ -+ sp = regs->active_tc.gpr[29]; -+ -+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { -+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; -+ } -+ -+ return ((sp - frame_size) & ~7); -+} -+ -+/* compare to mips/mips/pm_machdep.c sendsig() */ -+static void setup_frame(int sig, struct target_sigaction *ka, -+ target_sigset_t *set, CPUMIPSState *regs) -+{ -+ struct target_sigframe *frame; -+ abi_ulong frame_addr; -+ int i; -+ -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "setup_frame()\n"); -+#endif -+ -+ frame_addr = get_sigframe(ka, regs, sizeof(*frame)); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) -+ goto give_sigsegv; -+ -+ if (setup_sigmcontext(regs, &frame->sf_uc.uc_mcontext, -+ ! on_sig_stack(frame_addr))) -+ goto give_sigsegv; -+ -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) { -+ if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i])) -+ goto give_sigsegv; -+ } -+ -+ /* fill in sigframe structure */ -+ if (__put_user(sig, &frame->sf_signum)) -+ goto give_sigsegv; -+ if (__put_user(0, &frame->sf_siginfo)) -+ goto give_sigsegv; -+ if (__put_user(0, &frame->sf_ucontext)) -+ goto give_sigsegv; -+ -+ /* fill in siginfo structure */ -+ if (__put_user(sig, &frame->sf_si.si_signo)) -+ goto give_sigsegv; -+ if (__put_user(TARGET_SA_SIGINFO, &frame->sf_si.si_code)) -+ goto give_sigsegv; -+ if (__put_user(regs->CP0_BadVAddr, &frame->sf_si.si_addr)) -+ goto give_sigsegv; -+ -+ /* -+ * Arguments to signal handler: -+ * a0 ($4) = signal number -+ * a1 ($5) = siginfo pointer -+ * a2 ($6) = ucontext pointer -+ * PC = signal handler pointer -+ * t9 ($25) = signal handler pointer -+ * $29 = point to sigframe struct -+ * ra ($31) = sigtramp at base of user stack -+ */ -+ regs->active_tc.gpr[ 4] = sig; -+ regs->active_tc.gpr[ 5] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->active_tc.gpr[ 6] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; -+ regs->active_tc.gpr[29] = frame_addr; -+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ unlock_user_struct(frame, frame_addr, 1); -+ return; -+ -+give_sigsegv: -+ unlock_user_struct(frame, frame_addr, 1); -+ force_sig(TARGET_SIGSEGV); -+} -+ -+long -+do_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr) -+{ -+ target_ucontext_t *ucontext; -+ sigset_t blocked; -+ target_sigset_t target_set; -+ int i; -+ -+#if defined(DEBUG_SIGNAL) -+ fprintf(stderr, "do_sigreturn\n"); -+#endif -+ if (!lock_user_struct(VERIFY_READ, ucontext, uc_addr, 1)) -+ goto badframe; -+ -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) { -+ if (__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i])) -+ goto badframe; -+ } -+ -+ if (restore_sigmcontext(regs, &ucontext->uc_mcontext)) -+ goto badframe; -+ -+ target_to_host_sigset_internal(&blocked, &target_set); -+ sigprocmask(SIG_SETMASK, &blocked, NULL); -+ -+ regs->active_tc.PC = regs->CP0_EPC; -+ regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+ return (-TARGET_QEMU_ESIGRETURN); -+ -+badframe: -+ force_sig(TARGET_SIGSEGV); -+ return (0); -+} -+ -+#elif defined(TARGET_SPARC64) -+ -+extern abi_ulong sparc_user_sigtramp; -+ -+#define mc_flags mc_global[0] -+#define mc_sp mc_out[6] -+#define mc_fprs mc_local[0] -+#define mc_fsr mc_local[1] -+#define mc_qsr mc_local[2] -+#define mc_tnpc mc_in[0] -+#define mc_tpc mc_in[1] -+#define mc_tstate mc_in[2] -+#define mc_y mc_in[4] -+#define mc_wstate mc_in[5] -+ -+#define ureg_i0 regwptr[0 ] -+#define ureg_i1 regwptr[1 ] -+#define ureg_i2 regwptr[2 ] -+#define ureg_i3 regwptr[3 ] -+#define ureg_i4 regwptr[4 ] -+#define ureg_i5 regwptr[5 ] -+#define ureg_i6 regwptr[6 ] -+#define ureg_i7 regwptr[7 ] -+#define ureg_l0 regwptr[8 ] -+#define ureg_l1 regwptr[9 ] -+#define ureg_l2 regwptr[10] -+#define ureg_l3 regwptr[11] -+#define ureg_l4 regwptr[12] -+#define ureg_l5 regwptr[13] -+#define ureg_l6 regwptr[14] -+#define ureg_l7 regwptr[15] -+#define ureg_o0 regwptr[16] -+#define ureg_o1 regwptr[17] -+#define ureg_o2 regwptr[18] -+#define ureg_o3 regwptr[19] -+#define ureg_o4 regwptr[20] -+#define ureg_o5 regwptr[21] -+#define ureg_o6 regwptr[22] -+#define ureg_o7 regwptr[23] -+#define ureg_fp ureg_i6 -+#define ureg_sp ureg_o6 -+#define ureg_tnpc ureg_i0 -+#define ureg_tpc ureg_i1 -+ -+#define TARGET_FPRS_FEF (1 << 2) -+#define TARGET_MC_VERSION 1L -+ -+/* compare to sparc64/sparc64/machdep.c set_mcontext() */ -+static inline int -+restore_sigmcontext(CPUSPARCState *regs, target_mcontext_t *mc) -+{ -+ int err = 0; -+ -+ err |= __get_user(regs->gregs[1], &mc->mc_global[1]); -+ err |= __get_user(regs->gregs[2], &mc->mc_global[2]); -+ err |= __get_user(regs->gregs[3], &mc->mc_global[3]); -+ err |= __get_user(regs->gregs[4], &mc->mc_global[4]); -+ err |= __get_user(regs->gregs[5], &mc->mc_global[5]); -+ err |= __get_user(regs->gregs[6], &mc->mc_global[6]); -+ -+ err |= __get_user(regs->ureg_o0, &mc->mc_out[0]); -+ err |= __get_user(regs->ureg_o1, &mc->mc_out[1]); -+ err |= __get_user(regs->ureg_o2, &mc->mc_out[2]); -+ err |= __get_user(regs->ureg_o3, &mc->mc_out[3]); -+ err |= __get_user(regs->ureg_o4, &mc->mc_out[4]); -+ err |= __get_user(regs->ureg_o5, &mc->mc_out[5]); -+ err |= __get_user(regs->ureg_o6, &mc->mc_out[6]); -+ err |= __get_user(regs->ureg_o7, &mc->mc_out[0]); -+ -+ err |= __get_user(regs->ureg_l0, &mc->mc_fprs); /* mc_local[0] */ -+ err |= __get_user(regs->ureg_l1, &mc->mc_fsr); /* mc_local[1] */ -+ err |= __get_user(regs->ureg_l2, &mc->mc_qsr); /* mc_local[2] */ -+ -+ err |= __get_user(regs->ureg_i0, &mc->mc_tnpc); /* mc_in[0] */ -+ err |= __get_user(regs->ureg_i1, &mc->mc_tpc); /* mc_in[1] */ -+ err |= __get_user(regs->ureg_i2, &mc->mc_tstate);/* mc_in[2] */ -+ -+ err |= __get_user(regs->ureg_i4, &mc->mc_y); /* mc_in[4] */ -+ -+ /* XXX -+ if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) { -+ regs->ureg_l0 = 0; -+ for(i = 0; i < 64; i++) -+ err |= __get_user(regs->fpr[i], &mc->mc_fp[i]); -+ } -+ */ -+ -+ return (err); -+} -+ -+/* compare to sparc64/sparc64/machdep.c get_mcontext() */ -+static inline int -+setup_sigmcontext(CPUSPARCState *regs, target_mcontext_t *mc) -+{ -+ int err = 0; -+ abi_ulong ver = TARGET_MC_VERSION; -+ -+ err |= __put_user(ver, &mc->mc_flags); /* aka. mc_global[0] */ -+ err |= __put_user(regs->gregs[1], &mc->mc_global[1]); -+ err |= __put_user(regs->gregs[2], &mc->mc_global[2]); -+ err |= __put_user(regs->gregs[3], &mc->mc_global[3]); -+ err |= __put_user(regs->gregs[4], &mc->mc_global[4]); -+ err |= __put_user(regs->gregs[5], &mc->mc_global[5]); -+ err |= __put_user(regs->gregs[6], &mc->mc_global[6]); -+ /* skip %g7 since it is used as the userland TLS register */ -+ -+ err |= __put_user(regs->ureg_o0, &mc->mc_out[0]); -+ err |= __put_user(regs->ureg_o1, &mc->mc_out[1]); -+ err |= __put_user(regs->ureg_o2, &mc->mc_out[2]); -+ err |= __put_user(regs->ureg_o3, &mc->mc_out[3]); -+ err |= __put_user(regs->ureg_o4, &mc->mc_out[4]); -+ err |= __put_user(regs->ureg_o5, &mc->mc_out[5]); -+ err |= __put_user(regs->ureg_o6, &mc->mc_out[6]); -+ err |= __put_user(regs->ureg_o7, &mc->mc_out[7]); -+ -+ err |= __put_user(regs->ureg_l0, &mc->mc_fprs); /* mc_local[0] */ -+ err |= __put_user(regs->ureg_l1, &mc->mc_fsr); /* mc_local[1] */ -+ err |= __put_user(regs->ureg_l2, &mc->mc_qsr); /* mc_local[2] */ -+ -+ err |= __put_user(regs->ureg_i0, &mc->mc_tnpc); /* mc_in[0] */ -+ err |= __put_user(regs->ureg_i1, &mc->mc_tpc); /* mc_in[1] */ -+ err |= __put_user(regs->ureg_i2, &mc->mc_tstate);/* mc_in[2] */ -+ -+ err |= __put_user(regs->ureg_i4, &mc->mc_y); /* mc_in[4] */ -+ -+ /* XXX -+ if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) { -+ for(i = 0; i < 64; i++) -+ err |= __put_user(regs->fpr[i], &mc->mc_fp[i]); -+ } -+ */ -+ -+ return (err); -+} -+ -+static inline abi_ulong -+get_sigframe(struct target_sigaction *ka, CPUSPARCState *regs, size_t frame_size) -+{ -+ abi_ulong sp; -+ -+ /* Use default user stack */ -+ sp = regs->ureg_sp; -+ -+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { -+ sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; -+ } -+ -+ return (sp - frame_size); -+} -+ -+/* compare to sparc64/sparc64/machdep.c sendsig() */ -+static void setup_frame(int sig, struct target_sigaction *ka, -+ target_sigset_t *set, CPUSPARCState *regs) -+{ -+ struct target_sigframe *frame; -+ abi_ulong frame_addr; -+ int i; -+ -+ if (!sparc_user_sigtramp) { -+ /* No signal trampoline... kill the process. */ -+ fprintf(stderr, "setup_frame(): no sigtramp\n"); -+ force_sig(TARGET_SIGKILL); -+ } -+ -+ frame_addr = get_sigframe(ka, regs, sizeof(*frame)); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) -+ goto give_sigsegv; -+ -+ if (setup_sigmcontext(regs, &frame->sf_uc.uc_mcontext)) -+ goto give_sigsegv; -+ -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) { -+ if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i])) -+ goto give_sigsegv; -+ } -+ -+ /* Fill in siginfo structure */ -+ if (__put_user(sig, &frame->sf_si.si_signo)) -+ goto give_sigsegv; -+ if (__put_user(TARGET_SA_SIGINFO, &frame->sf_si.si_code)) -+ goto give_sigsegv; -+ -+ /* Arguments to signal handler: -+ * -+ * o0 = signal number -+ * o1 = pointer to siginfo struct -+ * o2 = pointer to ucontext struct -+ * o3 = (not used in new style) -+ * o4 = signal handler address (called by sigtramp) -+ */ -+ regs->ureg_o0 = sig; -+ regs->ureg_o1 = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->ureg_o2 = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ /* env->ureg_o3 used in the Old FreeBSD-style arguments. */ -+ regs->ureg_o4 = ka->_sa_handler; -+ -+ regs->ureg_tpc = sparc_user_sigtramp; -+ regs->ureg_tnpc = (regs->ureg_tpc + 4); -+ regs->ureg_sp = frame_addr - 2047 /* SPOFF */; -+ unlock_user_struct(frame, frame_addr, 1); -+ return; -+ -+give_sigsegv: -+ unlock_user_struct(frame, frame_addr, 1); -+ force_sig(TARGET_SIGSEGV); -+} -+ -+ -+long do_sigreturn(CPUSPARCState *regs, abi_ulong uc_addr) -+{ -+ target_ucontext_t *ucontext; -+ sigset_t blocked; -+ target_sigset_t target_set; -+ int i; -+ -+#if defined(DEBUG_SIGNAL) -+ fprintf(stderr, "do_sigreturn\n"); -+#endif -+ if (!lock_user_struct(VERIFY_READ, ucontext, uc_addr, 1)) -+ goto badframe; -+ -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) { -+ if (__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i])) -+ goto badframe; -+ } -+ -+ if (restore_sigmcontext(regs, &ucontext->uc_mcontext)) -+ goto badframe; -+ -+ target_to_host_sigset_internal(&blocked, &target_set); -+ sigprocmask(SIG_SETMASK, &blocked, NULL); -+ -+ return (-TARGET_QEMU_ESIGRETURN); -+ -+badframe: -+ force_sig(TARGET_SIGSEGV); -+ return (0); -+} -+ -+#else -+ -+static void -+setup_frame(int sig, struct target_sigaction *ka, target_sigset_t *set, -+ CPUArchState *env) -+{ -+ fprintf(stderr, "setup_frame: not implemented\n"); -+} -+ -+#if 0 -+static void -+setup_rt_frame(int sig, struct target_sigaction *ka, target_siginfo_t *info, -+ target_sigset_t *set, CPUArchState *env) -+{ -+ fprintf(stderr, "setup_rt_frame: not implemented\n"); -+} -+#endif -+ -+long -+do_sigreturn(CPUArchState *env, abi_ulong uc_addr) -+{ -+ fprintf(stderr,"do_sigreturn: not implemented\n"); -+ return (-TARGET_ENOSYS); -+} -+ -+long -+do_rt_sigreturn(CPUArchState *env) -+{ -+ fprintf(stderr, "do_rt_sigreturn: not implemented\n"); -+ return (-TARGET_ENOSYS); -+} -+#endif -+ -+void -+signal_init(void) -+{ -+ struct sigaction act; -+ struct sigaction oact; -+ int i, j; -+ int host_sig; -+ -+ /* Generate the signal conversion tables. */ -+ for(i = 1; i < _NSIG; i++) { -+ if (host_to_target_signal_table[i] == 0) -+ host_to_target_signal_table[i] = i; -+ } -+ for(i = 1; i < _NSIG; i++) { -+ j = host_to_target_signal_table[i]; -+ target_to_host_signal_table[j] = i; -+ } -+ -+ /* -+ * Set all host signal handlers. ALL signals are blocked during the -+ * handlers to serialize them. -+ */ -+ memset(sigact_table, 0, sizeof(sigact_table)); -+ -+ sigfillset(&act.sa_mask); -+ act.sa_sigaction = host_signal_handler; -+ -+ for (i = 1; i <= TARGET_NSIG; i++) { -+ host_sig = target_to_host_signal(i); -+ sigaction(host_sig, NULL, &oact); -+ if (oact.sa_sigaction == (void *)SIG_IGN) { -+ sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN; -+ } else if (oact.sa_sigaction == (void *)SIG_DFL) { -+ sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL; -+ } -+ /* -+ * If there's already a handler installed then something has -+ * gone horribly wrong, so don't even try to handle that case. -+ * Install some handlers for our own use. We need at least -+ * SIGSEGV and SIGBUS, to detect exceptions. We can not just -+ * trap all signals because it affects syscall interrupt -+ * behavior. But do trap all default-fatal signals. -+ */ -+ if (fatal_signal(i)) { -+ sigaction(host_sig, &act, NULL); -+ } -+ } -+} -+ -+void -+process_pending_signals(CPUArchState *cpu_env) -+{ -+ int sig; -+ abi_ulong handler; -+ sigset_t set, old_set; -+ target_sigset_t target_old_set; -+ struct emulated_sigtable *k; -+ struct target_sigaction *sa; -+ struct sigqueue *q; -+ TaskState *ts = cpu_env->opaque; -+ -+ if (!ts->signal_pending) -+ return; -+ -+ /* FIXME: This is not threadsafe. */ -+ k = ts->sigtab; -+ for(sig = 1; sig <= TARGET_NSIG; sig++) { -+ if (k->pending) -+ goto handle_signal; -+ k++; -+ } -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: process_pending_signals has no signals\n"); -+#endif -+ /* If no signal is pending then just return. */ -+ ts->signal_pending = 0; -+ return; -+ -+handle_signal: -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: process signal %d\n", sig); -+#endif -+ -+ /* Dequeue signal. */ -+ q = k->first; -+ k->first = q->next; -+ if (!k->first) -+ k->pending = 0; -+ -+ sig = gdb_handlesig (cpu_env, sig); -+ if (!sig) { -+ sa = NULL; -+ handler = TARGET_SIG_IGN; -+ } else { -+ sa = &sigact_table[sig - 1]; -+ handler = sa->_sa_handler; -+ } -+ -+ if (handler == TARGET_SIG_DFL) { -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: TARGET_SIG_DFL\n"); -+#endif -+ /* -+ * default handler : ignore some signal. The other are job -+ * control or fatal. -+ */ -+ if (TARGET_SIGTSTP == sig || TARGET_SIGTTIN == sig || -+ TARGET_SIGTTOU == sig) { -+ kill(getpid(),SIGSTOP); -+ } else if (TARGET_SIGCHLD != sig && TARGET_SIGURG != sig && -+ TARGET_SIGWINCH != sig && TARGET_SIGCONT != sig) { -+ force_sig(sig); -+ } -+ } else if (TARGET_SIG_IGN == handler) { -+ /* ignore sig */ -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: TARGET_SIG_IGN\n"); -+#endif -+ } else if (TARGET_SIG_ERR == handler) { -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: TARGET_SIG_ERR\n"); -+#endif -+ force_sig(sig); -+ } else { -+ /* compute the blocked signals during the handler execution */ -+ target_to_host_sigset(&set, &sa->sa_mask); -+ /* -+ * SA_NODEFER indicates that the current signal should not be -+ * blocked during the handler. -+ */ -+ if (!(sa->sa_flags & TARGET_SA_NODEFER)) -+ sigaddset(&set, target_to_host_signal(sig)); -+ -+ /* block signals in the handler */ -+ sigprocmask(SIG_BLOCK, &set, &old_set); -+ -+ /* -+ * Save the previous blocked signal state to restore it at the -+ * end of the signal execution (see do_sigreturn). -+ */ -+ host_to_target_sigset_internal(&target_old_set, &old_set); -+ -+#if 0 -+#if defined(TARGET_I386) && !defined(TARGET_X86_64) -+ /* if the CPU is in VM86 mode, we restore the 32 bit values */ -+ { -+ CPUX86State *env = cpu_env; -+ if (env->eflags & VM_MASK) -+ save_v86_state(env); -+ } -+#endif -+#endif -+ /* prepare the stack frame of the virtual CPU */ -+#if 0 /* XXX no rt for fbsd */ -+ if (sa->sa_flags & TARGET_SA_SIGINFO) -+ setup_rt_frame(sig, sa, &q->info, &target_old_set, -+ cpu_env); -+ else -+#endif -+ setup_frame(sig, sa, &target_old_set, cpu_env); -+ if (sa->sa_flags & TARGET_SA_RESETHAND) -+ sa->_sa_handler = TARGET_SIG_DFL; -+ } -+ if (q != &k->info) -+ free_sigqueue(cpu_env, q); - } -diff --git a/bsd-user/socket.h b/bsd-user/socket.h -new file mode 100644 -index 0000000..c9e019b ---- /dev/null -+++ b/bsd-user/socket.h -@@ -0,0 +1,66 @@ -+/* -+ * Target socket definitions. -+ */ -+ -+/* -+ * Types -+ */ -+#define TARGET_SOCK_STREAM 1 /* stream socket */ -+#define TARGET_SOCK_DGRAM 2 /* datagram socket */ -+#define TARGET_SOCK_RAW 3 /* raw-protocol interface */ -+#define TARGET_SOCK_RDM 4 /* reliably-delivered message */ -+#define TARGET_SOCK_SEQPACKET 5 /* sequenced packet stream */ -+ -+ -+/* -+ * Option flags per-socket. -+ */ -+ -+#define TARGET_SO_DEBUG 0x0001 /* turn on debugging info recording */ -+#define TARGET_SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -+#define TARGET_SO_REUSEADDR 0x0004 /* allow local address reuse */ -+#define TARGET_SO_KEEPALIVE 0x0008 /* keep connections alive */ -+#define TARGET_SO_DONTROUTE 0x0010 /* just use interface addresses */ -+#define TARGET_SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ -+#define TARGET_SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ -+#define TARGET_SO_LINGER 0x0080 /* linger on close if data present */ -+#define TARGET_SO_OOBINLINE 0x0100 /* leave received OOB data in line */ -+#define TARGET_SO_REUSEPORT 0x0200 /* allow local address & port reuse */ -+#define TARGET_SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */ -+#define TARGET_SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */ -+#define TARGET_SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ -+#define TARGET_SO_BINTIME 0x2000 /* timestamp received dgram traffic */ -+#define TARGET_SO_NO_OFFLOAD 0x4000 /* socket cannot be offloaded */ -+#define TARGET_SO_NO_DDP 0x8000 /* disable direct data placement */ -+ -+/* -+ * Additional options, not kept in so_options. -+ */ -+#define TARGET_SO_SNDBUF 0x1001 /* send buffer size */ -+#define TARGET_SO_RCVBUF 0x1002 /* receive buffer size */ -+#define TARGET_SO_SNDLOWAT 0x1003 /* send low-water mark */ -+#define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */ -+#define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ -+#define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ -+#define TARGET_SO_ERROR 0x1007 /* get error status and clear */ -+#define TARGET_SO_TYPE 0x1008 /* get socket type */ -+#define TARGET_SO_LABEL 0x1009 /* socket's MAC label */ -+#define TARGET_SO_PEERLABEL 0x1010 /* socket's peer's MAC label */ -+#define TARGET_SO_LISTENQLIMIT 0x1011 /* socket's backlog limit */ -+#define TARGET_SO_LISTENQLEN 0x1012 /* socket's complete queue length */ -+#define TARGET_SO_LISTENINCQLEN 0x1013 /* socket's incomplete queue length */ -+#define TARGET_SO_SETFIB 0x1014 /* use this FIB to route */ -+#define TARGET_SO_USER_COOKIE 0x1015 /* user cookie (dummynet etc.) */ -+#define TARGET_SO_PROTOCOL 0x1016 /* get socket protocol (Linux name) */ -+ -+/* alias for SO_PROTOCOL (SunOS name) */ -+#define TARGET_SO_PROTOTYPE TARGET_SO_PROTOCOL -+ -+/* -+ * Level number for (get/set)sockopt() to apply to socket itself. -+ */ -+#define TARGET_SOL_SOCKET 0xffff /* options for socket level */ -+ -+#ifndef CMSG_ALIGN -+#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) ) -+#endif -diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h -index 5b2abba..79dfc1e 100644 ---- a/bsd-user/sparc/target_signal.h -+++ b/bsd-user/sparc/target_signal.h -@@ -3,15 +3,6 @@ - - #include "cpu.h" - --/* this struct defines a stack used during syscall handling */ -- --typedef struct target_sigaltstack { -- abi_ulong ss_sp; -- abi_long ss_flags; -- abi_ulong ss_size; --} target_stack_t; -- -- - #ifndef UREG_I6 - #define UREG_I6 6 - #endif -@@ -19,6 +10,9 @@ typedef struct target_sigaltstack { - #define UREG_FP UREG_I6 - #endif - -+#define TARGET_MINSIGSTKSZ (512 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ - static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) - { - return state->regwptr[UREG_FP]; -diff --git a/bsd-user/sparc/target_vmparam.h b/bsd-user/sparc/target_vmparam.h -new file mode 100644 -index 0000000..9494c46 ---- /dev/null -+++ b/bsd-user/sparc/target_vmparam.h -@@ -0,0 +1,23 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#define TARGET_USRSTACK 0 -+ -+#ifdef __FreeBSD__ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#define TARGET_SZSIGCODE 0 -+#endif /* __FreeBSD__ */ -+ -+#endif /* _TARGET_VMPARAM_H_ */ -+ -diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h -index 5b2abba..d3e58bb 100644 ---- a/bsd-user/sparc64/target_signal.h -+++ b/bsd-user/sparc64/target_signal.h -@@ -3,15 +3,6 @@ - - #include "cpu.h" - --/* this struct defines a stack used during syscall handling */ -- --typedef struct target_sigaltstack { -- abi_ulong ss_sp; -- abi_long ss_flags; -- abi_ulong ss_size; --} target_stack_t; -- -- - #ifndef UREG_I6 - #define UREG_I6 6 - #endif -@@ -19,6 +10,9 @@ typedef struct target_sigaltstack { - #define UREG_FP UREG_I6 - #endif - -+#define TARGET_MINSIGSTKSZ (1024 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ - static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) - { - return state->regwptr[UREG_FP]; -diff --git a/bsd-user/sparc64/target_vmparam.h b/bsd-user/sparc64/target_vmparam.h -new file mode 100644 -index 0000000..12af063 ---- /dev/null -+++ b/bsd-user/sparc64/target_vmparam.h -@@ -0,0 +1,30 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#if defined(__FreeBSD__) -+#define TARGET_VM_MINUSER_ADDRESS (0x0000000000000000UL) -+#define TARGET_VM_MAXUSER_ADDRESS (0x000007fe00000000UL) -+ -+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS -+ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#define TARGET_SZSIGCODE 0 -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+#endif -+ -+#endif /* _TARGET_VMPARAM_H_ */ -+ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 443b01a..c627c62 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -2,6 +2,7 @@ - * BSD syscalls - * - * Copyright (c) 2003 - 2008 Fabrice Bellard -+ * Copyright (c) 2012 Stacey Son <sson@FreeBSD.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -21,18 +22,37 @@ - #include <stdint.h> - #include <stdarg.h> - #include <string.h> -+#include <dirent.h> - #include <errno.h> - #include <unistd.h> - #include <fcntl.h> - #include <time.h> - #include <limits.h> -+#include <poll.h> - #include <sys/types.h> -+#include <sys/time.h> - #include <sys/mman.h> - #include <sys/syscall.h> - #include <sys/param.h> -+#include <sys/resource.h> - #include <sys/sysctl.h> -+#include <sys/event.h> -+#include <sys/mount.h> -+#include <sys/wait.h> -+#include <sys/socket.h> -+#ifdef __FreeBSD__ -+#include <sys/regression.h> -+#include <sys/procdesc.h> -+#endif -+#include <sys/un.h> -+#include <sys/ipc.h> -+#include <sys/sem.h> -+#include <sys/shm.h> -+#include <sys/msg.h> - #include <utime.h> - -+#include <netinet/in.h> -+ - #include "qemu.h" - #include "qemu-common.h" - -@@ -50,6 +70,13 @@ static inline abi_long get_errno(abi_long ret) - return ret; - } - -+static inline int -+host_to_target_errno(int err) -+{ -+ /* XXX need to translate host errnos here */ -+ return (err); -+} -+ - #define target_to_host_bitmask(x, tbl) (x) - - static inline int is_error(abi_long ret) -@@ -152,13 +179,65 @@ static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms) - #endif - - #ifdef TARGET_SPARC -+struct target_sparc_sigtramp_install_args { -+ abi_ulong sia_new; /* address of sigtramp code */ -+ abi_ulong sia_old; /* user address to store old sigtramp addr */ -+}; -+ -+abi_ulong sparc_user_sigtramp = 0; -+ - static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - { -- /* XXX handle -- * TARGET_FREEBSD_SPARC_UTRAP_INSTALL, -- * TARGET_FREEBSD_SPARC_SIGTRAMP_INSTALL -- */ -- return -TARGET_EINVAL; -+ int ret = 0; -+ abi_ulong val, old; -+ /* -+ struct target_sparc_sigtramp_install_args *target_sigtramp_args; -+ */ -+ -+ -+ switch(op) { -+ case TARGET_SPARC_SIGTRAMP_INSTALL: -+ { -+ -+#if 0 -+ /* Sparc userland is giving us a new sigtramp code ptr. */ -+ if (!(target_sigtramp_args = lock_user(VERIFY_WRITE, parms, -+ sizeof(*target_sigtramp_args), 1))) { -+ ret = -TARGET_EFAULT; -+ } else { -+ if (target_sigtramp_args->sia_old) { -+ put_user_ual(sparc_user_sigtramp, -+ target_sigtramp_args->sia_old); -+ } -+ sparc_user_sigtramp = target_sigtramp_args->sia_new; -+ unlock_user(target_sigtramp_args, parms, 0); -+ -+ } -+#endif -+ val = sparc_user_sigtramp; -+ if (get_user(sparc_user_sigtramp, parms, abi_ulong)) { -+ return (-TARGET_EFAULT); -+ } -+ parms += sizeof(abi_ulong); -+ if (get_user(old, parms, abi_ulong)) { -+ return (-TARGET_EFAULT); -+ } -+ if (old) { -+ if (put_user(val, old, abi_ulong)) { -+ return (-TARGET_EFAULT); -+ } -+ } -+ } -+ break; -+ -+ case TARGET_SPARC_UTRAP_INSTALL: -+ /* XXX not currently handled */ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ -+ return (ret); - } - #endif - -@@ -168,7 +247,17 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - return -TARGET_EINVAL; - } - #endif -+ -+#ifdef TARGET_MIPS -+static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) -+{ -+ return -TARGET_EINVAL; -+} -+#endif -+ - #ifdef __FreeBSD__ -+extern int _getlogin(char *, int); -+ - /* - * XXX this uses the undocumented oidfmt interface to find the kind of - * a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt() -@@ -327,92 +416,3799 @@ static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, - return 0; - } - --/* do_syscall() should always have a single exit point at the end so -- that actions, such as logging of syscall results, can be performed. -- All errnos that do_syscall() returns must be -TARGET_<errcode>. */ --abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -- abi_long arg2, abi_long arg3, abi_long arg4, -- abi_long arg5, abi_long arg6, abi_long arg7, -- abi_long arg8) -+static inline abi_long -+target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, -+ socklen_t len) - { -- abi_long ret; -- void *p; -+ const socklen_t unix_maxlen = sizeof (struct sockaddr_un); -+ sa_family_t sa_family; -+ struct target_sockaddr *target_saddr; - --#ifdef DEBUG -- gemu_log("freebsd syscall %d\n", num); --#endif -- if(do_strace) -- print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); -+ target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); -+ if (!target_saddr) -+ return -TARGET_EFAULT; - -- switch(num) { -- case TARGET_FREEBSD_NR_exit: --#ifdef TARGET_GPROF -- _mcleanup(); -+ sa_family = tswap16(target_saddr->sa_family); -+ -+ /* -+ * Oops. The caller might send a incomplete sun_path; sun_path -+ * must be terminated by \0 (see the manual page), but unfortunately -+ * it is quite common to specify sockaddr_un length as -+ * "strlen(x->sun_path)" while it should be "strlen(...) + 1". We will -+ * fix that here if needed. -+ */ -+ if (sa_family == AF_UNIX) { -+ if (len < unix_maxlen && len > 0) { -+ char *cp = (char*)target_saddr; -+ -+ if ( cp[len-1] && !cp[len] ) -+ len++; -+ } -+ if (len > unix_maxlen) -+ len = unix_maxlen; -+ } -+ -+ memcpy(addr, target_saddr, len); -+ addr->sa_family = sa_family; -+ unlock_user(target_saddr, target_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr, -+ socklen_t len) -+{ -+ struct target_sockaddr *target_saddr; -+ -+ target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0); -+ if (!target_saddr) -+ return (-TARGET_EFAULT); -+ memcpy(target_saddr, addr, len); -+ target_saddr->sa_family = tswap16(addr->sa_family); -+ unlock_user(target_saddr, target_addr, len); -+ -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_cmsg(struct msghdr *msgh, struct target_msghdr *target_msgh) -+{ -+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); -+ abi_long msg_controllen; -+ abi_ulong target_cmsg_addr; -+ struct target_cmsghdr *target_cmsg; -+ socklen_t space = 0; -+ -+ -+ msg_controllen = tswapal(target_msgh->msg_controllen); -+ if (msg_controllen < sizeof (struct target_cmsghdr)) -+ goto the_end; -+ target_cmsg_addr = tswapal(target_msgh->msg_control); -+ target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, -+ msg_controllen, 1); -+ if (!target_cmsg) -+ return (-TARGET_EFAULT); -+ while (cmsg && target_cmsg) { -+ void *data = CMSG_DATA(cmsg); -+ void *target_data = TARGET_CMSG_DATA(target_cmsg); -+ int len = tswapal(target_cmsg->cmsg_len) - -+ TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr)); -+ space += CMSG_SPACE(len); -+ if (space > msgh->msg_controllen) { -+ space -= CMSG_SPACE(len); -+ gemu_log("Host cmsg overflow\n"); -+ break; -+ } -+ cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level); -+ cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type); -+ cmsg->cmsg_len = CMSG_LEN(len); -+ -+ if (cmsg->cmsg_level != TARGET_SOL_SOCKET || -+ cmsg->cmsg_type != SCM_RIGHTS) { -+ gemu_log("Unsupported ancillary data: %d/%d\n", -+ cmsg->cmsg_level, cmsg->cmsg_type); -+ memcpy(data, target_data, len); -+ } else { -+ int *fd = (int *)data; -+ int *target_fd = (int *)target_data; -+ int i, numfds = len / sizeof(int); -+ -+ for (i = 0; i < numfds; i++) -+ fd[i] = tswap32(target_fd[i]); -+ } -+ cmsg = CMSG_NXTHDR(msgh, cmsg); -+ target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); -+ } -+ unlock_user(target_cmsg, target_cmsg_addr, 0); -+ -+the_end: -+ msgh->msg_controllen = space; -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_cmsg(struct target_msghdr *target_msgh, struct msghdr *msgh) -+{ -+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); -+ abi_long msg_controllen; -+ abi_ulong target_cmsg_addr; -+ struct target_cmsghdr *target_cmsg; -+ socklen_t space = 0; -+ -+ msg_controllen = tswapal(target_msgh->msg_controllen); -+ if (msg_controllen < sizeof (struct target_cmsghdr)) -+ goto the_end; -+ target_cmsg_addr = tswapal(target_msgh->msg_control); -+ target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, -+ msg_controllen, 0); -+ if (!target_cmsg) -+ return (-TARGET_EFAULT); -+ while (cmsg && target_cmsg) { -+ void *data = CMSG_DATA(cmsg); -+ void *target_data = TARGET_CMSG_DATA(target_cmsg); -+ int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof (struct cmsghdr)); -+ -+ space += TARGET_CMSG_SPACE(len); -+ if (space > msg_controllen) { -+ space -= TARGET_CMSG_SPACE(len); -+ gemu_log("Target cmsg overflow\n"); -+ break; -+ } -+ target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level); -+ target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type); -+ target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len)); -+ if ((cmsg->cmsg_level == TARGET_SOL_SOCKET) && -+ (cmsg->cmsg_type == SCM_RIGHTS)) { -+ int *fd = (int *)data; -+ int *target_fd = (int *)target_data; -+ int i, numfds = len / sizeof(int); -+ for (i = 0; i < numfds; i++) -+ target_fd[i] = tswap32(fd[i]); -+ } else if ((cmsg->cmsg_level == TARGET_SOL_SOCKET) && -+ (cmsg->cmsg_type == SO_TIMESTAMP) && -+ (len == sizeof(struct timeval))) { -+ /* copy struct timeval to target */ -+ struct timeval *tv = (struct timeval *)data; -+ struct target_timeval *target_tv = -+ (struct target_timeval *)target_data; -+ target_tv->tv_sec = tswapal(tv->tv_sec); -+ target_tv->tv_usec = tswapal(tv->tv_usec); -+ } else { -+ gemu_log("Unsupported ancillary data: %d/%d\n", -+ cmsg->cmsg_level, cmsg->cmsg_type); -+ memcpy(target_data, data, len); -+ } -+ cmsg = CMSG_NXTHDR(msgh, cmsg); -+ target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); -+ } -+ unlock_user(target_cmsg, target_cmsg_addr, space); -+ -+the_end: -+ target_msgh->msg_controllen = tswapal(space); -+ return (0); -+} -+ -+static inline rlim_t -+target_to_host_rlim(abi_ulong target_rlim) -+{ -+ abi_ulong target_rlim_swap; -+ rlim_t result; -+ -+ target_rlim_swap = tswapal(target_rlim); -+ if (target_rlim_swap == TARGET_RLIM_INFINITY) -+ return (RLIM_INFINITY); -+ -+ result = target_rlim_swap; -+ if (target_rlim_swap != (rlim_t)result) -+ return (RLIM_INFINITY); -+ -+ return (result); -+} -+ -+static inline abi_ulong -+host_to_target_rlim(rlim_t rlim) -+{ -+ abi_ulong target_rlim_swap; -+ abi_ulong result; -+ -+ if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim) -+ target_rlim_swap = TARGET_RLIM_INFINITY; -+ else -+ target_rlim_swap = rlim; -+ result = tswapal(target_rlim_swap); -+ -+ return (result); -+} -+ -+static inline int -+target_to_host_resource(int code) -+{ -+ -+ switch (code) { -+ case TARGET_RLIMIT_AS: -+ return RLIMIT_AS; -+ -+ case TARGET_RLIMIT_CORE: -+ return RLIMIT_CORE; -+ -+ case TARGET_RLIMIT_CPU: -+ return RLIMIT_CPU; -+ -+ case TARGET_RLIMIT_DATA: -+ return RLIMIT_DATA; -+ -+ case TARGET_RLIMIT_FSIZE: -+ return RLIMIT_FSIZE; -+ -+ case TARGET_RLIMIT_MEMLOCK: -+ return RLIMIT_MEMLOCK; -+ -+ case TARGET_RLIMIT_NOFILE: -+ return RLIMIT_NOFILE; -+ -+ case TARGET_RLIMIT_NPROC: -+ return RLIMIT_NPROC; -+ -+ case TARGET_RLIMIT_RSS: -+ return RLIMIT_RSS; -+ -+ case TARGET_RLIMIT_SBSIZE: -+ return RLIMIT_SBSIZE; -+ -+ case TARGET_RLIMIT_STACK: -+ return RLIMIT_STACK; -+ -+ case TARGET_RLIMIT_SWAP: -+ return RLIMIT_SWAP; -+ -+ case TARGET_RLIMIT_NPTS: -+ return RLIMIT_NPTS; -+ -+ default: -+ return (code); -+ } -+} -+ -+static int -+target_to_host_fcntl_cmd(int cmd) -+{ -+ -+ switch(cmd) { -+ case TARGET_F_DUPFD: -+ return F_DUPFD; -+ -+ case TARGET_F_DUP2FD: -+ return F_DUP2FD; -+ -+ case TARGET_F_GETFD: -+ return F_GETFD; -+ -+ case TARGET_F_SETFD: -+ return F_SETFD; -+ -+ case TARGET_F_GETFL: -+ return F_GETFL; -+ -+ case TARGET_F_SETFL: -+ return F_SETFL; -+ -+ case TARGET_F_GETOWN: -+ return F_GETOWN; -+ -+ case TARGET_F_SETOWN: -+ return F_SETOWN; -+ -+ case TARGET_F_GETLK: -+ return F_GETLK; -+ -+ case TARGET_F_SETLK: -+ return F_SETLK; -+ -+ case TARGET_F_SETLKW: -+ return F_SETLKW; -+ -+ case TARGET_F_READAHEAD: -+ return F_READAHEAD; -+ -+ case TARGET_F_RDAHEAD: -+ return F_RDAHEAD; -+ -+ default: -+ return (cmd); -+ } -+} -+ -+static inline abi_long -+host_to_target_rusage(abi_ulong target_addr, const struct rusage *rusage) -+{ -+ struct target_rusage *target_rusage; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ target_rusage->ru_utime.tv_sec = tswapal(rusage->ru_utime.tv_sec); -+ target_rusage->ru_utime.tv_usec = tswapal(rusage->ru_utime.tv_usec); -+ target_rusage->ru_stime.tv_sec = tswapal(rusage->ru_stime.tv_sec); -+ target_rusage->ru_stime.tv_usec = tswapal(rusage->ru_stime.tv_usec); -+ target_rusage->ru_maxrss = tswapal(rusage->ru_maxrss); -+ target_rusage->ru_ixrss = tswapal(rusage->ru_ixrss); -+ target_rusage->ru_idrss = tswapal(rusage->ru_idrss); -+ target_rusage->ru_isrss = tswapal(rusage->ru_isrss); -+ target_rusage->ru_minflt = tswapal(rusage->ru_minflt); -+ target_rusage->ru_majflt = tswapal(rusage->ru_majflt); -+ target_rusage->ru_nswap = tswapal(rusage->ru_nswap); -+ target_rusage->ru_inblock = tswapal(rusage->ru_inblock); -+ target_rusage->ru_oublock = tswapal(rusage->ru_oublock); -+ target_rusage->ru_msgsnd = tswapal(rusage->ru_msgsnd); -+ target_rusage->ru_msgrcv = tswapal(rusage->ru_msgrcv); -+ target_rusage->ru_nsignals = tswapal(rusage->ru_nsignals); -+ target_rusage->ru_nvcsw = tswapal(rusage->ru_nvcsw); -+ target_rusage->ru_nivcsw = tswapal(rusage->ru_nivcsw); -+ unlock_user_struct(target_rusage, target_addr, 1); -+ -+ return (0); -+} -+ -+/* -+ * Map host to target signal numbers for the wait family of syscalls. -+ * Assume all other status bits are the same. -+ */ -+static int -+host_to_target_waitstatus(int status) -+{ -+ if (WIFSIGNALED(status)) { -+ return (host_to_target_signal(WTERMSIG(status)) | -+ (status & ~0x7f)); -+ } -+ if (WIFSTOPPED(status)) { -+ return (host_to_target_signal(WSTOPSIG(status)) << 8) | -+ (status & 0xff); -+ } -+ return (status); -+} -+ -+static inline abi_long -+copy_from_user_timeval(struct timeval *tv, abi_ulong target_tv_addr) -+{ -+ struct target_freebsd_timeval *target_tv; -+ -+ if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 0)) -+ return -TARGET_EFAULT; -+ __get_user(tv->tv_sec, &target_tv->tv_sec); -+ __get_user(tv->tv_usec, &target_tv->tv_usec); -+ unlock_user_struct(target_tv, target_tv_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_timespec(struct timespec *ts, abi_ulong target_ts_addr) -+{ -+ struct target_freebsd_timespec *target_ts; -+ -+ if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 0)) -+ return -TARGET_EFAULT; -+ __get_user(ts->tv_sec, &target_ts->tv_sec); -+ __get_user(ts->tv_nsec, &target_ts->tv_nsec); -+ unlock_user_struct(target_ts, target_ts_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+fbsd_copy_to_user_timeval(struct timeval *tv, abi_ulong target_tv_addr) -+{ -+ struct target_freebsd_timeval *target_tv; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) -+ return -TARGET_EFAULT; -+ __put_user(tv->tv_sec, &target_tv->tv_sec); -+ __put_user(tv->tv_usec, &target_tv->tv_usec); -+ unlock_user_struct(target_tv, target_tv_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_timespec(abi_ulong target_ts_addr, struct timespec *ts) -+{ -+ struct target_freebsd_timespec *target_ts; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0)) -+ return -TARGET_EFAULT; -+ __put_user(ts->tv_sec, &target_ts->tv_sec); -+ __put_user(ts->tv_nsec, &target_ts->tv_nsec); -+ unlock_user_struct(target_ts, target_ts_addr, 1); -+ return (0); -+} -+static inline abi_ulong -+copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n) -+{ -+ int i, nw, j, k; -+ abi_ulong b, *target_fds; -+ -+ nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; -+ if (!(target_fds = lock_user(VERIFY_READ, target_fds_addr, -+ sizeof(abi_ulong) * nw, 1))) -+ return (-TARGET_EFAULT); -+ -+ FD_ZERO(fds); -+ k = 0; -+ for (i = 0; i < nw; i++) { -+ /* grab the abi_ulong */ -+ __get_user(b, &target_fds[i]); -+ for (j = 0; j < TARGET_ABI_BITS; j++) { -+ /* check the bit inside the abi_ulong */ -+ if ((b >> j) & 1) -+ FD_SET(k, fds); -+ k++; -+ } -+ } -+ -+ unlock_user(target_fds, target_fds_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_ulong -+copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr, -+ abi_ulong target_fds_addr, int n) -+{ -+ if (target_fds_addr) { -+ if (copy_from_user_fdset(fds, target_fds_addr, n)) -+ return (-TARGET_EFAULT); -+ *fds_ptr = fds; -+ } else { -+ *fds_ptr = NULL; -+ } -+ return (0); -+} -+ -+static inline abi_long -+copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, int n) -+{ -+ int i, nw, j, k; -+ abi_long v; -+ abi_ulong *target_fds; -+ -+ nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; -+ if (!(target_fds = lock_user(VERIFY_WRITE, target_fds_addr, -+ sizeof(abi_ulong) * nw, 0))) -+ return (-TARGET_EFAULT); -+ -+ k = 0; -+ for (i = 0; i < nw; i++) { -+ v = 0; -+ for (j = 0; j < TARGET_ABI_BITS; j++) { -+ v |= ((FD_ISSET(k, fds) != 0) << j); -+ k++; -+ } -+ __put_user(v, &target_fds[i]); -+ } -+ -+ unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw); -+ -+ return (0); -+} -+ -+#if TARGET_ABI_BITS == 32 -+static inline uint64_t -+target_offset64(uint32_t word0, uint32_t word1) -+{ -+#ifdef TARGET_WORDS_BIGENDIAN -+ return ((uint64_t)word0 << 32) | word1; -+#else -+ return ((uint64_t)word1 << 32) | word0; - #endif -- gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -- _exit(arg1); -- ret = 0; /* avoid warning */ -- break; -- case TARGET_FREEBSD_NR_read: -- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -- goto efault; -- ret = get_errno(read(arg1, p, arg3)); -- unlock_user(p, arg2, ret); -- break; -- case TARGET_FREEBSD_NR_write: -- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -- goto efault; -- ret = get_errno(write(arg1, p, arg3)); -- unlock_user(p, arg2, 0); -- break; -- case TARGET_FREEBSD_NR_writev: -- { -- int count = arg3; -- struct iovec *vec; -+} -+#else /* TARGET_ABI_BITS != 32 */ -+static inline uint64_t -+target_offset64(uint64_t word0, uint64_t word1) -+{ -+ return (word0); -+} -+#endif /* TARGET_ABI_BITS != 32 */ - -- vec = alloca(count * sizeof(struct iovec)); -- if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -- goto efault; -- ret = get_errno(writev(arg1, vec, count)); -- unlock_iovec(vec, arg2, count, 0); -- } -- break; -- case TARGET_FREEBSD_NR_open: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(open(path(p), -- target_to_host_bitmask(arg2, fcntl_flags_tbl), -- arg3)); -- unlock_user(p, arg1, 0); -- break; -- case TARGET_FREEBSD_NR_mmap: -- ret = get_errno(target_mmap(arg1, arg2, arg3, -- target_to_host_bitmask(arg4, mmap_flags_tbl), -- arg5, -- arg6)); -- break; -- case TARGET_FREEBSD_NR_munmap: -- ret = get_errno(target_munmap(arg1, arg2)); -- break; -- case TARGET_FREEBSD_NR_mprotect: -- ret = get_errno(target_mprotect(arg1, arg2, arg3)); -- break; -- case TARGET_FREEBSD_NR_break: -- ret = do_obreak(arg1); -- break; --#ifdef __FreeBSD__ -- case TARGET_FREEBSD_NR___sysctl: -- ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6); -- break; -+/* ARM EABI and MIPS expect 64bit types aligned even on pairs of registers */ -+#ifdef TARGET_ARM -+static inline int -+regpairs_aligned(void *cpu_env) { -+ -+ return ((((CPUARMState *)cpu_env)->eabi) == 1); -+} -+#elif defined(TARGET_MIPS) && TARGET_ABI_BITS == 32 -+static inline int -+regpairs_aligned(void *cpu_env) { return 1; } -+#else -+static inline int -+regpairs_aligned(void *cpu_env) { return 0; } - #endif -- case TARGET_FREEBSD_NR_sysarch: -- ret = do_freebsd_sysarch(cpu_env, arg1, arg2); -- break; -- case TARGET_FREEBSD_NR_syscall: -- case TARGET_FREEBSD_NR___syscall: -- ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0); -- break; -+ -+static inline abi_long -+unimplemented(int num) -+{ -+ -+ qemu_log("qemu: Unsupported syscall: %d\n", num); -+ return (-TARGET_ENOSYS); -+} -+ -+/* do_bind() must return target values and target errnos. */ -+static abi_long -+do_bind(int sockfd, abi_ulong target_addr, socklen_t addrlen) -+{ -+ abi_long ret; -+ void *addr; -+ -+ if ((int)addrlen < 0) -+ return (-TARGET_EINVAL); -+ -+ addr = alloca(addrlen + 1); -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ if (ret) -+ return (ret); -+ -+ return get_errno(bind(sockfd, addr, addrlen)); -+} -+ -+/* do_connect() must return target values and target errnos. */ -+static abi_long -+do_connect(int sockfd, abi_ulong target_addr, socklen_t addrlen) -+{ -+ abi_long ret; -+ void *addr; -+ -+ if ((int)addrlen < 0) -+ return (-TARGET_EINVAL); -+ -+ addr = alloca(addrlen); -+ -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ -+ if (ret) -+ return (ret); -+ -+ return (get_errno(connect(sockfd, addr, addrlen))); -+} -+ -+/* do_sendrecvmsg() must return target values and target errnos. */ -+static abi_long -+do_sendrecvmsg(int fd, abi_ulong target_msg, int flags, int send) -+{ -+ abi_long ret, len; -+ struct target_msghdr *msgp; -+ struct msghdr msg; -+ int count; -+ struct iovec *vec; -+ abi_ulong target_vec; -+ -+ if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, msgp, -+ target_msg, send ? 1 : 0)) -+ return (-TARGET_EFAULT); -+ if (msgp->msg_name) { -+ msg.msg_namelen = tswap32(msgp->msg_namelen); -+ msg.msg_name = alloca(msg.msg_namelen); -+ ret = target_to_host_sockaddr(msg.msg_name, -+ tswapal(msgp->msg_name), msg.msg_namelen); -+ -+ if (ret) { -+ unlock_user_struct(msgp, target_msg, send ? 0 : 1); -+ return (ret); -+ } -+ } else { -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ } -+ msg.msg_controllen = 2 * tswapal(msgp->msg_controllen); -+ msg.msg_control = alloca(msg.msg_controllen); -+ msg.msg_flags = tswap32(msgp->msg_flags); -+ -+ count = tswapal(msgp->msg_iovlen); -+ vec = alloca(count * sizeof(struct iovec)); -+ target_vec = tswapal(msgp->msg_iov); -+ lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, -+ send); -+ msg.msg_iovlen = count; -+ msg.msg_iov = vec; -+ -+ if (send) { -+ ret = target_to_host_cmsg(&msg, msgp); -+ if (0 == ret) -+ ret = get_errno(sendmsg(fd, &msg, flags)); -+ } else { -+ ret = get_errno(recvmsg(fd, &msg, flags)); -+ if (!is_error(ret)) { -+ len = ret; -+ ret = host_to_target_cmsg(msgp, &msg); -+ if (!is_error(ret)) { -+ msgp->msg_namelen = tswap32(msg.msg_namelen); -+ if (msg.msg_name != NULL) { -+ ret = host_to_target_sockaddr( -+ tswapal(msgp->msg_name), -+ msg.msg_name, msg.msg_namelen); -+ if (ret) -+ goto out; -+ } -+ } -+ ret = len; -+ } -+ } -+out: -+ unlock_iovec(vec, target_vec, count, !send); -+ unlock_user_struct(msgp, target_msg, send ? 0 : 1); -+ return (ret); -+} -+ -+/* do_accept() must return target values and target errnos. */ -+static abi_long -+do_accept(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ -+ if (target_addr == 0) -+ return get_errno(accept(fd, NULL, NULL)); -+ -+ /* return EINVAL if addrlen pointer is invalid */ -+ if (get_user_u32(addrlen, target_addrlen_addr)) -+ return (-TARGET_EINVAL); -+ -+ if ((int)addrlen < 0) -+ return (-TARGET_EINVAL); -+ -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) -+ return -TARGET_EINVAL; -+ -+ addr = alloca(addrlen); -+ -+ ret = get_errno(accept(fd, addr, &addrlen)); -+ if (!is_error(ret)) { -+ host_to_target_sockaddr(target_addr, addr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen_addr)) -+ ret = (-TARGET_EFAULT); -+ } -+ return (ret); -+} -+ -+/* do_getpeername() must return target values and target errnos. */ -+static abi_long -+do_getpeername(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ if (get_user_u32(addrlen, target_addrlen_addr)) -+ return (-TARGET_EFAULT); -+ if ((int)addrlen < 0) { -+ return (-TARGET_EINVAL); -+ } -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) -+ return (-TARGET_EFAULT); -+ 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)) -+ ret = (-TARGET_EFAULT); -+ } -+ return (ret); -+} -+ -+/* do_getsockname() must return target values and target errnos. */ -+static abi_long -+do_getsockname(int fd, abi_ulong target_addr, abi_ulong target_addrlen_addr) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ -+ if (get_user_u32(addrlen, target_addrlen_addr)) -+ return (-TARGET_EFAULT); -+ -+ if ((int)addrlen < 0) -+ return (-TARGET_EINVAL); -+ -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) -+ return (-TARGET_EFAULT); -+ -+ addr = alloca(addrlen); -+ -+ 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)) -+ ret = (-TARGET_EFAULT); -+ } -+ return (ret); -+} -+ -+/* do_socketpair() must return target values and target errnos. */ -+static abi_long -+do_socketpair(int domain, int type, int protocol, abi_ulong target_tab_addr) -+{ -+ int tab[2]; -+ abi_long ret; -+ -+ ret = get_errno(socketpair(domain, type, protocol, tab)); -+ if (!is_error(ret)) { -+ if (put_user_s32(tab[0], target_tab_addr) -+ || put_user_s32(tab[1], target_tab_addr + sizeof(tab[0]))) -+ ret = (-TARGET_EFAULT); -+ } -+ return (ret); -+} -+ -+/* do_sendto() must return target values and target errnos. */ -+static abi_long -+do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, -+ socklen_t addrlen) -+{ -+ void *addr; -+ void *host_msg; -+ abi_long ret; -+ -+ if ((int)addrlen < 0) -+ return (-TARGET_EINVAL); -+ host_msg = lock_user(VERIFY_READ, msg, len, 1); -+ if (!host_msg) -+ return (-TARGET_EFAULT); -+ if (target_addr) { -+ addr = alloca(addrlen); -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ if (ret) { -+ unlock_user(host_msg, msg, 0); -+ return (ret); -+ } -+ ret = get_errno(sendto(fd, host_msg, len, flags, addr, -+ addrlen)); -+ } else { -+ ret = get_errno(send(fd, host_msg, len, flags)); -+ } -+ unlock_user(host_msg, msg, 0); -+ return (ret); -+} -+ -+/* do_recvfrom() must return target values and target errnos. */ -+static abi_long -+do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, -+ abi_ulong target_addrlen) -+{ -+ socklen_t addrlen; -+ void *addr; -+ void *host_msg; -+ abi_long ret; -+ -+ host_msg = lock_user(VERIFY_WRITE, msg, len, 0); -+ if (!host_msg) -+ return (-TARGET_EFAULT); -+ if (target_addr) { -+ if (get_user_u32(addrlen, target_addrlen)) { -+ ret = -TARGET_EFAULT; -+ goto fail; -+ } -+ if ((int)addrlen < 0) { -+ ret = (-TARGET_EINVAL); -+ goto fail; -+ } -+ addr = alloca(addrlen); -+ ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, -+ &addrlen)); -+ } else { -+ addr = NULL; /* To keep compiler quiet. */ -+ ret = get_errno(qemu_recv(fd, host_msg, len, flags)); -+ } -+ if (!is_error(ret)) { -+ if (target_addr) { -+ host_to_target_sockaddr(target_addr, addr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen)) { -+ ret = -TARGET_EFAULT; -+ goto fail; -+ } -+ } -+ unlock_user(host_msg, msg, len); -+ } else { -+fail: -+ unlock_user(host_msg, msg, 0); -+ } -+ return (ret); -+} -+ -+/* do_freebsd_select() must return target values and target errnos. */ -+static abi_long -+do_freebsd_select(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, -+ abi_ulong efd_addr, abi_ulong target_tv_addr) -+{ -+ fd_set rfds, wfds, efds; -+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; -+ struct timeval tv, *tv_ptr; -+ abi_long ret; -+ -+ if ((ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n)) != 0) -+ return (ret); -+ if ((ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n)) != 0) -+ return (ret); -+ if ((ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n)) != 0) -+ return (ret); -+ -+ if (target_tv_addr) { -+ if (copy_from_user_timeval(&tv, target_tv_addr)) -+ return (-TARGET_EFAULT); -+ tv_ptr = &tv; -+ } else { -+ tv_ptr = NULL; -+ } -+ -+ ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); -+ -+ if (!is_error(ret)) { -+ if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) -+ return (-TARGET_EFAULT); -+ if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) -+ return (-TARGET_EFAULT); -+ if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) -+ return (-TARGET_EFAULT); -+ -+ if (target_tv_addr && -+ fbsd_copy_to_user_timeval(&tv, target_tv_addr)) -+ return (-TARGET_EFAULT); -+ } -+ -+ return (ret); -+} -+ -+/* do_freebsd_pselect() must return target values and target errnos. */ -+static abi_long -+do_freebsd_pselect(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, -+ abi_ulong efd_addr, abi_ulong ts_addr, abi_ulong set_addr) -+{ -+ fd_set rfds, wfds, efds; -+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; -+ sigset_t set, *set_ptr; -+ struct timespec ts, *ts_ptr; -+ void *p; -+ abi_long ret; -+ -+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); -+ if (ret) -+ return (ret); -+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); -+ if (ret) -+ return (ret); -+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); -+ if (ret) -+ return (ret); -+ -+ /* Unlike select(), pselect() uses struct timespec instead of timeval */ -+ if (ts_addr) { -+ if (target_to_host_timespec(&ts, ts_addr)) -+ return (-TARGET_EFAULT); -+ ts_ptr = &ts; -+ } else { -+ ts_ptr = NULL; -+ } -+ -+ if (set_addr) { -+ if (!(p = lock_user(VERIFY_READ, set_addr, -+ sizeof(target_sigset_t), 1))) -+ return (-TARGET_EFAULT); -+ target_to_host_sigset(&set, p); -+ unlock_user(p, set_addr, 0); -+ set_ptr = &set; -+ } else { -+ set_ptr = NULL; -+ } -+ -+ ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, ts_ptr, -+ set_ptr)); -+ -+ if (!is_error(ret)) { -+ if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) -+ return (-TARGET_EFAULT); -+ if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) -+ return (-TARGET_EFAULT); -+ if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) -+ return (-TARGET_EFAULT); -+ -+ if (ts_addr && host_to_target_timespec(ts_addr, &ts)) -+ return (-TARGET_EFAULT); -+ } -+ -+ return (ret); -+} -+ -+/* do_getsockopt() must return target values and target errnos. */ -+static abi_long -+do_getsockopt(int sockfd, int level, int optname, abi_ulong optval_addr, -+ abi_ulong optlen) -+{ -+ abi_long ret; -+ int len, val; -+ socklen_t lv; -+ -+ switch(level) { -+ case TARGET_SOL_SOCKET: -+ level = SOL_SOCKET; -+ switch (optname) { -+ -+ /* These don't just return a single integer */ -+ case TARGET_SO_LINGER: -+ case TARGET_SO_RCVTIMEO: -+ case TARGET_SO_SNDTIMEO: -+ case TARGET_SO_ACCEPTFILTER: -+ goto unimplemented; -+ -+ /* Options with 'int' argument. */ -+ case TARGET_SO_DEBUG: -+ optname = SO_DEBUG; -+ goto int_case; -+ -+ case TARGET_SO_REUSEADDR: -+ optname = SO_REUSEADDR; -+ goto int_case; -+ -+ case TARGET_SO_REUSEPORT: -+ optname = SO_REUSEPORT; -+ goto int_case; -+ -+ case TARGET_SO_TYPE: -+ optname = SO_TYPE; -+ goto int_case; -+ -+ case TARGET_SO_ERROR: -+ optname = SO_ERROR; -+ goto int_case; -+ -+ case TARGET_SO_DONTROUTE: -+ optname = SO_DONTROUTE; -+ goto int_case; -+ -+ case TARGET_SO_BROADCAST: -+ optname = SO_BROADCAST; -+ goto int_case; -+ -+ case TARGET_SO_SNDBUF: -+ optname = SO_SNDBUF; -+ goto int_case; -+ -+ case TARGET_SO_RCVBUF: -+ optname = SO_RCVBUF; -+ goto int_case; -+ -+ case TARGET_SO_KEEPALIVE: -+ optname = SO_KEEPALIVE; -+ goto int_case; -+ -+ case TARGET_SO_OOBINLINE: -+ optname = SO_OOBINLINE; -+ goto int_case; -+ -+ case TARGET_SO_TIMESTAMP: -+ optname = SO_TIMESTAMP; -+ goto int_case; -+ -+ case TARGET_SO_RCVLOWAT: -+ optname = SO_RCVLOWAT; -+ goto int_case; -+ -+ case TARGET_SO_LISTENINCQLEN: -+ optname = SO_LISTENINCQLEN; -+ goto int_case; -+ -+ default: -+int_case: -+ if (get_user_u32(len, optlen)) -+ return (-TARGET_EFAULT); -+ if (len < 0) -+ return (-TARGET_EINVAL); -+ lv = sizeof(lv); -+ ret = get_errno(getsockopt(sockfd, level, optname, -+ &val, &lv)); -+ if (ret < 0) -+ return (ret); -+ if (len > lv) -+ len = lv; -+ if (len == 4) { -+ if (put_user_u32(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ } else { -+ if (put_user_u8(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ } -+ if (put_user_u32(len, optlen)) -+ return (-TARGET_EFAULT); -+ break; -+ -+ } -+ break; -+ -+ default: -+unimplemented: -+ gemu_log("getsockopt level=%d optname=%d not yet supported\n", -+ level, optname); -+ ret = -TARGET_EOPNOTSUPP; -+ break; -+ } -+ return (ret); -+} -+ -+/* 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) -+{ -+ int val; -+ abi_long ret; -+ -+ switch(level) { -+ case TARGET_SOL_SOCKET: -+ switch (optname) { -+ /* Options with 'int' argument. */ -+ case TARGET_SO_DEBUG: -+ optname = SO_DEBUG; -+ break; -+ -+ case TARGET_SO_REUSEADDR: -+ optname = SO_REUSEADDR; -+ break; -+ -+ case TARGET_SO_REUSEPORT: -+ optname = SO_REUSEADDR; -+ break; -+ -+ case TARGET_SO_KEEPALIVE: -+ optname = SO_KEEPALIVE; -+ break; -+ -+ case TARGET_SO_DONTROUTE: -+ optname = SO_DONTROUTE; -+ break; -+ -+ case TARGET_SO_LINGER: -+ optname = SO_LINGER; -+ break; -+ -+ case TARGET_SO_BROADCAST: -+ optname = SO_BROADCAST; -+ break; -+ -+ case TARGET_SO_OOBINLINE: -+ optname = SO_OOBINLINE; -+ break; -+ -+ case TARGET_SO_SNDBUF: -+ optname = SO_SNDBUF; -+ break; -+ -+ case TARGET_SO_RCVBUF: -+ optname = SO_RCVBUF; -+ break; -+ -+ case TARGET_SO_SNDLOWAT: -+ optname = SO_RCVLOWAT; -+ break; -+ -+ case TARGET_SO_RCVLOWAT: -+ optname = SO_RCVLOWAT; -+ break; -+ -+ case TARGET_SO_SNDTIMEO: -+ optname = SO_SNDTIMEO; -+ break; -+ -+ case TARGET_SO_RCVTIMEO: -+ optname = SO_RCVTIMEO; -+ break; -+ -+ case TARGET_SO_ACCEPTFILTER: -+ goto unimplemented; -+ -+ case TARGET_SO_NOSIGPIPE: -+ optname = SO_NOSIGPIPE; -+ break; -+ -+ case TARGET_SO_TIMESTAMP: -+ optname = SO_TIMESTAMP; -+ break; -+ -+ case TARGET_SO_BINTIME: -+ optname = SO_BINTIME; -+ break; -+ -+ case TARGET_SO_ERROR: -+ optname = SO_ERROR; -+ break; -+ -+ case TARGET_SO_SETFIB: -+ optname = SO_ERROR; -+ break; -+ -+ case TARGET_SO_USER_COOKIE: -+ optname = SO_USER_COOKIE; -+ 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))); -+ break; -+ default: -+unimplemented: -+ gemu_log("Unsupported setsockopt level=%d optname=%d\n", -+ level, optname); -+ ret = -TARGET_ENOPROTOOPT; -+ } -+ -+ return (ret); -+} -+ -+static inline abi_long -+target_to_host_sembuf(struct sembuf *host_sembuf, abi_ulong target_addr, -+ unsigned nsops) -+{ -+ struct target_sembuf *target_sembuf; -+ int i; -+ -+ target_sembuf = lock_user(VERIFY_READ, target_addr, -+ nsops * sizeof(struct target_sembuf), 1); -+ if (!target_sembuf) -+ return (-TARGET_EFAULT); -+ -+ for(i=0; i<nsops; i++) { -+ __get_user(host_sembuf[i].sem_num, &target_sembuf[i].sem_num); -+ __get_user(host_sembuf[i].sem_op, &target_sembuf[i].sem_op); -+ __get_user(host_sembuf[i].sem_flg, &target_sembuf[i].sem_flg); -+ } -+ -+ unlock_user(target_sembuf, target_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_long -+do_semop(int semid, abi_long ptr, unsigned nsops) -+{ -+ struct sembuf sops[nsops]; -+ -+ if (target_to_host_sembuf(sops, ptr, nsops)) -+ return (-TARGET_EFAULT); -+ -+ return semop(semid, sops, nsops); -+} -+ -+static inline abi_long -+target_to_host_semarray(int semid, unsigned short **host_array, -+ abi_ulong target_addr) -+{ -+ int nsems; -+ unsigned short *array; -+ union semun semun; -+ struct semid_ds semid_ds; -+ int i, ret; -+ -+ semun.buf = &semid_ds; -+ ret = semctl(semid, 0, IPC_STAT, semun); -+ if (ret == -1) -+ return (get_errno(ret)); -+ nsems = semid_ds.sem_nsems; -+ *host_array = malloc(nsems * sizeof(unsigned short)); -+ array = lock_user(VERIFY_READ, target_addr, -+ nsems*sizeof(unsigned short), 1); -+ if (!array) -+ return (-TARGET_EFAULT); -+ for(i=0; i<nsems; i++) { -+ __get_user((*host_array)[i], &array[i]); -+ } -+ unlock_user(array, target_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_semarray(int semid, abi_ulong target_addr, -+ unsigned short **host_array) -+{ -+ int nsems; -+ unsigned short *array; -+ union semun semun; -+ struct semid_ds semid_ds; -+ int i, ret; -+ -+ semun.buf = &semid_ds; -+ -+ ret = semctl(semid, 0, IPC_STAT, semun); -+ if (ret == -1) -+ return get_errno(ret); -+ -+ nsems = semid_ds.sem_nsems; -+ -+ array = lock_user(VERIFY_WRITE, target_addr, -+ nsems*sizeof(unsigned short), 0); -+ if (!array) -+ return (-TARGET_EFAULT); -+ -+ for(i=0; i<nsems; i++) { -+ __put_user((*host_array)[i], &array[i]); -+ } -+ free(*host_array); -+ unlock_user(array, target_addr, 1); -+ -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_ipc_perm(struct ipc_perm *host_ip, abi_ulong target_addr) -+{ -+ struct target_ipc_perm *target_ip; -+ struct target_semid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ target_ip = &(target_sd->sem_perm); -+ host_ip->cuid = tswapal(target_ip->cuid); -+ host_ip->cgid = tswapal(target_ip->cgid); -+ host_ip->uid = tswapal(target_ip->uid); -+ host_ip->gid = tswapal(target_ip->gid); -+ host_ip->mode = tswap16(target_ip->mode); -+ host_ip->seq = tswap16(target_ip->seq); -+ host_ip->key = tswapal(target_ip->key); -+ unlock_user_struct(target_sd, target_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_ipc_perm(abi_ulong target_addr, struct ipc_perm *host_ip) -+{ -+ struct target_ipc_perm *target_ip; -+ struct target_semid_ds *target_sd; -+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ target_ip = &(target_sd->sem_perm); -+ target_ip->cuid = tswapal(host_ip->cuid); -+ target_ip->cgid = tswapal(host_ip->cgid); -+ target_ip->uid = tswapal(host_ip->uid); -+ target_ip->gid = tswapal(host_ip->gid); -+ target_ip->mode = tswap16(host_ip->mode); -+ target_ip->seq = tswap16(host_ip->seq); -+ target_ip->key = tswapal(host_ip->key); -+ unlock_user_struct(target_sd, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_semid_ds(struct semid_ds *host_sd, abi_ulong target_addr) -+{ -+ struct target_semid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ if (target_to_host_ipc_perm(&(host_sd->sem_perm), target_addr)) -+ return (-TARGET_EFAULT); -+ /* sem_base is not used by kernel for IPC_STAT/IPC_SET */ -+ host_sd->sem_base = NULL; -+ host_sd->sem_nsems = tswapal(target_sd->sem_nsems); -+ host_sd->sem_otime = tswapal(target_sd->sem_otime); -+ host_sd->sem_ctime = tswapal(target_sd->sem_ctime); -+ unlock_user_struct(target_sd, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_semid_ds(abi_ulong target_addr, struct semid_ds *host_sd) -+{ -+ struct target_semid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm))) -+ return (-TARGET_EFAULT); -+ /* sem_base is not used by kernel for IPC_STAT/IPC_SET */ -+ target_sd->sem_nsems = tswapal(host_sd->sem_nsems); -+ target_sd->sem_otime = tswapal(host_sd->sem_otime); -+ target_sd->sem_ctime = tswapal(host_sd->sem_ctime); -+ unlock_user_struct(target_sd, target_addr, 1); -+ -+ return (0); -+} -+ -+static inline abi_long -+do_semctl(int semid, int semnum, int cmd, union target_semun target_su) -+{ -+ union semun arg; -+ struct semid_ds dsarg; -+ unsigned short *array = NULL; -+ abi_long ret = -TARGET_EINVAL; -+ abi_long err; -+ -+ cmd &= 0xff; -+ -+ switch( cmd ) { -+ case GETVAL: -+ case SETVAL: -+ arg.val = tswap32(target_su.val); -+ ret = get_errno(semctl(semid, semnum, cmd, arg)); -+ target_su.val = tswap32(arg.val); -+ break; -+ -+ case GETALL: -+ case SETALL: -+ err = target_to_host_semarray(semid, &array, target_su.array); -+ if (err) -+ return (err); -+ arg.array = array; -+ ret = get_errno(semctl(semid, semnum, cmd, arg)); -+ err = host_to_target_semarray(semid, target_su.array, &array); -+ if (err) -+ return (err); -+ break; -+ -+ case IPC_STAT: -+ case IPC_SET: -+ err = target_to_host_semid_ds(&dsarg, target_su.buf); -+ if (err) -+ return (err); -+ arg.buf = &dsarg; -+ ret = get_errno(semctl(semid, semnum, cmd, arg)); -+ err = host_to_target_semid_ds(target_su.buf, &dsarg); -+ if (err) -+ return (err); -+ break; -+ -+ case IPC_RMID: -+ case GETPID: -+ case GETNCNT: -+ case GETZCNT: -+ ret = get_errno(semctl(semid, semnum, cmd, NULL)); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ return (ret); -+} -+ -+#define N_SHM_REGIONS 32 -+ -+static struct shm_regions { -+ abi_long start; -+ abi_long size; -+} shm_regions[N_SHM_REGIONS]; -+ -+static inline abi_ulong -+do_shmat(int shmid, abi_ulong shmaddr, int shmflg) -+{ -+ abi_long raddr; -+ void *host_raddr; -+ struct shmid_ds shm_info; -+ int i,ret; -+ -+ /* Find out the length of the shared memory segment. */ -+ ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info)); -+ if (is_error(ret)) { -+ /* Can't get the length */ -+ return (ret); -+ } -+ -+ mmap_lock(); -+ -+ if (shmaddr) { -+ host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg); -+ } else { -+ abi_ulong mmap_start; -+ -+ mmap_start = mmap_find_vma(0, shm_info.shm_segsz); -+ -+ if (mmap_start == -1) { -+ errno = ENOMEM; -+ host_raddr = (void *)-1; -+ } else { -+ host_raddr = shmat(shmid, g2h(mmap_start), -+ shmflg /* | SHM_REMAP */); -+ } -+ } -+ -+ if (host_raddr == (void *)-1) { -+ mmap_unlock(); -+ return get_errno((long)host_raddr); -+ } -+ raddr=h2g((unsigned long)host_raddr); -+ -+ page_set_flags(raddr, raddr + shm_info.shm_segsz, -+ PAGE_VALID | PAGE_READ | ((shmflg & SHM_RDONLY)? 0 : PAGE_WRITE)); -+ -+ for (i = 0; i < N_SHM_REGIONS; i++) { -+ if (shm_regions[i].start == 0) { -+ shm_regions[i].start = raddr; -+ shm_regions[i].size = shm_info.shm_segsz; -+ break; -+ } -+ } -+ -+ mmap_unlock(); -+ return (raddr); -+} -+ -+static inline abi_long -+do_shmdt(abi_ulong shmaddr) -+{ -+ int i; -+ -+ for (i = 0; i < N_SHM_REGIONS; ++i) { -+ if (shm_regions[i].start == shmaddr) { -+ shm_regions[i].start = 0; -+ page_set_flags(shmaddr, -+ shmaddr + shm_regions[i].size, 0); -+ break; -+ } -+ } -+ -+ return ( get_errno(shmdt(g2h(shmaddr))) ); -+} -+ -+static inline abi_long -+target_to_host_shmid_ds(struct shmid_ds *host_sd, abi_ulong target_addr) -+{ -+ struct target_shmid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr)) -+ return (-TARGET_EFAULT); -+ __get_user(host_sd->shm_segsz, &target_sd->shm_segsz); -+ __get_user(host_sd->shm_lpid, &target_sd->shm_lpid); -+ __get_user(host_sd->shm_cpid, &target_sd->shm_cpid); -+ __get_user(host_sd->shm_nattch, &target_sd->shm_nattch); -+ __get_user(host_sd->shm_atime, &target_sd->shm_atime); -+ __get_user(host_sd->shm_dtime, &target_sd->shm_dtime); -+ __get_user(host_sd->shm_ctime, &target_sd->shm_ctime); -+ unlock_user_struct(target_sd, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_shmid_ds(abi_ulong target_addr, struct shmid_ds *host_sd) -+{ -+ struct target_shmid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm))) -+ return (-TARGET_EFAULT); -+ __put_user(host_sd->shm_segsz, &target_sd->shm_segsz); -+ __put_user(host_sd->shm_lpid, &target_sd->shm_lpid); -+ __put_user(host_sd->shm_cpid, &target_sd->shm_cpid); -+ __put_user(host_sd->shm_nattch, &target_sd->shm_nattch); -+ __put_user(host_sd->shm_atime, &target_sd->shm_atime); -+ __put_user(host_sd->shm_dtime, &target_sd->shm_dtime); -+ __put_user(host_sd->shm_ctime, &target_sd->shm_ctime); -+ unlock_user_struct(target_sd, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+do_shmctl(int shmid, int cmd, abi_long buff) -+{ -+ struct shmid_ds dsarg; -+ abi_long ret = -TARGET_EINVAL; -+ -+ cmd &= 0xff; -+ -+ switch(cmd) { -+ case IPC_STAT: -+ case IPC_SET: -+ if (target_to_host_shmid_ds(&dsarg, buff)) -+ return (-TARGET_EFAULT); -+ ret = get_errno(shmctl(shmid, cmd, &dsarg)); -+ if (host_to_target_shmid_ds(buff, &dsarg)) -+ return (-TARGET_EFAULT); -+ break; -+ -+ case IPC_RMID: -+ ret = get_errno(shmctl(shmid, cmd, NULL)); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ -+ return (ret); -+} -+ -+static inline abi_long -+target_to_host_msqid_ds(struct msqid_ds *host_md, abi_ulong target_addr) -+{ -+ struct target_msqid_ds *target_md; -+ -+ if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ if (target_to_host_ipc_perm(&(host_md->msg_perm),target_addr)) -+ return (-TARGET_EFAULT); -+ -+ /* msg_first and msg_last are not used by IPC_SET/IPC_STAT in kernel. */ -+ host_md->msg_first = host_md->msg_last = NULL; -+ -+ host_md->msg_cbytes = tswapal(target_md->msg_cbytes); -+ host_md->msg_qnum = tswapal(target_md->msg_qnum); -+ host_md->msg_qbytes = tswapal(target_md->msg_qbytes); -+ host_md->msg_lspid = tswapal(target_md->msg_lspid); -+ host_md->msg_lrpid = tswapal(target_md->msg_lrpid); -+ host_md->msg_stime = tswapal(target_md->msg_stime); -+ host_md->msg_rtime = tswapal(target_md->msg_rtime); -+ host_md->msg_ctime = tswapal(target_md->msg_ctime); -+ unlock_user_struct(target_md, target_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_msqid_ds(abi_ulong target_addr, struct msqid_ds *host_md) -+{ -+ struct target_msqid_ds *target_md; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ if (host_to_target_ipc_perm(target_addr,&(host_md->msg_perm))) -+ return (-TARGET_EFAULT); -+ -+ /* msg_first and msg_last are not used by IPC_SET/IPC_STAT in kernel. */ -+ target_md->msg_cbytes = tswapal(host_md->msg_cbytes); -+ target_md->msg_qnum = tswapal(host_md->msg_qnum); -+ target_md->msg_qbytes = tswapal(host_md->msg_qbytes); -+ target_md->msg_lspid = tswapal(host_md->msg_lspid); -+ target_md->msg_lrpid = tswapal(host_md->msg_lrpid); -+ target_md->msg_stime = tswapal(host_md->msg_stime); -+ target_md->msg_rtime = tswapal(host_md->msg_rtime); -+ target_md->msg_ctime = tswapal(host_md->msg_ctime); -+ unlock_user_struct(target_md, target_addr, 1); -+ -+ return (0); -+} -+ -+static inline abi_long -+do_msgctl(int msgid, int cmd, abi_long ptr) -+{ -+ struct msqid_ds dsarg; -+ abi_long ret = -TARGET_EINVAL; -+ -+ cmd &= 0xff; -+ -+ switch (cmd) { -+ case IPC_STAT: -+ case IPC_SET: -+ if (target_to_host_msqid_ds(&dsarg,ptr)) -+ return -TARGET_EFAULT; -+ ret = get_errno(msgctl(msgid, cmd, &dsarg)); -+ if (host_to_target_msqid_ds(ptr,&dsarg)) -+ return -TARGET_EFAULT; -+ break; -+ -+ case IPC_RMID: -+ ret = get_errno(msgctl(msgid, cmd, NULL)); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ return (ret); -+} -+ -+static inline abi_long -+do_msgsnd(int msqid, abi_long msgp, unsigned int msgsz, int msgflg) -+{ -+ struct target_msgbuf *target_mb; -+ struct mymsg *host_mb; -+ abi_long ret = 0; -+ -+ if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) -+ return (-TARGET_EFAULT); -+ -+ host_mb = malloc(msgsz+sizeof(long)); -+ host_mb->mtype = (abi_long) tswapal(target_mb->mtype); -+ memcpy(host_mb->mtext, target_mb->mtext, msgsz); -+ ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg)); -+ free(host_mb); -+ unlock_user_struct(target_mb, msgp, 0); -+ -+ return (ret); -+} -+ -+static inline abi_long -+do_msgrcv(int msqid, abi_long msgp, unsigned int msgsz, abi_long msgtyp, -+ int msgflg) -+{ -+ struct target_msgbuf *target_mb; -+ char *target_mtext; -+ struct mymsg *host_mb; -+ abi_long ret = 0; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) -+ return (-TARGET_EFAULT); -+ -+ host_mb = g_malloc(msgsz+sizeof(long)); -+ ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg)); -+ if (ret > 0) { -+ abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); -+ target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, -+ ret, 0); -+ if (!target_mtext) { -+ ret = -TARGET_EFAULT; -+ goto end; -+ } -+ memcpy(target_mb->mtext, host_mb->mtext, ret); -+ unlock_user(target_mtext, target_mtext_addr, ret); -+ } -+ target_mb->mtype = tswapal(host_mb->mtype); -+end: -+ if (target_mb) -+ unlock_user_struct(target_mb, msgp, 1); -+ g_free(host_mb); -+ return (ret); -+} -+ -+static void -+set_second_rval(CPUArchState *env, abi_ulong retval2) -+{ -+#if defined(TARGET_ALPHA) -+ ((CPUAlphaState *)env)->ir[IR_A4] = retval2; -+#elif defined(TARGET_ARM) -+ ((CPUARMState *)env)->regs[1] = retval2; -+#elif defined(TARGET_MIPS) -+ ((CPUMIPSState*)env)->active_tc.gpr[3] = retval2; -+#elif defined(TARGET_SH4) -+ ((CPUSH4State*)env)->gregs[1] = retval2; -+#elif defined(TARGET_X86_64) || defined(TARGET_I386) -+ ((CPUX86State*)env)->regs[R_EDX] = retval2; -+#elif defined(TARGET_SPARC64) || defined(TARGET_SPARC) -+ ((CPUSPARCState*)env)->regwptr[1] = retval2; -+#else -+#warning Arch not supported for returning multiple values from syscall. -+#endif -+} -+ -+/* -+ * do_fock() must return host values and target errnos (unlike most do_*() -+ * functions. -+ */ -+static int -+do_fork(CPUArchState *env, int num, int flags, int *fdp) -+{ -+ int ret, fd; -+ abi_ulong child_flag = 0; -+ -+ fork_start(); -+ switch(num) { -+ case TARGET_FREEBSD_NR_fork: -+ case TARGET_FREEBSD_NR_vfork: -+ ret = fork(); -+ break; -+ -+ case TARGET_FREEBSD_NR_rfork: -+ ret = rfork(flags); -+ break; -+ -+ case TARGET_FREEBSD_NR_pdfork: -+ ret = pdfork(&fd, flags); -+ break; -+ -+ default: -+ ret = -TARGET_ENOSYS; -+ break; -+ } -+ if (0 == ret) { -+ /* Child */ -+ child_flag = 1; -+ cpu_clone_regs(env, 0); -+ } else { -+ /* Parent */ -+ fork_end(0); -+ } -+ if (fdp != NULL) -+ *fdp = fd; -+ -+ /* -+ * The fork() syscall sets a child flag in 2nd return value: -+ * 0 for parent process, 1 for child process -+ */ -+ set_second_rval(env, child_flag); -+ -+ return (ret); -+} -+ -+/* do_syscall() should always have a single exit point at the end so -+ that actions, such as logging of syscall results, can be performed. -+ All errnos that do_syscall() returns must be -TARGET_<errcode>. */ -+abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, -+ abi_long arg5, abi_long arg6, abi_long arg7, -+ abi_long arg8) -+{ -+ abi_long ret; -+ void *p; -+ struct stat st; -+ -+#ifdef DEBUG -+ gemu_log("freebsd syscall %d\n", num); -+#endif -+ if(do_strace) -+ print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); -+ -+ switch(num) { -+ case TARGET_FREEBSD_NR_exit: -+#ifdef TARGET_GPROF -+ _mcleanup(); -+#endif -+ gdb_exit(cpu_env, arg1); -+ /* XXX: should free thread stack and CPU env */ -+ _exit(arg1); -+ ret = 0; /* avoid warning */ -+ break; -+ case TARGET_FREEBSD_NR_read: -+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -+ goto efault; -+ ret = get_errno(read(arg1, p, arg3)); -+ unlock_user(p, arg2, ret); -+ break; -+ -+ case TARGET_FREEBSD_NR_readv: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) -+ goto efault; -+ ret = get_errno(readv(arg1, vec, count)); -+ unlock_iovec(vec, arg2, count, 1); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_pread: -+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -+ goto efault; -+ ret = get_errno(pread(arg1, p, arg3, target_offset64(arg4, arg5))); -+ unlock_user(p, arg2, ret); -+ break; -+ -+ case TARGET_FREEBSD_NR_preadv: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) -+ goto efault; -+ ret = get_errno(preadv(arg1, vec, count, -+ target_offset64(arg4, arg5))); -+ unlock_iovec(vec, arg2, count, 1); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_write: -+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -+ goto efault; -+ ret = get_errno(write(arg1, p, arg3)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_writev: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -+ goto efault; -+ ret = get_errno(writev(arg1, vec, count)); -+ unlock_iovec(vec, arg2, count, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_pwrite: -+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -+ goto efault; -+ ret = get_errno(pwrite(arg1, p, arg3, target_offset64(arg4, arg5))); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_pwritev: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -+ goto efault; -+ ret = get_errno(pwritev(arg1, vec, count, -+ target_offset64(arg4, arg5))); -+ unlock_iovec(vec, arg2, count, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_open: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(open(path(p), -+ target_to_host_bitmask(arg2, fcntl_flags_tbl), -+ arg3)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_openat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(openat(arg1, path(p), -+ target_to_host_bitmask(arg3, fcntl_flags_tbl), -+ arg4)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_close: -+ ret = get_errno(close(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_closefrom: -+ ret = 0; -+ closefrom(arg1); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_creat -+ case TARGET_FREEBSD_NR_creat: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(creat(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_mmap: -+ ret = get_errno(target_mmap(arg1, arg2, arg3, -+ target_to_host_bitmask(arg4, mmap_flags_tbl), -+ arg5, -+ arg6)); -+ break; -+ -+ case TARGET_FREEBSD_NR_munmap: -+ ret = get_errno(target_munmap(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mprotect: -+ ret = get_errno(target_mprotect(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_msync: -+ ret = get_errno(msync(g2h(arg1), arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mlock: -+ ret = get_errno(mlock(g2h(arg1), arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_munlock: -+ ret = get_errno(munlock(g2h(arg1), arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mlockall: -+ ret = get_errno(mlockall(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_munlockall: -+ ret = get_errno(munlockall()); -+ break; -+ -+ case TARGET_FREEBSD_NR_madvise: -+ /* -+ * A straight passthrough may not be safe because qemu sometimes -+ * turns private file-backed mapping into anonymous mappings. This -+ * will break MADV_DONTNEED. This is a hint, so ignoring and returing -+ * success is ok. -+ */ -+ ret = get_errno(0); -+ break; -+ -+ case TARGET_FREEBSD_NR_break: -+ ret = do_obreak(arg1); -+ break; -+#ifdef __FreeBSD__ -+ case TARGET_FREEBSD_NR___sysctl: -+ ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+#endif -+ case TARGET_FREEBSD_NR_sysarch: -+ ret = do_freebsd_sysarch(cpu_env, arg1, arg2); -+ break; -+ case TARGET_FREEBSD_NR_syscall: -+ case TARGET_FREEBSD_NR___syscall: -+ ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0); -+ break; -+ -+ case TARGET_FREEBSD_NR_stat: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(stat(path(p), &st)); -+ unlock_user(p, arg1, 0); -+ goto do_stat; -+ -+ case TARGET_FREEBSD_NR_lstat: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lstat(path(p), &st)); -+ unlock_user(p, arg1, 0); -+ goto do_stat; -+ -+ case TARGET_FREEBSD_NR_nstat: -+ case TARGET_FREEBSD_NR_nfstat: -+ case TARGET_FREEBSD_NR_nlstat: -+ ret = unimplemented(num); -+ break; -+ -+ case TARGET_FREEBSD_NR_fstat: -+ { -+ ret = get_errno(fstat(arg1, &st)); -+ -+do_stat: -+ if (!is_error(ret)) { -+ struct target_freebsd_stat *target_st; -+ -+ 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); -+ __put_user(st.st_nlink, &target_st->st_nlink); -+ __put_user(st.st_uid, &target_st->st_uid); -+ __put_user(st.st_gid, &target_st->st_gid); -+ __put_user(st.st_rdev, &target_st->st_rdev); -+ __put_user(st.st_atim.tv_sec, &target_st->st_atim.tv_sec); -+ __put_user(st.st_atim.tv_nsec, &target_st->st_atim.tv_nsec); -+ __put_user(st.st_mtim.tv_sec, &target_st->st_mtim.tv_sec); -+ __put_user(st.st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); -+ __put_user(st.st_ctim.tv_sec, &target_st->st_ctim.tv_sec); -+ __put_user(st.st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); -+ __put_user(st.st_size, &target_st->st_size); -+ __put_user(st.st_blocks, &target_st->st_blocks); -+ __put_user(st.st_blksize, &target_st->st_blksize); -+ __put_user(st.st_flags, &target_st->st_flags); -+ __put_user(st.st_gen, &target_st->st_gen); -+ /* st_lspare not used */ -+ __put_user(st.st_birthtim.tv_sec, -+ &target_st->st_birthtim.tv_sec); -+ __put_user(st.st_birthtim.tv_nsec, -+ &target_st->st_birthtim.tv_nsec); -+ unlock_user_struct(target_st, arg2, 1); -+ } -+ -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_nanosleep: -+ { -+ struct timespec req, rem; -+ -+ target_to_host_timespec(&req, arg1); -+ ret = get_errno(nanosleep(&req, &rem)); -+ if (is_error(ret) && arg2) -+ host_to_target_timespec(arg2, &rem); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_clock_gettime: -+ { -+ struct timespec ts; -+ -+ ret = get_errno(clock_gettime(arg1, &ts)); -+ if (!is_error(ret)) { -+ if (host_to_target_timespec(arg2, &ts)) -+ goto efault; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_clock_getres: -+ { -+ struct timespec ts; -+ -+ ret = get_errno(clock_getres(arg1, &ts)); -+ if (!is_error(ret)) { -+ if (host_to_target_timespec(arg2, &ts)) -+ goto efault; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_clock_settime: -+ { -+ struct timespec ts; -+ -+ if (target_to_host_timespec(&ts, arg2) != 0) -+ goto efault; -+ ret = get_errno(clock_settime(arg1, &ts)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_gettimeofday: -+ { -+ struct timeval tv; -+ struct timezone tz, *target_tz; -+ if (arg2 != 0) { -+ if (!lock_user_struct(VERIFY_READ, target_tz, arg2, 0)) -+ goto efault; -+ __get_user(tz.tz_minuteswest, -+ &target_tz->tz_minuteswest); -+ __get_user(tz.tz_dsttime, &target_tz->tz_dsttime); -+ unlock_user_struct(target_tz, arg2, 1); -+ } -+ ret = get_errno(gettimeofday(&tv, arg2 != 0 ? &tz : NULL)); -+ if (!is_error(ret)) { -+ if (fbsd_copy_to_user_timeval(&tv, arg1)) -+ goto efault; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_settimeofday: -+ { -+ struct timeval tv; -+ struct timezone tz, *target_tz; -+ -+ if (arg2 != 0) { -+ if (!lock_user_struct(VERIFY_READ, target_tz, arg2, 0)) -+ goto efault; -+ __get_user(tz.tz_minuteswest, -+ &target_tz->tz_minuteswest); -+ __get_user(tz.tz_dsttime, &target_tz->tz_dsttime); -+ unlock_user_struct(target_tz, arg2, 1); -+ } -+ if (copy_from_user_timeval(&tv, arg1)) -+ goto efault; -+ ret = get_errno(settimeofday(&tv, arg2 != 0 ? & tz : NULL)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_ktimer_create: -+ case TARGET_FREEBSD_NR_ktimer_delete: -+ case TARGET_FREEBSD_NR_ktimer_settime: -+ case TARGET_FREEBSD_NR_ktimer_gettime: -+ case TARGET_FREEBSD_NR_ktimer_getoverrun: -+ case TARGET_FREEBSD_NR_minherit: -+ ret = unimplemented(num); -+ break; -+ -+ case TARGET_FREEBSD_NR_kqueue: -+ ret = get_errno(kqueue()); -+ break; -+ -+#ifdef __FreeBSD__ -+ case TARGET_FREEBSD_NR_kevent: -+ { -+ struct kevent *changelist = NULL, *eventlist = NULL; -+ struct target_kevent *target_changelist, *target_eventlist; -+ struct timespec ts; -+ int i; -+ -+ if (arg3 != 0) { -+ if (!(target_changelist = lock_user(VERIFY_READ, arg2, -+ sizeof(struct target_kevent) * arg3, 1))) -+ goto efault; -+ changelist = alloca(sizeof(struct kevent) * arg3); -+ -+ for (i = 0; i < arg3; i++) { -+ __get_user(changelist[i].ident, &target_changelist[i].ident); -+ __get_user(changelist[i].filter, &target_changelist[i].filter); -+ __get_user(changelist[i].flags, &target_changelist[i].flags); -+ __get_user(changelist[i].fflags, &target_changelist[i].fflags); -+ __get_user(changelist[i].data, &target_changelist[i].data); -+ /* XXX: This is broken when running a 64bits target on a 32bits host */ -+ /* __get_user(changelist[i].udata, &target_changelist[i].udata); */ -+#if TARGET_ABI_BITS == 32 -+ changelist[i].udata = (void *)(uintptr_t)target_changelist[i].udata; -+ tswap32s((uint32_t *)&changelist[i].udata); -+#else -+ changelist[i].udata = (void *)(uintptr_t)target_changelist[i].udata; -+ tswap64s((uint64_t *)&changelist[i].udata); -+#endif -+ } -+ unlock_user(target_changelist, arg2, 0); -+ } -+ -+ if (arg5 != 0) -+ eventlist = alloca(sizeof(struct kevent) * arg5); -+ if (arg6 != 0) -+ if (target_to_host_timespec(&ts, arg6)) -+ goto efault; -+ ret = get_errno(kevent(arg1, changelist, arg3, eventlist, arg5, -+ arg6 != 0 ? &ts : NULL)); -+ if (!is_error(ret)) { -+ if (!(target_eventlist = lock_user(VERIFY_WRITE, arg4, -+ sizeof(struct target_kevent) * arg5, 0))) -+ goto efault; -+ for (i = 0; i < arg5; i++) { -+ __put_user(eventlist[i].ident, &target_eventlist[i].ident); -+ __put_user(eventlist[i].filter, &target_eventlist[i].filter); -+ __put_user(eventlist[i].flags, &target_eventlist[i].flags); -+ __put_user(eventlist[i].fflags, &target_eventlist[i].fflags); -+ __put_user(eventlist[i].data, &target_eventlist[i].data); -+ /* __put_user(eventlist[i].udata, &target_eventlist[i].udata); */ -+#if TARGET_ABI_BITS == 32 -+ tswap32s((uint32_t *)&eventlist[i].data); -+ target_eventlist[i].data = (uintptr_t)eventlist[i].data; -+#else -+ tswap64s((uint64_t *)&eventlist[i].data); -+ target_eventlist[i].data = (uintptr_t)eventlist[i].data; -+#endif -+ } -+ unlock_user(target_eventlist, arg4, sizeof(struct target_kevent) * arg5); -+ -+ -+ } -+ } -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_execve: -+ { -+ char **argp, **envp; -+ int argc, envc; -+ abi_ulong gp; -+ abi_ulong guest_argp; -+ abi_ulong guest_envp; -+ abi_ulong addr; -+ char **q; -+ int total_size = 0; -+ -+ argc = 0; -+ guest_argp = arg2; -+ for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) { -+ if (get_user_ual(addr, gp)) -+ goto efault; -+ if (!addr) -+ break; -+ argc++; -+ } -+ envc = 0; -+ guest_envp = arg3; -+ for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) { -+ if (get_user_ual(addr, gp)) -+ goto efault; -+ if (!addr) -+ break; -+ envc++; -+ } -+ -+ argp = alloca((argc + 1) * sizeof(void *)); -+ envp = alloca((envc + 1) * sizeof(void *)); -+ -+ for (gp = guest_argp, q = argp; gp; -+ gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp)) -+ goto execve_efault; -+ if (!addr) -+ break; -+ if (!(*q = lock_user_string(addr))) -+ goto execve_efault; -+ total_size += strlen(*q) + 1; -+ } -+ *q = NULL; -+ -+ for (gp = guest_envp, q = envp; gp; -+ gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp)) -+ goto execve_efault; -+ if (!addr) -+ break; -+ if (!(*q = lock_user_string(addr))) -+ goto execve_efault; -+ total_size += strlen(*q) + 1; -+ } -+ *q = NULL; -+ -+ /* This case will not be caught by the host's execve() if its -+ page size is bigger than the target's. */ -+ if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) { -+ ret = -TARGET_E2BIG; -+ goto execve_end; -+ } -+ if (!(p = lock_user_string(arg1))) -+ goto execve_efault; -+ ret = get_errno(execve(p, argp, envp)); -+ unlock_user(p, arg1, 0); -+ -+ goto execve_end; -+ -+ execve_efault: -+ ret = -TARGET_EFAULT; -+ -+ execve_end: -+ for (gp = guest_argp, q = argp; *q; -+ gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp) -+ || !addr) -+ break; -+ unlock_user(*q, addr, 0); -+ } -+ for (gp = guest_envp, q = envp; *q; -+ gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp) -+ || !addr) -+ break; -+ unlock_user(*q, addr, 0); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_pipe: -+ { -+ int host_pipe[2]; -+ int host_ret = pipe(host_pipe); -+ -+ if (!is_error(host_ret)) { -+ set_second_rval(cpu_env, host_pipe[1]); -+ ret = host_pipe[0]; -+ } else -+ ret = get_errno(host_ret); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_lseek: -+ { -+#if defined(TARGET_MIPS) && TARGET_ABI_BITS == 32 -+ /* 32-bit MIPS uses two 32 registers for 64 bit arguments */ -+ int64_t res = lseek(arg1, target_offset64(arg2, arg3), arg4); -+ -+ if (res == -1) { -+ ret = get_errno(res); -+ } else { -+ ret = res & 0xFFFFFFFF; -+ ((CPUMIPSState*)cpu_env)->active_tc.gpr[3] = -+ (res >> 32) & 0xFFFFFFFF; -+ } -+#else -+ ret = get_errno(lseek(arg1, arg2, arg3)); -+#endif -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_select: -+ ret = do_freebsd_select(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_pselect: -+ ret = do_freebsd_pselect(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_poll: -+ { -+ nfds_t i, nfds = arg2; -+ int timeout = arg3; -+ struct pollfd *pfd; -+ struct target_pollfd *target_pfd = lock_user(VERIFY_WRITE, arg1, -+ sizeof(struct target_pollfd) * nfds, 1); -+ -+ if (!target_pfd) -+ goto efault; -+ -+ pfd = alloca(sizeof(struct pollfd) * nfds); -+ for(i = 0; i < nfds; i++) { -+ pfd[i].fd = tswap32(target_pfd[i].fd); -+ pfd[i].events = tswap16(target_pfd[i].events); -+ } -+ ret = get_errno(poll(pfd, nfds, timeout)); -+ -+ if (!is_error(ret)) { -+ for(i = 0; i < nfds; i++) { -+ target_pfd[i].revents = tswap16(pfd[i].revents); -+ } -+ } -+ unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * -+ nfds); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_openbsd_poll: -+ ret = unimplemented(num); -+ break; -+ -+ case TARGET_FREEBSD_NR_setrlimit: -+ { -+ int resource = target_to_host_resource(arg1); -+ struct target_rlimit *target_rlim; -+ struct rlimit rlim; -+ -+ if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) -+ goto efault; -+ rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur); -+ rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max); -+ unlock_user_struct(target_rlim, arg2, 0); -+ ret = get_errno(setrlimit(resource, &rlim)); -+ } -+ break; -+ -+ -+ case TARGET_FREEBSD_NR_getrlimit: -+ { -+ int resource = target_to_host_resource(arg1); -+ struct target_rlimit *target_rlim; -+ struct rlimit rlim; -+ -+ ret = get_errno(getrlimit(resource, &rlim)); -+ if (!is_error(ret)) { -+ if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, -+ 0)) -+ goto efault; -+ target_rlim->rlim_cur = -+ host_to_target_rlim(rlim.rlim_cur); -+ target_rlim->rlim_max = -+ host_to_target_rlim(rlim.rlim_max); -+ unlock_user_struct(target_rlim, arg2, 1); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_setitimer: -+ { -+ struct itimerval value, ovalue, *pvalue; -+ -+ if (arg2) { -+ pvalue = &value; -+ if (copy_from_user_timeval(&pvalue->it_interval, -+ arg2) || copy_from_user_timeval( -+ &pvalue->it_value, arg2 + -+ sizeof(struct target_timeval))) -+ goto efault; -+ } else { -+ pvalue = NULL; -+ } -+ ret = get_errno(setitimer(arg1, pvalue, &ovalue)); -+ if (!is_error(ret) && arg3) { -+ if (fbsd_copy_to_user_timeval(&ovalue.it_interval, arg3) -+ || fbsd_copy_to_user_timeval(&ovalue.it_value, -+ arg3 + sizeof(struct target_timeval))) -+ goto efault; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_getitimer: -+ { -+ struct itimerval value; -+ -+ ret = get_errno(getitimer(arg1, &value)); -+ if (!is_error(ret) && arg2) { -+ if (fbsd_copy_to_user_timeval(&value.it_interval, arg2) -+ || fbsd_copy_to_user_timeval(&value.it_value, -+ arg2 + sizeof(struct target_timeval))) -+ goto efault; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_utimes: -+ { -+ struct timeval *tvp, tv[2]; -+ -+ if (arg2) { -+ if (copy_from_user_timeval(&tv[0], arg2) -+ || copy_from_user_timeval(&tv[1], -+ arg2 + sizeof(struct target_timeval))) -+ -+ goto efault; -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(utimes(p, tvp)); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_lutimes: -+ { -+ struct timeval *tvp, tv[2]; -+ -+ if (arg2) { -+ if (copy_from_user_timeval(&tv[0], arg2) -+ || copy_from_user_timeval(&tv[1], -+ arg2 + sizeof(struct target_timeval))) -+ -+ goto efault; -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lutimes(p, tvp)); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_futimes: -+ { -+ struct timeval *tvp, tv[2]; -+ -+ if (arg2) { -+ if (copy_from_user_timeval(&tv[0], arg2) -+ || copy_from_user_timeval(&tv[1], -+ arg2 + sizeof(struct target_timeval))) -+ goto efault; -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ ret = get_errno(futimes(arg1, tvp)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_futimesat: -+ { -+ struct timeval *tvp, tv[2]; -+ -+ if (arg3) { -+ if (copy_from_user_timeval(&tv[0], arg3) -+ || copy_from_user_timeval(&tv[1], -+ arg3 + sizeof(struct target_timeval))) -+ goto efault; -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(futimesat(arg1, path(p), tvp)); -+ unlock_user(p, arg2, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_access: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(access(path(p), arg2)); -+ unlock_user(p, arg1, 0); -+ -+ case TARGET_FREEBSD_NR_eaccess: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(eaccess(path(p), arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_faccessat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(faccessat(arg1, p, arg3, arg4)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_chdir: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(chdir(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchdir: -+ ret = get_errno(fchdir(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_rename: -+ { -+ void *p2; -+ -+ p = lock_user_string(arg1); -+ p2 = lock_user_string(arg2); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(rename(p, p2)); -+ unlock_user(p2, arg2, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_renameat: -+ { -+ void *p2; -+ -+ p = lock_user_string(arg2); -+ p2 = lock_user_string(arg4); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(renameat(arg1, p, arg3, p2)); -+ unlock_user(p2, arg4, 0); -+ unlock_user(p, arg2, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_link: -+ { -+ void * p2; -+ -+ p = lock_user_string(arg1); -+ p2 = lock_user_string(arg2); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(link(p, p2)); -+ unlock_user(p2, arg2, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_linkat: -+ { -+ void * p2 = NULL; -+ -+ if (!arg2 || !arg4) -+ goto efault; -+ -+ p = lock_user_string(arg2); -+ p2 = lock_user_string(arg4); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(linkat(arg1, p, arg3, p2, arg5)); -+ unlock_user(p, arg2, 0); -+ unlock_user(p2, arg4, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_unlink: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(unlink(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_unlinkat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(unlinkat(arg1, p, arg3)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkdir: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(mkdir(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkdirat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(mkdirat(arg1, p, arg3)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_rmdir: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(rmdir(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR___getcwd: -+ if (!(p = lock_user(VERIFY_WRITE, arg1, arg2, 0))) -+ goto efault; -+ ret = get_errno(__getcwd(p, arg2)); -+ unlock_user(p, arg1, ret); -+ break; -+ -+ case TARGET_FREEBSD_NR_dup: -+ ret = get_errno(dup(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_dup2: -+ ret = get_errno(dup2(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_truncate: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (regpairs_aligned(cpu_env)) { -+ arg2 = arg3; -+ arg3 = arg4; -+ } -+ ret = get_errno(truncate(p, target_offset64(arg2, arg3))); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_ftruncate: -+ if (regpairs_aligned(cpu_env)) { -+ arg2 = arg3; -+ arg3 = arg4; -+ } -+ ret = get_errno(ftruncate(arg1, target_offset64(arg2, arg3))); -+ break; -+ -+ case TARGET_FREEBSD_NR_acct: -+ if (arg1 == 0) { -+ ret = get_errno(acct(NULL)); -+ } else { -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(acct(path(p))); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sync: -+ sync(); -+ ret = 0; -+ break; -+ -+ case TARGET_FREEBSD_NR_mount: -+ { -+ void *p2; -+ -+ /* We need to look at the data field. */ -+ p = lock_user_string(arg1); /* type */ -+ p2 = lock_user_string(arg2); /* dir */ -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else { -+ /* -+ * XXX arg5 should be locked, but it isn't clear -+ * how to do that since it's it may be not be a -+ * NULL-terminated string. -+ */ -+ if ( ! arg5 ) -+ ret = get_errno(mount(p, p2, arg3, NULL)); -+ else -+ ret = get_errno(mount(p, p2, arg3, g2h(arg5))); -+ } -+ unlock_user(p, arg1, 0); -+ unlock_user(p2, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_unmount: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(unmount(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_nmount: -+ { -+ int count = arg2; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -+ goto efault; -+ ret = get_errno(nmount(vec, count, arg3)); -+ unlock_iovec(vec, arg2, count, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_symlink: -+ { -+ void *p2; -+ -+ p = lock_user_string(arg1); -+ p2 = lock_user_string(arg2); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(symlink(p, p2)); -+ unlock_user(p2, arg2, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_symlinkat: -+ { -+ void *p2; -+ -+ p = lock_user_string(arg1); -+ p2 = lock_user_string(arg3); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(symlinkat(p, arg2, p2)); -+ unlock_user(p2, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_readlink: -+ { -+ void *p2; -+ -+ p = lock_user_string(arg1); -+ p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(readlink(path(p), p2, arg3)); -+ unlock_user(p2, arg2, ret); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_readlinkat: -+ { -+ void *p2; -+ p = lock_user_string(arg2); -+ p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); -+ -+ if (!p || !p2) -+ ret = -TARGET_EFAULT; -+ else -+ ret = get_errno(readlinkat(arg1, path(p), p2, arg4)); -+ unlock_user(p2, arg3, ret); -+ unlock_user(p, arg2, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_chmod: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(chmod(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchmod: -+ ret = get_errno(fchmod(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_lchmod: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lchmod(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchmodat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(fchmodat(arg1, p, arg3, arg4)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_mknod: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(mknod(p, arg2, arg3)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_mknodat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(mknodat(arg1, p, arg3, arg4)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_chown: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(chown(p, arg2, arg3)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchown: -+ ret = get_errno(fchown(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_lchown: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lchown(p, arg2, arg3)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchownat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(fchownat(arg1, p, arg3, arg4, arg5)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_chflags: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(chflags(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_lchflags: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lchflags(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchflags: -+ ret = get_errno(fchflags(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_getgroups: -+ { -+ int gidsetsize = arg1; -+ uint32_t *target_grouplist; -+ gid_t *grouplist; -+ int i; -+ -+ grouplist = alloca(gidsetsize * sizeof(gid_t)); -+ ret = get_errno(getgroups(gidsetsize, grouplist)); -+ if (gidsetsize == 0) -+ break; -+ if (!is_error(ret)) { -+ target_grouplist = lock_user(VERIFY_WRITE, arg2, -+ gidsetsize * 2, 0); -+ if (!target_grouplist) -+ goto efault; -+ for (i = 0;i < ret; i++) -+ target_grouplist[i] = tswap32(grouplist[i]); -+ unlock_user(target_grouplist, arg2, gidsetsize * 2); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_setgroups: -+ { -+ int gidsetsize = arg1; -+ uint32_t *target_grouplist; -+ gid_t *grouplist; -+ int i; -+ -+ grouplist = alloca(gidsetsize * sizeof(gid_t)); -+ target_grouplist = lock_user(VERIFY_READ, arg2, -+ gidsetsize * 2, 1); -+ if (!target_grouplist) { -+ ret = -TARGET_EFAULT; -+ goto fail; -+ } -+ for(i = 0;i < gidsetsize; i++) -+ grouplist[i] = tswap32(target_grouplist[i]); -+ unlock_user(target_grouplist, arg2, 0); -+ ret = get_errno(setgroups(gidsetsize, grouplist)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_umask: -+ ret = get_errno(umask(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_fcntl: -+ { -+ int host_cmd; -+ struct flock fl; -+ struct target_flock *target_fl; -+ -+ host_cmd = target_to_host_fcntl_cmd(arg2); -+ if (-TARGET_EINVAL == host_cmd) { -+ ret = host_cmd; -+ break; -+ } -+ -+ switch(arg2) { -+ case TARGET_F_GETLK: -+ if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) -+ return (-TARGET_EFAULT); -+ fl.l_type = tswap16(target_fl->l_type); -+ fl.l_whence = tswap16(target_fl->l_whence); -+ fl.l_start = tswapal(target_fl->l_start); -+ fl.l_len = tswapal(target_fl->l_len); -+ fl.l_pid = tswap32(target_fl->l_pid); -+ fl.l_sysid = tswap32(target_fl->l_sysid); -+ unlock_user_struct(target_fl, arg3, 0); -+ ret = get_errno(fcntl(arg1, host_cmd, &fl)); -+ if (0 == ret) { -+ if (!lock_user_struct(VERIFY_WRITE, target_fl, -+ arg3, 0)) -+ return (-TARGET_EFAULT); -+ target_fl->l_type = tswap16(fl.l_type); -+ target_fl->l_whence = tswap16(fl.l_whence); -+ target_fl->l_start = tswapal(fl.l_start); -+ target_fl->l_len = tswapal(fl.l_len); -+ target_fl->l_pid = tswap32(fl.l_pid); -+ target_fl->l_sysid = tswap32(fl.l_sysid); -+ unlock_user_struct(target_fl, arg3, 1); -+ } -+ break; -+ -+ case TARGET_F_SETLK: -+ case TARGET_F_SETLKW: -+ if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) -+ return (-TARGET_EFAULT); -+ fl.l_type = tswap16(target_fl->l_type); -+ fl.l_whence = tswap16(target_fl->l_whence); -+ fl.l_start = tswapal(target_fl->l_start); -+ fl.l_len = tswapal(target_fl->l_len); -+ fl.l_pid = tswap32(target_fl->l_pid); -+ fl.l_sysid = tswap32(target_fl->l_sysid); -+ unlock_user_struct(target_fl, arg3, 0); -+ ret = get_errno(fcntl(arg1, host_cmd, &fl)); -+ break; -+ -+ case TARGET_F_DUPFD: -+ case TARGET_F_DUP2FD: -+ case TARGET_F_GETOWN: -+ case TARGET_F_SETOWN: -+ case TARGET_F_GETFD: -+ case TARGET_F_SETFD: -+ case TARGET_F_GETFL: -+ case TARGET_F_SETFL: -+ case TARGET_F_READAHEAD: -+ case TARGET_F_RDAHEAD: -+ default: -+ ret = get_errno(fcntl(arg1, host_cmd, arg3)); -+ break; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_getdents: -+ { -+ struct dirent *dirp; -+ int32_t nbytes = arg3; -+ -+ if (!(dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0))) -+ goto efault; -+ ret = get_errno(getdents(arg1, (char *)dirp, nbytes)); -+ if (!is_error(ret)) { -+ struct dirent *de; -+ int len = ret; -+ int reclen; -+ -+ de = dirp; -+ while (len > 0) { -+ reclen = de->d_reclen; -+ if (reclen > len) -+ break; -+ de->d_reclen = tswap16(reclen); -+ len -= reclen; -+ } -+ } -+ unlock_user(dirp, arg2, ret); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_getdirentries: -+ { -+ struct dirent *dirp; -+ int32_t nbytes = arg3; -+ long basep; -+ -+ if (!(dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0))) -+ goto efault; -+ ret = get_errno(getdirentries(arg1, (char *)dirp, nbytes, -+ &basep)); -+ if (!is_error(ret)) { -+ struct dirent *de; -+ int len = ret; -+ int reclen; -+ -+ de = dirp; -+ while (len > 0) { -+ reclen = de->d_reclen; -+ if (reclen > len) -+ break; -+ de->d_reclen = tswap16(reclen); -+ len -= reclen; -+ } -+ } -+ unlock_user(dirp, arg2, ret); -+ if (arg4) -+ if (put_user(nbytes, arg4, abi_ulong)) -+ ret = -TARGET_EFAULT; -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_chroot: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(chroot(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_flock: -+ ret = get_errno(flock(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkfifo: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(mkfifo(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkfifoat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(mkfifoat(arg1, p, arg2)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_pathconf: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(pathconf(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_lpathconf: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lpathconf(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fpathconf: -+ ret = get_errno(fpathconf(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_undelete: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(undelete(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ -+ case TARGET_FREEBSD_NR___acl_get_file: -+ case TARGET_FREEBSD_NR___acl_set_file: -+ case TARGET_FREEBSD_NR___acl_get_fd: -+ case TARGET_FREEBSD_NR___acl_set_fd: -+ case TARGET_FREEBSD_NR___acl_delete_file: -+ case TARGET_FREEBSD_NR___acl_delete_fd: -+ case TARGET_FREEBSD_NR___acl_aclcheck_file: -+ case TARGET_FREEBSD_NR___acl_aclcheck_fd: -+ case TARGET_FREEBSD_NR___acl_get_link: -+ case TARGET_FREEBSD_NR___acl_set_link: -+ case TARGET_FREEBSD_NR___acl_delete_link: -+ case TARGET_FREEBSD_NR___acl_aclcheck_link: -+ case TARGET_FREEBSD_NR_extattrctl: -+ case TARGET_FREEBSD_NR_extattr_set_file: -+ case TARGET_FREEBSD_NR_extattr_get_file: -+ case TARGET_FREEBSD_NR_extattr_delete_file: -+ case TARGET_FREEBSD_NR_extattr_set_fd: -+ case TARGET_FREEBSD_NR_extattr_get_fd: -+ case TARGET_FREEBSD_NR_extattr_delete_fd: -+ case TARGET_FREEBSD_NR_extattr_get_link: -+ case TARGET_FREEBSD_NR_extattr_set_link: -+ case TARGET_FREEBSD_NR_extattr_delete_link: -+ case TARGET_FREEBSD_NR_extattr_list_fd: -+ case TARGET_FREEBSD_NR_extattr_list_file: -+ case TARGET_FREEBSD_NR_extattr_list_link: -+ ret = unimplemented(num); -+ break; -+ -+ case TARGET_FREEBSD_NR_setlogin: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(setlogin(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_getlogin: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(_getlogin(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_setloginclass: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(setloginclass(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_getloginclass: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(getloginclass(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_getrusage: -+ { -+ struct rusage rusage; -+ ret = get_errno(getrusage(arg1, &rusage)); -+ if (!is_error(ret)) -+ host_to_target_rusage(arg2, &rusage); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_wait4: -+ { -+ int status; -+ abi_long status_ptr = arg2; -+ struct rusage rusage, *rusage_ptr; -+ abi_ulong target_rusage = arg4; -+ -+ if (target_rusage) -+ rusage_ptr = &rusage; -+ else -+ rusage_ptr = NULL; -+ ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); -+ if (!is_error(ret)) { -+ status = host_to_target_waitstatus(status); -+ if (put_user_s32(status, status_ptr)) -+ goto efault; -+ if (target_rusage) -+ host_to_target_rusage(target_rusage, &rusage); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_accept: -+ ret = do_accept(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_bind: -+ ret = do_bind(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_connect: -+ ret = do_connect(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpeername: -+ ret = do_getpeername(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getsockname: -+ ret = do_getsockname(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getsockopt: -+ ret = do_getsockopt(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_setsockopt: -+ ret = do_setsockopt(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_listen: -+ ret = get_errno(listen(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_recvfrom: -+ ret = do_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_recvmsg: -+ ret = do_sendrecvmsg(arg1, arg2, arg3, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_sendmsg: -+ ret = do_sendrecvmsg(arg1, arg2, arg3, 1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sendto: -+ ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_socket: -+ ret = get_errno(socket(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_socketpair: -+ ret = do_socketpair(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpriority: -+ /* -+ * Note that negative values are valid for getpriority, so we must -+ * differentiate based on errno settings. -+ */ -+ errno = 0; -+ ret = getpriority(arg1, arg2); -+ if (ret == -1 && errno != 0) { -+ ret = -host_to_target_errno(errno); -+ break; -+ } -+ /* Return value is a biased priority to avoid negative numbers. */ -+ ret = 20 - ret; -+ break; -+ -+ case TARGET_FREEBSD_NR_setpriority: -+ ret = get_errno(setpriority(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_semget: -+ ret = get_errno(semget(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_semop: -+ ret = get_errno(do_semop(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR___semctl: -+ ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_msgctl: -+ ret = do_msgctl(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_msgrcv: -+ ret = do_msgrcv(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_msgsnd: -+ ret = do_msgsnd(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmget: -+ ret = get_errno(shmget(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmctl: -+ ret = do_shmctl(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmat: -+ ret = do_shmat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmdt: -+ ret = do_shmdt(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_shm_open: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(shm_open(path(p), -+ target_to_host_bitmask(arg2, fcntl_flags_tbl), -+ arg3)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_shm_unlink: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(shm_unlink(p)); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpid: -+ ret = get_errno(getpid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_getppid: -+ ret = get_errno(getppid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_getuid: -+ ret = get_errno(getuid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_geteuid: -+ ret = get_errno(geteuid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_getgid: -+ ret = get_errno(getgid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_getegid: -+ ret = get_errno(getegid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_setuid: -+ ret = get_errno(setuid(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_setgid: -+ ret = get_errno(setgid(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_setegid: -+ ret = get_errno(setegid(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_seteuid: -+ ret = get_errno(setegid(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpgrp: -+ ret = get_errno(getpgrp()); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_setpgrp -+ case TARGET_FREEBSD_NR_setpgrp: -+ ret = get_errno(setpgrp(arg1, arg2)); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_setreuid: -+ ret = get_errno(setreuid(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_setregid: -+ ret = get_errno(setregid(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_setresuid: -+ ret = get_errno(setresuid(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_setresgid: -+ ret = get_errno(setresgid(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_getresuid: -+ case TARGET_FREEBSD_NR_getresgid: -+ ret = unimplemented(num); -+ break; -+ -+ case TARGET_FREEBSD_NR_setsid: -+ ret = get_errno(setsid()); -+ break; -+ -+ case TARGET_FREEBSD_NR_getsid: -+ ret = get_errno(getsid(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_setfib: -+ ret = get_errno(setfib(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR___setugid: -+ ret = get_errno(__setugid(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_issetugid: -+ ret = get_errno(issetugid()); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_wait -+ case TARGET_FREEBSD_NR_wait: -+ ret = get_errno(wait()); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_fork: -+ ret = get_errno(do_fork(cpu_env, num, 0, NULL)); -+ break; -+ -+ case TARGET_FREEBSD_NR_rfork: -+ ret = get_errno(do_fork(cpu_env, num, arg1, NULL)); -+ break; -+ -+ case TARGET_FREEBSD_NR_vfork: -+ ret = get_errno(do_fork(cpu_env, num, 0, NULL)); -+ break; -+ -+ case TARGET_FREEBSD_NR_pdfork: -+ { -+ int pd; -+ -+ ret = get_errno(do_fork(cpu_env, num, arg2, &pd)); -+ if (put_user_s32(pd, arg1)) -+ goto efault; -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_kill: -+ ret = get_errno(kill(arg1, target_to_host_signal(arg2))); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_killpg -+ case TARGET_FREEBSD_NR_killpg: -+ ret = get_errno(killpg(arg1, target_to_host_signal(arg2))); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_sigaction: -+ { -+ struct target_sigaction *old_act, act, oact, *pact; -+ -+ if (arg2) { -+ if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) -+ goto efault; -+ act._sa_handler = old_act->_sa_handler; -+ act.sa_flags = old_act->sa_flags; -+ memcpy(&act.sa_mask, &old_act->sa_mask, -+ sizeof(target_sigset_t)); -+ unlock_user_struct(old_act, arg2, 0); -+ pact = &act; -+ } else { -+ pact = NULL; -+ } -+ ret = get_errno(do_sigaction(arg1, pact, &oact)); -+ if (!is_error(ret) && arg3) { -+ if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) -+ goto efault; -+ old_act->_sa_handler = oact._sa_handler; -+ old_act->sa_flags = oact.sa_flags; -+ memcpy(&old_act->sa_mask, &oact.sa_mask, -+ sizeof(target_sigset_t)); -+ unlock_user_struct(old_act, arg3, 1); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigprocmask: -+ { -+ sigset_t set, oldset, *set_ptr; -+ int how; -+ -+ if (arg2) { -+ switch (arg1) { -+ case TARGET_SIG_BLOCK: -+ how = SIG_BLOCK; -+ break; -+ -+ case TARGET_SIG_UNBLOCK: -+ how = SIG_UNBLOCK; -+ break; -+ -+ case TARGET_SIG_SETMASK: -+ how = SIG_SETMASK; -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ goto fail; -+ } -+ if (!(p = lock_user(VERIFY_READ, arg2, -+ sizeof(target_sigset_t), 1))) -+ goto efault; -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg2, 0); -+ set_ptr = &set; -+ } else { -+ how = 0; -+ set_ptr = NULL; -+ } -+ ret = get_errno(sigprocmask(how, set_ptr, &oldset)); -+ if (!is_error(ret) && arg3) { -+ if (!(p = lock_user(VERIFY_WRITE, arg3, -+ sizeof(target_sigset_t), 0))) -+ goto efault; -+ host_to_target_sigset(p, &oldset); -+ unlock_user(p, arg3, sizeof(target_sigset_t)); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigpending: -+ { -+ sigset_t set; -+ -+ ret = get_errno(sigpending(&set)); -+ if (!is_error(ret)) { -+ if (!(p = lock_user(VERIFY_WRITE, arg1, -+ sizeof(target_sigset_t), 0))) -+ goto efault; -+ host_to_target_sigset(p, &set); -+ unlock_user(p, arg1, sizeof(target_sigset_t)); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigsuspend: -+ { -+ sigset_t set; -+ -+ if (!(p = lock_user(VERIFY_READ, arg1, -+ sizeof(target_sigset_t), 1))) -+ goto efault; -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ ret = get_errno(sigsuspend(&set)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigreturn: -+ ret = do_sigreturn(cpu_env, arg1); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_sigvec -+ case TARGET_FREEBSD_NR_sigvec: -+ ret = unimplemented(num); -+ break; -+#endif -+#ifdef TARGET_FREEBSD_NR_sigblock -+ case TARGET_FREEBSD_NR_sigblock: -+ ret = unimplemented(num); -+ break; -+#endif -+#ifdef TARGET_FREEBSD_NR_sigsetmask -+ case TARGET_FREEBSD_NR_sigsetmask: -+ ret = unimplemented(num); -+ break; -+#endif -+#ifdef TARGET_FREEBSD_NR_sigstack -+ case TARGET_FREEBSD_NR_sigstack: -+ ret = unimplemented(num); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_sigwait: -+ { -+ sigset_t set; -+ int sig; -+ -+ if (!(p = lock_user(VERIFY_READ, arg1, -+ sizeof(target_sigset_t), 1))) -+ goto efault; -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ ret = get_errno(sigwait(&set, &sig)); -+ if (!is_error(ret) && arg2) { -+ /* XXX */ -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigtimedwait: -+ { -+ sigset_t set; -+ struct timespec uts, *puts; -+ siginfo_t uinfo; -+ -+ if (!(p = lock_user(VERIFY_READ, arg1, -+ sizeof(target_sigset_t), 1))) -+ goto efault; -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ if (arg3) { -+ puts = &uts; -+ target_to_host_timespec(puts, arg3); -+ } else { -+ puts = NULL; -+ } -+ ret = get_errno(sigtimedwait(&set, &uinfo, puts)); -+ if (!is_error(ret) && arg2) { -+ if (!(p = lock_user(VERIFY_WRITE, arg2, -+ sizeof(target_siginfo_t), 0))) -+ goto efault; -+ host_to_target_siginfo(p, &uinfo); -+ unlock_user(p, arg2, sizeof(target_siginfo_t)); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigwaitinfo: -+ { -+ sigset_t set; -+ siginfo_t uinfo; -+ -+ if (!(p = lock_user(VERIFY_READ, arg1, -+ sizeof(target_sigset_t), 1))) -+ goto efault; -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ ret = get_errno(sigwaitinfo(&set, &uinfo)); -+ if (!is_error(ret) && arg2) { -+ if (!(p = lock_user(VERIFY_WRITE, arg2, -+ sizeof(target_siginfo_t), 0))) -+ goto efault; -+ host_to_target_siginfo(p, &uinfo); -+ unlock_user(p, arg2, sizeof(target_siginfo_t)); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigqueue: -+ { -+ union sigval value; -+ -+ value.sival_ptr = (void *)(uintptr_t)arg3; -+ ret = get_errno(sigqueue(arg1, target_to_host_signal(arg2), -+ value)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_sigaltstack: -+ { -+ -+ ret = do_sigaltstack(arg1, arg2, -+ get_sp_from_cpustate((CPUArchState *)cpu_env)); -+ } -+ -+#ifdef TARGET_FREEBSD_NR_aio_read -+ case TARGET_FREEBSD_NR_aio_read: -+#endif -+#ifdef TARGET_FREEBSD_NR_aio_write -+ case TARGET_FREEBSD_NR_aio_write: -+#endif -+#ifdef TARGET_FREEBSD_NR_aio_return -+ case TARGET_FREEBSD_NR_aio_return: -+#endif -+#ifdef TARGET_FREEBSD_NR_aio_suspend -+ case TARGET_FREEBSD_NR_aio_suspend: -+#endif -+#ifdef TARGET_FREEBSD_NR_aio_cancel -+ case TARGET_FREEBSD_NR_aio_cancel: -+#endif -+#ifdef TARGET_FREEBSD_NR_aio_error -+ case TARGET_FREEBSD_NR_aio_error: -+#endif -+#ifdef TARGET_FREEBSD_NR_aio_waitcomplete -+ case TARGET_FREEBSD_NR_aio_waitcomplete: -+#endif -+#ifdef TARGET_FREEBSD_NR_lio_listio -+ case TARGET_FREEBSD_NR_lio_listio: -+#endif -+ -+ case TARGET_FREEBSD_NR_yield: -+ case TARGET_FREEBSD_NR_sched_setparam: -+ case TARGET_FREEBSD_NR_sched_getparam: -+ case TARGET_FREEBSD_NR_sched_setscheduler: -+ case TARGET_FREEBSD_NR_sched_getscheduler: -+ case TARGET_FREEBSD_NR_sched_yield: -+ case TARGET_FREEBSD_NR_sched_get_priority_max: -+ case TARGET_FREEBSD_NR_sched_get_priority_min: -+ case TARGET_FREEBSD_NR_sched_rr_get_interval: -+ -+ -+ case TARGET_FREEBSD_NR_reboot: -+ case TARGET_FREEBSD_NR_shutdown: -+ -+ case TARGET_FREEBSD_NR_swapon: -+ case TARGET_FREEBSD_NR_swapoff: -+ -+ case TARGET_FREEBSD_NR_pdkill: -+ case TARGET_FREEBSD_NR_pdgetpid: -+ -+ case TARGET_FREEBSD_NR_thr_create: -+ case TARGET_FREEBSD_NR_thr_exit: -+ case TARGET_FREEBSD_NR_thr_self: -+ case TARGET_FREEBSD_NR_thr_suspend: -+ case TARGET_FREEBSD_NR_thr_wake: -+ case TARGET_FREEBSD_NR_thr_new: -+ case TARGET_FREEBSD_NR_thr_set_name: -+ case TARGET_FREEBSD_NR_thr_kill2: -+ -+ case TARGET_FREEBSD_NR_getcontext: -+ case TARGET_FREEBSD_NR_setcontext: -+ case TARGET_FREEBSD_NR_swapcontext: -+ -+ case TARGET_FREEBSD_NR_rtprio_thread: -+ case TARGET_FREEBSD_NR_cpuset: -+ case TARGET_FREEBSD_NR_cpuset_getid: -+ case TARGET_FREEBSD_NR_cpuset_setid: -+ case TARGET_FREEBSD_NR_cpuset_getaffinity: -+ case TARGET_FREEBSD_NR_cpuset_setaffinity: -+ -+ case TARGET_FREEBSD_NR__umtx_lock: -+ case TARGET_FREEBSD_NR__umtx_unlock: -+ -+ case TARGET_FREEBSD_NR_posix_fadvise: -+ case TARGET_FREEBSD_NR_posix_fallocate: -+ -+ case TARGET_FREEBSD_NR_rctl_get_racct: -+ case TARGET_FREEBSD_NR_rctl_get_rules: -+ case TARGET_FREEBSD_NR_rctl_add_rule: -+ case TARGET_FREEBSD_NR_rctl_remove_rule: -+ case TARGET_FREEBSD_NR_rctl_get_limits: -+ -+ case TARGET_FREEBSD_NR_ntp_adjtime: -+ case TARGET_FREEBSD_NR_ntp_gettime: -+ -+#ifdef TARGET_FREEBSD_NR_getdomainname -+ case TARGET_FREEBSD_NR_getdomainname: -+#endif -+#ifdef TARGET_FREEBSD_NR_setdomainname -+ case TARGET_FREEBSD_NR_setdomainname: -+#endif -+#ifdef TARGET_FREEBSD_NR_uname -+ case TARGET_FREEBSD_NR_uname: -+#endif -+ -+ case TARGET_FREEBSD_NR_sctp_peeloff: -+ case TARGET_FREEBSD_NR_sctp_generic_sendmsg: -+ case TARGET_FREEBSD_NR_sctp_generic_recvmsg: -+ -+ case TARGET_FREEBSD_NR_getfh: -+ case TARGET_FREEBSD_NR_lgetfh: -+ case TARGET_FREEBSD_NR_fhstatfs: -+ case TARGET_FREEBSD_NR_fhopen: -+ case TARGET_FREEBSD_NR_fhstat: -+ -+ case TARGET_FREEBSD_NR_getfsstat: -+ case TARGET_FREEBSD_NR_fstatfs: -+ -+ case TARGET_FREEBSD_NR_modfnext: -+ case TARGET_FREEBSD_NR_modfind: -+ case TARGET_FREEBSD_NR_kldload: -+ case TARGET_FREEBSD_NR_kldunload: -+ case TARGET_FREEBSD_NR_kldunloadf: -+ case TARGET_FREEBSD_NR_kldfind: -+ case TARGET_FREEBSD_NR_kldnext: -+ case TARGET_FREEBSD_NR_kldstat: -+ case TARGET_FREEBSD_NR_kldfirstmod: -+ case TARGET_FREEBSD_NR_kldsym: -+ -+ case TARGET_FREEBSD_NR_quotactl: -+#ifdef TARGET_FREEBSD_NR_quota -+ case TARGET_FREEBSD_NR_quota: -+#endif -+ -+ case TARGET_FREEBSD_NR_adjtime: -+ -+#ifdef TARGET_FREEBSD_NR_gethostid -+ case TARGET_FREEBSD_NR_gethostid: -+#endif -+#ifdef TARGET_FREEBSD_NR_gethostname -+ case TARGET_FREEBSD_NR_gethostname: -+#endif -+#ifdef TARGET_FREEBSD_NR_sethostname -+ case TARGET_FREEBSD_NR_sethostname: -+#endif -+ -+ case TARGET_FREEBSD_NR_mincore: -+ -+ case TARGET_FREEBSD_NR_vadvise: -+ -+ case TARGET_FREEBSD_NR_sbrk: -+ case TARGET_FREEBSD_NR_sstk: -+ -+#ifdef TARGET_FREEBSD_NR_getkerninfo -+ case TARGET_FREEBSD_NR_getkerninfo: -+#endif -+#ifdef TARGET_FREEBSD_NR_getpagesize -+ case TARGET_FREEBSD_NR_getpagesize: -+#endif -+ -+ case TARGET_FREEBSD_NR_revoke: -+ -+ case TARGET_FREEBSD_NR_profil: -+ case TARGET_FREEBSD_NR_ktrace: -+ -+ case TARGET_FREEBSD_NR_jail: -+ case TARGET_FREEBSD_NR_jail_attach: -+ case TARGET_FREEBSD_NR_jail_get: -+ case TARGET_FREEBSD_NR_jail_set: -+ case TARGET_FREEBSD_NR_jail_remove: -+ -+ case TARGET_FREEBSD_NR_cap_enter: -+ case TARGET_FREEBSD_NR_cap_getmode: -+ -+ case TARGET_FREEBSD_NR_kenv: -+ case TARGET_FREEBSD_NR_uuidgen: -+ -+ case TARGET_FREEBSD_NR___mac_get_proc: -+ case TARGET_FREEBSD_NR___mac_set_proc: -+ case TARGET_FREEBSD_NR___mac_get_fd: -+ case TARGET_FREEBSD_NR___mac_set_fd: -+ case TARGET_FREEBSD_NR___mac_get_file: -+ case TARGET_FREEBSD_NR___mac_set_file: -+ case TARGET_FREEBSD_NR___mac_get_link: -+ case TARGET_FREEBSD_NR___mac_set_link: -+ case TARGET_FREEBSD_NR_mac_syscall: -+ -+ case TARGET_FREEBSD_NR_audit: -+ case TARGET_FREEBSD_NR_auditon: -+ case TARGET_FREEBSD_NR_getaudit: -+ case TARGET_FREEBSD_NR_setaudit: -+ case TARGET_FREEBSD_NR_getaudit_addr: -+ case TARGET_FREEBSD_NR_setaudit_addr: -+ case TARGET_FREEBSD_NR_auditctl: -+ -+ -+#ifdef TARGET_FREEBSD_NR_obreak -+ case TARGET_FREEBSD_NR_obreak: -+#endif -+ case TARGET_FREEBSD_NR_freebsd6_pread: -+ case TARGET_FREEBSD_NR_freebsd6_pwrite: -+ case TARGET_FREEBSD_NR_freebsd6_lseek: -+ case TARGET_FREEBSD_NR_freebsd6_truncate: -+ case TARGET_FREEBSD_NR_freebsd6_ftruncate: -+ case TARGET_FREEBSD_NR_sendfile: -+ case TARGET_FREEBSD_NR_ptrace: -+ case TARGET_FREEBSD_NR_utrace: -+ case TARGET_FREEBSD_NR_ioctl: -+ ret = unimplemented(num); -+ break; -+ -+ - default: - ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); - break; -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index 207ddee..ea1d25d 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -37,8 +37,6 @@ - * @(#)signal.h 8.2 (Berkeley) 1/21/94 - */ - --#define TARGET_NSIG 32 /* counting 0; could be 33 (mask is 1-32) */ -- - #define TARGET_SIGHUP 1 /* hangup */ - #define TARGET_SIGINT 2 /* interrupt */ - #define TARGET_SIGQUIT 3 /* quit */ -@@ -71,14 +69,21 @@ - #define TARGET_SIGINFO 29 /* information request */ - #define TARGET_SIGUSR1 30 /* user defined signal 1 */ - #define TARGET_SIGUSR2 31 /* user defined signal 2 */ -+#define TARGET_SIGTHR 32 /* reserved by thread library */ -+#define TARGET_SIGLWP SIGTHR /* compatibility */ -+#define TARGET_SIGLIBRT 33 /* reserved by the real-time library */ -+#define TARGET_SIGRTMIN 65 -+#define TARGET_SIGRTMAX 126 -+#define TARGET_QEMU_ESIGRETURN 255 /* fake errno value for use by sigreturn */ -+ - - /* - * Language spec says we must list exactly one parameter, even though we - * actually supply three. Ugh! - */ --#define TARGET_SIG_DFL (void (*)(int))0 --#define TARGET_SIG_IGN (void (*)(int))1 --#define TARGET_SIG_ERR (void (*)(int))-1 -+#define TARGET_SIG_DFL ((abi_long)0) /* default signal handling */ -+#define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ -+#define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ - - #define TARGET_SA_ONSTACK 0x0001 /* take signal on signal stack */ - #define TARGET_SA_RESTART 0x0002 /* restart system on signal return */ -@@ -98,17 +103,503 @@ - - #define TARGET_BADSIG SIG_ERR - -+/* -+ * sigaltstack controls -+ */ - #define TARGET_SS_ONSTACK 0x0001 /* take signals on alternate stack */ --#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on alternate stack */ -+#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on alternate -+ stack */ -+ -+#define TARGET_NSIG 128 -+#define TARGET_NSIG_BPW (sizeof(uint32_t) * 8) -+#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW) -+ -+/* -+ * si_code values -+ * Digital reserves positive values for kernel-generated signals. -+ */ -+ -+/* -+ * SIGSEGV si_codes -+ */ -+#define TARGET_SEGV_MAPERR (1) /* address not mapped to object */ -+#define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped -+ object */ -+/* -+ * SIGTRAP si_codes -+ */ -+#define TARGET_TRAP_BRKPT (1) /* process beakpoint */ -+#define TARGET_TRAP_TRACE (2) /* process trace trap */ - -+struct target_rlimit { -+ abi_ulong rlim_cur; -+ abi_ulong rlim_max; -+}; -+ -+#if defined(TARGET_ALPHA) -+#define TARGET_RLIM_INFINITY 0x7fffffffffffffffull -+#elif defined(TARGET_MIPS) || (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32) -+#define TARGET_RLIM_INFINITY 0x7fffffffUL -+#else -+#define TARGET_RLIM_INFINITY ((abi_ulong)-1) -+#endif -+ -+#define TARGET_RLIMIT_CPU 0 -+#define TARGET_RLIMIT_FSIZE 1 -+#define TARGET_RLIMIT_DATA 2 -+#define TARGET_RLIMIT_STACK 3 -+#define TARGET_RLIMIT_CORE 4 -+#define TARGET_RLIMIT_RSS 5 -+#define TARGET_RLIMIT_MEMLOCK 6 -+#define TARGET_RLIMIT_NPROC 7 -+#define TARGET_RLIMIT_NOFILE 8 -+#define TARGET_RLIMIT_SBSIZE 9 -+#define TARGET_RLIMIT_AS 10 -+#define TARGET_RLIMIT_NPTS 11 -+#define TARGET_RLIMIT_SWAP 12 -+ -+struct target_pollfd { -+ int fd; /* file descriptor */ -+ short events; /* requested events */ -+ short revents; /* returned events */ -+}; -+ -+/* -+ * Constants used for fcntl(2). -+ */ -+ -+/* command values */ -+#define TARGET_F_DUPFD 0 -+#define TARGET_F_GETFD 1 -+#define TARGET_F_SETFD 2 -+#define TARGET_F_GETFL 3 -+#define TARGET_F_SETFL 4 -+#define TARGET_F_GETOWN 5 -+#define TARGET_F_SETOWN 6 -+#define TARGET_F_OGETLK 7 -+#define TARGET_F_OSETLK 8 -+#define TARGET_F_OSETLKW 9 -+#define TARGET_F_DUP2FD 10 -+#define TARGET_F_GETLK 11 -+#define TARGET_F_SETLK 12 -+#define TARGET_F_SETLKW 13 -+#define TARGET_F_SETLK_REMOTE 14 -+#define TARGET_F_READAHEAD 15 -+#define TARGET_F_RDAHEAD 16 -+ -+#define TARGET_O_NONBLOCK 0x00000004 -+#define TARGET_O_APPEND 0x00000008 -+#define TARGET_O_ASYNC 0x00000040 -+#define TARGET_O_DIRECT 0x00010000 -+ -+#define TARGET_SPARC_UTRAP_INSTALL 1 -+#define TARGET_SPARC_SIGTRAMP_INSTALL 2 -+ -+#include "socket.h" - #include "errno_defs.h" - - #include "freebsd/syscall_nr.h" - #include "netbsd/syscall_nr.h" - #include "openbsd/syscall_nr.h" - -+struct target_flock { -+ unsigned long long l_start; -+ unsigned long long l_len; -+ int l_pid; -+ int l_sysid; -+ short l_type; -+ short l_whence; -+} QEMU_PACKED; -+ - struct target_iovec { - abi_long iov_base; /* Starting address */ - abi_long iov_len; /* Number of bytes */ - }; - -+struct target_msghdr { -+ abi_long msg_name; /* Socket name */ -+ int msg_namelen; /* Length of name */ -+ abi_long msg_iov; /* Data blocks */ -+ abi_long msg_iovlen; /* Number of blocks */ -+ abi_long msg_control; /* Per protocol magic -+ (eg BSD file descriptor passing) */ -+ abi_long msg_controllen; /* Length of cmsg list */ -+ int msg_flags; /* flags on received message */ -+}; -+ -+struct target_cmsghdr { -+ abi_long cmsg_len; -+ int cmsg_level; -+ int cmsg_type; -+}; -+ -+#define TARGET_CMSG_DATA(cmsg) \ -+ ((unsigned char *) ((struct target_cmsghdr *) (cmsg) + 1)) -+#define TARGET_CMSG_NXTHDR(mhdr, cmsg) __target_cmsg_nxthdr (mhdr, cmsg) -+#define TARGET_CMSG_ALIGN(len) (((len) + sizeof (abi_long) - 1) \ -+ & (size_t) ~(sizeof (abi_long) - 1)) -+#define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN (len) \ -+ + TARGET_CMSG_ALIGN (sizeof (struct target_cmsghdr))) -+#define TARGET_CMSG_LEN(len) \ -+ (TARGET_CMSG_ALIGN (sizeof (struct target_cmsghdr)) + (len)) -+ -+static __inline__ struct target_cmsghdr * -+__target_cmsg_nxthdr (struct target_msghdr *__mhdr, -+ struct target_cmsghdr *__cmsg) -+{ -+ struct target_cmsghdr *__ptr; -+ -+ __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg + -+ TARGET_CMSG_ALIGN (tswapal(__cmsg->cmsg_len))); -+ if ((unsigned long)((char *)(__ptr+1) - -+ (char *)(size_t)tswapal(__mhdr->msg_control)) > -+ tswapal(__mhdr->msg_controllen)) -+ /* No more entries. */ -+ return ((struct target_cmsghdr *)0); -+ return (__cmsg); -+} -+ -+struct target_sockaddr { -+ uint16_t sa_family; -+ uint8_t sa_data[14]; -+}; -+ -+struct target_in_addr { -+ uint32_t s_addr; /* big endian */ -+}; -+ -+ -+struct target_timeval { -+ abi_long tv_sec; -+ abi_long tv_usec; -+}; -+ -+typedef abi_long target_clock_t; -+ -+struct target_rusage { -+ struct target_timeval ru_utime; /* user time used */ -+ struct target_timeval ru_stime; /* system time used */ -+ abi_long ru_maxrss; /* maximum resident set size */ -+ abi_long ru_ixrss; /* integral shared memory size */ -+ abi_long ru_idrss; /* integral unshared data size */ -+ abi_long ru_isrss; /* integral unshared stack size */ -+ abi_long ru_minflt; /* page reclaims */ -+ abi_long ru_majflt; /* page faults */ -+ abi_long ru_nswap; /* swaps */ -+ abi_long ru_inblock; /* block input operations */ -+ abi_long ru_oublock; /* block output operations */ -+ abi_long ru_msgsnd; /* messages sent */ -+ abi_long ru_msgrcv; /* messages received */ -+ abi_long ru_nsignals; /* signals received */ -+ abi_long ru_nvcsw; /* voluntary context switches */ -+ abi_long ru_nivcsw; /* involuntary context switches */ -+}; -+ -+struct target_kevent { -+ abi_ulong ident; -+ short filter; -+ u_short flags; -+ u_int fflags; -+ abi_long data; -+ abi_ulong udata; -+} __packed; -+ -+/* -+ * FreeBSD/arm uses a 64bits time_t, even in 32bits mode, so we have to -+ * add a special case here. -+ */ -+#if defined(TARGET_ARM) -+typedef uint64_t target_freebsd_time_t; -+#else -+typedef long target_freebsd_time_t; -+#endif -+ -+struct target_freebsd_timespec { -+ target_freebsd_time_t tv_sec; /* seconds */ -+ abi_long tv_nsec; /* and nanoseconds */ -+} __packed; -+ -+struct target_freebsd_timeval { -+ target_freebsd_time_t tv_sec; -+ abi_long tv_usec; -+} __packed; -+ -+struct target_freebsd_stat { -+ uint32_t st_dev; /* inode's device */ -+ uint32_t st_ino; /* inode's number */ -+ int16_t st_mode; /* inode protection mode */ -+ int16_t st_nlink; /* number of hard links */ -+ uint32_t st_uid; /* user ID of the file's owner */ -+ uint32_t st_gid; /* group ID of the file's group */ -+ uint32_t st_rdev; /* device type */ -+ struct target_freebsd_timespec st_atim; /* time of last access */ -+ struct target_freebsd_timespec st_mtim; /* time of last data modification */ -+ struct target_freebsd_timespec st_ctim; /* time of last file status change */ -+ int64_t st_size; /* file size, in bytes */ -+ int64_t st_blocks; /* blocks allocated for file */ -+ uint32_t st_blksize; /* optimal blocksize for I/O */ -+ uint32_t st_flags; /* user defined flags for file */ -+ __uint32_t st_gen; /* file generation number */ -+ __int32_t st_lspare; -+ struct target_freebsd_timespec st_birthtim; /* time of file creation */ -+ /* -+ * Explicitly pad st_birthtim to 16 bytes so that the size of -+ * struct stat is backwards compatible. We use bitfields instead -+ * of an array of chars so that this doesn't require a C99 compiler -+ * to compile if the size of the padding is 0. We use 2 bitfields -+ * to cover up to 64 bits on 32-bit machines. We assume that -+ * CHAR_BIT is 8... -+ */ -+ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); -+ unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec)); -+} __packed; -+ -+int __getcwd(char *, size_t); -+ -+struct target_sembuf { -+ unsigned short sem_num; /* semaphore # */ -+ short sem_op; /* semaphore operation */ -+ short sem_flg; /* operation flags */ -+}; -+ -+union target_semun { -+ int val; /* value for SETVAL */ -+ abi_ulong buf; /* buffer for IPC_STAT & IPC_SET */ -+ abi_ulong array; /* array for GETALL & SETALL */ -+}; -+ -+struct target_ipc_perm { -+ uint32_t cuid; /* creator user id */ -+ uint32_t cgid; /* creator group id */ -+ uint32_t uid; /* user id */ -+ uint32_t gid; /* group id */ -+ uint16_t mode; /* r/w permission */ -+ uint16_t seq; /* sequence # */ -+ abi_long key; /* user specified msg/sem/shm key */ -+}; -+ -+struct target_msqid_ds { -+ struct target_ipc_perm msg_perm; /* msg queue permission bits */ -+ abi_ulong msg_first; /* first message in the queue */ -+ abi_ulong msg_last; /* last message in the queue */ -+ abi_ulong msg_cbytes; /* # of bytes in use on the queue */ -+ abi_ulong msg_qnum; /* number of msgs in the queue */ -+ abi_ulong msg_qbytes; /* max # of bytes on the queue */ -+ int32_t msg_lspid; /* pid of last msgsnd() */ -+ int32_t msg_lrpid; /* pid of last msgrcv() */ -+ abi_ulong msg_stime; /* time of last msgsnd() */ -+ abi_ulong msg_rtime; /* time of last msgrcv() */ -+ abi_ulong msg_ctime; /* time of last msgctl() */ -+}; -+ -+struct target_msgbuf { -+ abi_long mtype; /* message type */ -+ char mtext[1]; /* body of message */ -+}; -+ -+struct target_semid_ds { -+ struct target_ipc_perm sem_perm; /* operation permission struct */ -+ abi_ulong sem_base; /* pointer to first semaphore in set */ -+ uint16_t sem_nsems; /* number of sems in set */ -+ abi_ulong sem_otime; /* last operation time */ -+ abi_ulong sem_ctime; /* times measured in secs */ -+}; -+ -+struct target_shmid_ds { -+ struct target_ipc_perm shm_perm; /* peration permission structure */ -+ abi_ulong shm_segsz; /* size of segment in bytes */ -+ int32_t shm_lpid; /* process ID of last shared memory op */ -+ int32_t shm_cpid; /* process ID of creator */ -+ int32_t shm_nattch; /* number of current attaches */ -+ abi_ulong shm_atime; /* time of last shmat() */ -+ abi_ulong shm_dtime; /* time of last shmdt() */ -+ abi_ulong shm_ctime; /* time of last change by shmctl() */ -+}; -+ -+/* this struct defines a stack used during syscall handling */ -+typedef struct target_sigaltstack { -+ abi_long ss_sp; -+ abi_ulong ss_size; -+ abi_long ss_flags; -+} target_stack_t; -+ -+typedef struct { -+ uint32_t __bits[TARGET_NSIG_WORDS]; -+} target_sigset_t; -+ -+struct target_sigaction { -+ abi_ulong _sa_handler; -+ int32_t sa_flags; -+ target_sigset_t sa_mask; -+}; -+ -+union target_sigval { -+ int32_t sival_int; -+ abi_ulong sival_ptr; -+ int32_t sigval_int; -+ abi_ulong sigval_ptr; -+}; -+ -+typedef struct target_siginfo { -+ int32_t si_signo; /* signal number */ -+ int32_t si_errno; /* errno association */ -+ int32_t si_code; /* signal code */ -+ int32_t si_pid; /* sending process */ -+ int32_t si_uid; /* sender's ruid */ -+ abi_ulong si_addr; /* faulting instruction */ -+ -+ union target_sigval si_value; /* signal value */ -+ -+ union { -+ struct { -+ int32_t _trapno; /* machine specific trap code */ -+ } _fault; -+ -+ /* POSIX.1b timers */ -+ struct { -+ int32_t _timerid; -+ int32_t _overrun; -+ } _timer; -+ -+ struct { -+ int32_t _mqd; -+ } _mesgp; -+ -+ /* SIGPOLL */ -+ struct { -+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ -+ } _poll; -+ -+ struct { -+ abi_long __spare1__; -+ int32_t __spare2_[7]; -+ } __spare__; -+ } _reason; -+} target_siginfo_t; -+ -+#if defined(TARGET_MIPS) -+ -+struct target_sigcontext { -+ target_sigset_t sc_mask; /* signal mask to retstore */ -+ int32_t sc_onstack; /* sigstack state to restore */ -+ abi_long sc_pc; /* pc at time of signal */ -+ abi_long sc_reg[32]; /* processor regs 0 to 31 */ -+ abi_long mullo, mulhi; /* mullo and mulhi registers */ -+ int32_t sc_fpused; /* fp has been used */ -+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -+ abi_long sc_fpc_eir; /* fp exception instr reg */ -+ /* int32_t reserved[8]; */ -+}; -+ -+typedef struct target_mcontext { -+ int32_t mc_onstack; /* sigstack state to restore */ -+ abi_long mc_pc; /* pc at time of signal */ -+ abi_long mc_regs[32]; /* process regs 0 to 31 */ -+ abi_long sr; /* status register */ -+ abi_long mullo, mulhi; -+ int32_t mc_fpused; /* fp has been used */ -+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */ -+ abi_long mc_fpc_eir; /* fp exception instr reg */ -+ abi_ulong mc_tls; /* pointer to TLS area */ -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ target_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __space__[8]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+#elif defined(TARGET_SPARC64) -+ -+struct target_mcontext { -+ uint64_t mc_global[8]; -+ uint64_t mc_out[8]; -+ uint64_t mc_local[8]; -+ uint64_t mc_in[8]; -+ uint32_t mc_fp[64]; -+} __aligned(64); -+ -+typedef struct target_mcontext target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ target_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __space__[8]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ target_ucontext_t sf_uc; -+ target_siginfo_t sf_si; -+}; -+ -+#else -+ -+typedef target_ulong target_mcontext_t; /* dummy */ -+ -+#endif -+ -+/* XXX where did this come from? -+typedef struct target_ucontext { -+ target_ulong uc_flags; -+ target_ulong uc_link; -+ target_stack_t uc_stack; -+ target_mcontext_t uc_mcontext; -+ target_ulong uc_filer[80]; -+ target_sigset_t uc_sigmask; -+} target_ucontext_t; -+*/ -+ -+ -+#ifdef BSWAP_NEEDED -+static inline void -+tswap_sigset(target_sigset_t *d, const target_sigset_t *s) -+{ -+ int i; -+ -+ for(i = 0;i < TARGET_NSIG_WORDS; i++) -+ d->__bits[i] = tswapal(s->__bits[i]); -+} -+ -+#else -+static inline void -+tswap_sigset(target_sigset_t *d, const target_sigset_t *s) -+{ -+ -+ *d = *s; -+} -+#endif -+ -+/* XXX -+static inline void -+target_siginitset(target_sigset_t *d, abi_ulong set) -+{ -+ int i; -+ -+ d->sig[0] = set; -+ for(i = 1;i < TARGET_NSIG_WORDS; i++) -+ d->sig[i] = 0; -+} -+*/ -+ -+void host_to_target_sigset(target_sigset_t *d, const sigset_t *s); -+void target_to_host_sigset(sigset_t *d, const target_sigset_t *s); -+void host_to_target_old_sigset(abi_ulong *old_sigset, const sigset_t *sigset); -+void target_to_host_old_sigset(sigset_t *sigset, const abi_ulong *old_sigset); -+int do_sigaction(int sig, const struct target_sigaction *act, -+ struct target_sigaction *oact); -diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h -index 659cd40..ea89f5a 100644 ---- a/bsd-user/x86_64/target_signal.h -+++ b/bsd-user/x86_64/target_signal.h -@@ -3,17 +3,16 @@ - - #include "cpu.h" - --/* this struct defines a stack used during syscall handling */ -- --typedef struct target_sigaltstack { -- abi_ulong ss_sp; -- abi_long ss_flags; -- abi_ulong ss_size; --} target_stack_t; -- - static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) - { - return state->regs[R_ESP]; - } - -+#define TARGET_SS_ONSTACK 0x0001 /* take signal on alternate stack */ -+#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on -+ alternate stack */ -+ -+#define TARGET_MINSIGSTKSZ (512 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/x86_64/target_vmparam.h b/bsd-user/x86_64/target_vmparam.h -new file mode 100644 -index 0000000..aa5e0e0 ---- /dev/null -+++ b/bsd-user/x86_64/target_vmparam.h -@@ -0,0 +1,28 @@ -+#ifndef _TARGET_VMPARAM_H_ -+#define _TARGET_VMPARAM_H_ -+ -+#if defined(__FreeBSD__) -+#define TARGET_VM_MAXUSER_ADDRESS (0x0000800000000000UL) -+ -+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+ -+struct target_ps_strings { -+ abi_ulong ps_argvstr; -+ uint32_t ps_nargvstr; -+ abi_ulong ps_envstr; -+ uint32_t ps_nenvstr; -+}; -+ -+#define TARGET_SPACE_USRSPACE 4096 -+#define TARGET_ARG_MAX 262144 -+ -+#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) -+ -+#define TARGET_SZSIGCODE 0 -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+#endif -+ -+#endif /* _TARGET_VMPARAM_H_ */ -diff --git a/configure b/configure -index 169b9bd..34eca43 100755 ---- a/configure -+++ b/configure -@@ -1018,6 +1018,10 @@ x86_64-bsd-user \ - sparc-bsd-user \ - sparc64-bsd-user \ - arm-bsd-user \ -+armeb-bsd-user \ -+mips-bsd-user \ -+mipsel-bsd-user \ -+mips64-bsd-user \ - " - fi - -diff --git a/default-configs/armeb-bsd-user.mak b/default-configs/armeb-bsd-user.mak -new file mode 100644 -index 0000000..1b6fe65 ---- /dev/null -+++ b/default-configs/armeb-bsd-user.mak -@@ -0,0 +1,3 @@ -+# Default configuration for armeb-bsd-user -+ -+CONFIG_GDBSTUB_XML=y -diff --git a/default-configs/mips-bsd-user.mak b/default-configs/mips-bsd-user.mak -new file mode 100644 -index 0000000..3fb129a ---- /dev/null -+++ b/default-configs/mips-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mips-bsd-user -diff --git a/default-configs/mips64-bsd-user.mak b/default-configs/mips64-bsd-user.mak -new file mode 100644 -index 0000000..d4e72a6 ---- /dev/null -+++ b/default-configs/mips64-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mips64-bsd-user -diff --git a/default-configs/mipsel-bsd-user.mak b/default-configs/mipsel-bsd-user.mak -new file mode 100644 -index 0000000..312b9d5 ---- /dev/null -+++ b/default-configs/mipsel-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mipsel-bsd-user -diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h -index bf094a3..030937c 100644 ---- a/target-mips/mips-defs.h -+++ b/target-mips/mips-defs.h -@@ -10,8 +10,14 @@ - - #if defined(TARGET_MIPS64) - #define TARGET_LONG_BITS 64 --#define TARGET_PHYS_ADDR_SPACE_BITS 36 --#define TARGET_VIRT_ADDR_SPACE_BITS 42 -+//#define TARGET_PHYS_ADDR_SPACE_BITS 36 -+#define TARGET_PHYS_ADDR_SPACE_BITS 59 -+# ifdef TARGET_ABI32 -+# define TARGET_VIRT_ADDR_SPACE_BITS 32 -+# else -+//# define TARGET_VIRT_ADDR_SPACE_BITS 42 -+# define TARGET_VIRT_ADDR_SPACE_BITS 62 -+# endif - #else - #define TARGET_LONG_BITS 32 - #define TARGET_PHYS_ADDR_SPACE_BITS 36 -diff --git a/user-exec.c b/user-exec.c -index b9ea9dd..9ad4858 100644 ---- a/user-exec.c -+++ b/user-exec.c -@@ -34,11 +34,11 @@ - #undef EDI - #undef EIP - #include <signal.h> --#ifdef __linux__ -+#if defined(__linux__) || defined(__FreeBSD__) - #include <sys/ucontext.h> - #endif - --//#define DEBUG_SIGNAL -+#define DEBUG_SIGNAL - - static void exception_action(CPUArchState *env1) - { -@@ -58,6 +58,8 @@ void cpu_resume_from_signal(CPUArchState *env1, void *puc) - struct ucontext *uc = puc; - #elif defined(__OpenBSD__) - struct sigcontext *uc = puc; -+#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -+ ucontext_t *uc = puc; - #endif - - #ifndef CONFIG_TCG_PASS_AREG0 -@@ -76,6 +78,8 @@ void cpu_resume_from_signal(CPUArchState *env1, void *puc) - #endif - #elif defined(__OpenBSD__) - sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); -+#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -+ sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); - #endif - } - env1->exception_index = -1; diff --git a/emulators/qemu-devel/files/patch-z2b-bsd-user-sson-002b b/emulators/qemu-devel/files/patch-z2b-bsd-user-sson-002b deleted file mode 100644 index 799c6e75ee23..000000000000 --- a/emulators/qemu-devel/files/patch-z2b-bsd-user-sson-002b +++ /dev/null @@ -1,217 +0,0 @@ -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index 0502a6a..52441c4 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -31,7 +31,7 @@ - #include "qemu.h" - #include "target_signal.h" - --// #define DEBUG_SIGNAL -+//#define DEBUG_SIGNAL - - #ifndef _NSIG - #define _NSIG 128 -@@ -441,7 +441,7 @@ host_signal_handler(int host_signum, siginfo_t *info, void *puc) - * we forward to it some signals. - */ - if ((host_signum == SIGSEGV || host_signum == SIGBUS) && -- info->si_code > 0) { -+ info->si_code < 0x10000) { - if (cpu_signal_handler(host_signum, info, puc)) - return; - } -@@ -1099,6 +1099,7 @@ signal_init(void) - - sigfillset(&act.sa_mask); - act.sa_sigaction = host_signal_handler; -+ act.sa_flags = SA_SIGINFO; - - for (i = 1; i <= TARGET_NSIG; i++) { - host_sig = target_to_host_signal(i); -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index c627c62..625c3cf 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -3544,6 +3544,30 @@ do_stat: - } - break; - -+#ifdef TARGET_FREEBSD_NR_pdwait4 -+ case TARGET_FREEBSD_NR_pdwait4: -+ { -+ int status; -+ abi_long status_ptr = arg2; -+ struct rusage rusage, *rusage_ptr; -+ abi_long target_rusage = arg4; -+ -+ if (target_rusage) -+ rusage_ptr = &rusage; -+ else -+ rusage_ptr = NULL; -+ ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); -+ if (!is_error(ret)) { -+ status = host_to_target_waitstatus(status); -+ if (put_user_s32(status, status_ptr)) -+ goto efault; -+ if (target_rusage) -+ host_to_target_rusage(target_rusage, &rusage); -+ } -+ } -+ break; -+#endif /* TARGET_FREEBSD_NR_pdwait4 */ -+ - case TARGET_FREEBSD_NR_accept: - ret = do_accept(arg1, arg2, arg3); - break; -@@ -3803,6 +3827,20 @@ do_stat: - break; - #endif - -+ case TARGET_FREEBSD_NR_pdkill: -+ ret = get_errno(pdkill(arg1, target_to_host_signal(arg2))); -+ break; -+ -+ case TARGET_FREEBSD_NR_pdgetpid: -+ { -+ pid_t pid; -+ -+ ret = get_errno(pdgetpid(arg1, &pid)); -+ if (put_user_u32(pid, arg2)) -+ goto efault; -+ } -+ break; -+ - case TARGET_FREEBSD_NR_sigaction: - { - struct target_sigaction *old_act, act, oact, *pact; -@@ -4014,27 +4052,88 @@ do_stat: - - #ifdef TARGET_FREEBSD_NR_aio_read - case TARGET_FREEBSD_NR_aio_read: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_aio_write - case TARGET_FREEBSD_NR_aio_write: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_aio_return - case TARGET_FREEBSD_NR_aio_return: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_aio_suspend - case TARGET_FREEBSD_NR_aio_suspend: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_aio_cancel - case TARGET_FREEBSD_NR_aio_cancel: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_aio_error - case TARGET_FREEBSD_NR_aio_error: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_aio_waitcomplete - case TARGET_FREEBSD_NR_aio_waitcomplete: -+ ret = unimplemented(num); -+ break; - #endif - #ifdef TARGET_FREEBSD_NR_lio_listio - case TARGET_FREEBSD_NR_lio_listio: -+ ret = unimplemented(num); -+ break; -+#endif -+ -+#if 0 /* XXX not supported in libc yet, it seems (10.0 addition). */ -+ case TARGET_FREEBSD_NR_posix_fadvise: -+ { -+ off_t offset = arg2, len = arg3; -+ int advice = arg4; -+ -+#if TARGET_ABI_BITS == 32 -+ if (regpairs_aligned(cpu_env)) { -+ offset = target_offset64(arg3, arg4); -+ len = target_offset64(arg5, arg6); -+ advice = arg7; -+ } else { -+ offset = target_offset64(arg2, arg3); -+ len = target_offset64(arg4, arg5); -+ advice = arg6; -+ } -+#endif -+ ret = get_errno(posix_fadvise(arg1, offset, len, advice)); -+ } -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_posix_fallocate: -+ { -+ off_t offset = arg2, len = arg3; -+ -+#if TARGET_ABI_BITS == 32 -+ if (regpairs_aligned(cpu_env)) { -+ offset = target_offset64(arg3, arg4); -+ len = target_offset64(arg5, arg6); -+ } else { -+ offset = target_offset64(arg2, arg3); -+ len = target_offset64(arg4, arg5); -+ } -+#endif -+ ret = get_errno(posix_fallocate(arg1, offset, len)); -+ } -+ break; -+ -+#ifdef TARGET_FREEBSD_posix_openpt -+ case TARGET_FREEBSD_posix_openpt: -+ ret = get_errno(posix_openpt(arg1)); -+ break; - #endif - - case TARGET_FREEBSD_NR_yield: -@@ -4054,9 +4153,6 @@ do_stat: - case TARGET_FREEBSD_NR_swapon: - case TARGET_FREEBSD_NR_swapoff: - -- case TARGET_FREEBSD_NR_pdkill: -- case TARGET_FREEBSD_NR_pdgetpid: -- - case TARGET_FREEBSD_NR_thr_create: - case TARGET_FREEBSD_NR_thr_exit: - case TARGET_FREEBSD_NR_thr_self: -@@ -4080,9 +4176,6 @@ do_stat: - case TARGET_FREEBSD_NR__umtx_lock: - case TARGET_FREEBSD_NR__umtx_unlock: - -- case TARGET_FREEBSD_NR_posix_fadvise: -- case TARGET_FREEBSD_NR_posix_fallocate: -- - case TARGET_FREEBSD_NR_rctl_get_racct: - case TARGET_FREEBSD_NR_rctl_get_rules: - case TARGET_FREEBSD_NR_rctl_add_rule: -diff --git a/user-exec.c b/user-exec.c -index 9ad4858..bf29e84 100644 ---- a/user-exec.c -+++ b/user-exec.c -@@ -38,7 +38,7 @@ - #include <sys/ucontext.h> - #endif - --#define DEBUG_SIGNAL -+//#define DEBUG_SIGNAL - - static void exception_action(CPUArchState *env1) - { -@@ -103,7 +103,7 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, - } - #endif - #if defined(DEBUG_SIGNAL) -- qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", -+ qemu_printf("qemu: SIGSEGV pc=0x%08lx address=0x%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); - #endif - /* XXX: locking issue */ diff --git a/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c b/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c deleted file mode 100644 index 0c1d7720f3bb..000000000000 --- a/emulators/qemu-devel/files/patch-z2c-bsd-user-sson-002c +++ /dev/null @@ -1,2300 +0,0 @@ -diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h -index 19cc188..6b7bb67 100644 ---- a/bsd-user/arm/target_signal.h -+++ b/bsd-user/arm/target_signal.h -@@ -11,4 +11,29 @@ static inline abi_ulong get_sp_from_cpustate(CPUARMState *state) - #define TARGET_MINSIGSTKSZ (1024 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -+typedef target_ulong target_mcontext_t; /* dummy */ -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+static inline int -+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "ARM doesn't have support for get_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ -+static inline int -+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "ARM doesn't have support for set_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index 1edf412..b09f766 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -38,6 +38,7 @@ - { TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_getcontext, "getcontext", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL }, -@@ -123,6 +124,7 @@ - { TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_setcontext, "setcontext", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL }, -@@ -160,6 +162,15 @@ - { TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_create, "thr_create", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_new, "thr_new", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_self, "thr_self", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL }, -diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h -index 285e7f9..28481ce 100644 ---- a/bsd-user/i386/target_signal.h -+++ b/bsd-user/i386/target_signal.h -@@ -11,4 +11,29 @@ static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -+typedef target_ulong target_mcontext_t; /* dummy */ -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+static inline int -+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "i386 doesn't have support for get_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ -+static inline int -+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "i386 doesn't have support for set_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/main.c b/bsd-user/main.c -index 146f022..7a99537 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -34,6 +34,10 @@ - #include "qemu/timer.h" - #include "qemu/envlist.h" - -+#if defined(CONFIG_USE_NPTL) && defined(__FreeBSD__) -+#include <sys/thr.h> -+#endif -+ - int singlestep; - #if defined(CONFIG_USE_GUEST_BASE) - unsigned long mmap_min_addr; -@@ -68,41 +72,185 @@ int cpu_get_pic_interrupt(CPUX86State *e - } - #endif - --/* These are no-ops because we are not threadsafe. */ --static inline void cpu_exec_start(CPUArchState *env) -+#if defined(CONFIG_USE_NPTL) -+/* Helper routines for implementing atomic operations. */ -+ -+/* -+ * To implement exclusive operations we force all cpus to synchronize. -+ * We don't require a full sync, only that no cpus are executing guest code. -+ * The alternative is to map target atomic ops onto host eqivalents, -+ * which requires quite a lot of per host/target work. -+ */ -+static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER; -+static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER; -+static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER; -+static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER; -+static int pending_cpus; -+ -+/* Make sure everything is in a consistent state for calling fork(). */ -+void fork_start(void) - { -+ pthread_mutex_lock(&tb_lock); -+ pthread_mutex_lock(&exclusive_lock); -+ mmap_fork_start(); - } - --static inline void cpu_exec_end(CPUArchState *env) -+void fork_end(int child) - { -+ mmap_fork_end(child); -+ if (child) { -+ /* -+ * Child processes created by fork() only have a single thread. -+ * Discard information about the parent threads. -+ */ -+ first_cpu = thread_env; -+ thread_env->next_cpu = NULL; -+ pending_cpus = 0; -+ pthread_mutex_init(&exclusive_lock, NULL); -+ pthread_mutex_init(&cpu_list_mutex, NULL); -+ pthread_cond_init(&exclusive_cond, NULL); -+ pthread_cond_init(&exclusive_resume, NULL); -+ pthread_mutex_init(&tb_lock, NULL); -+ gdbserver_fork(thread_env); -+ } else { -+ pthread_mutex_unlock(&exclusive_lock); -+ pthread_mutex_unlock(&tb_lock); -+ } - } - --static inline void start_exclusive(void) -+/* -+ * Wait for pending exclusive operations to complete. The exclusive lock -+ * must be held. -+ */ -+static inline void -+exclusive_idle(void) - { -+ while (pending_cpus) { -+ pthread_cond_wait(&exclusive_resume, &exclusive_lock); -+ } - } - --static inline void end_exclusive(void) -+/* Start an exclusive operation. Must only be called outside of cpu_exec. */ -+static inline void -+start_exclusive(void) -+{ -+ CPUArchState *other; -+ -+ pthread_mutex_lock(&exclusive_lock); -+ exclusive_idle(); -+ -+ pending_cpus = 1; -+ /* Make all other cpus stop executing. */ -+ for (other = first_cpu; other; other = other->next_cpu) { -+ if (other->running) { -+ pending_cpus++; -+ cpu_exit(other); -+ } -+ } -+ if (pending_cpus > 1) { -+ pthread_cond_wait(&exclusive_cond, &exclusive_lock); -+ } -+} -+ -+/* Finish an exclusive operation. */ -+static inline void -+end_exclusive(void) -+{ -+ pending_cpus = 0; -+ pthread_cond_broadcast(&exclusive_resume); -+ pthread_mutex_unlock(&exclusive_lock); -+} -+ -+/* Wait for exclusive ops to finish, and begin cpu execution. */ -+static inline void -+cpu_exec_start(CPUArchState *env) -+{ -+ pthread_mutex_lock(&exclusive_lock); -+ exclusive_idle(); -+ env->running = 1; -+ pthread_mutex_unlock(&exclusive_lock); -+} -+ -+/* Mark cpu as not excuting, and release pending exclusive ops. */ -+static inline void -+cpu_exec_end(CPUArchState *env) -+{ -+ pthread_mutex_lock(&exclusive_lock); -+ env->running = 0; -+ if (pending_cpus > 1) { -+ pending_cpus--; -+ if (pending_cpus == 1) { -+ pthread_cond_signal(&exclusive_cond); -+ } -+ } -+ exclusive_idle(); -+ pthread_mutex_unlock(&exclusive_lock); -+} -+ -+void -+cpu_list_lock(void) - { -+ pthread_mutex_lock(&cpu_list_mutex); - } - --void fork_start(void) -+void -+cpu_list_unlock(void) - { -+ pthread_mutex_unlock(&cpu_list_mutex); - } - --void fork_end(int child) -+#else /* ! CONFIG_USE_NPTL */ -+ -+/* These are no-ops because we are not threadsafe. */ -+void -+fork_start(void) -+{ -+} -+ -+void -+fork_end(int child) - { - if (child) { - gdbserver_fork(thread_env); - } - } - --void cpu_list_lock(void) -+static inline void -+exclusive_idle(void) -+{ -+} -+ -+static inline void -+start_exclusive(void) -+{ -+} -+ -+static inline void -+end_exclusive(void) -+{ -+} -+ -+static inline void -+cpu_exec_start(CPUArchState *env) - { - } - --void cpu_list_unlock(void) -+ -+static inline void -+cpu_exec_end(CPUArchState *env) -+{ -+} -+ -+void -+cpu_list_lock(void) -+{ -+} -+ -+void -+cpu_list_unlock(void) - { - } -+#endif /* CONFIG_USE_NPTL */ - - #ifdef TARGET_I386 - /***********************************************************/ -@@ -738,7 +886,10 @@ void cpu_loop(CPUMIPSState *env) - - for(;;) { - cpu_exec_start(env); -+ /* XXX there is a concurrency problem - giant lock for now */ -+ pthread_mutex_lock(&exclusive_lock); /* XXX */ - trapnr = cpu_mips_exec(env); -+ pthread_mutex_unlock(&exclusive_lock); /* XXX */ - cpu_exec_end(env); - switch(trapnr) { - case EXCP_SYSCALL: /* syscall exception */ -@@ -1204,6 +1355,18 @@ static void usage(void) - - THREAD CPUArchState *thread_env; - -+void task_settid(TaskState *ts) -+{ -+ if (0 == ts->ts_tid) { -+#ifdef CONFIG_USE_NPTL -+ (void)thr_self(&ts->ts_tid); -+#else -+ /* When no threads then just use PID */ -+ ts->ts_tid = getpid(); -+#endif -+ } -+} -+ - void stop_all_tasks(void) - { - /* -diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h -index 28871c3..484cfd8 100644 ---- a/bsd-user/mips/target_signal.h -+++ b/bsd-user/mips/target_signal.h -@@ -6,9 +6,187 @@ - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - --static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) -+struct target_sigcontext { -+ target_sigset_t sc_mask; /* signal mask to retstore */ -+ int32_t sc_onstack; /* sigstack state to restore */ -+ abi_long sc_pc; /* pc at time of signal */ -+ abi_long sc_reg[32]; /* processor regs 0 to 31 */ -+ abi_long mullo, mulhi; /* mullo and mulhi registers */ -+ int32_t sc_fpused; /* fp has been used */ -+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -+ abi_long sc_fpc_eir; /* fp exception instr reg */ -+ /* int32_t reserved[8]; */ -+}; -+ -+typedef struct target_mcontext { -+ int32_t mc_onstack; /* sigstack state to restore */ -+ abi_long mc_pc; /* pc at time of signal */ -+ abi_long mc_regs[32]; /* process regs 0 to 31 */ -+ abi_long sr; /* status register */ -+ abi_long mullo, mulhi; -+ int32_t mc_fpused; /* fp has been used */ -+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */ -+ abi_long mc_fpc_eir; /* fp exception instr reg */ -+ abi_ulong mc_tls; /* pointer to TLS area */ -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+ -+/* Get the stack pointer. */ -+static inline abi_ulong -+get_sp_from_cpustate(CPUMIPSState *state) - { - return state->active_tc.gpr[29]; - } - -+/* -+ * Compare to mips/mips/pm_machdep.c sendsig() -+ * Assumes that "frame" memory is locked. -+ */ -+static inline int -+set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) -+{ -+ -+ frame->sf_signum = sig; -+ frame->sf_siginfo = 0; -+ frame->sf_ucontext = 0; -+ -+ frame->sf_si.si_signo = sig; -+ frame->sf_si.si_code = TARGET_SA_SIGINFO; -+ frame->sf_si.si_addr = regs->CP0_BadVAddr; -+ -+ /* -+ * Arguments to signal handler: -+ * a0 ($4) = signal number -+ * a1 ($5) = siginfo pointer -+ * a2 ($6) = ucontext pointer -+ * PC = signal handler pointer -+ * t9 ($25) = signal handler pointer -+ * $29 = point to sigframe struct -+ * ra ($31) = sigtramp at base of user stack -+ */ -+ regs->active_tc.gpr[ 4] = sig; -+ regs->active_tc.gpr[ 5] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; -+ regs->active_tc.gpr[29] = frame_addr; -+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ -+ return (0); -+} -+ -+/* -+ * Compare to mips/mips/pm_machdep.c get_mcontext() -+ * Assumes that the memory is locked if mcp points to user memory. -+ */ -+static inline int -+get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) -+{ -+ int i, err = 0; -+ -+ if (flags & TARGET_MC_ADD_MAGIC) { -+ mcp->mc_regs[0] = tswapal(TARGET_UCONTEXT_MAGIC); -+ } else { -+ mcp->mc_regs[0] = 0; -+ } -+ -+ if (flags & TARGET_MC_SET_ONSTACK) { -+ mcp->mc_onstack = tswapal(1); -+ } else { -+ mcp->mc_onstack = 0; -+ } -+ -+ for(i = 1; i < 32; i++) -+ mcp->mc_regs[i] = tswapal(regs->active_tc.gpr[i]); -+ -+#if 0 /* XXX FP is not used right now. */ -+ abi_ulong used_fp = used_math() ? TARGET_MDTD_FPUSED : 0; -+ -+ mcp->mc_fpused = used_fp; -+ if (used_fp) { -+ preempt_disable(); -+ if (!is_fpu_owner()) { -+ own_fpu(); -+ for(i = 0; i < 33; i++) -+ mcp->mc_fpregs[i] = tswapal(regs->active_fpu.fpr[i]); -+ } -+ preempt_enable(); -+ } -+#else -+ mcp->mc_fpused = 0; -+#endif -+ -+ if (flags & TARGET_MC_GET_CLEAR_RET) { -+ mcp->mc_regs[2] = 0; /* v0 = 0 */ -+ mcp->mc_regs[3] = 0; /* v1 = 0 */ -+ mcp->mc_regs[7] = 0; /* a3 = 0 */ -+ } -+ -+ mcp->mc_pc = tswapal(regs->active_tc.PC); -+ mcp->mullo = tswapal(regs->active_tc.LO[0]); -+ mcp->mulhi = tswapal(regs->active_tc.HI[0]); -+ mcp->mc_tls = tswapal(regs->tls_value); -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return (err); -+} -+ -+/* Compare to mips/mips/pm_machdep.c set_mcontext() */ -+static inline int -+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) -+{ -+ int i, err = 0; -+ -+ for(i = 1; i < 32; i++) -+ regs->active_tc.gpr[i] = tswapal(mcp->mc_regs[i]); -+ -+#if 0 /* XXX FP is not used right now */ -+ abi_ulong used_fp = 0; -+ -+ used_fp = tswapal(mcp->mc_fpused) -+ conditional_used_math(used_fp); -+ -+ preempt_disabled(); -+ if (used_math()) { -+ /* restore fpu context if we have used it before */ -+ own_fpu(); -+ for (i = 0; i < 32; i++) -+ regs->active_fpu.fpr[i] = tswapal(mcp->mc_fpregs[i]); -+ } else { -+ /* Signal handler may have used FPU. Give it up. */ -+ lose_fpu(); -+ } -+ preempt_enable(); -+#endif -+ -+ regs->CP0_EPC = tswapal(mcp->mc_pc); -+ regs->active_tc.LO[0] = tswapal(mcp->mullo); -+ regs->active_tc.HI[0] = tswapal(mcp->mulhi); -+ regs->tls_value = tswapal(mcp->mc_tls); -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return (err); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h -index d671f4e..e9c8a9f 100644 ---- a/bsd-user/mips64/target_signal.h -+++ b/bsd-user/mips64/target_signal.h -@@ -7,11 +7,186 @@ - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - #define TARGET_SZSIGCODE 16 - --#define TARGET_UCONTEXT_MAGIC 0xACEDBADE -+struct target_sigcontext { -+ target_sigset_t sc_mask; /* signal mask to retstore */ -+ int32_t sc_onstack; /* sigstack state to restore */ -+ abi_long sc_pc; /* pc at time of signal */ -+ abi_long sc_reg[32]; /* processor regs 0 to 31 */ -+ abi_long mullo, mulhi; /* mullo and mulhi registers */ -+ int32_t sc_fpused; /* fp has been used */ -+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -+ abi_long sc_fpc_eir; /* fp exception instr reg */ -+ /* int32_t reserved[8]; */ -+}; - --static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) -+typedef struct target_mcontext { -+ int32_t mc_onstack; /* sigstack state to restore */ -+ abi_long mc_pc; /* pc at time of signal */ -+ abi_long mc_regs[32]; /* process regs 0 to 31 */ -+ abi_long sr; /* status register */ -+ abi_long mullo, mulhi; -+ int32_t mc_fpused; /* fp has been used */ -+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */ -+ abi_long mc_fpc_eir; /* fp exception instr reg */ -+ abi_ulong mc_tls; /* pointer to TLS area */ -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+static inline abi_ulong -+get_sp_from_cpustate(CPUMIPSState *state) - { - return state->active_tc.gpr[29]; - } - -+/* -+ * Compare to mips/mips/pm_machdep.c sendsig() -+ * Assumes that "frame" memory is locked. -+ */ -+static inline int -+set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) -+{ -+ -+ frame->sf_signum = sig; -+ frame->sf_siginfo = 0; -+ frame->sf_ucontext = 0; -+ -+ frame->sf_si.si_signo = sig; -+ frame->sf_si.si_code = TARGET_SA_SIGINFO; -+ frame->sf_si.si_addr = regs->CP0_BadVAddr; -+ -+ /* -+ * Arguments to signal handler: -+ * a0 ($4) = signal number -+ * a1 ($5) = siginfo pointer -+ * a2 ($6) = ucontext pointer -+ * PC = signal handler pointer -+ * t9 ($25) = signal handler pointer -+ * $29 = point to sigframe struct -+ * ra ($31) = sigtramp at base of user stack -+ */ -+ regs->active_tc.gpr[ 4] = sig; -+ regs->active_tc.gpr[ 5] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; -+ regs->active_tc.gpr[29] = frame_addr; -+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ -+ return (0); -+} -+ -+/* -+ * Compare to mips/mips/pm_machdep.c get_mcontext() -+ * Assumes that the memory is locked if mcp points to user memory. -+ */ -+static inline int -+get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) -+{ -+ int i, err = 0; -+ -+ if (flags & TARGET_MC_ADD_MAGIC) { -+ mcp->mc_regs[0] = tswapal(TARGET_UCONTEXT_MAGIC); -+ } else { -+ mcp->mc_regs[0] = 0; -+ } -+ -+ if (flags & TARGET_MC_SET_ONSTACK) { -+ mcp->mc_onstack = tswapal(1); -+ } else { -+ mcp->mc_onstack = 0; -+ } -+ -+ for(i = 1; i < 32; i++) -+ mcp->mc_regs[i] = tswapal(regs->active_tc.gpr[i]); -+ -+#if 0 /* XXX FP is not used right now */ -+ abi_ulong used_fp = used_math() ? TARGET_MDTD_FPUSED : 0; -+ -+ mcp->mc_fpused = used_fp; -+ if (used_fp) { -+ preempt_disable(); -+ if (!is_fpu_owner()) { -+ own_fpu(); -+ for(i = 0; i < 33; i++) -+ mcp->mc_fpregs[i] = tswapal(regs->active_fpu.fpr[i]); -+ } -+ preempt_enable(); -+ } -+#else -+ mcp->mc_fpused = 0; -+#endif -+ -+ if (flags & TARGET_MC_GET_CLEAR_RET) { -+ mcp->mc_regs[2] = 0; /* v0 = 0 */ -+ mcp->mc_regs[3] = 0; /* v1 = 0 */ -+ mcp->mc_regs[7] = 0; /* a3 = 0 */ -+ } -+ -+ mcp->mc_pc = tswapal(regs->active_tc.PC); -+ mcp->mullo = tswapal(regs->active_tc.LO[0]); -+ mcp->mulhi = tswapal(regs->active_tc.HI[0]); -+ mcp->mc_tls = tswapal(regs->tls_value); -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return (err); -+} -+ -+/* Compare to mips/mips/pm_machdep.c set_mcontext() */ -+static inline int -+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) -+{ -+ int i, err = 0; -+ -+ for(i = 1; i < 32; i++) -+ regs->active_tc.gpr[i] = tswapal(mcp->mc_regs[i]); -+ -+#if 0 /* XXX FP is not used right now */ -+ abi_ulong used_fp = 0; -+ -+ used_fp = tswapal(mcp->mc_fpused) -+ conditional_used_math(used_fp); -+ -+ preempt_disabled(); -+ if (used_math()) { -+ /* restore fpu context if we have used it before */ -+ own_fpu(); -+ for (i = 0; i < 32; i++) -+ regs->active_fpu.fpr[i] = tswapal(mcp->mc_fpregs[i]); -+ } else { -+ /* Signal handler may have used FPU. Give it up. */ -+ lose_fpu(); -+ } -+ preempt_enable(); -+#endif -+ -+ regs->CP0_EPC = tswapal(mcp->mc_pc); -+ regs->active_tc.LO[0] = tswapal(mcp->mullo); -+ regs->active_tc.HI[0] = tswapal(mcp->mulhi); -+ regs->tls_value = tswapal(mcp->mc_tls); -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return (err); -+} -+ - #endif /* TARGET_SIGNAL_H */ -+ -diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c ---- a/bsd-user/mmap.c -+++ b/bsd-user/mmap.c -@@ -74,6 +74,8 @@ void mmap_unlock(void) - } - #endif - -+#if 0 /* XXX not sure why we need our own g_malloc() and friends. -+ g_strdup(), however, has serious problems with this g_malloc/g_free */ - static void *bsd_vmalloc(size_t size) - { - void *p; -@@ -133,6 +135,7 @@ void *g_realloc(void *ptr, size_t size) - g_free(ptr); - return new_ptr; - } -+#endif - - /* NOTE: all the constants are the HOST ones, but addresses are target. */ - int target_mprotect(abi_ulong start, abi_ulong len, int prot) -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index ab7e18c..9d4edbf 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -80,7 +80,7 @@ struct emulated_sigtable { - typedef struct TaskState { - struct TaskState *next; - int used; /* non zero if used */ --#if 1 -+ long ts_tid; /* tid (or pid) of this task */ - #ifdef TARGET_ARM - int swi_errno; - #endif -@@ -90,7 +90,6 @@ typedef struct TaskState { - uint32_t heap_limit; - #endif - uint32_t stack_base; --#endif - struct image_info *info; - struct bsd_binprm *bprm; - -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index 52441c4..d56837b 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -31,7 +31,7 @@ - #include "qemu.h" - #include "target_signal.h" - --//#define DEBUG_SIGNAL -+// #define DEBUG_SIGNAL - - #ifndef _NSIG - #define _NSIG 128 -@@ -606,101 +606,31 @@ do_sigaction(int sig, const struct target_sigaction *act, - return (ret); - } - --#if defined(TARGET_MIPS64) --static inline int --restore_sigmcontext(CPUMIPSState *regs, target_mcontext_t *mc) --{ -- int i, err = 0; -- -- for(i = 1; i < 32; i++) -- err |= __get_user(regs->active_tc.gpr[i], -- &mc->mc_regs[i]); -- err |= __get_user(regs->CP0_EPC, &mc->mc_pc); -- err |= __get_user(regs->active_tc.LO[0], &mc->mullo); -- err |= __get_user(regs->active_tc.HI[0], &mc->mulhi); -- err |= __get_user(regs->tls_value, &mc->mc_tls); /* XXX thread tls */ -- --#if 0 /* XXX */ -- int used_fp = 0; -- -- err |= __get_user(used_fp, &mc->mc_fpused); -- conditional_used_math(used_fp); -- -- preempt_disabled(); -- if (used_math()) { -- /* restore fpu context if we have used it before */ -- own_fpu(); -- err |= restore_fp_context(mc); -- } else { -- /* signal handler may have used FPU. Give it up. */ -- lose_fpu(); -- } -- preempt_enable(); --#endif -- -- return (err); --} -- --static inline int --setup_sigmcontext(CPUMIPSState *regs, target_mcontext_t *mc, int32_t oonstack) --{ -- int i, err = 0; -- abi_long ucontext_magic = TARGET_UCONTEXT_MAGIC; -- -- err = __put_user(oonstack ? 1 : 0, &mc->mc_onstack); -- err |= __put_user(regs->active_tc.PC, &mc->mc_pc); -- err |= __put_user(regs->active_tc.LO[0], &mc->mullo); -- err |= __put_user(regs->active_tc.HI[0], &mc->mulhi); -- err |= __put_user(regs->tls_value, &mc->mc_tls); /* XXX thread tls */ -- -- err |= __put_user(ucontext_magic, &mc->mc_regs[0]); -- for(i = 1; i < 32; i++) -- err |= __put_user(regs->active_tc.gpr[i], &mc->mc_regs[i]); -- -- err |= __put_user(0, &mc->mc_fpused); -- --#if 0 /* XXX */ -- err |= __put_user(used_math(), &mc->mc_fpused); -- if (used_math()) -- goto out; -- -- /* -- * Save FPU state to signal context. Signal handler will "inherit" -- * current FPU state. -- */ -- preempt_disable(); -- -- if (!is_fpu_owner()) { -- own_fpu(); -- for(i = 0; i < 33; i++) -- err |= __put_user(regs->active_tc.fpregs[i], &mc->mc_fpregs[i]); -- } -- err |= save_fp_context(fg); -- -- preempt_enable(); --out: --#endif -- return (err); --} -+#if defined(TARGET_MIPS) || defined(TARGET_SPARC64) - - static inline abi_ulong --get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size) -+get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size) - { - abi_ulong sp; - - /* Use default user stack */ -- sp = regs->active_tc.gpr[29]; -+ sp = get_sp_from_cpustate(regs); - - if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { -- sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; -+ sp = target_sigaltstack_used.ss_sp + -+ target_sigaltstack_used.ss_size; - } - -+#if defined(TARGET_MIPS) - return ((sp - frame_size) & ~7); -+#else -+ return (sp - frame_size); -+#endif - } - --/* compare to mips/mips/pm_machdep.c sendsig() */ -+/* compare to mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c sendsig() */ - static void setup_frame(int sig, struct target_sigaction *ka, -- target_sigset_t *set, CPUMIPSState *regs) -+ target_sigset_t *set, CPUArchState *regs) - { - struct target_sigframe *frame; - abi_ulong frame_addr; -@@ -709,54 +639,36 @@ static void setup_frame(int sig, struct target_sigaction *ka, - #ifdef DEBUG_SIGNAL - fprintf(stderr, "setup_frame()\n"); - #endif -+#if defined(TARGET_SPARC64) -+ if (!sparc_user_sigtramp) { -+ /* No signal trampoline... kill the process. */ -+ fprintf(stderr, "setup_frame(): no sigtramp\n"); -+ force_sig(TARGET_SIGKILL); -+ } -+#endif - - frame_addr = get_sigframe(ka, regs, sizeof(*frame)); - if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) - goto give_sigsegv; - -- if (setup_sigmcontext(regs, &frame->sf_uc.uc_mcontext, -- ! on_sig_stack(frame_addr))) -+#if defined(TARGET_MIPS) -+ int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC : -+ TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC; -+#else -+ int mflags = 0; -+#endif -+ if (get_mcontext(regs, &frame->sf_uc.uc_mcontext, mflags)) - goto give_sigsegv; - - for(i = 0; i < TARGET_NSIG_WORDS; i++) { -- if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i])) -+ if (__put_user(set->__bits[i], -+ &frame->sf_uc.uc_sigmask.__bits[i])) - goto give_sigsegv; - } - -- /* fill in sigframe structure */ -- if (__put_user(sig, &frame->sf_signum)) -- goto give_sigsegv; -- if (__put_user(0, &frame->sf_siginfo)) -- goto give_sigsegv; -- if (__put_user(0, &frame->sf_ucontext)) -+ if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) - goto give_sigsegv; - -- /* fill in siginfo structure */ -- if (__put_user(sig, &frame->sf_si.si_signo)) -- goto give_sigsegv; -- if (__put_user(TARGET_SA_SIGINFO, &frame->sf_si.si_code)) -- goto give_sigsegv; -- if (__put_user(regs->CP0_BadVAddr, &frame->sf_si.si_addr)) -- goto give_sigsegv; -- -- /* -- * Arguments to signal handler: -- * a0 ($4) = signal number -- * a1 ($5) = siginfo pointer -- * a2 ($6) = ucontext pointer -- * PC = signal handler pointer -- * t9 ($25) = signal handler pointer -- * $29 = point to sigframe struct -- * ra ($31) = sigtramp at base of user stack -- */ -- regs->active_tc.gpr[ 4] = sig; -- regs->active_tc.gpr[ 5] = frame_addr + -- offsetof(struct target_sigframe, sf_si); -- regs->active_tc.gpr[ 6] = frame_addr + -- offsetof(struct target_sigframe, sf_uc); -- regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; -- regs->active_tc.gpr[29] = frame_addr; -- regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; - unlock_user_struct(frame, frame_addr, 1); - return; - -@@ -766,7 +678,7 @@ give_sigsegv: - } - - long --do_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr) -+do_sigreturn(CPUArchState *regs, abi_ulong uc_addr) - { - target_ucontext_t *ucontext; - sigset_t blocked; -@@ -784,14 +696,17 @@ do_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr) - goto badframe; - } - -- if (restore_sigmcontext(regs, &ucontext->uc_mcontext)) -+ if (set_mcontext(regs, &ucontext->uc_mcontext, 0)) - goto badframe; - - target_to_host_sigset_internal(&blocked, &target_set); - sigprocmask(SIG_SETMASK, &blocked, NULL); - -- regs->active_tc.PC = regs->CP0_EPC; -- regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+#if defined(TARGET_MIPS) -+ CPUMIPSState *mips_regs = (CPUMIPSState *)regs; -+ mips_regs->active_tc.PC = mips_regs->CP0_EPC; -+ mips_regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+#endif - return (-TARGET_QEMU_ESIGRETURN); - - badframe: -@@ -799,9 +714,10 @@ badframe: - return (0); - } - --#elif defined(TARGET_SPARC64) - --extern abi_ulong sparc_user_sigtramp; -+ -+/* #elif defined(TARGET_SPARC64) */ -+#if 0 - - #define mc_flags mc_global[0] - #define mc_sp mc_out[6] -@@ -1039,6 +955,7 @@ badframe: - force_sig(TARGET_SIGSEGV); - return (0); - } -+#endif - - #else - -diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h -index 79dfc1e..e2fe79c 100644 ---- a/bsd-user/sparc/target_signal.h -+++ b/bsd-user/sparc/target_signal.h -@@ -13,9 +13,34 @@ - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -+typedef target_ulong target_mcontext_t; /* dummy */ -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ - static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) - { - return state->regwptr[UREG_FP]; - } - -+static inline int -+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "SPARC doesn't have support for get_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ -+static inline int -+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "SPARC doesn't have support for set_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h -index d3e58bb..1bc7c96 100644 ---- a/bsd-user/sparc64/target_signal.h -+++ b/bsd-user/sparc64/target_signal.h -@@ -10,12 +10,239 @@ - #define UREG_FP UREG_I6 - #endif - -+#define mc_flags mc_global[0] -+#define mc_sp mc_out[6] -+#define mc_fprs mc_local[0] -+#define mc_fsr mc_local[1] -+#define mc_gsr mc_local[2] -+#define mc_tnpc mc_in[0] -+#define mc_tpc mc_in[1] -+#define mc_tstate mc_in[2] -+#define mc_y mc_in[4] -+#define mc_wstate mc_in[5] -+ -+#define ureg_i0 regwptr[0 ] -+#define ureg_i1 regwptr[1 ] -+#define ureg_i2 regwptr[2 ] -+#define ureg_i3 regwptr[3 ] -+#define ureg_i4 regwptr[4 ] -+#define ureg_i5 regwptr[5 ] -+#define ureg_i6 regwptr[6 ] -+#define ureg_i7 regwptr[7 ] -+#define ureg_l0 regwptr[8 ] -+#define ureg_l1 regwptr[9 ] -+#define ureg_l2 regwptr[10] -+#define ureg_l3 regwptr[11] -+#define ureg_l4 regwptr[12] -+#define ureg_l5 regwptr[13] -+#define ureg_l6 regwptr[14] -+#define ureg_l7 regwptr[15] -+#define ureg_o0 regwptr[16] -+#define ureg_o1 regwptr[17] -+#define ureg_o2 regwptr[18] -+#define ureg_o3 regwptr[19] -+#define ureg_o4 regwptr[20] -+#define ureg_o5 regwptr[21] -+#define ureg_o6 regwptr[22] -+#define ureg_o7 regwptr[23] -+#define ureg_fp ureg_i6 -+#define ureg_sp ureg_o6 -+#define ureg_fprs fprs -+#define ureg_fsr fsr -+#define ureg_gsr gsr -+#define ureg_tnpc npc -+#define ureg_tpc pc -+#define ureg_y y -+ -+#define TARGET_FPRS_FEF (1 << 2) -+#define TARGET_MC_VERSION 1L -+ - #define TARGET_MINSIGSTKSZ (1024 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - --static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) -+#define TARGET_STACK_BIAS 2047 /* AKA. SPOFF */ -+ -+struct target_mcontext { -+ uint64_t mc_global[8]; -+ uint64_t mc_out[8]; -+ uint64_t mc_local[8]; -+ uint64_t mc_in[8]; -+ uint32_t mc_fp[64]; -+} __aligned(64); -+ -+typedef struct target_mcontext target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ target_ucontext_t sf_uc; -+ target_siginfo_t sf_si; -+}; -+ -+extern abi_ulong sparc_user_sigtramp; -+ -+static inline int -+set_sigtramp_args(CPUSPARCState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) - { -+ -+ frame->sf_si.si_signo = sig; -+ frame->sf_si.si_code = TARGET_SA_SIGINFO; -+ -+ /* Arguments to signal handler: -+ * -+ * i0 = signal number -+ * i1 = pointer to siginfo struct -+ * i2 = pointer to ucontext struct -+ * i3 = (not used in new style) -+ * i4 = signal handler address (called by sigtramp) -+ */ -+ regs->ureg_i0 = sig; -+ regs->ureg_i1 = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->ureg_i2 = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ /* env->ureg_o3 used in the Old FreeBSD-style arguments. */ -+ regs->ureg_i4 = ka->_sa_handler; -+ regs->ureg_tpc = sparc_user_sigtramp; -+ regs->ureg_tnpc = (regs->ureg_tpc + 4); -+ regs->ureg_sp = frame_addr - TARGET_STACK_BIAS; -+ -+ return (0); -+} -+ -+static inline abi_ulong -+get_sp_from_cpustate(CPUSPARCState *state) -+{ -+ - return state->regwptr[UREG_FP]; - } - -+/* compare to sparc64/sparc64/machdep.c get_mcontext() */ -+static inline int -+get_mcontext(CPUSPARCState *regs, target_mcontext_t *mcp, int flags) -+{ -+ -+ /* Skip over the trap instruction, first. */ -+ regs->pc = regs->npc; -+ regs->npc += 4; -+ -+ mcp->mc_flags = TARGET_MC_VERSION; /* mc_global[0] */ -+ mcp->mc_global[1] = tswapal(regs->gregs[1]); -+ mcp->mc_global[2] = tswapal(regs->gregs[2]); -+ mcp->mc_global[3] = tswapal(regs->gregs[3]); -+ mcp->mc_global[4] = tswapal(regs->gregs[4]); -+ mcp->mc_global[5] = tswapal(regs->gregs[5]); -+ mcp->mc_global[6] = tswapal(regs->gregs[6]); -+ /* skip %g7 since it is used as the userland TLS register */ -+ -+ if (flags & TARGET_MC_GET_CLEAR_RET) { -+ mcp->mc_out[0] = 0; -+ mcp->mc_out[1] = 0; -+ } else { -+ mcp->mc_out[0] = tswapal(regs->ureg_i0); -+ mcp->mc_out[1] = tswapal(regs->ureg_i1); -+ } -+ mcp->mc_out[2] = tswapal(regs->ureg_i2); -+ mcp->mc_out[3] = tswapal(regs->ureg_i3); -+ mcp->mc_out[4] = tswapal(regs->ureg_i4); -+ mcp->mc_out[5] = tswapal(regs->ureg_i5); -+ mcp->mc_out[6] = tswapal(regs->ureg_i6); -+ mcp->mc_out[7] = tswapal(regs->ureg_i7); -+ -+ mcp->mc_fprs = tswapal(regs->fprs); /* mc_local[0] */ -+ mcp->mc_fsr = tswapal(regs->fsr); /* mc_local[1] */ -+ mcp->mc_gsr = tswapal(regs->gsr); /* mc_local[2] */ -+ -+ mcp->mc_tnpc = tswapal(regs->npc); /* mc_in[0] */ -+ mcp->mc_tpc = tswapal(regs->pc); /* mc_in[1] */ -+#if 0 -+ mcp->mc_tstate = tswapal(regs->ureg_tstate); /* mc_in[2] */ -+#else -+ abi_ulong cwp64 = cpu_get_cwp64(regs); -+ abi_ulong ccr = cpu_get_ccr(regs) << 32; -+ abi_ulong asi = (regs->asi & 0xff) << 24; -+ mcp->mc_tstate = tswapal(ccr | asi | cwp64); -+#endif -+ -+ mcp->mc_y = tswapal(regs->y); /* mc_in[4] */ -+ -+ /* XXX -+ if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) { -+ int i; -+ -+ for(i = 0; i < 64; i++) -+ mcp->mc_fp[i] = tswapal(regs->fpr[i]); -+ } -+ */ -+ -+ return (0); -+} -+ -+extern void helper_flushw(CPUSPARCState *env); -+ -+/* compare to sparc64/sparc64/machdep.c set_mcontext() */ -+static inline int -+set_mcontext(CPUSPARCState *regs, target_mcontext_t *mcp, int flags) -+{ -+ /* XXX need to add version check here. */ -+ -+ /* Make sure the windows are spilled first. */ -+ helper_flushw(regs); -+ -+ regs->gregs[1] = tswapal(mcp->mc_global[1]); -+ regs->gregs[2] = tswapal(mcp->mc_global[2]); -+ regs->gregs[3] = tswapal(mcp->mc_global[3]); -+ regs->gregs[4] = tswapal(mcp->mc_global[4]); -+ regs->gregs[5] = tswapal(mcp->mc_global[5]); -+ regs->gregs[6] = tswapal(mcp->mc_global[6]); -+ -+ regs->ureg_i0 = tswapal(mcp->mc_out[0]); -+ regs->ureg_i1 = tswapal(mcp->mc_out[1]); -+ regs->ureg_i2 = tswapal(mcp->mc_out[2]); -+ regs->ureg_i3 = tswapal(mcp->mc_out[3]); -+ regs->ureg_i4 = tswapal(mcp->mc_out[4]); -+ regs->ureg_i5 = tswapal(mcp->mc_out[5]); -+ regs->ureg_i6 = tswapal(mcp->mc_out[6]); -+ regs->ureg_i7 = tswapal(mcp->mc_out[7]); -+ -+ regs->fprs = tswapal(mcp->mc_fprs); /* mc_local[0] */ -+ regs->fsr = tswapal(mcp->mc_fsr); /* mc_local[1] */ -+ regs->gsr = tswapal(mcp->mc_gsr); /* mc_local[2] */ -+ -+ regs->npc = tswapal(mcp->mc_tnpc); /* mc_in[0] */ -+ regs->pc = tswapal(mcp->mc_tpc); /* mc_in[1] */ -+ -+#if 0 -+ regs->ureg_tstate = tswapal(mcp->mc_tstate); /* mc_in[2] */ -+#else -+ abi_ulong tstate = tswapal(mcp->mc_tstate); /* mc_in[2] */ -+ -+ regs->asi = (tstate >> 24) & 0xff; -+ cpu_put_ccr(regs, tstate >> 32); -+ cpu_put_cwp64(regs, tstate & 0x1f); -+ -+#endif -+ regs->ureg_y = tswapal(mcp->mc_y); /* mc_in[4] */ -+ -+ /* XXX -+ if ((regs->ureg_fprs & TARGET_FPRS_FEF) != 0) { -+ int i; -+ -+ regs->ureg_l0 = 0; -+ for(i = 0; i < 64; i++) -+ regs->fpr[i] = tswapal(mcp->mc_fp[i]); -+ } -+ */ -+ -+ return (0); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 625c3cf..4deb0db 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -43,6 +43,12 @@ - #ifdef __FreeBSD__ - #include <sys/regression.h> - #include <sys/procdesc.h> -+#include <sys/ucontext.h> -+#include <sys/thr.h> -+#include <sys/rtprio.h> -+#include <sys/umtx.h> -+#include <pthread.h> -+#include <machine/atomic.h> - #endif - #include <sys/un.h> - #include <sys/ipc.h> -@@ -251,7 +257,24 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - #ifdef TARGET_MIPS - static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - { -- return -TARGET_EINVAL; -+ int ret = 0; -+ CPUMIPSState *mips_env = (CPUMIPSState *)env; -+ -+ switch(op) { -+ case TARGET_MIPS_SET_TLS: -+ if (get_user(mips_env->tls_value, parms, abi_ulong)) -+ ret = -TARGET_EFAULT; -+ break; -+ case TARGET_MIPS_GET_TLS: -+ if (put_user(mips_env->tls_value, parms, abi_ulong)) -+ ret = -TARGET_EFAULT; -+ break; -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ -+ return (ret); - } - #endif - -@@ -2119,6 +2142,383 @@ do_fork(CPUArchState *env, int num, int flags, int *fdp) - return (ret); - } - -+#if defined(CONFIG_USE_NPTL) -+ -+#define NEW_STACK_SIZE (0x40000) -+ -+static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER; -+typedef struct { -+ CPUArchState *env; -+ long tid; -+ pthread_mutex_t mutex; -+ pthread_cond_t cond; -+ pthread_t thread; -+ sigset_t sigmask; -+ struct target_thr_param param; -+} new_thread_info_t; -+ -+static void * -+new_thread_start(void *arg) -+{ -+ new_thread_info_t *info = arg; -+ CPUArchState *env; -+ TaskState *ts; -+ long tid; -+ -+ env = info->env; -+ thread_env = env; -+ ts = (TaskState *)thread_env->opaque; -+ (void)thr_self(&tid); -+ info->tid = tid; -+ task_settid(ts); -+ -+ /* copy out the TID info */ -+ if (info->param.child_tid) -+ put_user(tid, info->param.child_tid, abi_long); -+ if (info->param.parent_tid) -+ put_user(tid, info->param.parent_tid, abi_long); -+ -+#ifdef TARGET_MIPS64 -+ CPUMIPSState *regs = env; -+ regs->active_tc.gpr[25] = regs->active_tc.PC = info->param.start_func; -+ regs->active_tc.gpr[ 4] = info->param.arg; -+ regs->active_tc.gpr[29] = info->param.stack_base; -+#endif -+ /* Eenable signals */ -+ sigprocmask(SIG_SETMASK, &info->sigmask, NULL); -+ /* Signal to the parent that we're ready. */ -+ pthread_mutex_lock(&info->mutex); -+ pthread_cond_broadcast(&info->cond); -+ pthread_mutex_unlock(&info->mutex); -+ /* Wait until the parent has finished initializing the TLS state. */ -+ pthread_mutex_lock(&new_thread_lock); -+ pthread_mutex_unlock(&new_thread_lock); -+ -+ cpu_loop(env); -+ /* never exits */ -+ -+ return (NULL); -+} -+ -+static void -+rtp_to_schedparam(const struct rtprio *rtp, int *policy, struct sched_param *param) -+{ -+ -+ switch(rtp->type) { -+ case RTP_PRIO_REALTIME: -+ *policy = SCHED_RR; -+ param->sched_priority = RTP_PRIO_MAX - rtp->prio; -+ break; -+ -+ case RTP_PRIO_FIFO: -+ *policy = SCHED_FIFO; -+ param->sched_priority = RTP_PRIO_MAX - rtp->prio; -+ break; -+ -+ default: -+ *policy = SCHED_OTHER; -+ param->sched_priority = 0; -+ break; -+ } -+} -+ -+static int -+do_thr_create(CPUArchState *env, ucontext_t *ctx, long *id, int flags) -+{ -+ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_create)); -+} -+ -+static int -+do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size) -+{ -+ new_thread_info_t info; -+ pthread_attr_t attr; -+ TaskState *ts; -+ CPUArchState *new_env; -+ struct target_thr_param *target_param; -+ abi_ulong target_rtp_addr; -+ struct target_rtprio *target_rtp; -+ struct rtprio *rtp_ptr, rtp; -+ TaskState *parent_ts = (TaskState *)env->opaque; -+ sigset_t sigmask; -+ struct sched_param sched_param; -+ int sched_policy; -+ int ret = 0; -+ -+ memset(&info, 0, sizeof(info)); -+ -+ if (!lock_user_struct(VERIFY_READ, target_param, target_param_addr, 1)) -+ return (-TARGET_EFAULT); -+ info.param.start_func = tswapal(target_param->start_func); -+ info.param.arg = tswapal(target_param->arg); -+ info.param.stack_base = tswapal(target_param->stack_base); -+ info.param.stack_size = tswapal(target_param->stack_size); -+ info.param.tls_base = tswapal(target_param->tls_base); -+ info.param.tls_size = tswapal(target_param->tls_size); -+ info.param.child_tid = tswapal(target_param->child_tid); -+ info.param.parent_tid = tswapal(target_param->parent_tid); -+ target_rtp_addr = info.param.rtp = tswapal(target_param->rtp); -+ unlock_user(target_param, target_param_addr, 0); -+ -+ if (target_rtp_addr) { -+ if (!lock_user_struct(VERIFY_READ, target_rtp, target_rtp_addr, -+ 1)) -+ return (-TARGET_EFAULT); -+ rtp.type = tswap16(target_rtp->type); -+ rtp.prio = tswap16(target_rtp->prio); -+ unlock_user(target_rtp, target_rtp_addr, 0); -+ rtp_ptr = &rtp; -+ } else { -+ rtp_ptr = NULL; -+ } -+ -+ /* Create a new CPU instance. */ -+ ts = g_malloc0(sizeof(TaskState)); -+ init_task_state(ts); -+ new_env = cpu_copy(env); -+#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) -+ cpu_reset(ENV_GET_CPU(new_env)); -+#endif -+ -+ /* init regs that differ from the parent thread. */ -+ cpu_clone_regs(new_env, info.param.stack_base); -+ new_env->opaque = ts; -+ ts->bprm = parent_ts->bprm; -+ ts->info = parent_ts->info; -+ -+#if defined(TARGET_MIPS) -+ env->tls_value = info.param.tls_base; -+ /* cpu_set_tls(new_env, info.param.tls_base); */ -+#endif -+ -+ /* Grab a mutex so that thread setup appears atomic. */ -+ pthread_mutex_lock(&new_thread_lock); -+ -+ pthread_mutex_init(&info.mutex, NULL); -+ pthread_mutex_lock(&info.mutex); -+ pthread_cond_init(&info.cond, NULL); -+ info.env = new_env; -+ -+ /* XXX return value needs to be checked... */ -+ pthread_attr_init(&attr); -+ pthread_attr_setstacksize(&attr, NEW_STACK_SIZE); -+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -+ if (rtp_ptr) { -+ rtp_to_schedparam(&rtp, &sched_policy, &sched_param); -+ pthread_attr_setschedpolicy(&attr, sched_policy); -+ pthread_attr_setschedparam(&attr, &sched_param); -+ } -+ -+ /* -+ * It is not safe to deliver signals until the child has finished -+ * initializing, so temporarily block all signals. -+ */ -+ sigfillset(&sigmask); -+ sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); -+ -+ /* XXX return value needs to be checked... */ -+ ret = pthread_create(&info.thread, &attr, new_thread_start, &info); -+ /* XXX Free new CPU state if thread creation fails. */ -+ -+ sigprocmask(SIG_SETMASK, &info.sigmask, NULL); -+ pthread_attr_destroy(&attr); -+ if (0 == ret) { -+ /* Wait for the child to initialize. */ -+ pthread_cond_wait(&info.cond, &info.mutex); -+ } else { -+ /* pthread_create failed. */ -+ } -+ -+ pthread_mutex_unlock(&info.mutex); -+ pthread_cond_destroy(&info.cond); -+ pthread_mutex_destroy(&info.mutex); -+ pthread_mutex_unlock(&new_thread_lock); -+ -+ return (ret); -+} -+ -+static int -+do_thr_self(long *id) -+{ -+ -+ return (get_errno(thr_self(id))); -+} -+ -+static void -+do_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) -+{ -+ -+ if (first_cpu->next_cpu) { -+ TaskState *ts; -+ CPUArchState **lastp, *p; -+ -+ /* -+ * *XXX This probably breaks if a signal arrives. -+ * We should disable signals. -+ */ -+ cpu_list_lock(); -+ lastp = &first_cpu; -+ p = first_cpu; -+ while (p && p != (CPUArchState *)cpu_env) { -+ lastp = &p->next_cpu; -+ p = p->next_cpu; -+ } -+ /* -+ * if we didn't find the CPU for this thread then something -+ * is horribly wrong. -+ */ -+ if (!p) -+ abort(); -+ /* Remove the CPU from the list. */ -+ *lastp = p->next_cpu; -+ cpu_list_unlock(); -+ ts = ((CPUArchState *)cpu_env)->opaque; -+ -+ if (tid_addr) { -+ /* Signal target userland that it can free the stack. */ -+ if (! put_user_u32(1, tid_addr)) -+ _umtx_op(g2h(tid_addr), UMTX_OP_WAKE, INT_MAX, -+ NULL, NULL); -+ } -+ -+ thread_env = NULL; -+ object_delete(OBJECT(ENV_GET_CPU(cpu_env))); -+ g_free(ts); -+ pthread_exit(NULL); -+ } -+} -+ -+static int -+do_thr_kill(long id, int sig) -+{ -+ -+ return (get_errno(thr_kill(id, sig))); -+} -+ -+static int -+do_thr_kill2(pid_t pid, long id, int sig) -+{ -+ -+ return (get_errno(thr_kill2(pid, id, sig))); -+} -+ -+static int -+do_thr_suspend(const struct timespec *timeout) -+{ -+ -+ return (get_errno(thr_suspend(timeout))); -+} -+ -+static int -+do_thr_wake(long tid) -+{ -+ -+ return (get_errno(thr_wake(tid))); -+} -+ -+static int -+do_thr_set_name(long tid, char *name) -+{ -+ -+ return (get_errno(thr_set_name(tid, name))); -+} -+ -+ -+#else /* ! CONFIG_USE_NPTL */ -+ -+static int -+do_thr_create(CPUArchState *env, ucontext_t *ctx, long *id, int flags) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_create)); -+} -+ -+static int -+do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_new)); -+} -+ -+static int -+do_thr_self(long *tid) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_self)); -+} -+ -+static void -+do_thr_exit(CPUArchState *cpu_env, abi_ulong state_addr) -+{ -+} -+ -+static int -+do_thr_kill(long tid, int sig) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_kill2)); -+} -+ -+static int -+do_thr_kill2(pid_t pid, long tid, int sig) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_kill2)); -+} -+ -+static int -+do_thr_suspend(const struct timespec *timeout) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_suspend)); -+} -+ -+static int -+do_thr_wake(long tid) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_wake)); -+} -+ -+static int -+do_thr_set_name(long tid, char *name) -+{ -+ return (unimplemented(TARGET_FREEBSD_NR_thr_set_name)); -+} -+ -+#endif /* CONFIG_USE_NPTL */ -+ -+static int -+do_umtx_lock(abi_ulong umtx_addr, uint32_t id) -+{ -+ int ret = 0; -+ -+ for (;;) { -+ ret = get_errno(_umtx_op(g2h(umtx_addr + -+ offsetof(struct target_umtx, u_owner)), -+ UMTX_OP_MUTEX_WAIT, UMTX_UNOWNED, 0, 0)); -+ if (ret) -+ return (ret); -+ if (atomic_cmpset_acq_32(g2h(umtx_addr + -+ offsetof(struct target_umtx, u_owner)), -+ UMTX_UNOWNED, id)) -+ return (0); -+ } -+} -+ -+static int -+do_umtx_unlock(abi_ulong umtx_addr, uint32 id) -+{ -+ uint32_t owner; -+ -+ do { -+ if (get_user_u32(owner, umtx_addr + -+ offsetof(struct target_umtx, u_owner))) -+ return (-TARGET_EFAULT); -+ if (owner != id) -+ return (-TARGET_EPERM); -+ } while (!atomic_cmpset_rel_32(g2h(umtx_addr + -+ offsetof(struct target_umtx, u_owner)), owner, -+ UMUTEX_UNOWNED)); -+ -+ return (0); -+} -+ -+ - /* do_syscall() should always have a single exit point at the end so - that actions, such as logging of syscall results, can be performed. - All errnos that do_syscall() returns must be -TARGET_<errcode>. */ -@@ -4091,6 +4491,23 @@ do_stat: - break; - #endif - -+#ifdef TARGET_FREEBSD_NR_getdomainname -+ case TARGET_FREEBSD_NR_getdomainname: -+ ret = unimplemented(num); -+ break; -+#endif -+#ifdef TARGET_FREEBSD_NR_setdomainname -+ case TARGET_FREEBSD_NR_setdomainname: -+ ret = unimplemented(num); -+ break; -+#endif -+#ifdef TARGET_FREEBSD_NR_uname -+ case TARGET_FREEBSD_NR_uname: -+ ret = unimplemented(num); -+ break; -+#endif -+ -+ - #if 0 /* XXX not supported in libc yet, it seems (10.0 addition). */ - case TARGET_FREEBSD_NR_posix_fadvise: - { -@@ -4136,6 +4553,211 @@ do_stat: - break; - #endif - -+ case TARGET_FREEBSD_NR_thr_new: -+ ret = do_thr_new(cpu_env, arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_create: -+ { -+ ucontext_t ucxt; -+ long tid; -+ -+ ret = do_thr_create(cpu_env, &ucxt, &tid, arg3); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_set_name: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = do_thr_set_name(arg1, p); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_self: -+ { -+ long tid; -+ -+ if ((ret = do_thr_self(&tid)) == 0) { -+ if (put_user((abi_long)tid, arg1, abi_long)) -+ goto efault; -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_suspend: -+ { -+ struct timespec ts; -+ -+ if (target_to_host_timespec(&ts, arg1)) -+ goto efault; -+ -+ ret = do_thr_suspend(&ts); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_wake: -+ ret = do_thr_wake(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_kill: -+ ret = do_thr_kill(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_kill2: -+ ret = do_thr_kill2(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_exit: -+ ret = 0; /* suspress compile warning */ -+ do_thr_exit(cpu_env, arg1); -+ /* Shouldn't be reached. */ -+ break; -+ -+ case TARGET_FREEBSD_NR_rtprio_thread: -+ ret = 0; -+ break; -+ -+ case TARGET_FREEBSD_NR_getcontext: -+ { -+ target_ucontext_t *ucp; -+ sigset_t sigmask; -+ -+ if (0 == arg1) { -+ ret = -TARGET_EINVAL; -+ } else { -+ ret = get_errno(sigprocmask(0, NULL, &sigmask)); -+ if (!is_error(ret)) { -+ if (!(ucp = lock_user(VERIFY_WRITE, arg1, -+ sizeof(target_ucontext_t), 0))) -+ goto efault; -+ ret = get_mcontext(cpu_env, &ucp->uc_mcontext, -+ TARGET_MC_GET_CLEAR_RET); -+ host_to_target_sigset(&ucp->uc_sigmask, -+ &sigmask); -+ memset(ucp->__spare__, 0, -+ sizeof(ucp->__spare__)); -+ unlock_user(ucp, arg1, -+ sizeof(target_ucontext_t)); -+ } -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_setcontext: -+ { -+ target_ucontext_t *ucp; -+ sigset_t sigmask; -+ -+ if (0 == arg1) { -+ ret = -TARGET_EINVAL; -+ } else { -+ if (!(ucp = lock_user(VERIFY_READ, arg1, -+ sizeof(target_ucontext_t), 1))) -+ goto efault; -+ ret = set_mcontext(cpu_env, &ucp->uc_mcontext, 0); -+ target_to_host_sigset(&sigmask, &ucp->uc_sigmask); -+ unlock_user(ucp, arg1, sizeof(target_ucontext_t)); -+ if (0 == ret) -+ (void)sigprocmask(SIG_SETMASK, &sigmask, NULL); -+ } -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_swapcontext: -+ /* -+ * XXX Does anything besides old implementations of -+ * setjmp()/longjmp() uses these? -+ */ -+ ret = unimplemented(num); -+ break; -+ -+ case TARGET_FREEBSD_NR__umtx_lock: -+ { -+ long tid; -+ -+ thr_self(&tid); -+ ret = do_umtx_lock(arg1, tswap32(tid)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR__umtx_unlock: -+ { -+ long tid; -+ -+ thr_self(&tid); -+ ret = do_umtx_unlock(arg1, tswap32(tid)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR__umtx_op: -+ { -+ struct timespec ts; -+ void *object = NULL; -+ int operation; -+ void *addr = NULL; -+ void *addr2 = NULL; -+ -+ -+ /* int _umtx_op(void *obj, int op, u_long val, -+ * void *uaddr, void *uaddr2); */ -+ -+ abi_ulong obj = arg1; -+ int op = (int)arg2; -+ u_long val = arg3; -+ /* abi_ulong uaddr = arg4; */ -+ abi_ulong uaddr2 = arg5; -+ -+ switch(op) { -+ case TARGET_UMTX_OP_LOCK: -+ ret = do_umtx_lock(obj, tswap32((uint32_t)val)); -+ break; -+ -+ case TARGET_UMTX_OP_UNLOCK: -+ ret = do_umtx_unlock(obj, tswap32((uint32_t)val)); -+ break; -+ -+ case TARGET_UMTX_OP_WAIT: -+ if (uaddr2) { -+ if (target_to_host_timespec(&ts, uaddr2)) -+ goto efault; -+ addr2 = (void *)&ts; -+ } -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT, -+ tswap32(val), addr, addr2)); -+ break; -+ -+ case TARGET_UMTX_OP_WAKE: -+ operation = UMTX_OP_WAKE; -+ object = g2h(obj); -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE, -+ val, 0, 0)); -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_TRYLOCK: -+ case TARGET_UMTX_OP_MUTEX_LOCK: -+ case TARGET_UMTX_OP_MUTEX_UNLOCK: -+ case TARGET_UMTX_OP_SET_CEILING: -+ case TARGET_UMTX_OP_CV_WAIT: -+ case TARGET_UMTX_OP_CV_SIGNAL: -+ case TARGET_UMTX_OP_CV_BROADCAST: -+ case TARGET_UMTX_OP_WAIT_UINT: -+ case TARGET_UMTX_OP_RW_RDLOCK: -+ case TARGET_UMTX_OP_RW_WRLOCK: -+ case TARGET_UMTX_OP_RW_UNLOCK: -+ case TARGET_UMTX_OP_WAIT_UINT_PRIVATE: -+ case TARGET_UMTX_OP_WAKE_PRIVATE: -+ case TARGET_UMTX_OP_MUTEX_WAIT: -+ case TARGET_UMTX_OP_MUTEX_WAKE: -+ case TARGET_UMTX_OP_SEM_WAIT: -+ case TARGET_UMTX_OP_SEM_WAKE: -+ case TARGET_UMTX_OP_NWAKE_PRIVATE: -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ } -+ break; -+ - case TARGET_FREEBSD_NR_yield: - case TARGET_FREEBSD_NR_sched_setparam: - case TARGET_FREEBSD_NR_sched_getparam: -@@ -4146,36 +4768,18 @@ do_stat: - case TARGET_FREEBSD_NR_sched_get_priority_min: - case TARGET_FREEBSD_NR_sched_rr_get_interval: - -- - case TARGET_FREEBSD_NR_reboot: - case TARGET_FREEBSD_NR_shutdown: - - case TARGET_FREEBSD_NR_swapon: - case TARGET_FREEBSD_NR_swapoff: - -- case TARGET_FREEBSD_NR_thr_create: -- case TARGET_FREEBSD_NR_thr_exit: -- case TARGET_FREEBSD_NR_thr_self: -- case TARGET_FREEBSD_NR_thr_suspend: -- case TARGET_FREEBSD_NR_thr_wake: -- case TARGET_FREEBSD_NR_thr_new: -- case TARGET_FREEBSD_NR_thr_set_name: -- case TARGET_FREEBSD_NR_thr_kill2: -- -- case TARGET_FREEBSD_NR_getcontext: -- case TARGET_FREEBSD_NR_setcontext: -- case TARGET_FREEBSD_NR_swapcontext: -- -- case TARGET_FREEBSD_NR_rtprio_thread: - case TARGET_FREEBSD_NR_cpuset: - case TARGET_FREEBSD_NR_cpuset_getid: - case TARGET_FREEBSD_NR_cpuset_setid: - case TARGET_FREEBSD_NR_cpuset_getaffinity: - case TARGET_FREEBSD_NR_cpuset_setaffinity: - -- case TARGET_FREEBSD_NR__umtx_lock: -- case TARGET_FREEBSD_NR__umtx_unlock: -- - case TARGET_FREEBSD_NR_rctl_get_racct: - case TARGET_FREEBSD_NR_rctl_get_rules: - case TARGET_FREEBSD_NR_rctl_add_rule: -@@ -4185,16 +4789,6 @@ do_stat: - case TARGET_FREEBSD_NR_ntp_adjtime: - case TARGET_FREEBSD_NR_ntp_gettime: - --#ifdef TARGET_FREEBSD_NR_getdomainname -- case TARGET_FREEBSD_NR_getdomainname: --#endif --#ifdef TARGET_FREEBSD_NR_setdomainname -- case TARGET_FREEBSD_NR_setdomainname: --#endif --#ifdef TARGET_FREEBSD_NR_uname -- case TARGET_FREEBSD_NR_uname: --#endif -- - case TARGET_FREEBSD_NR_sctp_peeloff: - case TARGET_FREEBSD_NR_sctp_generic_sendmsg: - case TARGET_FREEBSD_NR_sctp_generic_recvmsg: -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index ea1d25d..2879d83 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -416,6 +416,11 @@ struct target_shmid_ds { - abi_ulong shm_ctime; /* time of last change by shmctl() */ - }; - -+#define TARGET_UCONTEXT_MAGIC 0xACEDBADE -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+#define TARGET_MC_ADD_MAGIC 0x0002 -+#define TARGET_MC_SET_ONSTACK 0x0004 -+ - /* this struct defines a stack used during syscall handling */ - typedef struct target_sigaltstack { - abi_long ss_sp; -@@ -477,95 +482,6 @@ typedef struct target_siginfo { - } _reason; - } target_siginfo_t; - --#if defined(TARGET_MIPS) -- --struct target_sigcontext { -- target_sigset_t sc_mask; /* signal mask to retstore */ -- int32_t sc_onstack; /* sigstack state to restore */ -- abi_long sc_pc; /* pc at time of signal */ -- abi_long sc_reg[32]; /* processor regs 0 to 31 */ -- abi_long mullo, mulhi; /* mullo and mulhi registers */ -- int32_t sc_fpused; /* fp has been used */ -- abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -- abi_long sc_fpc_eir; /* fp exception instr reg */ -- /* int32_t reserved[8]; */ --}; -- --typedef struct target_mcontext { -- int32_t mc_onstack; /* sigstack state to restore */ -- abi_long mc_pc; /* pc at time of signal */ -- abi_long mc_regs[32]; /* process regs 0 to 31 */ -- abi_long sr; /* status register */ -- abi_long mullo, mulhi; -- int32_t mc_fpused; /* fp has been used */ -- abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */ -- abi_long mc_fpc_eir; /* fp exception instr reg */ -- abi_ulong mc_tls; /* pointer to TLS area */ --} target_mcontext_t; -- --typedef struct target_ucontext { -- target_sigset_t uc_sigmask; -- target_mcontext_t uc_mcontext; -- target_ulong uc_link; -- target_stack_t uc_stack; -- int32_t uc_flags; -- int32_t __space__[8]; --} target_ucontext_t; -- --struct target_sigframe { -- abi_ulong sf_signum; -- abi_ulong sf_siginfo; /* code or pointer to sf_si */ -- abi_ulong sf_ucontext; /* points to sf_uc */ -- abi_ulong sf_addr; /* undocumented 4th arg */ -- target_ucontext_t sf_uc; /* = *sf_uncontext */ -- target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -- uint32_t __spare__[2]; --}; -- --#elif defined(TARGET_SPARC64) -- --struct target_mcontext { -- uint64_t mc_global[8]; -- uint64_t mc_out[8]; -- uint64_t mc_local[8]; -- uint64_t mc_in[8]; -- uint32_t mc_fp[64]; --} __aligned(64); -- --typedef struct target_mcontext target_mcontext_t; -- --typedef struct target_ucontext { -- target_sigset_t uc_sigmask; -- target_mcontext_t uc_mcontext; -- target_ulong uc_link; -- target_stack_t uc_stack; -- int32_t uc_flags; -- int32_t __space__[8]; --} target_ucontext_t; -- --struct target_sigframe { -- target_ucontext_t sf_uc; -- target_siginfo_t sf_si; --}; -- --#else -- --typedef target_ulong target_mcontext_t; /* dummy */ -- --#endif -- --/* XXX where did this come from? --typedef struct target_ucontext { -- target_ulong uc_flags; -- target_ulong uc_link; -- target_stack_t uc_stack; -- target_mcontext_t uc_mcontext; -- target_ulong uc_filer[80]; -- target_sigset_t uc_sigmask; --} target_ucontext_t; --*/ -- -- - #ifdef BSWAP_NEEDED - static inline void - tswap_sigset(target_sigset_t *d, const target_sigset_t *s) -@@ -603,3 +519,101 @@ void host_to_target_old_sigset(abi_ulong *old_sigset, const sigset_t *sigset); - void target_to_host_old_sigset(sigset_t *sigset, const abi_ulong *old_sigset); - int do_sigaction(int sig, const struct target_sigaction *act, - struct target_sigaction *oact); -+ -+ -+/* -+ * FreeBSD thread support. -+ */ -+ -+#define TARGET_THR_SUSPENDED 0x0001 -+#define TARGET_THR_SYSTEM_SCOPE 0x0002 -+ -+/* sysarch() ops */ -+#define TARGET_MIPS_SET_TLS 1 -+#define TARGET_MIPS_GET_TLS 2 -+ -+struct target_thr_param { -+ abi_ulong start_func; /* thread entry function. */ -+ abi_ulong arg; /* argument for entry function. */ -+ abi_ulong stack_base; /* stack base address. */ -+ abi_ulong stack_size; /* stack size. */ -+ abi_ulong tls_base; /* tls base address. */ -+ abi_ulong tls_size; /* tls size. */ -+ abi_ulong child_tid; /* address to store new TID. */ -+ abi_ulong parent_tid; /* parent access the new TID here. */ -+ abi_ulong rtp; /* Real-time scheduling priority. */ -+ abi_ulong spare[3]; /* spares. */ -+}; -+ -+struct target_rtprio { -+ uint16_t type; -+ uint16_t prio; -+}; -+ -+/* -+ * sys/_umtx.h -+ */ -+ -+struct target_umtx { -+ uint32_t u_owner; /* Owner of the mutex. */ -+}; -+ -+struct target_umutex { -+ uint32_t m_owner; /* Owner of the mutex */ -+ uint32_t m_flags; /* Flags of the mutex */ -+ uint32_t m_ceiling[2]; /* Priority protect ceiling */ -+ uint32_t m_spare[4]; -+}; -+ -+struct target_ucond { -+ uint32_t c_has_waiters; /* Has waiters in kernel */ -+ uint32_t c_flags; /* Flags of the condition variable */ -+ uint32_t c_clockid; /* Clock id */ -+ uint32_t c_spare[1]; -+}; -+ -+struct target_urwlock { -+ int32_t rw_state; -+ uint32_t rw_flags; -+ uint32_t rw_blocked_readers; -+ uint32_t rw_blocked_writers; -+ uint32_t rw_spare[4]; -+}; -+ -+struct target__usem { -+ uint32_t _has_waiters; -+ uint32_t _count; -+ uint32_t _flags; -+}; -+ -+/* -+ * sys/utmx.h -+ */ -+ -+/* op code for _umtx_op */ -+#define TARGET_UMTX_OP_LOCK 0 -+#define TARGET_UMTX_OP_UNLOCK 1 -+#define TARGET_UMTX_OP_WAIT 2 -+#define TARGET_UMTX_OP_WAKE 3 -+#define TARGET_UMTX_OP_MUTEX_TRYLOCK 4 -+#define TARGET_UMTX_OP_MUTEX_LOCK 5 -+#define TARGET_UMTX_OP_MUTEX_UNLOCK 6 -+#define TARGET_UMTX_OP_SET_CEILING 7 -+#define TARGET_UMTX_OP_CV_WAIT 8 -+#define TARGET_UMTX_OP_CV_SIGNAL 9 -+#define TARGET_UMTX_OP_CV_BROADCAST 10 -+#define TARGET_UMTX_OP_WAIT_UINT 11 -+#define TARGET_UMTX_OP_RW_RDLOCK 12 -+#define TARGET_UMTX_OP_RW_WRLOCK 13 -+#define TARGET_UMTX_OP_RW_UNLOCK 14 -+#define TARGET_UMTX_OP_WAIT_UINT_PRIVATE 15 -+#define TARGET_UMTX_OP_WAKE_PRIVATE 16 -+#define TARGET_UMTX_OP_MUTEX_WAIT 17 -+#define TARGET_UMTX_OP_MUTEX_WAKE 18 -+#define TARGET_UMTX_OP_SEM_WAIT 19 -+#define TARGET_UMTX_OP_SEM_WAKE 20 -+#define TARGET_UMTX_OP_NWAKE_PRIVATE 21 -+#define TARGET_UMTX_OP_MAX 22 -+ -+/* flags for UMTX_OP_CV_WAIT */ -+#define TARGET_CHECK_UNPARKING 0x01 -diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h -index ea89f5a..a14e0b9 100644 ---- a/bsd-user/x86_64/target_signal.h -+++ b/bsd-user/x86_64/target_signal.h -@@ -15,4 +15,29 @@ static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -+typedef target_ulong target_mcontext_t; /* dummy */ -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+static inline int -+get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "x86_64 doesn't have support for get_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ -+static inline int -+set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+{ -+ fprintf(stderr, "x86_64 doesn't have support for set_mcontext()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/configure b/configure -index 34eca43..be75584 100755 ---- a/configure -+++ b/configure -@@ -1386,6 +1386,11 @@ fi - - if test "$nptl" != "no" ; then - cat > $TMPC <<EOF -+#ifdef __FreeBSD__ -+int main(void) { -+ return (0); -+} -+#else - #include <sched.h> - #include <linux/futex.h> - int main(void) { -@@ -1394,6 +1399,7 @@ int main(void) { - #endif - return 0; - } -+#endif - EOF - - if compile_object ; then -@@ -3751,5 +3757,6 @@ case "$target_arch2" in - TARGET_ARCH=mips64 - TARGET_BASE_ARCH=mips - echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak -+ target_nptl="yes" - target_long_alignment=8 - ;; diff --git a/emulators/qemu-devel/files/patch-z2d-bsd-user-sson-002d b/emulators/qemu-devel/files/patch-z2d-bsd-user-sson-002d deleted file mode 100644 index 107d03b485a3..000000000000 --- a/emulators/qemu-devel/files/patch-z2d-bsd-user-sson-002d +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 4deb0db..bde9ee9 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -2377,7 +2377,7 @@ do_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) - - if (tid_addr) { - /* Signal target userland that it can free the stack. */ -- if (! put_user_u32(1, tid_addr)) -+ if (! put_user_sal(1, tid_addr)) - _umtx_op(g2h(tid_addr), UMTX_OP_WAKE, INT_MAX, - NULL, NULL); - } -@@ -4588,10 +4588,13 @@ do_stat: - { - struct timespec ts; - -- if (target_to_host_timespec(&ts, arg1)) -- goto efault; -+ if (arg1) { -+ if (target_to_host_timespec(&ts, arg1)) -+ goto efault; -+ ret = do_thr_suspend(&ts); -+ } else -+ ret = do_thr_suspend(NULL); - -- ret = do_thr_suspend(&ts); - } - break; - diff --git a/emulators/qemu-devel/files/patch-z2e-bsd-user-sson-002e b/emulators/qemu-devel/files/patch-z2e-bsd-user-sson-002e deleted file mode 100644 index 969b6b825640..000000000000 --- a/emulators/qemu-devel/files/patch-z2e-bsd-user-sson-002e +++ /dev/null @@ -1,3316 +0,0 @@ -diff --git a/Makefile.target b/Makefile.target ---- a/Makefile.target -+++ b/Makefile.target -@@ -95,7 +95,7 @@ ifdef CONFIG_BSD_USER - QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH) - - obj-y += bsd-user/ --obj-y += gdbstub.o user-exec.o -+obj-y += gdbstub.o thunk.o user-exec.o - - endif #CONFIG_BSD_USER - -diff --git a/bsd-user/freebsd/ioccom.h b/bsd-user/freebsd/ioccom.h -new file mode 100644 -index 0000000..830e377 ---- /dev/null -+++ b/bsd-user/freebsd/ioccom.h -@@ -0,0 +1,34 @@ -+#ifndef _FREEBSD_IOCCOM_H_ -+#define _FREEBSD_IOCCOM_H_ -+/* -+ * Ioctl's have the command encoded in the lower word, and the size of -+ * any in or out parameters in the upper word. The high 3 bits of the -+ * upper word are used to encode the in/out status of the parameter. -+ */ -+/* number of bits for ioctl size */ -+#define TARGET_IOCPARM_SHIFT 13 -+ -+/* parameter length mask */ -+#define TARGET_IOCPARM_MASK ((1 << TARGET_IOCPARM_SHIFT) - 1) -+ -+#define TARGET_IOCPARM_LEN(x) (((x) >> 16) & TARGET_IOCPARM_MASK) -+#define TARGET_IOCBASECMD(x) ((x) & ~(TARGET_IOCPARM_MASK << 16)) -+#define TARGET_IOCGROUP(x) (((x) >> 8) & 0xff) -+ -+#define TARGET_IOCPARM_MAX (1 << TARGET_IOCPARM_SHIFT) /* max size of ioctl */ -+#define TARGET_IOC_VOID 0x20000000 /* no parameters */ -+#define TARGET_IOC_OUT 0x40000000 /* copy out parameters */ -+#define TARGET_IOC_IN 0x80000000 /* copy in parameters */ -+#define TARGET_IOC_INOUT (TARGET_IOC_IN|TARGET_IOC_OUT) -+#define TARGET_IOC_DIRMASK (TARGET_IOC_VOID|TARGET_IOC_OUT|TARGET_IOC_IN) -+ -+#define TARGET_IOC(inout,group,num,len) ((abi_ulong) \ -+ ((inout) | (((len) & TARGET_IOCPARM_MASK) << 16) | ((group) << 8) \ -+ | (num))) -+#define TARGET_IO(g,n) TARGET_IOC(IOC_VOID, (g), (n), 0) -+#define TARGET_IOWINT(g,n) TARGET_IOC(IOC_VOID, (g), (n), sizeof(int)) -+#define TARGET_IOR(g,n,t) TARGET_IOC(IOC_OUT, (g), (n), sizeof(t)) -+#define TARGET_IOW(g,n,t) TARGET_IOC(IOC_IN, (g), (n), sizeof(t)) -+/* this should be _IORW, but stdio got there first */ -+#define TARGET_IOWR(g,n,t) TARGET_IOC(IOC_INOUT, (g), (n), sizeof(t)) -+#endif -diff --git a/bsd-user/freebsd/ioctl.h b/bsd-user/freebsd/ioctl.h -new file mode 100644 -index 0000000..67c5583 ---- /dev/null -+++ b/bsd-user/freebsd/ioctl.h -@@ -0,0 +1,35 @@ -+#ifndef _FREEBSD_IOCTL_H_ -+#define _FREEBSD_IOCTL_H_ -+ -+/* sys/ttycom.h tty(4) */ -+IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCCBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCSDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCCDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCGPGRP, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_CHAR)) -+IOCTL(TIOCNOTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCSTOP, IOC_, TYPE_NULL) -+IOCTL(TIOCSTART, IOC_, TYPE_NULL) -+IOCTL(TIOCSCTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCDRAIN, IOC_, TYPE_NULL) -+IOCTL(TIOCEXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCNXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCFLUSH, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCCONS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) -+ -+#endif -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index b09f766..bcdd931 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -2,6 +2,7 @@ - { TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_types.h b/bsd-user/freebsd/syscall_types.h -new file mode 100644 -index 0000000..6e43400 ---- /dev/null -+++ b/bsd-user/freebsd/syscall_types.h -@@ -0,0 +1,8 @@ -+#ifndef _FREEBSD_SYSCALL_TYPES_H_ -+#define _FREEBSD_SYSCALL_TYPES_H_ -+ -+STRUCT_SPECIAL(termios) -+ -+STRUCT(winsize, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) -+ -+#endif -diff --git a/bsd-user/freebsd/ttycom.h b/bsd-user/freebsd/ttycom.h -new file mode 100644 -index 0000000..699c282 ---- /dev/null -+++ b/bsd-user/freebsd/ttycom.h -@@ -0,0 +1,238 @@ -+#ifndef _FREEBSD_TTYCOM_H_ -+#define _FREEBSD_TTYCOM_H_ -+ -+#include "ioccom.h" -+ -+/* From sys/ttycom.h and sys/_termios.h */ -+ -+#define TARGET_VEOF 0 /* ICANON */ -+#define TARGET_VEOL 1 /* ICANON */ -+#define TARGET_VEOL2 2 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE 3 /* ICANON */ -+#define TARGET_VWERASE 4 /* ICANON together with IEXTEN */ -+#define TARGET_VKILL 5 /* ICANON */ -+#define TARGET_VREPRINT 6 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE2 7 /* ICANON */ -+#define TARGET_VINTR 8 /* ISIG */ -+#define TARGET_VQUIT 9 /* ISIG */ -+#define TARGET_VSUSP 10 /* ISIG */ -+#define TARGET_VDSUSP 11 /* ISIG together with IEXTEN */ -+#define TARGET_VSTART 12 /* IXON, IXOFF */ -+#define TARGET_VSTOP 13 /* IXON, IXOFF */ -+#define TARGET_VLNEXT 14 /* IEXTEN */ -+#define TARGET_VDISCARD 15 /* IEXTEN */ -+#define TARGET_VMIN 16 /* !ICANON */ -+#define TARGET_VTIME 17 /* !ICANON */ -+#define TARGET_VSTATUS 18 /* ICANON together with IEXTEN */ -+/* 19 spare 2 */ -+#define TARGET_NCCS 20 -+ -+/* -+ * Input flags - software input processing -+ */ -+#define TARGET_IGNBRK 0x00000001 /* ignore BREAK condition */ -+#define TARGET_BRKINT 0x00000002 /* map BREAK to SIGINTR */ -+#define TARGET_IGNPAR 0x00000004 /* ignore (discard) parity errors */ -+#define TARGET_PARMRK 0x00000008 /* mark parity and framing errors */ -+#define TARGET_INPCK 0x00000010 /* enable checking of parity errors */ -+#define TARGET_ISTRIP 0x00000020 /* strip 8th bit off chars */ -+#define TARGET_INLCR 0x00000040 /* map NL into CR */ -+#define TARGET_IGNCR 0x00000080 /* ignore CR */ -+#define TARGET_ICRNL 0x00000100 /* map CR to NL (ala CRMOD) */ -+#define TARGET_IXON 0x00000200 /* enable output flow control */ -+#define TARGET_IXOFF 0x00000400 /* enable input flow control */ -+#define TARGET_IXANY 0x00000800 /* any char will restart after stop */ -+#define TARGET_IMAXBEL 0x00002000 /* ring bell on input queue full */ -+ -+/* -+ * Output flags - software output processing -+ */ -+#define TARGET_OPOST 0x00000001 /* enable following output processing */ -+#define TARGET_ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */ -+#define TARGET_TABDLY 0x00000004 /* tab delay mask */ -+#define TARGET_TAB0 0x00000000 /* no tab delay and expansion */ -+#define TARGET_TAB3 0x00000004 /* expand tabs to spaces */ -+#define TARGET_ONOEOT 0x00000008 /* discard EOT's (^D) on output) */ -+#define TARGET_OCRNL 0x00000010 /* map CR to NL on output */ -+#define TARGET_ONOCR 0x00000020 /* no CR output at column 0 */ -+#define TARGET_ONLRET 0x00000040 /* NL performs CR function */ -+ -+/* -+ * Control flags - hardware control of terminal -+ */ -+#define TARGET_CIGNORE 0x00000001 /* ignore control flags */ -+#define TARGET_CSIZE 0x00000300 /* character size mask */ -+#define TARGET_CS5 0x00000000 /* 5 bits (pseudo) */ -+#define TARGET_CS6 0x00000100 /* 6 bits */ -+#define TARGET_CS7 0x00000200 /* 7 bits */ -+#define TARGET_CS8 0x00000300 /* 8 bits */ -+#define TARGET_CSTOPB 0x00000400 /* send 2 stop bits */ -+#define TARGET_CREAD 0x00000800 /* enable receiver */ -+#define TARGET_PARENB 0x00001000 /* parity enable */ -+#define TARGET_PARODD 0x00002000 /* odd parity, else even */ -+#define TARGET_HUPCL 0x00004000 /* hang up on last close */ -+#define TARGET_CLOCAL 0x00008000 /* ignore modem status lines */ -+#define TARGET_CCTS_OFLOW 0x00010000 /* CTS flow control of output */ -+#define TARGET_CRTSCTS (TARGET_CCTS_OFLOW | TARGET_CRTS_IFLOW) -+#define TARGET_CRTS_IFLOW 0x00020000 /* RTS flow control of input */ -+#define TARGET_CDTR_IFLOW 0x00040000 /* DTR flow control of input */ -+#define TARGET_CDSR_OFLOW 0x00080000 /* DSR flow control of output */ -+#define TARGET_CCAR_OFLOW 0x00100000 /* DCD flow control of output */ -+ -+/* -+ * "Local" flags - dumping ground for other state -+ */ -+#define TARGET_ECHOKE 0x00000001 /* visual erase for line kill */ -+#define TARGET_ECHOE 0x00000002 /* visually erase chars */ -+#define TARGET_ECHOK 0x00000004 /* echo NL after line kill */ -+#define TARGET_ECHO 0x00000008 /* enable echoing */ -+#define TARGET_ECHONL 0x00000010 /* echo NL even if ECHO is off */ -+#define TARGET_ECHOPRT 0x00000020 /* visual erase mode for hardcopy */ -+#define TARGET_ECHOCTL 0x00000040 /* echo control chars as ^(Char) */ -+#define TARGET_ISIG 0x00000080 /* enable signals INTR, QUIT, [D]SUSP */ -+#define TARGET_ICANON 0x00000100 /* canonicalize input lines */ -+#define TARGET_ALTWERASE 0x00000200 /* use alternate WERASE algorithm */ -+#define TARGET_IEXTEN 0x00000400 /* enable DISCARD and LNEXT */ -+#define TARGET_EXTPROC 0x00000800 /* external processing */ -+#define TARGET_TOSTOP 0x00400000 /* stop background jobs from output */ -+#define TARGET_FLUSHO 0x00800000 /* output being flushed (state) */ -+#define TARGET_NOKERNINFO 0x02000000 /* no kernel output from VSTATUS */ -+#define TARGET_PENDIN 0x20000000 /* XXX retype pending input (state) */ -+#define TARGET_NOFLSH 0x80000000 /* don't flush after interrupt */ -+ -+struct target_termios { -+ uint32_t c_iflag; /* input flags */ -+ uint32_t c_oflag; /* output flags */ -+ uint32_t c_cflag; /* control flags */ -+ uint32_t c_lflag; /* local flags */ -+ uint8_t c_cc[TARGET_NCCS]; /* control chars */ -+ uint32_t c_ispeed; /* input speed */ -+ uint32_t c_ospeed; /* output speed */ -+}; -+ -+ -+struct target_winsize { -+ uint16_t ws_row; /* rows, in characters */ -+ uint16_t ws_col; /* columns, in characters */ -+ uint16_t ws_xpixel; /* horizontal size, pixels */ -+ uint16_t ws_ypixel; /* vertical size, pixels */ -+}; -+ -+ /* 0-2 compat */ -+ /* 3-7 unused */ -+ /* 8-10 compat */ -+ /* 11-12 unused */ -+#define TARGET_TIOCEXCL TARGET_IO('t', 13) /* set exclusive use of tty */ -+#define TARGET_TIOCNXCL TARGET_IO('t', 14) /* reset exclusive use of tty */ -+#define TARGET_TIOCGPTN TARGET_IOR('t', 15, int) /* Get pts number. */ -+#define TARGET_TIOCFLUSH TARGET_IOW('t', 16, int) /* flush buffers */ -+ /* 17-18 compat */ -+/* get termios struct */ -+#define TARGET_TIOCGETA TARGET_IOR('t', 19, struct target_termios) -+/* set termios struct */ -+#define TARGET_TIOCSETA TARGET_IOW('t', 20, struct target_termios) -+/* drain output, set */ -+#define TARGET_TIOCSETAW TARGET_IOW('t', 21, struct target_termios) -+/* drn out, fls in, set */ -+#define TARGET_TIOCSETAF TARGET_IOW('t', 22, struct target_termios) -+ /* 23-25 unused */ -+#define TARGET_TIOCGETD TARGET_IOR('t', 26, int) /* get line discipline */ -+#define TARGET_TIOCSETD TARGET_IOW('t', 27, int) /* set line discipline */ -+#define TARGET_TIOCPTMASTER TARGET_IO('t', 28) /* pts master validation */ -+ /* 29-85 unused */ -+/* get ttywait timeout */ -+#define TARGET_TIOCGDRAINWAIT TARGET_IOR('t', 86, int) -+/* set ttywait timeout */ -+#define TARGET_TIOCSDRAINWAIT TARGET_IOW('t', 87, int) -+ /* 88 unused */ -+ /* 89-91 conflicts: tun and tap */ -+/* enable/get timestamp of last input event */ -+#define TARGET_TIOCTIMESTAMP TARGET_IOR('t', 89, struct target_timeval) -+/* modem: get wait on close */ -+#define TARGET_TIOCMGDTRWAIT TARGET_IOR('t', 90, int) -+/* modem: set wait on close */ -+#define TARGET_TIOCMSDTRWAIT TARGET_IOW('t', 91, int) -+ /* 92-93 tun and tap */ -+ /* 94-97 conflicts: tun and tap */ -+/* wait till output drained */ -+#define TARGET_TIOCDRAIN TARGET_IO('t', 94) -+ /* pty: generate signal */ -+#define TARGET_TIOCSIG TARGET_IOWINT('t', 95) -+/* pty: external processing */ -+#define TARGET_TIOCEXT TARGET_IOW('t', 96, int) -+/* become controlling tty */ -+#define TARGET_TIOCSCTTY TARGET_IO('t', 97) -+/* become virtual console */ -+#define TARGET_TIOCCONS TARGET_IOW('t', 98, int) -+/* get session id */ -+#define TARGET_TIOCGSID TARGET_IOR('t', 99, int) -+ /* 100 unused */ -+/* simulate ^T status message */ -+#define TARGET_TIOCSTAT TARGET_IO('t', 101) -+ /* pty: set/clr usr cntl mode */ -+#define TARGET_TIOCUCNTL TARGET_IOW('t', 102, int) -+/* usr cntl op "n" */ -+#define TARGET_TIOCCMD(n) TARGET_IO('u', n) -+/* set window size */ -+#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct target_winsize) -+/* get window size */ -+#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct target_winsize) -+ /* 105 unused */ -+/* get all modem bits */ -+#define TARGET_TIOCMGET TARGET_IOR('t', 106, int) -+#define TARGET_TIOCM_LE 0001 /* line enable */ -+#define TARGET_TIOCM_DTR 0002 /* data terminal ready */ -+#define TARGET_TIOCM_RTS 0004 /* request to send */ -+#define TARGET_TIOCM_ST 0010 /* secondary transmit */ -+#define TARGET_TIOCM_SR 0020 /* secondary receive */ -+#define TARGET_TIOCM_CTS 0040 /* clear to send */ -+#define TARGET_TIOCM_DCD 0100 /* data carrier detect */ -+#define TARGET_TIOCM_RI 0200 /* ring indicate */ -+#define TARGET_TIOCM_DSR 0400 /* data set ready */ -+#define TARGET_TIOCM_CD TARGET_TIOCM_DCD -+#define TARGET_TIOCM_CAR TARGET_TIOCM_DCD -+#define TARGET_TIOCM_RNG TARGET_TIOCM_RI -+#define TARGET_TIOCMBIC TARGET_IOW('t', 107, int) /* bic modem bits */ -+#define TARGET_TIOCMBIS TARGET_IOW('t', 108, int) /* bis modem bits */ -+#define TARGET_TIOCMSET TARGET_IOW('t', 109, int) /* set all modem bits */ -+/* start output, like ^Q */ -+#define TARGET_TIOCSTART TARGET_IO('t', 110) -+/* stop output, like ^S */ -+#define TARGET_TIOCSTOP TARGET_IO('t', 111) -+/* pty: set/clear packet mode */ -+#define TARGET_TIOCPKT TARGET_IOW('t', 112, int) -+#define TARGET_TIOCPKT_DATA 0x00 /* data packet */ -+#define TARGET_TIOCPKT_FLUSHREAD 0x01 /* flush packet */ -+#define TARGET_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ -+#define TARGET_TIOCPKT_STOP 0x04 /* stop output */ -+#define TARGET_TIOCPKT_START 0x08 /* start output */ -+#define TARGET_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ -+#define TARGET_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ -+#define TARGET_TIOCPKT_IOCTL 0x40 /* state change of pty -+ driver */ -+#define TARGET_TIOCNOTTY TARGET_IO('t', 113) /* void tty -+ association */ -+#define TARGET_TIOCSTI TARGET_IOW('t', 114, char) /* simulate -+ terminal input */ -+#define TARGET_TIOCOUTQ TARGET_IOR('t', 115, int) /* output queue size */ -+ /* 116-117 compat */ -+#define TARGET_TIOCSPGRP TARGET_IOW('t', 118, int) /* set pgrp of tty */ -+#define TARGET_TIOCGPGRP TARGET_IOR('t', 119, int) /* get pgrp of tty */ -+#define TARGET_TIOCCDTR TARGET_IO('t', 120) /* clear data terminal -+ ready */ -+#define TARGET_TIOCSDTR TARGET_IO('t', 121) /* set data terminal -+ ready */ -+#define TARGET_TIOCCBRK TARGET_IO('t', 122) /* clear break bit */ -+#define TARGET_TIOCSBRK TARGET_IO('t', 123) /* set break bit */ -+ /* 124-127 compat */ -+ -+#define TARGET_TTYDISC 0 /* termios tty line -+ discipline */ -+#define TARGET_SLIPDISC 4 /* serial IP discipline */ -+#define TARGET_PPPDISC 5 /* PPP discipline */ -+#define TARGET_NETGRAPHDISC 6 /* Netgraph tty node -+ discipline */ -+#define TARGET_H4DISC 7 /* Netgraph Bluetooth H4 -+ discipline */ -+ -+#endif /* _FREEBSD_TTYCOM_H_ */ -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index 9d4edbf..e3bcc57 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -23,6 +23,7 @@ extern enum BSDType bsd_type; - abi_long memcpy_to_target(abi_ulong dest, const void *src, - unsigned long len); - -+#include "exec/user/thunk.h" - #include "syscall_defs.h" - #include "syscall.h" - #include "target_vmparam.h" -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index bde9ee9..89ce296 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -47,6 +47,12 @@ - #include <sys/thr.h> - #include <sys/rtprio.h> - #include <sys/umtx.h> -+#include <sys/uuid.h> -+#include <sys/_termios.h> -+#include <sys/ttycom.h> -+#include <sys/reboot.h> -+#include <sys/timex.h> -+#include <kenv.h> - #include <pthread.h> - #include <machine/atomic.h> - #endif -@@ -61,6 +67,10 @@ - - #include "qemu.h" - #include "qemu-common.h" -+#ifdef __FreeBSD__ -+#include "freebsd/ttycom.h" -+#endif -+ - - //#define DEBUG - -@@ -791,7 +801,7 @@ host_to_target_waitstatus(int status) - } - - static inline abi_long --copy_from_user_timeval(struct timeval *tv, abi_ulong target_tv_addr) -+target_to_host_timeval(struct timeval *tv, abi_ulong target_tv_addr) - { - struct target_freebsd_timeval *target_tv; - -@@ -804,6 +814,33 @@ copy_from_user_timeval(struct timeval *tv, abi_ulong target_tv_addr) - } - - static inline abi_long -+target_to_host_timex(struct timex *host_tx, abi_ulong target_tx_addr) -+{ -+ struct target_timex *target_tx; -+ -+ if (!lock_user_struct(VERIFY_READ, target_tx, target_tx_addr, 0)) -+ return (-TARGET_EFAULT); -+ __get_user(host_tx->modes, &target_tx->modes); -+ __get_user(host_tx->offset, &target_tx->offset); -+ __get_user(host_tx->freq, &target_tx->freq); -+ __get_user(host_tx->maxerror, &target_tx->maxerror); -+ __get_user(host_tx->esterror, &target_tx->esterror); -+ __get_user(host_tx->status, &target_tx->status); -+ __get_user(host_tx->constant, &target_tx->constant); -+ __get_user(host_tx->precision, &target_tx->precision); -+ __get_user(host_tx->ppsfreq, &target_tx->ppsfreq); -+ __get_user(host_tx->jitter, &target_tx->jitter); -+ __get_user(host_tx->shift, &target_tx->shift); -+ __get_user(host_tx->stabil, &target_tx->stabil); -+ __get_user(host_tx->jitcnt, &target_tx->jitcnt); -+ __get_user(host_tx->calcnt, &target_tx->calcnt); -+ __get_user(host_tx->errcnt, &target_tx->errcnt); -+ __get_user(host_tx->stbcnt, &target_tx->stbcnt); -+ unlock_user_struct(target_tx, target_tx_addr, 1); -+ return (0); -+} -+ -+static inline abi_long - target_to_host_timespec(struct timespec *ts, abi_ulong target_ts_addr) - { - struct target_freebsd_timespec *target_ts; -@@ -817,7 +854,7 @@ target_to_host_timespec(struct timespec *ts, abi_ulong target_ts_addr) - } - - static inline abi_long --fbsd_copy_to_user_timeval(struct timeval *tv, abi_ulong target_tv_addr) -+host_to_target_timeval(struct timeval *tv, abi_ulong target_tv_addr) - { - struct target_freebsd_timeval *target_tv; - -@@ -841,6 +878,23 @@ host_to_target_timespec(abi_ulong target_ts_addr, struct timespec *ts) - unlock_user_struct(target_ts, target_ts_addr, 1); - return (0); - } -+ -+static inline abi_long -+host_to_target_ntptimeval(abi_ulong target_ntv_addr, struct ntptimeval *ntv) -+{ -+ struct target_ntptimeval *target_ntv; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ntv, target_ntv_addr, 0)) -+ return (-TARGET_EFAULT); -+ __put_user(ntv->time.tv_sec, &target_ntv->time.tv_sec); -+ __put_user(ntv->time.tv_nsec, &target_ntv->time.tv_nsec); -+ __put_user(ntv->maxerror, &target_ntv->maxerror); -+ __put_user(ntv->esterror, &target_ntv->esterror); -+ __put_user(ntv->tai, &target_ntv->tai); -+ __put_user(ntv->time_state, &target_ntv->time_state); -+ return (0); -+} -+ - static inline abi_ulong - copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n) - { -@@ -1251,7 +1305,7 @@ do_freebsd_select(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, - return (ret); - - if (target_tv_addr) { -- if (copy_from_user_timeval(&tv, target_tv_addr)) -+ if (target_to_host_timeval(&tv, target_tv_addr)) - return (-TARGET_EFAULT); - tv_ptr = &tv; - } else { -@@ -1269,7 +1323,7 @@ do_freebsd_select(int n, abi_ulong rfd_addr, abi_ulong wfd_addr, - return (-TARGET_EFAULT); - - if (target_tv_addr && -- fbsd_copy_to_user_timeval(&tv, target_tv_addr)) -+ host_to_target_timeval(&tv, target_tv_addr)) - return (-TARGET_EFAULT); - } - -@@ -2483,234 +2537,1659 @@ do_thr_set_name(long tid, char *name) - #endif /* CONFIG_USE_NPTL */ - - static int --do_umtx_lock(abi_ulong umtx_addr, uint32_t id) -+tcmpset_al(abi_ulong *addr, abi_ulong a, abi_ulong b) - { -- int ret = 0; -+ abi_ulong current = tswapal(a); -+ abi_ulong new = tswapal(b); -+ -+#ifdef TARGET_ABI32 -+ return (atomic_cmpset_acq_32(addr, current, new)); -+#else -+ return (atomic_cmpset_acq_64(addr, current, new)); -+#endif -+} -+ -+static int -+tcmpset_32(uint32_t *addr, uint32_t a, uint32_t b) -+{ -+ uint32_t current = tswap32(a); -+ uint32_t new = tswap32(b); -+ -+ return (atomic_cmpset_acq_32(addr, current, new)); -+} -+ -+static int -+do_lock_umtx(abi_ulong target_addr, abi_long id, struct timespec *timeout) -+{ -+ abi_long owner; -+ int ret; - -+ /* -+ * XXX Note that memory at umtx_addr can change and so we need to be -+ * careful and check for faults. -+ */ - for (;;) { -- ret = get_errno(_umtx_op(g2h(umtx_addr + -- offsetof(struct target_umtx, u_owner)), -- UMTX_OP_MUTEX_WAIT, UMTX_UNOWNED, 0, 0)); -+ struct target_umtx *target_umtx; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_umtx, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ /* Check the simple uncontested case. */ -+ if (tcmpset_al(&target_umtx->u_owner, -+ TARGET_UMTX_UNOWNED, id)) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return (0); -+ } -+ -+ /* Check to see if the lock is contested but free. */ -+ __get_user(owner, &target_umtx->u_owner); -+ -+ if (TARGET_UMTX_CONTESTED == owner) { -+ if (tcmpset_al(&target_umtx->u_owner, -+ TARGET_UMTX_CONTESTED, -+ id | TARGET_UMTX_CONTESTED)) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return (0); -+ } -+ -+ /* We failed because it changed on us, restart. */ -+ unlock_user_struct(target_umtx, target_addr, 1); -+ continue; -+ } -+ -+ /* Set the contested bit and sleep. */ -+ do { -+ __get_user(owner, &target_umtx->u_owner); -+ if (owner & TARGET_UMTX_CONTESTED) -+ break; -+ } while (!tcmpset_al(&target_umtx->u_owner, owner, -+ owner | TARGET_UMTX_CONTESTED)); -+ -+ __get_user(owner, &target_umtx->u_owner); -+ unlock_user_struct(target_umtx, target_addr, 1); -+ -+ /* Byte swap, if needed, to match what is stored in user mem. */ -+ owner = tswapal(owner); -+#ifdef TARGET_ABI32 -+ ret = get_errno(_umtx_op(target_umtx, UMTX_OP_WAIT_UINT, owner, -+ NULL, timeout)); -+#else -+ ret = get_errno(_umtx_op(target_umtx, UMTX_OP_WAIT, owner, -+ NULL, timeout)); -+#endif - if (ret) - return (ret); -- if (atomic_cmpset_acq_32(g2h(umtx_addr + -- offsetof(struct target_umtx, u_owner)), -- UMTX_UNOWNED, id)) -- return (0); - } - } - - static int --do_umtx_unlock(abi_ulong umtx_addr, uint32 id) -+do_unlock_umtx(abi_ulong target_addr, abi_ulong id) - { -- uint32_t owner; -+ abi_ulong owner; -+ struct target_umtx *target_umtx; - -- do { -- if (get_user_u32(owner, umtx_addr + -- offsetof(struct target_umtx, u_owner))) -- return (-TARGET_EFAULT); -- if (owner != id) -- return (-TARGET_EPERM); -- } while (!atomic_cmpset_rel_32(g2h(umtx_addr + -- offsetof(struct target_umtx, u_owner)), owner, -- UMUTEX_UNOWNED)); -+ if (!lock_user_struct(VERIFY_WRITE, target_umtx, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ __get_user(owner, &target_umtx->u_owner); -+ if ((owner & ~TARGET_UMTX_CONTESTED) != id) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return (-TARGET_EPERM); -+ } -+ -+ /* Check the simple uncontested case. */ -+ if ((owner & ~TARGET_UMTX_CONTESTED) == 0) -+ if (tcmpset_al(&target_umtx->u_owner, owner, -+ TARGET_UMTX_UNOWNED)) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return (0); -+ } -+ -+ /* This is a contested lock. Unlock it. */ -+ __put_user(TARGET_UMTX_UNOWNED, &target_umtx->u_owner); -+ unlock_user_struct(target_umtx, target_addr, 1); -+ -+ /* Wake up all those contesting it. */ -+ _umtx_op(target_umtx, UMTX_OP_WAKE, 0, 0, 0); - - return (0); - } - -- --/* do_syscall() should always have a single exit point at the end so -- that actions, such as logging of syscall results, can be performed. -- All errnos that do_syscall() returns must be -TARGET_<errcode>. */ --abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -- abi_long arg2, abi_long arg3, abi_long arg4, -- abi_long arg5, abi_long arg6, abi_long arg7, -- abi_long arg8) -+static int -+do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts, -+ int mode) - { -- abi_long ret; -- void *p; -- struct stat st; -+ uint32_t owner, flags; -+ int ret; - --#ifdef DEBUG -- gemu_log("freebsd syscall %d\n", num); --#endif -- if(do_strace) -- print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); -- -- switch(num) { -- case TARGET_FREEBSD_NR_exit: --#ifdef TARGET_GPROF -- _mcleanup(); --#endif -- gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -- _exit(arg1); -- ret = 0; /* avoid warning */ -- break; -- case TARGET_FREEBSD_NR_read: -- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -- goto efault; -- ret = get_errno(read(arg1, p, arg3)); -- unlock_user(p, arg2, ret); -- break; -+ for (;;) { -+ struct target_umutex *target_umutex; - -- case TARGET_FREEBSD_NR_readv: -- { -- int count = arg3; -- struct iovec *vec; -+ if (!lock_user_struct(VERIFY_WRITE, target_umutex, -+ target_addr, 0)) -+ return (-TARGET_EFAULT); - -- vec = alloca(count * sizeof(struct iovec)); -- if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) -- goto efault; -- ret = get_errno(readv(arg1, vec, count)); -- unlock_iovec(vec, arg2, count, 1); -- } -- break; -+ __get_user(owner, &target_umutex->m_owner); - -- case TARGET_FREEBSD_NR_pread: -- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -- goto efault; -- ret = get_errno(pread(arg1, p, arg3, target_offset64(arg4, arg5))); -- unlock_user(p, arg2, ret); -- break; -+ if (TARGET_UMUTEX_WAIT == mode) { -+ if (TARGET_UMUTEX_UNOWNED == owner || -+ TARGET_UMUTEX_CONTESTED == owner) -+ unlock_user_struct(target_umutex, -+ target_addr, 1); -+ return (0); -+ } else { -+ if (tcmpset_32(&target_umutex->m_owner, -+ TARGET_UMUTEX_UNOWNED, id)) { -+ /* The acquired succeeded. */ -+ unlock_user_struct(target_umutex, -+ target_addr, 1); -+ return (0); -+ } - -- case TARGET_FREEBSD_NR_preadv: -- { -- int count = arg3; -- struct iovec *vec; -+ /* -+ * If no one owns it but it is contested try to acquire -+ * it. -+ */ -+ if (TARGET_UMUTEX_CONTESTED == owner) { -+ if (tcmpset_32(&target_umutex->m_owner, -+ TARGET_UMUTEX_CONTESTED, -+ id | TARGET_UMUTEX_CONTESTED)) { - -- vec = alloca(count * sizeof(struct iovec)); -- if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) -- goto efault; -- ret = get_errno(preadv(arg1, vec, count, -- target_offset64(arg4, arg5))); -- unlock_iovec(vec, arg2, count, 1); -- } -- break; -+ unlock_user_struct(target_umutex, -+ target_addr, 1); -+ return (0); -+ } - -- case TARGET_FREEBSD_NR_write: -- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -- goto efault; -- ret = get_errno(write(arg1, p, arg3)); -- unlock_user(p, arg2, 0); -- break; -+ /* The lock changed so restart. */ -+ unlock_user_struct(target_umutex, -+ target_addr, 1); -+ continue; -+ } -+ } - -- case TARGET_FREEBSD_NR_writev: -- { -- int count = arg3; -- struct iovec *vec; -+ __get_user(flags, &target_umutex->m_flags); -+ flags = tswap32(flags); -+ if ((flags & TARGET_UMUTEX_ERROR_CHECK) != 0 && -+ (owner & ~TARGET_UMUTEX_CONTESTED) == id) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return (-TARGET_EDEADLK); -+ } - -- vec = alloca(count * sizeof(struct iovec)); -- if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -- goto efault; -- ret = get_errno(writev(arg1, vec, count)); -- unlock_iovec(vec, arg2, count, 0); -- } -- break; -+ if (TARGET_UMUTEX_TRY == mode) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return (-TARGET_EBUSY); -+ } - -- case TARGET_FREEBSD_NR_pwrite: -- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -- goto efault; -- ret = get_errno(pwrite(arg1, p, arg3, target_offset64(arg4, arg5))); -- unlock_user(p, arg2, 0); -- break; -+ /* Set the contested bit and sleep. */ -+ if (!tcmpset_32(&target_umutex->m_owner, owner, -+ owner | TARGET_UMUTEX_CONTESTED)) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ continue; -+ } - -- case TARGET_FREEBSD_NR_pwritev: -- { -- int count = arg3; -- struct iovec *vec; -+ owner = owner | TARGET_UMUTEX_CONTESTED; -+ unlock_user_struct(target_umutex, target_addr, 1); - -- vec = alloca(count * sizeof(struct iovec)); -- if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -- goto efault; -- ret = get_errno(pwritev(arg1, vec, count, -- target_offset64(arg4, arg5))); -- unlock_iovec(vec, arg2, count, 0); -+ /* Byte swap, if needed, to match what is stored in user mem. */ -+ owner = tswap32(owner); -+ ret = get_errno(_umtx_op(target_umutex, UMTX_OP_WAIT_UINT, owner, -+ 0, ts)); -+ if (ret) -+ return (ret); - } -- break; - -- case TARGET_FREEBSD_NR_open: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(open(path(p), -- target_to_host_bitmask(arg2, fcntl_flags_tbl), -- arg3)); -- unlock_user(p, arg1, 0); -- break; -+ return (0); -+} - -- case TARGET_FREEBSD_NR_openat: -- if (!(p = lock_user_string(arg2))) -- goto efault; -- ret = get_errno(openat(arg1, path(p), -- target_to_host_bitmask(arg3, fcntl_flags_tbl), -- arg4)); -- unlock_user(p, arg2, 0); -- break; -+static int -+do_unlock_umutex(abi_ulong target_addr, uint32_t id) -+{ -+ struct target_umutex *target_umutex; -+ uint32_t owner; - -- case TARGET_FREEBSD_NR_close: -- ret = get_errno(close(arg1)); -- break; - -- case TARGET_FREEBSD_NR_closefrom: -- ret = 0; -- closefrom(arg1); -- break; -+ if (!lock_user_struct(VERIFY_WRITE, target_umutex, target_addr, 0)) -+ return (-TARGET_EFAULT); - --#ifdef TARGET_FREEBSD_NR_creat -- case TARGET_FREEBSD_NR_creat: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(creat(p, arg2)); -- unlock_user(p, arg1, 0); -- break; --#endif -+ /* Make sure we own this mutex. */ -+ __get_user(owner, &target_umutex->m_owner); -+ if ((owner & ~TARGET_UMUTEX_CONTESTED) != id) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return (-TARGET_EPERM); -+ } - -- case TARGET_FREEBSD_NR_mmap: -- ret = get_errno(target_mmap(arg1, arg2, arg3, -- target_to_host_bitmask(arg4, mmap_flags_tbl), -- arg5, -- arg6)); -- break; -+ if ((owner & TARGET_UMUTEX_CONTESTED) == 0) -+ if (tcmpset_32(&target_umutex->m_owner, owner, -+ TARGET_UMTX_UNOWNED)) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return (0); -+ } - -- case TARGET_FREEBSD_NR_munmap: -- ret = get_errno(target_munmap(arg1, arg2)); -- break; -+ /* This is a contested lock. Unlock it. */ -+ __put_user(TARGET_UMUTEX_UNOWNED, &target_umutex->m_owner); -+ unlock_user_struct(target_umutex, target_addr, 1); - -- case TARGET_FREEBSD_NR_mprotect: -- ret = get_errno(target_mprotect(arg1, arg2, arg3)); -- break; -+ /* And wake up all those contesting it. */ -+ return ( _umtx_op(g2h(target_addr), UMTX_OP_WAKE, 0, 0, 0)); -+} - -- case TARGET_FREEBSD_NR_msync: -- ret = get_errno(msync(g2h(arg1), arg2, arg3)); -- break; -+/* -+ * _cv_mutex is keeps other threads from doing a signal or broadcast until -+ * the thread is actually asleep and ready. This is a global mutex for all -+ * condition vars so I am sure performance may be a problem if there are lots -+ * of CVs. -+ */ -+static struct umutex _cv_mutex = {0,0,{0,0},{0,0,0,0}}; - -- case TARGET_FREEBSD_NR_mlock: -- ret = get_errno(mlock(g2h(arg1), arg2)); -- break; - -- case TARGET_FREEBSD_NR_munlock: -- ret = get_errno(munlock(g2h(arg1), arg2)); -- break; -+/* -+ * wflags CVWAIT_CHECK_UNPARKING, CVWAIT_ABSTIME, CVWAIT_CLOCKID -+ */ -+static int -+do_cv_wait(abi_ulong target_ucond_addr, abi_ulong target_umtx_addr, -+ struct timespec *ts, int wflags) -+{ -+ long tid; -+ int ret; - -- case TARGET_FREEBSD_NR_mlockall: -- ret = get_errno(mlockall(arg1)); -- break; -+ if (! access_ok(VERIFY_WRITE, target_ucond_addr, -+ sizeof(struct target_ucond))) { - -- case TARGET_FREEBSD_NR_munlockall: -- ret = get_errno(munlockall()); -- break; -+ return (-TARGET_EFAULT); -+ } - -- case TARGET_FREEBSD_NR_madvise: -- /* -- * A straight passthrough may not be safe because qemu sometimes -- * turns private file-backed mapping into anonymous mappings. This -- * will break MADV_DONTNEED. This is a hint, so ignoring and returing -- * success is ok. -- */ -- ret = get_errno(0); -- break; -+ /* Check the clock ID if needed. */ -+ if ((wflags & TARGET_CVWAIT_CLOCKID) != 0) { -+ struct target_ucond *target_ucond; -+ uint32_t clockid; - -- case TARGET_FREEBSD_NR_break: -+ if (!lock_user_struct(VERIFY_WRITE, target_ucond, -+ target_ucond_addr, 0)) -+ return (-TARGET_EFAULT); -+ __get_user(clockid, &target_ucond->c_clockid); -+ unlock_user_struct(target_ucond, target_ucond_addr, 1); -+ if (clockid < CLOCK_REALTIME || -+ clockid >= CLOCK_THREAD_CPUTIME_ID) { -+ /* Only HW clock id will work. */ -+ return (-TARGET_EINVAL); -+ } -+ } -+ -+ thr_self(&tid); -+ -+ /* Lock the _cv_mutex so we can safely unlock the user mutex */ -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); -+ -+ /* unlock the user mutex */ -+ ret = do_unlock_umutex(target_umtx_addr, tid); -+ if (ret) { -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); -+ return (ret); -+ } -+ -+ /* UMTX_OP_CV_WAIT unlocks _cv_mutex */ -+ ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_WAIT, -+ wflags, &_cv_mutex, ts)); -+ -+ return (ret); -+} -+ -+static int -+do_cv_signal(abi_ulong target_ucond_addr) -+{ -+ int ret; -+ -+ if (! access_ok(VERIFY_WRITE, target_ucond_addr, -+ sizeof(struct target_ucond))) -+ return (-TARGET_EFAULT); -+ -+ /* Lock the _cv_mutex to prevent a race in do_cv_wait(). */ -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); -+ ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_SIGNAL, 0, -+ NULL, NULL)); -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); -+ -+ return (ret); -+} -+ -+static int -+do_cv_broadcast(abi_ulong target_ucond_addr) -+{ -+ int ret; -+ -+ if (! access_ok(VERIFY_WRITE, target_ucond_addr, -+ sizeof(struct target_ucond))) -+ return (-TARGET_EFAULT); -+ -+ /* Lock the _cv_mutex to prevent a race in do_cv_wait(). */ -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); -+ ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_BROADCAST, -+ 0, NULL, NULL)); -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); -+ -+ return (ret); -+} -+ -+static int -+do_umtx_op_wait(abi_ulong target_addr, abi_ulong id, struct timespec *ts) -+{ -+ -+ /* We want to check the user memory but not lock it. We might sleep. */ -+ if (! access_ok(VERIFY_READ, target_addr, sizeof(abi_ulong))) -+ return (-TARGET_EFAULT); -+ -+ /* id has already been byte swapped to match what may be in user mem. */ -+#ifdef TARGET_ABI32 -+ return (get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT_UINT, id, NULL, -+ ts))); -+#else -+ return (get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT, id, NULL, -+ ts))); -+#endif -+} -+ -+static int -+do_umtx_op_wake(abi_ulong target_addr, abi_ulong n_wake) -+{ -+ -+ return (get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAKE, n_wake, NULL, -+ 0))); -+} -+ -+static int -+do_rw_rdlock(abi_ulong target_addr, long fflag, struct timespec *ts) -+{ -+ struct target_urwlock *target_urwlock; -+ uint32_t flags, wrflags; -+ uint32_t state; -+ uint32_t blocked_readers; -+ int ret; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ __get_user(flags, &target_urwlock->rw_flags); -+ wrflags = TARGET_URWLOCK_WRITE_OWNER; -+ if (!(fflag & TARGET_URWLOCK_PREFER_READER) && -+ !(flags & TARGET_URWLOCK_PREFER_READER)) -+ wrflags |= TARGET_URWLOCK_WRITE_WAITERS; -+ -+ for (;;) { -+ __get_user(state, &target_urwlock->rw_state); -+ /* try to lock it */ -+ while (!(state & wrflags)) { -+ if (TARGET_URWLOCK_READER_COUNT(state) == -+ TARGET_URWLOCK_MAX_READERS) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return (-TARGET_EAGAIN); -+ } -+ if (tcmpset_32(&target_urwlock->rw_state, state, -+ (state + 1))) { -+ /* The acquired succeeded. */ -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return (0); -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* set read contention bit */ -+ if (! tcmpset_32(&target_urwlock->rw_state, state, -+ state | TARGET_URWLOCK_READ_WAITERS)) { -+ /* The state has changed. Start over. */ -+ continue; -+ } -+ -+ /* contention bit is set, increase read waiter count */ -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ while (! tcmpset_32(&target_urwlock->rw_blocked_readers, -+ blocked_readers, blocked_readers + 1)) { -+ __get_user(blocked_readers, -+ &target_urwlock->rw_blocked_readers); -+ } -+ -+ while (state & wrflags) { -+ /* sleep/wait */ -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ ret = get_errno(_umtx_op( -+ &target_urwlock->rw_blocked_readers, -+ UMTX_OP_WAIT_UINT, blocked_readers, 0, ts)); -+ if (ret) -+ return (ret); -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, -+ target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* decrease read waiter count */ -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ while (! tcmpset_32(&target_urwlock->rw_blocked_readers, -+ blocked_readers, (blocked_readers - 1))) { -+ __get_user(blocked_readers, -+ &target_urwlock->rw_blocked_readers); -+ } -+ if (1 == blocked_readers) { -+ /* clear read contention bit */ -+ __get_user(state, &target_urwlock->rw_state); -+ while(! tcmpset_32(&target_urwlock->rw_state, state, -+ state & ~TARGET_URWLOCK_READ_WAITERS)) { -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ } -+ } -+} -+ -+static int -+do_rw_wrlock(abi_ulong target_addr, long fflag, struct timespec *ts) -+{ -+ struct target_urwlock *target_urwlock; -+ uint32_t blocked_readers, blocked_writers; -+ uint32_t state; -+ int ret; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ blocked_readers = 0; -+ for (;;) { -+ __get_user(state, &target_urwlock->rw_state); -+ while (!(state & TARGET_URWLOCK_WRITE_OWNER) && -+ TARGET_URWLOCK_READER_COUNT(state) == 0) { -+ if (tcmpset_32(&target_urwlock->rw_state, state, -+ state | TARGET_URWLOCK_WRITE_OWNER)) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return (0); -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ if (!(state & (TARGET_URWLOCK_WRITE_OWNER | -+ TARGET_URWLOCK_WRITE_WAITERS)) && -+ blocked_readers != 0) { -+ ret = get_errno(_umtx_op( -+ &target_urwlock->rw_blocked_readers, -+ UMTX_OP_WAKE, INT_MAX, NULL, NULL)); -+ return (ret); -+ } -+ -+ /* re-read the state */ -+ __get_user(state, &target_urwlock->rw_state); -+ -+ /* and set TARGET_URWLOCK_WRITE_WAITERS */ -+ while (((state & TARGET_URWLOCK_WRITE_OWNER) || -+ TARGET_URWLOCK_READER_COUNT(state) != 0) && -+ (state & TARGET_URWLOCK_WRITE_WAITERS) == 0) { -+ if (tcmpset_32(&target_urwlock->rw_state, state, -+ state | TARGET_URWLOCK_WRITE_WAITERS)) { -+ break; -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* contention bit is set, increase write waiter count */ -+ __get_user(blocked_writers, &target_urwlock->rw_blocked_writers); -+ while (! tcmpset_32(&target_urwlock->rw_blocked_writers, -+ blocked_writers, blocked_writers + 1)) { -+ __get_user(blocked_writers, -+ &target_urwlock->rw_blocked_writers); -+ } -+ -+ /* sleep */ -+ while ((state & TARGET_URWLOCK_WRITE_OWNER) || -+ (TARGET_URWLOCK_READER_COUNT(state) != 0)) { -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ ret = get_errno(_umtx_op( -+ &target_urwlock->rw_blocked_writers, -+ UMTX_OP_WAIT_UINT, blocked_writers, 0, ts)); -+ if (ret) -+ return (ret); -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, -+ target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* decrease the write waiter count */ -+ __get_user(blocked_writers, &target_urwlock->rw_blocked_writers); -+ while (! tcmpset_32(&target_urwlock->rw_blocked_writers, -+ blocked_writers, (blocked_writers - 1))) { -+ __get_user(blocked_writers, -+ &target_urwlock->rw_blocked_writers); -+ } -+ if (1 == blocked_writers) { -+ /* clear write contention bit */ -+ __get_user(state, &target_urwlock->rw_state); -+ while(! tcmpset_32(&target_urwlock->rw_state, state, -+ state & ~TARGET_URWLOCK_WRITE_WAITERS)) { -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ __get_user(blocked_readers, -+ &target_urwlock->rw_blocked_readers); -+ } else -+ blocked_readers = 0; -+ } -+} -+ -+static int -+do_rw_unlock(abi_ulong target_addr) -+{ -+ struct target_urwlock *target_urwlock; -+ uint32_t flags, state, count; -+ void *q = NULL; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ __get_user(flags, &target_urwlock->rw_flags); -+ __get_user(state, &target_urwlock->rw_state); -+ -+ if (state & TARGET_URWLOCK_WRITE_OWNER) { -+ for (;;) { -+ if (! tcmpset_32(&target_urwlock->rw_state, state, -+ state & ~TARGET_URWLOCK_WRITE_OWNER)) { -+ __get_user(state, &target_urwlock->rw_state); -+ if (!(state & TARGET_URWLOCK_WRITE_OWNER)) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return (-TARGET_EPERM); -+ } -+ } else -+ break; -+ } -+ } else if (TARGET_URWLOCK_READER_COUNT(state) != 0) { -+ /* decrement reader count */ -+ for (;;) { -+ if (! tcmpset_32(&target_urwlock->rw_state, -+ state, (state - 1))) { -+ if (TARGET_URWLOCK_READER_COUNT(state) == 0) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return (-TARGET_EPERM); -+ } -+ } else -+ break; -+ } -+ } else { -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ return (-TARGET_EPERM); -+ } -+ -+ count = 0; -+ -+ if (! (flags & TARGET_URWLOCK_PREFER_READER)) { -+ if (state & TARGET_URWLOCK_WRITE_WAITERS) { -+ count = 1; -+ q = &target_urwlock->rw_blocked_writers; -+ } else if (state & TARGET_URWLOCK_READ_WAITERS) { -+ count = INT_MAX; -+ q = &target_urwlock->rw_blocked_readers; -+ } -+ } else { -+ if (state & TARGET_URWLOCK_READ_WAITERS) { -+ count = INT_MAX; -+ q = &target_urwlock->rw_blocked_readers; -+ } else if (state & TARGET_URWLOCK_WRITE_WAITERS) { -+ count = 1; -+ q = &target_urwlock->rw_blocked_writers; -+ } -+ } -+ -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ if (q != NULL) -+ return (get_errno(_umtx_op(q, UMTX_OP_WAKE, count, NULL, NULL))); -+ else -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_statfs(struct statfs *host_statfs, abi_ulong target_addr) -+{ -+ struct target_statfs *target_statfs; -+ -+ if (!lock_user_struct(VERIFY_READ, target_statfs, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ __get_user(host_statfs->f_version, &target_statfs->f_version); -+ __get_user(host_statfs->f_type, &target_statfs->f_type); -+ __get_user(host_statfs->f_flags, &target_statfs->f_flags); -+ __get_user(host_statfs->f_bsize, &target_statfs->f_bsize); -+ __get_user(host_statfs->f_iosize, &target_statfs->f_iosize); -+ __get_user(host_statfs->f_blocks, &target_statfs->f_blocks); -+ __get_user(host_statfs->f_bfree, &target_statfs->f_bfree); -+ __get_user(host_statfs->f_bavail, &target_statfs->f_bavail); -+ __get_user(host_statfs->f_files, &target_statfs->f_files); -+ __get_user(host_statfs->f_ffree, &target_statfs->f_ffree); -+ __get_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites); -+ __get_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites); -+ __get_user(host_statfs->f_syncreads, &target_statfs->f_syncreads); -+ __get_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads); -+ /* uint64_t f_spare[10]; */ -+ __get_user(host_statfs->f_namemax, &target_statfs->f_namemax); -+ __get_user(host_statfs->f_owner, &target_statfs->f_owner); -+ __get_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]); -+ __get_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]); -+ /* char f_charspace[80]; */ -+ strncpy(host_statfs->f_fstypename, &target_statfs->f_fstypename[0], -+ TARGET_MFSNAMELEN); -+ strncpy(host_statfs->f_mntfromname, &target_statfs->f_mntfromname[0], -+ TARGET_MNAMELEN); -+ strncpy(host_statfs->f_mntonname, &target_statfs->f_mntonname[0], -+ TARGET_MNAMELEN); -+ unlock_user_struct(target_statfs, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_statfs(abi_ulong target_addr, struct statfs *host_statfs) -+{ -+ struct target_statfs *target_statfs; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_statfs, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __put_user(host_statfs->f_version, &target_statfs->f_version); -+ __put_user(host_statfs->f_type, &target_statfs->f_type); -+ __put_user(host_statfs->f_flags, &target_statfs->f_flags); -+ __put_user(host_statfs->f_bsize, &target_statfs->f_bsize); -+ __put_user(host_statfs->f_iosize, &target_statfs->f_iosize); -+ __put_user(host_statfs->f_blocks, &target_statfs->f_blocks); -+ __put_user(host_statfs->f_bfree, &target_statfs->f_bfree); -+ __put_user(host_statfs->f_bavail, &target_statfs->f_bavail); -+ __put_user(host_statfs->f_files, &target_statfs->f_files); -+ __put_user(host_statfs->f_ffree, &target_statfs->f_ffree); -+ __put_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites); -+ __put_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites); -+ __put_user(host_statfs->f_syncreads, &target_statfs->f_syncreads); -+ __put_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads); -+ /* uint64_t f_spare[10]; */ -+ __put_user(host_statfs->f_namemax, &target_statfs->f_namemax); -+ __put_user(host_statfs->f_owner, &target_statfs->f_owner); -+ __put_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]); -+ __put_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]); -+ /* char f_charspace[80]; */ -+ strncpy(&target_statfs->f_fstypename[0], host_statfs->f_fstypename, -+ TARGET_MFSNAMELEN); -+ strncpy(&target_statfs->f_mntfromname[0], host_statfs->f_mntfromname, -+ TARGET_MNAMELEN); -+ strncpy(&target_statfs->f_mntonname[0], host_statfs->f_mntonname, -+ TARGET_MNAMELEN); -+ unlock_user_struct(target_statfs, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_fhandle(fhandle_t *host_fh, abi_ulong target_addr) -+{ -+ target_fhandle_t *target_fh; -+ -+ if (!lock_user_struct(VERIFY_READ, target_fh, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ __get_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]); -+ __get_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]); -+ -+ __get_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len); -+ /* u_short fid_data0; */ -+ memcpy(host_fh->fh_fid.fid_data, target_fh->fh_fid.fid_data, -+ TARGET_MAXFIDSZ); -+ unlock_user_struct(target_fh, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_fhandle(abi_ulong target_addr, fhandle_t *host_fh) -+{ -+ target_fhandle_t *target_fh; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_fh, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __put_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]); -+ __put_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]); -+ -+ __put_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len); -+ /* u_short fid_data0; */ -+ memcpy(target_fh->fh_fid.fid_data, host_fh->fh_fid.fid_data, -+ TARGET_MAXFIDSZ); -+ unlock_user_struct(target_fh, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+target_to_host_sched_param(struct sched_param *host_sp, abi_ulong target_addr) -+{ -+ struct target_sched_param *target_sp; -+ -+ if (!lock_user_struct(VERIFY_READ, target_sp, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ __get_user(host_sp->sched_priority, &target_sp->sched_priority); -+ unlock_user_struct(target_sp, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_sched_param(abi_ulong target_addr, struct sched_param *host_sp) -+{ -+ struct target_sched_param *target_sp; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_sp, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __put_user(host_sp->sched_priority, &target_sp->sched_priority); -+ unlock_user_struct(target_sp, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+do_sched_setparam(pid_t pid, abi_ulong target_sp_addr) -+{ -+ int ret; -+ struct sched_param host_sp; -+ -+ ret = target_to_host_sched_param(&host_sp, target_sp_addr); -+ if (0 == ret) -+ ret = get_errno(sched_setparam(pid, &host_sp)); -+ -+ return (ret); -+} -+ -+static inline abi_long -+do_sched_getparam(pid_t pid, abi_ulong target_sp_addr) -+{ -+ int ret; -+ struct sched_param host_sp; -+ -+ ret = get_errno(sched_getparam(pid, &host_sp)); -+ if (0 == ret) -+ ret = host_to_target_sched_param(target_sp_addr, &host_sp); -+ -+ return (ret); -+} -+ -+static inline abi_long -+do_sched_setscheduler(pid_t pid, int policy, abi_ulong target_sp_addr) -+{ -+ int ret; -+ struct sched_param host_sp; -+ -+ ret = target_to_host_sched_param(&host_sp, target_sp_addr); -+ if (0 == ret) -+ ret = get_errno(sched_setscheduler(pid, policy, &host_sp)); -+ -+ return (ret); -+} -+ -+static inline abi_long -+do_sched_rr_get_interval(pid_t pid, abi_ulong target_ts_addr) -+{ -+ int ret; -+ struct timespec host_ts; -+ -+ ret = get_errno(sched_rr_get_interval(pid, &host_ts)); -+ if (0 == ret) -+ ret = host_to_target_timespec(target_ts_addr, &host_ts); -+ -+ return (ret); -+} -+ -+static inline abi_long -+host_to_target_uuid(abi_ulong target_addr, struct uuid *host_uuid) -+{ -+ struct target_uuid *target_uuid; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_uuid, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __put_user(host_uuid->time_low, &target_uuid->time_low); -+ __put_user(host_uuid->time_mid, &target_uuid->time_mid); -+ __put_user(host_uuid->time_hi_and_version, -+ &target_uuid->time_hi_and_version); -+ host_uuid->clock_seq_hi_and_reserved = -+ target_uuid->clock_seq_hi_and_reserved; -+ host_uuid->clock_seq_low = target_uuid->clock_seq_low; -+ memcpy(host_uuid->node, target_uuid->node, TARGET_UUID_NODE_LEN); -+ unlock_user_struct(target_uuid, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_stat(abi_ulong target_addr, struct stat *host_st) -+{ -+ struct target_freebsd_stat *target_st; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ memset(target_st, 0, sizeof(*target_st)); -+ __put_user(host_st->st_dev, &target_st->st_dev); -+ __put_user(host_st->st_ino, &target_st->st_ino); -+ __put_user(host_st->st_mode, &target_st->st_mode); -+ __put_user(host_st->st_nlink, &target_st->st_nlink); -+ __put_user(host_st->st_uid, &target_st->st_uid); -+ __put_user(host_st->st_gid, &target_st->st_gid); -+ __put_user(host_st->st_rdev, &target_st->st_rdev); -+ __put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec); -+ __put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec); -+ __put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec); -+ __put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); -+ __put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec); -+ __put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); -+ __put_user(host_st->st_size, &target_st->st_size); -+ __put_user(host_st->st_blocks, &target_st->st_blocks); -+ __put_user(host_st->st_blksize, &target_st->st_blksize); -+ __put_user(host_st->st_flags, &target_st->st_flags); -+ __put_user(host_st->st_gen, &target_st->st_gen); -+ /* st_lspare not used */ -+ __put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec); -+ __put_user(host_st->st_birthtim.tv_nsec, -+ &target_st->st_birthtim.tv_nsec); -+ unlock_user_struct(target_st, target_addr, 1); -+ -+ return (0); -+} -+ -+static inline abi_long -+do_getfh(const char *path, abi_ulong target_addr) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ -+ ret = get_errno(getfh(path, &host_fh)); -+ if (ret) -+ return (ret); -+ -+ return (host_to_target_fhandle(target_addr, &host_fh)); -+} -+ -+static inline abi_long -+do_lgetfh(const char *path, abi_ulong target_addr) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ -+ ret = get_errno(lgetfh(path, &host_fh)); -+ if (ret) -+ return (ret); -+ -+ return (host_to_target_fhandle(target_addr, &host_fh)); -+} -+ -+static inline abi_long -+do_fhopen(abi_ulong target_addr, int flags) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ -+ ret = target_to_host_fhandle(&host_fh, target_addr); -+ if (ret) -+ return (ret); -+ -+ return (get_errno(fhopen(&host_fh, flags))); -+} -+ -+static inline abi_long -+do_fhstat(abi_ulong target_fhp_addr, abi_ulong target_sb_addr) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ struct stat host_sb; -+ -+ ret = target_to_host_fhandle(&host_fh, target_fhp_addr); -+ if (ret) -+ return (ret); -+ -+ ret = get_errno(fhstat(&host_fh, &host_sb)); -+ if (ret) -+ return (ret); -+ -+ return (host_to_target_stat(target_sb_addr, &host_sb)); -+} -+ -+static inline abi_long -+do_fhstatfs(abi_ulong target_fhp_addr, abi_ulong target_stfs_addr) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ struct statfs host_stfs; -+ -+ ret = target_to_host_fhandle(&host_fh, target_fhp_addr); -+ if (ret) -+ return (ret); -+ -+ ret = get_errno(fhstatfs(&host_fh, &host_stfs)); -+ if (ret) -+ return (ret); -+ -+ return (host_to_target_statfs(target_stfs_addr, &host_stfs)); -+} -+ -+static inline abi_long -+do_statfs(const char *path, abi_ulong target_addr) -+{ -+ abi_long ret; -+ struct statfs host_stfs; -+ -+ ret = get_errno(statfs(path, &host_stfs)); -+ if (ret) -+ return (ret); -+ -+ return (host_to_target_statfs(target_addr, &host_stfs)); -+} -+ -+static inline abi_long -+do_fstatfs(int fd, abi_ulong target_addr) -+{ -+ abi_long ret; -+ struct statfs host_stfs; -+ -+ ret = get_errno(fstatfs(fd, &host_stfs)); -+ if (ret) -+ return (ret); -+ -+ return (host_to_target_statfs(target_addr, &host_stfs)); -+} -+ -+static inline abi_long -+do_getfsstat(abi_ulong target_addr, abi_long bufsize, int flags) -+{ -+ abi_long ret; -+ struct statfs *host_stfs; -+ int count; -+ long host_bufsize; -+ -+ count = bufsize / sizeof(struct target_statfs); -+ -+ /* if user buffer is NULL then return number of mounted FS's */ -+ if (0 == target_addr || 0 == count) -+ return (get_errno(getfsstat(NULL, 0, flags))); -+ -+ /* XXX check count to be reasonable */ -+ host_bufsize = sizeof(struct statfs) * count; -+ host_stfs = alloca(host_bufsize); -+ if (! host_stfs) -+ return (-TARGET_EINVAL); -+ -+ ret = count = get_errno(getfsstat(host_stfs, host_bufsize, flags)); -+ if (ret < 0) -+ return (ret); -+ -+ while (count--) -+ if (host_to_target_statfs( -+ (target_addr + (count * sizeof(struct target_statfs))), -+ &host_stfs[count])) -+ return (-TARGET_EFAULT); -+ -+ return (ret); -+} -+ -+static abi_long -+do_uuidgen(abi_ulong target_addr, int count) -+{ -+ int i; -+ abi_long ret; -+ struct uuid *host_uuid; -+ -+ if (count < 1 || count > 2048) -+ return (-TARGET_EINVAL); -+ -+ host_uuid = (struct uuid *)g_malloc(count * sizeof(struct uuid)); -+ -+ if (NULL == host_uuid) -+ return (-TARGET_EINVAL); -+ -+ ret = get_errno(uuidgen(host_uuid, count)); -+ if (ret) -+ goto out; -+ for(i = 0; i < count; i++) { -+ ret = host_to_target_uuid(target_addr + -+ (abi_ulong)(sizeof(struct target_uuid) * i), &host_uuid[i]); -+ if (ret) -+ goto out; -+ } -+ -+out: -+ g_free(host_uuid); -+ return (ret); -+} -+ -+static abi_long -+do_adjtime(abi_ulong target_delta_addr, abi_ulong target_old_addr) -+{ -+ abi_long ret; -+ struct timeval host_delta, host_old; -+ -+ ret = target_to_host_timeval(&host_delta, target_delta_addr); -+ if (ret) -+ goto out; -+ -+ if (target_old_addr) { -+ ret = get_errno(adjtime(&host_delta, &host_old)); -+ if (ret) -+ goto out; -+ ret = host_to_target_timeval(&host_old, target_old_addr); -+ } else -+ ret = get_errno(adjtime(&host_delta, NULL)); -+ -+out: -+ return (ret); -+} -+ -+static abi_long -+do_ntp_adjtime(abi_ulong target_tx_addr) -+{ -+ abi_long ret; -+ struct timex host_tx; -+ -+ ret = target_to_host_timex(&host_tx, target_tx_addr); -+ if (ret) -+ goto out; -+ -+ ret = get_errno(ntp_adjtime(&host_tx)); -+ -+out: -+ return (ret); -+} -+ -+static abi_long -+do_ntp_gettime(abi_ulong target_ntv_addr) -+{ -+ abi_long ret; -+ struct ntptimeval host_ntv; -+ -+ ret = get_errno(ntp_gettime(&host_ntv)); -+ if (ret) -+ goto out; -+ -+ ret = host_to_target_ntptimeval(target_ntv_addr, &host_ntv); -+out: -+ return (ret); -+} -+ -+/* -+ * ioctl() -+ */ -+ -+static const bitmask_transtbl iflag_tbl[] = { -+ { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK }, -+ { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT }, -+ { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR }, -+ { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK }, -+ { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK }, -+ { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP }, -+ { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR }, -+ { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR }, -+ { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL }, -+ { TARGET_IXON, TARGET_IXON, IXON, IXON }, -+ { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF }, -+#ifdef IXANY -+ { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY }, -+#endif -+#ifdef IMAXBEL -+ { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL }, -+#endif -+ { 0, 0, 0, 0 } -+}; -+ -+static const bitmask_transtbl oflag_tbl[] = { -+ { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST }, -+#ifdef ONLCR -+ { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR }, -+#endif -+#ifdef TABDLY -+ { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 }, -+ { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 }, -+#endif -+#ifdef ONOEOT -+ { TARGET_ONOEOT, TARGET_ONOEOT, ONOEOT, ONOEOT }, -+#endif -+#ifdef OCRNL -+ { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL }, -+#endif -+#ifdef ONOCR -+ { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR }, -+#endif -+#ifdef ONLRET -+ { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET }, -+#endif -+ { 0, 0, 0, 0 } -+}; -+ -+static const bitmask_transtbl cflag_tbl[] = { -+#ifdef CIGNORE -+ { TARGET_CIGNORE, TARGET_CIGNORE, CIGNORE, CIGNORE }, -+#endif -+ { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, -+ { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, -+ { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, -+ { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 }, -+ { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB }, -+ { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD }, -+ { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB }, -+ { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD }, -+ { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL }, -+ { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL }, -+#ifdef CCTS_OFLOW -+ { TARGET_CCTS_OFLOW, TARGET_CCTS_OFLOW, CCTS_OFLOW, CCTS_OFLOW }, -+#endif -+#ifdef CRTSCTS -+ { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS }, -+#endif -+#ifdef CRTS_IFLOW -+ { TARGET_CRTS_IFLOW, TARGET_CRTS_IFLOW, CRTS_IFLOW, CRTS_IFLOW }, -+#endif -+#ifdef CDTS_IFLOW -+ { TARGET_CDTR_IFLOW, TARGET_CDTR_IFLOW, CDTR_IFLOW, CDTR_IFLOW }, -+#endif -+#ifdef CDSR_OFLOW -+ { TARGET_CDSR_OFLOW, TARGET_CDSR_OFLOW, CDSR_OFLOW, CDSR_OFLOW }, -+#endif -+#ifdef CCAR_OFLOW -+ { TARGET_CCAR_OFLOW, TARGET_CCAR_OFLOW, CCAR_OFLOW, CCAR_OFLOW }, -+#endif -+ { 0, 0, 0, 0 } -+}; -+ -+static const bitmask_transtbl lflag_tbl[] = { -+#ifdef ECHOKE -+ { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE }, -+#endif -+ { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE }, -+ { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK }, -+ { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO }, -+ { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL }, -+#ifdef ECHOPRT -+ { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT }, -+#endif -+#ifdef ECHOCTL -+ { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL }, -+#endif -+ { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG }, -+ { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON }, -+#ifdef ALTWERASE -+ { TARGET_ALTWERASE, TARGET_ALTWERASE, ALTWERASE, ALTWERASE }, -+#endif -+ { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN }, -+ { TARGET_EXTPROC, TARGET_EXTPROC, EXTPROC, EXTPROC }, -+ { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP }, -+#ifdef FLUSHO -+ { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO }, -+#endif -+#ifdef NOKERNINFO -+ { TARGET_NOKERNINFO, TARGET_NOKERNINFO, NOKERNINFO, NOKERNINFO }, -+#endif -+#ifdef PENDIN -+ { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN }, -+#endif -+ { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH }, -+ { 0, 0, 0, 0 } -+}; -+ -+static void -+target_to_host_termios(void *dst, const void *src) -+{ -+ struct termios *host = dst; -+ const struct target_termios *target = src; -+ -+ host->c_iflag = -+ target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); -+ host->c_oflag = -+ target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); -+ host->c_cflag = -+ target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); -+ host->c_lflag = -+ target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); -+ -+ memset(host->c_cc, 0, sizeof(host->c_cc)); -+ host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; -+ host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; -+#ifdef VEOL2 -+ host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; -+#endif -+ host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; -+#ifdef VWERASE -+ host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; -+#endif -+ host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; -+#ifdef VREPRINT -+ host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; -+#endif -+#ifdef VERASE2 -+ host->c_cc[VERASE2] = target->c_cc[TARGET_VERASE2]; -+#endif -+ host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; -+ host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; -+ host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; -+#ifdef VDSUSP -+ host->c_cc[VDSUSP] = target->c_cc[TARGET_VDSUSP]; -+#endif -+ host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; -+ host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; -+#ifdef VLNEXT -+ host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; -+#endif -+#ifdef VDISCARD -+ host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; -+#endif -+ host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; -+ host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; -+#ifdef VSTATUS -+ host->c_cc[VSTATUS] = target->c_cc[TARGET_VSTATUS]; -+#endif -+ -+ host->c_ispeed = tswap32(target->c_ispeed); -+ host->c_ospeed = tswap32(target->c_ospeed); -+} -+ -+static void -+host_to_target_termios(void *dst, const void *src) -+{ -+ struct target_termios *target = dst; -+ const struct termios *host = src; -+ -+ target->c_iflag = -+ tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); -+ target->c_oflag = -+ tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); -+ target->c_cflag = -+ tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); -+ target->c_lflag = -+ tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); -+ -+ memset(target->c_cc, 0, sizeof(target->c_cc)); -+ target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; -+ target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; -+#ifdef VEOL2 -+ target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2]; -+#endif -+ target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; -+#ifdef VWERASE -+ target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; -+#endif -+ target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; -+#ifdef VREPRINT -+ target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; -+#endif -+#ifdef VERASE2 -+ target->c_cc[TARGET_VERASE2] = host->c_cc[VERASE2]; -+#endif -+ target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; -+ target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; -+ target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; -+#ifdef VDSUSP -+ target->c_cc[TARGET_VDSUSP] = host->c_cc[VDSUSP]; -+#endif -+ target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; -+ target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; -+#ifdef VLNEXT -+ target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; -+#endif -+#ifdef VDISCARD -+ target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; -+#endif -+ target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; -+ target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; -+#ifdef VSTATUS -+ target->c_cc[TARGET_VSTATUS] = host->c_cc[VSTATUS]; -+#endif -+ -+ target->c_ispeed = tswap32(host->c_ispeed); -+ target->c_ospeed = tswap32(host->c_ospeed); -+} -+ -+static const StructEntry struct_termios_def = { -+ .convert = { host_to_target_termios, target_to_host_termios }, -+ .size = { sizeof(struct target_termios), sizeof(struct termios) }, -+ .align = { __alignof__(struct target_termios), -+ __alignof__(struct termios) }, -+}; -+ -+/* kernel structure types definitions */ -+ -+#define STRUCT(name, ...) STRUCT_ ## name, -+#define STRUCT_SPECIAL(name) STRUCT_ ## name, -+enum { -+#ifdef __FreeBSD__ -+#include "freebsd/syscall_types.h" -+#else -+#warning No syscall_types.h -+#endif -+}; -+#undef STRUCT -+#undef STRUCT_SPECIAL -+ -+#define STRUCT(name, ...) \ -+ static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL }; -+#define STRUCT_SPECIAL(name) -+#ifdef __FreeBSD__ -+#include "freebsd/syscall_types.h" -+#else -+#warning No syscall_types.h -+#endif -+#undef STRUCT -+#undef STRUCT_SPECIAL -+ -+typedef struct IOCTLEntry IOCTLEntry; -+ -+typedef abi_long do_ioctl_fn(const IOCTLEntry *ie, uint8_t *buf_temp, -+ int fd, abi_long cmd, abi_long arg); -+ -+struct IOCTLEntry { -+ unsigned int target_cmd; -+ unsigned int host_cmd; -+ const char *name; -+ int access; -+ do_ioctl_fn *do_ioctl; -+ const argtype arg_type[5]; -+}; -+ -+#define MAX_STRUCT_SIZE 4096 -+ -+static IOCTLEntry ioctl_entries[] = { -+#define IOC_ 0x0000 -+#define IOC_R 0x0001 -+#define IOC_W 0x0002 -+#define IOC_RW (IOC_R | IOC_W) -+#define IOCTL(cmd, access, ...) \ -+ { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, -+#define IOCTL_SPECIAL(cmd, access, dofn, ...) \ -+ { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } }, -+#ifdef __FreeBSD__ -+#include "freebsd/ioctl.h" -+#else -+#warning No ioctl.h -+#endif -+ { 0, 0 }, -+}; -+ -+static abi_long -+do_ioctl(int fd, abi_long cmd, abi_long arg) -+{ -+ const IOCTLEntry *ie; -+ const argtype *arg_type; -+ abi_long ret; -+ uint8_t buf_temp[MAX_STRUCT_SIZE]; -+ int target_size; -+ void *argptr; -+ -+ ie = ioctl_entries; -+ for(;;) { -+ if (0 == ie->target_cmd) { -+ gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); -+ return (-TARGET_ENOSYS); -+ } -+ if (ie->target_cmd == cmd) -+ break; -+ ie++; -+ } -+ arg_type = ie->arg_type; -+#if defined(DEBUG) -+ gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name); -+#endif -+ if (ie->do_ioctl) { -+ return (ie->do_ioctl(ie, buf_temp, fd, cmd, arg)); -+ } -+ -+ switch(arg_type[0]) { -+ case TYPE_NULL: -+ /* no argument */ -+ ret = get_errno(ioctl(fd, ie->host_cmd)); -+ break; -+ -+ case TYPE_PTRVOID: -+ case TYPE_INT: -+ /* int argument */ -+ ret = get_errno(ioctl(fd, ie->host_cmd, arg)); -+ break; -+ -+ case TYPE_PTR: -+ arg_type++; -+ target_size = thunk_type_size(arg_type, 0); -+ switch(ie->access) { -+ case IOC_R: -+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); -+ if (!is_error(ret)) { -+ argptr = lock_user(VERIFY_WRITE, arg, -+ target_size, 0); -+ if (!argptr) -+ return (-TARGET_EFAULT); -+ thunk_convert(argptr, buf_temp, arg_type, -+ THUNK_TARGET); -+ unlock_user(argptr, arg, target_size); -+ } -+ break; -+ -+ case IOC_W: -+ argptr = lock_user(VERIFY_READ, arg, target_size, 1); -+ if (!argptr) -+ return (-TARGET_EFAULT); -+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); -+ unlock_user(argptr, arg, 0); -+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); -+ -+ case IOC_RW: -+ default: -+ argptr = lock_user(VERIFY_READ, arg, target_size, 1); -+ if (!argptr) -+ return (-TARGET_EFAULT); -+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); -+ unlock_user(argptr, arg, 0); -+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); -+ if (!is_error(ret)) { -+ argptr = lock_user(VERIFY_WRITE, arg, -+ target_size, 0); -+ if (!argptr) -+ return (-TARGET_EFAULT); -+ thunk_convert(argptr, buf_temp, arg_type, -+ THUNK_TARGET); -+ unlock_user(argptr, arg, target_size); -+ } -+ break; -+ } -+ break; -+ -+ default: -+ gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", -+ (long)cmd, arg_type[0]); -+ ret = -TARGET_ENOSYS; -+ break; -+ } -+ return (ret); -+} -+ -+/* do_syscall() should always have a single exit point at the end so -+ that actions, such as logging of syscall results, can be performed. -+ All errnos that do_syscall() returns must be -TARGET_<errcode>. */ -+abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, -+ abi_long arg5, abi_long arg6, abi_long arg7, -+ abi_long arg8) -+{ -+ abi_long ret; -+ void *p; -+ -+#ifdef DEBUG -+ gemu_log("freebsd syscall %d\n", num); -+#endif -+ if(do_strace) -+ print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); -+ -+ switch(num) { -+ case TARGET_FREEBSD_NR_exit: -+#ifdef TARGET_GPROF -+ _mcleanup(); -+#endif -+ gdb_exit(cpu_env, arg1); -+ /* XXX: should free thread stack and CPU env */ -+ _exit(arg1); -+ ret = 0; /* avoid warning */ -+ break; -+ case TARGET_FREEBSD_NR_read: -+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -+ goto efault; -+ ret = get_errno(read(arg1, p, arg3)); -+ unlock_user(p, arg2, ret); -+ break; -+ -+ case TARGET_FREEBSD_NR_readv: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) -+ goto efault; -+ ret = get_errno(readv(arg1, vec, count)); -+ unlock_iovec(vec, arg2, count, 1); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_pread: -+ if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -+ goto efault; -+ ret = get_errno(pread(arg1, p, arg3, target_offset64(arg4, arg5))); -+ unlock_user(p, arg2, ret); -+ break; -+ -+ case TARGET_FREEBSD_NR_preadv: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) -+ goto efault; -+ ret = get_errno(preadv(arg1, vec, count, -+ target_offset64(arg4, arg5))); -+ unlock_iovec(vec, arg2, count, 1); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_write: -+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -+ goto efault; -+ ret = get_errno(write(arg1, p, arg3)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_writev: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -+ goto efault; -+ ret = get_errno(writev(arg1, vec, count)); -+ unlock_iovec(vec, arg2, count, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_pwrite: -+ if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -+ goto efault; -+ ret = get_errno(pwrite(arg1, p, arg3, target_offset64(arg4, arg5))); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_pwritev: -+ { -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -+ goto efault; -+ ret = get_errno(pwritev(arg1, vec, count, -+ target_offset64(arg4, arg5))); -+ unlock_iovec(vec, arg2, count, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_open: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(open(path(p), -+ target_to_host_bitmask(arg2, fcntl_flags_tbl), -+ arg3)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_openat: -+ if (!(p = lock_user_string(arg2))) -+ goto efault; -+ ret = get_errno(openat(arg1, path(p), -+ target_to_host_bitmask(arg3, fcntl_flags_tbl), -+ arg4)); -+ unlock_user(p, arg2, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_close: -+ ret = get_errno(close(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_closefrom: -+ ret = 0; -+ closefrom(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_revoke: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(revoke(p)); -+ unlock_user(p, arg1, 0); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_creat -+ case TARGET_FREEBSD_NR_creat: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(creat(p, arg2)); -+ unlock_user(p, arg1, 0); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_mmap: -+ ret = get_errno(target_mmap(arg1, arg2, arg3, -+ target_to_host_bitmask(arg4, mmap_flags_tbl), -+ arg5, -+ arg6)); -+ break; -+ -+ case TARGET_FREEBSD_NR_munmap: -+ ret = get_errno(target_munmap(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mprotect: -+ ret = get_errno(target_mprotect(arg1, arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_msync: -+ ret = get_errno(msync(g2h(arg1), arg2, arg3)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mlock: -+ ret = get_errno(mlock(g2h(arg1), arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_munlock: -+ ret = get_errno(munlock(g2h(arg1), arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_mlockall: -+ ret = get_errno(mlockall(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_munlockall: -+ ret = get_errno(munlockall()); -+ break; -+ -+ case TARGET_FREEBSD_NR_madvise: -+ /* -+ * A straight passthrough may not be safe because qemu sometimes -+ * turns private file-backed mapping into anonymous mappings. This -+ * will break MADV_DONTNEED. This is a hint, so ignoring and returing -+ * success is ok. -+ */ -+ ret = get_errno(0); -+ break; -+ -+ case TARGET_FREEBSD_NR_break: - ret = do_obreak(arg1); - break; - #ifdef __FreeBSD__ -@@ -2727,18 +4206,30 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_stat: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(stat(path(p), &st)); -- unlock_user(p, arg1, 0); -- goto do_stat; -+ { -+ struct stat st; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(stat(path(p), &st)); -+ unlock_user(p, arg1, 0); -+ if (0 == ret) -+ ret = host_to_target_stat(arg2, &st); -+ } -+ break; - - case TARGET_FREEBSD_NR_lstat: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(lstat(path(p), &st)); -- unlock_user(p, arg1, 0); -- goto do_stat; -+ { -+ struct stat st; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(lstat(path(p), &st)); -+ unlock_user(p, arg1, 0); -+ if (0 == ret) -+ ret = host_to_target_stat(arg2, &st); -+ } -+ break; - - case TARGET_FREEBSD_NR_nstat: - case TARGET_FREEBSD_NR_nfstat: -@@ -2747,42 +4238,11 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_fstat: -- { -- ret = get_errno(fstat(arg1, &st)); -- --do_stat: -- if (!is_error(ret)) { -- struct target_freebsd_stat *target_st; -- -- 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); -- __put_user(st.st_nlink, &target_st->st_nlink); -- __put_user(st.st_uid, &target_st->st_uid); -- __put_user(st.st_gid, &target_st->st_gid); -- __put_user(st.st_rdev, &target_st->st_rdev); -- __put_user(st.st_atim.tv_sec, &target_st->st_atim.tv_sec); -- __put_user(st.st_atim.tv_nsec, &target_st->st_atim.tv_nsec); -- __put_user(st.st_mtim.tv_sec, &target_st->st_mtim.tv_sec); -- __put_user(st.st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); -- __put_user(st.st_ctim.tv_sec, &target_st->st_ctim.tv_sec); -- __put_user(st.st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); -- __put_user(st.st_size, &target_st->st_size); -- __put_user(st.st_blocks, &target_st->st_blocks); -- __put_user(st.st_blksize, &target_st->st_blksize); -- __put_user(st.st_flags, &target_st->st_flags); -- __put_user(st.st_gen, &target_st->st_gen); -- /* st_lspare not used */ -- __put_user(st.st_birthtim.tv_sec, -- &target_st->st_birthtim.tv_sec); -- __put_user(st.st_birthtim.tv_nsec, -- &target_st->st_birthtim.tv_nsec); -- unlock_user_struct(target_st, arg2, 1); -- } -- -+ { -+ struct stat st; -+ ret = get_errno(fstat(arg1, &st)); -+ if (! ret) -+ ret = host_to_target_stat(arg2, &st); - } - break; - -@@ -2845,7 +4305,7 @@ do_stat: - } - ret = get_errno(gettimeofday(&tv, arg2 != 0 ? &tz : NULL)); - if (!is_error(ret)) { -- if (fbsd_copy_to_user_timeval(&tv, arg1)) -+ if (host_to_target_timeval(&tv, arg1)) - goto efault; - } - } -@@ -2864,7 +4324,7 @@ do_stat: - __get_user(tz.tz_dsttime, &target_tz->tz_dsttime); - unlock_user_struct(target_tz, arg2, 1); - } -- if (copy_from_user_timeval(&tv, arg1)) -+ if (target_to_host_timeval(&tv, arg1)) - goto efault; - ret = get_errno(settimeofday(&tv, arg2 != 0 ? & tz : NULL)); - } -@@ -3155,8 +4615,8 @@ do_stat: - - if (arg2) { - pvalue = &value; -- if (copy_from_user_timeval(&pvalue->it_interval, -- arg2) || copy_from_user_timeval( -+ if (target_to_host_timeval(&pvalue->it_interval, -+ arg2) || target_to_host_timeval( - &pvalue->it_value, arg2 + - sizeof(struct target_timeval))) - goto efault; -@@ -3165,8 +4625,8 @@ do_stat: - } - ret = get_errno(setitimer(arg1, pvalue, &ovalue)); - if (!is_error(ret) && arg3) { -- if (fbsd_copy_to_user_timeval(&ovalue.it_interval, arg3) -- || fbsd_copy_to_user_timeval(&ovalue.it_value, -+ if (host_to_target_timeval(&ovalue.it_interval, arg3) -+ || host_to_target_timeval(&ovalue.it_value, - arg3 + sizeof(struct target_timeval))) - goto efault; - } -@@ -3179,8 +4639,8 @@ do_stat: - - ret = get_errno(getitimer(arg1, &value)); - if (!is_error(ret) && arg2) { -- if (fbsd_copy_to_user_timeval(&value.it_interval, arg2) -- || fbsd_copy_to_user_timeval(&value.it_value, -+ if (host_to_target_timeval(&value.it_interval, arg2) -+ || host_to_target_timeval(&value.it_value, - arg2 + sizeof(struct target_timeval))) - goto efault; - } -@@ -3192,8 +4652,8 @@ do_stat: - struct timeval *tvp, tv[2]; - - if (arg2) { -- if (copy_from_user_timeval(&tv[0], arg2) -- || copy_from_user_timeval(&tv[1], -+ if (target_to_host_timeval(&tv[0], arg2) -+ || target_to_host_timeval(&tv[1], - arg2 + sizeof(struct target_timeval))) - - goto efault; -@@ -3213,8 +4673,8 @@ do_stat: - struct timeval *tvp, tv[2]; - - if (arg2) { -- if (copy_from_user_timeval(&tv[0], arg2) -- || copy_from_user_timeval(&tv[1], -+ if (target_to_host_timeval(&tv[0], arg2) -+ || target_to_host_timeval(&tv[1], - arg2 + sizeof(struct target_timeval))) - - goto efault; -@@ -3234,8 +4694,8 @@ do_stat: - struct timeval *tvp, tv[2]; - - if (arg2) { -- if (copy_from_user_timeval(&tv[0], arg2) -- || copy_from_user_timeval(&tv[1], -+ if (target_to_host_timeval(&tv[0], arg2) -+ || target_to_host_timeval(&tv[1], - arg2 + sizeof(struct target_timeval))) - goto efault; - tvp = tv; -@@ -3251,8 +4711,8 @@ do_stat: - struct timeval *tvp, tv[2]; - - if (arg3) { -- if (copy_from_user_timeval(&tv[0], arg3) -- || copy_from_user_timeval(&tv[1], -+ if (target_to_host_timeval(&tv[0], arg3) -+ || target_to_host_timeval(&tv[1], - arg3 + sizeof(struct target_timeval))) - goto efault; - tvp = tv; -@@ -4024,6 +5484,10 @@ do_stat: - ret = do_socketpair(arg1, arg2, arg3, arg4); - break; - -+ case TARGET_FREEBSD_NR_shutdown: -+ ret = get_errno(shutdown(arg1, arg2)); -+ break; -+ - case TARGET_FREEBSD_NR_getpriority: - /* - * Note that negative values are valid for getpriority, so we must -@@ -4165,8 +5629,31 @@ do_stat: - break; - - case TARGET_FREEBSD_NR_getresuid: -+ { -+ uid_t ruid, euid, suid; -+ -+ ret = get_errno(getresuid(&ruid, &euid, &suid)); -+ if (put_user_s32(ruid, arg1)) -+ goto efault; -+ if (put_user_s32(euid, arg2)) -+ goto efault; -+ if (put_user_s32(suid, arg3)) -+ goto efault; -+ } -+ break; -+ - case TARGET_FREEBSD_NR_getresgid: -- ret = unimplemented(num); -+ { -+ gid_t rgid, egid, sgid; -+ -+ ret = get_errno(getresgid(&rgid, &egid, &sgid)); -+ if (put_user_s32(rgid, arg1)) -+ goto efault; -+ if (put_user_s32(egid, arg2)) -+ goto efault; -+ if (put_user_s32(sgid, arg3)) -+ goto efault; -+ } - break; - - case TARGET_FREEBSD_NR_setsid: -@@ -4679,7 +6166,7 @@ do_stat: - long tid; - - thr_self(&tid); -- ret = do_umtx_lock(arg1, tswap32(tid)); -+ ret = do_lock_umtx(arg1, tid, NULL); - } - break; - -@@ -4688,72 +6175,238 @@ do_stat: - long tid; - - thr_self(&tid); -- ret = do_umtx_unlock(arg1, tswap32(tid)); -+ ret = do_unlock_umtx(arg1, tid); - } - break; - - case TARGET_FREEBSD_NR__umtx_op: - { - struct timespec ts; -- void *object = NULL; -- int operation; -- void *addr = NULL; -- void *addr2 = NULL; -- -+ long tid; - - /* int _umtx_op(void *obj, int op, u_long val, -- * void *uaddr, void *uaddr2); */ -+ * void *uaddr, void *target_ts); */ - - abi_ulong obj = arg1; - int op = (int)arg2; - u_long val = arg3; -- /* abi_ulong uaddr = arg4; */ -- abi_ulong uaddr2 = arg5; -+ abi_ulong uaddr = arg4; -+ abi_ulong target_ts = arg5; - - switch(op) { - case TARGET_UMTX_OP_LOCK: -- ret = do_umtx_lock(obj, tswap32((uint32_t)val)); -+ thr_self(&tid); -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = do_lock_umtx(obj, tid, &ts); -+ } else -+ ret = do_lock_umtx(obj, tid, NULL); - break; - - case TARGET_UMTX_OP_UNLOCK: -- ret = do_umtx_unlock(obj, tswap32((uint32_t)val)); -+ thr_self(&tid); -+ ret = do_unlock_umtx(obj, tid); - break; - - case TARGET_UMTX_OP_WAIT: -- if (uaddr2) { -- if (target_to_host_timespec(&ts, uaddr2)) -+ /* args: obj *, val, ts * */ -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) - goto efault; -- addr2 = (void *)&ts; -- } -- ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT, -- tswap32(val), addr, addr2)); -- break; -+ ret = do_umtx_op_wait(obj, tswapal(val), &ts); -+ } else -+ ret = do_umtx_op_wait(obj, tswapal(val), NULL); -+ break; - - case TARGET_UMTX_OP_WAKE: -- operation = UMTX_OP_WAKE; -- object = g2h(obj); -- ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE, -- val, 0, 0)); -+ /* args: obj *, nr_wakeup */ -+ ret = do_umtx_op_wake(obj, val); - break; - -- case TARGET_UMTX_OP_MUTEX_TRYLOCK: - case TARGET_UMTX_OP_MUTEX_LOCK: -+ thr_self(&tid); -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = do_lock_umutex(obj, tid, &ts, 0); -+ } else { -+ ret = do_lock_umutex(obj, tid, NULL, 0); -+ } -+ break; -+ - case TARGET_UMTX_OP_MUTEX_UNLOCK: -+ thr_self(&tid); -+ ret = do_unlock_umutex(obj, tid); -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_TRYLOCK: -+ thr_self(&tid); -+ ret = do_lock_umutex(obj, tid, NULL, TARGET_UMUTEX_TRY); -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_WAIT: -+ thr_self(&tid); -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = do_lock_umutex(obj, tid, &ts, -+ TARGET_UMUTEX_WAIT); -+ } else { -+ ret = do_lock_umutex(obj, tid, NULL, -+ TARGET_UMUTEX_WAIT); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_WAKE: -+ /* Don't need to do access_ok(). */ -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_MUTEX_WAKE, -+ val, NULL, NULL)); -+ break; -+ - case TARGET_UMTX_OP_SET_CEILING: -+ ret = 0; /* XXX quietly ignore these things for now */ -+ break; -+ - case TARGET_UMTX_OP_CV_WAIT: -+ /* -+ * Initialization of the struct conv is done by -+ * bzero'ing everything in userland. -+ */ -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = do_cv_wait(obj, uaddr, &ts, val); -+ } else { -+ ret = do_cv_wait(obj, uaddr, NULL, val); -+ } -+ break; -+ - case TARGET_UMTX_OP_CV_SIGNAL: -+ /* -+ * XXX -+ * User code may check if c_has_waiters is zero. Other -+ * than that it is assume that user code doesn't do -+ * much with the struct conv fields and is pretty -+ * much opauque to userland. -+ */ -+ ret = do_cv_signal(obj); -+ break; -+ - case TARGET_UMTX_OP_CV_BROADCAST: -+ /* -+ * XXX -+ * User code may check if c_has_waiters is zero. Other -+ * than that it is assume that user code doesn't do -+ * much with the struct conv fields and is pretty -+ * much opauque to userland. -+ */ -+ ret = do_cv_broadcast(obj); -+ break; -+ - case TARGET_UMTX_OP_WAIT_UINT: -+ if (! access_ok(VERIFY_READ, obj, sizeof(abi_ulong))) -+ goto efault; -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_WAIT_UINT, -+ tswap32((uint32_t)val), NULL, &ts)); -+ } else -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_WAIT_UINT, -+ tswap32((uint32_t)val), NULL, NULL)); -+ -+ break; -+ -+ case TARGET_UMTX_OP_WAIT_UINT_PRIVATE: -+ if (! access_ok(VERIFY_READ, obj, sizeof(abi_ulong))) -+ goto efault; -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_WAIT_UINT_PRIVATE, -+ tswap32((uint32_t)val), NULL, &ts)); -+ } else -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_WAIT_UINT_PRIVATE, -+ tswap32((uint32_t)val), NULL, NULL)); -+ -+ break; -+ -+ case TARGET_UMTX_OP_WAKE_PRIVATE: -+ /* Don't need to do access_ok(). */ -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE_PRIVATE, -+ val, NULL, NULL)); -+ break; -+ -+ case TARGET_UMTX_OP_NWAKE_PRIVATE: -+ if (! access_ok(VERIFY_READ, obj, -+ val * sizeof(uint32_t))) -+ goto efault; -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE, -+ val, NULL, NULL)); -+ break; -+ -+ - case TARGET_UMTX_OP_RW_RDLOCK: -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = do_rw_rdlock(obj, val, &ts); -+ } else -+ ret = do_rw_rdlock(obj, val, NULL); -+ break; -+ - case TARGET_UMTX_OP_RW_WRLOCK: -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = do_rw_wrlock(obj, val, &ts); -+ } else -+ ret = do_rw_wrlock(obj, val, NULL); -+ break; -+ - case TARGET_UMTX_OP_RW_UNLOCK: -- case TARGET_UMTX_OP_WAIT_UINT_PRIVATE: -- case TARGET_UMTX_OP_WAKE_PRIVATE: -- case TARGET_UMTX_OP_MUTEX_WAIT: -- case TARGET_UMTX_OP_MUTEX_WAKE: -+ ret = do_rw_unlock(obj); -+ break; -+ -+#ifdef UMTX_OP_MUTEX_WAKE2 -+ case TARGET_UMTX_OP_MUTEX_WAKE2: -+ if (! access_ok(VERIFY_WRITE, obj, -+ sizeof(struct target_ucond))) { -+ goto efault; -+ } -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_MUTEX_WAKE2, val, NULL, NULL)); -+ break; -+#endif -+ - case TARGET_UMTX_OP_SEM_WAIT: -+ /* XXX Assumes struct _usem is opauque to the user */ -+ if (! access_ok(VERIFY_WRITE, obj, -+ sizeof(struct target__usem))) { -+ goto efault; -+ } -+ if (target_ts) { -+ if (target_to_host_timespec(&ts, target_ts)) -+ goto efault; -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_SEM_WAIT, 0, NULL, &ts)); -+ } else { -+ ret = get_errno(_umtx_op(g2h(obj), -+ UMTX_OP_SEM_WAIT, 0, NULL, NULL)); -+ } -+ break; -+ - case TARGET_UMTX_OP_SEM_WAKE: -- case TARGET_UMTX_OP_NWAKE_PRIVATE: -+ /* Don't need to do access_ok(). */ -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAKE, -+ val, NULL, NULL)); -+ break; -+ - default: - ret = -TARGET_EINVAL; - break; -@@ -4761,21 +6414,150 @@ do_stat: - } - break; - -+ case TARGET_FREEBSD_NR_getfh: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = do_getfh(path(p), arg2); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_lgetfh: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = do_lgetfh(path(p), arg2); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fhopen: -+ ret = do_fhopen(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fhstat: -+ ret = do_fhstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fhstatfs: -+ ret = do_fhstatfs(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getfsstat: -+ ret = do_getfsstat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_statfs: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = do_statfs(path(p), arg2); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_fstatfs: -+ ret = do_fstatfs(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_ioctl: -+ ret = do_ioctl(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_kenv: -+ { -+ char *n, *v; -+ -+ if (!(n = lock_user_string(arg2))) -+ goto efault; -+ if (!(v = lock_user_string(arg3))) -+ goto efault; -+ ret = get_errno(kenv(arg1, n, v, arg4)); -+ unlock_user(v, arg3, 0); -+ unlock_user(n, arg2, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR_swapon: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(swapon(path(p))); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_swapoff: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ ret = get_errno(swapoff(path(p))); -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR_reboot: -+ ret = get_errno(reboot(arg1)); -+ break; -+ -+ case TARGET_FREEBSD_NR_uuidgen: -+ ret = do_uuidgen(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mincore: -+ if (!(p = lock_user(VERIFY_WRITE, arg3, arg2, 0))) -+ goto efault; -+ ret = get_errno(mincore(g2h(arg1), arg2, p)); -+ unlock_user(p, arg3, ret); -+ break; -+ -+ case TARGET_FREEBSD_NR_adjtime: -+ ret = do_adjtime(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_ntp_adjtime: -+ ret = do_ntp_adjtime(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_ntp_gettime: -+ ret = do_ntp_gettime(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_vadvise: -+ ret = -TARGET_EINVAL; /* See sys_ovadvise() in vm_unix.c */ -+ break; -+ -+ case TARGET_FREEBSD_NR_sbrk: -+ ret = -TARGET_EOPNOTSUPP; /* see sys_sbrk() in vm_mmap.c */ -+ break; -+ -+ case TARGET_FREEBSD_NR_sstk: -+ ret = -TARGET_EOPNOTSUPP; /* see sys_sstk() in vm_mmap.c */ -+ break; -+ - case TARGET_FREEBSD_NR_yield: -+ case TARGET_FREEBSD_NR_sched_yield: -+ ret = get_errno(sched_yield()); -+ break; -+ - case TARGET_FREEBSD_NR_sched_setparam: -+ ret = do_sched_setparam(arg1, arg2); -+ break; -+ - case TARGET_FREEBSD_NR_sched_getparam: -+ ret = do_sched_getparam(arg1, arg2); -+ break; -+ - case TARGET_FREEBSD_NR_sched_setscheduler: -+ ret = do_sched_setscheduler(arg1, arg2, arg3); -+ break; -+ - case TARGET_FREEBSD_NR_sched_getscheduler: -- case TARGET_FREEBSD_NR_sched_yield: -+ ret = get_errno(sched_getscheduler(arg1)); -+ break; -+ - case TARGET_FREEBSD_NR_sched_get_priority_max: -- case TARGET_FREEBSD_NR_sched_get_priority_min: -- case TARGET_FREEBSD_NR_sched_rr_get_interval: -+ ret = get_errno(sched_get_priority_max(arg1)); -+ break; - -- case TARGET_FREEBSD_NR_reboot: -- case TARGET_FREEBSD_NR_shutdown: -+ case TARGET_FREEBSD_NR_sched_get_priority_min: -+ ret = get_errno(sched_get_priority_min(arg1)); -+ break; - -- case TARGET_FREEBSD_NR_swapon: -- case TARGET_FREEBSD_NR_swapoff: -+ case TARGET_FREEBSD_NR_sched_rr_get_interval: -+ ret = do_sched_rr_get_interval(arg1, arg2); -+ break; - - case TARGET_FREEBSD_NR_cpuset: - case TARGET_FREEBSD_NR_cpuset_getid: -@@ -4789,22 +6571,10 @@ do_stat: - case TARGET_FREEBSD_NR_rctl_remove_rule: - case TARGET_FREEBSD_NR_rctl_get_limits: - -- case TARGET_FREEBSD_NR_ntp_adjtime: -- case TARGET_FREEBSD_NR_ntp_gettime: -- - case TARGET_FREEBSD_NR_sctp_peeloff: - case TARGET_FREEBSD_NR_sctp_generic_sendmsg: - case TARGET_FREEBSD_NR_sctp_generic_recvmsg: - -- case TARGET_FREEBSD_NR_getfh: -- case TARGET_FREEBSD_NR_lgetfh: -- case TARGET_FREEBSD_NR_fhstatfs: -- case TARGET_FREEBSD_NR_fhopen: -- case TARGET_FREEBSD_NR_fhstat: -- -- case TARGET_FREEBSD_NR_getfsstat: -- case TARGET_FREEBSD_NR_fstatfs: -- - case TARGET_FREEBSD_NR_modfnext: - case TARGET_FREEBSD_NR_modfind: - case TARGET_FREEBSD_NR_kldload: -@@ -4821,8 +6591,6 @@ do_stat: - case TARGET_FREEBSD_NR_quota: - #endif - -- case TARGET_FREEBSD_NR_adjtime: -- - #ifdef TARGET_FREEBSD_NR_gethostid - case TARGET_FREEBSD_NR_gethostid: - #endif -@@ -4833,13 +6601,6 @@ do_stat: - case TARGET_FREEBSD_NR_sethostname: - #endif - -- case TARGET_FREEBSD_NR_mincore: -- -- case TARGET_FREEBSD_NR_vadvise: -- -- case TARGET_FREEBSD_NR_sbrk: -- case TARGET_FREEBSD_NR_sstk: -- - #ifdef TARGET_FREEBSD_NR_getkerninfo - case TARGET_FREEBSD_NR_getkerninfo: - #endif -@@ -4847,8 +6608,6 @@ do_stat: - case TARGET_FREEBSD_NR_getpagesize: - #endif - -- case TARGET_FREEBSD_NR_revoke: -- - case TARGET_FREEBSD_NR_profil: - case TARGET_FREEBSD_NR_ktrace: - -@@ -4857,12 +6616,13 @@ do_stat: - case TARGET_FREEBSD_NR_jail_get: - case TARGET_FREEBSD_NR_jail_set: - case TARGET_FREEBSD_NR_jail_remove: -+ ret = unimplemented(num); -+ break; - - case TARGET_FREEBSD_NR_cap_enter: - case TARGET_FREEBSD_NR_cap_getmode: -- -- case TARGET_FREEBSD_NR_kenv: -- case TARGET_FREEBSD_NR_uuidgen: -+ ret = unimplemented(num); -+ break; - - case TARGET_FREEBSD_NR___mac_get_proc: - case TARGET_FREEBSD_NR___mac_set_proc: -@@ -4873,6 +6633,8 @@ do_stat: - case TARGET_FREEBSD_NR___mac_get_link: - case TARGET_FREEBSD_NR___mac_set_link: - case TARGET_FREEBSD_NR_mac_syscall: -+ ret = unimplemented(num); -+ break; - - case TARGET_FREEBSD_NR_audit: - case TARGET_FREEBSD_NR_auditon: -@@ -4881,6 +6643,8 @@ do_stat: - case TARGET_FREEBSD_NR_getaudit_addr: - case TARGET_FREEBSD_NR_setaudit_addr: - case TARGET_FREEBSD_NR_auditctl: -+ ret = unimplemented(num); -+ break; - - - #ifdef TARGET_FREEBSD_NR_obreak -@@ -4894,7 +6658,6 @@ do_stat: - case TARGET_FREEBSD_NR_sendfile: - case TARGET_FREEBSD_NR_ptrace: - case TARGET_FREEBSD_NR_utrace: -- case TARGET_FREEBSD_NR_ioctl: - ret = unimplemented(num); - break; - -@@ -5061,4 +6824,43 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, - - void syscall_init(void) - { -+ IOCTLEntry *ie; -+ const argtype *arg_type; -+ int size; -+ -+#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); -+#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); -+#ifdef __FreeBSD__ -+#include "freebsd/syscall_types.h" -+#else -+#warning No syscall_types.h -+#endif -+#undef STRUCT -+#undef STRUCT_SPECIAL -+ -+ /* -+ * Patch the ioctl size if necessary using the fact that no -+ * ioctl has all the bits at '1' in the size field -+ * (IOCPARM_MAX - 1). -+ */ -+ ie = ioctl_entries; -+ while (ie->target_cmd != 0) { -+ if (((ie->target_cmd >> TARGET_IOCPARM_SHIFT) & -+ TARGET_IOCPARM_MASK) == TARGET_IOCPARM_MASK) { -+ arg_type = ie->arg_type; -+ if (arg_type[0] != TYPE_PTR) { -+ fprintf(stderr, -+ "cannot patch size for ioctl 0x%x\n", -+ ie->target_cmd); -+ exit(1); -+ } -+ arg_type++; -+ size = thunk_type_size(arg_type, 0); -+ ie->target_cmd = (ie->target_cmd & ~(TARGET_IOCPARM_MASK -+ << TARGET_IOCPARM_SHIFT)) | -+ (size << TARGET_IOCPARM_SHIFT); -+ } -+ ie++; -+ } -+ - } -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index 2879d83..3eb760b 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -555,7 +555,7 @@ struct target_rtprio { - */ - - struct target_umtx { -- uint32_t u_owner; /* Owner of the mutex. */ -+ abi_ulong u_owner; /* Owner of the mutex. */ - }; - - struct target_umutex { -@@ -573,7 +573,7 @@ struct target_ucond { - }; - - struct target_urwlock { -- int32_t rw_state; -+ uint32_t rw_state; - uint32_t rw_flags; - uint32_t rw_blocked_readers; - uint32_t rw_blocked_writers; -@@ -613,7 +613,146 @@ struct target__usem { - #define TARGET_UMTX_OP_SEM_WAIT 19 - #define TARGET_UMTX_OP_SEM_WAKE 20 - #define TARGET_UMTX_OP_NWAKE_PRIVATE 21 --#define TARGET_UMTX_OP_MAX 22 -+#define TARGET_UMTX_OP_MUTEX_WAKE2 22 -+#define TARGET_UMTX_OP_MAX 23 - - /* flags for UMTX_OP_CV_WAIT */ --#define TARGET_CHECK_UNPARKING 0x01 -+#define TARGET_CVWAIT_CHECK_UNPARKING 0x01 -+#define TARGET_CVWAIT_ABSTIME 0x02 -+#define TARGET_CVWAIT_CLOCKID 0x04 -+ -+#define TARGET_UMTX_UNOWNED 0x0 -+#define TARGET_UMUTEX_UNOWNED 0x0 -+#define TARGET_UMTX_CONTESTED (abi_long)(0x8000000000000000) -+#define TARGET_UMUTEX_CONTESTED 0x80000000U -+ -+/* flags for umutex */ -+#define TARGET_UMUTEX_ERROR_CHECK 0x0002 /* Error-checking mutex */ -+#define TARGET_UMUTEX_PRIO_INHERIT 0x0004 /* Priority inherited mutex */ -+#define TARGET_UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */ -+ -+#define TARGET_UMUTEX_TRY 1 -+#define TARGET_UMUTEX_WAIT 2 -+ -+/* urwlock flags */ -+#define TARGET_URWLOCK_PREFER_READER 0x0002 -+#define TARGET_URWLOCK_WRITE_OWNER 0x80000000U -+#define TARGET_URWLOCK_WRITE_WAITERS 0x40000000U -+#define TARGET_URWLOCK_READ_WAITERS 0x20000000U -+#define TARGET_URWLOCK_MAX_READERS 0x1fffffffU -+#define TARGET_URWLOCK_READER_COUNT(c) ((c) & TARGET_URWLOCK_MAX_READERS) -+ -+/* mount.h statfs */ -+/* -+ * filesystem id type -+ */ -+typedef struct target_fsid { int32_t val[2]; } target_fsid_t; -+ -+/* -+ * filesystem statistics -+ */ -+#define TARGET_MFSNAMELEN 16 /* length of type name include null */ -+#define TARGET_MNAMELEN 88 /* size of on/from name bufs */ -+#define TARGET_STATFS_VERSION 0x20030518 /* current version number */ -+struct target_statfs { -+ uint32_t f_version; /* structure version number */ -+ uint32_t f_type; /* type of filesystem */ -+ uint64_t f_flags; /* copy of mount exported flags */ -+ uint64_t f_bsize; /* filesystem fragment size */ -+ uint64_t f_iosize; /* optimal transfer block size */ -+ uint64_t f_blocks; /* total data blocks in filesystem */ -+ uint64_t f_bfree; /* free blocks in filesystem */ -+ int64_t f_bavail; /* free blocks avail to non-superuser */ -+ uint64_t f_files; /* total file nodes in filesystem */ -+ int64_t f_ffree; /* free nodes avail to non-superuser */ -+ uint64_t f_syncwrites; /* count of sync writes since mount */ -+ uint64_t f_asyncwrites; /* count of async writes since mount */ -+ uint64_t f_syncreads; /* count of sync reads since mount */ -+ uint64_t f_asyncreads; /* count of async reads since mount */ -+ uint64_t f_spare[10]; /* unused spare */ -+ uint32_t f_namemax; /* maximum filename length */ -+ uid_t f_owner; /* user that mounted the filesystem */ -+ target_fsid_t f_fsid; /* filesystem id */ -+ char f_charspare[80]; /* spare string space */ -+ char f_fstypename[TARGET_MFSNAMELEN]; /* filesys type name */ -+ char f_mntfromname[TARGET_MNAMELEN]; /* mount filesystem */ -+ char f_mntonname[TARGET_MNAMELEN]; /* dir on which mounted*/ -+}; -+ -+/* -+ * File identifier. -+ * These are unique per filesystem on a single machine. -+ */ -+#define TARGET_MAXFIDSZ 16 -+ -+struct target_fid { -+ u_short fid_len; /* len of data in bytes */ -+ u_short fid_data0; /* force longword align */ -+ char fid_data[TARGET_MAXFIDSZ]; /* data (variable len) */ -+}; -+ -+/* -+ * Generic file handle -+ */ -+struct target_fhandle { -+ target_fsid_t fh_fsid; /* Filesystem id of mount point */ -+ struct target_fid fh_fid; /* Filesys specific id */ -+}; -+typedef struct target_fhandle target_fhandle_t; -+ -+ -+/* -+ * uuidgen. From sys/uuid.h. -+ */ -+ -+#define TARGET_UUID_NODE_LEN 6 -+ -+struct target_uuid { -+ uint32_t time_low; -+ uint16_t time_mid; -+ uint16_t time_hi_and_version; -+ uint8_t clock_seq_hi_and_reserved; -+ uint8_t clock_seq_low; -+ uint8_t node[TARGET_UUID_NODE_LEN]; -+}; -+ -+/* -+ * ntp. From sys/timex.h. -+ */ -+ -+struct target_ntptimeval { -+ struct target_freebsd_timespec time; -+ abi_long maxerror; -+ abi_long esterror; -+ abi_long tai; -+ int32_t time_state; -+}; -+ -+struct target_timex { -+ uint32_t modes; -+ abi_long offset; -+ abi_long freq; -+ abi_long maxerror; -+ abi_long esterror; -+ int32_t status; -+ abi_long constant; -+ abi_long precision; -+ abi_long tolerance; -+ -+ abi_long ppsfreq; -+ abi_long jitter; -+ int32_t shift; -+ abi_long stabil; -+ abi_long jitcnt; -+ abi_long calcnt; -+ abi_long errcnt; -+ abi_long stbcnt; -+}; -+ -+/* -+ * sched.h From sched.h -+ */ -+ -+struct target_sched_param { -+ int32_t sched_priority; -+}; diff --git a/emulators/qemu-devel/files/patch-z3-bsd-user-8fix b/emulators/qemu-devel/files/patch-z3-bsd-user-8fix deleted file mode 100644 index d8ad10af8fd1..000000000000 --- a/emulators/qemu-devel/files/patch-z3-bsd-user-8fix +++ /dev/null @@ -1,61 +0,0 @@ ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -17,6 +17,18 @@ - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ -+ -+#if defined(__FreeBSD__) -+#include <sys/param.h> -+#endif -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version < 900000 -+#define st_atim st_atimespec -+#define st_ctim st_ctimespec -+#define st_mtim st_mtimespec -+#define st_birthtim st_birthtimespec -+#endif -+ - #include <stdlib.h> - #include <stdio.h> - #include <stdint.h> -@@ -1519,9 +1533,11 @@ do_setsockopt(int sockfd, int level, int - optname = SO_ERROR; - break; - -+#ifdef SO_USER_COOKIE - case TARGET_SO_USER_COOKIE: - optname = SO_USER_COOKIE; - break; -+#endif - - default: - goto unimplemented; -@@ -2091,9 +2107,11 @@ do_fork(CPUArchState *env, int num, int - ret = rfork(flags); - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_FREEBSD_NR_pdfork: - ret = pdfork(&fd, flags); - break; -+#endif - - default: - ret = -TARGET_ENOSYS; -@@ -3499,6 +3517,7 @@ do_stat: - unlock_user(p, arg1, 0); - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_FREEBSD_NR_setloginclass: - if (!(p = lock_user_string(arg1))) - goto efault; -@@ -3512,6 +3531,7 @@ do_stat: - ret = get_errno(getloginclass(p, arg2)); - unlock_user(p, arg1, 0); - break; -+#endif - - case TARGET_FREEBSD_NR_getrusage: - { diff --git a/emulators/qemu-devel/files/patch-z3b-bsd-user-8fix b/emulators/qemu-devel/files/patch-z3b-bsd-user-8fix deleted file mode 100644 index 7a4de89f5a5b..000000000000 --- a/emulators/qemu-devel/files/patch-z3b-bsd-user-8fix +++ /dev/null @@ -1,34 +0,0 @@ ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -3890,6 +3890,7 @@ do_stat: - break; - #endif - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_FREEBSD_NR_pdkill: - ret = get_errno(pdkill(arg1, target_to_host_signal(arg2))); - break; -@@ -3903,6 +3904,7 @@ do_stat: - goto efault; - } - break; -+#endif - - case TARGET_FREEBSD_NR_sigaction: - { -@@ -4176,6 +4178,7 @@ do_stat: - break; - #endif - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_FREEBSD_NR_posix_fallocate: - { - off_t offset = arg2, len = arg3; -@@ -4192,6 +4195,7 @@ do_stat: - ret = get_errno(posix_fallocate(arg1, offset, len)); - } - break; -+#endif - - #ifdef TARGET_FREEBSD_posix_openpt - case TARGET_FREEBSD_posix_openpt: diff --git a/emulators/qemu-devel/files/patch-z3c-bsd-user-8fix b/emulators/qemu-devel/files/patch-z3c-bsd-user-8fix deleted file mode 100644 index 20e2003aa488..000000000000 --- a/emulators/qemu-devel/files/patch-z3c-bsd-user-8fix +++ /dev/null @@ -1,12 +0,0 @@ ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -54,7 +54,9 @@ - #include <sys/socket.h> - #ifdef __FreeBSD__ - #include <sys/regression.h> -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - #include <sys/procdesc.h> -+#endif - #include <sys/ucontext.h> - #include <sys/thr.h> - #include <sys/rtprio.h> diff --git a/emulators/qemu-devel/files/patch-z3d-bsd-user-8fix b/emulators/qemu-devel/files/patch-z3d-bsd-user-8fix deleted file mode 100644 index 1e3201a4f6bc..000000000000 --- a/emulators/qemu-devel/files/patch-z3d-bsd-user-8fix +++ /dev/null @@ -1,47 +0,0 @@ ---- qemu-1.4.0/bsd-user/syscall.c.orig -+++ qemu-1.4.0/bsd-user/syscall.c -@@ -62,7 +62,11 @@ - #include <sys/rtprio.h> - #include <sys/umtx.h> - #include <sys/uuid.h> -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - #include <sys/_termios.h> -+#else -+#include <sys/termios.h> -+#endif - #include <sys/ttycom.h> - #include <sys/reboot.h> - #include <sys/timex.h> -@@ -6383,6 +6387,7 @@ abi_long do_freebsd_syscall(void *cpu_en - val, NULL, NULL)); - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_UMTX_OP_NWAKE_PRIVATE: - if (! access_ok(VERIFY_READ, obj, - val * sizeof(uint32_t))) -@@ -6390,7 +6395,7 @@ abi_long do_freebsd_syscall(void *cpu_en - ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE, - val, NULL, NULL)); - break; -- -+#endif - - case TARGET_UMTX_OP_RW_RDLOCK: - if (target_ts) { -@@ -6425,6 +6430,7 @@ abi_long do_freebsd_syscall(void *cpu_en - break; - #endif - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_UMTX_OP_SEM_WAIT: - /* XXX Assumes struct _usem is opauque to the user */ - if (! access_ok(VERIFY_WRITE, obj, -@@ -6447,6 +6453,7 @@ abi_long do_freebsd_syscall(void *cpu_en - ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAKE, - val, NULL, NULL)); - break; -+#endif - - default: - ret = -TARGET_EINVAL; diff --git a/emulators/qemu-devel/files/patch-z4-bsd-user-elfload b/emulators/qemu-devel/files/patch-z4-bsd-user-elfload deleted file mode 100644 index f1c4ae31ed17..000000000000 --- a/emulators/qemu-devel/files/patch-z4-bsd-user-elfload +++ /dev/null @@ -1,26 +0,0 @@ ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -812,8 +812,9 @@ static abi_ulong setup_arg_pages(abi_ulo - * Add argv strings. Note that the argv[] vectors are added by - * loader_build_argptr() - */ -- i = bprm->argc; -- while (i-- > 0) { -+ // i = bprm->argc; -+ // while (i-- > 0) { -+ for (i = 0; i < bprm->argc; ++i) { - size_t len = strlen(bprm->argv[i]) + 1; - /* XXX - check return value of memcpy_to_target(). */ - memcpy_to_target(destp, bprm->argv[i], len); -@@ -826,8 +827,9 @@ static abi_ulong setup_arg_pages(abi_ulo - * Add env strings. Note that the envp[] vectors are added by - * loader_build_argptr(). - */ -- i = bprm->envc; -- while(i-- > 0) { -+ // i = bprm->envc; -+ // while(i-- > 0) { -+ for (i = 0; i < bprm->envc; ++i) { - size_t len = strlen(bprm->envp[i]) + 1; - /* XXX - check return value of memcpy_to_target(). */ - memcpy_to_target(destp, bprm->envp[i], len); diff --git a/emulators/qemu-devel/files/patch-z6-bsd-user-usrstack1 b/emulators/qemu-devel/files/patch-z6-bsd-user-usrstack1 deleted file mode 100644 index df26a50388f1..000000000000 --- a/emulators/qemu-devel/files/patch-z6-bsd-user-usrstack1 +++ /dev/null @@ -1,18 +0,0 @@ ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -377,6 +377,15 @@ static abi_long do_freebsd_sysctl(abi_ul - *q++ = tswap32(*p); - oidfmt(snamep, namelen, NULL, &kind); - /* XXX swap hnewp */ -+#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32 -+ /* XXX there may be more sysctls that differ */ -+ if (namelen == 2 && -+ snamep[0] == CTL_KERN && snamep[1] == KERN_USRSTACK && -+ holdlen && holdlen == 4 && hnewp == NULL) { -+ (*(uint32_t *)holdp) = 0xfffff000U; -+ ret = 0; -+ } else -+#endif - ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen)); - if (!ret) - sysctl_oldcvt(holdp, holdlen, kind); diff --git a/emulators/qemu-devel/files/patch-z7-bsd-user-tls1-cognet b/emulators/qemu-devel/files/patch-z7-bsd-user-tls1-cognet deleted file mode 100644 index f3aac00b4908..000000000000 --- a/emulators/qemu-devel/files/patch-z7-bsd-user-tls1-cognet +++ /dev/null @@ -1,171 +0,0 @@ ---- oldqemu-1.3.0/bsd-user/syscall.c 2012-12-13 23:51:09.000000000 +0100 -+++ qemu-1.3.0/bsd-user/syscall.c 2012-12-13 23:46:55.000000000 +0100 -@@ -258,6 +258,16 @@ static abi_long do_freebsd_sysarch(void - #ifdef TARGET_ARM - static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - { -+ abi_ulong val; -+ -+ switch (op) { -+ case TARGET_FREEBSD_ARM_SET_TP: -+ if (get_user(val, parms, abi_ulong)) -+ return -TARGET_EINVAL; -+ cpu_set_tls(env, val); -+ return 0; -+ } -+ - return -TARGET_EINVAL; - } - #endif ---- oldqemu-1.3.0/bsd-user/elfload.c 2012-12-13 23:51:09.000000000 +0100 -+++ qemu-1.3.0/bsd-user/elfload.c 2012-12-13 23:50:14.000000000 +0100 -@@ -948,10 +948,8 @@ static abi_ulong create_elf_tables(abi_u - * Force 16 byte _final_ alignment here for generality. - */ - sp = sp &~ (abi_ulong)15; --#ifdef __FreeBSD__ -- size = 0; --#else - size = (DLINFO_ITEMS + 1) * 2; -+#ifndef __FreeBSD__ - if (k_platform) - size += 2; - #ifdef DLINFO_ARCH_ITEMS -@@ -964,7 +962,6 @@ static abi_ulong create_elf_tables(abi_u - if (size & 15) - sp -= 16 - (size & 15); - --#ifndef __FreeBSD__ - /* This is correct because Linux defines - * elf_addr_t as Elf32_Off / Elf64_Off - */ -@@ -989,8 +986,10 @@ static abi_ulong create_elf_tables(abi_u - NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); - NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); - NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); -+#ifndef __FreeBSD__ - if (k_platform) - NEW_AUX_ENT(AT_PLATFORM, u_platform); -+#endif - #ifdef ARCH_DLINFO - /* - * ARCH_DLINFO must come last so platform specific code can enforce -@@ -999,7 +998,6 @@ static abi_ulong create_elf_tables(abi_u - ARCH_DLINFO; - #endif - #undef NEW_AUX_ENT --#endif /* ! __FreeBSD__ */ - - sp = loader_build_argptr(envc, argc, sp, p, !ibcs); - return sp; ---- oldqemu-1.3.0/bsd-user/main.c 2012-12-13 23:51:09.000000000 +0100 -+++ qemu-1.3.0/bsd-user/main.c 2012-12-13 23:01:30.000000000 +0100 -@@ -392,6 +392,84 @@ void cpu_loop(CPUX86State *env) - #ifdef TARGET_ARM - // #define DEBUG_ARM - -+static int do_strex(CPUARMState *env) -+{ -+ uint32_t val; -+ int size; -+ int rc = 1; -+ int segv = 0; -+ uint32_t addr; -+ start_exclusive(); -+ addr = env->exclusive_addr; -+ if (addr != env->exclusive_test) { -+ goto fail; -+ } -+ size = env->exclusive_info & 0xf; -+ switch (size) { -+ case 0: -+ segv = get_user_u8(val, addr); -+ break; -+ case 1: -+ segv = get_user_u16(val, addr); -+ break; -+ case 2: -+ case 3: -+ segv = get_user_u32(val, addr); -+ break; -+ default: -+ abort(); -+ } -+ if (segv) { -+ env->cp15.c6_data = addr; -+ goto done; -+ } -+ if (val != env->exclusive_val) { -+ goto fail; -+ } -+ if (size == 3) { -+ segv = get_user_u32(val, addr + 4); -+ if (segv) { -+ env->cp15.c6_data = addr + 4; -+ goto done; -+ } -+ if (val != env->exclusive_high) { -+ goto fail; -+ } -+ } -+ val = env->regs[(env->exclusive_info >> 8) & 0xf]; -+ switch (size) { -+ case 0: -+ segv = put_user_u8(val, addr); -+ break; -+ case 1: -+ segv = put_user_u16(val, addr); -+ break; -+ case 2: -+ case 3: -+ segv = put_user_u32(val, addr); -+ break; -+ } -+ if (segv) { -+ env->cp15.c6_data = addr; -+ goto done; -+ } -+ if (size == 3) { -+ val = env->regs[(env->exclusive_info >> 12) & 0xf]; -+ segv = put_user_u32(val, addr + 4); -+ if (segv) { -+ env->cp15.c6_data = addr + 4; -+ goto done; -+ } -+ } -+ rc = 0; -+fail: -+ env->regs[15] += 4; -+ env->regs[(env->exclusive_info >> 4) & 0xf] = rc; -+done: -+ end_exclusive(); -+ return segv; -+} -+ - void cpu_loop(CPUARMState *env) - { - int trapnr; -@@ -622,6 +700,7 @@ void cpu_loop(CPUARMState *env) - if (do_kernel_trap(env)) - goto error; - break; -+#endif - case EXCP_STREX: - if (do_strex(env)) { - addr = env->cp15.c6_data; -@@ -629,7 +708,6 @@ void cpu_loop(CPUARMState *env) - } - break; - error: --#endif - default: - fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", - trapnr); ---- oldqemu-1.3.0/bsd-user/arm/syscall.h 2012-12-13 23:51:09.000000000 +0100 -+++ qemu-1.3.0/bsd-user/arm/syscall.h 2012-12-13 23:45:22.000000000 +0100 -@@ -21,3 +21,5 @@ struct target_pt_regs { - #define ARM_r0 uregs[0] - - #define ARM_SYSCALL_BASE 0 /* XXX: FreeBSD only */ -+ -+#define TARGET_FREEBSD_ARM_SET_TP 2 diff --git a/emulators/qemu-devel/files/patch-z7b-bsd-user-tls2 b/emulators/qemu-devel/files/patch-z7b-bsd-user-tls2 deleted file mode 100644 index 81dc689b6869..000000000000 --- a/emulators/qemu-devel/files/patch-z7b-bsd-user-tls2 +++ /dev/null @@ -1,13 +0,0 @@ ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -266,9 +268,7 @@ static abi_long do_freebsd_sysarch(void - - switch (op) { - case TARGET_FREEBSD_ARM_SET_TP: -- if (get_user(val, parms, abi_ulong)) -- return -TARGET_EINVAL; -- cpu_set_tls(env, val); -+ cpu_set_tls(env, parms); - return 0; - } - diff --git a/emulators/qemu-devel/files/patch-z8-bsd-user-unref b/emulators/qemu-devel/files/patch-z8-bsd-user-unref deleted file mode 100644 index 6f9b0f96617a..000000000000 --- a/emulators/qemu-devel/files/patch-z8-bsd-user-unref +++ /dev/null @@ -1,11 +0,0 @@ ---- qemu-1.4.0/bsd-user/syscall.c.orig -+++ qemu-1.4.0/bsd-user/syscall.c -@@ -2418,7 +2418,7 @@ do_thr_exit(CPUArchState *cpu_env, abi_u - } - - thread_env = NULL; -- object_delete(OBJECT(ENV_GET_CPU(cpu_env))); -+ object_unref(OBJECT(ENV_GET_CPU(cpu_env))); - g_free(ts); - pthread_exit(NULL); - } diff --git a/emulators/qemu-devel/files/patch-z9-bsd-user-sson003a b/emulators/qemu-devel/files/patch-z9-bsd-user-sson003a deleted file mode 100644 index 3a8887d6c98a..000000000000 --- a/emulators/qemu-devel/files/patch-z9-bsd-user-sson003a +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/bsd-user/freebsd/ioctl.h b/bsd-user/freebsd/ioctl.h -index 67c5583..f83f6c1 100644 ---- a/bsd-user/freebsd/ioctl.h -+++ b/bsd-user/freebsd/ioctl.h -@@ -8,8 +8,8 @@ IOCTL(TIOCSBRK, IOC_, TYPE_NULL) - IOCTL(TIOCCBRK, IOC_, TYPE_NULL) - IOCTL(TIOCSDTR, IOC_, TYPE_NULL) - IOCTL(TIOCCDTR, IOC_, TYPE_NULL) --IOCTL(TIOCGPGRP, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCSPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) - IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) - IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) - IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -diff --git a/bsd-user/main.c b/bsd-user/main.c -index d9a0ecd..7cc77aa 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -1907,7 +1907,7 @@ int main(int argc, char **argv) - env->hflags |= MIPS_HFLAG_M16; - } - #if defined(TARGET_MIPS64) -- env->hflags |= MIPS_HFLAG_UX; -+ env->hflags |= MIPS_HFLAG_UX | MIPS_HFLAG_64; - #endif - } - #else -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 581a31f..a40d7ce 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -278,7 +278,6 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - #ifdef TARGET_ARM - static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - { -- abi_ulong val; - - switch (op) { - case TARGET_FREEBSD_ARM_SET_TP: diff --git a/emulators/qemu-devel/files/patch-z9b-bsd-user-sson003b b/emulators/qemu-devel/files/patch-z9b-bsd-user-sson003b deleted file mode 100644 index 68d86a69a347..000000000000 --- a/emulators/qemu-devel/files/patch-z9b-bsd-user-sson003b +++ /dev/null @@ -1,332 +0,0 @@ -diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h -index 0427244..24dca00 100644 ---- a/bsd-user/arm/target_vmparam.h -+++ b/bsd-user/arm/target_vmparam.h -@@ -20,6 +20,10 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 0c48f5a..f5f652f 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -715,9 +715,13 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - /* Create enough stack to hold everything. If we don't use - * it for args, we'll use it for something else... - */ -+#ifdef TARGET_STACK_SIZE -+ size = TARGET_STACK_SIZE; -+#else - size = x86_stack_size; - if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) - size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; -+#endif - - #ifdef TARGET_USRSTACK - stack_base = TARGET_USRSTACK - size; -@@ -738,7 +742,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - - #if defined(__FreeBSD__) - /* -- * The inital FreeBSD stack looks like follows: -+ * The inital FreeBSD stack is as follows: - * (see kern/kern_exec.c exec_copyout_strings() ) - * - * Hi Address -> char **ps_argvstr (struct ps_strings for ps, w, etc.) -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index bcdd931..c66dcfa 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -118,6 +118,7 @@ - { TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL }, - { TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL }, -diff --git a/bsd-user/i386/target_vmparam.h b/bsd-user/i386/target_vmparam.h -index 8fc98d5..ea7546c 100644 ---- a/bsd-user/i386/target_vmparam.h -+++ b/bsd-user/i386/target_vmparam.h -@@ -19,6 +19,10 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/main.c b/bsd-user/main.c -index 7cc77aa..32bd3e5 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -855,7 +855,9 @@ void cpu_loop(CPUARMState *env) - goto do_segv; - } - break; -+#if 0 - error: -+#endif - default: - fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", - trapnr); -diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h -index 9fca7f3..8abc26c 100644 ---- a/bsd-user/mips/target_vmparam.h -+++ b/bsd-user/mips/target_vmparam.h -@@ -21,6 +21,10 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h -index 47c2267..55ed254 100644 ---- a/bsd-user/mips64/target_vmparam.h -+++ b/bsd-user/mips64/target_vmparam.h -@@ -20,6 +20,10 @@ struct target_ps_strings { - - #define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) - -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/sparc/target_vmparam.h b/bsd-user/sparc/target_vmparam.h -index 9494c46..82c29ed 100644 ---- a/bsd-user/sparc/target_vmparam.h -+++ b/bsd-user/sparc/target_vmparam.h -@@ -1,8 +1,6 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - --#define TARGET_USRSTACK 0 -- - #ifdef __FreeBSD__ - struct target_ps_strings { - abi_ulong ps_argvstr; -@@ -14,9 +12,22 @@ struct target_ps_strings { - #define TARGET_SPACE_USRSPACE 4096 - #define TARGET_ARG_MAX 262144 - -+/* XXX */ -+#define TARGET_VM_MAXUSER_ADDRESS (0xc0000000 - (512 * 1024 * 1024)) -+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS -+ - #define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) - - #define TARGET_SZSIGCODE 0 -+ -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ -+#else -+ -+#define TARGET_USRSTACK 0 -+ - #endif /* __FreeBSD__ */ - - #endif /* _TARGET_VMPARAM_H_ */ -diff --git a/bsd-user/sparc64/target_vmparam.h b/bsd-user/sparc64/target_vmparam.h -index 12af063..7f2b464 100644 ---- a/bsd-user/sparc64/target_vmparam.h -+++ b/bsd-user/sparc64/target_vmparam.h -@@ -21,6 +21,10 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index a40d7ce..8565ae8 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -409,19 +409,44 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++) - *q++ = tswap32(*p); - oidfmt(snamep, namelen, NULL, &kind); -- /* XXX swap hnewp */ --#if HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32 -- /* XXX there may be more sysctls that differ */ -- if (namelen == 2 && -- snamep[0] == CTL_KERN && snamep[1] == KERN_USRSTACK && -- holdlen && holdlen == 4 && hnewp == NULL) { -- (*(uint32_t *)holdp) = 0xfffff000U; -- ret = 0; -- } else -+ -+ /* Handle some arch/emulator dependent sysctl()'s here. */ -+ if (CTL_KERN == snamep[0]) { -+ switch(snamep[1]) { -+ case KERN_USRSTACK: -+#if defined(TARGET_ARM) && HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32 -+ (*(uint32_t *)holdp) = 0xfffff000U; -+ holdlen = sizeof(uint32_t); -+ ret = 0; -+#elif TARGET_USRSTACK != 0 -+ (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK); -+ holdlen = sizeof(abi_ulong); -+ ret = 0; -+#else -+ ret = -TARGET_ENOENT; -+#endif -+ goto out; -+ -+ case KERN_PS_STRINGS: -+#if defined(TARGET_PS_STRINGS) -+ (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS); -+ holdlen = sizeof(abi_ulong); -+ ret = 0; -+#else -+ ret = -TARGET_ENOENT; - #endif -+ goto out; -+ -+ default: -+ break; -+ } -+ } -+ - ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen)); - if (!ret) - sysctl_oldcvt(holdp, holdlen, kind); -+ -+out: - put_user_ual(holdlen, oldlenp); - unlock_user(hnamep, namep, 0); - unlock_user(holdp, oldp, holdlen); -@@ -3293,6 +3318,47 @@ host_to_target_fhandle(abi_ulong target_addr, fhandle_t *host_fh) - } - - static inline abi_long -+target_to_host_rtprio(struct rtprio *host_rtp, abi_ulong target_addr) -+{ -+ struct target_rtprio *target_rtp; -+ -+ if (!lock_user_struct(VERIFY_READ, target_rtp, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ __get_user(host_rtp->type, &target_rtp->type); -+ __get_user(host_rtp->prio, &target_rtp->prio); -+ unlock_user_struct(target_rtp, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_rtprio(abi_ulong target_addr, struct rtprio *host_rtp) -+{ -+ struct target_rtprio *target_rtp; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_rtp, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ __put_user(host_rtp->type, &target_rtp->type); -+ __put_user(host_rtp->prio, &target_rtp->prio); -+ unlock_user_struct(target_rtp, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long -+do_rtprio_thread(int function, lwpid_t lwpid, abi_ulong target_addr) -+{ -+ int ret; -+ struct rtprio rtp; -+ -+ ret = target_to_host_rtprio(&rtp, target_addr); -+ if (0 == ret) -+ ret = get_errno(rtprio_thread(function, lwpid, &rtp)); -+ if (0 == ret) -+ ret = host_to_target_rtprio(target_addr, &rtp); -+ -+ return (ret); -+} -+ -+static inline abi_long - target_to_host_sched_param(struct sched_param *host_sp, abi_ulong target_addr) - { - struct target_sched_param *target_sp; -@@ -4617,12 +4683,17 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - struct target_rlimit *target_rlim; - struct rlimit rlim; - -- if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) -- goto efault; -- rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur); -- rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max); -- unlock_user_struct(target_rlim, arg2, 0); -- ret = get_errno(setrlimit(resource, &rlim)); -+ if (RLIMIT_STACK == resource) { -+ /* XXX We should, maybe, allow the stack size to shrink */ -+ ret = -TARGET_EPERM; -+ } else { -+ if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) -+ goto efault; -+ rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur); -+ rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max); -+ unlock_user_struct(target_rlim, arg2, 0); -+ ret = get_errno(setrlimit(resource, &rlim)); -+ } - } - break; - -@@ -4633,7 +4704,12 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - struct target_rlimit *target_rlim; - struct rlimit rlim; - -- ret = get_errno(getrlimit(resource, &rlim)); -+ /* Return the target stack size */ -+ if (RLIMIT_STACK == resource) { -+ rlim.rlim_cur = rlim.rlim_max = TARGET_STACK_SIZE; -+ ret = 0; -+ } else -+ ret = get_errno(getrlimit(resource, &rlim)); - if (!is_error(ret)) { - if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, - 0)) -@@ -6148,7 +6224,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_rtprio_thread: -- ret = 0; -+ ret = do_rtprio_thread(arg1, arg2, arg3); - break; - - case TARGET_FREEBSD_NR_getcontext: -diff --git a/bsd-user/x86_64/target_vmparam.h b/bsd-user/x86_64/target_vmparam.h -index aa5e0e0..ff9f534 100644 ---- a/bsd-user/x86_64/target_vmparam.h -+++ b/bsd-user/x86_64/target_vmparam.h -@@ -20,6 +20,10 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - -+/* Make stack size large enough to hold everything. */ -+#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -+ MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -+ - #else - - #define TARGET_USRSTACK 0 diff --git a/emulators/qemu-devel/files/patch-z9c-bsd-user-sson003c b/emulators/qemu-devel/files/patch-z9c-bsd-user-sson003c deleted file mode 100644 index b80d91863a19..000000000000 --- a/emulators/qemu-devel/files/patch-z9c-bsd-user-sson003c +++ /dev/null @@ -1,2408 +0,0 @@ -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index f5f652f..8abb1dd 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -403,8 +403,11 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i - { - - regs->cp0_status = 2 << CP0St_KSU; -- regs->regs[25] = regs->cp0_epc = infop->entry; /* t9 = pc = entry */ -+ regs->regs[25] = regs->cp0_epc = infop->entry & ~3; /* t9 = pc = entry */ - regs->regs[4] = regs->regs[29] = infop->start_stack; /* a0 = sp = start_stack */ -+ regs->regs[5] = 0; /* a1 = 0 */ -+ regs->regs[6] = 0; /* a2 = 0 */ -+ regs->regs[7] = TARGET_PS_STRINGS; /* a3 = ps_strings */ - } - - #define USE_ELF_CORE_DUMP -@@ -765,7 +768,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - { - abi_ulong stack_hi_addr; - size_t execpath_len; -- abi_ulong destp; -+ abi_ulong destp, argvp, envp; - struct target_ps_strings ps_strs; - char canary[sizeof(abi_long) * 8]; - char execpath[PATH_MAX]; -@@ -808,6 +811,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - /* XXX - check return value of put_user_ual(). */ - put_user_ual(TARGET_PAGE_SIZE, p); - -+ argvp = p - TARGET_SPACE_USRSPACE; - p = destp = p - TARGET_SPACE_USRSPACE - TARGET_ARG_MAX; - - /* XXX should check strlen(argv and envp strings) < TARGET_ARG_MAX */ -@@ -816,31 +820,38 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - * Add argv strings. Note that the argv[] vectors are added by - * loader_build_argptr() - */ -+ envp = argvp + (bprm->argc + 2) * sizeof(abi_ulong); -+ ps_strs.ps_argvstr = tswapl(argvp); -+ ps_strs.ps_nargvstr = tswap32(bprm->argc); - // i = bprm->argc; - // while (i-- > 0) { - for (i = 0; i < bprm->argc; ++i) { - size_t len = strlen(bprm->argv[i]) + 1; - /* XXX - check return value of memcpy_to_target(). */ - memcpy_to_target(destp, bprm->argv[i], len); -+ put_user_ual(destp, argvp); -+ argvp += sizeof(abi_ulong); - destp += len; - } -- ps_strs.ps_argvstr = tswapl(destp); -- ps_strs.ps_nargvstr = tswap32(bprm->argc); -+ put_user_ual(0, argvp); - - /* - * Add env strings. Note that the envp[] vectors are added by - * loader_build_argptr(). - */ -+ ps_strs.ps_envstr = tswapl(envp); -+ ps_strs.ps_nenvstr = tswap32(bprm->envc); - // i = bprm->envc; - // while(i-- > 0) { - for (i = 0; i < bprm->envc; ++i) { - size_t len = strlen(bprm->envp[i]) + 1; - /* XXX - check return value of memcpy_to_target(). */ - memcpy_to_target(destp, bprm->envp[i], len); -+ put_user_ual(destp, envp); -+ envp += sizeof(abi_ulong); - destp += len; - } -- ps_strs.ps_envstr = tswapl(destp); -- ps_strs.ps_nenvstr = tswap32(bprm->envc); -+ put_user_ual(0, envp); - - /* XXX - check return value of memcpy_to_target(). */ - memcpy_to_target(stack_hi_addr - sizeof(ps_strs), &ps_strs, -@@ -1304,6 +1315,27 @@ static void load_symbols(struct elfhdr *hdr, int fd) - syminfos = s; - } - -+/* Check the elf header and see if this a target elf binary. */ -+int is_target_elf_binary(int fd) -+{ -+ uint8_t buf[128]; -+ struct elfhdr elf_ex; -+ -+ if (lseek(fd, 0L, SEEK_SET) < 0) -+ return (0); -+ if (read(fd, buf, sizeof(buf)) < 0) -+ return (0); -+ -+ elf_ex = *((struct elfhdr *)buf); -+ bswap_ehdr(&elf_ex); -+ -+ if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || -+ (! elf_check_arch(elf_ex.e_machine))) -+ return (0); -+ else -+ return (1); -+} -+ - int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info) - { -@@ -1424,13 +1456,10 @@ int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - /* JRP - Need to add X86 lib dir stuff here... */ - - if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || -- strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) { -+ strcmp(elf_interpreter,"/libexec/ld-elf.so.1") == 0) { - ibcs2_interpreter = 1; - } - --#if 0 -- printf("Using ELF interpreter %s\n", path(elf_interpreter)); --#endif - if (retval >= 0) { - retval = open(path(elf_interpreter), O_RDONLY); - if(retval >= 0) { -diff --git a/bsd-user/freebsd/filio.h b/bsd-user/freebsd/filio.h -new file mode 100644 -index 0000000..2269484 ---- /dev/null -+++ b/bsd-user/freebsd/filio.h -@@ -0,0 +1,27 @@ -+#ifndef _FREEBSD_FILIO_H_ -+#define _FREEBSD_FILIO_H_ -+ -+/* see sys/filio.h */ -+#define TARGET_FIOCLEX TARGET_IO('f', 1) -+#define TARGET_FIONCLEX TARGET_IO('f', 2) -+#define TARGET_FIONREAD TARGET_IOR('f', 127, int) -+#define TARGET_FIONBIO TARGET_IOW('f', 126, int) -+#define TARGET_FIOASYNC TARGET_IOW('f', 125, int) -+#define TARGET_FIOSETOWN TARGET_IOW('f', 124, int) -+#define TARGET_FIOGETOWN TARGET_IOR('f', 123, int) -+#define TARGET_FIODTYPE TARGET_IOR('f', 122, int) -+#define TARGET_FIOGETLBA TARGET_IOR('f', 121, int) -+ -+struct target_fiodgname_arg { -+ int32_t len; -+ abi_ulong buf; -+}; -+ -+#define TARGET_FIODGNAME TARGET_IOW('f', 120, \ -+ struct target_fiodgname_arg) -+#define TARGET_FIONWRITE TARGET_IOR('f', 119, int) -+#define TARGET_FIONSPACE TARGET_IOR('f', 118, int) -+#define TARGET_FIOSEEKDATA TARGET_IOWR('f', 97, off_t) -+#define TARGET_FIOSEEKHOLE TARGET_IOWR('f', 98, off_t) -+ -+#endif /* !_FREEBSD_FILIO_H_ */ -diff --git a/bsd-user/freebsd/ioctl.h b/bsd-user/freebsd/ioctl.h -deleted file mode 100644 -index f83f6c1..0000000 ---- a/bsd-user/freebsd/ioctl.h -+++ /dev/null -@@ -1,35 +0,0 @@ --#ifndef _FREEBSD_IOCTL_H_ --#define _FREEBSD_IOCTL_H_ -- --/* sys/ttycom.h tty(4) */ --IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) --IOCTL(TIOCSBRK, IOC_, TYPE_NULL) --IOCTL(TIOCCBRK, IOC_, TYPE_NULL) --IOCTL(TIOCSDTR, IOC_, TYPE_NULL) --IOCTL(TIOCCDTR, IOC_, TYPE_NULL) --IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) --IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) --IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) --IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) --IOCTL(TIOCSETAF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) --IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) --IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_CHAR)) --IOCTL(TIOCNOTTY, IOC_, TYPE_NULL) --IOCTL(TIOCSTOP, IOC_, TYPE_NULL) --IOCTL(TIOCSTART, IOC_, TYPE_NULL) --IOCTL(TIOCSCTTY, IOC_, TYPE_NULL) --IOCTL(TIOCDRAIN, IOC_, TYPE_NULL) --IOCTL(TIOCEXCL, IOC_, TYPE_NULL) --IOCTL(TIOCNXCL, IOC_, TYPE_NULL) --IOCTL(TIOCFLUSH, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) --IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) --IOCTL(TIOCCONS, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) --IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) --IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) -- --#endif -diff --git a/bsd-user/freebsd/ioctls.h b/bsd-user/freebsd/ioctls.h -new file mode 100644 -index 0000000..85d3c41 ---- /dev/null -+++ b/bsd-user/freebsd/ioctls.h -@@ -0,0 +1,47 @@ -+ -+/* sys/ttycom.h tty(4) */ -+IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCCBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCSDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCCDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_CHAR)) -+IOCTL(TIOCNOTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCSTOP, IOC_, TYPE_NULL) -+IOCTL(TIOCSTART, IOC_, TYPE_NULL) -+IOCTL(TIOCSCTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCDRAIN, IOC_, TYPE_NULL) -+IOCTL(TIOCEXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCNXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCFLUSH, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCCONS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) -+ -+/* sys/filio.h */ -+IOCTL(FIOCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOSETOWN, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETOWN, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODTYPE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETLBA, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODGNAME, IOC_R, MK_PTR(STRUCT_fiodgname_arg)) -+IOCTL(FIONWRITE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONSPACE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOSEEKDATA, IOC_RW, MK_PTR(TYPE_ULONG)) -+IOCTL(FIOSEEKHOLE, IOC_RW, MK_PTR(TYPE_ULONG)) -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index c66dcfa..8270c37 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -1,7 +1,19 @@ -+{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_set_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_set_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, - { TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL }, - { TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, -@@ -23,19 +35,34 @@ - { TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL }, - { TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL }, - { TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL }, - { TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL }, --{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL }, -@@ -65,7 +92,7 @@ - { TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL }, --{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL }, - { TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL }, - { TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL }, -@@ -74,6 +101,7 @@ - { TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL }, - { TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL }, -@@ -98,7 +126,9 @@ - { TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_pathconf, "pathconf", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL }, -@@ -162,7 +192,7 @@ - { TARGET_FREEBSD_NR_statfs, "statfs", "%s(\"%s\",%p)", NULL, NULL }, - { TARGET_FREEBSD_NR_symlink, "symlink", "%s(\"%s\",\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, print_sysarch, NULL }, - { TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_thr_create, "thr_create", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_thr_exit, "thr_exit", NULL, NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_types.h b/bsd-user/freebsd/syscall_types.h -index 6e43400..60b9288 100644 ---- a/bsd-user/freebsd/syscall_types.h -+++ b/bsd-user/freebsd/syscall_types.h -@@ -1,8 +1,7 @@ --#ifndef _FREEBSD_SYSCALL_TYPES_H_ --#define _FREEBSD_SYSCALL_TYPES_H_ - - STRUCT_SPECIAL(termios) - - STRUCT(winsize, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) - --#endif -+STRUCT(fiodgname_arg, TYPE_INT, TYPE_PTRVOID) -+ -diff --git a/bsd-user/main.c b/bsd-user/main.c -index 32bd3e5..bb614de 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -2,6 +2,7 @@ - * qemu user main - * - * Copyright (c) 2003-2008 Fabrice Bellard -+ * Copyright (c) 2012-2013 Stacey Son - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -25,6 +26,7 @@ - #include <machine/trap.h> - #include <sys/types.h> - #include <sys/mman.h> -+#include <sys/sysctl.h> - - #include "qemu.h" - #include "qemu-common.h" -@@ -58,6 +60,36 @@ enum BSDType bsd_type; - by remapping the process stack directly at the right place */ - unsigned long x86_stack_size = 512 * 1024; - -+static void save_proc_pathname(void); -+char qemu_proc_pathname[PATH_MAX]; -+ -+#ifdef __FreeBSD__ -+static void -+save_proc_pathname(void) -+{ -+ int mib[4]; -+ size_t len; -+ -+ mib[0] = CTL_KERN; -+ mib[1] = KERN_PROC; -+ mib[2] = KERN_PROC_PATHNAME; -+ mib[3] = -1; -+ -+ len = sizeof(qemu_proc_pathname); -+ -+ if (sysctl(mib, 4, qemu_proc_pathname, &len, NULL, 0)) -+ perror("sysctl"); -+} -+ -+#else -+ -+static void -+save_proc_pathname(void) -+{ -+} -+ -+#endif /* !__FreeBSD__ */ -+ - void gemu_log(const char *fmt, ...) - { - va_list ap; -@@ -1496,6 +1528,8 @@ int main(int argc, char **argv) - if (argc <= 1) - usage(); - -+ save_proc_pathname(); -+ - module_call_init(MODULE_INIT_QOM); - - if ((envlist = envlist_create()) == NULL) { -diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h -index e9c8a9f..c592136 100644 ---- a/bsd-user/mips64/target_signal.h -+++ b/bsd-user/mips64/target_signal.h -@@ -65,13 +65,7 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - abi_ulong frame_addr, struct target_sigaction *ka) - { - -- frame->sf_signum = sig; -- frame->sf_siginfo = 0; -- frame->sf_ucontext = 0; -- -- frame->sf_si.si_signo = sig; -- frame->sf_si.si_code = TARGET_SA_SIGINFO; -- frame->sf_si.si_addr = regs->CP0_BadVAddr; -+ /* frame->sf_si.si_addr = regs->CP0_BadVAddr; */ - - /* - * Arguments to signal handler: -@@ -86,6 +80,8 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - regs->active_tc.gpr[ 4] = sig; - regs->active_tc.gpr[ 5] = frame_addr + - offsetof(struct target_sigframe, sf_si); -+ regs->active_tc.gpr[ 6] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); - regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; - regs->active_tc.gpr[29] = frame_addr; - regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index d9c9934..110b54e 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -64,15 +64,15 @@ struct image_info { - - #define MAX_SIGQUEUE_SIZE 1024 - --struct sigqueue { -- struct sigqueue *next; -+struct qemu_sigqueue { -+ struct qemu_sigqueue *next; - target_siginfo_t info; - }; - - struct emulated_sigtable { - int pending; /* true if signal is pending */ -- struct sigqueue *first; -- struct sigqueue info; /* in order to always have memory for the -+ struct qemu_sigqueue *first; -+ struct qemu_sigqueue info; /* in order to always have memory for the - first signal, we put it here */ - }; - -@@ -95,8 +95,8 @@ typedef struct TaskState { - struct bsd_binprm *bprm; - - struct emulated_sigtable sigtab[TARGET_NSIG]; -- struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ -- struct sigqueue *first_free; /* first free siginfo queue entry */ -+ struct qemu_sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ -+ struct qemu_sigqueue *first_free; /* first free siginfo queue entry */ - int signal_pending; /* non zero if a signal may be pending */ - - uint8_t stack[0]; -@@ -146,6 +146,7 @@ int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); - int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); -+int is_target_elf_binary(int fd); - - void target_set_brk(abi_ulong new_brk); - abi_long do_brk(abi_ulong new_brk); -@@ -222,6 +223,7 @@ void mmap_fork_end(int child); - - /* main.c */ - extern unsigned long x86_stack_size; -+extern char qemu_proc_pathname[]; - - /* user access */ - -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index d56837b..29e8e12 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -77,7 +77,7 @@ static uint8_t host_to_target_signal_table[_NSIG] = { - [SIGUSR1] = TARGET_SIGUSR1, - [SIGUSR2] = TARGET_SIGUSR2, - #ifdef SIGTHR -- [SIGTHR] = TARGET_SIGTHR, -+ [SIGTHR + 3] = TARGET_SIGTHR, - #endif - /* [SIGLWP] = TARGET_SIGLWP, */ - #ifdef SIGLIBRT -@@ -207,9 +207,10 @@ target_to_host_sigset(sigset_t *d, const target_sigset_t *s) - static inline void - host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) - { -- int sig; -+ int sig, code; - - sig = host_to_target_signal(info->si_signo); -+ code = tswap32(info->si_code); /* XXX should have host_to_target_si_code() */ - tinfo->si_signo = sig; - tinfo->si_errno = info->si_errno; - tinfo->si_code = info->si_code; -@@ -222,11 +223,13 @@ host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) - if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || - SIGBUS == sig || SIGTRAP == sig) { - tinfo->_reason._fault._trapno = info->_reason._fault._trapno; -+ } - #ifdef SIGPOLL -- } else if (SIGPOLL == sig) { -+ if (SIGPOLL == sig) { - tinfo->_reason._poll._band = info->_reason._poll._band; -+ } - #endif -- } else { -+ if (SI_TIMER == code) { - tinfo->_reason._timer._timerid = info->_reason._timer._timerid; - tinfo->_reason._timer._overrun = info->_reason._timer._overrun; - } -@@ -235,8 +238,10 @@ host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) - static void - tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) - { -- int sig; -+ int sig, code; -+ - sig = info->si_signo; -+ code = info->si_code; - tinfo->si_signo = tswap32(sig); - tinfo->si_errno = tswap32(info->si_errno); - tinfo->si_code = tswap32(info->si_code); -@@ -247,11 +252,13 @@ tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) - SIGBUS == sig || SIGTRAP == sig) { - tinfo->_reason._fault._trapno = - tswap32(info->_reason._fault._trapno); -+ } - #ifdef SIGPOLL -- } else if (SIGPOLL == sig) { -+ if (SIGPOLL == sig) { - tinfo->_reason._poll._band = tswap32(info->_reason._poll._band); -+ } - #endif -- } else { -+ if (SI_TIMER == code) { - tinfo->_reason._timer._timerid = - tswap32(info->_reason._timer._timerid); - tinfo->_reason._timer._overrun = -@@ -286,11 +293,11 @@ core_dump_signal(int sig) - } - - /* Signal queue handling. */ --static inline struct sigqueue * -+static inline struct qemu_sigqueue * - alloc_sigqueue(CPUArchState *env) - { - TaskState *ts = env->opaque; -- struct sigqueue *q = ts->first_free; -+ struct qemu_sigqueue *q = ts->first_free; - - if (!q) - return (NULL); -@@ -299,7 +306,7 @@ alloc_sigqueue(CPUArchState *env) - } - - static inline void --free_sigqueue(CPUArchState *env, struct sigqueue *q) -+free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q) - { - - TaskState *ts = env->opaque; -@@ -372,7 +379,7 @@ queue_signal(CPUArchState *env, int sig, target_siginfo_t *info) - { - TaskState *ts = env->opaque; - struct emulated_sigtable *k; -- struct sigqueue *q, **pq; -+ struct qemu_sigqueue *q, **pq; - abi_ulong handler; - int queue; - -@@ -606,7 +613,7 @@ do_sigaction(int sig, const struct target_sigaction *act, - return (ret); - } - --#if defined(TARGET_MIPS) || defined(TARGET_SPARC64) -+#if defined(TARGET_MIPS64) /* || defined(TARGET_SPARC64) */ - - static inline abi_ulong - get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size) -@@ -629,8 +636,8 @@ get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size) - } - - /* compare to mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c sendsig() */ --static void setup_frame(int sig, struct target_sigaction *ka, -- target_sigset_t *set, CPUArchState *regs) -+static void setup_frame(int sig, int code, struct target_sigaction *ka, -+ target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *regs) - { - struct target_sigframe *frame; - abi_ulong frame_addr; -@@ -651,6 +658,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, - if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) - goto give_sigsegv; - -+ memset(frame, 0, sizeof(*frame)); - #if defined(TARGET_MIPS) - int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC : - TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC; -@@ -666,6 +674,58 @@ static void setup_frame(int sig, struct target_sigaction *ka, - goto give_sigsegv; - } - -+ if (tinfo) { -+ frame->sf_si.si_signo = tinfo->si_signo; -+ frame->sf_si.si_errno = tinfo->si_errno; -+ frame->sf_si.si_code = tinfo->si_code; -+ frame->sf_si.si_pid = tinfo->si_pid; -+ frame->sf_si.si_uid = tinfo->si_uid; -+ frame->sf_si.si_status = tinfo->si_status; -+ frame->sf_si.si_addr = tinfo->si_addr; -+ -+ if (TARGET_SIGILL == sig || TARGET_SIGFPE == sig || -+ TARGET_SIGSEGV == sig || TARGET_SIGBUS == sig || -+ TARGET_SIGTRAP == sig) -+ frame->sf_si._reason._fault._trapno = -+ tinfo->_reason._fault._trapno; -+ -+ /* -+ * If si_code is one of SI_QUEUE, SI_TIMER, SI_ASYNCIO, or -+ * SI_MESGQ, then si_value contains the application-specified -+ * signal value. Otherwise, the contents of si_value are -+ * undefined. -+ */ -+ if (SI_QUEUE == code || SI_TIMER == code || -+ SI_ASYNCIO == code || SI_MESGQ == code) { -+ frame->sf_si.si_value.sival_int = -+ tinfo->si_value.sival_int; -+ } -+ -+ if (SI_TIMER == code) { -+ frame->sf_si._reason._timer._timerid = -+ tinfo->_reason._timer._timerid; -+ frame->sf_si._reason._timer._overrun = -+ tinfo->_reason._timer._overrun; -+ } -+ -+#ifdef SIGPOLL -+ if (SIGPOLL == sig) { -+ frame->sf_si._reason._band = -+ tinfo->_reason._band; -+ } -+#endif -+ -+ frame->sf_signum = sig; -+ frame->sf_siginfo = (abi_ulong)&frame->sf_si; -+ frame->sf_ucontext = (abi_ulong)&frame->sf_uc; -+ -+ } else { -+ frame->sf_signum = sig; -+ frame->sf_siginfo = 0; -+ frame->sf_ucontext = 0; -+ } -+ -+ - if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) - goto give_sigsegv; - -@@ -866,8 +926,8 @@ get_sigframe(struct target_sigaction *ka, CPUSPARCState *regs, size_t frame_size - } - - /* compare to sparc64/sparc64/machdep.c sendsig() */ --static void setup_frame(int sig, struct target_sigaction *ka, -- target_sigset_t *set, CPUSPARCState *regs) -+static void setup_frame(int sig, int code, struct target_sigaction *ka, -+ target_sigset_t *set, target_siginfo_t *tinfo, CPUSPARCState *regs) - { - struct target_sigframe *frame; - abi_ulong frame_addr; -@@ -960,21 +1020,12 @@ badframe: - #else - - static void --setup_frame(int sig, struct target_sigaction *ka, target_sigset_t *set, -- CPUArchState *env) -+setup_frame(int sig, int code, struct target_sigaction *ka, target_sigset_t *set, -+ target_siginfo_t *tinfo, CPUArchState *env) - { - fprintf(stderr, "setup_frame: not implemented\n"); - } - --#if 0 --static void --setup_rt_frame(int sig, struct target_sigaction *ka, target_siginfo_t *info, -- target_sigset_t *set, CPUArchState *env) --{ -- fprintf(stderr, "setup_rt_frame: not implemented\n"); --} --#endif -- - long - do_sigreturn(CPUArchState *env, abi_ulong uc_addr) - { -@@ -1043,13 +1094,14 @@ signal_init(void) - void - process_pending_signals(CPUArchState *cpu_env) - { -- int sig; -+ int sig, code; - abi_ulong handler; - sigset_t set, old_set; - target_sigset_t target_old_set; -+ target_siginfo_t tinfo; - struct emulated_sigtable *k; - struct target_sigaction *sa; -- struct sigqueue *q; -+ struct qemu_sigqueue *q; - TaskState *ts = cpu_env->opaque; - - if (!ts->signal_pending) -@@ -1143,14 +1195,16 @@ handle_signal: - } - #endif - #endif -+ code = q->info.si_code; - /* prepare the stack frame of the virtual CPU */ --#if 0 /* XXX no rt for fbsd */ -- if (sa->sa_flags & TARGET_SA_SIGINFO) -- setup_rt_frame(sig, sa, &q->info, &target_old_set, -+ if (sa->sa_flags & TARGET_SA_SIGINFO) { -+ tswap_siginfo(&tinfo, &q->info); -+ setup_frame(sig, code, sa, &target_old_set, &tinfo, - cpu_env); -- else --#endif -- setup_frame(sig, sa, &target_old_set, cpu_env); -+ } else { -+ setup_frame(sig, code, sa, &target_old_set, NULL, -+ cpu_env); -+ } - if (sa->sa_flags & TARGET_SA_RESETHAND) - sa->_sa_handler = TARGET_SIG_DFL; - } -diff --git a/bsd-user/strace.c b/bsd-user/strace.c -index d73bbca..7f0f7bd 100644 ---- a/bsd-user/strace.c -+++ b/bsd-user/strace.c -@@ -4,7 +4,12 @@ - #include <sys/types.h> - #include <unistd.h> - #include <sys/syscall.h> -+#include <sys/ioccom.h> -+#include <ctype.h> - #include "qemu.h" -+#ifdef __FreeBSD__ -+#include "freebsd/syscall_nr.h" -+#endif - - int do_strace=0; - -@@ -23,6 +28,29 @@ struct syscallname { - */ - - static void -+print_sysctl(const struct syscallname *name, -+ abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ uint32_t i; -+ int32_t *namep; -+ -+ -+ gemu_log("%s({ ", name->name); -+ namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1); -+ if (namep) { -+ int32_t *p = namep; -+ -+ for(i = 0; i < (uint32_t)arg2; i++) -+ gemu_log("%d ", tswap32(*p++)); -+ unlock_user(namep, arg1, 0); -+ } -+ gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x" -+ TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")", -+ (uint32_t)arg2, arg3, arg4, arg5, arg6); -+} -+ -+static void - print_execve(const struct syscallname *name, - abi_long arg1, abi_long arg2, abi_long arg3, - abi_long arg4, abi_long arg5, abi_long arg6) -@@ -30,10 +58,18 @@ print_execve(const struct syscallname *name, - abi_ulong arg_ptr_addr; - char *s; - -- if (!(s = lock_user_string(arg1))) -- return; -- gemu_log("%s(\"%s\",{", name->name, s); -- unlock_user(s, arg1, 0); -+#ifdef __FreeBSD__ -+ if (TARGET_FREEBSD_NR_fexecve == name->nr) { -+ gemu_log("%s(%d,{", name->name, (int)arg1); -+ -+ } else -+#endif -+ { -+ if (!(s = lock_user_string(arg1))) -+ return; -+ gemu_log("%s(\"%s\",{", name->name, s); -+ unlock_user(s, arg1, 0); -+ } - - for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) { - abi_ulong *arg_ptr, arg_addr; -@@ -54,6 +90,54 @@ print_execve(const struct syscallname *name, - gemu_log("NULL})"); - } - -+static void -+print_ioctl(const struct syscallname *name, -+ abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ /* Decode the ioctl request */ -+ gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x" -+ TARGET_ABI_FMT_lx ", ...)", -+ -+ name->name, -+ (int)arg1, -+ (unsigned long)arg2, -+ arg2 & IOC_OUT ? "R" : "", -+ arg2 & IOC_IN ? "W" : "", -+ (unsigned)IOCGROUP(arg2), -+ isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?', -+ (int)arg2 & 0xFF, -+ (int)IOCPARM_LEN(arg2), -+ arg3); -+} -+ -+static void -+print_sysarch(const struct syscallname *name, -+ abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+#ifdef TARGET_MIPS -+ switch(arg1) { -+ case 1: -+ gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", -+ name->name, arg2); -+ break; -+ -+ case 2: -+ gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", -+ name->name, arg2); -+ break; -+ -+ default: -+ gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", -+ (int)arg1, arg2); -+ } -+#else -+ gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", " -+ TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4); -+#endif -+} -+ - /* - * Variants for the return value output function - */ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 8565ae8..74b5c86 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -2,7 +2,7 @@ - * BSD syscalls - * - * Copyright (c) 2003 - 2008 Fabrice Bellard -- * Copyright (c) 2012 Stacey Son <sson@FreeBSD.org> -+ * Copyright (c) 2012 - 2013 Stacey Son <sson@FreeBSD.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -33,6 +33,7 @@ - #include <stdio.h> - #include <stdint.h> - #include <stdarg.h> -+#include <stddef.h> - #include <string.h> - #include <dirent.h> - #include <errno.h> -@@ -68,8 +69,12 @@ - #include <sys/termios.h> - #endif - #include <sys/ttycom.h> -+#include <sys/filio.h> - #include <sys/reboot.h> - #include <sys/timex.h> -+#define _ACL_PRIVATE -+#include <sys/acl.h> -+#include <sys/extattr.h> - #include <kenv.h> - #include <pthread.h> - #include <machine/atomic.h> -@@ -87,6 +92,7 @@ - #include "qemu-common.h" - #ifdef __FreeBSD__ - #include "freebsd/ttycom.h" -+#include "freebsd/filio.h" - #endif - - -@@ -95,6 +101,70 @@ - static abi_ulong target_brk; - static abi_ulong target_original_brk; - -+static char *get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len); -+ -+#ifdef __FreeBSD__ -+#include <sys/queue.h> -+#include <sys/user.h> -+#include <libprocstat.h> -+ -+ -+/* -+ * Get the filename for the given file descriptor. -+ * Note that this may return NULL (fail) if no longer cached in the kernel. -+ */ -+static char * -+get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len) -+{ -+ unsigned int cnt; -+ struct procstat *procstat = NULL; -+ struct kinfo_proc *kipp = NULL; -+ struct filestat_list *head = NULL; -+ struct filestat *fst; -+ char *ret = NULL; -+ -+ procstat = procstat_open_sysctl(); -+ if (NULL == procstat) -+ goto out; -+ -+ kipp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt); -+ if (NULL == kipp) -+ goto out; -+ -+ head = procstat_getfiles(procstat, kipp, 0); -+ if (NULL == head) -+ goto out; -+ -+ STAILQ_FOREACH(fst, head, next) { -+ if (fd == fst->fs_fd) { -+ if (fst->fs_path != NULL) { -+ (void)strlcpy(filename, fst->fs_path, len); -+ ret = filename; -+ } -+ break; -+ } -+ } -+ -+out: -+ if (head != NULL) -+ procstat_freefiles(procstat, head); -+ if (kipp != NULL) -+ procstat_freeprocs(procstat, kipp); -+ if (procstat != NULL) -+ procstat_close(procstat); -+ return (ret); -+} -+ -+#else -+ -+static char * -+get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len) -+{ -+ return (NULL); -+} -+ -+#endif /* ! __FreeBSD__ */ -+ - static inline abi_long get_errno(abi_long ret) - { - if (ret == -1) -@@ -297,9 +367,9 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - - switch(op) { - case TARGET_MIPS_SET_TLS: -- if (get_user(mips_env->tls_value, parms, abi_ulong)) -- ret = -TARGET_EFAULT; -+ mips_env->tls_value = parms; - break; -+ - case TARGET_MIPS_GET_TLS: - if (put_user(mips_env->tls_value, parms, abi_ulong)) - ret = -TARGET_EFAULT; -@@ -386,24 +456,46 @@ static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind) - return 0; - } - -+/* -+ * Convert the undocmented name2oid sysctl data for the target. -+ */ -+static inline void -+sysctl_name2oid(uint32_t *holdp, size_t holdlen) -+{ -+ size_t i; -+ -+ for(i = 0; i < holdlen; i++) -+ holdp[i] = tswap32(holdp[i]); -+} -+ -+static inline void -+sysctl_oidfmt(uint32_t *holdp) -+{ -+ /* byte swap the kind */ -+ holdp[0] = tswap32(holdp[0]); -+} -+ - /* XXX this needs to be emulated on non-FreeBSD hosts... */ - static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong oldp, - abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen) - { - abi_long ret; -- void *hnamep, *holdp, *hnewp = NULL; -+ void *hnamep, *holdp = NULL, *hnewp = NULL; - size_t holdlen; - abi_ulong oldlen = 0; - int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i; - uint32_t kind = 0; -+ abi_ulong argv, argv0; -+ char *fullpath = NULL; - - if (oldlenp) -- get_user_ual(oldlen, oldlenp); -+ if (get_user_ual(oldlen, oldlenp)) -+ return -TARGET_EFAULT; - if (!(hnamep = lock_user(VERIFY_READ, namep, namelen, 1))) - return -TARGET_EFAULT; - if (newp && !(hnewp = lock_user(VERIFY_READ, newp, newlen, 1))) - return -TARGET_EFAULT; -- if (!(holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0))) -+ if (oldp && !(holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0))) - return -TARGET_EFAULT; - holdlen = oldlen; - for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++) -@@ -411,7 +503,8 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - oidfmt(snamep, namelen, NULL, &kind); - - /* Handle some arch/emulator dependent sysctl()'s here. */ -- if (CTL_KERN == snamep[0]) { -+ switch(snamep[0]) { -+ case CTL_KERN: - switch(snamep[1]) { - case KERN_USRSTACK: - #if defined(TARGET_ARM) && HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32 -@@ -437,17 +530,77 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - #endif - goto out; - -+ case KERN_PROC: -+ switch(snamep[2]) { -+ case KERN_PROC_PATHNAME: -+ if (get_user_ual(argv, TARGET_PS_STRINGS)) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ if (get_user_ual(argv0, argv)) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ -+ fullpath = realpath(g2h(argv0), NULL); -+ if (NULL == fullpath) -+ fullpath = (char *)g2h(argv0); -+ holdlen = strlen(fullpath) + 1; -+ if (holdp) { -+ if (oldlen < holdlen) { -+ ret = -TARGET_EINVAL; -+ goto out; -+ } -+ if (!access_ok(VERIFY_WRITE, argv0, -+ holdlen)) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ strlcpy(holdp, fullpath, oldlen); -+ } -+ ret = 0; -+ goto out; -+ -+ default: -+ break; -+ } -+ break; -+ - default: - break; - } -+ break; -+ -+ default: -+ break; - } - - ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen)); -- if (!ret) -- sysctl_oldcvt(holdp, holdlen, kind); -+ if (!ret && (holdp != 0 && holdlen != 0)) { -+ if (0 == snamep[0] && (3 == snamep[1] || 4 == snamep[1])) { -+ if (3 == snamep[1]) { -+ /* Handle the undocumented name2oid special case. */ -+ sysctl_name2oid(holdp, holdlen); -+ } else { -+ /* Handle oidfmt */ -+ sysctl_oidfmt(holdp); -+ } -+ } else { -+ sysctl_oldcvt(holdp, holdlen, kind); -+ } -+ } -+#ifdef DEBUG -+ else { -+ printf("sysctl(mib[0]=%d, mib[1]=%d, mib[3]=%d...) returned %d\n", -+ snamep[0], snamep[1], snamep[2], (int)ret); -+ } -+#endif - - out: -- put_user_ual(holdlen, oldlenp); -+ if (fullpath) -+ free(fullpath); -+ if (oldlenp) -+ put_user_ual(holdlen, oldlenp); - unlock_user(hnamep, namep, 0); - unlock_user(holdp, oldp, holdlen); - if (hnewp) -@@ -509,6 +662,24 @@ static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, - } - - static inline abi_long -+target_to_host_ip_mreq(struct ip_mreqn *mreqn, abi_ulong target_addr, -+ socklen_t len) -+{ -+ struct target_ip_mreqn *target_smreqn; -+ -+ target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1); -+ if (!target_smreqn) -+ return -TARGET_EFAULT; -+ mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr; -+ mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr; -+ if (len == sizeof(struct target_ip_mreqn)) -+ mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex); -+ unlock_user(target_smreqn, target_addr, 0); -+ -+ return (0); -+} -+ -+static inline abi_long - target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, - socklen_t len) - { -@@ -1554,11 +1725,62 @@ int_case: - } - break; - -+ case IPPROTO_TCP: -+ /* TCP options all take an 'int' value. */ -+ goto int_case; -+ -+ case IPPROTO_IP: -+ switch(optname) { -+ case IP_HDRINCL: -+ case IP_TOS: -+ case IP_TTL: -+ case IP_RECVOPTS: -+ case IP_RECVRETOPTS: -+ case IP_RECVDSTADDR: -+ -+ case IP_RETOPTS: -+ case IP_RECVTOS: -+ case IP_MULTICAST_TTL: -+ case IP_MULTICAST_LOOP: -+ case IP_PORTRANGE: -+ case IP_IPSEC_POLICY: -+ case IP_FAITH: -+ case IP_ONESBCAST: -+ case IP_BINDANY: -+ if (get_user_u32(len, optlen)) -+ return (-TARGET_EFAULT); -+ if (len < 0) -+ return (-TARGET_EINVAL); -+ lv = sizeof(lv); -+ ret = get_errno(getsockopt(sockfd, level, optname, -+ &val, &lv)); -+ if (ret < 0) -+ return (ret); -+ if (len < sizeof(int) && len > 0 && val >= 0 && -+ val < 255) { -+ len = 1; -+ if (put_user_u32(len, optlen) -+ || put_user_u8(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ } else { -+ if (len > sizeof(int)) -+ len = sizeof(int); -+ if (put_user_u32(len, optlen) -+ || put_user_u32(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ } -+ break; -+ -+ default: -+ goto unimplemented; -+ } -+ break; -+ - default: - unimplemented: - gemu_log("getsockopt level=%d optname=%d not yet supported\n", - level, optname); -- ret = -TARGET_EOPNOTSUPP; -+ ret = (-TARGET_EOPNOTSUPP); - break; - } - return (ret); -@@ -1569,10 +1791,67 @@ static abi_long - do_setsockopt(int sockfd, int level, int optname, abi_ulong optval_addr, - socklen_t optlen) - { -- int val; - abi_long ret; -+ int val; -+ struct ip_mreqn *ip_mreq; - - switch(level) { -+ case IPPROTO_TCP: -+ /* TCP options all take an 'int' value. */ -+ if (optlen < sizeof(uint32_t)) -+ return (-TARGET_EINVAL); -+ -+ if (get_user_u32(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ ret = get_errno(setsockopt(sockfd, level, optname, &val, -+ sizeof(val))); -+ break; -+ -+ case IPPROTO_IP: -+ switch (optname) { -+ case IP_HDRINCL:/* int; header is included with data */ -+ case IP_TOS: /* int; IP type of service and preced. */ -+ case IP_TTL: /* int; IP time to live */ -+ case IP_RECVOPTS: /* bool; receive all IP opts w/dgram */ -+ case IP_RECVRETOPTS: /* bool; receive IP opts for response */ -+ case IP_RECVDSTADDR: /* bool; receive IP dst addr w/dgram */ -+ case IP_MULTICAST_IF:/* u_char; set/get IP multicast i/f */ -+ case IP_MULTICAST_TTL:/* u_char; set/get IP multicast ttl */ -+ case IP_MULTICAST_LOOP:/*u_char;set/get IP multicast loopback */ -+ case IP_PORTRANGE: /* int; range to choose for unspec port */ -+ case IP_RECVIF: /* bool; receive reception if w/dgram */ -+ case IP_IPSEC_POLICY: /* int; set/get security policy */ -+ case IP_FAITH: /* bool; accept FAITH'ed connections */ -+ case IP_RECVTTL: /* bool; receive reception TTL w/dgram */ -+ val = 0; -+ if (optlen >= sizeof(uint32_t)) { -+ if (get_user_u32(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ } else if (optlen >= 1) { -+ if (get_user_u8(val, optval_addr)) -+ return (-TARGET_EFAULT); -+ } -+ ret = get_errno(setsockopt(sockfd, level, optname, -+ &val, sizeof(val))); -+ break; -+ -+ case IP_ADD_MEMBERSHIP: /*ip_mreq; add an IP group membership */ -+ case IP_DROP_MEMBERSHIP:/*ip_mreq; drop an IP group membership*/ -+ if (optlen < sizeof (struct target_ip_mreq) || -+ optlen > sizeof (struct target_ip_mreqn)) -+ return (-TARGET_EINVAL); -+ ip_mreq = (struct ip_mreqn *) alloca(optlen); -+ target_to_host_ip_mreq(ip_mreq, optval_addr, optlen); -+ ret = get_errno(setsockopt(sockfd, level, optname, -+ ip_mreq, optlen)); -+ break; -+ -+ default: -+ goto unimplemented; -+ } -+ break; -+ -+ - case TARGET_SOL_SOCKET: - switch (optname) { - /* Options with 'int' argument. */ -@@ -1730,13 +2009,15 @@ target_to_host_semarray(int semid, unsigned short **host_array, - if (ret == -1) - return (get_errno(ret)); - nsems = semid_ds.sem_nsems; -- *host_array = malloc(nsems * sizeof(unsigned short)); -+ *host_array = (unsigned short *)malloc(nsems * sizeof(unsigned short)); - array = lock_user(VERIFY_READ, target_addr, - nsems*sizeof(unsigned short), 1); -- if (!array) -+ if (!array) { -+ free(*host_array); - return (-TARGET_EFAULT); -+ } - for(i=0; i<nsems; i++) { -- __get_user((*host_array)[i], &array[i]); -+ (*host_array)[i] = array[i]; - } - unlock_user(array, target_addr, 0); - -@@ -1756,18 +2037,21 @@ host_to_target_semarray(int semid, abi_ulong target_addr, - semun.buf = &semid_ds; - - ret = semctl(semid, 0, IPC_STAT, semun); -- if (ret == -1) -+ if (ret == -1) { -+ free(*host_array); - return get_errno(ret); -+ } - - nsems = semid_ds.sem_nsems; -- -- array = lock_user(VERIFY_WRITE, target_addr, -+ array = (unsigned short *)lock_user(VERIFY_WRITE, target_addr, - nsems*sizeof(unsigned short), 0); -- if (!array) -+ if (!array) { -+ free(*host_array); - return (-TARGET_EFAULT); -+ } - - for(i=0; i<nsems; i++) { -- __put_user((*host_array)[i], &array[i]); -+ array[i] = (*host_array)[i]; - } - free(*host_array); - unlock_user(array, target_addr, 1); -@@ -1779,19 +2063,17 @@ static inline abi_long - target_to_host_ipc_perm(struct ipc_perm *host_ip, abi_ulong target_addr) - { - struct target_ipc_perm *target_ip; -- struct target_semid_ds *target_sd; - -- if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) -+ if (!lock_user_struct(VERIFY_READ, target_ip, target_addr, 1)) - return (-TARGET_EFAULT); -- target_ip = &(target_sd->sem_perm); -- host_ip->cuid = tswapal(target_ip->cuid); -- host_ip->cgid = tswapal(target_ip->cgid); -- host_ip->uid = tswapal(target_ip->uid); -- host_ip->gid = tswapal(target_ip->gid); -+ host_ip->cuid = tswap32(target_ip->cuid); -+ host_ip->cgid = tswap32(target_ip->cgid); -+ host_ip->uid = tswap32(target_ip->uid); -+ host_ip->gid = tswap32(target_ip->gid); - host_ip->mode = tswap16(target_ip->mode); - host_ip->seq = tswap16(target_ip->seq); - host_ip->key = tswapal(target_ip->key); -- unlock_user_struct(target_sd, target_addr, 0); -+ unlock_user_struct(target_ip, target_addr, 0); - - return (0); - } -@@ -1800,18 +2082,17 @@ static inline abi_long - host_to_target_ipc_perm(abi_ulong target_addr, struct ipc_perm *host_ip) - { - struct target_ipc_perm *target_ip; -- struct target_semid_ds *target_sd; -- if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ip, target_addr, 0)) - return (-TARGET_EFAULT); -- target_ip = &(target_sd->sem_perm); -- target_ip->cuid = tswapal(host_ip->cuid); -- target_ip->cgid = tswapal(host_ip->cgid); -- target_ip->uid = tswapal(host_ip->uid); -- target_ip->gid = tswapal(host_ip->gid); -+ target_ip->cuid = tswap32(host_ip->cuid); -+ target_ip->cgid = tswap32(host_ip->cgid); -+ target_ip->uid = tswap32(host_ip->uid); -+ target_ip->gid = tswap32(host_ip->gid); - target_ip->mode = tswap16(host_ip->mode); - target_ip->seq = tswap16(host_ip->seq); - target_ip->key = tswapal(host_ip->key); -- unlock_user_struct(target_sd, target_addr, 1); -+ unlock_user_struct(target_ip, target_addr, 1); - return (0); - } - -@@ -1822,11 +2103,12 @@ target_to_host_semid_ds(struct semid_ds *host_sd, abi_ulong target_addr) - - if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) - return (-TARGET_EFAULT); -- if (target_to_host_ipc_perm(&(host_sd->sem_perm), target_addr)) -+ if (target_to_host_ipc_perm(&(host_sd->sem_perm), (target_addr + -+ offsetof(struct target_semid_ds, sem_perm)) )) - return (-TARGET_EFAULT); - /* sem_base is not used by kernel for IPC_STAT/IPC_SET */ -- host_sd->sem_base = NULL; -- host_sd->sem_nsems = tswapal(target_sd->sem_nsems); -+ /* host_sd->sem_base = g2h(target_sd->sem_base); */ -+ host_sd->sem_nsems = tswap16(target_sd->sem_nsems); - host_sd->sem_otime = tswapal(target_sd->sem_otime); - host_sd->sem_ctime = tswapal(target_sd->sem_ctime); - unlock_user_struct(target_sd, target_addr, 0); -@@ -1840,10 +2122,13 @@ host_to_target_semid_ds(abi_ulong target_addr, struct semid_ds *host_sd) - - if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) - return (-TARGET_EFAULT); -- if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm))) -+ if (host_to_target_ipc_perm((target_addr + -+ offsetof(struct target_semid_ds, sem_perm)), -+ &(host_sd->sem_perm))) - return (-TARGET_EFAULT); - /* sem_base is not used by kernel for IPC_STAT/IPC_SET */ -- target_sd->sem_nsems = tswapal(host_sd->sem_nsems); -+ /* target_sd->sem_base = h2g((void *)host_sd->sem_base); */ -+ target_sd->sem_nsems = tswap16(host_sd->sem_nsems); - target_sd->sem_otime = tswapal(host_sd->sem_otime); - target_sd->sem_ctime = tswapal(host_sd->sem_ctime); - unlock_user_struct(target_sd, target_addr, 1); -@@ -1859,6 +2144,7 @@ do_semctl(int semid, int semnum, int cmd, union target_semun target_su) - unsigned short *array = NULL; - abi_long ret = -TARGET_EINVAL; - abi_long err; -+ abi_ulong target_addr; - - cmd &= 0xff; - -@@ -1872,24 +2158,28 @@ do_semctl(int semid, int semnum, int cmd, union target_semun target_su) - - case GETALL: - case SETALL: -- err = target_to_host_semarray(semid, &array, target_su.array); -+ if (get_user_ual(target_addr, (abi_ulong)target_su.array)) -+ return (-TARGET_EFAULT); -+ err = target_to_host_semarray(semid, &array, target_addr); - if (err) - return (err); - arg.array = array; - ret = get_errno(semctl(semid, semnum, cmd, arg)); -- err = host_to_target_semarray(semid, target_su.array, &array); -+ err = host_to_target_semarray(semid, target_addr, &array); - if (err) - return (err); - break; - - case IPC_STAT: - case IPC_SET: -- err = target_to_host_semid_ds(&dsarg, target_su.buf); -+ if (get_user_ual(target_addr, (abi_ulong)target_su.buf)) -+ return (-TARGET_EFAULT); -+ err = target_to_host_semid_ds(&dsarg, target_addr); - if (err) - return (err); - arg.buf = &dsarg; - ret = get_errno(semctl(semid, semnum, cmd, arg)); -- err = host_to_target_semid_ds(target_su.buf, &dsarg); -+ err = host_to_target_semid_ds(target_addr, &dsarg); - if (err) - return (err); - break; -@@ -3383,6 +3673,64 @@ host_to_target_sched_param(abi_ulong target_addr, struct sched_param *host_sp) - } - - static inline abi_long -+target_to_host_acl(struct acl *host_acl, abi_ulong target_addr) -+{ -+ uint32_t i; -+ struct target_acl *target_acl; -+ -+ if (!lock_user_struct(VERIFY_READ, target_acl, target_addr, 1)) -+ return (-TARGET_EFAULT); -+ -+ __get_user(host_acl->acl_maxcnt, &target_acl->acl_maxcnt); -+ __get_user(host_acl->acl_cnt, &target_acl->acl_cnt); -+ -+ for(i = 0; i < host_acl->acl_maxcnt; i++) { -+ __get_user(host_acl->acl_entry[i].ae_tag, -+ &target_acl->acl_entry[i].ae_tag); -+ __get_user(host_acl->acl_entry[i].ae_id, -+ &target_acl->acl_entry[i].ae_id); -+ __get_user(host_acl->acl_entry[i].ae_perm, -+ &target_acl->acl_entry[i].ae_perm); -+ __get_user(host_acl->acl_entry[i].ae_entry_type, -+ &target_acl->acl_entry[i].ae_entry_type); -+ __get_user(host_acl->acl_entry[i].ae_flags, -+ &target_acl->acl_entry[i].ae_flags); -+ } -+ -+ unlock_user_struct(target_acl, target_addr, 0); -+ return (0); -+} -+ -+static inline abi_long -+host_to_target_acl(abi_ulong target_addr, struct acl *host_acl) -+{ -+ uint32_t i; -+ struct target_acl *target_acl; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_acl, target_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ __put_user(host_acl->acl_maxcnt, &target_acl->acl_maxcnt); -+ __put_user(host_acl->acl_cnt, &target_acl->acl_cnt); -+ -+ for(i = 0; i < host_acl->acl_maxcnt; i++) { -+ __put_user(host_acl->acl_entry[i].ae_tag, -+ &target_acl->acl_entry[i].ae_tag); -+ __put_user(host_acl->acl_entry[i].ae_id, -+ &target_acl->acl_entry[i].ae_id); -+ __put_user(host_acl->acl_entry[i].ae_perm, -+ &target_acl->acl_entry[i].ae_perm); -+ __get_user(host_acl->acl_entry[i].ae_entry_type, -+ &target_acl->acl_entry[i].ae_entry_type); -+ __get_user(host_acl->acl_entry[i].ae_flags, -+ &target_acl->acl_entry[i].ae_flags); -+ } -+ -+ unlock_user_struct(target_acl, target_addr, 1); -+ return (0); -+} -+ -+static inline abi_long - do_sched_setparam(pid_t pid, abi_ulong target_sp_addr) - { - int ret; -@@ -3993,10 +4341,10 @@ static IOCTLEntry ioctl_entries[] = { - { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, - #define IOCTL_SPECIAL(cmd, access, dofn, ...) \ - { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } }, --#ifdef __FreeBSD__ --#include "freebsd/ioctl.h" -+#if defined(__FreeBSD__) -+#include "freebsd/ioctls.h" - #else --#warning No ioctl.h -+#warning No *bsd/ioctls.h - #endif - { 0, 0 }, - }; -@@ -4096,6 +4444,158 @@ do_ioctl(int fd, abi_long cmd, abi_long arg) - return (ret); - } - -+static inline abi_long -+freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, -+ abi_ulong guest_envp, int do_fexec) -+{ -+ char **argp, **envp, **qargp, **qarg1; -+ int argc, envc; -+ abi_ulong gp; -+ abi_ulong addr; -+ char **q; -+ int total_size = 0; -+ void *p; -+ abi_long ret; -+ -+ argc = 0; -+ for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) { -+ if (get_user_ual(addr, gp)) -+ return (-TARGET_EFAULT); -+ if (!addr) -+ break; -+ argc++; -+ } -+ envc = 0; -+ for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) { -+ if (get_user_ual(addr, gp)) -+ return (-TARGET_EFAULT); -+ if (!addr) -+ break; -+ envc++; -+ } -+ -+ qargp = argp = alloca((argc + 3) * sizeof(void *)); -+ /* save the first agrument for the emulator */ -+ *argp++ = (char *)getprogname(); -+ qarg1 = argp; -+ envp = alloca((envc + 1) * sizeof(void *)); -+ for (gp = guest_argp, q = argp; gp; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp)) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ if (!addr) -+ break; -+ if (!(*q = lock_user_string(addr))) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ total_size += strlen(*q) + 1; -+ } -+ *q = NULL; -+ -+ for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp)) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ if (!addr) -+ break; -+ if (!(*q = lock_user_string(addr))) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ total_size += strlen(*q) + 1; -+ } -+ *q = NULL; -+ -+ /* -+ * This case will not be caught by the host's execve() if its -+ * page size is bigger than the target's. -+ */ -+ if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) { -+ ret = -TARGET_E2BIG; -+ goto execve_end; -+ } -+ -+ if (do_fexec) { -+ if (((int)path_or_fd > 0 && -+ is_target_elf_binary((int)path_or_fd)) == 1) { -+ char execpath[PATH_MAX]; -+ -+ /* -+ * The executable is an elf binary for the target -+ * arch. execve() it using the emulator if we can -+ * determine the filename path from the fd. -+ */ -+ if (get_filename_from_fd(getpid(), (int)path_or_fd, -+ execpath, sizeof(execpath)) != NULL) { -+ *qarg1 = execpath; -+ ret = get_errno(execve(qemu_proc_pathname, -+ qargp, envp)); -+ } else { -+ /* Getting the filename path failed. */ -+ ret = -TARGET_EBADF; -+ goto execve_end; -+ } -+ } else { -+ ret = get_errno(fexecve((int)path_or_fd, argp, envp)); -+ } -+ } else { -+ int fd; -+ -+ if (!(p = lock_user_string(path_or_fd))) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ -+ /* -+ * Check the header and see if it a target elf binary. If so -+ * then execute using qemu user mode emulator. -+ */ -+ fd = open(p, O_RDONLY | O_CLOEXEC); -+ if (fd > 0 && is_target_elf_binary(fd) == 1) { -+ close(fd); -+ /* Execve() as a target binary using emulator. */ -+ *qarg1 = (char *)p; -+ ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); -+ } else { -+ close(fd); -+ /* Execve() as a host native binary. */ -+ ret = get_errno(execve(p, argp, envp)); -+ } -+ unlock_user(p, path_or_fd, 0); -+ } -+ -+execve_end: -+ for (gp = guest_argp, q = argp; *q; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp) || !addr) -+ break; -+ unlock_user(*q, addr, 0); -+ } -+ -+ for (gp = guest_envp, q = envp; *q; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp) || !addr) -+ break; -+ unlock_user(*q, addr, 0); -+ } -+ return (ret); -+} -+ -+static inline abi_long -+do_freebsd_execve(abi_ulong path_or_fd, abi_ulong argp, abi_ulong envp) -+{ -+ -+ return (freebsd_exec_common(path_or_fd, argp, envp, 0)); -+} -+ -+static inline abi_long -+do_freebsd_fexecve(abi_ulong path_or_fd, abi_ulong argp, abi_ulong envp) -+{ -+ -+ return (freebsd_exec_common(path_or_fd, argp, envp, 1)); -+} -+ - /* do_syscall() should always have a single exit point at the end so - that actions, such as logging of syscall results, can be performed. - All errnos that do_syscall() returns must be -TARGET_<errcode>. */ -@@ -4515,96 +5015,14 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - #endif - - case TARGET_FREEBSD_NR_execve: -- { -- char **argp, **envp; -- int argc, envc; -- abi_ulong gp; -- abi_ulong guest_argp; -- abi_ulong guest_envp; -- abi_ulong addr; -- char **q; -- int total_size = 0; -- -- argc = 0; -- guest_argp = arg2; -- for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) { -- if (get_user_ual(addr, gp)) -- goto efault; -- if (!addr) -- break; -- argc++; -- } -- envc = 0; -- guest_envp = arg3; -- for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) { -- if (get_user_ual(addr, gp)) -- goto efault; -- if (!addr) -- break; -- envc++; -- } -- -- argp = alloca((argc + 1) * sizeof(void *)); -- envp = alloca((envc + 1) * sizeof(void *)); -- -- for (gp = guest_argp, q = argp; gp; -- gp += sizeof(abi_ulong), q++) { -- if (get_user_ual(addr, gp)) -- goto execve_efault; -- if (!addr) -- break; -- if (!(*q = lock_user_string(addr))) -- goto execve_efault; -- total_size += strlen(*q) + 1; -- } -- *q = NULL; -- -- for (gp = guest_envp, q = envp; gp; -- gp += sizeof(abi_ulong), q++) { -- if (get_user_ual(addr, gp)) -- goto execve_efault; -- if (!addr) -- break; -- if (!(*q = lock_user_string(addr))) -- goto execve_efault; -- total_size += strlen(*q) + 1; -- } -- *q = NULL; -- -- /* This case will not be caught by the host's execve() if its -- page size is bigger than the target's. */ -- if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) { -- ret = -TARGET_E2BIG; -- goto execve_end; -- } -- if (!(p = lock_user_string(arg1))) -- goto execve_efault; -- ret = get_errno(execve(p, argp, envp)); -- unlock_user(p, arg1, 0); -- -- goto execve_end; -- -- execve_efault: -- ret = -TARGET_EFAULT; -+ ret = do_freebsd_execve(arg1, arg2, arg3); -+ break; - -- execve_end: -- for (gp = guest_argp, q = argp; *q; -- gp += sizeof(abi_ulong), q++) { -- if (get_user_ual(addr, gp) -- || !addr) -- break; -- unlock_user(*q, addr, 0); -- } -- for (gp = guest_envp, q = envp; *q; -- gp += sizeof(abi_ulong), q++) { -- if (get_user_ual(addr, gp) -- || !addr) -- break; -- unlock_user(*q, addr, 0); -- } -- } -+ case TARGET_FREEBSD_NR_fexecve: -+ ret = do_freebsd_fexecve(arg1, arg2, arg3); - break; - -+ - case TARGET_FREEBSD_NR_pipe: - { - int host_pipe[2]; -@@ -5296,11 +5714,11 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_F_SETLKW: - if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) - return (-TARGET_EFAULT); -- fl.l_type = tswap16(target_fl->l_type); -- fl.l_whence = tswap16(target_fl->l_whence); - fl.l_start = tswapal(target_fl->l_start); - fl.l_len = tswapal(target_fl->l_len); - fl.l_pid = tswap32(target_fl->l_pid); -+ fl.l_type = tswap16(target_fl->l_type); -+ fl.l_whence = tswap16(target_fl->l_whence); - fl.l_sysid = tswap32(target_fl->l_sysid); - unlock_user_struct(target_fl, arg3, 0); - ret = get_errno(fcntl(arg1, host_cmd, &fl)); -@@ -5370,13 +5788,16 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - if (reclen > len) - break; - de->d_reclen = tswap16(reclen); -+ de->d_fileno = tswap32(de->d_fileno); - len -= reclen; -+ de = (struct dirent *)((void *)de + reclen); - } - } - unlock_user(dirp, arg2, ret); -- if (arg4) -- if (put_user(nbytes, arg4, abi_ulong)) -+ if (arg4) { -+ if (put_user(basep, arg4, abi_ulong)) - ret = -TARGET_EFAULT; -+ } - } - break; - -@@ -5431,32 +5852,406 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - -- case TARGET_FREEBSD_NR___acl_get_file: -- case TARGET_FREEBSD_NR___acl_set_file: -- case TARGET_FREEBSD_NR___acl_get_fd: -- case TARGET_FREEBSD_NR___acl_set_fd: -- case TARGET_FREEBSD_NR___acl_delete_file: -- case TARGET_FREEBSD_NR___acl_delete_fd: -- case TARGET_FREEBSD_NR___acl_aclcheck_file: - case TARGET_FREEBSD_NR___acl_aclcheck_fd: -+ { -+ struct acl host_acl; -+ -+ ret = target_to_host_acl(&host_acl, arg3); -+ if (!is_error(ret)) -+ ret = get_errno(__acl_aclcheck_fd(arg1, arg2, -+ &host_acl)); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_aclcheck_file: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = target_to_host_acl(&host_acl, arg3); -+ if (!is_error(ret)) -+ ret = get_errno(__acl_aclcheck_file(path(p) , arg2, -+ &host_acl)); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_aclcheck_link: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = target_to_host_acl(&host_acl, arg3); -+ if (!is_error(ret)) -+ ret = get_errno(__acl_aclcheck_link(path(p), arg2, -+ &host_acl)); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_delete_fd: -+ ret = get_errno(__acl_delete_fd(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_delete_file: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = get_errno(__acl_delete_file(path(p), arg2)); -+ -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_delete_link: -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = get_errno(__acl_delete_link(path(p), arg2)); -+ -+ unlock_user(p, arg1, 0); -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_get_fd: -+ { -+ struct acl host_acl; -+ -+ ret = get_errno(__acl_get_fd(arg1, arg2, &host_acl)); -+ -+ if (!is_error(ret)) -+ ret = host_to_target_acl(arg3, &host_acl); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_get_file: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = get_errno(__acl_get_file(path(p), arg2, &host_acl)); -+ -+ if (!is_error(ret)) -+ ret = host_to_target_acl(arg3, &host_acl); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR___acl_get_link: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = get_errno(__acl_get_link(path(p), arg2, &host_acl)); -+ -+ if (!is_error(ret)) -+ ret = host_to_target_acl(arg3, &host_acl); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_set_fd: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = target_to_host_acl(&host_acl, arg3); -+ if (!is_error(ret)) -+ ret = get_errno(__acl_set_fd(arg1, arg2, &host_acl)); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ -+ case TARGET_FREEBSD_NR___acl_set_file: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = target_to_host_acl(&host_acl, arg3); -+ if (!is_error(ret)) -+ ret = get_errno(__acl_set_file(path(p), arg2, -+ &host_acl)); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR___acl_set_link: -- case TARGET_FREEBSD_NR___acl_delete_link: -- case TARGET_FREEBSD_NR___acl_aclcheck_link: -+ { -+ struct acl host_acl; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ ret = target_to_host_acl(&host_acl, arg3); -+ if (!is_error(ret)) -+ ret = get_errno(__acl_set_link(path(p), arg2, -+ &host_acl)); -+ -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattrctl: -+ { -+ void *a, *f; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(f = lock_user_string(arg3))) -+ goto efault; -+ if (!(a = lock_user_string(arg5))) -+ goto efault; -+ -+ ret = get_errno(extattrctl(path(p), arg2, f, arg4, a)); -+ -+ unlock_user(a, arg5, 0); -+ unlock_user(f, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_set_file: -+ { -+ void *a, *d; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ if (!(d = lock_user(VERIFY_READ, arg4, arg5, 1))) -+ goto efault; -+ -+ ret = get_errno(extattr_set_file(path(p), arg2, a, d, arg5)); -+ -+ unlock_user(d, arg4, arg5); -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_get_file: -+ { -+ void *a, *d; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ -+ if (arg4 && arg5 > 0) { -+ if (!(d = lock_user(VERIFY_WRITE, arg4, arg5, 0))) -+ goto efault; -+ ret = get_errno(extattr_get_file(path(p), arg2, a, d, -+ arg5)); -+ unlock_user(d, arg4, arg5); -+ } else { -+ ret = get_errno(extattr_get_file(path(p), arg2, a, -+ NULL, arg5)); -+ } -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_delete_file: -+ { -+ void *a; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ -+ ret = get_errno(extattr_delete_file(path(p), arg2, a)); -+ -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_set_fd: -+ { -+ void *a, *d; -+ -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ if (!(d = lock_user(VERIFY_READ, arg4, arg5, 1))) -+ goto efault; -+ -+ ret = get_errno(extattr_set_fd(arg1, arg2, a, d, arg5)); -+ -+ unlock_user(d, arg4, arg5); -+ unlock_user(a, arg3, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_get_fd: -+ { -+ void *a, *d; -+ -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ -+ if (arg4 && arg5 > 0) { -+ if (!(d = lock_user(VERIFY_WRITE, arg4, arg5, 0))) -+ goto efault; -+ ret = get_errno(extattr_get_fd(arg1, arg2, a, d, -+ arg5)); -+ unlock_user(d, arg4, arg5); -+ } else { -+ ret = get_errno(extattr_get_fd(arg1, arg2, a, -+ NULL, arg5)); -+ } -+ unlock_user(a, arg3, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_delete_fd: -+ { -+ void *a; -+ -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ -+ ret = get_errno(extattr_delete_fd(arg1, arg2, a)); -+ -+ unlock_user(a, arg3, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_get_link: -+ { -+ void *a, *d; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ -+ if (arg4 && arg5 > 0) { -+ if (!(d = lock_user(VERIFY_WRITE, arg4, arg5, 0))) -+ goto efault; -+ ret = get_errno(extattr_get_link(path(p), arg2, a, d, -+ arg5)); -+ unlock_user(d, arg4, arg5); -+ } else { -+ ret = get_errno(extattr_get_link(path(p), arg2, a, -+ NULL, arg5)); -+ } -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_set_link: -+ { -+ void *a, *d; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ if (!(d = lock_user(VERIFY_READ, arg4, arg5, 1))) -+ goto efault; -+ -+ ret = get_errno(extattr_set_link(path(p), arg2, a, d, arg5)); -+ -+ unlock_user(d, arg4, arg5); -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_delete_link: -+ { -+ void *a; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ if (!(a = lock_user_string(arg3))) -+ goto efault; -+ -+ ret = get_errno(extattr_delete_link(path(p), arg2, a)); -+ -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_list_fd: -+ { -+ void *d; -+ -+ if (arg3 && arg4 > 0) { -+ if (!(d = lock_user(VERIFY_WRITE, arg3, arg4, 0))) -+ goto efault; -+ ret = get_errno(extattr_list_fd(arg1, arg2, d, -+ arg4)); -+ unlock_user(d, arg3, arg4); -+ } else { -+ ret = get_errno(extattr_list_fd(arg1, arg2, -+ NULL, arg4)); -+ } -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_list_file: -+ { -+ void *d; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ if (arg3 && arg4 > 0) { -+ if (!(d = lock_user(VERIFY_WRITE, arg3, arg4, 0))) -+ goto efault; -+ ret = get_errno(extattr_list_file(path(p), arg2, d, -+ arg4)); -+ unlock_user(d, arg3, arg4); -+ } else { -+ ret = get_errno(extattr_list_file(path(p), arg2, -+ NULL, arg4)); -+ } -+ unlock_user(p, arg1, 0); -+ } -+ break; -+ - case TARGET_FREEBSD_NR_extattr_list_link: -- ret = unimplemented(num); -+ { -+ void *d; -+ -+ if (!(p = lock_user_string(arg1))) -+ goto efault; -+ -+ if (arg3 && arg4 > 0) { -+ if (!(d = lock_user(VERIFY_WRITE, arg3, arg4, 0))) -+ goto efault; -+ ret = get_errno(extattr_list_link(path(p), arg2, d, -+ arg4)); -+ unlock_user(d, arg3, arg4); -+ } else { -+ ret = get_errno(extattr_list_link(path(p), arg2, -+ NULL, arg4)); -+ } -+ -+ unlock_user(p, arg1, 0); -+ } - break; - - case TARGET_FREEBSD_NR_setlogin: -@@ -5635,6 +6430,10 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4); - break; - -+ case TARGET_FREEBSD_NR_freebsd7___semctl: -+ ret = unimplemented(num); -+ break; -+ - case TARGET_FREEBSD_NR_msgctl: - ret = do_msgctl(arg1, arg2, arg3); - break; -@@ -5715,7 +6514,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_seteuid: -- ret = get_errno(setegid(arg1)); -+ ret = get_errno(seteuid(arg1)); - break; - - case TARGET_FREEBSD_NR_getpgrp: -@@ -6953,7 +7752,7 @@ void syscall_init(void) - - #define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); - #define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); --#ifdef __FreeBSD__ -+#if defined(__FreeBSD__) - #include "freebsd/syscall_types.h" - #else - #warning No syscall_types.h -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index 3eb760b..8a92403 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -203,12 +203,12 @@ struct target_pollfd { - #include "openbsd/syscall_nr.h" - - struct target_flock { -- unsigned long long l_start; -- unsigned long long l_len; -- int l_pid; -- int l_sysid; -- short l_type; -- short l_whence; -+ abi_long l_start; -+ abi_long l_len; -+ int32_t l_pid; -+ int16_t l_type; -+ int16_t l_whence; -+ int32_t l_sysid; - } QEMU_PACKED; - - struct target_iovec { -@@ -451,6 +451,7 @@ typedef struct target_siginfo { - int32_t si_code; /* signal code */ - int32_t si_pid; /* sending process */ - int32_t si_uid; /* sender's ruid */ -+ int32_t si_status; /* exit value */ - abi_ulong si_addr; /* faulting instruction */ - - union target_sigval si_value; /* signal value */ -@@ -756,3 +757,41 @@ struct target_timex { - struct target_sched_param { - int32_t sched_priority; - }; -+ -+ -+/* -+ * sys/acl.h -+ */ -+ -+#define TARGET_ACL_MAX_ENTRIES 254 -+ -+struct target_acl_entry { -+ int32_t ae_tag; -+ uint32_t ae_id; -+ uint16_t ae_perm; -+ uint16_t ae_entry_type; -+ uint16_t ae_flags; -+}; -+ -+struct target_acl { -+ uint32_t acl_maxcnt; -+ uint32_t acl_cnt; -+ int32_t acl_space[4]; -+ struct target_acl_entry acl_entry[TARGET_ACL_MAX_ENTRIES]; -+}; -+ -+ -+/* -+ * netinet/in.h -+ */ -+ -+struct target_ip_mreq { -+ struct target_in_addr imr_multiaddr; -+ struct target_in_addr imr_interface; -+}; -+ -+struct target_ip_mreqn { -+ struct target_in_addr imr_multiaddr; -+ struct target_in_addr imr_address; -+ int32_t imr_ifindex; -+}; -diff --git a/configure b/configure -index d99584d..6d17c97 100755 ---- a/configure -+++ b/configure -@@ -434,8 +434,9 @@ FreeBSD) - make="${MAKE-gmake}" - audio_drv_list="oss" - audio_possible_drivers="oss sdl esd pa" -- # needed for kinfo_getvmmap(3) in libutil.h -- LIBS="-lutil $LIBS" -+ # -lutil needed for kinfo_getvmmap(3) in libutil.h -+ # -lprocstat needed for procstat_*(3) in main.c -+ LIBS="-lprocstat -lutil $LIBS" - ;; - DragonFly) - bsd="yes" -@@ -1237,6 +1238,11 @@ if test "$static" = "yes" ; then - else - pie="no" - fi -+ if test "$bsd" = "yes" ; then -+ # Missing libs when linking statically -+ LIBS="$LIBS -lintl -lkvm" -+ libs_qga="-lintl $libs_qga" -+ fi - fi - - if test "$pie" = ""; then diff --git a/emulators/qemu-devel/files/patch-z9d-bsd-user-sson003d b/emulators/qemu-devel/files/patch-z9d-bsd-user-sson003d deleted file mode 100644 index 5dfbaa4ea476..000000000000 --- a/emulators/qemu-devel/files/patch-z9d-bsd-user-sson003d +++ /dev/null @@ -1,92 +0,0 @@ -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 8abb1dd..c2c3a65 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -798,6 +798,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - p -= roundup(execpath_len, sizeof(abi_ulong)); - /* XXX - check return value of memcpy_to_target() */ - memcpy_to_target(p, execpath, execpath_len); -+ strlcpy(target_proc_pathname, execpath, execpath_len); - } - - /* Add canary for SSP. */ -diff --git a/bsd-user/main.c b/bsd-user/main.c -index bb614de..b6aaa7e 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -62,6 +62,7 @@ unsigned long x86_stack_size = 512 * 1024; - - static void save_proc_pathname(void); - char qemu_proc_pathname[PATH_MAX]; -+char target_proc_pathname[PATH_MAX]; - - #ifdef __FreeBSD__ - static void -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index 110b54e..d51f50c 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -224,6 +224,7 @@ void mmap_fork_end(int child); - /* main.c */ - extern unsigned long x86_stack_size; - extern char qemu_proc_pathname[]; -+extern char target_proc_pathname[]; - - /* user access */ - -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 74b5c86..636083a 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -485,8 +485,6 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - abi_ulong oldlen = 0; - int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i; - uint32_t kind = 0; -- abi_ulong argv, argv0; -- char *fullpath = NULL; - - if (oldlenp) - if (get_user_ual(oldlen, oldlenp)) -@@ -533,30 +531,14 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - case KERN_PROC: - switch(snamep[2]) { - case KERN_PROC_PATHNAME: -- if (get_user_ual(argv, TARGET_PS_STRINGS)) { -- ret = -TARGET_EFAULT; -- goto out; -- } -- if (get_user_ual(argv0, argv)) { -- ret = -TARGET_EFAULT; -- goto out; -- } -- -- fullpath = realpath(g2h(argv0), NULL); -- if (NULL == fullpath) -- fullpath = (char *)g2h(argv0); -- holdlen = strlen(fullpath) + 1; -+ holdlen = strlen(target_proc_pathname) + 1; - if (holdp) { - if (oldlen < holdlen) { - ret = -TARGET_EINVAL; - goto out; - } -- if (!access_ok(VERIFY_WRITE, argv0, -- holdlen)) { -- ret = -TARGET_EFAULT; -- goto out; -- } -- strlcpy(holdp, fullpath, oldlen); -+ strlcpy(holdp, target_proc_pathname, -+ oldlen); - } - ret = 0; - goto out; -@@ -597,8 +579,6 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - #endif - - out: -- if (fullpath) -- free(fullpath); - if (oldlenp) - put_user_ual(holdlen, oldlenp); - unlock_user(hnamep, namep, 0); diff --git a/emulators/qemu-devel/files/patch-z9e-bsd-user-cognet-elfload b/emulators/qemu-devel/files/patch-z9e-bsd-user-cognet-elfload deleted file mode 100644 index a47642b24e6e..000000000000 --- a/emulators/qemu-devel/files/patch-z9e-bsd-user-cognet-elfload +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 8abb1dd..eee159b 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -999,9 +999,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, - NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); - NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); - NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); -+#ifndef __FreeBSD__ - NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); - NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); --#ifndef __FreeBSD__ - if (k_platform) - NEW_AUX_ENT(AT_PLATFORM, u_platform); - #endif diff --git a/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f b/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f deleted file mode 100644 index 2cf57e8a1429..000000000000 --- a/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f +++ /dev/null @@ -1,321 +0,0 @@ -diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h -index 6b7bb67..4a9e518 100644 ---- a/bsd-user/arm/target_signal.h -+++ b/bsd-user/arm/target_signal.h -@@ -3,15 +3,57 @@ - - #include "cpu.h" - --static inline abi_ulong get_sp_from_cpustate(CPUARMState *state) --{ -- return state->regs[13]; --} -+#define TARGET_REG_R0 0 -+#define TARGET_REG_R1 1 -+#define TARGET_REG_R2 2 -+#define TARGET_REG_R3 3 -+#define TARGET_REG_R4 4 -+#define TARGET_REG_R5 5 -+#define TARGET_REG_R6 6 -+#define TARGET_REG_R7 7 -+#define TARGET_REG_R8 8 -+#define TARGET_REG_R9 9 -+#define TARGET_REG_R10 10 -+#define TARGET_REG_R11 11 -+#define TARGET_REG_R12 12 -+#define TARGET_REG_R13 13 -+#define TARGET_REG_R14 14 -+#define TARGET_REG_R15 15 -+#define TARGET_REG_CPSR 16 -+/* Convenience synonyms */ -+#define TARGET_REG_FP TARGET_REG_R11 -+#define TARGET_REG_SP TARGET_REG_R13 -+#define TARGET_REG_LR TARGET_REG_R14 -+#define TARGET_REG_PC TARGET_REG_R15 -+ -+#define TARGET_GET_MC_CLEAR_RET 1 - - #define TARGET_MINSIGSTKSZ (1024 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+#define TARGET__NGREG 17 -+ -+typedef struct { -+ uint32_t __fp_fpsr; -+ struct { -+ uint32_t __fp_exponent; -+ uint32_t __fp_mantissa_hi; -+ uint32_t __fp_mantissa_lo; -+ } __fp_fr[8]; -+} target__fpregset_t; - --typedef target_ulong target_mcontext_t; /* dummy */ -+typedef struct { -+ uint32_t __vfp_fpscr; -+ uint32_t __vfp_fstmx[33]; -+ uint32_t __vfp_fpsid; -+} target__vfpregset_t; -+ -+typedef struct { -+ uint32_t __gregs[TARGET__NGREG]; -+ union { -+ target__fpregset_t __fpregs; -+ target__vfpregset_t __vfpregs; -+ } __fpu; -+} target_mcontext_t; - - typedef struct target_ucontext { - target_sigset_t uc_sigmask; -@@ -22,18 +64,119 @@ typedef struct target_ucontext { - int32_t __spare__[4]; - } target_ucontext_t; - -+struct target_sigframe { -+ target_siginfo_t sf_si; /* saved siginfo */ -+ target_ucontext_t sf_uc; /* saved ucontext */ -+}; -+ -+#define TARGET_SZSIGCODE (8 * 4) -+ -+/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */ -+static inline int -+install_sigtramp(abi_ulong offset, unsigned sigf_us, uint32_t sys_sigreturn) -+{ -+ int i; -+ uint32_t sys_exit = TARGET_FREEBSD_NR_exit; -+ /* -+ * The code has to load r7 manually rather than using -+ * "ldr r7, =SYS_return to make sure the size of the -+ * code is correct. -+ */ -+ uint32_t sigtramp_code[] = { -+ /* 1 */ 0xE1A0000D, /* mov r0, sp */ -+ /* 2 */ 0xE59F700C, /* ldr r7, [pc, #12] */ -+ /* 3 */ 0xEF000000 + sys_sigreturn, /* swi (SYS_sigreturn) */ -+ /* 4 */ 0xE59F7008, /* ldr r7, [pc, #8] */ -+ /* 5 */ 0xEF000000 + sys_exit, /* swi (SYS_exit)*/ -+ /* 6 */ 0xEAFFFFFA, /* b . -16 */ -+ /* 7 */ sys_sigreturn, -+ /* 8 */ sys_exit -+ }; -+ -+ for(i = 0; i < 8; i++) -+ tswap32s(&sigtramp_code[i]); -+ -+ return(memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE)); -+} -+ -+static inline abi_ulong -+get_sp_from_cpustate(CPUARMState *state) -+{ -+ return state->regs[13]; /* sp */ -+} -+ -+/* -+ * Compare to arm/arm/machdep.c sendsig() -+ * Assumes that the target stack frame memory is locked. -+ */ -+static inline int -+set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) -+{ -+ /* -+ * Arguments to signal handler: -+ * r0 = signal number -+ * r1 = siginfo pointer -+ * r2 = ucontext pointer -+ * r5 = ucontext pointer -+ * pc = signal handler pointer -+ * sp = sigframe struct pointer -+ * lr = sigtramp at base of user stack -+ */ -+ -+ regs->regs[0] = sig; -+ regs->regs[1] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->regs[2] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ -+ /* the trampoline uses r5 as the uc address */ -+ regs->regs[5] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ regs->regs[TARGET_REG_PC] = ka->_sa_handler; -+ regs->regs[TARGET_REG_SP] = frame_addr; -+ regs->regs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ -+ return (0); -+} -+ -+/* Compare to arm/arm/machdep.c get_mcontext() */ - static inline int --get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int clear_ret) - { -- fprintf(stderr, "ARM doesn't have support for get_mcontext()\n"); -- return (-TARGET_ENOSYS); -+ int i, err = 0; -+ uint32_t *gr = mcp->__gregs; -+ -+ -+ if (clear_ret & TARGET_GET_MC_CLEAR_RET) -+ gr[TARGET_REG_R0] = 0; -+ else -+ gr[TARGET_REG_R0] = tswap32(regs->regs[0]); -+ for(i = 1; i < 12; i++) -+ gr[i] = tswap32(regs->regs[i]); -+ gr[TARGET_REG_SP] = tswap32(regs->regs[13]); -+ gr[TARGET_REG_LR] = tswap32(regs->regs[14]); -+ gr[TARGET_REG_PC] = tswap32(regs->regs[15]); -+ gr[TARGET_REG_CPSR] = tswap32(regs->spsr); -+ -+ return (err); - } - -+/* Compare to arm/arm/machdep.c set_mcontext() */ - static inline int --set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) -+set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int flags) - { -- fprintf(stderr, "ARM doesn't have support for set_mcontext()\n"); -- return (-TARGET_ENOSYS); -+ int i, err = 0; -+ const uint32_t *gr = mcp->__gregs; -+ -+ for(i = 0; i < 12; i++) -+ regs->regs[i] = tswap32(gr[i]); -+ regs->regs[13] = tswap32(gr[TARGET_REG_SP]); -+ regs->regs[14] = tswap32(gr[TARGET_REG_LR]); -+ regs->regs[15] = tswap32(gr[TARGET_REG_PC]); -+ regs->spsr = tswap32(gr[TARGET_REG_CPSR]); -+ -+ return (err); - } - - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h -index 24dca00..bc50fbb 100644 ---- a/bsd-user/arm/target_vmparam.h -+++ b/bsd-user/arm/target_vmparam.h -@@ -18,8 +18,6 @@ struct target_ps_strings { - - #define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) - --#define TARGET_SZSIGCODE 0 -- - /* Make stack size large enough to hold everything. */ - #define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ - MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index c2c3a65..76681e1 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -690,24 +690,6 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, - return p; - } - --#if defined(TARGET_MIPS64) --static inline int --install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned syscall) --{ -- int i; -- uint32_t sigtramp_code[] = { -- 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -- 0x24020000 + syscall, /* li $v0, (syscall) */ -- 0x0000000C, /* syscall */ -- 0x0000000D /* break */ -- }; -- -- for(i = 0; i < 4; i++) -- tswap32s(&sigtramp_code[i]); -- -- return (memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE)); --} --#endif - - static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - struct image_info *info) -diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h -index c592136..f657909 100644 ---- a/bsd-user/mips64/target_signal.h -+++ b/bsd-user/mips64/target_signal.h -@@ -5,7 +5,6 @@ - - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) --#define TARGET_SZSIGCODE 16 - - struct target_sigcontext { - target_sigset_t sc_mask; /* signal mask to retstore */ -@@ -56,9 +55,29 @@ get_sp_from_cpustate(CPUMIPSState *state) - return state->active_tc.gpr[29]; - } - -+#define TARGET_SZSIGCODE (4 * 4) -+ -+/* Compare to mips/mips/locore.S sigcode() */ -+static inline int -+install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned sys_sigreturn) -+{ -+ int i; -+ uint32_t sigtramp_code[] = { -+ /* 1 */ 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -+ /* 2 */ 0x24020000 + sys_sigreturn, /* li $v0, (sys_sigreturn) */ -+ /* 3 */ 0x0000000C, /* syscall */ -+ /* 4 */ 0x0000000D /* break */ -+ }; -+ -+ for(i = 0; i < 4; i++) -+ tswap32s(&sigtramp_code[i]); -+ -+ return (memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE)); -+} -+ - /* - * Compare to mips/mips/pm_machdep.c sendsig() -- * Assumes that "frame" memory is locked. -+ * Assumes that target stack frame memory is locked. - */ - static inline int - set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, -@@ -67,6 +86,11 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - - /* frame->sf_si.si_addr = regs->CP0_BadVAddr; */ - -+ /* MIPS only struct target_sigframe members: */ -+ frame->sf_signum = sig; -+ frame->sf_siginfo = (abi_ulong)&frame->sf_si; -+ frame->sf_ucontext = (abi_ulong)&frame->sf_uc; -+ - /* - * Arguments to signal handler: - * a0 ($4) = signal number -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index 29e8e12..b04e874 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -613,7 +613,7 @@ do_sigaction(int sig, const struct target_sigaction *act, - return (ret); - } - --#if defined(TARGET_MIPS64) /* || defined(TARGET_SPARC64) */ -+#if defined(TARGET_MIPS64) || defined(TARGET_ARM) - - static inline abi_ulong - get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size) -@@ -715,17 +715,8 @@ static void setup_frame(int sig, int code, struct target_sigaction *ka, - } - #endif - -- frame->sf_signum = sig; -- frame->sf_siginfo = (abi_ulong)&frame->sf_si; -- frame->sf_ucontext = (abi_ulong)&frame->sf_uc; -- -- } else { -- frame->sf_signum = sig; -- frame->sf_siginfo = 0; -- frame->sf_ucontext = 0; - } - -- - if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) - goto give_sigsegv; - diff --git a/emulators/qemu-devel/files/patch-za-bsd-user-8fix b/emulators/qemu-devel/files/patch-za-bsd-user-8fix deleted file mode 100644 index a8653c16722d..000000000000 --- a/emulators/qemu-devel/files/patch-za-bsd-user-8fix +++ /dev/null @@ -1,12 +0,0 @@ ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -106,7 +106,9 @@ static char *get_filename_from_fd(pid_t - #ifdef __FreeBSD__ - #include <sys/queue.h> - #include <sys/user.h> -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - #include <libprocstat.h> -+#endif - - - /* diff --git a/emulators/qemu-devel/files/patch-zb-bsd-user-sson004a b/emulators/qemu-devel/files/patch-zb-bsd-user-sson004a deleted file mode 100644 index c25c52b6d5c6..000000000000 --- a/emulators/qemu-devel/files/patch-zb-bsd-user-sson004a +++ /dev/null @@ -1,1151 +0,0 @@ -diff --git a/bsd-user/arm/syscall.h b/bsd-user/arm/syscall.h -index bd54b37..4d98841 100644 ---- a/bsd-user/arm/syscall.h -+++ b/bsd-user/arm/syscall.h -@@ -22,4 +22,7 @@ struct target_pt_regs { - - #define ARM_SYSCALL_BASE 0 /* XXX: FreeBSD only */ - --#define TARGET_FREEBSD_ARM_SET_TP 2 -+#define TARGET_FREEBSD_ARM_SYNC_ICACHE 0 -+#define TARGET_FREEBSD_ARM_DRAIN_WRITEBUF 1 -+#define TARGET_FREEBSD_ARM_SET_TP 2 -+#define TARGET_FREEBSD_ARM_GET_TP 3 -diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h -index 4a9e518..05c9d1c 100644 ---- a/bsd-user/arm/target_signal.h -+++ b/bsd-user/arm/target_signal.h -@@ -26,8 +26,6 @@ - #define TARGET_REG_LR TARGET_REG_R14 - #define TARGET_REG_PC TARGET_REG_R15 - --#define TARGET_GET_MC_CLEAR_RET 1 -- - #define TARGET_MINSIGSTKSZ (1024 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - #define TARGET__NGREG 17 -@@ -109,7 +107,7 @@ get_sp_from_cpustate(CPUARMState *state) - * Compare to arm/arm/machdep.c sendsig() - * Assumes that the target stack frame memory is locked. - */ --static inline int -+static inline abi_ulong - set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame, - abi_ulong frame_addr, struct target_sigaction *ka) - { -@@ -141,42 +139,89 @@ set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame, - } - - /* Compare to arm/arm/machdep.c get_mcontext() */ --static inline int -+static inline abi_long - get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int clear_ret) - { -- int i, err = 0; -+ int err = 0; - uint32_t *gr = mcp->__gregs; - - -- if (clear_ret & TARGET_GET_MC_CLEAR_RET) -+ if (clear_ret & TARGET_MC_GET_CLEAR_RET) - gr[TARGET_REG_R0] = 0; - else - gr[TARGET_REG_R0] = tswap32(regs->regs[0]); -- for(i = 1; i < 12; i++) -- gr[i] = tswap32(regs->regs[i]); -+ -+ gr[TARGET_REG_R1 ] = tswap32(regs->regs[ 1]); -+ gr[TARGET_REG_R2 ] = tswap32(regs->regs[ 2]); -+ gr[TARGET_REG_R3 ] = tswap32(regs->regs[ 3]); -+ gr[TARGET_REG_R4 ] = tswap32(regs->regs[ 4]); -+ gr[TARGET_REG_R5 ] = tswap32(regs->regs[ 5]); -+ gr[TARGET_REG_R6 ] = tswap32(regs->regs[ 6]); -+ gr[TARGET_REG_R7 ] = tswap32(regs->regs[ 7]); -+ gr[TARGET_REG_R8 ] = tswap32(regs->regs[ 8]); -+ gr[TARGET_REG_R9 ] = tswap32(regs->regs[ 9]); -+ gr[TARGET_REG_R10] = tswap32(regs->regs[10]); -+ gr[TARGET_REG_R11] = tswap32(regs->regs[11]); -+ gr[TARGET_REG_R12] = tswap32(regs->regs[12]); -+ - gr[TARGET_REG_SP] = tswap32(regs->regs[13]); - gr[TARGET_REG_LR] = tswap32(regs->regs[14]); - gr[TARGET_REG_PC] = tswap32(regs->regs[15]); -- gr[TARGET_REG_CPSR] = tswap32(regs->spsr); -+ gr[TARGET_REG_CPSR] = tswap32(cpsr_read(regs)); - - return (err); - } - - /* Compare to arm/arm/machdep.c set_mcontext() */ --static inline int --set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int flags) -+static inline abi_long -+set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int srflag) - { -- int i, err = 0; -+ int err = 0; - const uint32_t *gr = mcp->__gregs; -+ uint32_t cpsr; -+ -+ regs->regs[ 0] = tswap32(gr[TARGET_REG_R0 ]); -+ regs->regs[ 1] = tswap32(gr[TARGET_REG_R1 ]); -+ regs->regs[ 2] = tswap32(gr[TARGET_REG_R2 ]); -+ regs->regs[ 3] = tswap32(gr[TARGET_REG_R3 ]); -+ regs->regs[ 4] = tswap32(gr[TARGET_REG_R4 ]); -+ regs->regs[ 5] = tswap32(gr[TARGET_REG_R5 ]); -+ regs->regs[ 6] = tswap32(gr[TARGET_REG_R6 ]); -+ regs->regs[ 7] = tswap32(gr[TARGET_REG_R7 ]); -+ regs->regs[ 8] = tswap32(gr[TARGET_REG_R8 ]); -+ regs->regs[ 9] = tswap32(gr[TARGET_REG_R9 ]); -+ regs->regs[10] = tswap32(gr[TARGET_REG_R10]); -+ regs->regs[11] = tswap32(gr[TARGET_REG_R11]); -+ regs->regs[12] = tswap32(gr[TARGET_REG_R12]); - -- for(i = 0; i < 12; i++) -- regs->regs[i] = tswap32(gr[i]); - regs->regs[13] = tswap32(gr[TARGET_REG_SP]); - regs->regs[14] = tswap32(gr[TARGET_REG_LR]); - regs->regs[15] = tswap32(gr[TARGET_REG_PC]); -- regs->spsr = tswap32(gr[TARGET_REG_CPSR]); -+ cpsr = tswap32(gr[TARGET_REG_CPSR]); -+ cpsr_write(regs, cpsr, CPSR_USER | CPSR_EXEC); - - return (err); - } - -+/* Compare to arm/arm/machdep.c sys_sigreturn() */ -+static inline abi_long -+get_ucontext_sigreturn(CPUARMState *regs, abi_ulong sf_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ struct target_sigframe *sf; -+ uint32_t cpsr = cpsr_read(regs); -+ -+ if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR || -+ (cpsr & (CPSR_I | CPSR_F)) != 0) -+ return (-TARGET_EINVAL); -+ -+ if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ *locked_addr = sf; -+ *ucontext = (target_ucontext_t *)g2h(tswapal(sf_addr + -+ offsetof(struct target_sigframe, sf_uc))); -+ return (0); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 76681e1..7a7c3eb 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -13,6 +13,7 @@ - - #include "qemu.h" - #include "disas/disas.h" -+#include "target_signal.h" - - #ifdef _ARCH_PPC64 - #undef ARCH_DLINFO -diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h -index 1efa502..7f2e0ca 100644 ---- a/bsd-user/errno_defs.h -+++ b/bsd-user/errno_defs.h -@@ -147,3 +147,7 @@ - #define TARGET_EIDRM 89 /* Identifier removed */ - #define TARGET_ENOMSG 90 /* No message of desired type */ - #define TARGET_ELAST 90 /* Must be equal largest errno */ -+ -+/* pseudo-errors just used in the kernel/emulator: */ -+#define TARGET_ERESTART 255 /* restart syscall */ -+#define TARGET_EJUSTRETURN 254 /* Don't modify regs, just ret */ -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index 8270c37..1f8ee10 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -33,6 +33,7 @@ - { TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(%s,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL }, - { TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL }, - { TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL }, -@@ -51,7 +52,7 @@ - { TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL }, --{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL }, - { TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL }, -@@ -185,7 +186,7 @@ - { TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL }, -diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h -index 28481ce..51a2a7b 100644 ---- a/bsd-user/i386/target_signal.h -+++ b/bsd-user/i386/target_signal.h -@@ -3,11 +3,6 @@ - - #include "cpu.h" - --static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) --{ -- return state->regs[R_ESP]; --} -- - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -@@ -22,18 +17,32 @@ typedef struct target_ucontext { - int32_t __spare__[4]; - } target_ucontext_t; - --static inline int -+static inline abi_ulong -+get_sp_from_cpustate(CPUX86State *state) -+{ -+ return state->regs[R_ESP]; -+} -+ -+static inline abi_long - get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) - { - fprintf(stderr, "i386 doesn't have support for get_mcontext()\n"); - return (-TARGET_ENOSYS); - } - --static inline int -+static inline abi_long - set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) - { - fprintf(stderr, "i386 doesn't have support for set_mcontext()\n"); - return (-TARGET_ENOSYS); - } - -+static inline abi_long -+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ fprintf(stderr, "i386 doesn't have support for do_sigreturn()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/main.c b/bsd-user/main.c -index b6aaa7e..b248a91 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -35,6 +35,7 @@ - #include "tcg.h" - #include "qemu/timer.h" - #include "qemu/envlist.h" -+#include "target_signal.h" - - #if defined(CONFIG_USE_NPTL) && defined(__FreeBSD__) - #include <sys/thr.h> -@@ -813,15 +814,25 @@ void cpu_loop(CPUARMState *env) - arg6, - arg7, - arg8); -- if ((unsigned int)ret >= (unsigned int)(-515)) { -- ret = -ret; -- cpsr_write(env, CPSR_C, CPSR_C); -- env->regs[0] = ret; -- } else { -- cpsr_write(env, 0, CPSR_C); -- env->regs[0] = ret; // XXX need to handle lseek()? -- // env->regs[1] = 0; -- } -+ /* Compare to arm/arm/vm_machdep.c cpu_set_syscall_retval() */ -+ /* XXX armeb may need some extra magic here */ -+ if (-TARGET_EJUSTRETURN == ret) { -+ /* -+ * Returning from a successful sigreturn syscall. -+ * Avoid clobbering register state. -+ */ -+ break; -+ } -+ /* XXX Need to handle ERESTART. Backup the PC by 1 instruction*/ -+ if ((unsigned int)ret >= (unsigned int)(-515)) { -+ ret = -ret; -+ cpsr_write(env, CPSR_C, CPSR_C); -+ env->regs[0] = ret; -+ } else { -+ cpsr_write(env, 0, CPSR_C); -+ env->regs[0] = ret; // XXX need to handle lseek()? -+ // env->regs[1] = 0; -+ } - } else { - // XXX is this correct? - env->regs[0] = do_openbsd_syscall(env, -@@ -1068,13 +1079,20 @@ void cpu_loop(CPUMIPSState *env) - } - } - /* done_syscall: */ -- if (-TARGET_QEMU_ESIGRETURN == ret) { -+ /* -+ * Compare to mips/mips/vm_machdep.c -+ * cpu_set_syscall_retval() -+ * -+ * XXX need to handle lseek here. -+ */ -+ if (-TARGET_EJUSTRETURN == ret) { - /* - * Returning from a successful sigreturn - * syscall. Avoid clobbering register state. - */ - break; - } -+ /* XXX need to handle ERESTART */ - if ((unsigned int)ret >= (unsigned int)(-1133)) { - env->active_tc.gpr[7] = 1; - ret = -ret; -diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h -index 484cfd8..0f57f0f 100644 ---- a/bsd-user/mips/target_signal.h -+++ b/bsd-user/mips/target_signal.h -@@ -61,7 +61,7 @@ get_sp_from_cpustate(CPUMIPSState *state) - * Compare to mips/mips/pm_machdep.c sendsig() - * Assumes that "frame" memory is locked. - */ --static inline int -+static inline abi_long - set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - abi_ulong frame_addr, struct target_sigaction *ka) - { -@@ -98,7 +98,7 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - * Compare to mips/mips/pm_machdep.c get_mcontext() - * Assumes that the memory is locked if mcp points to user memory. - */ --static inline int -+static inline abi_long - get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) - { - int i, err = 0; -@@ -152,8 +152,8 @@ get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) - } - - /* Compare to mips/mips/pm_machdep.c set_mcontext() */ --static inline int --set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) -+static inline abi_long -+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int srflag) - { - int i, err = 0; - -@@ -184,9 +184,27 @@ set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) - regs->active_tc.HI[0] = tswapal(mcp->mulhi); - regs->tls_value = tswapal(mcp->mc_tls); - -+ if (srflag) { -+ /* doing sigreturn() */ -+ regs->active_tc.PC = regs->CP0_EPC; -+ regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+ } -+ - /* Don't do any of the status and cause registers. */ - - return (err); - } - -+/* mips/mips/pm_machdep.c sys_sigreturn() */ -+static inline abi_long -+get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ if (!lock_user_struct(VERIFY_READ, *ucontext, uc_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ *locked_addr = *ucontext; -+ return (0); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h -index f657909..3fee772 100644 ---- a/bsd-user/mips64/target_signal.h -+++ b/bsd-user/mips64/target_signal.h -@@ -58,7 +58,7 @@ get_sp_from_cpustate(CPUMIPSState *state) - #define TARGET_SZSIGCODE (4 * 4) - - /* Compare to mips/mips/locore.S sigcode() */ --static inline int -+static inline abi_long - install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned sys_sigreturn) - { - int i; -@@ -79,7 +79,7 @@ install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned sys_sigreturn) - * Compare to mips/mips/pm_machdep.c sendsig() - * Assumes that target stack frame memory is locked. - */ --static inline int -+static inline abi_long - set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - abi_ulong frame_addr, struct target_sigaction *ka) - { -@@ -117,7 +117,7 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, - * Compare to mips/mips/pm_machdep.c get_mcontext() - * Assumes that the memory is locked if mcp points to user memory. - */ --static inline int -+static inline abi_long - get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) - { - int i, err = 0; -@@ -171,8 +171,8 @@ get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) - } - - /* Compare to mips/mips/pm_machdep.c set_mcontext() */ --static inline int --set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) -+static inline abi_long -+set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int srflag) - { - int i, err = 0; - -@@ -203,10 +203,28 @@ set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, int flags) - regs->active_tc.HI[0] = tswapal(mcp->mulhi); - regs->tls_value = tswapal(mcp->mc_tls); - -+ if (srflag) { -+ /* doing sigreturn() */ -+ regs->active_tc.PC = regs->CP0_EPC; -+ regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+ } -+ - /* Don't do any of the status and cause registers. */ - - return (err); - } - -+/* mips/mips/pm_machdep.c sys_sigreturn() */ -+static inline abi_long -+get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ if (!lock_user_struct(VERIFY_READ, *ucontext, uc_addr, 0)) -+ return (-TARGET_EFAULT); -+ -+ *locked_addr = *ucontext; -+ return (0); -+} -+ - #endif /* TARGET_SIGNAL_H */ - -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index d51f50c..fbcdd6c 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -27,7 +27,6 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src, - #include "syscall_defs.h" - #include "syscall.h" - #include "target_vmparam.h" --#include "target_signal.h" - #include "exec/gdbstub.h" - - #if defined(CONFIG_USE_NPTL) -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index b04e874..e7e9e41 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -101,6 +101,9 @@ static struct target_sigaction sigact_table[TARGET_NSIG]; - - static void host_signal_handler(int host_signum, siginfo_t *info, void *puc); - -+static void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s); -+void QEMU_NORETURN force_sig(int target_sig); -+ - static inline int - on_sig_stack(unsigned long sp) - { -@@ -315,7 +318,7 @@ free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q) - } - - /* Abort execution with signal. */ --static void QEMU_NORETURN -+void QEMU_NORETURN - force_sig(int target_sig) - { - TaskState *ts = (TaskState *)thread_env->opaque; -@@ -728,194 +731,20 @@ give_sigsegv: - force_sig(TARGET_SIGSEGV); - } - --long --do_sigreturn(CPUArchState *regs, abi_ulong uc_addr) --{ -- target_ucontext_t *ucontext; -- sigset_t blocked; -- target_sigset_t target_set; -- int i; -- --#if defined(DEBUG_SIGNAL) -- fprintf(stderr, "do_sigreturn\n"); --#endif -- if (!lock_user_struct(VERIFY_READ, ucontext, uc_addr, 1)) -- goto badframe; -- -- for(i = 0; i < TARGET_NSIG_WORDS; i++) { -- if (__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i])) -- goto badframe; -- } -- -- if (set_mcontext(regs, &ucontext->uc_mcontext, 0)) -- goto badframe; -- -- target_to_host_sigset_internal(&blocked, &target_set); -- sigprocmask(SIG_SETMASK, &blocked, NULL); -- --#if defined(TARGET_MIPS) -- CPUMIPSState *mips_regs = (CPUMIPSState *)regs; -- mips_regs->active_tc.PC = mips_regs->CP0_EPC; -- mips_regs->CP0_EPC = 0; /* XXX for nested signals ? */ --#endif -- return (-TARGET_QEMU_ESIGRETURN); -- --badframe: -- force_sig(TARGET_SIGSEGV); -- return (0); --} -- -- -- --/* #elif defined(TARGET_SPARC64) */ --#if 0 -- --#define mc_flags mc_global[0] --#define mc_sp mc_out[6] --#define mc_fprs mc_local[0] --#define mc_fsr mc_local[1] --#define mc_qsr mc_local[2] --#define mc_tnpc mc_in[0] --#define mc_tpc mc_in[1] --#define mc_tstate mc_in[2] --#define mc_y mc_in[4] --#define mc_wstate mc_in[5] -- --#define ureg_i0 regwptr[0 ] --#define ureg_i1 regwptr[1 ] --#define ureg_i2 regwptr[2 ] --#define ureg_i3 regwptr[3 ] --#define ureg_i4 regwptr[4 ] --#define ureg_i5 regwptr[5 ] --#define ureg_i6 regwptr[6 ] --#define ureg_i7 regwptr[7 ] --#define ureg_l0 regwptr[8 ] --#define ureg_l1 regwptr[9 ] --#define ureg_l2 regwptr[10] --#define ureg_l3 regwptr[11] --#define ureg_l4 regwptr[12] --#define ureg_l5 regwptr[13] --#define ureg_l6 regwptr[14] --#define ureg_l7 regwptr[15] --#define ureg_o0 regwptr[16] --#define ureg_o1 regwptr[17] --#define ureg_o2 regwptr[18] --#define ureg_o3 regwptr[19] --#define ureg_o4 regwptr[20] --#define ureg_o5 regwptr[21] --#define ureg_o6 regwptr[22] --#define ureg_o7 regwptr[23] --#define ureg_fp ureg_i6 --#define ureg_sp ureg_o6 --#define ureg_tnpc ureg_i0 --#define ureg_tpc ureg_i1 -- --#define TARGET_FPRS_FEF (1 << 2) --#define TARGET_MC_VERSION 1L -- --/* compare to sparc64/sparc64/machdep.c set_mcontext() */ --static inline int --restore_sigmcontext(CPUSPARCState *regs, target_mcontext_t *mc) --{ -- int err = 0; -- -- err |= __get_user(regs->gregs[1], &mc->mc_global[1]); -- err |= __get_user(regs->gregs[2], &mc->mc_global[2]); -- err |= __get_user(regs->gregs[3], &mc->mc_global[3]); -- err |= __get_user(regs->gregs[4], &mc->mc_global[4]); -- err |= __get_user(regs->gregs[5], &mc->mc_global[5]); -- err |= __get_user(regs->gregs[6], &mc->mc_global[6]); -- -- err |= __get_user(regs->ureg_o0, &mc->mc_out[0]); -- err |= __get_user(regs->ureg_o1, &mc->mc_out[1]); -- err |= __get_user(regs->ureg_o2, &mc->mc_out[2]); -- err |= __get_user(regs->ureg_o3, &mc->mc_out[3]); -- err |= __get_user(regs->ureg_o4, &mc->mc_out[4]); -- err |= __get_user(regs->ureg_o5, &mc->mc_out[5]); -- err |= __get_user(regs->ureg_o6, &mc->mc_out[6]); -- err |= __get_user(regs->ureg_o7, &mc->mc_out[0]); -- -- err |= __get_user(regs->ureg_l0, &mc->mc_fprs); /* mc_local[0] */ -- err |= __get_user(regs->ureg_l1, &mc->mc_fsr); /* mc_local[1] */ -- err |= __get_user(regs->ureg_l2, &mc->mc_qsr); /* mc_local[2] */ -- -- err |= __get_user(regs->ureg_i0, &mc->mc_tnpc); /* mc_in[0] */ -- err |= __get_user(regs->ureg_i1, &mc->mc_tpc); /* mc_in[1] */ -- err |= __get_user(regs->ureg_i2, &mc->mc_tstate);/* mc_in[2] */ -- -- err |= __get_user(regs->ureg_i4, &mc->mc_y); /* mc_in[4] */ -- -- /* XXX -- if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) { -- regs->ureg_l0 = 0; -- for(i = 0; i < 64; i++) -- err |= __get_user(regs->fpr[i], &mc->mc_fp[i]); -- } -- */ -- -- return (err); --} -+#else - --/* compare to sparc64/sparc64/machdep.c get_mcontext() */ --static inline int --setup_sigmcontext(CPUSPARCState *regs, target_mcontext_t *mc) -+static void -+setup_frame(int sig, int code, struct target_sigaction *ka, target_sigset_t *set, -+ target_siginfo_t *tinfo, CPUArchState *env) - { -- int err = 0; -- abi_ulong ver = TARGET_MC_VERSION; -- -- err |= __put_user(ver, &mc->mc_flags); /* aka. mc_global[0] */ -- err |= __put_user(regs->gregs[1], &mc->mc_global[1]); -- err |= __put_user(regs->gregs[2], &mc->mc_global[2]); -- err |= __put_user(regs->gregs[3], &mc->mc_global[3]); -- err |= __put_user(regs->gregs[4], &mc->mc_global[4]); -- err |= __put_user(regs->gregs[5], &mc->mc_global[5]); -- err |= __put_user(regs->gregs[6], &mc->mc_global[6]); -- /* skip %g7 since it is used as the userland TLS register */ -- -- err |= __put_user(regs->ureg_o0, &mc->mc_out[0]); -- err |= __put_user(regs->ureg_o1, &mc->mc_out[1]); -- err |= __put_user(regs->ureg_o2, &mc->mc_out[2]); -- err |= __put_user(regs->ureg_o3, &mc->mc_out[3]); -- err |= __put_user(regs->ureg_o4, &mc->mc_out[4]); -- err |= __put_user(regs->ureg_o5, &mc->mc_out[5]); -- err |= __put_user(regs->ureg_o6, &mc->mc_out[6]); -- err |= __put_user(regs->ureg_o7, &mc->mc_out[7]); -- -- err |= __put_user(regs->ureg_l0, &mc->mc_fprs); /* mc_local[0] */ -- err |= __put_user(regs->ureg_l1, &mc->mc_fsr); /* mc_local[1] */ -- err |= __put_user(regs->ureg_l2, &mc->mc_qsr); /* mc_local[2] */ - -- err |= __put_user(regs->ureg_i0, &mc->mc_tnpc); /* mc_in[0] */ -- err |= __put_user(regs->ureg_i1, &mc->mc_tpc); /* mc_in[1] */ -- err |= __put_user(regs->ureg_i2, &mc->mc_tstate);/* mc_in[2] */ -- -- err |= __put_user(regs->ureg_i4, &mc->mc_y); /* mc_in[4] */ -- -- /* XXX -- if ((regs->ureg_l0 & TARGET_FPRS_FEF) != 0) { -- for(i = 0; i < 64; i++) -- err |= __put_user(regs->fpr[i], &mc->mc_fp[i]); -- } -- */ -- -- return (err); -+ fprintf(stderr, "setup_frame: not implemented\n"); - } - --static inline abi_ulong --get_sigframe(struct target_sigaction *ka, CPUSPARCState *regs, size_t frame_size) --{ -- abi_ulong sp; -+#endif /* ! TARGET_ARM && TARGET_MIPS */ - -- /* Use default user stack */ -- sp = regs->ureg_sp; -- -- if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { -- sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; -- } -- -- return (sp - frame_size); --} - -+#if 0 - /* compare to sparc64/sparc64/machdep.c sendsig() */ - static void setup_frame(int sig, int code, struct target_sigaction *ka, - target_sigset_t *set, target_siginfo_t *tinfo, CPUSPARCState *regs) -@@ -974,64 +803,60 @@ give_sigsegv: - unlock_user_struct(frame, frame_addr, 1); - force_sig(TARGET_SIGSEGV); - } -+#endif - -- --long do_sigreturn(CPUSPARCState *regs, abi_ulong uc_addr) -+static int -+reset_signal_mask(target_ucontext_t *ucontext) - { -- target_ucontext_t *ucontext; -+ int i; - sigset_t blocked; - target_sigset_t target_set; -- int i; - --#if defined(DEBUG_SIGNAL) -- fprintf(stderr, "do_sigreturn\n"); --#endif -- if (!lock_user_struct(VERIFY_READ, ucontext, uc_addr, 1)) -- goto badframe; -+ for(i = 0; i < TARGET_NSIG_WORDS; i++) -+ if (__get_user(target_set.__bits[i], -+ &ucontext->uc_sigmask.__bits[i])) { -+ return (-TARGET_EFAULT); -+ } -+ target_to_host_sigset_internal(&blocked, &target_set); -+ sigprocmask(SIG_SETMASK, &blocked, NULL); - -- for(i = 0; i < TARGET_NSIG_WORDS; i++) { -- if (__get_user(target_set.__bits[i], &ucontext->uc_sigmask.__bits[i])) -+ return (0); -+} -+ -+long -+do_sigreturn(CPUArchState *regs, abi_ulong addr) -+{ -+ int ret; -+ target_ucontext_t *ucontext; -+ void *locked_addr = NULL; -+ -+ /* Lock the memory and get the ucontext ptr from the stack frame */ -+ ret = get_ucontext_sigreturn(regs, addr, &ucontext, &locked_addr); -+ if (ret) { -+ if (-TARGET_EFAULT == ret) - goto badframe; -+ else -+ return (ret); - } - -- if (restore_sigmcontext(regs, &ucontext->uc_mcontext)) -+ /* Set the register state back to before the signal. */ -+ if (set_mcontext(regs, &ucontext->uc_mcontext, 1)) - goto badframe; - -- target_to_host_sigset_internal(&blocked, &target_set); -- sigprocmask(SIG_SETMASK, &blocked, NULL); -+ /* And reset the signal mask. */ -+ if (reset_signal_mask(ucontext)) -+ goto badframe; - -- return (-TARGET_QEMU_ESIGRETURN); -+ unlock_user_struct(locked_addr, addr, 0); -+ return (-TARGET_EJUSTRETURN); - - badframe: -+ if (locked_addr != NULL) -+ unlock_user_struct(locked_addr, addr, 0); - force_sig(TARGET_SIGSEGV); -- return (0); --} --#endif -- --#else -- --static void --setup_frame(int sig, int code, struct target_sigaction *ka, target_sigset_t *set, -- target_siginfo_t *tinfo, CPUArchState *env) --{ -- fprintf(stderr, "setup_frame: not implemented\n"); --} -- --long --do_sigreturn(CPUArchState *env, abi_ulong uc_addr) --{ -- fprintf(stderr,"do_sigreturn: not implemented\n"); -- return (-TARGET_ENOSYS); -+ return (-TARGET_EFAULT); - } - --long --do_rt_sigreturn(CPUArchState *env) --{ -- fprintf(stderr, "do_rt_sigreturn: not implemented\n"); -- return (-TARGET_ENOSYS); --} --#endif -- - void - signal_init(void) - { -diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h -index e2fe79c..65d315a 100644 ---- a/bsd-user/sparc/target_signal.h -+++ b/bsd-user/sparc/target_signal.h -@@ -43,4 +43,12 @@ set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) - return (-TARGET_ENOSYS); - } - -+static inline abi_long -+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ fprintf(stderr, "SPARC doesn't have support for do_sigreturn()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h -index 1bc7c96..fa8edb8 100644 ---- a/bsd-user/sparc64/target_signal.h -+++ b/bsd-user/sparc64/target_signal.h -@@ -245,4 +245,12 @@ set_mcontext(CPUSPARCState *regs, target_mcontext_t *mcp, int flags) - return (0); - } - -+static inline abi_long -+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ fprintf(stderr, "SPARC64 doesn't have support for do_sigreturn()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 636083a..2d97a23 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -90,12 +90,12 @@ - - #include "qemu.h" - #include "qemu-common.h" -+#include "target_signal.h" - #ifdef __FreeBSD__ - #include "freebsd/ttycom.h" - #include "freebsd/filio.h" - #endif - -- - //#define DEBUG - - static abi_ulong target_brk; -@@ -346,32 +346,47 @@ static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) - #endif - - #ifdef TARGET_ARM --static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) -+static abi_long do_freebsd_sysarch(CPUARMState *env, int op, abi_ulong parms) - { -+ int ret = 0; - - switch (op) { -+ case TARGET_FREEBSD_ARM_SYNC_ICACHE: -+ case TARGET_FREEBSD_ARM_DRAIN_WRITEBUF: -+ break; -+ - case TARGET_FREEBSD_ARM_SET_TP: - cpu_set_tls(env, parms); -- return 0; -+ break; -+ -+ case TARGET_FREEBSD_ARM_GET_TP: -+ /* XXX Need a cpu_get_tls() */ -+ if (put_user(env->cp15.c13_tls2, parms, abi_ulong)) -+ ret = -TARGET_EFAULT; -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; - } - -- return -TARGET_EINVAL; -+ return (ret); - } - #endif - - #ifdef TARGET_MIPS --static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) -+static abi_long do_freebsd_sysarch(CPUMIPSState *env, int op, abi_ulong parms) - { - int ret = 0; -- CPUMIPSState *mips_env = (CPUMIPSState *)env; - - switch(op) { - case TARGET_MIPS_SET_TLS: -- mips_env->tls_value = parms; -+ cpu_set_tls(env, parms); - break; - - case TARGET_MIPS_GET_TLS: -- if (put_user(mips_env->tls_value, parms, abi_ulong)) -+ /* XXX Need a cpu_get_tls() */ -+ if (put_user(env->tls_value, parms, abi_ulong)) - ret = -TARGET_EFAULT; - break; - default: -@@ -671,7 +686,7 @@ target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, - if (!target_saddr) - return -TARGET_EFAULT; - -- sa_family = tswap16(target_saddr->sa_family); -+ sa_family = target_saddr->sa_family; - - /* - * Oops. The caller might send a incomplete sun_path; sun_path -@@ -680,7 +695,7 @@ target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, - * "strlen(x->sun_path)" while it should be "strlen(...) + 1". We will - * fix that here if needed. - */ -- if (sa_family == AF_UNIX) { -+ if (target_saddr->sa_family == AF_UNIX) { - if (len < unix_maxlen && len > 0) { - char *cp = (char*)target_saddr; - -@@ -692,7 +707,8 @@ target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, - } - - memcpy(addr, target_saddr, len); -- addr->sa_family = sa_family; -+ addr->sa_family = sa_family; /* type uint8_t */ -+ addr->sa_len = target_saddr->sa_len; /* type uint8_t */ - unlock_user(target_saddr, target_addr, 0); - - return (0); -@@ -708,7 +724,8 @@ host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr, - if (!target_saddr) - return (-TARGET_EFAULT); - memcpy(target_saddr, addr, len); -- target_saddr->sa_family = tswap16(addr->sa_family); -+ target_saddr->sa_family = addr->sa_family; /* type uint8_t */ -+ target_saddr->sa_len = addr->sa_len; /* type uint8_t */ - unlock_user(target_saddr, target_addr, len); - - return (0); -@@ -1427,7 +1444,7 @@ static abi_long - do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, - socklen_t addrlen) - { -- void *addr; -+ struct sockaddr *saddr; - void *host_msg; - abi_long ret; - -@@ -1437,13 +1454,13 @@ do_sendto(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, - if (!host_msg) - return (-TARGET_EFAULT); - if (target_addr) { -- addr = alloca(addrlen); -- ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ saddr = alloca(addrlen); -+ ret = target_to_host_sockaddr(saddr, target_addr, addrlen); - if (ret) { - unlock_user(host_msg, msg, 0); - return (ret); - } -- ret = get_errno(sendto(fd, host_msg, len, flags, addr, -+ ret = get_errno(sendto(fd, host_msg, len, flags, saddr, - addrlen)); - } else { - ret = get_errno(send(fd, host_msg, len, flags)); -@@ -1458,7 +1475,7 @@ do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, - abi_ulong target_addrlen) - { - socklen_t addrlen; -- void *addr; -+ struct sockaddr *saddr; - void *host_msg; - abi_long ret; - -@@ -1474,16 +1491,16 @@ do_recvfrom(int fd, abi_ulong msg, size_t len, int flags, abi_ulong target_addr, - ret = (-TARGET_EINVAL); - goto fail; - } -- addr = alloca(addrlen); -- ret = get_errno(recvfrom(fd, host_msg, len, flags, addr, -+ saddr = alloca(addrlen); -+ ret = get_errno(recvfrom(fd, host_msg, len, flags, saddr, - &addrlen)); - } else { -- addr = NULL; /* To keep compiler quiet. */ -+ saddr = NULL; /* To keep compiler quiet. */ - ret = get_errno(qemu_recv(fd, host_msg, len, flags)); - } - if (!is_error(ret)) { - if (target_addr) { -- host_to_target_sockaddr(target_addr, addr, addrlen); -+ host_to_target_sockaddr(target_addr, saddr, addrlen); - if (put_user_u32(addrlen, target_addrlen)) { - ret = -TARGET_EFAULT; - goto fail; -@@ -5670,8 +5687,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - return (-TARGET_EFAULT); - fl.l_type = tswap16(target_fl->l_type); - fl.l_whence = tswap16(target_fl->l_whence); -- fl.l_start = tswapal(target_fl->l_start); -- fl.l_len = tswapal(target_fl->l_len); -+ fl.l_start = tswap64(target_fl->l_start); -+ fl.l_len = tswap64(target_fl->l_len); - fl.l_pid = tswap32(target_fl->l_pid); - fl.l_sysid = tswap32(target_fl->l_sysid); - unlock_user_struct(target_fl, arg3, 0); -@@ -5682,8 +5699,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - return (-TARGET_EFAULT); - target_fl->l_type = tswap16(fl.l_type); - target_fl->l_whence = tswap16(fl.l_whence); -- target_fl->l_start = tswapal(fl.l_start); -- target_fl->l_len = tswapal(fl.l_len); -+ target_fl->l_start = tswap64(fl.l_start); -+ target_fl->l_len = tswap64(fl.l_len); - target_fl->l_pid = tswap32(fl.l_pid); - target_fl->l_sysid = tswap32(fl.l_sysid); - unlock_user_struct(target_fl, arg3, 1); -@@ -5694,8 +5711,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_F_SETLKW: - if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) - return (-TARGET_EFAULT); -- fl.l_start = tswapal(target_fl->l_start); -- fl.l_len = tswapal(target_fl->l_len); -+ fl.l_start = tswap64(target_fl->l_start); -+ fl.l_len = tswap64(target_fl->l_len); - fl.l_pid = tswap32(target_fl->l_pid); - fl.l_type = tswap16(target_fl->l_type); - fl.l_whence = tswap16(target_fl->l_whence); -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index 8a92403..eb804b3 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -132,8 +132,8 @@ - #define TARGET_TRAP_TRACE (2) /* process trace trap */ - - struct target_rlimit { -- abi_ulong rlim_cur; -- abi_ulong rlim_max; -+ uint64_t rlim_cur; -+ uint64_t rlim_max; - }; - - #if defined(TARGET_ALPHA) -@@ -203,8 +203,8 @@ struct target_pollfd { - #include "openbsd/syscall_nr.h" - - struct target_flock { -- abi_long l_start; -- abi_long l_len; -+ int64_t l_start; -+ int64_t l_len; - int32_t l_pid; - int16_t l_type; - int16_t l_whence; -@@ -260,19 +260,29 @@ __target_cmsg_nxthdr (struct target_msghdr *__mhdr, - } - - struct target_sockaddr { -- uint16_t sa_family; -+ uint8_t sa_len; -+ uint8_t sa_family; - uint8_t sa_data[14]; --}; -+} QEMU_PACKED; - - struct target_in_addr { - uint32_t s_addr; /* big endian */ - }; - -+/* -+ * FreeBSD/{arm, mips} uses a 64bits time_t, even in 32bits mode, -+ * so we have to add a special case here. -+ */ -+#if defined(TARGET_ARM) || defined(TARGET_MIPS) -+typedef int64_t target_freebsd_time_t; -+#else -+typedef abi_long target_freebsd_time_t; -+#endif - - struct target_timeval { -- abi_long tv_sec; -+ target_freebsd_time_t tv_sec; - abi_long tv_usec; --}; -+} QEMU_PACKED; - - typedef abi_long target_clock_t; - -@@ -304,21 +314,13 @@ struct target_kevent { - abi_ulong udata; - } __packed; - --/* -- * FreeBSD/arm uses a 64bits time_t, even in 32bits mode, so we have to -- * add a special case here. -- */ --#if defined(TARGET_ARM) --typedef uint64_t target_freebsd_time_t; --#else --typedef long target_freebsd_time_t; --#endif - - struct target_freebsd_timespec { - target_freebsd_time_t tv_sec; /* seconds */ - abi_long tv_nsec; /* and nanoseconds */ - } __packed; - -+/* XXX We have target_*_timeval defined twice. */ - struct target_freebsd_timeval { - target_freebsd_time_t tv_sec; - abi_long tv_usec; -@@ -672,7 +674,7 @@ struct target_statfs { - uint64_t f_asyncreads; /* count of async reads since mount */ - uint64_t f_spare[10]; /* unused spare */ - uint32_t f_namemax; /* maximum filename length */ -- uid_t f_owner; /* user that mounted the filesystem */ -+ uint32_t f_owner; /* user that mounted the filesystem */ - target_fsid_t f_fsid; /* filesystem id */ - char f_charspare[80]; /* spare string space */ - char f_fstypename[TARGET_MFSNAMELEN]; /* filesys type name */ -diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h -index a14e0b9..72df2f0 100644 ---- a/bsd-user/x86_64/target_signal.h -+++ b/bsd-user/x86_64/target_signal.h -@@ -3,7 +3,8 @@ - - #include "cpu.h" - --static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) -+static inline abi_ulong -+get_sp_from_cpustate(CPUX86State *state) - { - return state->regs[R_ESP]; - } -@@ -26,18 +27,26 @@ typedef struct target_ucontext { - int32_t __spare__[4]; - } target_ucontext_t; - --static inline int -+static inline abi_long - get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) - { - fprintf(stderr, "x86_64 doesn't have support for get_mcontext()\n"); - return (-TARGET_ENOSYS); - } - --static inline int -+static inline abi_long - set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags) - { - fprintf(stderr, "x86_64 doesn't have support for set_mcontext()\n"); - return (-TARGET_ENOSYS); - } - -+static inline abi_long -+get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, -+ target_ucontext_t **ucontext, void **locked_addr) -+{ -+ fprintf(stderr, "x86_64 doesn't have support for do_sigreturn()\n"); -+ return (-TARGET_ENOSYS); -+} -+ - #endif /* TARGET_SIGNAL_H */ diff --git a/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b b/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b deleted file mode 100644 index 3700f5b9c65a..000000000000 --- a/emulators/qemu-devel/files/patch-zb2-bsd-user-sson004b +++ /dev/null @@ -1,1048 +0,0 @@ -diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h -index 05c9d1c..214d691 100644 ---- a/bsd-user/arm/target_signal.h -+++ b/bsd-user/arm/target_signal.h -@@ -67,6 +67,29 @@ struct target_sigframe { - target_ucontext_t sf_uc; /* saved ucontext */ - }; - -+/* compare to sys/arm/include/frame.h */ -+typedef struct target_trapframe { -+ abi_ulong tf_spsr; /* Zero on arm26 */ -+ abi_ulong tf_r0; -+ abi_ulong tf_r1; -+ abi_ulong tf_r2; -+ abi_ulong tf_r3; -+ abi_ulong tf_r4; -+ abi_ulong tf_r5; -+ abi_ulong tf_r6; -+ abi_ulong tf_r7; -+ abi_ulong tf_r8; -+ abi_ulong tf_r9; -+ abi_ulong tf_r10; -+ abi_ulong tf_r11; -+ abi_ulong tf_r12; -+ abi_ulong tf_usr_sp; -+ abi_ulong tf_usr_lr; -+ abi_ulong tf_svc_sp; /* Not used on arm26 */ -+ abi_ulong tf_svc_lr; /* Not used on arm26 */ -+ abi_ulong tf_pc; -+} target_trapframe_t; -+ - #define TARGET_SZSIGCODE (8 * 4) - - /* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */ -@@ -224,4 +247,22 @@ get_ucontext_sigreturn(CPUARMState *regs, abi_ulong sf_addr, - return (0); - } - -+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */ -+/* XXX crashes on first shared lib call */ -+static inline void -+thread_set_upcall(CPUARMState *regs, abi_ulong entry, abi_ulong arg, -+ abi_ulong stack_base, abi_ulong stack_size) -+{ -+ abi_ulong sp; -+ -+ sp = ((stack_base + stack_size) & (8 - 1)) - sizeof(struct target_trapframe); -+ -+ /* fp = sp = stack base */ -+ regs->regs[11] = regs->regs[13] = sp; -+ /* pc = start function entry */ -+ regs->regs[15] = regs->regs[14] = entry & 0xfffffffe; -+ /* r0 = arg */ -+ regs->regs[0] = arg; -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h -index bc50fbb..2186c68 100644 ---- a/bsd-user/arm/target_vmparam.h -+++ b/bsd-user/arm/target_vmparam.h -@@ -1,7 +1,19 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "arm" -+#define TARGET_HW_MACHINE_ARCH "armv6" -+ - #if defined(__FreeBSD__) -+ -+/* compare to arm/include/vmparam.h */ -+#define TARGET_MAXTSIZ (64UL*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (128UL*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (512UL*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (2UL*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (8UL*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ -+ - /* KERNBASE - 512 MB */ - #define TARGET_VM_MAXUSER_ADDRESS (0xc0000000 - (512 * 1024 * 1024)) - #define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS -@@ -18,10 +30,6 @@ struct target_ps_strings { - - #define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 7a7c3eb..da9ad73 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -701,13 +701,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - /* Create enough stack to hold everything. If we don't use - * it for args, we'll use it for something else... - */ --#ifdef TARGET_STACK_SIZE -- size = TARGET_STACK_SIZE; --#else -- size = x86_stack_size; -- if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) -- size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; --#endif -+ size = target_dflssiz; - - #ifdef TARGET_USRSTACK - stack_base = TARGET_USRSTACK - size; -diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h -index 51a2a7b..034b455 100644 ---- a/bsd-user/i386/target_signal.h -+++ b/bsd-user/i386/target_signal.h -@@ -45,4 +45,12 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, - return (-TARGET_ENOSYS); - } - -+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void -+thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg, -+ abi_ulong stack_base, abi_ulong stack_size) -+{ -+ fprintf(stderr, "i386 doesn't have support for thread_set_upcall()\n"); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/i386/target_vmparam.h b/bsd-user/i386/target_vmparam.h -index ea7546c..fb8493f 100644 ---- a/bsd-user/i386/target_vmparam.h -+++ b/bsd-user/i386/target_vmparam.h -@@ -1,8 +1,19 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "i386" -+#define TARGET_HW_MACHINE_ARCH "i386" -+ - #if defined(__FreeBSD__) - -+/* compare to i386/include/vmparam.h */ -+#define TARGET_MAXTSIZ (128UL*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (128UL*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (512UL*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (8UL*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (64UL*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ -+ - #define TARGET_USRSTACK (0xbfc00000) - - struct target_ps_strings { -@@ -19,10 +30,6 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/main.c b/bsd-user/main.c -index b248a91..99b94c1 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -54,10 +54,15 @@ const char *qemu_uname_release = CONFIG_ - extern char **environ; - enum BSDType bsd_type; - -+unsigned long target_maxtsiz = TARGET_MAXTSIZ; /* max text size */ -+unsigned long target_dfldsiz = TARGET_DFLDSIZ; /* initial data size limit */ -+unsigned long target_maxdsiz = TARGET_MAXDSIZ; /* max data size */ - /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so - we allocate a bigger stack. Need a better solution, for example - by remapping the process stack directly at the right place */ --unsigned long x86_stack_size = 512 * 1024; -+unsigned long target_dflssiz = TARGET_DFLSSIZ; /* initial data size limit */ -+unsigned long target_maxssiz = TARGET_MAXSSIZ; /* max stack size */ -+unsigned long target_sgrowsiz = TARGET_SGROWSIZ;/* amount to grow stack */ - - static void save_proc_pathname(void); - char qemu_proc_pathname[PATH_MAX]; -@@ -124,7 +129,7 @@ static int pending_cpus; - /* Make sure everything is in a consistent state for calling fork(). */ - void fork_start(void) - { -- pthread_mutex_lock(&tb_lock); -+ spin_lock(&tb_lock); - pthread_mutex_lock(&exclusive_lock); - mmap_fork_start(); - } -@@ -144,11 +149,11 @@ void fork_end(int child) - pthread_mutex_init(&cpu_list_mutex, NULL); - pthread_cond_init(&exclusive_cond, NULL); - pthread_cond_init(&exclusive_resume, NULL); -- pthread_mutex_init(&tb_lock, NULL); -+ spin_lock_init(&tb_lock); - gdbserver_fork(thread_env); - } else { - pthread_mutex_unlock(&exclusive_lock); -- pthread_mutex_unlock(&tb_lock); -+ spin_unlock(&tb_lock); - } - } - -@@ -1010,10 +1015,7 @@ void cpu_loop(CPUMIPSState *env) - - for(;;) { - cpu_exec_start(env); -- /* XXX there is a concurrency problem - giant lock for now */ -- pthread_mutex_lock(&exclusive_lock); /* XXX */ - trapnr = cpu_mips_exec(env); -- pthread_mutex_unlock(&exclusive_lock); /* XXX */ - cpu_exec_end(env); - switch(trapnr) { - case EXCP_SYSCALL: /* syscall exception */ -@@ -1480,7 +1482,7 @@ static void usage(void) - , - TARGET_ARCH, - interp_prefix, -- x86_stack_size); -+ target_dflssiz); - exit(1); - } - -@@ -1601,13 +1603,15 @@ int main(int argc, char **argv) - usage(); - } else if (!strcmp(r, "s")) { - r = argv[optind++]; -- x86_stack_size = strtol(r, (char **)&r, 0); -- if (x86_stack_size <= 0) -+ target_dflssiz = strtol(r, (char **)&r, 0); -+ if (target_dflssiz <= 0) - usage(); - if (*r == 'M') -- x86_stack_size *= 1024 * 1024; -+ target_dflssiz *= 1024 * 1024; - else if (*r == 'k' || *r == 'K') -- x86_stack_size *= 1024; -+ target_dflssiz *= 1024; -+ if (target_dflssiz > target_maxssiz) -+ usage(); - } else if (!strcmp(r, "L")) { - interp_prefix = argv[optind++]; - } else if (!strcmp(r, "p")) { -@@ -1791,7 +1795,7 @@ int main(int argc, char **argv) - qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry); - } - -- target_set_brk(info->brk); -+ target_set_brk(info->start_data, info->brk, info->end_data); - syscall_init(); - signal_init(); - -diff --git a/bsd-user/mips/target_signal.h b/bsd-user/mips/target_signal.h -index 0f57f0f..abe4587 100644 ---- a/bsd-user/mips/target_signal.h -+++ b/bsd-user/mips/target_signal.h -@@ -6,6 +6,10 @@ - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -+/* compare to sys/mips/include/asm.h */ -+#define TARGET_SZREG 4 -+#define TARGET_CALLFRAME_SIZ (TARGET_SZREG * 4) -+ - struct target_sigcontext { - target_sigset_t sc_mask; /* signal mask to retstore */ - int32_t sc_onstack; /* sigstack state to restore */ -@@ -207,4 +211,27 @@ get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr, - return (0); - } - -+/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void -+thread_set_upcall(CPUMIPSState *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ abi_ulong sp; -+ -+ /* -+ * At the point where a function is called, sp must be 8 -+ * byte aligned[for compatibility with 64-bit CPUs] -+ * in ``See MIPS Run'' by D. Sweetman, p. 269 -+ * align stack -+ */ -+ sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ; -+ -+ /* t9 = pc = start function entry */ -+ regs->active_tc.gpr[25] = regs->active_tc.PC = entry; -+ /* a0 = arg */ -+ regs->active_tc.gpr[ 4] = arg; -+ /* sp = top of the stack */ -+ regs->active_tc.gpr[29] = sp; -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h -index 8abc26c..6eca54f 100644 ---- a/bsd-user/mips/target_vmparam.h -+++ b/bsd-user/mips/target_vmparam.h -@@ -1,7 +1,19 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "mips" -+#define TARGET_HW_MACHINE_ARCH "mips" -+ - #if defined(__FreeBSD__) -+ -+/* compare to sys/mips/include/vmparam.h */ -+#define TARGET_MAXTSIZ (128UL*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (128UL*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (1*1024UL*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (8UL*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (64UL*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ -+ - #define TARGET_VM_MINUSER_ADDRESS (0x00000000) - #define TARGET_VM_MAXUSER_ADDRESS (0x80000000) - -@@ -21,10 +33,6 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h -index 3fee772..60105ec 100644 ---- a/bsd-user/mips64/target_signal.h -+++ b/bsd-user/mips64/target_signal.h -@@ -6,6 +6,10 @@ - #define TARGET_MINSIGSTKSZ (512 * 4) - #define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) - -+/* compare to sys/mips/include/asm.h */ -+#define TARGET_SZREG 8 -+#define TARGET_CALLFRAME_SIZ (TARGET_SZREG * 4) -+ - struct target_sigcontext { - target_sigset_t sc_mask; /* signal mask to retstore */ - int32_t sc_onstack; /* sigstack state to restore */ -@@ -226,5 +230,28 @@ get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr, - return (0); - } - -+/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void -+thread_set_upcall(CPUMIPSState *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ abi_ulong sp; -+ -+ /* -+ * At the point where a function is called, sp must be 8 -+ * byte aligned[for compatibility with 64-bit CPUs] -+ * in ``See MIPS Run'' by D. Sweetman, p. 269 -+ * align stack -+ */ -+ sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ; -+ -+ /* t9 = pc = start function entry */ -+ regs->active_tc.gpr[25] = regs->active_tc.PC = entry; -+ /* a0 = arg */ -+ regs->active_tc.gpr[ 4] = arg; -+ /* sp = top of the stack */ -+ regs->active_tc.gpr[29] = sp; -+} -+ - #endif /* TARGET_SIGNAL_H */ - -diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h -index 55ed254..3fe93fb 100644 ---- a/bsd-user/mips64/target_vmparam.h -+++ b/bsd-user/mips64/target_vmparam.h -@@ -1,8 +1,19 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "mips" -+#define TARGET_HW_MACHINE_ARCH "mips64" -+ - #if defined(__FreeBSD__) - -+/* compare to sys/mips/include/vmparam.h */ -+#define TARGET_MAXTSIZ (128UL*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (128UL*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (1*1024UL*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (8UL*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (64UL*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ -+ - #define TARGET_VM_MINUSER_ADDRESS (0x0000000000000000UL) - #define TARGET_VM_MAXUSER_ADDRESS (0x0000008000000000UL) - -@@ -20,10 +31,6 @@ struct target_ps_strings { - - #define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c -index 495f0ec..1ed597a 100644 ---- a/bsd-user/mmap.c -+++ b/bsd-user/mmap.c -@@ -31,8 +31,8 @@ - //#define DEBUG_MMAP - - #if defined(CONFIG_USE_NPTL) --pthread_mutex_t mmap_mutex; --static int __thread mmap_lock_count; -+pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER; -+static __thread int mmap_lock_count; - - void mmap_lock(void) - { -@@ -348,6 +348,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, - case MAP_SHARED: - printf("MAP_SHARED "); - break; -+ case MAP_STACK: -+ printf("MAP_STACK "); -+ break; - default: - printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK); - break; -@@ -356,6 +359,14 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, - } - #endif - -+ if (flags & MAP_STACK) { -+ if ((fd != -1) || -+ ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE))) { -+ errno = EINVAL; -+ goto fail; -+ } -+ } -+ - if (offset & ~TARGET_PAGE_MASK) { - errno = EINVAL; - goto fail; -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index fbcdd6c..4c20e48 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -147,7 +147,7 @@ int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs, - struct image_info * info); - int is_target_elf_binary(int fd); - --void target_set_brk(abi_ulong new_brk); -+void target_set_brk(abi_ulong start_brk, abi_ulong cur_brk, abi_ulong end_brk); - abi_long do_brk(abi_ulong new_brk); - void syscall_init(void); - abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -@@ -221,7 +221,12 @@ void mmap_fork_end(int child); - #endif - - /* main.c */ --extern unsigned long x86_stack_size; -+extern unsigned long target_maxtsiz; -+extern unsigned long target_dfldsiz; -+extern unsigned long target_maxdsiz; -+extern unsigned long target_dflssiz; -+extern unsigned long target_maxssiz; -+extern unsigned long target_sgrowsiz; - extern char qemu_proc_pathname[]; - extern char target_proc_pathname[]; - -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index e7e9e41..c4e8440 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -631,7 +631,7 @@ get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size) - target_sigaltstack_used.ss_size; - } - --#if defined(TARGET_MIPS) -+#if defined(TARGET_MIPS) || defined(TARGET_ARM) - return ((sp - frame_size) & ~7); - #else - return (sp - frame_size); -diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h -index 65d315a..20630d7 100644 ---- a/bsd-user/sparc/target_signal.h -+++ b/bsd-user/sparc/target_signal.h -@@ -51,4 +51,12 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, - return (-TARGET_ENOSYS); - } - -+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void -+thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg, -+ abi_ulong stack_base, abi_ulong stack_size) -+{ -+ fprintf(stderr, "SPARC doesn't have support for thread_set_upcall()\n"); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/sparc/target_vmparam.h b/bsd-user/sparc/target_vmparam.h -index 82c29ed..b8dcd0d 100644 ---- a/bsd-user/sparc/target_vmparam.h -+++ b/bsd-user/sparc/target_vmparam.h -@@ -1,7 +1,18 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "sparc" -+#define TARGET_HW_MACHINE_ARCH "sparc" -+ - #ifdef __FreeBSD__ -+ -+#define TARGET_MAXTSIZ (1*1024*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (128*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (1*1024*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (128*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (1*1024*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128*1024) /* amount to grow stack */ -+ - struct target_ps_strings { - abi_ulong ps_argvstr; - uint32_t ps_nargvstr; -@@ -20,10 +31,6 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h -index fa8edb8..67378a5 100644 ---- a/bsd-user/sparc64/target_signal.h -+++ b/bsd-user/sparc64/target_signal.h -@@ -253,4 +253,12 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, - return (-TARGET_ENOSYS); - } - -+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void -+thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg, -+ abi_ulong stack_base, abi_ulong stack_size) -+{ -+ fprintf(stderr, "SPARC64 doesn't have support for thread_set_upcall()\n"); -+} -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/sparc64/target_vmparam.h b/bsd-user/sparc64/target_vmparam.h -index 7f2b464..b8dbf2c 100644 ---- a/bsd-user/sparc64/target_vmparam.h -+++ b/bsd-user/sparc64/target_vmparam.h -@@ -1,7 +1,19 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "sparc" -+#define TARGET_HW_MACHINE_ARCH "sparc64" -+ - #if defined(__FreeBSD__) -+ -+/* compare to amd64/include/vmparam.h */ -+#define TARGET_MAXTSIZ (1*1024*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (128*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (1*1024*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (128*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (1*1024*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128*1024) /* amount to grow stack */ -+ - #define TARGET_VM_MINUSER_ADDRESS (0x0000000000000000UL) - #define TARGET_VM_MAXUSER_ADDRESS (0x000007fe00000000UL) - -@@ -21,10 +33,6 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 2d97a23..0f337e2 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -98,8 +98,7 @@ - - //#define DEBUG - --static abi_ulong target_brk; --static abi_ulong target_original_brk; -+static abi_ulong target_brk_start, target_brk_cur, target_brk_end; - - static char *get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len); - -@@ -123,6 +122,7 @@ get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len) - struct filestat *fst; - char *ret = NULL; - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - procstat = procstat_open_sysctl(); - if (NULL == procstat) - goto out; -@@ -152,6 +152,7 @@ out: - procstat_freeprocs(procstat, kipp); - if (procstat != NULL) - procstat_close(procstat); -+#endif - return (ret); - } - -@@ -188,41 +189,45 @@ static inline int is_error(abi_long ret) - return (abi_ulong)ret >= (abi_ulong)(-4096); - } - --void target_set_brk(abi_ulong new_brk) -+void target_set_brk(abi_ulong start_brk, abi_ulong cur_brk, abi_ulong end_brk) - { -- target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); -+ target_brk_start = HOST_PAGE_ALIGN(start_brk); -+ target_brk_cur = cur_brk; -+ target_brk_end = HOST_PAGE_ALIGN(end_brk); - } - - /* do_obreak() must return target errnos. */ - static abi_long do_obreak(abi_ulong new_brk) - { -- abi_ulong brk_page; - abi_long mapped_addr; -- int new_alloc_size; -+ abi_ulong new_alloc_size; -+ -+ return -TARGET_EINVAL; // XXX Temporary disable obreak() until it can be properly fixed - - if (!new_brk) - return 0; -- if (new_brk < target_original_brk) -+ if (new_brk < target_brk_cur) { - return -TARGET_EINVAL; -- -- brk_page = HOST_PAGE_ALIGN(target_brk); -+ } - - /* If the new brk is less than this, set it and we're done... */ -- if (new_brk < brk_page) { -- target_brk = new_brk; -+ if (new_brk < target_brk_end) { -+ target_brk_cur = new_brk; - return 0; - } - - /* We need to allocate more memory after the brk... */ -- new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); -- mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, -+ new_alloc_size = HOST_PAGE_ALIGN(new_brk - target_brk_end + 1); -+ mapped_addr = get_errno(target_mmap(target_brk_end, new_alloc_size, - PROT_READ|PROT_WRITE, - MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)); - -- if (!is_error(mapped_addr)) -- target_brk = new_brk; -- else -+ if (!is_error(mapped_addr)) { -+ target_brk_cur = new_brk; -+ target_brk_end += new_alloc_size; -+ } else { - return mapped_addr; -+ } - - return 0; - } -@@ -520,11 +525,7 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - case CTL_KERN: - switch(snamep[1]) { - case KERN_USRSTACK: --#if defined(TARGET_ARM) && HOST_LONG_BITS == 64 && TARGET_ABI_BITS == 32 -- (*(uint32_t *)holdp) = 0xfffff000U; -- holdlen = sizeof(uint32_t); -- ret = 0; --#elif TARGET_USRSTACK != 0 -+#if TARGET_USRSTACK != 0 - (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK); - holdlen = sizeof(abi_ulong); - ret = 0; -@@ -568,6 +569,22 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol - } - break; - -+ case CTL_HW: -+ switch(snamep[1]) { -+ case HW_MACHINE: -+ strlcpy(holdp, TARGET_HW_MACHINE, oldlen); -+ ret = 0; -+ goto out; -+ -+ case HW_MACHINE_ARCH: -+ strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen); -+ ret = 0; -+ goto out; -+ -+ default: -+ break; -+ } -+ - default: - break; - } -@@ -1736,7 +1753,9 @@ int_case: - case IP_RECVDSTADDR: - - case IP_RETOPTS: -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case IP_RECVTOS: -+#endif - case IP_MULTICAST_TTL: - case IP_MULTICAST_LOOP: - case IP_PORTRANGE: -@@ -2553,7 +2572,7 @@ do_fork(CPUArchState *env, int num, int flags, int *fdp) - static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER; - typedef struct { - CPUArchState *env; -- long tid; -+ long parent_tid; - pthread_mutex_t mutex; - pthread_cond_t cond; - pthread_t thread; -@@ -2571,24 +2590,23 @@ new_thread_start(void *arg) - - env = info->env; - thread_env = env; -+ fork_end(1); -+ - ts = (TaskState *)thread_env->opaque; - (void)thr_self(&tid); -- info->tid = tid; - task_settid(ts); - - /* copy out the TID info */ - if (info->param.child_tid) - put_user(tid, info->param.child_tid, abi_long); - if (info->param.parent_tid) -- put_user(tid, info->param.parent_tid, abi_long); -+ put_user(info->parent_tid, info->param.parent_tid, abi_long); - --#ifdef TARGET_MIPS64 -- CPUMIPSState *regs = env; -- regs->active_tc.gpr[25] = regs->active_tc.PC = info->param.start_func; -- regs->active_tc.gpr[ 4] = info->param.arg; -- regs->active_tc.gpr[29] = info->param.stack_base; --#endif -- /* Eenable signals */ -+ /* Set arch dependent registers to start thread. */ -+ thread_set_upcall(env, info->param.start_func, info->param.arg, -+ info->param.stack_base, info->param.stack_size); -+ -+ /* Enable signals */ - sigprocmask(SIG_SETMASK, &info->sigmask, NULL); - /* Signal to the parent that we're ready. */ - pthread_mutex_lock(&info->mutex); -@@ -2662,9 +2680,12 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size) - info.param.tls_size = tswapal(target_param->tls_size); - info.param.child_tid = tswapal(target_param->child_tid); - info.param.parent_tid = tswapal(target_param->parent_tid); -+ info.param.flags = tswap32(target_param->flags); - target_rtp_addr = info.param.rtp = tswapal(target_param->rtp); - unlock_user(target_param, target_param_addr, 0); - -+ thr_self(&info.parent_tid); -+ - if (target_rtp_addr) { - if (!lock_user_struct(VERIFY_READ, target_rtp, target_rtp_addr, - 1)) -@@ -2678,6 +2699,7 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size) - } - - /* Create a new CPU instance. */ -+ fork_start(); - ts = g_malloc0(sizeof(TaskState)); - init_task_state(ts); - new_env = cpu_copy(env); -@@ -2691,9 +2713,8 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size) - ts->bprm = parent_ts->bprm; - ts->info = parent_ts->info; - --#if defined(TARGET_MIPS) -- env->tls_value = info.param.tls_base; -- /* cpu_set_tls(new_env, info.param.tls_base); */ -+#if defined(TARGET_MIPS) || defined(TARGET_ARM) -+ cpu_set_tls(env, info.param.tls_base); - #endif - - /* Grab a mutex so that thread setup appears atomic. */ -@@ -2725,6 +2746,8 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size) - ret = pthread_create(&info.thread, &attr, new_thread_start, &info); - /* XXX Free new CPU state if thread creation fails. */ - -+ fork_end(0); -+ - sigprocmask(SIG_SETMASK, &info.sigmask, NULL); - pthread_attr_destroy(&attr); - if (0 == ret) { -@@ -2791,6 +2814,9 @@ do_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) - g_free(ts); - pthread_exit(NULL); - } -+ -+ gdb_exit(cpu_env, 0); /* XXX need to put in the correct exit status here? */ -+ _exit(0); - } - - static int -@@ -3010,7 +3036,7 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts, - int mode) - { - uint32_t owner, flags; -- int ret; -+ int ret = 0; - - for (;;) { - struct target_umutex *target_umutex; -@@ -3058,7 +3084,6 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts, - } - - __get_user(flags, &target_umutex->m_flags); -- flags = tswap32(flags); - if ((flags & TARGET_UMUTEX_ERROR_CHECK) != 0 && - (owner & ~TARGET_UMUTEX_CONTESTED) == id) { - unlock_user_struct(target_umutex, target_addr, 1); -@@ -3070,6 +3095,15 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts, - return (-TARGET_EBUSY); - } - -+ /* -+ * If we caught a signal, we have retried and now -+ * exit immediately. -+ */ -+ if (ret) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return (ret); -+ } -+ - /* Set the contested bit and sleep. */ - if (!tcmpset_32(&target_umutex->m_owner, owner, - owner | TARGET_UMUTEX_CONTESTED)) { -@@ -3084,8 +3118,6 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts, - owner = tswap32(owner); - ret = get_errno(_umtx_op(target_umutex, UMTX_OP_WAIT_UINT, owner, - 0, ts)); -- if (ret) -- return (ret); - } - - return (0); -@@ -4841,8 +4873,9 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_FREEBSD_NR_fstat: - { - struct stat st; -+ - ret = get_errno(fstat(arg1, &st)); -- if (! ret) -+ if (!is_error(ret)) - ret = host_to_target_stat(arg2, &st); - } - break; -@@ -4851,10 +4884,12 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - { - struct timespec req, rem; - -- target_to_host_timespec(&req, arg1); -- ret = get_errno(nanosleep(&req, &rem)); -- if (is_error(ret) && arg2) -- host_to_target_timespec(arg2, &rem); -+ ret = target_to_host_timespec(&req, arg1); -+ if (!is_error(ret)) { -+ ret = get_errno(nanosleep(&req, &rem)); -+ if (!is_error(ret) && arg2) -+ host_to_target_timespec(arg2, &rem); -+ } - } - break; - -@@ -5119,12 +5154,23 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - struct target_rlimit *target_rlim; - struct rlimit rlim; - -- /* Return the target stack size */ -- if (RLIMIT_STACK == resource) { -- rlim.rlim_cur = rlim.rlim_max = TARGET_STACK_SIZE; -+ switch (resource) { -+ case RLIMIT_STACK: -+ rlim.rlim_cur = target_dflssiz; -+ rlim.rlim_max = target_maxssiz; - ret = 0; -- } else -+ break; -+ -+ case RLIMIT_DATA: -+ rlim.rlim_cur = target_dfldsiz; -+ rlim.rlim_max = target_maxdsiz; -+ ret = 0; -+ break; -+ -+ default: - ret = get_errno(getrlimit(resource, &rlim)); -+ break; -+ } - if (!is_error(ret)) { - if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, - 0)) -@@ -7260,11 +7306,28 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - - #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - case TARGET_UMTX_OP_NWAKE_PRIVATE: -- if (! access_ok(VERIFY_READ, obj, -- val * sizeof(uint32_t))) -- goto efault; -- ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE, -- val, NULL, NULL)); -+ { -+ int i; -+ abi_ulong *uaddr; -+ -+ if (! access_ok(VERIFY_READ, obj, -+ val * sizeof(uint32_t))) -+ goto efault; -+ -+ ret = get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE, -+ val, NULL, NULL)); -+ -+ uaddr = (abi_ulong *)g2h(obj); -+ ret = 0; -+ for(i = 0; i < (int32_t)val; i++) { -+ ret = get_errno(_umtx_op(g2h(tswapal(uaddr[i])), -+ UMTX_OP_WAKE_PRIVATE, tswap32(INT_MAX), -+ NULL, NULL)); -+ if (ret) -+ break; -+ } -+ -+ } - break; - #endif - -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index eb804b3..c2e78bd 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -544,6 +544,7 @@ struct target_thr_param { - abi_ulong tls_size; /* tls size. */ - abi_ulong child_tid; /* address to store new TID. */ - abi_ulong parent_tid; /* parent access the new TID here. */ -+ int32_t flags; /* thread flags. */ - abi_ulong rtp; /* Real-time scheduling priority. */ - abi_ulong spare[3]; /* spares. */ - }; -diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h -index 72df2f0..51e32bf 100644 ---- a/bsd-user/x86_64/target_signal.h -+++ b/bsd-user/x86_64/target_signal.h -@@ -49,4 +49,13 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr, - return (-TARGET_ENOSYS); - } - -+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void -+thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg, -+ abi_ulong stack_base, abi_ulong stack_size) -+{ -+ fprintf(stderr, "x86_64 doesn't have support for thread_set_upcall()\n"); -+} -+ -+ - #endif /* TARGET_SIGNAL_H */ -diff --git a/bsd-user/x86_64/target_vmparam.h b/bsd-user/x86_64/target_vmparam.h -index ff9f534..70891a1 100644 ---- a/bsd-user/x86_64/target_vmparam.h -+++ b/bsd-user/x86_64/target_vmparam.h -@@ -1,7 +1,19 @@ - #ifndef _TARGET_VMPARAM_H_ - #define _TARGET_VMPARAM_H_ - -+#define TARGET_HW_MACHINE "amd64" -+#define TARGET_HW_MACHINE_ARCH "amd64" -+ - #if defined(__FreeBSD__) -+ -+/* compare to amd64/include/vmparam.h */ -+#define TARGET_MAXTSIZ (128UL*1024*1024) /* max text size */ -+#define TARGET_DFLDSIZ (32768UL*1024*1024) /* initial data size limit */ -+#define TARGET_MAXDSIZ (32768UL*1024*1024) /* max data size */ -+#define TARGET_DFLSSIZ (8UL*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (512UL*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ -+ - #define TARGET_VM_MAXUSER_ADDRESS (0x0000800000000000UL) - - #define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -@@ -20,10 +32,6 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - --/* Make stack size large enough to hold everything. */ --#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \ -- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size) -- - #else - - #define TARGET_USRSTACK 0 -diff --git a/include/exec/spinlock.h b/include/exec/spinlock.h -index a72edda..fc1f808 100644 ---- a/include/exec/spinlock.h -+++ b/include/exec/spinlock.h -@@ -24,6 +24,7 @@ - #include <pthread.h> - #define spin_lock pthread_mutex_lock - #define spin_unlock pthread_mutex_unlock -+#define spin_lock_init(mtx) pthread_mutex_init(mtx, NULL) - #define spinlock_t pthread_mutex_t - #define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER - -diff --git a/include/qemu/tls.h b/include/qemu/tls.h -index b92ea9d..ae7d79d 100644 ---- a/include/qemu/tls.h -+++ b/include/qemu/tls.h -@@ -38,7 +38,7 @@ - * TODO: proper implementations via Win32 .tls sections and - * POSIX pthread_getspecific. - */ --#ifdef __linux__ -+#if defined(__linux__) || defined(__FreeBSD__) - #define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x) - #define DEFINE_TLS(type, x) __thread __typeof__(type) tls__##x - #define tls_var(x) tls__##x diff --git a/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c b/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c deleted file mode 100644 index 2101ab2bdd16..000000000000 --- a/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c +++ /dev/null @@ -1,186 +0,0 @@ -diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c -index dcf6f66..83ff852 100644 ---- a/bsd-user/bsdload.c -+++ b/bsd-user/bsdload.c -@@ -154,19 +154,77 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, - return sp; - } - -+static int -+is_there(const char *candidate) -+{ -+ struct stat fin; -+ -+ /* XXX work around access(2) false positives for superuser */ -+ if (access(candidate, X_OK) == 0 && -+ stat(candidate, &fin) == 0 && -+ S_ISREG(fin.st_mode) && -+ (getuid() != 0 || -+ (fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) { -+ return (1); -+ } -+ return (0); -+} -+ -+static int -+find_in_path(char *path, const char *filename, char *retpath, size_t rpsize) -+{ -+ const char *d; -+ int found; -+ -+ if (strchr(filename, '/') != NULL) -+ return (is_there(filename) ? 0 : -1); -+ found = 0; -+ while ((d = strsep(&path, ":")) != NULL) { -+ if (*d == '\0') -+ d = "."; -+ if (snprintf(retpath, rpsize, "%s/%s", d, -+ filename) >= (int)rpsize) -+ continue; -+ if (is_there((const char *)retpath)) { -+ found = 1; -+ break; -+ } -+ } -+ return (found); -+} -+ - int loader_exec(const char * filename, char ** argv, char ** envp, - struct target_pt_regs * regs, struct image_info *infop, - struct bsd_binprm *bprm) - { - int retval; - int i; -+ char *p, *path, fullpath[PATH_MAX]; -+ ssize_t pathlen; - - bprm->p = TARGET_PAGE_SIZE*MAX_ARG_PAGES /*-sizeof(unsigned int) XXX */; - for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */ - bprm->page[i] = NULL; -- retval = open(filename, O_RDONLY); -+ -+ /* Find target executable in path, if not already fullpath. */ -+ if ((p = getenv("PATH")) != NULL) { -+ pathlen = strlen(p) + 1; -+ path = malloc(pathlen); -+ if (NULL == path) { -+ fprintf(stderr, "Out of memory\n"); -+ return (-1); -+ } -+ memcpy(path, p, pathlen); -+ if (find_in_path(path, filename, fullpath, sizeof(fullpath))) -+ retval = open(fullpath, O_RDONLY); -+ else -+ retval = open(filename, O_RDONLY); -+ -+ } else -+ retval = open(filename, O_RDONLY); - if (retval < 0) - return retval; -+ - bprm->fd = retval; - bprm->filename = (char *)filename; - bprm->argc = count(argv); -diff --git a/bsd-user/main.c b/bsd-user/main.c -index 99b94c1..9b526b3 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -1022,7 +1022,7 @@ void cpu_loop(CPUMIPSState *env) - switch(trapnr) { - case EXCP_SYSCALL: /* syscall exception */ - syscall_num = env->active_tc.gpr[2]; /* v0 */ -- env->active_tc.PC += 4; -+ env->active_tc.PC += TARGET_INSN_SIZE; - if (syscall_num >= SYS_MAXSYSCALL) { - ret = -TARGET_ENOSYS; - } else { -@@ -1094,7 +1094,11 @@ void cpu_loop(CPUMIPSState *env) - */ - break; - } -- /* XXX need to handle ERESTART */ -+ if (-TARGET_ERESTART == ret) { -+ /* Backup the pc to point at the swi. */ -+ env->active_tc.PC -= TARGET_INSN_SIZE; -+ break; -+ } - if ((unsigned int)ret >= (unsigned int)(-1133)) { - env->active_tc.gpr[7] = 1; - ret = -ret; -diff --git a/bsd-user/mips/target_vmparam.h b/bsd-user/mips/target_vmparam.h -index 6eca54f..abdb1dc 100644 ---- a/bsd-user/mips/target_vmparam.h -+++ b/bsd-user/mips/target_vmparam.h -@@ -33,6 +33,8 @@ struct target_ps_strings { - - #define TARGET_SZSIGCODE 0 - -+#define TARGET_INSN_SIZE 4 -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/mips64/target_vmparam.h b/bsd-user/mips64/target_vmparam.h -index 3fe93fb..3a3bb6e 100644 ---- a/bsd-user/mips64/target_vmparam.h -+++ b/bsd-user/mips64/target_vmparam.h -@@ -31,6 +31,8 @@ struct target_ps_strings { - - #define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings)) - -+#define TARGET_INSN_SIZE 4 -+ - #else - - #define TARGET_USRSTACK 0 -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index c4e8440..a26d40a 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -122,8 +122,9 @@ int - host_to_target_signal(int sig) - { - -- if (sig >= _NSIG) -+ if (sig < 0 || sig >= _NSIG) - return (sig); -+ - return (host_to_target_signal_table[sig]); - } - -@@ -598,11 +599,13 @@ do_sigaction(int sig, const struct target_sigaction *act, - if (k->_sa_handler == TARGET_SIG_IGN) { - act1.sa_sigaction = (void *)SIG_IGN; - } else if (k->_sa_handler == TARGET_SIG_DFL) { -- if (fatal_signal(sig)) -+ if (fatal_signal(sig)) { -+ act1.sa_flags = SA_SIGINFO; - act1.sa_sigaction = - host_signal_handler; -- else -+ } else { - act1.sa_sigaction = (void *)SIG_DFL; -+ } - } else { - act1.sa_flags = SA_SIGINFO; - act1.sa_sigaction = host_signal_handler; -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 0f337e2..490227c 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -3120,6 +3120,15 @@ do_lock_umutex(abi_ulong target_addr, uint32_t id, struct timespec *ts, - 0, ts)); - } - -+ if (NULL == ts) { -+ /* -+ * In the case of no timeout do a restart on this syscall, -+ * if interrupted. -+ */ -+ if (-TARGET_EINTR == ret) -+ ret = -TARGET_ERESTART; -+ } -+ - return (0); - } - diff --git a/emulators/qemu-devel/files/patch-zb4-bsd-user-main.c b/emulators/qemu-devel/files/patch-zb4-bsd-user-main.c deleted file mode 100644 index 037e471efd01..000000000000 --- a/emulators/qemu-devel/files/patch-zb4-bsd-user-main.c +++ /dev/null @@ -1,129 +0,0 @@ ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -129,7 +129,7 @@ static int pending_cpus; - /* Make sure everything is in a consistent state for calling fork(). */ - void fork_start(void) - { -- spin_lock(&tb_lock); -+ spin_lock(&tcg_ctx.tb_ctx.tb_lock); - pthread_mutex_lock(&exclusive_lock); - mmap_fork_start(); - } -@@ -149,11 +149,11 @@ void fork_end(int child) - pthread_mutex_init(&cpu_list_mutex, NULL); - pthread_cond_init(&exclusive_cond, NULL); - pthread_cond_init(&exclusive_resume, NULL); -- spin_lock_init(&tb_lock); -+ spin_lock_init(&tcg_ctx.tb_ctx.tb_lock); - gdbserver_fork(thread_env); - } else { - pthread_mutex_unlock(&exclusive_lock); -- spin_unlock(&tb_lock); -+ spin_unlock(&tcg_ctx.tb_ctx.tb_lock); - } - } - -@@ -174,6 +174,7 @@ static inline void - start_exclusive(void) - { - CPUArchState *other; -+ CPUState *other_cpu; - - pthread_mutex_lock(&exclusive_lock); - exclusive_idle(); -@@ -181,7 +182,8 @@ start_exclusive(void) - pending_cpus = 1; - /* Make all other cpus stop executing. */ - for (other = first_cpu; other; other = other->next_cpu) { -- if (other->running) { -+ other_cpu = ENV_GET_CPU(other); -+ if (other_cpu->running) { - pending_cpus++; - cpu_exit(other); - } -@@ -202,20 +204,20 @@ end_exclusive(void) - - /* Wait for exclusive ops to finish, and begin cpu execution. */ - static inline void --cpu_exec_start(CPUArchState *env) -+cpu_exec_start(CPUState *cpu) - { - pthread_mutex_lock(&exclusive_lock); - exclusive_idle(); -- env->running = 1; -+ cpu->running = true; - pthread_mutex_unlock(&exclusive_lock); - } - - /* Mark cpu as not excuting, and release pending exclusive ops. */ - static inline void --cpu_exec_end(CPUArchState *env) -+cpu_exec_end(CPUState *cpu) - { - pthread_mutex_lock(&exclusive_lock); -- env->running = 0; -+ cpu->running = false; - if (pending_cpus > 1) { - pending_cpus--; - if (pending_cpus == 1) { -@@ -270,13 +272,13 @@ end_exclusive(void) - } - - static inline void --cpu_exec_start(CPUArchState *env) -+cpu_exec_start(CPUState *cpu) - { - } - - - static inline void --cpu_exec_end(CPUArchState *env) -+cpu_exec_end(CPUState *cpu) - { - } - -@@ -657,6 +659,7 @@ done: - - void cpu_loop(CPUARMState *env) - { -+ CPUState *cs = CPU(arm_env_get_cpu(env)); - int trapnr; - unsigned int n, insn; - uint32_t addr; -@@ -665,7 +668,7 @@ void cpu_loop(CPUARMState *env) - #ifdef DEBUG_ARM - printf("CPU LOOPING\n"); - #endif -- cpu_exec_start(env); -+ cpu_exec_start(cs); - #ifdef DEBUG_ARM - printf("EXECUTING...\n"); - #endif -@@ -673,7 +676,7 @@ void cpu_loop(CPUARMState *env) - #ifdef DEBUG_ARM - printf("trapnr %d\n", trapnr); - #endif -- cpu_exec_end(env); -+ cpu_exec_end(cs); - switch(trapnr) { - case EXCP_UDEF: - { -@@ -1008,15 +1011,16 @@ static int do_store_exclusive(CPUMIPSSta - - void cpu_loop(CPUMIPSState *env) - { -+ CPUState *cs = CPU(mips_env_get_cpu(env)); - target_siginfo_t info; - int trapnr; - abi_long ret; - unsigned int syscall_num; - - for(;;) { -- cpu_exec_start(env); -+ cpu_exec_start(cs); - trapnr = cpu_mips_exec(env); -- cpu_exec_end(env); -+ cpu_exec_end(cs); - switch(trapnr) { - case EXCP_SYSCALL: /* syscall exception */ - syscall_num = env->active_tc.gpr[2]; /* v0 */ diff --git a/emulators/qemu-devel/pkg-plist b/emulators/qemu-devel/pkg-plist index 9ea1e6ec5a31..98b4e9498c7c 100644 --- a/emulators/qemu-devel/pkg-plist +++ b/emulators/qemu-devel/pkg-plist @@ -30,6 +30,7 @@ bin/qemu-system-i386 %%BSD_USER%%bin/qemu-i386 %%BSD_USER%%bin/qemu-mips %%BSD_USER64%%bin/qemu-mips64 +%%BSD_USER64%%bin/qemu-mips64el %%BSD_USER%%bin/qemu-mipsel %%BSD_USER%%bin/qemu-sparc %%BSD_USER64%%bin/qemu-sparc64 @@ -84,6 +85,7 @@ etc/qemu/target-x86_64.conf.sample %%DATADIR%%/bamboo.dtb %%DATADIR%%/kvmvapic.bin %%DATADIR%%/qemu-icon.bmp +%%DATADIR%%/qemu_logo_no_text.svg %%DATADIR%%/keymaps/ar %%DATADIR%%/keymaps/bepo %%DATADIR%%/keymaps/common @@ -123,6 +125,7 @@ etc/qemu/target-x86_64.conf.sample %%GTK2%%share/locale/de_DE/LC_MESSAGES/qemu.mo %%GTK2%%share/locale/fr_FR/LC_MESSAGES/qemu.mo %%GTK2%%share/locale/it/LC_MESSAGES/qemu.mo +%%GTK2%%share/locale/hu/LC_MESSAGES/qemu.mo %%GTK2%%share/locale/tr/LC_MESSAGES/qemu.mo @dirrm %%DATADIR%%/keymaps %%GTK2%%@dirrmtry share/locale/de_DE/LC_MESSAGES |