-----BEGIN PGP SIGNATURE-----
iQIcBAABAgAGBQJa64FbAAoJEPMMOL0/L748X0cP/2qFqnEHI5DB1NVySLgG+xW9 vXiSzWFXInObbxxzLEMBLwuOWZdVYwZigMsjO6+NV2kPbGeeoL6GyleWglkpEcn+ rJpijE4aNGCZW3YwPtoerNK4ybsJVgz0nqCjfWXmvE3dkFgwOc7fQAHgyTcMkxua 9ktnk9B+wufO0+OnfchLv86Ut04ChDgTmr7ff/8QgS0gkzAkrTvlFYW7ORmiFEAf pShm14HjII0sRunew8GOBDMwGHAExq172HpywXUZBk/y8swNFxV9chSzp4n9Foi8 SxalhVh2/3ht9UCDZFHiuq+1zYhQvFzluHkIEXMqGSrrfuN1a2g8TuYIyMEo5yOm 4Q8R2GNa0mW8X6nrwGv1LtalPf3CppAAaocqa40cG1zi6DnJRjRJFEHqt26L1WKX U2iKRBhkSQ9MuzApGkB0xldO5+djjFFeC6hED9vMjMeDr5GiPHESFbelVLSok4J/ dSbvOPuXHK7GyMSTVJ8bwfD5PFtgNEFSmrcKuC5LqVFlvfUxcnVzLsbWyd9ijRxm MKzOgBdYGVdTYh4SLIWAKBR3qwDgR8fNS+cJBUqsnRkggUMxlZCHg1Wxgn7fwwNc Btj6nHeomjwzZzjZLl4a4T0lPxqnUKmhP8/0Y7R82oN9vSuHTW/pqdJlV/2gJmdd 5q7n7ELTPT9wTmY4/2nY =myHy -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.13-pull-request' into staging # gpg: Signature made Thu 03 May 2018 22:38:35 BST # gpg: using RSA key F30C38BD3F2FBE3C # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" # gpg: aka "Laurent Vivier <laurent@vivier.eu>" # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-2.13-pull-request: linux-user: remove useless padding in flock64 structure linux-user: introduce target_sigsp() and target_save_altstack() linux-user: ARM-FDPIC: Add support for signals for FDPIC targets linux-user: ARM-FDPIC: Add support of FDPIC for ARM. linux-user: ARM-FDPIC: Identify ARM FDPIC binaries Remove CONFIG_USE_FDPIC. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
f0c8895222
@ -1483,6 +1483,7 @@ typedef struct elf64_shdr {
|
||||
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
|
||||
#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
|
||||
#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
|
||||
#define ELFOSABI_ARM_FDPIC 65 /* ARM FDPIC */
|
||||
#define ELFOSABI_ARM 97 /* ARM */
|
||||
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define ABI_LLONG_ALIGNMENT 2
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
|
||||
#if (defined(TARGET_I386) && !defined(TARGET_X86_64)) || defined(TARGET_SH4)
|
||||
#define ABI_LLONG_ALIGNMENT 4
|
||||
#endif
|
||||
|
||||
|
@ -120,9 +120,7 @@ static void target_setup_general_frame(struct target_rt_sigframe *sf,
|
||||
__put_user(0, &sf->uc.tuc_flags);
|
||||
__put_user(0, &sf->uc.tuc_link);
|
||||
|
||||
__put_user(target_sigaltstack_used.ss_sp, &sf->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->xregs[31]), &sf->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size, &sf->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&sf->uc.tuc_stack, env);
|
||||
|
||||
for (i = 0; i < 31; i++) {
|
||||
__put_user(env->xregs[i], &sf->uc.tuc_mcontext.regs[i]);
|
||||
@ -372,14 +370,7 @@ static abi_ulong get_sigframe(struct target_sigaction *ka,
|
||||
{
|
||||
abi_ulong sp;
|
||||
|
||||
sp = env->xregs[31];
|
||||
|
||||
/*
|
||||
* This is the X/Open sanctioned signal stack switching.
|
||||
*/
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(get_sp_from_cpustate(env), ka);
|
||||
|
||||
sp = (sp - size) & ~15;
|
||||
|
||||
|
@ -117,12 +117,10 @@ static inline abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
CPUAlphaState *env,
|
||||
unsigned long framesize)
|
||||
{
|
||||
abi_ulong sp = env->ir[IR_SP];
|
||||
abi_ulong sp;
|
||||
|
||||
sp = target_sigsp(get_sp_from_cpustate(env), sa);
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
return (sp - framesize) & -32;
|
||||
}
|
||||
|
||||
@ -187,12 +185,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(set->sig[0], &frame->uc.tuc_osf_sigmask);
|
||||
__put_user(target_sigaltstack_used.ss_sp,
|
||||
&frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->ir[IR_SP]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
setup_sigcontext(&frame->uc.tuc_mcontext, env, frame_addr, set);
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
|
||||
__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
|
||||
|
@ -102,13 +102,13 @@ struct sigframe_v1
|
||||
{
|
||||
struct target_sigcontext sc;
|
||||
abi_ulong extramask[TARGET_NSIG_WORDS-1];
|
||||
abi_ulong retcode;
|
||||
abi_ulong retcode[4];
|
||||
};
|
||||
|
||||
struct sigframe_v2
|
||||
{
|
||||
struct target_ucontext_v2 uc;
|
||||
abi_ulong retcode;
|
||||
abi_ulong retcode[4];
|
||||
};
|
||||
|
||||
struct rt_sigframe_v1
|
||||
@ -117,14 +117,14 @@ struct rt_sigframe_v1
|
||||
abi_ulong puc;
|
||||
struct target_siginfo info;
|
||||
struct target_ucontext_v1 uc;
|
||||
abi_ulong retcode;
|
||||
abi_ulong retcode[4];
|
||||
};
|
||||
|
||||
struct rt_sigframe_v2
|
||||
{
|
||||
struct target_siginfo info;
|
||||
struct target_ucontext_v2 uc;
|
||||
abi_ulong retcode;
|
||||
abi_ulong retcode[4];
|
||||
};
|
||||
|
||||
#define TARGET_CONFIG_CPU_32 1
|
||||
@ -147,6 +147,21 @@ static const abi_ulong retcodes[4] = {
|
||||
SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN
|
||||
};
|
||||
|
||||
/*
|
||||
* Stub needed to make sure the FD register (r9) contains the right
|
||||
* value.
|
||||
*/
|
||||
static const unsigned long sigreturn_fdpic_codes[3] = {
|
||||
0xe59fc004, /* ldr r12, [pc, #4] to read function descriptor */
|
||||
0xe59c9004, /* ldr r9, [r12, #4] to setup GOT */
|
||||
0xe59cf000 /* ldr pc, [r12] to jump into restorer */
|
||||
};
|
||||
|
||||
static const unsigned long sigreturn_fdpic_thumb_codes[3] = {
|
||||
0xc008f8df, /* ldr r12, [pc, #8] to read function descriptor */
|
||||
0x9004f8dc, /* ldr r9, [r12, #4] to setup GOT */
|
||||
0xf000f8dc /* ldr pc, [r12] to jump into restorer */
|
||||
};
|
||||
|
||||
static inline int valid_user_regs(CPUARMState *regs)
|
||||
{
|
||||
@ -186,27 +201,42 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
|
||||
static inline abi_ulong
|
||||
get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
|
||||
{
|
||||
unsigned long sp = regs->regs[13];
|
||||
unsigned long sp;
|
||||
|
||||
/*
|
||||
* This is the X/Open sanctioned signal stack switching.
|
||||
*/
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(get_sp_from_cpustate(regs), ka);
|
||||
/*
|
||||
* ATPCS B01 mandates 8-byte alignment
|
||||
*/
|
||||
return (sp - framesize) & ~7;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
setup_return(CPUARMState *env, struct target_sigaction *ka,
|
||||
abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)
|
||||
{
|
||||
abi_ulong handler = ka->_sa_handler;
|
||||
abi_ulong handler = 0;
|
||||
abi_ulong handler_fdpic_GOT = 0;
|
||||
abi_ulong retcode;
|
||||
int thumb = handler & 1;
|
||||
|
||||
int thumb;
|
||||
int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
|
||||
|
||||
if (is_fdpic) {
|
||||
/* In FDPIC mode, ka->_sa_handler points to a function
|
||||
* descriptor (FD). The first word contains the address of the
|
||||
* handler. The second word contains the value of the PIC
|
||||
* register (r9). */
|
||||
abi_ulong funcdesc_ptr = ka->_sa_handler;
|
||||
if (get_user_ual(handler, funcdesc_ptr)
|
||||
|| get_user_ual(handler_fdpic_GOT, funcdesc_ptr + 4)) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
handler = ka->_sa_handler;
|
||||
}
|
||||
|
||||
thumb = handler & 1;
|
||||
|
||||
uint32_t cpsr = cpsr_read(env);
|
||||
|
||||
cpsr &= ~CPSR_IT;
|
||||
@ -217,7 +247,28 @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
|
||||
}
|
||||
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
retcode = ka->sa_restorer;
|
||||
if (is_fdpic) {
|
||||
/* For FDPIC we ensure that the restorer is called with a
|
||||
* correct r9 value. For that we need to write code on
|
||||
* the stack that sets r9 and jumps back to restorer
|
||||
* value.
|
||||
*/
|
||||
if (thumb) {
|
||||
__put_user(sigreturn_fdpic_thumb_codes[0], rc);
|
||||
__put_user(sigreturn_fdpic_thumb_codes[1], rc + 1);
|
||||
__put_user(sigreturn_fdpic_thumb_codes[2], rc + 2);
|
||||
__put_user((abi_ulong)ka->sa_restorer, rc + 3);
|
||||
} else {
|
||||
__put_user(sigreturn_fdpic_codes[0], rc);
|
||||
__put_user(sigreturn_fdpic_codes[1], rc + 1);
|
||||
__put_user(sigreturn_fdpic_codes[2], rc + 2);
|
||||
__put_user((abi_ulong)ka->sa_restorer, rc + 3);
|
||||
}
|
||||
|
||||
retcode = rc_addr + thumb;
|
||||
} else {
|
||||
retcode = ka->sa_restorer;
|
||||
}
|
||||
} else {
|
||||
unsigned int idx = thumb;
|
||||
|
||||
@ -231,10 +282,15 @@ setup_return(CPUARMState *env, struct target_sigaction *ka,
|
||||
}
|
||||
|
||||
env->regs[0] = usig;
|
||||
if (is_fdpic) {
|
||||
env->regs[9] = handler_fdpic_GOT;
|
||||
}
|
||||
env->regs[13] = frame_addr;
|
||||
env->regs[14] = retcode;
|
||||
env->regs[15] = handler & (thumb ? ~1 : ~3);
|
||||
cpsr_write(env, cpsr, CPSR_IT | CPSR_T, CPSRWriteByInstr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
|
||||
@ -285,9 +341,7 @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
|
||||
memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
|
||||
|
||||
memset(&stack, 0, sizeof(stack));
|
||||
__put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
|
||||
__put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
|
||||
target_save_altstack(&stack, env);
|
||||
memcpy(&uc->tuc_stack, &stack, sizeof(stack));
|
||||
|
||||
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
|
||||
@ -327,12 +381,15 @@ static void setup_frame_v1(int usig, struct target_sigaction *ka,
|
||||
__put_user(set->sig[i], &frame->extramask[i - 1]);
|
||||
}
|
||||
|
||||
setup_return(regs, ka, &frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct sigframe_v1, retcode));
|
||||
if (setup_return(regs, ka, frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct sigframe_v1, retcode))) {
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
@ -349,12 +406,15 @@ static void setup_frame_v2(int usig, struct target_sigaction *ka,
|
||||
|
||||
setup_sigframe_v2(&frame->uc, set, regs);
|
||||
|
||||
setup_return(regs, ka, &frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct sigframe_v2, retcode));
|
||||
if (setup_return(regs, ka, frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct sigframe_v2, retcode))) {
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
@ -394,9 +454,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
|
||||
memset(&frame->uc, 0, offsetof(struct target_ucontext_v1, tuc_mcontext));
|
||||
|
||||
memset(&stack, 0, sizeof(stack));
|
||||
__put_user(target_sigaltstack_used.ss_sp, &stack.ss_sp);
|
||||
__put_user(target_sigaltstack_used.ss_size, &stack.ss_size);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), &stack.ss_flags);
|
||||
target_save_altstack(&stack, env);
|
||||
memcpy(&frame->uc.tuc_stack, &stack, sizeof(stack));
|
||||
|
||||
setup_sigcontext(&frame->uc.tuc_mcontext, env, set->sig[0]);
|
||||
@ -404,8 +462,10 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
|
||||
__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
|
||||
}
|
||||
|
||||
setup_return(env, ka, &frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct rt_sigframe_v1, retcode));
|
||||
if (setup_return(env, ka, frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct rt_sigframe_v1, retcode))) {
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
env->regs[1] = info_addr;
|
||||
env->regs[2] = uc_addr;
|
||||
@ -413,6 +473,7 @@ static void setup_rt_frame_v1(int usig, struct target_sigaction *ka,
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
@ -435,8 +496,10 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
|
||||
|
||||
setup_sigframe_v2(&frame->uc, set, env);
|
||||
|
||||
setup_return(env, ka, &frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct rt_sigframe_v2, retcode));
|
||||
if (setup_return(env, ka, frame->retcode, frame_addr, usig,
|
||||
frame_addr + offsetof(struct rt_sigframe_v2, retcode))) {
|
||||
goto sigsegv;
|
||||
}
|
||||
|
||||
env->regs[1] = info_addr;
|
||||
env->regs[2] = uc_addr;
|
||||
@ -444,6 +507,7 @@ static void setup_rt_frame_v2(int usig, struct target_sigaction *ka,
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
sigsegv:
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
force_sigsegv(usig);
|
||||
}
|
||||
|
||||
|
@ -49,4 +49,11 @@ struct target_shmid_ds {
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
struct target_oabi_flock64 {
|
||||
abi_short l_type;
|
||||
abi_short l_whence;
|
||||
abi_llong l_start;
|
||||
abi_llong l_len;
|
||||
abi_int l_pid;
|
||||
} QEMU_PACKED;
|
||||
#endif
|
||||
|
@ -78,6 +78,11 @@ enum {
|
||||
*/
|
||||
#define personality(pers) (pers & PER_MASK)
|
||||
|
||||
int info_is_fdpic(struct image_info *info)
|
||||
{
|
||||
return info->personality == PER_LINUX_FDPIC;
|
||||
}
|
||||
|
||||
/* this flag is uneffective under linux too, should be deleted */
|
||||
#ifndef MAP_DENYWRITE
|
||||
#define MAP_DENYWRITE 0
|
||||
@ -287,6 +292,25 @@ static inline void init_thread(struct target_pt_regs *regs,
|
||||
/* For uClinux PIC binaries. */
|
||||
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
|
||||
regs->uregs[10] = infop->start_data;
|
||||
|
||||
/* Support ARM FDPIC. */
|
||||
if (info_is_fdpic(infop)) {
|
||||
/* As described in the ABI document, r7 points to the loadmap info
|
||||
* prepared by the kernel. If an interpreter is needed, r8 points
|
||||
* to the interpreter loadmap and r9 points to the interpreter
|
||||
* PT_DYNAMIC info. If no interpreter is needed, r8 is zero, and
|
||||
* r9 points to the main program PT_DYNAMIC info.
|
||||
*/
|
||||
regs->uregs[7] = infop->loadmap_addr;
|
||||
if (infop->interpreter_loadmap_addr) {
|
||||
/* Executable is dynamically loaded. */
|
||||
regs->uregs[8] = infop->interpreter_loadmap_addr;
|
||||
regs->uregs[9] = infop->interpreter_pt_dynamic_addr;
|
||||
} else {
|
||||
regs->uregs[8] = 0;
|
||||
regs->uregs[9] = infop->pt_dynamic_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ELF_NREG 18
|
||||
@ -1681,7 +1705,19 @@ static void zero_bss(abi_ulong elf_bss, abi_ulong last_bss, int prot)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
#ifdef TARGET_ARM
|
||||
static int elf_is_fdpic(struct elfhdr *exec)
|
||||
{
|
||||
return exec->e_ident[EI_OSABI] == ELFOSABI_ARM_FDPIC;
|
||||
}
|
||||
#else
|
||||
/* Default implementation, always false. */
|
||||
static int elf_is_fdpic(struct elfhdr *exec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong sp)
|
||||
{
|
||||
uint16_t n;
|
||||
@ -1706,7 +1742,6 @@ static abi_ulong loader_build_fdpic_loadmap(struct image_info *info, abi_ulong s
|
||||
|
||||
return sp;
|
||||
}
|
||||
#endif
|
||||
|
||||
static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
struct elfhdr *exec,
|
||||
@ -1725,7 +1760,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
|
||||
sp = p;
|
||||
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
/* Needs to be before we load the env/argc/... */
|
||||
if (elf_is_fdpic(exec)) {
|
||||
/* Need 4 byte alignment for these structs */
|
||||
@ -1735,9 +1769,13 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
|
||||
if (interp_info) {
|
||||
interp_info->other_info = info;
|
||||
sp = loader_build_fdpic_loadmap(interp_info, sp);
|
||||
info->interpreter_loadmap_addr = interp_info->loadmap_addr;
|
||||
info->interpreter_pt_dynamic_addr = interp_info->pt_dynamic_addr;
|
||||
} else {
|
||||
info->interpreter_loadmap_addr = 0;
|
||||
info->interpreter_pt_dynamic_addr = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
u_platform = 0;
|
||||
k_platform = ELF_PLATFORM;
|
||||
@ -2153,10 +2191,8 @@ static void load_elf_image(const char *image_name, int image_fd,
|
||||
}
|
||||
bswap_phdr(phdr, ehdr->e_phnum);
|
||||
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
info->nsegs = 0;
|
||||
info->pt_dynamic_addr = 0;
|
||||
#endif
|
||||
|
||||
mmap_lock();
|
||||
|
||||
@ -2173,9 +2209,7 @@ static void load_elf_image(const char *image_name, int image_fd,
|
||||
if (a > hiaddr) {
|
||||
hiaddr = a;
|
||||
}
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
++info->nsegs;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -2200,8 +2234,7 @@ static void load_elf_image(const char *image_name, int image_fd,
|
||||
}
|
||||
load_bias = load_addr - loaddr;
|
||||
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
{
|
||||
if (elf_is_fdpic(ehdr)) {
|
||||
struct elf32_fdpic_loadseg *loadsegs = info->loadsegs =
|
||||
g_malloc(sizeof(*loadsegs) * info->nsegs);
|
||||
|
||||
@ -2219,7 +2252,6 @@ static void load_elf_image(const char *image_name, int image_fd,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
info->load_bias = load_bias;
|
||||
info->load_addr = load_addr;
|
||||
|
@ -113,11 +113,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
struct target_rt_sigframe *frame;
|
||||
int i;
|
||||
|
||||
sp = env->gr[30];
|
||||
if (ka->sa_flags & TARGET_SA_ONSTACK) {
|
||||
if (sas_ss_flags(sp) == 0) {
|
||||
sp = (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
|
||||
}
|
||||
sp = get_sp_from_cpustate(env);
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
|
||||
sp = (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
|
||||
}
|
||||
frame_addr = QEMU_ALIGN_UP(sp, 64);
|
||||
sp = frame_addr + PARISC_RT_SIGFRAME_SIZE32;
|
||||
@ -132,11 +130,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
frame->uc.tuc_flags = 0;
|
||||
frame->uc.tuc_link = 0;
|
||||
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
|
||||
|
@ -283,16 +283,14 @@ get_sigframe(struct target_sigaction *ka, CPUX86State *env, size_t frame_size)
|
||||
unsigned long esp;
|
||||
|
||||
/* Default to using normal stack */
|
||||
esp = env->regs[R_ESP];
|
||||
esp = get_sp_from_cpustate(env);
|
||||
#ifdef TARGET_X86_64
|
||||
esp -= 128; /* this is the redzone */
|
||||
#endif
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (ka->sa_flags & TARGET_SA_ONSTACK) {
|
||||
if (sas_ss_flags(esp) == 0) {
|
||||
esp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
esp = target_sigsp(esp, ka);
|
||||
} else {
|
||||
#ifndef TARGET_X86_64
|
||||
/* This is the legacy signal stack switching. */
|
||||
@ -404,11 +402,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
/* Create the ucontext. */
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
setup_sigcontext(&frame->uc.tuc_mcontext, &frame->fpstate, env,
|
||||
set->sig[0], frame_addr + offsetof(struct rt_sigframe, fpstate));
|
||||
|
||||
|
@ -117,14 +117,10 @@ static inline abi_ulong
|
||||
get_sigframe(struct target_sigaction *ka, CPUM68KState *regs,
|
||||
size_t frame_size)
|
||||
{
|
||||
unsigned long sp;
|
||||
abi_ulong sp;
|
||||
|
||||
sp = regs->aregs[7];
|
||||
sp = target_sigsp(get_sp_from_cpustate(regs), ka);
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
|
||||
return ((sp - frame_size) & -8UL);
|
||||
}
|
||||
@ -318,12 +314,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp,
|
||||
&frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->aregs[7]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
err |= target_rt_setup_ucontext(&frame->uc, env);
|
||||
|
||||
if (err)
|
||||
|
@ -133,9 +133,7 @@ static abi_ulong get_sigframe(struct target_sigaction *ka,
|
||||
{
|
||||
abi_ulong sp = env->regs[1];
|
||||
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !on_sig_stack(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(sp, ka);
|
||||
|
||||
return ((sp - frame_size) & -8UL);
|
||||
}
|
||||
|
@ -179,20 +179,12 @@ get_sigframe(struct target_sigaction *ka, CPUMIPSState *regs, size_t frame_size)
|
||||
{
|
||||
unsigned long sp;
|
||||
|
||||
/* Default to using normal stack */
|
||||
sp = regs->active_tc.gpr[29];
|
||||
|
||||
/*
|
||||
* FPU emulator may have its own trampoline active just
|
||||
* above the user stack, 16-bytes before the next lowest
|
||||
* 16 byte boundary. Try to avoid trashing it.
|
||||
*/
|
||||
sp -= 32;
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags (sp) == 0)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(get_sp_from_cpustate(regs) - 32, ka);
|
||||
|
||||
return (sp - frame_size) & ~7;
|
||||
}
|
||||
@ -323,10 +315,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
__put_user(0, &frame->rs_uc.tuc_flags);
|
||||
__put_user(0, &frame->rs_uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->rs_uc.tuc_stack.ss_sp);
|
||||
__put_user(target_sigaltstack_used.ss_size, &frame->rs_uc.tuc_stack.ss_size);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
|
||||
&frame->rs_uc.tuc_stack.ss_flags);
|
||||
target_save_altstack(&frame->rs_uc.tuc_stack, env);
|
||||
|
||||
setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
|
||||
|
||||
|
@ -42,18 +42,6 @@ struct target_rt_sigframe {
|
||||
struct target_ucontext uc;
|
||||
};
|
||||
|
||||
static unsigned long sigsp(unsigned long sp, struct target_sigaction *ka)
|
||||
{
|
||||
if (unlikely((ka->sa_flags & SA_ONSTACK)) && !sas_ss_flags(sp)) {
|
||||
#ifdef CONFIG_STACK_GROWSUP
|
||||
return target_sigaltstack_used.ss_sp;
|
||||
#else
|
||||
return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
#endif
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
static int rt_setup_ucontext(struct target_ucontext *uc, CPUNios2State *env)
|
||||
{
|
||||
unsigned long *gregs = uc->tuc_mcontext.gregs;
|
||||
@ -158,11 +146,8 @@ static void *get_sigframe(struct target_sigaction *ka, CPUNios2State *env,
|
||||
{
|
||||
unsigned long usp;
|
||||
|
||||
/* Default to using normal stack. */
|
||||
usp = env->regs[R_SP];
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
usp = sigsp(usp, ka);
|
||||
usp = target_sigsp(get_sp_from_cpustate(env), ka);
|
||||
|
||||
/* Verify, is it 32 or 64 bit aligned */
|
||||
return (void *)((usp - frame_size) & -8UL);
|
||||
@ -185,9 +170,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
/* Create the ucontext. */
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->regs[R_SP]), &frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
err |= rt_setup_ucontext(&frame->uc, env);
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__put_user((abi_ulong)set->sig[i],
|
||||
|
@ -124,14 +124,11 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka,
|
||||
CPUOpenRISCState *regs,
|
||||
size_t frame_size)
|
||||
{
|
||||
unsigned long sp = cpu_get_gpr(regs, 1);
|
||||
unsigned long sp = get_sp_from_cpustate(regs);
|
||||
int onsigstack = on_sig_stack(sp);
|
||||
|
||||
/* redzone */
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !onsigstack) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(sp, ka);
|
||||
|
||||
sp = align_sigframe(sp - frame_size);
|
||||
|
||||
@ -175,12 +172,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
/*err |= __clear_user(&frame->uc, offsetof(ucontext_t, uc_mcontext));*/
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp,
|
||||
&frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(cpu_get_gpr(env, 1)),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
setup_sigcontext(&frame->sc, env, set->sig[0]);
|
||||
|
||||
/*err |= copy_to_user(frame->uc.tuc_sigmask, set, sizeof(*set));*/
|
||||
|
@ -217,13 +217,7 @@ static target_ulong get_sigframe(struct target_sigaction *ka,
|
||||
{
|
||||
target_ulong oldsp;
|
||||
|
||||
oldsp = env->gpr[1];
|
||||
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) &&
|
||||
(sas_ss_flags(oldsp) == 0)) {
|
||||
oldsp = (target_sigaltstack_used.ss_sp
|
||||
+ target_sigaltstack_used.ss_size);
|
||||
}
|
||||
oldsp = target_sigsp(get_sp_from_cpustate(env), ka);
|
||||
|
||||
return (oldsp - frame_size) & ~0xFUL;
|
||||
}
|
||||
@ -515,12 +509,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
__put_user(0, &rt_sf->uc.tuc_flags);
|
||||
__put_user(0, &rt_sf->uc.tuc_link);
|
||||
__put_user((target_ulong)target_sigaltstack_used.ss_sp,
|
||||
&rt_sf->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->gpr[1]),
|
||||
&rt_sf->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&rt_sf->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&rt_sf->uc.tuc_stack, env);
|
||||
#if !defined(TARGET_PPC64)
|
||||
__put_user(h2g (&rt_sf->uc.tuc_mcontext),
|
||||
&rt_sf->uc.tuc_regs);
|
||||
|
@ -51,13 +51,15 @@ struct image_info {
|
||||
abi_ulong file_string;
|
||||
uint32_t elf_flags;
|
||||
int personality;
|
||||
#ifdef CONFIG_USE_FDPIC
|
||||
|
||||
/* The fields below are used in FDPIC mode. */
|
||||
abi_ulong loadmap_addr;
|
||||
uint16_t nsegs;
|
||||
void *loadsegs;
|
||||
abi_ulong pt_dynamic_addr;
|
||||
abi_ulong interpreter_loadmap_addr;
|
||||
abi_ulong interpreter_pt_dynamic_addr;
|
||||
struct image_info *other_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef TARGET_I386
|
||||
@ -183,6 +185,13 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
|
||||
struct target_pt_regs * regs, struct image_info *infop,
|
||||
struct linux_binprm *);
|
||||
|
||||
/* Returns true if the image uses the FDPIC ABI. If this is the case,
|
||||
* we have to provide some information (loadmap, pt_dynamic_info) such
|
||||
* that the program can be relocated adequately. This is also useful
|
||||
* when handling signals.
|
||||
*/
|
||||
int info_is_fdpic(struct image_info *info);
|
||||
|
||||
uint32_t get_elf_eflags(int fd);
|
||||
int load_elf_binary(struct linux_binprm *bprm, struct image_info *info);
|
||||
int load_flt_binary(struct linux_binprm *bprm, struct image_info *info);
|
||||
|
@ -54,24 +54,20 @@ struct target_rt_sigframe {
|
||||
static abi_ulong get_sigframe(struct target_sigaction *ka,
|
||||
CPURISCVState *regs, size_t framesize)
|
||||
{
|
||||
abi_ulong sp = regs->gpr[xSP];
|
||||
int onsigstack = on_sig_stack(sp);
|
||||
|
||||
/* redzone */
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !onsigstack) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
|
||||
sp -= framesize;
|
||||
sp &= ~3UL; /* align sp on 4-byte boundary */
|
||||
abi_ulong sp = get_sp_from_cpustate(regs);
|
||||
|
||||
/* If we are on the alternate signal stack and would overflow it, don't.
|
||||
Return an always-bogus address instead so we will die with SIGSEGV. */
|
||||
if (onsigstack && !likely(on_sig_stack(sp))) {
|
||||
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
sp = target_sigsp(sp, ka) - framesize;
|
||||
|
||||
/* XXX: kernel aligns with 0xf ? */
|
||||
sp &= ~3UL; /* align sp on 4-byte boundary */
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
@ -95,16 +91,10 @@ static void setup_sigcontext(struct target_sigcontext *sc, CPURISCVState *env)
|
||||
static void setup_ucontext(struct target_ucontext *uc,
|
||||
CPURISCVState *env, target_sigset_t *set)
|
||||
{
|
||||
abi_ulong ss_sp = (target_ulong)target_sigaltstack_used.ss_sp;
|
||||
abi_ulong ss_flags = sas_ss_flags(env->gpr[xSP]);
|
||||
abi_ulong ss_size = target_sigaltstack_used.ss_size;
|
||||
|
||||
__put_user(0, &(uc->uc_flags));
|
||||
__put_user(0, &(uc->uc_link));
|
||||
|
||||
__put_user(ss_sp, &(uc->uc_stack.ss_sp));
|
||||
__put_user(ss_flags, &(uc->uc_stack.ss_flags));
|
||||
__put_user(ss_size, &(uc->uc_stack.ss_size));
|
||||
target_save_altstack(&uc->uc_stack, env);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
|
@ -86,14 +86,11 @@ get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
|
||||
abi_ulong sp;
|
||||
|
||||
/* Default to using normal stack */
|
||||
sp = env->regs[15];
|
||||
sp = get_sp_from_cpustate(env);
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (ka->sa_flags & TARGET_SA_ONSTACK) {
|
||||
if (!sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp +
|
||||
target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(sp, ka);
|
||||
}
|
||||
|
||||
/* This is the legacy signal stack switching. */
|
||||
@ -205,10 +202,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
/* Create the ucontext. */
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
save_sigregs(env, &frame->uc.tuc_mcontext);
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__put_user((abi_ulong)set->sig[i],
|
||||
|
@ -78,9 +78,7 @@ struct target_rt_sigframe
|
||||
static abi_ulong get_sigframe(struct target_sigaction *ka,
|
||||
unsigned long sp, size_t frame_size)
|
||||
{
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
sp = target_sigsp(sp, ka);
|
||||
|
||||
return (sp - frame_size) & -8ul;
|
||||
}
|
||||
@ -238,12 +236,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
/* Create the ucontext. */
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, (unsigned long *)&frame->uc.tuc_link);
|
||||
__put_user((unsigned long)target_sigaltstack_used.ss_sp,
|
||||
&frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(regs->gregs[15]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, regs);
|
||||
setup_sigcontext(&frame->uc.tuc_mcontext,
|
||||
regs, set->sig[0]);
|
||||
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
|
@ -21,17 +21,10 @@
|
||||
#define SIGNAL_COMMON_H
|
||||
extern struct target_sigaltstack target_sigaltstack_used;
|
||||
|
||||
static inline int on_sig_stack(unsigned long sp)
|
||||
{
|
||||
return (sp - target_sigaltstack_used.ss_sp
|
||||
< target_sigaltstack_used.ss_size);
|
||||
}
|
||||
|
||||
static inline int sas_ss_flags(unsigned long sp)
|
||||
{
|
||||
return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
|
||||
: on_sig_stack(sp) ? SS_ONSTACK : 0);
|
||||
}
|
||||
int on_sig_stack(unsigned long sp);
|
||||
int sas_ss_flags(unsigned long sp);
|
||||
abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka);
|
||||
void target_save_altstack(target_stack_t *uss, CPUArchState *env);
|
||||
|
||||
static inline void target_sigemptyset(target_sigset_t *set)
|
||||
{
|
||||
|
@ -249,6 +249,38 @@ void set_sigmask(const sigset_t *set)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sigaltstack management */
|
||||
|
||||
int on_sig_stack(unsigned long sp)
|
||||
{
|
||||
return (sp - target_sigaltstack_used.ss_sp
|
||||
< target_sigaltstack_used.ss_size);
|
||||
}
|
||||
|
||||
int sas_ss_flags(unsigned long sp)
|
||||
{
|
||||
return (target_sigaltstack_used.ss_size == 0 ? SS_DISABLE
|
||||
: on_sig_stack(sp) ? SS_ONSTACK : 0);
|
||||
}
|
||||
|
||||
abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka)
|
||||
{
|
||||
/*
|
||||
* This is the X/Open sanctioned signal stack switching.
|
||||
*/
|
||||
if ((ka->sa_flags & TARGET_SA_ONSTACK) && !sas_ss_flags(sp)) {
|
||||
return target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
return sp;
|
||||
}
|
||||
|
||||
void target_save_altstack(target_stack_t *uss, CPUArchState *env)
|
||||
{
|
||||
__put_user(target_sigaltstack_used.ss_sp, &uss->ss_sp);
|
||||
__put_user(sas_ss_flags(get_sp_from_cpustate(env)), &uss->ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size, &uss->ss_size);
|
||||
}
|
||||
|
||||
/* siginfo conversion */
|
||||
|
||||
static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
|
||||
|
@ -123,18 +123,28 @@ static inline abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
CPUSPARCState *env,
|
||||
unsigned long framesize)
|
||||
{
|
||||
abi_ulong sp;
|
||||
abi_ulong sp = get_sp_from_cpustate(env);
|
||||
|
||||
sp = env->regwptr[UREG_FP];
|
||||
/*
|
||||
* If we are on the alternate signal stack and would overflow it, don't.
|
||||
* Return an always-bogus address instead so we will die with SIGSEGV.
|
||||
*/
|
||||
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (sa->sa_flags & TARGET_SA_ONSTACK) {
|
||||
if (!on_sig_stack(sp)
|
||||
&& !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
}
|
||||
return sp - framesize;
|
||||
sp = target_sigsp(sp, sa) - framesize;
|
||||
|
||||
/* Always align the stack frame. This handles two cases. First,
|
||||
* sigaltstack need not be mindful of platform specific stack
|
||||
* alignment. Second, if we took this signal because the stack
|
||||
* is not aligned properly, we'd like to take the signal cleanly
|
||||
* and report that.
|
||||
*/
|
||||
sp &= ~15UL;
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -6600,10 +6600,10 @@ typedef abi_long from_flock64_fn(struct flock64 *fl, abi_ulong target_addr);
|
||||
typedef abi_long to_flock64_fn(abi_ulong target_addr, const struct flock64 *fl);
|
||||
|
||||
#if defined(TARGET_ARM) && TARGET_ABI_BITS == 32
|
||||
static inline abi_long copy_from_user_eabi_flock64(struct flock64 *fl,
|
||||
static inline abi_long copy_from_user_oabi_flock64(struct flock64 *fl,
|
||||
abi_ulong target_flock_addr)
|
||||
{
|
||||
struct target_eabi_flock64 *target_fl;
|
||||
struct target_oabi_flock64 *target_fl;
|
||||
short l_type;
|
||||
|
||||
if (!lock_user_struct(VERIFY_READ, target_fl, target_flock_addr, 1)) {
|
||||
@ -6620,10 +6620,10 @@ static inline abi_long copy_from_user_eabi_flock64(struct flock64 *fl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline abi_long copy_to_user_eabi_flock64(abi_ulong target_flock_addr,
|
||||
static inline abi_long copy_to_user_oabi_flock64(abi_ulong target_flock_addr,
|
||||
const struct flock64 *fl)
|
||||
{
|
||||
struct target_eabi_flock64 *target_fl;
|
||||
struct target_oabi_flock64 *target_fl;
|
||||
short l_type;
|
||||
|
||||
if (!lock_user_struct(VERIFY_WRITE, target_fl, target_flock_addr, 0)) {
|
||||
@ -11629,9 +11629,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
to_flock64_fn *copyto = copy_to_user_flock64;
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
if (((CPUARMState *)cpu_env)->eabi) {
|
||||
copyfrom = copy_from_user_eabi_flock64;
|
||||
copyto = copy_to_user_eabi_flock64;
|
||||
if (!((CPUARMState *)cpu_env)->eabi) {
|
||||
copyfrom = copy_from_user_oabi_flock64;
|
||||
copyto = copy_to_user_oabi_flock64;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2649,29 +2649,12 @@ struct target_flock {
|
||||
};
|
||||
|
||||
struct target_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) \
|
||||
|| defined(TARGET_SPARC) || defined(TARGET_HPPA) \
|
||||
|| defined(TARGET_MICROBLAZE) || defined(TARGET_TILEGX) \
|
||||
|| defined(TARGET_XTENSA)
|
||||
int __pad;
|
||||
#endif
|
||||
abi_short l_type;
|
||||
abi_short l_whence;
|
||||
abi_llong l_start;
|
||||
abi_llong l_len;
|
||||
int l_pid;
|
||||
} QEMU_PACKED;
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
struct target_eabi_flock64 {
|
||||
short l_type;
|
||||
short l_whence;
|
||||
int __pad;
|
||||
abi_llong l_start;
|
||||
abi_llong l_len;
|
||||
int l_pid;
|
||||
} QEMU_PACKED;
|
||||
#endif
|
||||
abi_int l_pid;
|
||||
};
|
||||
|
||||
struct target_f_owner_ex {
|
||||
int type; /* Owner type of ID. */
|
||||
|
@ -86,17 +86,13 @@ static void restore_sigcontext(CPUTLGState *env, struct target_sigcontext *sc)
|
||||
static abi_ulong get_sigframe(struct target_sigaction *ka, CPUArchState *env,
|
||||
size_t frame_size)
|
||||
{
|
||||
unsigned long sp = env->regs[TILEGX_R_SP];
|
||||
unsigned long sp = get_sp_from_cpustate(env);
|
||||
|
||||
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) {
|
||||
return -1UL;
|
||||
}
|
||||
|
||||
if ((ka->sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
|
||||
sp -= frame_size;
|
||||
sp = target_sigsp(sp, ka) - frame_size;
|
||||
sp &= -16UL;
|
||||
return sp;
|
||||
}
|
||||
@ -127,10 +123,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
/* Create the ucontext. */
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->regs[TILEGX_R_SP]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
setup_sigcontext(&frame->uc.tuc_mcontext, env, info->si_signo);
|
||||
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
|
@ -55,12 +55,10 @@ static abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
CPUXtensaState *env,
|
||||
unsigned long framesize)
|
||||
{
|
||||
abi_ulong sp = env->regs[1];
|
||||
abi_ulong sp;
|
||||
|
||||
sp = target_sigsp(get_sp_from_cpustate(env), sa);
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
|
||||
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
|
||||
}
|
||||
return (sp - framesize) & -16;
|
||||
}
|
||||
|
||||
@ -152,12 +150,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
__put_user(target_sigaltstack_used.ss_sp,
|
||||
&frame->uc.tuc_stack.ss_sp);
|
||||
__put_user(sas_ss_flags(env->regs[1]),
|
||||
&frame->uc.tuc_stack.ss_flags);
|
||||
__put_user(target_sigaltstack_used.ss_size,
|
||||
&frame->uc.tuc_stack.ss_size);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
if (!setup_sigcontext(frame, env)) {
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
goto give_sigsegv;
|
||||
|
Loading…
Reference in New Issue
Block a user