mirror of https://github.com/golang/go.git
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/22461 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
86c93c989e
commit
9629f55fbb
|
|
@ -334,6 +334,11 @@ func buildModeInit() {
|
|||
}
|
||||
return p
|
||||
}
|
||||
switch platform {
|
||||
case "darwin/arm":
|
||||
codegenArg = "-shared"
|
||||
default:
|
||||
}
|
||||
exeSuffix = ".a"
|
||||
ldBuildmode = "c-archive"
|
||||
case "c-shared":
|
||||
|
|
|
|||
|
|
@ -330,6 +330,36 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
|
|||
|
||||
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.Dynid < 0 {
|
||||
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) {
|
|||
o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
|
||||
}
|
||||
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 {
|
||||
o += int64(r.Siz)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ const (
|
|||
MACHO_X86_64_RELOC_SIGNED_2 = 7
|
||||
MACHO_X86_64_RELOC_SIGNED_4 = 8
|
||||
MACHO_ARM_RELOC_VANILLA = 0
|
||||
MACHO_ARM_RELOC_PAIR = 1
|
||||
MACHO_ARM_RELOC_SECTDIFF = 2
|
||||
MACHO_ARM_RELOC_BR24 = 5
|
||||
MACHO_ARM64_RELOC_UNSIGNED = 0
|
||||
MACHO_ARM64_RELOC_BRANCH26 = 2
|
||||
|
|
@ -350,8 +352,9 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
|
|||
|
||||
var msect *MachoSect
|
||||
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
|
||||
(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.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive)) ||
|
||||
(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
|
||||
// executable, put it in __DATA segment.
|
||||
msect = newMachoSect(mseg, buf, "__DATA")
|
||||
|
|
|
|||
|
|
@ -13,10 +13,14 @@ import "unsafe"
|
|||
//go:linkname x_cgo_panicmem x_cgo_panicmem
|
||||
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
|
||||
// runtime has finished loading, which may be after its use.
|
||||
func init() {
|
||||
x_cgo_panicmem = funcPC(panicmem)
|
||||
*_cgo_panicmem = funcPC(panicmem)
|
||||
}
|
||||
|
||||
func funcPC(f interface{}) uintptr {
|
||||
|
|
|
|||
Loading…
Reference in New Issue