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