summaryrefslogtreecommitdiff
path: root/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c
diff options
context:
space:
mode:
authorJuergen Lock <nox@FreeBSD.org>2013-05-05 20:27:15 +0000
committerJuergen Lock <nox@FreeBSD.org>2013-05-05 20:27:15 +0000
commit56931a5c0c35432ba64120ff13885f60b9508c40 (patch)
tree4ca5e5438834e4431f966a66492298e94d473152 /emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c
parent. Update to 7u21. (diff)
- Update to 1.4.1, announce posting is here:
https://lists.gnu.org/archive/html/qemu-devel/2013-04/msg02956.html - Update to sson's latest bsd-user patches. - Add bugfix for mips64 target uncovered by --enable-debug. [1] Obtained from: qemu-devel mailinglist [1]
Notes
Notes: svn path=/head/; revision=317432
Diffstat (limited to 'emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c')
-rw-r--r--emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c186
1 files changed, 186 insertions, 0 deletions
diff --git a/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c b/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c
new file mode 100644
index 000000000000..2101ab2bdd16
--- /dev/null
+++ b/emulators/qemu-devel/files/patch-zb3-bsd-user-sson004c
@@ -0,0 +1,186 @@
+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);
+ }
+