summaryrefslogtreecommitdiff
path: root/src/cmd/5g/gsubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5g/gsubr.c')
-rw-r--r--src/cmd/5g/gsubr.c81
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;