]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: always use symbol-targeted relocations on Mach-O
authorCherry Mui <cherryyz@google.com>
Thu, 15 Jun 2023 21:25:08 +0000 (17:25 -0400)
committerCherry Mui <cherryyz@google.com>
Mon, 31 Jul 2023 17:02:24 +0000 (17:02 +0000)
In Mach-O object files, there are two kinds of relocations:
"external" relocation, which targets a symbol, and "non-external"
relocation, which targets a section. For targeting symbols not in
the current object, we must use symbol-targeted relocations. For
targeting symbols defined in the current object, for some
relocation types, both kinds can be used. We currently use
section-targeted relocations for R_ADDR targeting locally defined
symbols.

Modern Apple toolchain seems to prefer symbol-targeted relocations.
Also, Apple's new linker, ld-prime, seems to not handle section-
targeted relocations well in some cases. So this CL switches to
always generate symbol-targeted relocations. This also simplifies
the code.

One exception is that DWARF tools seem to handle only section-
targeted relocations. So generate those in DWARF sections.

This CL supersedes CL 502616.

Fixes #60694.
For #61229.

Change-Id: I3b74df64f21114635061bcd89114392b3a2d588b
Reviewed-on: https://go-review.googlesource.com/c/go/+/503935
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/sym/symkind.go

index 0c5486bf53c361568698306eadedc4df7ddfae20..f5a3786e2e2bcbcd7303d13d08e6ea134c8113ea 100644 (file)
@@ -469,7 +469,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
        rs := r.Xsym
        rt := r.Type
 
-       if rt == objabi.R_PCREL || rt == objabi.R_GOTPCREL || rt == objabi.R_CALL || ldr.SymType(rs) == sym.SHOSTOBJ || ldr.SymType(s) == sym.SINITARR {
+       if !ldr.SymType(s).IsDWARF() {
                if ldr.SymDynid(rs) < 0 {
                        ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
                        return false
index 6e691dbe65cd11caba526e8305d4bddc995bbb74..ee4349f42286f5496f70819bca4c6b2515a03f1f 100644 (file)
@@ -557,9 +557,11 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
        siz := r.Size
        xadd := r.Xadd
 
-       if xadd != signext24(xadd) {
+       if xadd != signext24(xadd) && rt != objabi.R_ADDR {
                // If the relocation target would overflow the addend, then target
                // a linker-manufactured label symbol with a smaller addend instead.
+               // R_ADDR has full-width addend encoded in data content, so it doesn't
+               // use a label symbol.
                label := ldr.Lookup(offsetLabelName(ldr, rs, xadd/machoRelocLimit*machoRelocLimit), ldr.SymVersion(rs))
                if label != 0 {
                        xadd = ldr.SymValue(rs) + xadd - ldr.SymValue(label)
@@ -577,11 +579,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
                }
        }
 
-       if rt == objabi.R_CALLARM64 ||
-               rt == objabi.R_ARM64_PCREL_LDST8 || rt == objabi.R_ARM64_PCREL_LDST16 ||
-               rt == objabi.R_ARM64_PCREL_LDST32 || rt == objabi.R_ARM64_PCREL_LDST64 ||
-               rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL ||
-               ldr.SymType(rs) == sym.SHOSTOBJ || ldr.SymType(s) == sym.SINITARR {
+       if !ldr.SymType(s).IsDWARF() {
                if ldr.SymDynid(rs) < 0 {
                        ldr.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
                        return false
index 21b2e9a9d4896b62de1e05128ccbda95ceae9f0d..95fc8b5a42ac822334579d786a93183f323342d9 100644 (file)
@@ -368,9 +368,11 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                                                o = 0
                                        }
                                } else if target.IsDarwin() {
-                                       if ldr.SymType(rs) != sym.SHOSTOBJ && ldr.SymType(s) != sym.SINITARR {
-                                               // ld-prime drops the offset in data for SINITARR. We need to use
-                                               // symbol-targeted relocation. See also machoreloc1.
+                                       if ldr.SymType(s).IsDWARF() {
+                                               // We generally use symbol-targeted relocations.
+                                               // DWARF tools seem to only handle section-targeted relocations,
+                                               // so generate section-targeted relocations in DWARF sections.
+                                               // See also machoreloc1.
                                                o += ldr.SymValue(rs)
                                        }
                                } else if target.IsWindows() {
index 77dbf75a51cc5938096aeb2511bc151581976e9a..08cafb206b93097dfa6b174423d9f989ef546aa7 100644 (file)
@@ -184,3 +184,7 @@ var RelROMap = map[SymKind]SymKind{
 func (t SymKind) IsData() bool {
        return t == SDATA || t == SNOPTRDATA || t == SBSS || t == SNOPTRBSS
 }
+
+func (t SymKind) IsDWARF() bool {
+       return t >= SDWARFSECT && t <= SDWARFLINES
+}