diff options
Diffstat (limited to 'src/cmd/8g/gsubr.c')
-rw-r--r-- | src/cmd/8g/gsubr.c | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index 756bdd203..34703ba6e 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -31,9 +31,11 @@ #include <u.h> #include <libc.h> #include "gg.h" +#include "../../pkg/runtime/funcdata.h" // TODO(rsc): Can make this bigger if we move // the text segment up higher in 8l for all GOOS. +// At the same time, can raise StackBig in ../../pkg/runtime/stack.h. uint32 unmappedzero = 4096; #define CASE(a,b) (((a)<<16)|((b)<<0)) @@ -208,6 +210,16 @@ ggloblnod(Node *nam) } void +gargsize(int32 size) +{ + Node n1, n2; + + nodconst(&n1, types[TINT32], PCDATA_ArgSize); + nodconst(&n2, types[TINT32], size); + gins(APCDATA, &n1, &n2); +} + +void ggloblsym(Sym *s, int32 width, int dupok, int rodata) { Prog *p; @@ -1145,6 +1157,7 @@ ismem(Node *n) { switch(n->op) { case OITAB: + case OSPTR: case OLEN: case OCAP: case OINDREG: @@ -2158,43 +2171,6 @@ gins(int as, Node *f, Node *t) return p; } -// Generate an instruction referencing *n -// to force segv on nil pointer dereference. -void -checkref(Node *n, int force) -{ - Node m; - - if(!force && isptr[n->type->etype] && n->type->type->width < unmappedzero) - return; - - regalloc(&m, types[TUINTPTR], n); - cgen(n, &m); - m.xoffset = 0; - m.op = OINDREG; - m.type = types[TUINT8]; - gins(ATESTB, nodintconst(0), &m); - regfree(&m); -} - -static void -checkoffset(Addr *a, int canemitcode) -{ - Prog *p; - - if(a->offset < unmappedzero) - return; - if(!canemitcode) - fatal("checkoffset %#x, cannot emit code", a->offset); - - // cannot rely on unmapped nil page at 0 to catch - // reference with large offset. instead, emit explicit - // test of 0(reg). - p = gins(ATESTB, nodintconst(0), N); - p->to = *a; - p->to.offset = 0; -} - /* * generate code to compute n; * make a refer to result. @@ -2344,8 +2320,16 @@ naddr(Node *n, Addr *a, int canemitcode) break; // len(nil) a->etype = tptr; a->width = widthptr; - if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) - checkoffset(a, canemitcode); + break; + + case OSPTR: + // pointer in a string or slice + naddr(n->left, a, canemitcode); + if(a->type == D_CONST && a->offset == 0) + break; // ptr(nil) + a->etype = simtype[TUINTPTR]; + a->offset += Array_array; + a->width = widthptr; break; case OLEN: @@ -2356,8 +2340,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->etype = TUINT32; a->offset += Array_nel; a->width = 4; - if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) - checkoffset(a, canemitcode); break; case OCAP: @@ -2368,8 +2350,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->etype = TUINT32; a->offset += Array_cap; a->width = 4; - if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) - checkoffset(a, canemitcode); break; // case OADD: |