Skip to content

Commit be910bf

Browse files
committed
cmd/link: always use symbol-targeted relocations on Mach-O
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 <[email protected]> Run-TryBot: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent bad9ca8 commit be910bf

File tree

4 files changed

+14
-10
lines changed

4 files changed

+14
-10
lines changed

src/cmd/link/internal/amd64/asm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
469469
rs := r.Xsym
470470
rt := r.Type
471471

472-
if rt == objabi.R_PCREL || rt == objabi.R_GOTPCREL || rt == objabi.R_CALL || ldr.SymType(rs) == sym.SHOSTOBJ || ldr.SymType(s) == sym.SINITARR {
472+
if !ldr.SymType(s).IsDWARF() {
473473
if ldr.SymDynid(rs) < 0 {
474474
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))
475475
return false

src/cmd/link/internal/arm64/asm.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,11 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
557557
siz := r.Size
558558
xadd := r.Xadd
559559

560-
if xadd != signext24(xadd) {
560+
if xadd != signext24(xadd) && rt != objabi.R_ADDR {
561561
// If the relocation target would overflow the addend, then target
562562
// a linker-manufactured label symbol with a smaller addend instead.
563+
// R_ADDR has full-width addend encoded in data content, so it doesn't
564+
// use a label symbol.
563565
label := ldr.Lookup(offsetLabelName(ldr, rs, xadd/machoRelocLimit*machoRelocLimit), ldr.SymVersion(rs))
564566
if label != 0 {
565567
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
577579
}
578580
}
579581

580-
if rt == objabi.R_CALLARM64 ||
581-
rt == objabi.R_ARM64_PCREL_LDST8 || rt == objabi.R_ARM64_PCREL_LDST16 ||
582-
rt == objabi.R_ARM64_PCREL_LDST32 || rt == objabi.R_ARM64_PCREL_LDST64 ||
583-
rt == objabi.R_ADDRARM64 || rt == objabi.R_ARM64_GOTPCREL ||
584-
ldr.SymType(rs) == sym.SHOSTOBJ || ldr.SymType(s) == sym.SINITARR {
582+
if !ldr.SymType(s).IsDWARF() {
585583
if ldr.SymDynid(rs) < 0 {
586584
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))
587585
return false

src/cmd/link/internal/ld/data.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,11 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
368368
o = 0
369369
}
370370
} else if target.IsDarwin() {
371-
if ldr.SymType(rs) != sym.SHOSTOBJ && ldr.SymType(s) != sym.SINITARR {
372-
// ld-prime drops the offset in data for SINITARR. We need to use
373-
// symbol-targeted relocation. See also machoreloc1.
371+
if ldr.SymType(s).IsDWARF() {
372+
// We generally use symbol-targeted relocations.
373+
// DWARF tools seem to only handle section-targeted relocations,
374+
// so generate section-targeted relocations in DWARF sections.
375+
// See also machoreloc1.
374376
o += ldr.SymValue(rs)
375377
}
376378
} else if target.IsWindows() {

src/cmd/link/internal/sym/symkind.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,7 @@ var RelROMap = map[SymKind]SymKind{
184184
func (t SymKind) IsData() bool {
185185
return t == SDATA || t == SNOPTRDATA || t == SBSS || t == SNOPTRBSS
186186
}
187+
188+
func (t SymKind) IsDWARF() bool {
189+
return t >= SDWARFSECT && t <= SDWARFLINES
190+
}

0 commit comments

Comments
 (0)