diff options
Diffstat (limited to 'src/cmd/5g/gsubr.c')
-rw-r--r-- | src/cmd/5g/gsubr.c | 81 |
1 files changed, 13 insertions, 68 deletions
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index 6f0a072cc..481174b21 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -1189,48 +1189,6 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs) return p; } -// Generate an instruction referencing *n -// to force segv on nil pointer dereference. -void -checkref(Node *n, int force) -{ - Node m1, m2; - - if(!force && isptr[n->type->etype] && n->type->type->width < unmappedzero) - return; - - regalloc(&m1, types[TUINTPTR], n); - regalloc(&m2, types[TUINT8], n); - cgen(n, &m1); - m1.xoffset = 0; - m1.op = OINDREG; - m1.type = types[TUINT8]; - gins(AMOVB, &m1, &m2); - regfree(&m2); - regfree(&m1); -} - -static void -checkoffset(Addr *a, int canemitcode) -{ - Prog *p; - Node n1; - - 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). - regalloc(&n1, types[TUINTPTR], N); - p = gins(AMOVB, N, &n1); - p->from = *a; - p->from.offset = 0; - regfree(&n1); -} - /* * generate code to compute n; * make a refer to result. @@ -1294,7 +1252,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->reg = n->val.u.reg; a->sym = n->sym; a->offset = n->xoffset; - checkoffset(a, canemitcode); break; case OPARAM: @@ -1402,8 +1359,6 @@ naddr(Node *n, Addr *a, int canemitcode) a->etype = TINT32; if(a->type == D_CONST && a->offset == 0) break; // len(nil) - if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) - checkoffset(a, canemitcode); break; case OLEN: @@ -1413,8 +1368,6 @@ naddr(Node *n, Addr *a, int canemitcode) if(a->type == D_CONST && a->offset == 0) break; // len(nil) a->offset += Array_nel; - if(a->offset >= unmappedzero && a->offset-Array_nel < unmappedzero) - checkoffset(a, canemitcode); break; case OCAP: @@ -1424,8 +1377,6 @@ naddr(Node *n, Addr *a, int canemitcode) if(a->type == D_CONST && a->offset == 0) break; // cap(nil) a->offset += Array_cap; - if(a->offset >= unmappedzero && a->offset-Array_cap < unmappedzero) - checkoffset(a, canemitcode); break; case OADDR: @@ -1932,6 +1883,7 @@ odot: n1.xoffset = oary[0]; } else { cgen(nn, reg); + cgen_checknil(reg); n1.xoffset = -(oary[0]+1); } @@ -1939,6 +1891,7 @@ odot: if(oary[i] >= 0) fatal("can't happen"); gins(AMOVW, &n1, reg); + cgen_checknil(reg); n1.xoffset = -(oary[i]+1); } @@ -1986,9 +1939,10 @@ oindex: // load the array (reg) if(l->ullman > r->ullman) { regalloc(reg, types[tptr], N); - if(o & OPtrto) + if(o & OPtrto) { cgen(l, reg); - else + cgen_checknil(reg); + } else agen(l, reg); } @@ -2005,9 +1959,10 @@ oindex: // load the array (reg) if(l->ullman <= r->ullman) { regalloc(reg, types[tptr], N); - if(o & OPtrto) + if(o & OPtrto) { cgen(l, reg); - else + cgen_checknil(reg); + } else agen(l, reg); } @@ -2019,20 +1974,10 @@ oindex: n2.type = types[tptr]; n2.xoffset = Array_nel; } else { - if(l->type->width >= unmappedzero && l->op == OIND) { - // cannot rely on page protections to - // catch array ptr == 0, so dereference. - n2 = *reg; - n2.op = OINDREG; - n2.type = types[TUINTPTR]; - n2.xoffset = 0; - regalloc(&n3, n2.type, N); - gins(AMOVW, &n2, &n3); - regfree(&n3); - } - nodconst(&n2, types[TUINT32], l->type->bound); if(o & OPtrto) nodconst(&n2, types[TUINT32], l->type->type->bound); + else + nodconst(&n2, types[TUINT32], l->type->bound); } regalloc(&n3, n2.type, N); cgen(&n2, &n3); @@ -2080,14 +2025,14 @@ oindex_const: // can multiply by width statically regalloc(reg, types[tptr], N); - if(o & OPtrto) + if(o & OPtrto) { cgen(l, reg); - else + cgen_checknil(reg); + } else agen(l, reg); v = mpgetfix(r->val.u.xval); if(o & ODynam) { - if(!debug['B'] && !n->bounded) { n1 = *reg; n1.op = OINDREG; |