aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/link')
-rw-r--r--src/cmd/link/internal/ld/lib.go8
-rw-r--r--src/cmd/link/internal/loader/loader.go12
2 files changed, 15 insertions, 5 deletions
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 21441a7afa..703986828b 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1556,7 +1556,7 @@ func (ctxt *Link) hostlink() {
}
const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
- if ctxt.compressDWARF && linkerFlagSupported(argv[0], altLinker, compressDWARF) {
+ if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
argv = append(argv, compressDWARF)
}
@@ -1646,7 +1646,7 @@ func (ctxt *Link) hostlink() {
if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
// GCC uses -no-pie, clang uses -nopie.
for _, nopie := range []string{"-no-pie", "-nopie"} {
- if linkerFlagSupported(argv[0], altLinker, nopie) {
+ if linkerFlagSupported(ctxt.Arch, argv[0], altLinker, nopie) {
argv = append(argv, nopie)
break
}
@@ -1747,7 +1747,7 @@ func (ctxt *Link) hostlink() {
var createTrivialCOnce sync.Once
-func linkerFlagSupported(linker, altLinker, flag string) bool {
+func linkerFlagSupported(arch *sys.Arch, linker, altLinker, flag string) bool {
createTrivialCOnce.Do(func() {
src := filepath.Join(*flagTmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
@@ -1781,7 +1781,7 @@ func linkerFlagSupported(linker, altLinker, flag string) bool {
"-target",
}
- var flags []string
+ flags := hostlinkArchArgs(arch)
keep := false
skip := false
extldflags := strings.Fields(*flagExtldflags)
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 32c342e545..3df84c5c94 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -434,7 +434,17 @@ func (l *Loader) AddSym(name string, ver int, r *oReader, li int, kind int, dupo
if l.flags&FlagStrictDups != 0 {
l.checkdup(name, r, li, oldi)
}
- return oldi, false
+ // Fix for issue #46656 -- given two dupok symbols with
+ // different sizes, favor symbol with larger size.
+ szdup := l.SymSize(oldi)
+ sz := int64(r.Sym(li).Siz())
+ if szdup >= sz {
+ return oldi, false
+ } else {
+ // new symbol overwrites old symbol.
+ l.objSyms[oldi] = objSym{r, li}
+ return oldi, true
+ }
}
oldr, oldli := l.toLocal(oldi)
oldsym := oldr.Sym(oldli)