Commit b33f5d53 authored by Ken Thompson's avatar Ken Thompson

fix arm bug in reflect.call

R=rsc
CC=golang-dev
https://golang.org/cl/2475042
parent d9c989fa
...@@ -2087,12 +2087,13 @@ olr(int32 v, int b, int r, int sc) ...@@ -2087,12 +2087,13 @@ olr(int32 v, int b, int r, int sc)
o |= 1 << 23; o |= 1 << 23;
if(sc & C_WBIT) if(sc & C_WBIT)
o |= 1 << 21; o |= 1 << 21;
o |= (0x1<<26) | (1<<20); o |= (1<<26) | (1<<20);
if(v < 0) { if(v < 0) {
if(sc & C_UBIT) diag(".U on neg offset");
v = -v; v = -v;
o ^= 1 << 23; o ^= 1 << 23;
} }
if(v >= (1<<12)) if(v >= (1<<12) || v < 0)
diag("literal span too large: %d (R%d)\n%P", v, b, PP); diag("literal span too large: %d (R%d)\n%P", v, b, PP);
o |= v; o |= v;
o |= b << 16; o |= b << 16;
...@@ -2117,7 +2118,7 @@ olhr(int32 v, int b, int r, int sc) ...@@ -2117,7 +2118,7 @@ olhr(int32 v, int b, int r, int sc)
v = -v; v = -v;
o ^= 1 << 23; o ^= 1 << 23;
} }
if(v >= (1<<8)) if(v >= (1<<8) || v < 0)
diag("literal span too large: %d (R%d)\n%P", v, b, PP); diag("literal span too large: %d (R%d)\n%P", v, b, PP);
o |= (v&0xf)|((v>>4)<<8)|(1<<22); o |= (v&0xf)|((v>>4)<<8)|(1<<22);
o |= b << 16; o |= b << 16;
...@@ -2191,7 +2192,8 @@ ofsr(int a, int r, int32 v, int b, int sc, Prog *p) ...@@ -2191,7 +2192,8 @@ ofsr(int a, int r, int32 v, int b, int sc, Prog *p)
} }
if(v & 3) if(v & 3)
diag("odd offset for floating point op: %d\n%P", v, p); diag("odd offset for floating point op: %d\n%P", v, p);
else if(v >= (1<<10)) else
if(v >= (1<<10) || v < 0)
diag("literal span too large: %d\n%P", v, p); diag("literal span too large: %d\n%P", v, p);
o |= (v>>2) & 0xFF; o |= (v>>2) & 0xFF;
o |= b << 16; o |= b << 16;
......
...@@ -123,7 +123,6 @@ TEXT gogocall(SB), 7, $-4 ...@@ -123,7 +123,6 @@ TEXT gogocall(SB), 7, $-4
MOVW 0(g), R3 // make sure g != nil MOVW 0(g), R3 // make sure g != nil
MOVW gobuf_sp(R0), SP // restore SP MOVW gobuf_sp(R0), SP // restore SP
MOVW gobuf_pc(R0), LR MOVW gobuf_pc(R0), LR
SUB R2, SP
MOVW R1, PC MOVW R1, PC
/* /*
...@@ -141,8 +140,7 @@ TEXT ·morestack(SB),7,$-4 ...@@ -141,8 +140,7 @@ TEXT ·morestack(SB),7,$-4
// Cannot grow scheduler stack (m->g0). // Cannot grow scheduler stack (m->g0).
MOVW m_g0(m), R4 MOVW m_g0(m), R4
CMP g, R4 CMP g, R4
BNE 2(PC) BL.EQ abort(SB)
BL abort(SB)
// Save in m. // Save in m.
MOVW R1, m_moreframe(m) MOVW R1, m_moreframe(m)
...@@ -185,6 +183,9 @@ TEXT reflect·call(SB), 7, $-4 ...@@ -185,6 +183,9 @@ TEXT reflect·call(SB), 7, $-4
MOVW 8(SP), R1 // arg frame MOVW 8(SP), R1 // arg frame
MOVW 12(SP), R2 // arg size MOVW 12(SP), R2 // arg size
SUB $4,R1 // add the saved LR to the frame
ADD $4,R2
MOVW R0, m_morepc(m) // f's PC MOVW R0, m_morepc(m) // f's PC
MOVW R1, m_morefp(m) // argument frame pointer MOVW R1, m_morefp(m) // argument frame pointer
MOVW R2, m_moreargs(m) // f's argument size MOVW R2, m_moreargs(m) // f's argument size
......
...@@ -527,8 +527,9 @@ scheduler(void) ...@@ -527,8 +527,9 @@ scheduler(void)
gp->status = Grunning; gp->status = Grunning;
m->curg = gp; m->curg = gp;
gp->m = m; gp->m = m;
if(gp->sched.pc == (byte*)goexit) // kickoff if(gp->sched.pc == (byte*)goexit) { // kickoff
gogocall(&gp->sched, (void(*)(void))gp->entry, 0); gogocall(&gp->sched, (void(*)(void))gp->entry);
}
gogo(&gp->sched, 1); gogo(&gp->sched, 1);
} }
...@@ -770,7 +771,8 @@ newstack(void) ...@@ -770,7 +771,8 @@ newstack(void)
free = true; free = true;
} }
//printf("newstack frame=%d args=%d morepc=%p morefp=%p gobuf=%p, %p newstk=%p\n", frame, args, m->morepc, m->morefp, g->sched.pc, g->sched.sp, stk); //printf("newstack frame=%d args=%d morepc=%p morefp=%p gobuf=%p, %p newstk=%p\n",
//frame, args, m->morepc, m->morefp, g->sched.pc, g->sched.sp, stk);
top->stackbase = g1->stackbase; top->stackbase = g1->stackbase;
top->stackguard = g1->stackguard; top->stackguard = g1->stackguard;
...@@ -797,7 +799,7 @@ newstack(void) ...@@ -797,7 +799,7 @@ newstack(void)
label.sp = sp; label.sp = sp;
label.pc = (byte*)·lessstack; label.pc = (byte*)·lessstack;
label.g = m->curg; label.g = m->curg;
gogocall(&label, m->morepc, 0); gogocall(&label, m->morepc);
*(int32*)345 = 123; // never return *(int32*)345 = 123; // never return
} }
......
...@@ -377,7 +377,7 @@ int32 charntorune(int32*, uint8*, int32); ...@@ -377,7 +377,7 @@ int32 charntorune(int32*, uint8*, int32);
* very low level c-called * very low level c-called
*/ */
void gogo(Gobuf*, uintptr); void gogo(Gobuf*, uintptr);
void gogocall(Gobuf*, void(*)(void), int64); void gogocall(Gobuf*, void(*)(void));
uintptr gosave(Gobuf*); uintptr gosave(Gobuf*);
void ·lessstack(void); void ·lessstack(void);
void goargs(void); void goargs(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment