diff options
Diffstat (limited to 'src/liblink/obj8.c')
-rw-r--r-- | src/liblink/obj8.c | 129 |
1 files changed, 76 insertions, 53 deletions
diff --git a/src/liblink/obj8.c b/src/liblink/obj8.c index 72934c149..f54153ae9 100644 --- a/src/liblink/obj8.c +++ b/src/liblink/obj8.c @@ -33,7 +33,7 @@ #include <bio.h> #include <link.h> #include "../cmd/8l/8.out.h" -#include "../pkg/runtime/stack.h" +#include "../runtime/stack.h" static Prog zprg = { .back = 2, @@ -261,7 +261,7 @@ static Prog* stacksplit(Link*, Prog*, int32, int, Prog**); static void addstacksplit(Link *ctxt, LSym *cursym) { - Prog *p, *q; + Prog *p, *q, *p1, *p2; int32 autoffset, deltasp; int a; @@ -270,8 +270,8 @@ addstacksplit(Link *ctxt, LSym *cursym) ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0); } - if(ctxt->headtype == Hplan9 && ctxt->plan9tos == nil) - ctxt->plan9tos = linklookup(ctxt, "_tos", 0); + if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil) + ctxt->plan9privates = linklookup(ctxt, "_privates", 0); ctxt->cursym = cursym; @@ -317,13 +317,64 @@ addstacksplit(Link *ctxt, LSym *cursym) deltasp = autoffset; if(cursym->text->from.scale & WRAPPER) { - // g->panicwrap += autoffset + ctxt->arch->ptrsize; + // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame + // + // MOVL g_panic(CX), BX + // TESTL BX, BX + // JEQ end + // LEAL (autoffset+4)(SP), DI + // CMPL panic_argp(BX), DI + // JNE end + // MOVL SP, panic_argp(BX) + // end: + // NOP + // + // The NOP is needed to give the jumps somewhere to land. + // It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes. + p = appendp(ctxt, p); - p->as = AADDL; - p->from.type = D_CONST; - p->from.offset = autoffset + ctxt->arch->ptrsize; - p->to.type = D_INDIR+D_CX; - p->to.offset = 2*ctxt->arch->ptrsize; + p->as = AMOVL; + p->from.type = D_INDIR+D_CX; + p->from.offset = 4*ctxt->arch->ptrsize; // G.panic + p->to.type = D_BX; + + p = appendp(ctxt, p); + p->as = ATESTL; + p->from.type = D_BX; + p->to.type = D_BX; + + p = appendp(ctxt, p); + p->as = AJEQ; + p->to.type = D_BRANCH; + p1 = p; + + p = appendp(ctxt, p); + p->as = ALEAL; + p->from.type = D_INDIR+D_SP; + p->from.offset = autoffset+4; + p->to.type = D_DI; + + p = appendp(ctxt, p); + p->as = ACMPL; + p->from.type = D_INDIR+D_BX; + p->from.offset = 0; // Panic.argp + p->to.type = D_DI; + + p = appendp(ctxt, p); + p->as = AJNE; + p->to.type = D_BRANCH; + p2 = p; + + p = appendp(ctxt, p); + p->as = AMOVL; + p->from.type = D_SP; + p->to.type = D_INDIR+D_BX; + p->to.offset = 0; // Panic.argp + + p = appendp(ctxt, p); + p->as = ANOP; + p1->pcond = p; + p2->pcond = p; } if(ctxt->debugzerostack && autoffset && !(cursym->text->from.scale&NOSPLIT)) { @@ -396,19 +447,6 @@ addstacksplit(Link *ctxt, LSym *cursym) if(autoffset != deltasp) ctxt->diag("unbalanced PUSH/POP"); - if(cursym->text->from.scale & WRAPPER) { - p = load_g_cx(ctxt, p); - p = appendp(ctxt, p); - // g->panicwrap -= autoffset + ctxt->arch->ptrsize; - p->as = ASUBL; - p->from.type = D_CONST; - p->from.offset = autoffset + ctxt->arch->ptrsize; - p->to.type = D_INDIR+D_CX; - p->to.offset = 2*ctxt->arch->ptrsize; - p = appendp(ctxt, p); - p->as = ARET; - } - if(autoffset) { p->as = AADJSP; p->from.type = D_CONST; @@ -463,7 +501,6 @@ static Prog* stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) { Prog *q, *q1; - int arg; if(ctxt->debugstack) { // 8l -K means check not only for stack @@ -501,6 +538,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) p->as = ACMPL; p->from.type = D_SP; p->to.type = D_INDIR+D_CX; + p->to.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 + if(ctxt->cursym->cfunc) + p->to.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 } else if(framesize <= StackBig) { // large stack: SP-framesize <= stackguard-StackSmall // LEAL -(framesize-StackSmall)(SP), AX @@ -515,6 +555,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) p->as = ACMPL; p->from.type = D_AX; p->to.type = D_INDIR+D_CX; + p->to.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 + if(ctxt->cursym->cfunc) + p->to.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 } else { // Such a large stack we need to protect against wraparound // if SP is close to zero. @@ -534,6 +577,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) p->as = AMOVL; p->from.type = D_INDIR+D_CX; p->from.offset = 0; + p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0 + if(ctxt->cursym->cfunc) + p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1 p->to.type = D_SI; p = appendp(ctxt, p); @@ -573,37 +619,13 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok) p->to.offset = 4; q = p; - p = appendp(ctxt, p); // save frame size in DI - p->as = AMOVL; - p->to.type = D_DI; - p->from.type = D_CONST; - - // If we ask for more stack, we'll get a minimum of StackMin bytes. - // We need a stack frame large enough to hold the top-of-stack data, - // the function arguments+results, our caller's PC, our frame, - // a word for the return PC of the next call, and then the StackLimit bytes - // that must be available on entry to any function called from a function - // that did a stack check. If StackMin is enough, don't ask for a specific - // amount: then we can use the custom functions and save a few - // instructions. - if(StackTop + ctxt->cursym->text->to.offset2 + ctxt->arch->ptrsize + framesize + ctxt->arch->ptrsize + StackLimit >= StackMin) - p->from.offset = (framesize+7) & ~7LL; - - arg = ctxt->cursym->text->to.offset2; - if(arg == 1) // special marker for known 0 - arg = 0; - if(arg&3) - ctxt->diag("misaligned argument size in stack split"); - p = appendp(ctxt, p); // save arg size in AX - p->as = AMOVL; - p->to.type = D_AX; - p->from.type = D_CONST; - p->from.offset = arg; - p = appendp(ctxt, p); p->as = ACALL; p->to.type = D_BRANCH; - p->to.sym = ctxt->symmorestack[noctxt]; + if(ctxt->cursym->cfunc) + p->to.sym = linklookup(ctxt, "runtime.morestackc", 0); + else + p->to.sym = ctxt->symmorestack[noctxt]; p = appendp(ctxt, p); p->as = AJMP; @@ -697,7 +719,7 @@ xfol(Link *ctxt, Prog *p, Prog **last) { Prog *q; int i; - enum as a; + int a; loop: if(p == nil) @@ -816,6 +838,7 @@ loop: LinkArch link386 = { .name = "386", .thechar = '8', + .endian = LittleEndian, .addstacksplit = addstacksplit, .assemble = span8, |