--- /dev/null
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build cgo && darwin
+
+package cgotest
+
+import "testing"
+
+func TestIssue76023(t *testing.T) { issue76023(t) }
--- /dev/null
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build darwin
+
+package cgotest
+
+/*
+#cgo LDFLAGS: -Wl,-undefined,dynamic_lookup
+
+extern void __gotest_cgo_null_api(void) __attribute__((weak_import));
+
+int issue76023(void) {
+ if (__gotest_cgo_null_api) return 1;
+ return 0;
+}
+*/
+import "C"
+import "testing"
+
+func issue76023(t *testing.T) {
+ r := C.issue76023()
+ if r != 0 {
+ t.Error("found __gotest_cgo_null_api")
+ }
+}
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
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))
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
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),
}
}
+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
}
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