From 2aceea630f29d3716eea4b8a7d7973f1b3b5e5c8 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Thu, 7 Apr 2011 14:20:42 -0400 Subject: [PATCH] ld: fix Mach-O X86_64_RELOC_SIGNED relocations Fixes #1658. R=rsc CC=golang-dev https://golang.org/cl/4344066 --- src/cmd/ld/ldmacho.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/cmd/ld/ldmacho.c b/src/cmd/ld/ldmacho.c index fbf2f1779b..ad275dca8c 100644 --- a/src/cmd/ld/ldmacho.c +++ b/src/cmd/ld/ldmacho.c @@ -422,6 +422,7 @@ void ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) { int i, j, is64; + uint64 secaddr; uchar hdr[7*4], *cmdp; uchar tmp[4]; uchar *dat; @@ -754,8 +755,29 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn) rp->siz = rel->length; rp->type = 512 + (rel->type<<1) + rel->pcrel; rp->off = rel->addr; - - rp->add = e->e32(s->p+rp->off); + + // Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0). + if (thechar == '6' && rel->extrn == 0 && rel->type == 1) { + // Calculate the addend as the offset into the section. + // + // The rip-relative offset stored in the object file is encoded + // as follows: + // + // movsd 0x00000360(%rip),%xmm0 + // + // To get the absolute address of the value this rip-relative address is pointing + // to, we must add the address of the next instruction to it. This is done by + // taking the address of the relocation and adding 4 to it (since the rip-relative + // offset can at most be 32 bits long). To calculate the offset into the section the + // relocation is referencing, we subtract the vaddr of the start of the referenced + // section found in the original object file. + // + // [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h] + secaddr = c->seg.sect[rel->symnum-1].addr; + rp->add = e->e32(s->p+rp->off) + rp->off + 4 - secaddr; + } else + rp->add = e->e32(s->p+rp->off); + // For i386 Mach-O PC-relative, the addend is written such that // it *is* the PC being subtracted. Use that to make // it match our version of PC-relative. -- 2.50.0