aboutsummaryrefslogtreecommitdiff
path: root/src/liblink
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2014-12-05 09:24:01 -0500
committerAustin Clements <austin@google.com>2014-12-05 09:24:01 -0500
commite04c8b063fd7d7aaded8e1ff549dbb520038c61e (patch)
treea19eedb14272aa2ba3073f144b8a0c9184cc67dd /src/liblink
parent274976f45c9b2c3f9140768b457e9140ea65bfb4 (diff)
downloadgo-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')
-rw-r--r--src/liblink/pass.c4
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)