Commit 9629f55f authored by Cherry Zhang's avatar Cherry Zhang Committed by David Crawshaw

cmd/link: remove absolute address for c-archive on darwin/arm

Now it is possible to build a c-archive as PIC on darwin/arm (this is
now the default). Then the system linker can link the binary using
the archive as PIE.

Fixes #12896.

Change-Id: Iad84131572422190f5fa036e7d71910dc155f155
Reviewed-on: https://go-review.googlesource.com/22461Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 86c93c98
...@@ -334,6 +334,11 @@ func buildModeInit() { ...@@ -334,6 +334,11 @@ func buildModeInit() {
} }
return p return p
} }
switch platform {
case "darwin/arm":
codegenArg = "-shared"
default:
}
exeSuffix = ".a" exeSuffix = ".a"
ldBuildmode = "c-archive" ldBuildmode = "c-archive"
case "c-shared": case "c-shared":
......
...@@ -330,6 +330,36 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -330,6 +330,36 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
rs := r.Xsym rs := r.Xsym
if r.Type == obj.R_PCREL {
if rs.Type == obj.SHOSTOBJ {
ld.Diag("pc-relative relocation of external symbol is not supported")
return -1
}
if r.Siz != 4 {
return -1
}
// emit a pair of "scattered" relocations that
// resolve to the difference of section addresses of
// the symbol and the instruction
// this value is added to the field being relocated
o1 := uint32(sectoff)
o1 |= 1 << 31 // scattered bit
o1 |= ld.MACHO_ARM_RELOC_SECTDIFF << 24
o1 |= 2 << 28 // size = 4
o2 := uint32(0)
o2 |= 1 << 31 // scattered bit
o2 |= ld.MACHO_ARM_RELOC_PAIR << 24
o2 |= 2 << 28 // size = 4
ld.Thearch.Lput(o1)
ld.Thearch.Lput(uint32(ld.Symaddr(rs)))
ld.Thearch.Lput(o2)
ld.Thearch.Lput(uint32(ld.Ctxt.Cursym.Value + int64(r.Off)))
return 0
}
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM { if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM {
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type) ld.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
......
...@@ -560,6 +560,9 @@ func relocsym(s *LSym) { ...@@ -560,6 +560,9 @@ func relocsym(s *LSym) {
o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr) o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
} }
o -= int64(r.Off) // relative to section offset, not symbol o -= int64(r.Off) // relative to section offset, not symbol
} else if SysArch.Family == sys.ARM {
// see ../arm/asm.go:/machoreloc1
o += Symaddr(rs) - int64(Ctxt.Cursym.Value) - int64(r.Off)
} else { } else {
o += int64(r.Siz) o += int64(r.Siz)
} }
......
...@@ -79,6 +79,8 @@ const ( ...@@ -79,6 +79,8 @@ const (
MACHO_X86_64_RELOC_SIGNED_2 = 7 MACHO_X86_64_RELOC_SIGNED_2 = 7
MACHO_X86_64_RELOC_SIGNED_4 = 8 MACHO_X86_64_RELOC_SIGNED_4 = 8
MACHO_ARM_RELOC_VANILLA = 0 MACHO_ARM_RELOC_VANILLA = 0
MACHO_ARM_RELOC_PAIR = 1
MACHO_ARM_RELOC_SECTDIFF = 2
MACHO_ARM_RELOC_BR24 = 5 MACHO_ARM_RELOC_BR24 = 5
MACHO_ARM64_RELOC_UNSIGNED = 0 MACHO_ARM64_RELOC_UNSIGNED = 0
MACHO_ARM64_RELOC_BRANCH26 = 2 MACHO_ARM64_RELOC_BRANCH26 = 2
...@@ -350,8 +352,9 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) { ...@@ -350,8 +352,9 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
var msect *MachoSect var msect *MachoSect
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 || if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
(SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive))) { (SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive)) ||
// Darwin external linker on arm64 and on amd64 in c-shared/c-archive buildmode (SysArch.Family == sys.ARM && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive))) {
// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
// complains about absolute relocs in __TEXT, so if the section is not // complains about absolute relocs in __TEXT, so if the section is not
// executable, put it in __DATA segment. // executable, put it in __DATA segment.
msect = newMachoSect(mseg, buf, "__DATA") msect = newMachoSect(mseg, buf, "__DATA")
......
...@@ -13,10 +13,14 @@ import "unsafe" ...@@ -13,10 +13,14 @@ import "unsafe"
//go:linkname x_cgo_panicmem x_cgo_panicmem //go:linkname x_cgo_panicmem x_cgo_panicmem
var x_cgo_panicmem uintptr var x_cgo_panicmem uintptr
// use a pointer to avoid relocation of external symbol in __TEXT
// make linker happy
var _cgo_panicmem = &x_cgo_panicmem
// TODO(crawshaw): move this into x_cgo_init, it will not run until // TODO(crawshaw): move this into x_cgo_init, it will not run until
// runtime has finished loading, which may be after its use. // runtime has finished loading, which may be after its use.
func init() { func init() {
x_cgo_panicmem = funcPC(panicmem) *_cgo_panicmem = funcPC(panicmem)
} }
func funcPC(f interface{}) uintptr { func funcPC(f interface{}) uintptr {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment