Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
1228112b
Commit
1228112b
authored
Oct 27, 2009
by
Kai Backman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bug162, large indices on nil references
R=rsc
http://go/go-review/1013016
parent
ae3c9992
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
71 additions
and
14 deletions
+71
-14
cgen.c
src/cmd/5g/cgen.c
+10
-0
gg.h
src/cmd/5g/gg.h
+2
-1
gsubr.c
src/cmd/5g/gsubr.c
+59
-13
No files found.
src/cmd/5g/cgen.c
View file @
1228112b
...
...
@@ -702,6 +702,16 @@ agen(Node *n, Node *res)
case
ODOTPTR
:
cgen
(
nl
,
res
);
if
(
n
->
xoffset
!=
0
)
{
// explicit check for nil if struct is large enough
// that we might derive too big a pointer.
if
(
nl
->
type
->
type
->
width
>=
unmappedzero
)
{
regalloc
(
&
n1
,
types
[
tptr
],
N
);
gmove
(
res
,
&
n1
);
p1
=
gins
(
AMOVW
,
&
n1
,
&
n1
);
p1
->
from
.
type
=
D_OREG
;
p1
->
from
.
offset
=
0
;
regfree
(
&
n1
);
}
nodconst
(
&
n1
,
types
[
TINT32
],
n
->
xoffset
);
regalloc
(
&
n2
,
n1
.
type
,
N
);
regalloc
(
&
n3
,
types
[
tptr
],
N
);
...
...
src/cmd/5g/gg.h
View file @
1228112b
...
...
@@ -62,6 +62,7 @@ EXTERN Node* deferproc;
EXTERN
Node
*
deferreturn
;
EXTERN
Node
*
throwindex
;
EXTERN
Node
*
throwreturn
;
EXTERN
long
unmappedzero
;
EXTERN
int
maxstksize
;
/*
...
...
@@ -99,7 +100,7 @@ void raddr(Node *n, Prog *p);
Prog
*
gcmp
(
int
,
Node
*
,
Node
*
);
Prog
*
gshift
(
int
as
,
Node
*
lhs
,
int32
stype
,
int32
sval
,
Node
*
rhs
);
Prog
*
gregshift
(
int
as
,
Node
*
lhs
,
int32
stype
,
Node
*
reg
,
Node
*
rhs
);
void
naddr
(
Node
*
,
Addr
*
);
void
naddr
(
Node
*
,
Addr
*
,
int
);
void
cgen_aret
(
Node
*
,
Node
*
);
/*
...
...
src/cmd/5g/gsubr.c
View file @
1228112b
...
...
@@ -30,6 +30,10 @@
#include "gg.h"
// TODO(kaib): Can make this bigger if we move
// the text segment up higher in 5l for all GOOS.
long
unmappedzero
=
4096
;
void
clearp
(
Prog
*
p
)
{
...
...
@@ -863,6 +867,7 @@ gins(int as, Node *f, Node *t)
// Node nod;
// int32 v;
Prog
*
p
;
Addr
af
,
at
;
if
(
f
!=
N
&&
f
->
op
==
OINDEX
)
{
fatal
(
"gins OINDEX not implemented"
);
...
...
@@ -883,11 +888,16 @@ gins(int as, Node *f, Node *t)
// regfree(&nod);
}
p
=
prog
(
as
);
memset
(
&
af
,
0
,
sizeof
af
);
memset
(
&
at
,
0
,
sizeof
at
);
if
(
f
!=
N
)
naddr
(
f
,
&
p
->
from
);
naddr
(
f
,
&
af
,
1
);
if
(
t
!=
N
)
naddr
(
t
,
&
p
->
to
);
naddr
(
t
,
&
at
,
1
);
p
=
prog
(
as
);
if
(
f
!=
N
)
p
->
from
=
af
;
if
(
t
!=
N
)
p
->
to
=
at
;
if
(
debug
[
'g'
])
print
(
"%P
\n
"
,
p
);
return
p
;
...
...
@@ -901,7 +911,7 @@ raddr(Node *n, Prog *p)
{
Addr
a
;
naddr
(
n
,
&
a
);
naddr
(
n
,
&
a
,
1
);
if
(
a
.
type
!=
D_REG
&&
a
.
type
!=
D_FREG
)
{
if
(
n
)
fatal
(
"bad in raddr: %O"
,
n
->
op
);
...
...
@@ -958,13 +968,33 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
return
p
;
}
static
void
checkoffset
(
Addr
*
a
,
int
canemitcode
)
{
Prog
*
p
;
Node
n1
;
if
(
a
->
offset
<
unmappedzero
)
return
;
if
(
!
canemitcode
)
fatal
(
"checkoffset %#llx, 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
(
AMOVW
,
N
,
&
n1
);
p
->
from
=
*
a
;
p
->
from
.
offset
=
0
;
regfree
(
&
n1
);
}
/*
* generate code to compute n;
* make a refer to result.
*/
void
naddr
(
Node
*
n
,
Addr
*
a
)
naddr
(
Node
*
n
,
Addr
*
a
,
int
canemitcode
)
{
a
->
type
=
D_NONE
;
a
->
name
=
D_NONE
;
...
...
@@ -1014,6 +1044,7 @@ naddr(Node *n, Addr *a)
a
->
reg
=
n
->
val
.
u
.
reg
;
a
->
sym
=
n
->
sym
;
a
->
offset
=
n
->
xoffset
;
checkoffset
(
a
,
canemitcode
);
break
;
case
OPARAM
:
...
...
@@ -1099,18 +1130,22 @@ naddr(Node *n, Addr *a)
case
OLEN
:
// len of string or slice
naddr
(
n
->
left
,
a
);
naddr
(
n
->
left
,
a
,
canemitcode
);
a
->
offset
+=
Array_nel
;
if
(
a
->
offset
>=
unmappedzero
&&
a
->
offset
-
Array_nel
<
unmappedzero
)
checkoffset
(
a
,
canemitcode
);
break
;
case
OCAP
:
// cap of string or slice
naddr
(
n
->
left
,
a
);
naddr
(
n
->
left
,
a
,
canemitcode
);
a
->
offset
+=
Array_cap
;
if
(
a
->
offset
>=
unmappedzero
&&
a
->
offset
-
Array_cap
<
unmappedzero
)
checkoffset
(
a
,
canemitcode
);
break
;
case
OADDR
:
naddr
(
n
->
left
,
a
);
naddr
(
n
->
left
,
a
,
canemitcode
);
switch
(
a
->
type
)
{
case
D_OREG
:
a
->
type
=
D_CONST
;
...
...
@@ -1558,7 +1593,7 @@ lit:
reg1
=
&
clean
[
cleani
-
2
];
reg
->
op
=
OEMPTY
;
reg1
->
op
=
OEMPTY
;
naddr
(
n
,
a
);
naddr
(
n
,
a
,
1
);
goto
yes
;
odot:
...
...
@@ -1571,7 +1606,7 @@ odot:
n1
=
*
nn
;
n1
.
type
=
n
->
type
;
n1
.
xoffset
+=
oary
[
0
];
naddr
(
&
n1
,
a
);
naddr
(
&
n1
,
a
,
1
);
goto
yes
;
}
...
...
@@ -1595,7 +1630,7 @@ odot:
a
->
type
=
D_NONE
;
a
->
name
=
D_NONE
;
naddr
(
&
n1
,
a
);
naddr
(
&
n1
,
a
,
1
);
goto
yes
;
oindex:
...
...
@@ -1669,6 +1704,17 @@ 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
);
...
...
@@ -1699,7 +1745,7 @@ oindex:
else
if
(
*
w
==
8
)
gshift
(
AADD
,
reg1
,
SHIFT_LL
,
3
,
reg
);
naddr
(
reg1
,
a
);
naddr
(
reg1
,
a
,
1
);
a
->
type
=
D_OREG
;
a
->
reg
=
reg
->
val
.
u
.
reg
;
a
->
offset
=
0
;
...
...
@@ -1763,7 +1809,7 @@ oindex_const:
n2
.
xoffset
=
v
*
(
*
w
);
a
->
type
=
D_NONE
;
a
->
name
=
D_NONE
;
naddr
(
&
n2
,
a
);
naddr
(
&
n2
,
a
,
1
);
goto
yes
;
yes:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment