mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
pull-bsd-user-20210511 is the next round of cleanups to bsd-user in merging the
bsd-user fork into qemu. It contains a number of style commits, as well as 3 commits that start to change things: Some unused files are deleted, building the sparc and sparc64 targets are removed, and a structure is renamed. The next set of pull requests will start to execute the following plan: 1. Move existing code around to have a structure similar to the bsd-user fork. 2. Incrementally merge groups of system calls, focused on making x86 work. 3. Once the groups of system calls are all merged, additional platforms will be added back. 4. Concurrently, as changes are requested as part of the merge happen, those changes will be merged into the fork. An experimental merge to tip of master is under test and is what will be updated. 5. Eventually, there will be no diference, and the bsd-user fork will only be a staging area for cutting-edge features prior to upstreaming into qemu mainline. The bsd-user code in qemu has a lot of style issues. This cleans up a number in the files touched. However, the checkpatch.pl detects some incremental issues in the commits. The following are expected, but are corrected in later hashes in this branch. MAINTAINERS does not need to be updated, since all the files added or deleted are covered under existing regexp in MAINTAINERS. Checking all commits since f9a576a818044133f8564e0d243ebd97df0b3280... d60c3b932e2fa06aba5d7aa1c451b5d287095dc8:101: ERROR: consider using qemu_strtol in preference to strtol d60c3b932e2fa06aba5d7aa1c451b5d287095dc8:142: ERROR: braces {} are necessary for all arms of this statement d60c3b932e2fa06aba5d7aa1c451b5d287095dc8:145: ERROR: braces {} are necessary for all arms of this statement total: 3 errors, 0 warnings, 119 lines checked b4bebeee1dee8d333bfa105a6c28fec5eb34b147:148: WARNING: line over 80 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:330: ERROR: braces {} are necessary for all arms of this statement b4bebeee1dee8d333bfa105a6c28fec5eb34b147:340: ERROR: braces {} are necessary for all arms of this statement b4bebeee1dee8d333bfa105a6c28fec5eb34b147:381: ERROR: space prohibited between function name and open parenthesis '(' b4bebeee1dee8d333bfa105a6c28fec5eb34b147:390: ERROR: spaces required around that '<' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:408: WARNING: Block comments use a leading /* on a separate line b4bebeee1dee8d333bfa105a6c28fec5eb34b147:409: WARNING: Block comments use * on subsequent lines b4bebeee1dee8d333bfa105a6c28fec5eb34b147:409: WARNING: Block comments use a trailing */ on a separate line b4bebeee1dee8d333bfa105a6c28fec5eb34b147:441: WARNING: line over 80 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:445: WARNING: line over 80 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:502: ERROR: line over 90 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:551: ERROR: space required after that ',' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:552: ERROR: space required after that ',' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:587: ERROR: space required after that ';' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:623: ERROR: suspect code indent for conditional statements (12, 14) total: 9 errors, 6 warnings, 664 lines checked 86545e7afe3f822b8561c7ceee7540fc3b19c3f0:31: ERROR: space required after that ';' (ctx:VxV) 86545e7afe3f822b8561c7ceee7540fc3b19c3f0:40: ERROR: space required after that ';' (ctx:VxV) total: 2 errors, 0 warnings, 60 lines checked Use of uninitialized value $acpi_testexpected in string eq at scripts/checkpatch.pl line 1529. 65d58c91ef1a15ad945ece367983437576f8e82b:22: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? total: 0 errors, 1 warnings, 14 lines checked Use of uninitialized value $acpi_testexpected in string eq at scripts/checkpatch.pl line 1529. f8ce39701b5be032fb3f9c05e8adb4055f70eec2:21: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? total: 0 errors, 1 warnings, 0 lines checked FAIL one or more commits failed scripts/checkpatch.pl Cleaning up file based variables ERROR: Job failed: exit code 1 -----BEGIN PGP SIGNATURE----- Comment: GPGTools - https://gpgtools.org iQIzBAABCgAdFiEEIDX4lLAKo898zeG3bBzRKH2wEQAFAmCcBQIACgkQbBzRKH2w EQD4+A/9E3Yr7cIBegz0km6pTHX89y6AW4+qd6QkQgYkZ9PloIVCjSn3NxvvPy3d sCVhZu2FutEuoI2EOjzBpgQCp8mhSfayPKiZIzvHeJn9yiTmNnuHd/Opr2NaxkUV WT9Eli7aB5AhYL1AD6RVEyYQYQJLq/ULdJXUVaOe5X2werk/FT7izhVqA4hkMFUm Rx3RrMZDAyhgPT1+EUrNMgw2/dQw7QEH3w0RREc/Btfs8Wwisqq+Uy0Z8p9+khSU K5ES6FnYAoOU9EP1LMjOzuh54B2Ta9J0Z4vfjlul8+WM9DBap5FogiNChVd/mjvL 1NYJUPFIC9KaV+5xNAJanW7h531lFKwHzZka68Dmzsbjdj0sUg2GkPhneOXEH8lX Q6Kmoxpg8IpfwfB/VDPM4eL3SdNQd8d/1VSUkLOS0reOc8L9RmLXSYlJILzNkDR9 yODoBgSktX2e4wnyuknyXi1JuIx2yHCsPHq+PtBYUnHEfc8W7V9yxwhAYshuRQDy sZO1AdwEQHzgNjnCPK8ru6DqrizHwKnlE1KUy5KxUOcmfaacZ//t9ezf8qSd19eC 6deGfmfvp3Xxtz38eCLogKJXzIDjf+FMaN+0znOd0ut9qPPCqBgALZNnkeaDz+zx 2ZGhjwcRAsKZmGSLQoKPN+YkM5POwzWvEPNApPsVJjpTXpoZcJ8= =pW6n -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bsdimp/tags/pull-bsd-user-20210511' into staging pull-bsd-user-20210511 is the next round of cleanups to bsd-user in merging the bsd-user fork into qemu. It contains a number of style commits, as well as 3 commits that start to change things: Some unused files are deleted, building the sparc and sparc64 targets are removed, and a structure is renamed. The next set of pull requests will start to execute the following plan: 1. Move existing code around to have a structure similar to the bsd-user fork. 2. Incrementally merge groups of system calls, focused on making x86 work. 3. Once the groups of system calls are all merged, additional platforms will be added back. 4. Concurrently, as changes are requested as part of the merge happen, those changes will be merged into the fork. An experimental merge to tip of master is under test and is what will be updated. 5. Eventually, there will be no diference, and the bsd-user fork will only be a staging area for cutting-edge features prior to upstreaming into qemu mainline. The bsd-user code in qemu has a lot of style issues. This cleans up a number in the files touched. However, the checkpatch.pl detects some incremental issues in the commits. The following are expected, but are corrected in later hashes in this branch. MAINTAINERS does not need to be updated, since all the files added or deleted are covered under existing regexp in MAINTAINERS. Checking all commits since f9a576a818044133f8564e0d243ebd97df0b3280... d60c3b932e2fa06aba5d7aa1c451b5d287095dc8:101: ERROR: consider using qemu_strtol in preference to strtol d60c3b932e2fa06aba5d7aa1c451b5d287095dc8:142: ERROR: braces {} are necessary for all arms of this statement d60c3b932e2fa06aba5d7aa1c451b5d287095dc8:145: ERROR: braces {} are necessary for all arms of this statement total: 3 errors, 0 warnings, 119 lines checked b4bebeee1dee8d333bfa105a6c28fec5eb34b147:148: WARNING: line over 80 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:330: ERROR: braces {} are necessary for all arms of this statement b4bebeee1dee8d333bfa105a6c28fec5eb34b147:340: ERROR: braces {} are necessary for all arms of this statement b4bebeee1dee8d333bfa105a6c28fec5eb34b147:381: ERROR: space prohibited between function name and open parenthesis '(' b4bebeee1dee8d333bfa105a6c28fec5eb34b147:390: ERROR: spaces required around that '<' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:408: WARNING: Block comments use a leading /* on a separate line b4bebeee1dee8d333bfa105a6c28fec5eb34b147:409: WARNING: Block comments use * on subsequent lines b4bebeee1dee8d333bfa105a6c28fec5eb34b147:409: WARNING: Block comments use a trailing */ on a separate line b4bebeee1dee8d333bfa105a6c28fec5eb34b147:441: WARNING: line over 80 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:445: WARNING: line over 80 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:502: ERROR: line over 90 characters b4bebeee1dee8d333bfa105a6c28fec5eb34b147:551: ERROR: space required after that ',' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:552: ERROR: space required after that ',' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:587: ERROR: space required after that ';' (ctx:VxV) b4bebeee1dee8d333bfa105a6c28fec5eb34b147:623: ERROR: suspect code indent for conditional statements (12, 14) total: 9 errors, 6 warnings, 664 lines checked 86545e7afe3f822b8561c7ceee7540fc3b19c3f0:31: ERROR: space required after that ';' (ctx:VxV) 86545e7afe3f822b8561c7ceee7540fc3b19c3f0:40: ERROR: space required after that ';' (ctx:VxV) total: 2 errors, 0 warnings, 60 lines checked Use of uninitialized value $acpi_testexpected in string eq at scripts/checkpatch.pl line 1529. 65d58c91ef1a15ad945ece367983437576f8e82b:22: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? total: 0 errors, 1 warnings, 14 lines checked Use of uninitialized value $acpi_testexpected in string eq at scripts/checkpatch.pl line 1529. f8ce39701b5be032fb3f9c05e8adb4055f70eec2:21: WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? total: 0 errors, 1 warnings, 0 lines checked FAIL one or more commits failed scripts/checkpatch.pl Cleaning up file based variables ERROR: Job failed: exit code 1 # gpg: Signature made Wed 12 May 2021 17:40:34 BST # gpg: using RSA key 2035F894B00AA3CF7CCDE1B76C1CD1287DB01100 # gpg: Good signature from "Warner Losh <wlosh@netflix.com>" [unknown] # gpg: aka "Warner Losh <imp@bsdimp.com>" [unknown] # gpg: aka "Warner Losh <imp@freebsd.org>" [unknown] # gpg: aka "Warner Losh <imp@village.org>" [unknown] # gpg: aka "Warner Losh <wlosh@bsdimp.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 2035 F894 B00A A3CF 7CCD E1B7 6C1C D128 7DB0 1100 * remotes/bsdimp/tags/pull-bsd-user-20210511: bsd-user: rename linux_binprm to bsd_binprm bsd-user: Stop building the sparc targets bsd-user: remove target_signal.h, it's unused bsd-user: style tweak: keyword space ( bsd-user: style tweak: Remove #if 0'd code bsd-user: style tweak: keyword space ( bsd-user: style tweak: keyword space ( bsd-user: whitespace changes bsd-user: use qemu_strtoul in preference to strtol bsd-user: style tweak: use {} consistently in for / if / else statements bsd-user: style tweak: use {} for all if statements, format else correctly bsd-user: style tweak: don't assign in if statements bsd-user: style tweak: Use preferred block comments bsd-user: style tweak: remove spacing after '*' and add after } bsd-user: style tweak: move extern to header file bsd-user: Remove commented out code bsd-user: style tweak: Use preferred block comments bsd-user: style tweak: Remove #if 0'd code bsd-user: style tweak: use C not C++ comments bsd-user: whitespace changes Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
a1362f392b
15 changed files with 350 additions and 554 deletions
|
@ -32,7 +32,7 @@ static int count(char **vec)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prepare_binprm(struct linux_binprm *bprm)
|
static int prepare_binprm(struct bsd_binprm *bprm)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int mode;
|
int mode;
|
||||||
|
@ -127,7 +127,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
|
||||||
int loader_exec(const char *filename, char **argv, char **envp,
|
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 linux_binprm bprm;
|
struct bsd_binprm bprm;
|
||||||
int retval;
|
int retval;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -662,7 +662,7 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
|
static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
|
||||||
struct image_info *info)
|
struct image_info *info)
|
||||||
{
|
{
|
||||||
abi_ulong stack_base, size, error;
|
abi_ulong stack_base, size, error;
|
||||||
|
@ -1143,7 +1143,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
|
||||||
syminfos = s;
|
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 image_info *info)
|
||||||
{
|
{
|
||||||
struct elfhdr elf_ex;
|
struct elfhdr elf_ex;
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#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(CPUX86State *state)
|
|
||||||
{
|
|
||||||
return state->regs[R_ESP];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TARGET_SIGNAL_H */
|
|
258
bsd-user/main.c
258
bsd-user/main.c
|
@ -36,6 +36,7 @@
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "qemu/envlist.h"
|
#include "qemu/envlist.h"
|
||||||
|
#include "qemu/cutils.h"
|
||||||
#include "exec/log.h"
|
#include "exec/log.h"
|
||||||
#include "trace/control.h"
|
#include "trace/control.h"
|
||||||
|
|
||||||
|
@ -47,12 +48,13 @@ unsigned long reserved_va;
|
||||||
|
|
||||||
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
||||||
const char *qemu_uname_release;
|
const char *qemu_uname_release;
|
||||||
extern char **environ;
|
|
||||||
enum BSDType bsd_type;
|
enum BSDType bsd_type;
|
||||||
|
|
||||||
/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
|
/*
|
||||||
we allocate a bigger stack. Need a better solution, for example
|
* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
|
||||||
by remapping the process stack directly at the right place */
|
* 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 x86_stack_size = 512 * 1024;
|
||||||
|
|
||||||
void gemu_log(const char *fmt, ...)
|
void gemu_log(const char *fmt, ...)
|
||||||
|
@ -147,7 +149,7 @@ void cpu_loop(CPUX86State *env)
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
int trapnr;
|
int trapnr;
|
||||||
abi_ulong pc;
|
abi_ulong pc;
|
||||||
//target_siginfo_t info;
|
/* target_siginfo_t info; */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
cpu_exec_start(cs);
|
cpu_exec_start(cs);
|
||||||
|
@ -196,7 +198,7 @@ void cpu_loop(CPUX86State *env)
|
||||||
arg6,
|
arg6,
|
||||||
arg7,
|
arg7,
|
||||||
arg8);
|
arg8);
|
||||||
} else { //if (bsd_type == target_openbsd)
|
} else { /* if (bsd_type == target_openbsd) */
|
||||||
env->regs[R_EAX] = do_openbsd_syscall(env,
|
env->regs[R_EAX] = do_openbsd_syscall(env,
|
||||||
env->regs[R_EAX],
|
env->regs[R_EAX],
|
||||||
env->regs[R_EBX],
|
env->regs[R_EBX],
|
||||||
|
@ -216,7 +218,7 @@ void cpu_loop(CPUX86State *env)
|
||||||
#ifndef TARGET_ABI32
|
#ifndef TARGET_ABI32
|
||||||
case EXCP_SYSCALL:
|
case EXCP_SYSCALL:
|
||||||
/* syscall from syscall instruction */
|
/* syscall from syscall instruction */
|
||||||
if (bsd_type == target_freebsd)
|
if (bsd_type == target_freebsd) {
|
||||||
env->regs[R_EAX] = do_freebsd_syscall(env,
|
env->regs[R_EAX] = do_freebsd_syscall(env,
|
||||||
env->regs[R_EAX],
|
env->regs[R_EAX],
|
||||||
env->regs[R_EDI],
|
env->regs[R_EDI],
|
||||||
|
@ -225,7 +227,7 @@ void cpu_loop(CPUX86State *env)
|
||||||
env->regs[R_ECX],
|
env->regs[R_ECX],
|
||||||
env->regs[8],
|
env->regs[8],
|
||||||
env->regs[9], 0, 0);
|
env->regs[9], 0, 0);
|
||||||
else { //if (bsd_type == target_openbsd)
|
} else { /* if (bsd_type == target_openbsd) */
|
||||||
env->regs[R_EAX] = do_openbsd_syscall(env,
|
env->regs[R_EAX] = do_openbsd_syscall(env,
|
||||||
env->regs[R_EAX],
|
env->regs[R_EAX],
|
||||||
env->regs[R_EDI],
|
env->regs[R_EDI],
|
||||||
|
@ -243,121 +245,14 @@ void cpu_loop(CPUX86State *env)
|
||||||
env->eflags &= ~CC_C;
|
env->eflags &= ~CC_C;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
case EXCP0B_NOSEG:
|
|
||||||
case EXCP0C_STACK:
|
|
||||||
info.si_signo = SIGBUS;
|
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_SI_KERNEL;
|
|
||||||
info._sifields._sigfault._addr = 0;
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
break;
|
|
||||||
case EXCP0D_GPF:
|
|
||||||
/* XXX: potential problem if ABI32 */
|
|
||||||
#ifndef TARGET_X86_64
|
|
||||||
if (env->eflags & VM_MASK) {
|
|
||||||
handle_vm86_fault(env);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
info.si_signo = SIGSEGV;
|
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_SI_KERNEL;
|
|
||||||
info._sifields._sigfault._addr = 0;
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXCP0E_PAGE:
|
|
||||||
info.si_signo = SIGSEGV;
|
|
||||||
info.si_errno = 0;
|
|
||||||
if (!(env->error_code & 1))
|
|
||||||
info.si_code = TARGET_SEGV_MAPERR;
|
|
||||||
else
|
|
||||||
info.si_code = TARGET_SEGV_ACCERR;
|
|
||||||
info._sifields._sigfault._addr = env->cr[2];
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
break;
|
|
||||||
case EXCP00_DIVZ:
|
|
||||||
#ifndef TARGET_X86_64
|
|
||||||
if (env->eflags & VM_MASK) {
|
|
||||||
handle_vm86_trap(env, trapnr);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* division by zero */
|
|
||||||
info.si_signo = SIGFPE;
|
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_FPE_INTDIV;
|
|
||||||
info._sifields._sigfault._addr = env->eip;
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXCP01_DB:
|
|
||||||
case EXCP03_INT3:
|
|
||||||
#ifndef TARGET_X86_64
|
|
||||||
if (env->eflags & VM_MASK) {
|
|
||||||
handle_vm86_trap(env, trapnr);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
info.si_signo = SIGTRAP;
|
|
||||||
info.si_errno = 0;
|
|
||||||
if (trapnr == EXCP01_DB) {
|
|
||||||
info.si_code = TARGET_TRAP_BRKPT;
|
|
||||||
info._sifields._sigfault._addr = env->eip;
|
|
||||||
} else {
|
|
||||||
info.si_code = TARGET_SI_KERNEL;
|
|
||||||
info._sifields._sigfault._addr = 0;
|
|
||||||
}
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXCP04_INTO:
|
|
||||||
case EXCP05_BOUND:
|
|
||||||
#ifndef TARGET_X86_64
|
|
||||||
if (env->eflags & VM_MASK) {
|
|
||||||
handle_vm86_trap(env, trapnr);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
info.si_signo = SIGSEGV;
|
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_SI_KERNEL;
|
|
||||||
info._sifields._sigfault._addr = 0;
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EXCP06_ILLOP:
|
|
||||||
info.si_signo = SIGILL;
|
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_ILL_ILLOPN;
|
|
||||||
info._sifields._sigfault._addr = env->eip;
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case EXCP_INTERRUPT:
|
case EXCP_INTERRUPT:
|
||||||
/* just indicate that signals should be handled asap */
|
/* just indicate that signals should be handled asap */
|
||||||
break;
|
break;
|
||||||
#if 0
|
|
||||||
case EXCP_DEBUG:
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
pc = env->segs[R_CS].base + env->eip;
|
pc = env->segs[R_CS].base + env->eip;
|
||||||
fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
|
fprintf(stderr,
|
||||||
|
"qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
|
||||||
(long)pc, trapnr);
|
(long)pc, trapnr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -369,16 +264,21 @@ void cpu_loop(CPUX86State *env)
|
||||||
#ifdef TARGET_SPARC
|
#ifdef TARGET_SPARC
|
||||||
#define SPARC64_STACK_BIAS 2047
|
#define SPARC64_STACK_BIAS 2047
|
||||||
|
|
||||||
//#define DEBUG_WIN
|
/* #define DEBUG_WIN */
|
||||||
/* WARNING: dealing with register windows _is_ complicated. More info
|
/*
|
||||||
can be found at http://www.sics.se/~psm/sparcstack.html */
|
* WARNING: dealing with register windows _is_ complicated. More info
|
||||||
|
* can be found at http://www.sics.se/~psm/sparcstack.html
|
||||||
|
*/
|
||||||
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
|
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
|
||||||
{
|
{
|
||||||
index = (index + cwp * 16) % (16 * env->nwindows);
|
index = (index + cwp * 16) % (16 * env->nwindows);
|
||||||
/* wrap handling : if cwp is on the last window, then we use the
|
/*
|
||||||
registers 'after' the end */
|
* wrap handling : if cwp is on the last window, then we use the
|
||||||
if (index < 8 && env->cwp == env->nwindows - 1)
|
* registers 'after' the end
|
||||||
|
*/
|
||||||
|
if (index < 8 && env->cwp == env->nwindows - 1) {
|
||||||
index += 16 * env->nwindows;
|
index += 16 * env->nwindows;
|
||||||
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,8 +290,9 @@ static inline void save_window_offset(CPUSPARCState *env, int cwp1)
|
||||||
|
|
||||||
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
|
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (sp_ptr & 3)
|
if (sp_ptr & 3) {
|
||||||
sp_ptr += SPARC64_STACK_BIAS;
|
sp_ptr += SPARC64_STACK_BIAS;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(DEBUG_WIN)
|
#if defined(DEBUG_WIN)
|
||||||
printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
|
printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
|
||||||
|
@ -440,8 +341,9 @@ static void restore_window(CPUSPARCState *env)
|
||||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
||||||
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
|
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
if (sp_ptr & 3)
|
if (sp_ptr & 3) {
|
||||||
sp_ptr += SPARC64_STACK_BIAS;
|
sp_ptr += SPARC64_STACK_BIAS;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(DEBUG_WIN)
|
#if defined(DEBUG_WIN)
|
||||||
printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
|
printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
|
||||||
|
@ -454,8 +356,9 @@ static void restore_window(CPUSPARCState *env)
|
||||||
}
|
}
|
||||||
#ifdef TARGET_SPARC64
|
#ifdef TARGET_SPARC64
|
||||||
env->canrestore++;
|
env->canrestore++;
|
||||||
if (env->cleanwin < env->nwindows - 1)
|
if (env->cleanwin < env->nwindows - 1) {
|
||||||
env->cleanwin++;
|
env->cleanwin++;
|
||||||
|
}
|
||||||
env->cansave--;
|
env->cansave--;
|
||||||
#else
|
#else
|
||||||
env->wim = new_wim;
|
env->wim = new_wim;
|
||||||
|
@ -471,11 +374,13 @@ static void flush_windows(CPUSPARCState *env)
|
||||||
/* if restore would invoke restore_window(), then we can stop */
|
/* if restore would invoke restore_window(), then we can stop */
|
||||||
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
||||||
#ifndef TARGET_SPARC64
|
#ifndef TARGET_SPARC64
|
||||||
if (env->wim & (1 << cwp1))
|
if (env->wim & (1 << cwp1)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
if (env->canrestore == 0)
|
if (env->canrestore == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
env->cansave++;
|
env->cansave++;
|
||||||
env->canrestore--;
|
env->canrestore--;
|
||||||
#endif
|
#endif
|
||||||
|
@ -496,7 +401,7 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
int trapnr, ret, syscall_nr;
|
int trapnr, ret, syscall_nr;
|
||||||
//target_siginfo_t info;
|
/* target_siginfo_t info; */
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
cpu_exec_start(cs);
|
cpu_exec_start(cs);
|
||||||
|
@ -510,8 +415,9 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
#else
|
#else
|
||||||
/* FreeBSD uses 0x141 for syscalls too */
|
/* FreeBSD uses 0x141 for syscalls too */
|
||||||
case 0x141:
|
case 0x141:
|
||||||
if (bsd_type != target_freebsd)
|
if (bsd_type != target_freebsd) {
|
||||||
goto badtrap;
|
goto badtrap;
|
||||||
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 0x100:
|
case 0x100:
|
||||||
#endif
|
#endif
|
||||||
|
@ -520,13 +426,14 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
ret = do_freebsd_syscall(env, syscall_nr,
|
ret = do_freebsd_syscall(env, syscall_nr,
|
||||||
env->regwptr[0], env->regwptr[1],
|
env->regwptr[0], env->regwptr[1],
|
||||||
env->regwptr[2], env->regwptr[3],
|
env->regwptr[2], env->regwptr[3],
|
||||||
env->regwptr[4], env->regwptr[5], 0, 0);
|
env->regwptr[4], env->regwptr[5],
|
||||||
|
0, 0);
|
||||||
else if (bsd_type == target_netbsd)
|
else if (bsd_type == target_netbsd)
|
||||||
ret = do_netbsd_syscall(env, syscall_nr,
|
ret = do_netbsd_syscall(env, syscall_nr,
|
||||||
env->regwptr[0], env->regwptr[1],
|
env->regwptr[0], env->regwptr[1],
|
||||||
env->regwptr[2], env->regwptr[3],
|
env->regwptr[2], env->regwptr[3],
|
||||||
env->regwptr[4], env->regwptr[5]);
|
env->regwptr[4], env->regwptr[5]);
|
||||||
else { //if (bsd_type == target_openbsd)
|
else { /* if (bsd_type == target_openbsd) */
|
||||||
#if defined(TARGET_SPARC64)
|
#if defined(TARGET_SPARC64)
|
||||||
syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
|
syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
|
||||||
TARGET_OPENBSD_SYSCALL_G2RFLAG);
|
TARGET_OPENBSD_SYSCALL_G2RFLAG);
|
||||||
|
@ -588,16 +495,6 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
break;
|
break;
|
||||||
case TT_TFAULT:
|
case TT_TFAULT:
|
||||||
case TT_DFAULT:
|
case TT_DFAULT:
|
||||||
#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 = env->mmuregs[4];
|
|
||||||
queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
case TT_SPILL: /* window overflow */
|
case TT_SPILL: /* window overflow */
|
||||||
|
@ -608,19 +505,6 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
break;
|
break;
|
||||||
case TT_TFAULT:
|
case TT_TFAULT:
|
||||||
case TT_DFAULT:
|
case TT_DFAULT:
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
info.si_signo = SIGSEGV;
|
|
||||||
info.si_errno = 0;
|
|
||||||
/* XXX: check env->error_code */
|
|
||||||
info.si_code = TARGET_SEGV_MAPERR;
|
|
||||||
if (trapnr == TT_DFAULT)
|
|
||||||
info._sifields._sigfault._addr = env->dmmuregs[4];
|
|
||||||
else
|
|
||||||
info._sifields._sigfault._addr = env->tsptr->tpc;
|
|
||||||
//queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case EXCP_INTERRUPT:
|
case EXCP_INTERRUPT:
|
||||||
|
@ -628,19 +512,7 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
break;
|
break;
|
||||||
case EXCP_DEBUG:
|
case EXCP_DEBUG:
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
int sig =
|
|
||||||
#endif
|
|
||||||
gdb_handlesig(cs, TARGET_SIGTRAP);
|
gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
#if 0
|
|
||||||
if (sig)
|
|
||||||
{
|
|
||||||
info.si_signo = sig;
|
|
||||||
info.si_errno = 0;
|
|
||||||
info.si_code = TARGET_TRAP_BRKPT;
|
|
||||||
//queue_signal(env, info.si_signo, &info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -741,15 +613,16 @@ int main(int argc, char **argv)
|
||||||
TaskState ts1, *ts = &ts1;
|
TaskState ts1, *ts = &ts1;
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
CPUState *cpu;
|
CPUState *cpu;
|
||||||
int optind;
|
int optind, rv;
|
||||||
const char *r;
|
const char *r;
|
||||||
const char *gdbstub = NULL;
|
const char *gdbstub = NULL;
|
||||||
char **target_environ, **wrk;
|
char **target_environ, **wrk;
|
||||||
envlist_t *envlist = NULL;
|
envlist_t *envlist = NULL;
|
||||||
bsd_type = target_openbsd;
|
bsd_type = target_openbsd;
|
||||||
|
|
||||||
if (argc <= 1)
|
if (argc <= 1) {
|
||||||
usage();
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
error_init(argv[0]);
|
error_init(argv[0]);
|
||||||
module_call_init(MODULE_INIT_TRACE);
|
module_call_init(MODULE_INIT_TRACE);
|
||||||
|
@ -769,11 +642,13 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (optind >= argc)
|
if (optind >= argc) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
r = argv[optind];
|
r = argv[optind];
|
||||||
if (r[0] != '-')
|
if (r[0] != '-') {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
optind++;
|
optind++;
|
||||||
r++;
|
r++;
|
||||||
if (!strcmp(r, "-")) {
|
if (!strcmp(r, "-")) {
|
||||||
|
@ -790,24 +665,28 @@ int main(int argc, char **argv)
|
||||||
log_file = argv[optind++];
|
log_file = argv[optind++];
|
||||||
} else if (!strcmp(r, "E")) {
|
} else if (!strcmp(r, "E")) {
|
||||||
r = argv[optind++];
|
r = argv[optind++];
|
||||||
if (envlist_setenv(envlist, r) != 0)
|
if (envlist_setenv(envlist, r) != 0) {
|
||||||
usage();
|
usage();
|
||||||
|
}
|
||||||
} else if (!strcmp(r, "ignore-environment")) {
|
} else if (!strcmp(r, "ignore-environment")) {
|
||||||
envlist_free(envlist);
|
envlist_free(envlist);
|
||||||
envlist = envlist_create();
|
envlist = envlist_create();
|
||||||
} else if (!strcmp(r, "U")) {
|
} else if (!strcmp(r, "U")) {
|
||||||
r = argv[optind++];
|
r = argv[optind++];
|
||||||
if (envlist_unsetenv(envlist, r) != 0)
|
if (envlist_unsetenv(envlist, r) != 0) {
|
||||||
usage();
|
usage();
|
||||||
|
}
|
||||||
} else if (!strcmp(r, "s")) {
|
} else if (!strcmp(r, "s")) {
|
||||||
r = argv[optind++];
|
r = argv[optind++];
|
||||||
x86_stack_size = strtol(r, (char **)&r, 0);
|
rv = qemu_strtoul(r, &r, 0, &x86_stack_size);
|
||||||
if (x86_stack_size <= 0)
|
if (rv < 0 || x86_stack_size <= 0) {
|
||||||
usage();
|
usage();
|
||||||
if (*r == 'M')
|
}
|
||||||
|
if (*r == 'M') {
|
||||||
x86_stack_size *= MiB;
|
x86_stack_size *= MiB;
|
||||||
else if (*r == 'k' || *r == 'K')
|
} else if (*r == 'k' || *r == 'K') {
|
||||||
x86_stack_size *= KiB;
|
x86_stack_size *= KiB;
|
||||||
|
}
|
||||||
} else if (!strcmp(r, "L")) {
|
} else if (!strcmp(r, "L")) {
|
||||||
interp_prefix = argv[optind++];
|
interp_prefix = argv[optind++];
|
||||||
} else if (!strcmp(r, "p")) {
|
} else if (!strcmp(r, "p")) {
|
||||||
|
@ -831,7 +710,10 @@ int main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else if (!strcmp(r, "B")) {
|
} else if (!strcmp(r, "B")) {
|
||||||
guest_base = strtol(argv[optind++], NULL, 0);
|
rv = qemu_strtoul(argv[optind++], NULL, 0, &guest_base);
|
||||||
|
if (rv < 0) {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
have_guest_base = true;
|
have_guest_base = true;
|
||||||
} else if (!strcmp(r, "drop-ld-preload")) {
|
} else if (!strcmp(r, "drop-ld-preload")) {
|
||||||
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
|
(void) envlist_unsetenv(envlist, "LD_PRELOAD");
|
||||||
|
@ -947,11 +829,13 @@ int main(int argc, char **argv)
|
||||||
if (!have_guest_base) {
|
if (!have_guest_base) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
|
fp = fopen("/proc/sys/vm/mmap_min_addr", "r");
|
||||||
|
if (fp != NULL) {
|
||||||
unsigned long tmp;
|
unsigned long tmp;
|
||||||
if (fscanf(fp, "%lu", &tmp) == 1) {
|
if (fscanf(fp, "%lu", &tmp) == 1) {
|
||||||
mmap_min_addr = tmp;
|
mmap_min_addr = tmp;
|
||||||
qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n", mmap_min_addr);
|
qemu_log_mask(CPU_LOG_PAGE, "host mmap_min_addr=0x%lx\n",
|
||||||
|
mmap_min_addr);
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
@ -989,9 +873,11 @@ int main(int argc, char **argv)
|
||||||
syscall_init();
|
syscall_init();
|
||||||
signal_init();
|
signal_init();
|
||||||
|
|
||||||
/* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
|
/*
|
||||||
generating the prologue until now so that the prologue can take
|
* Now that we've loaded the binary, GUEST_BASE is fixed. Delay
|
||||||
the real value of GUEST_BASE into account. */
|
* generating the prologue until now so that the prologue can take
|
||||||
|
* the real value of GUEST_BASE into account.
|
||||||
|
*/
|
||||||
tcg_prologue_init(tcg_ctx);
|
tcg_prologue_init(tcg_ctx);
|
||||||
tcg_region_init();
|
tcg_region_init();
|
||||||
|
|
||||||
|
@ -1122,11 +1008,13 @@ int main(int argc, char **argv)
|
||||||
env->pc = regs->pc;
|
env->pc = regs->pc;
|
||||||
env->npc = regs->npc;
|
env->npc = regs->npc;
|
||||||
env->y = regs->y;
|
env->y = regs->y;
|
||||||
for(i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++) {
|
||||||
env->gregs[i] = regs->u_regs[i];
|
env->gregs[i] = regs->u_regs[i];
|
||||||
for(i = 0; i < 8; i++)
|
}
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
env->regwptr[i] = regs->u_regs[i + 8];
|
env->regwptr[i] = regs->u_regs[i + 8];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error unsupported target CPU
|
#error unsupported target CPU
|
||||||
#endif
|
#endif
|
||||||
|
|
113
bsd-user/qemu.h
113
bsd-user/qemu.h
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include "exec/user/abitypes.h"
|
#include "exec/user/abitypes.h"
|
||||||
|
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
enum BSDType {
|
enum BSDType {
|
||||||
target_freebsd,
|
target_freebsd,
|
||||||
target_netbsd,
|
target_netbsd,
|
||||||
|
@ -36,7 +38,6 @@ extern enum BSDType bsd_type;
|
||||||
|
|
||||||
#include "syscall_defs.h"
|
#include "syscall_defs.h"
|
||||||
#include "target_syscall.h"
|
#include "target_syscall.h"
|
||||||
#include "target_signal.h"
|
|
||||||
#include "exec/gdbstub.h"
|
#include "exec/gdbstub.h"
|
||||||
|
|
||||||
#if defined(CONFIG_USE_NPTL)
|
#if defined(CONFIG_USE_NPTL)
|
||||||
|
@ -45,9 +46,10 @@ extern enum BSDType bsd_type;
|
||||||
#define THREAD
|
#define THREAD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This struct is used to hold certain information about the image.
|
/*
|
||||||
* Basically, it replicates in user space what would be certain
|
* This struct is used to hold certain information about the image. Basically,
|
||||||
* task_struct fields in the kernel
|
* it replicates in user space what would be certain task_struct fields in the
|
||||||
|
* kernel
|
||||||
*/
|
*/
|
||||||
struct image_info {
|
struct image_info {
|
||||||
abi_ulong load_addr;
|
abi_ulong load_addr;
|
||||||
|
@ -71,18 +73,18 @@ struct image_info {
|
||||||
|
|
||||||
struct sigqueue {
|
struct sigqueue {
|
||||||
struct sigqueue *next;
|
struct sigqueue *next;
|
||||||
//target_siginfo_t info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct emulated_sigtable {
|
struct emulated_sigtable {
|
||||||
int pending; /* true if signal is pending */
|
int pending; /* true if signal is pending */
|
||||||
struct sigqueue *first;
|
struct sigqueue *first;
|
||||||
struct sigqueue info; /* in order to always have memory for the
|
/* in order to always have memory for the first signal, we put it here */
|
||||||
first signal, we put it here */
|
struct sigqueue info;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NOTE: we force a big alignment so that the stack stored after is
|
/*
|
||||||
aligned too */
|
* NOTE: we force a big alignment so that the stack stored after is aligned too
|
||||||
|
*/
|
||||||
typedef struct TaskState {
|
typedef struct TaskState {
|
||||||
pid_t ts_tid; /* tid (or pid) of this task */
|
pid_t ts_tid; /* tid (or pid) of this task */
|
||||||
|
|
||||||
|
@ -102,7 +104,6 @@ void init_task_state(TaskState *ts);
|
||||||
extern const char *qemu_uname_release;
|
extern const char *qemu_uname_release;
|
||||||
extern unsigned long mmap_min_addr;
|
extern unsigned long mmap_min_addr;
|
||||||
|
|
||||||
/* ??? See if we can avoid exposing so much of the loader internals. */
|
|
||||||
/*
|
/*
|
||||||
* MAX_ARG_PAGES defines the number of pages allocated for arguments
|
* MAX_ARG_PAGES defines the number of pages allocated for arguments
|
||||||
* and envelope for the new program. 32 should suffice, this gives
|
* and envelope for the new program. 32 should suffice, this gives
|
||||||
|
@ -114,7 +115,7 @@ extern unsigned long mmap_min_addr;
|
||||||
* This structure is used to hold the arguments that are
|
* This structure is used to hold the arguments that are
|
||||||
* used when loading binaries.
|
* used when loading binaries.
|
||||||
*/
|
*/
|
||||||
struct linux_binprm {
|
struct bsd_binprm {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
void *page[MAX_ARG_PAGES];
|
void *page[MAX_ARG_PAGES];
|
||||||
abi_ulong p;
|
abi_ulong p;
|
||||||
|
@ -132,9 +133,9 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
|
||||||
int loader_exec(const char *filename, char **argv, char **envp,
|
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);
|
||||||
|
|
||||||
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 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);
|
struct image_info *info);
|
||||||
|
|
||||||
abi_long memcpy_to_target(abi_ulong dest, const void *src,
|
abi_long memcpy_to_target(abi_ulong dest, const void *src,
|
||||||
|
@ -193,9 +194,6 @@ extern int do_strace;
|
||||||
/* signal.c */
|
/* signal.c */
|
||||||
void process_pending_signals(CPUArchState *cpu_env);
|
void process_pending_signals(CPUArchState *cpu_env);
|
||||||
void signal_init(void);
|
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);
|
long do_sigreturn(CPUArchState *env);
|
||||||
long do_rt_sigreturn(CPUArchState *env);
|
long do_rt_sigreturn(CPUArchState *env);
|
||||||
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
|
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
|
||||||
|
@ -226,9 +224,11 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||||
return page_check_range((target_ulong)addr, size, type) == 0;
|
return page_check_range((target_ulong)addr, size, type) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE __get_user and __put_user use host pointers and don't check access. */
|
/*
|
||||||
/* These are usually used to access struct data members once the
|
* NOTE __get_user and __put_user use host pointers and don't check access.
|
||||||
* struct has been locked - usually with lock_user_struct().
|
*
|
||||||
|
* These are usually used to access struct data members once the struct has been
|
||||||
|
* locked - usually with lock_user_struct().
|
||||||
*/
|
*/
|
||||||
#define __put_user(x, hptr)\
|
#define __put_user(x, hptr)\
|
||||||
({\
|
({\
|
||||||
|
@ -269,24 +269,26 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||||
x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
|
x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
|
||||||
break;\
|
break;\
|
||||||
default:\
|
default:\
|
||||||
/* avoid warning */\
|
|
||||||
x = 0;\
|
x = 0;\
|
||||||
abort();\
|
abort();\
|
||||||
} \
|
} \
|
||||||
0;\
|
0;\
|
||||||
})
|
})
|
||||||
|
|
||||||
/* put_user()/get_user() take a guest address and check access */
|
/*
|
||||||
/* These are usually used to access an atomic data type, such as an int,
|
* put_user()/get_user() take a guest address and check access
|
||||||
* that has been passed by address. These internally perform locking
|
*
|
||||||
* and unlocking on the data type.
|
* These are usually used to access an atomic data type, such as an int, that
|
||||||
|
* has been passed by address. These internally perform locking and unlocking
|
||||||
|
* on the data type.
|
||||||
*/
|
*/
|
||||||
#define put_user(x, gaddr, target_type) \
|
#define put_user(x, gaddr, target_type) \
|
||||||
({ \
|
({ \
|
||||||
abi_ulong __gaddr = (gaddr); \
|
abi_ulong __gaddr = (gaddr); \
|
||||||
target_type *__hptr; \
|
target_type *__hptr; \
|
||||||
abi_long __ret; \
|
abi_long __ret; \
|
||||||
if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
|
__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0); \
|
||||||
|
if (__hptr) { \
|
||||||
__ret = __put_user((x), __hptr); \
|
__ret = __put_user((x), __hptr); \
|
||||||
unlock_user(__hptr, __gaddr, sizeof(target_type)); \
|
unlock_user(__hptr, __gaddr, sizeof(target_type)); \
|
||||||
} else \
|
} else \
|
||||||
|
@ -299,11 +301,11 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||||
abi_ulong __gaddr = (gaddr); \
|
abi_ulong __gaddr = (gaddr); \
|
||||||
target_type *__hptr; \
|
target_type *__hptr; \
|
||||||
abi_long __ret; \
|
abi_long __ret; \
|
||||||
if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
|
__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1); \
|
||||||
|
if (__hptr) { \
|
||||||
__ret = __get_user((x), __hptr); \
|
__ret = __get_user((x), __hptr); \
|
||||||
unlock_user(__hptr, __gaddr, 0); \
|
unlock_user(__hptr, __gaddr, 0); \
|
||||||
} else { \
|
} else { \
|
||||||
/* avoid warning */ \
|
|
||||||
(x) = 0; \
|
(x) = 0; \
|
||||||
__ret = -TARGET_EFAULT; \
|
__ret = -TARGET_EFAULT; \
|
||||||
} \
|
} \
|
||||||
|
@ -332,33 +334,41 @@ static inline bool access_ok(int type, abi_ulong addr, abi_ulong size)
|
||||||
#define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t)
|
#define get_user_u8(x, gaddr) get_user((x), (gaddr), uint8_t)
|
||||||
#define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t)
|
#define get_user_s8(x, gaddr) get_user((x), (gaddr), int8_t)
|
||||||
|
|
||||||
/* copy_from_user() and copy_to_user() are usually used to copy data
|
/*
|
||||||
|
* copy_from_user() and copy_to_user() are usually used to copy data
|
||||||
* buffers between the target and host. These internally perform
|
* buffers between the target and host. These internally perform
|
||||||
* locking/unlocking of the memory.
|
* locking/unlocking of the memory.
|
||||||
*/
|
*/
|
||||||
abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
|
abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
|
||||||
abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
|
abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
|
||||||
|
|
||||||
/* Functions for accessing guest memory. The tget and tput functions
|
/*
|
||||||
read/write single values, byteswapping as necessary. The lock_user function
|
* Functions for accessing guest memory. The tget and tput functions
|
||||||
gets a pointer to a contiguous area of guest memory, but does not perform
|
* read/write single values, byteswapping as necessary. The lock_user function
|
||||||
any byteswapping. lock_user may return either a pointer to the guest
|
* gets a pointer to a contiguous area of guest memory, but does not perform
|
||||||
memory, or a temporary buffer. */
|
* any byteswapping. lock_user may return either a pointer to the guest
|
||||||
|
* memory, or a temporary buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Lock an area of guest memory into the host. If copy is true then the
|
/*
|
||||||
host area will have the same contents as the guest. */
|
* Lock an area of guest memory into the host. If copy is true then the
|
||||||
static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
|
* host area will have the same contents as the guest.
|
||||||
|
*/
|
||||||
|
static inline void *lock_user(int type, abi_ulong guest_addr, long len,
|
||||||
|
int copy)
|
||||||
{
|
{
|
||||||
if (!access_ok(type, guest_addr, len))
|
if (!access_ok(type, guest_addr, len)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
#ifdef DEBUG_REMAP
|
#ifdef DEBUG_REMAP
|
||||||
{
|
{
|
||||||
void *addr;
|
void *addr;
|
||||||
addr = g_malloc(len);
|
addr = g_malloc(len);
|
||||||
if (copy)
|
if (copy) {
|
||||||
memcpy(addr, g2h_untagged(guest_addr), len);
|
memcpy(addr, g2h_untagged(guest_addr), len);
|
||||||
else
|
} else {
|
||||||
memset(addr, 0, len);
|
memset(addr, 0, len);
|
||||||
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -366,26 +376,32 @@ static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unlock an area of guest memory. The first LEN bytes must be
|
/*
|
||||||
flushed back to guest memory. host_ptr = NULL is explicitly
|
* Unlock an area of guest memory. The first LEN bytes must be flushed back to
|
||||||
allowed and does nothing. */
|
* guest memory. host_ptr = NULL is explicitly allowed and does nothing.
|
||||||
|
*/
|
||||||
static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
|
static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
|
||||||
long len)
|
long len)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef DEBUG_REMAP
|
#ifdef DEBUG_REMAP
|
||||||
if (!host_ptr)
|
if (!host_ptr) {
|
||||||
return;
|
return;
|
||||||
if (host_ptr == g2h_untagged(guest_addr))
|
}
|
||||||
|
if (host_ptr == g2h_untagged(guest_addr)) {
|
||||||
return;
|
return;
|
||||||
if (len > 0)
|
}
|
||||||
|
if (len > 0) {
|
||||||
memcpy(g2h_untagged(guest_addr), host_ptr, len);
|
memcpy(g2h_untagged(guest_addr), host_ptr, len);
|
||||||
|
}
|
||||||
g_free(host_ptr);
|
g_free(host_ptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the length of a string in target memory or -TARGET_EFAULT if
|
/*
|
||||||
access error. */
|
* Return the length of a string in target memory or -TARGET_EFAULT if access
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
abi_long target_strlen(abi_ulong gaddr);
|
abi_long target_strlen(abi_ulong gaddr);
|
||||||
|
|
||||||
/* Like lock_user but for null terminated strings. */
|
/* Like lock_user but for null terminated strings. */
|
||||||
|
@ -393,8 +409,9 @@ static inline void *lock_user_string(abi_ulong guest_addr)
|
||||||
{
|
{
|
||||||
abi_long len;
|
abi_long len;
|
||||||
len = target_strlen(guest_addr);
|
len = target_strlen(guest_addr);
|
||||||
if (len < 0)
|
if (len < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
|
return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
#include "target_signal.h"
|
|
||||||
|
|
||||||
void signal_init(void)
|
void signal_init(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
#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;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef UREG_I6
|
|
||||||
#define UREG_I6 6
|
|
||||||
#endif
|
|
||||||
#ifndef UREG_FP
|
|
||||||
#define UREG_FP UREG_I6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
|
|
||||||
{
|
|
||||||
return state->regwptr[UREG_FP];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TARGET_SIGNAL_H */
|
|
|
@ -1,27 +0,0 @@
|
||||||
#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;
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef UREG_I6
|
|
||||||
#define UREG_I6 6
|
|
||||||
#endif
|
|
||||||
#ifndef UREG_FP
|
|
||||||
#define UREG_FP UREG_I6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
|
|
||||||
{
|
|
||||||
return state->regwptr[UREG_FP];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TARGET_SIGNAL_H */
|
|
|
@ -128,14 +128,6 @@ static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* currently unused */
|
|
||||||
static void
|
|
||||||
print_syscall_ret_raw(struct syscallname *name, abi_long ret)
|
|
||||||
{
|
|
||||||
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An array of all of the syscalls we know about
|
* An array of all of the syscalls we know about
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#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(CPUX86State *state)
|
|
||||||
{
|
|
||||||
return state->regs[R_ESP];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* TARGET_SIGNAL_H */
|
|
|
@ -1,3 +0,0 @@
|
||||||
TARGET_ARCH=sparc
|
|
||||||
TARGET_ALIGNED_ONLY=y
|
|
||||||
TARGET_WORDS_BIGENDIAN=y
|
|
|
@ -1,4 +0,0 @@
|
||||||
TARGET_ARCH=sparc64
|
|
||||||
TARGET_BASE_ARCH=sparc
|
|
||||||
TARGET_ALIGNED_ONLY=y
|
|
||||||
TARGET_WORDS_BIGENDIAN=y
|
|
Loading…
Add table
Add a link
Reference in a new issue