]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: remove absolute address for c-archive on darwin/arm
authorCherry Zhang <cherryyz@google.com>
Tue, 26 Apr 2016 19:17:56 +0000 (15:17 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Wed, 27 Apr 2016 16:22:06 +0000 (16:22 +0000)
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>
src/cmd/go/build.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/macho.go
src/runtime/cgo/signal_darwin_armx.go

index 4aaad04b3abf909edb4537ae77e2ef05309521ea..b8c12db1965cf086794d41a41b0c309cecf55546 100644 (file)
@@ -334,6 +334,11 @@ func buildModeInit() {
                        }
                        return p
                }
+               switch platform {
+               case "darwin/arm":
+                       codegenArg = "-shared"
+               default:
+               }
                exeSuffix = ".a"
                ldBuildmode = "c-archive"
        case "c-shared":
index 069812fcef4855c246d27583ceff045b844c361d..aafdd9bc3d51c07b0708c921516624b0483b94e3 100644 (file)
@@ -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)
index dbd5ad0b75507254170bc38334f3d92cb68f2b82..89647578464cb0484515f68708e43adac74e2884 100644 (file)
@@ -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)
                                        }
index 310435e49e2b3cd53ab7c9ac9502ab4e6892e9f7..53cc96275d956da5e9d0ecbadfe736e8e02c4851 100644 (file)
@@ -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")
index 9c1ba5dee1dd6b81dcab7be8bbfd20c197c79f94..9f6741eb08581976b4ebfb0315476c8a6223340a 100644 (file)
@@ -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 {