Permalink
Browse files

Fix sysctl and getrlimit to return correct USRSTACK, PS_STRINGS, & st…

…ack size.
  • Loading branch information...
1 parent 67a4b95 commit 28b28e1b4615526b32478eb02f07f9c2acad550f @staceyson committed Feb 18, 2013
@@ -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
@@ -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.)
@@ -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
@@ -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);
@@ -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
@@ -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
@@ -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_ */
@@ -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
@@ -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);
@@ -4617,12 +4642,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 +4663,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))
@@ -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

0 comments on commit 28b28e1

Please sign in to comment.