diff options
| author | qmuntal <quimmuntal@gmail.com> | 2025-10-22 16:33:18 +0200 |
|---|---|---|
| committer | Quim Muntal <quimmuntal@gmail.com> | 2025-11-05 12:38:57 -0800 |
| commit | 8cf7a0b4c956aad5a8b98efde8ea6b7cde173902 (patch) | |
| tree | 0bcafd2aa09032ebe34e7780d5fc7ba489724697 /src/cmd/link/internal | |
| parent | 2dd7e94e163f172472273b81846e6e3add412bc6 (diff) | |
| download | go-8cf7a0b4c956aad5a8b98efde8ea6b7cde173902.tar.xz | |
cmd/link: support weak binding on darwin
Symbols loaded from host files can have the N_WEAK_REF bit set,
which is used to instruct the loader to not fail if that symbol
can't be resolved.
The Go internal linker should honor this information by setting the
BIND_SYMBOL_FLAGS_WEAK_IMPORT flag in the corresponding bind table
entry.
Fixes #76023
Cq-Include-Trybots: luci.golang.try:gotip-darwin-amd64-longtest,gotip-darwin-amd64_12,gotip-darwin-arm64_12,gotip-darwin-arm64_15,gotip-darwin-arm64-longtest,gotip-darwin-amd64_14
Change-Id: Id2cef247ec7a9cb08455844f3c30ff874772bb7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/713760
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/link/internal')
| -rw-r--r-- | src/cmd/link/internal/ld/macho.go | 8 | ||||
| -rw-r--r-- | src/cmd/link/internal/loader/loader.go | 14 | ||||
| -rw-r--r-- | src/cmd/link/internal/loadmacho/ldmacho.go | 3 |
3 files changed, 24 insertions, 1 deletions
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 6d3347ff2d..65ae1268c3 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -180,6 +180,8 @@ const ( BIND_SPECIAL_DYLIB_FLAT_LOOKUP = -2 BIND_SPECIAL_DYLIB_WEAK_LOOKUP = -3 + BIND_SYMBOL_FLAGS_WEAK_IMPORT = 0x1 + BIND_OPCODE_MASK = 0xF0 BIND_IMMEDIATE_MASK = 0x0F BIND_OPCODE_DONE = 0x00 @@ -1429,7 +1431,11 @@ func machoDyldInfo(ctxt *Link) { bind.AddUint8(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | uint8(d)&0xf) } - bind.AddUint8(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM) + flags := uint8(0) + if ldr.SymWeakBinding(r.targ) { + flags |= BIND_SYMBOL_FLAGS_WEAK_IMPORT + } + bind.AddUint8(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | flags) // target symbol name as a C string, with _ prefix bind.AddUint8('_') bind.Addstring(ldr.SymExtname(r.targ)) diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 3fb2e86514..a612a1ac81 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -241,6 +241,7 @@ type Loader struct { plt map[Sym]int32 // stores dynimport for pe objects got map[Sym]int32 // stores got for pe objects dynid map[Sym]int32 // stores Dynid for symbol + weakBinding map[Sym]bool // stores whether a symbol has a weak binding relocVariant map[relocId]sym.RelocVariant // stores variant relocs @@ -326,6 +327,7 @@ func NewLoader(flags uint32, reporter *ErrorReporter) *Loader { plt: make(map[Sym]int32), got: make(map[Sym]int32), dynid: make(map[Sym]int32), + weakBinding: make(map[Sym]bool), attrCgoExportDynamic: make(map[Sym]struct{}), attrCgoExportStatic: make(map[Sym]struct{}), deferReturnTramp: make(map[Sym]bool), @@ -1447,6 +1449,18 @@ func (l *Loader) SetSymExtname(i Sym, value string) { } } +func (l *Loader) SymWeakBinding(i Sym) bool { + return l.weakBinding[i] +} + +func (l *Loader) SetSymWeakBinding(i Sym, v bool) { + // reject bad symbols + if i >= Sym(len(l.objSyms)) || i == 0 { + panic("bad symbol index in SetSymWeakBinding") + } + l.weakBinding[i] = v +} + // SymElfType returns the previously recorded ELF type for a symbol // (used only for symbols read from shared libraries by ldshlibsyms). // It is not set for symbols defined by the packages being linked or diff --git a/src/cmd/link/internal/loadmacho/ldmacho.go b/src/cmd/link/internal/loadmacho/ldmacho.go index 5e8022ce69..dcb0fd92c1 100644 --- a/src/cmd/link/internal/loadmacho/ldmacho.go +++ b/src/cmd/link/internal/loadmacho/ldmacho.go @@ -613,6 +613,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, } if machsym.desc&(N_WEAK_REF|N_WEAK_DEF) != 0 { l.SetAttrDuplicateOK(s, true) + if machsym.desc&N_WEAK_REF != 0 { + l.SetSymWeakBinding(s, true) + } } machsym.sym = s if machsym.sectnum == 0 { // undefined |
