summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2008-09-18 15:41:20 -0700
committerRuss Cox <rsc@golang.org>2008-09-18 15:41:20 -0700
commit20db8c4125cf37d4fae1471d440125351b0c638d (patch)
treef997bc81628a0cd65652a8c648fdb4376da70863
parentc1b01891de8fc8c845562e146cc455bf11dd2c17 (diff)
downloadgolang-20db8c4125cf37d4fae1471d440125351b0c638d.tar.gz
add -K flag to check stack underflow
R=ken DELTA=38 (36 added, 0 deleted, 2 changed) OCL=15482 CL=15491
-rw-r--r--src/cmd/6l/pass.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/cmd/6l/pass.c b/src/cmd/6l/pass.c
index fed9495c1..39394026d 100644
--- a/src/cmd/6l/pass.c
+++ b/src/cmd/6l/pass.c
@@ -565,7 +565,7 @@ brloop(Prog *p)
void
dostkoff(void)
{
- Prog *p, *q;
+ Prog *p, *q, *q1;
int32 autoffset, deltasp;
int a, f, curframe, curbecome, maxbecome, pcsize;
Prog *pmorestack;
@@ -667,8 +667,33 @@ dostkoff(void)
autoffset = 0;
q = P;
+ q1 = P;
if(pmorestack != P)
if(!(p->from.scale & NOSPLIT)) {
+ if(debug['K']) {
+ // 6l -K means check not only for stack
+ // overflow but stack underflow.
+ // On underflow, INT 3 (breakpoint).
+ // Underflow itself is rare but this also
+ // catches out-of-sync stack guard info.
+ p = appendp(p);
+ p->as = ACMPQ;
+ p->from.type = D_INDIR+D_R15;
+ p->from.offset = 8;
+ p->to.type = D_SP;
+
+ p = appendp(p);
+ p->as = AJHI;
+ p->to.type = D_BRANCH;
+ p->to.offset = 4;
+ q1 = p;
+
+ p = appendp(p);
+ p->as = AINT;
+ p->from.type = D_CONST;
+ p->from.offset = 3;
+ }
+
if(autoffset < 4096) { // do we need to call morestack
if(autoffset <= 75) {
// small stack
@@ -676,7 +701,10 @@ dostkoff(void)
p->as = ACMPQ;
p->from.type = D_SP;
p->to.type = D_INDIR+D_R15;
-
+ if(q1) {
+ q1->pcond = p;
+ q1 = P;
+ }
} else {
// large stack
p = appendp(p);
@@ -684,6 +712,10 @@ dostkoff(void)
p->from.type = D_INDIR+D_SP;
p->from.offset = -(autoffset-75);
p->to.type = D_AX;
+ if(q1) {
+ q1->pcond = p;
+ q1 = P;
+ }
p = appendp(p);
p->as = ACMPQ;
@@ -704,6 +736,10 @@ dostkoff(void)
p->from.type = D_CONST;
p->from.offset = 0;
p->to.type = D_AX;
+ if(q1) {
+ q1->pcond = p;
+ q1 = P;
+ }
/* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
if(autoffset+160 > 4096)