diff options
| author | Austin Clements <austin@google.com> | 2014-12-05 09:24:01 -0500 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2014-12-05 09:24:01 -0500 |
| commit | e04c8b063fd7d7aaded8e1ff549dbb520038c61e (patch) | |
| tree | a19eedb14272aa2ba3073f144b8a0c9184cc67dd /src/liblink/pass.c | |
| parent | 274976f45c9b2c3f9140768b457e9140ea65bfb4 (diff) | |
| download | go-e04c8b063fd7d7aaded8e1ff549dbb520038c61e.tar.xz | |
[dev.cc] liblink: don't patch jumps to jumps to symbols
When liblink sees something like
JMP x
...
x: JMP y
it rewrites the first jump to jump directly to y. This is
fine if y is a resolved label. However, it *also* does this
if y is a function symbol, but fails to carry over the
relocation that would later patch in that symbol's value. As
a result, the original jump becomes either a self-jump (if
relative) or a jump to PC 0 (if absolute).
Fix this by disabling this optimization if the jump being
patched in is a jump to a symbol.
LGTM=minux
R=rsc, minux
CC=golang-codereviews
https://golang.org/cl/185890044
Diffstat (limited to 'src/liblink/pass.c')
| -rw-r--r-- | src/liblink/pass.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/liblink/pass.c b/src/liblink/pass.c index bc8eb43679..8721a6a796 100644 --- a/src/liblink/pass.c +++ b/src/liblink/pass.c @@ -41,7 +41,7 @@ brchain(Link *ctxt, Prog *p) int i; for(i=0; i<20; i++) { - if(p == nil || p->as != ctxt->arch->AJMP) + if(p == nil || p->as != ctxt->arch->AJMP || p->pcond == nil) return p; p = p->pcond; } @@ -56,7 +56,7 @@ brloop(Link *ctxt, Prog *p) c = 0; for(q = p; q != nil; q = q->pcond) { - if(q->as != ctxt->arch->AJMP) + if(q->as != ctxt->arch->AJMP || q->pcond == nil) break; c++; if(c >= 5000) |
