mirror of
https://git.freebsd.org/ports.git
synced 2025-06-25 14:40:32 -04:00
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]
186 lines
4.9 KiB
Text
186 lines
4.9 KiB
Text
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);
|
|
}
|
|
|