Index: qemu-devel/Makefile =================================================================== --- qemu-devel/Makefile (revision 11252) +++ qemu-devel/Makefile (working copy) @@ -3,6 +3,7 @@ PORTNAME= qemu PORTVERSION= 1.4.0 +PORTREVISION= 1 CATEGORIES= emulators MASTER_SITES= http://wiki.qemu.org/download/:release \ LOCAL/nox:snapshot @@ -31,7 +32,7 @@ MAKE_JOBS_SAFE= yes OPTIONS_DEFINE= SAMBA SDL OPENGL GNUTLS SASL JPEG PNG CDROM_DMA PCAP \ - USBREDIR GNS3 ADD_AUDIO CLANG_HACK X86_TARGETS BSD_USER \ + USBREDIR GNS3 ADD_AUDIO X86_TARGETS BSD_USER \ STATIC_LINK SAMBA_DESC= samba dependency (for -smb) GNUTLS_DESC= gnutls dependency (vnc encryption) @@ -44,7 +45,6 @@ USBREDIR_DESC= usb device network redirection (experimental!) GNS3_DESC= gns3 patches (promiscuous multicast) ADD_AUDIO_DESC= Emulate more audio hardware (experimental!) -CLANG_HACK_DESC= clang workaround (result slow and less stable!) X86_TARGETS_DESC= Don't build non-x86 system targets BSD_USER_DESC= Also build bsd-user targets (for testing) STATIC_LINK_DESC= Statically link the executables @@ -55,16 +55,6 @@ CONFIGURE_ARGS+= --extra-ldflags=-L${LOCALBASE}/lib PORTDOCS= docs qemu-doc.html qemu-tech.html qmp-commands.txt -# XXX this fixes build with clang but --enable-tcg-interpreter that's -# needed to avoid global register usage that clang doesn't support -# causes the result to be slow and less stable. -.if ${PORT_OPTIONS:MCLANG_HACK} -CONFIGURE_ARGS+= --enable-tcg-interpreter -CLANG_CFLAGS_AS+= -no-integrated-as -.else -USE_GCC= any -.endif - .if ${PORT_OPTIONS:MX86_TARGETS} .if ${PORT_OPTIONS:MBSD_USER} .if ${ARCH} != "amd64" @@ -230,9 +220,6 @@ -e "s|^(LDFLAGS=).*|\1${LDFLAGS}|" \ ${WRKSRC}/Makefile @${REINPLACE_CMD} -E \ - -e "s|^(CFLAGS[ ]*:=.*)|\1 ${CLANG_CFLAGS_AS}|" \ - ${WRKSRC}/pc-bios/optionrom/Makefile - @${REINPLACE_CMD} -E \ -e "1s|^(#! )/usr/bin/perl|\1${PERL}|" \ ${WRKSRC}/scripts/texi2pod.pl Index: qemu-devel/files/patch-za-bsd-user-8fix =================================================================== --- qemu-devel/files/patch-za-bsd-user-8fix (revision 10817) +++ qemu-devel/files/patch-za-bsd-user-8fix (working copy) @@ -1,28 +1,12 @@ --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c -@@ -123,6 +123,7 @@ get_filename_from_fd(pid_t pid, int fd, - struct filestat *fst; - char *ret = NULL; - +@@ -106,7 +106,9 @@ static char *get_filename_from_fd(pid_t + #ifdef __FreeBSD__ + #include + #include +#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - procstat = procstat_open_sysctl(); - if (NULL == procstat) - goto out; -@@ -152,6 +153,7 @@ out: - procstat_freeprocs(procstat, kipp); - if (procstat != NULL) - procstat_close(procstat); + #include +#endif - return (ret); - } -@@ -1739,7 +1741,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: + /* Index: qemu-devel/files/patch-zb2-bsd-user-sson004b =================================================================== --- qemu-devel/files/patch-zb2-bsd-user-sson004b (revision 0) +++ qemu-devel/files/patch-zb2-bsd-user-sson004b (working copy) @@ -0,0 +1,1048 @@ +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 +@@ -56,10 +56,15 @@ const char *qemu_uname_release = CONFIG_UNAME_RELEASE; + 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]; +@@ -126,7 +131,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(); + } +@@ -146,11 +151,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); + } + } + +@@ -1012,10 +1017,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 */ +@@ -1481,7 +1483,7 @@ static void usage(void) + , + TARGET_ARCH, + interp_prefix, +- x86_stack_size, ++ target_dflssiz, + DEBUG_LOGFILE); + exit(1); + } +@@ -1603,13 +1605,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")) { +@@ -1797,7 +1801,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 + #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 Property changes on: qemu-devel/files/patch-zb2-bsd-user-sson004b ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property