summaryrefslogtreecommitdiffstats
path: root/sys/amd64/ia32
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2006-12-17 06:48:40 +0000
committerkmacy <kmacy@FreeBSD.org>2006-12-17 06:48:40 +0000
commit20611107850a6c1de42880a35271d3a18a4b8811 (patch)
tree4a10bc4aba837d9f1be450b197838da90973dd1b /sys/amd64/ia32
parentee539b99dcacb73703a09f64d8ada227bb88a165 (diff)
downloadFreeBSD-src-20611107850a6c1de42880a35271d3a18a4b8811.zip
FreeBSD-src-20611107850a6c1de42880a35271d3a18a4b8811.tar.gz
Newer versions of gcc don't support treating structures passed by value
as if they were really passed by reference. Specifically, the dead stores elimination pass in the GCC 4.1 optimiser breaks the non-compliant behavior on which FreeBSD relied. This change brings FreeBSD up to date by switching trap frames to being explicitly passed by reference. Reviewed by: kan Tested by: kan
Diffstat (limited to 'sys/amd64/ia32')
-rw-r--r--sys/amd64/ia32/ia32_exception.S1
-rw-r--r--sys/amd64/ia32/ia32_syscall.c34
2 files changed, 18 insertions, 17 deletions
diff --git a/sys/amd64/ia32/ia32_exception.S b/sys/amd64/ia32/ia32_exception.S
index c65634e..4820f53 100644
--- a/sys/amd64/ia32/ia32_exception.S
+++ b/sys/amd64/ia32/ia32_exception.S
@@ -61,6 +61,7 @@ IDTVEC(int0x80_syscall)
movq %r14,TF_R14(%rsp)
movq %r15,TF_R15(%rsp)
FAKE_MCOUNT(TF_RIP(%rsp))
+ movq %rsp, %rdi
call ia32_syscall
MEXITCOUNT
jmp doreti
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index e007b3a..c51a2be 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -86,10 +86,10 @@ __FBSDID("$FreeBSD$");
extern inthand_t IDTVEC(int0x80_syscall), IDTVEC(rsvd);
extern const char *freebsd32_syscallnames[];
-void ia32_syscall(struct trapframe frame); /* Called from asm code */
+void ia32_syscall(struct trapframe *frame); /* Called from asm code */
void
-ia32_syscall(struct trapframe frame)
+ia32_syscall(struct trapframe *frame)
{
caddr_t params;
int i;
@@ -111,18 +111,18 @@ ia32_syscall(struct trapframe frame)
PCPU_LAZY_INC(cnt.v_syscall);
td->td_pticks = 0;
- td->td_frame = &frame;
+ td->td_frame = frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
- params = (caddr_t)frame.tf_rsp + sizeof(u_int32_t);
- code = frame.tf_rax;
- orig_tf_rflags = frame.tf_rflags;
+ params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t);
+ code = frame->tf_rax;
+ orig_tf_rflags = frame->tf_rflags;
if (p->p_sysent->sv_prepsyscall) {
/*
* The prep code is MP aware.
*/
- (*p->p_sysent->sv_prepsyscall)(&frame, args, &code, &params);
+ (*p->p_sysent->sv_prepsyscall)(frame, args, &code, &params);
} else {
/*
* Need to check if this is a 32 bit or 64 bit syscall.
@@ -177,7 +177,7 @@ ia32_syscall(struct trapframe frame)
if (error == 0) {
td->td_retval[0] = 0;
- td->td_retval[1] = frame.tf_rdx;
+ td->td_retval[1] = frame->tf_rdx;
STOPEVENT(p, S_SCE, narg);
@@ -190,9 +190,9 @@ ia32_syscall(struct trapframe frame)
switch (error) {
case 0:
- frame.tf_rax = td->td_retval[0];
- frame.tf_rdx = td->td_retval[1];
- frame.tf_rflags &= ~PSL_C;
+ frame->tf_rax = td->td_retval[0];
+ frame->tf_rdx = td->td_retval[1];
+ frame->tf_rflags &= ~PSL_C;
break;
case ERESTART:
@@ -200,7 +200,7 @@ ia32_syscall(struct trapframe frame)
* Reconstruct pc, assuming lcall $X,y is 7 bytes,
* int 0x80 is 2 bytes. We saved this in tf_err.
*/
- frame.tf_rip -= frame.tf_err;
+ frame->tf_rip -= frame->tf_err;
break;
case EJUSTRETURN:
@@ -213,8 +213,8 @@ ia32_syscall(struct trapframe frame)
else
error = p->p_sysent->sv_errtbl[error];
}
- frame.tf_rax = error;
- frame.tf_rflags |= PSL_C;
+ frame->tf_rax = error;
+ frame->tf_rflags |= PSL_C;
break;
}
@@ -222,11 +222,11 @@ ia32_syscall(struct trapframe frame)
* Traced syscall.
*/
if (orig_tf_rflags & PSL_T) {
- frame.tf_rflags &= ~PSL_T;
+ frame->tf_rflags &= ~PSL_T;
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_TRACE;
- ksi.ksi_addr = (void *)frame.tf_rip;
+ ksi.ksi_addr = (void *)frame->tf_rip;
trapsignal(td, &ksi);
}
@@ -246,7 +246,7 @@ ia32_syscall(struct trapframe frame)
/*
* Handle reschedule and other end-of-syscall issues
*/
- userret(td, &frame);
+ userret(td, frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
OpenPOWER on IntegriCloud