diff options
| author | Katie Hockman <katie@golang.org> | 2020-12-14 10:03:05 -0500 |
|---|---|---|
| committer | Katie Hockman <katie@golang.org> | 2020-12-14 10:06:13 -0500 |
| commit | 0345ede87ee12698988973884cfc0fd3d499dffd (patch) | |
| tree | 7123cff141ee5661208d2f5f437b8f5252ac7f6a /src/cmd/link/internal/ld/lib.go | |
| parent | 4651d6b267818b0e0d128a5443289717c4bb8cbc (diff) | |
| parent | 0a02371b0576964e81c3b40d328db9a3ef3b031b (diff) | |
| download | go-0345ede87ee12698988973884cfc0fd3d499dffd.tar.xz | |
[dev.fuzz] all: merge master into dev.fuzz
Change-Id: I5d8c8329ccc9d747bd81ade6b1cb7cb8ae2e94b2
Diffstat (limited to 'src/cmd/link/internal/ld/lib.go')
| -rw-r--r-- | src/cmd/link/internal/ld/lib.go | 80 |
1 files changed, 56 insertions, 24 deletions
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 4295b2a660..e1cc7184de 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -247,12 +247,16 @@ type Arch struct { Elfreloc1 func(*Link, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int, int64) bool ElfrelocSize uint32 // size of an ELF relocation record, must match Elfreloc1. Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) - Gentext func(*Link, *loader.Loader) + Gentext func(*Link, *loader.Loader) // Generate text before addressing has been performed. Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool MachorelocSize uint32 // size of an Mach-O relocation record, must match Machoreloc1. PEreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool Xcoffreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool + // Generate additional symbols for the native symbol table just prior to + // code generation. + GenSymsLate func(*Link, *loader.Loader) + // TLSIEtoLE converts a TLS Initial Executable relocation to // a TLS Local Executable relocation. // @@ -294,6 +298,11 @@ func (ctxt *Link) CanUsePlugins() bool { return ctxt.canUsePlugins } +// NeedCodeSign reports whether we need to code-sign the output binary. +func (ctxt *Link) NeedCodeSign() bool { + return ctxt.IsDarwin() && ctxt.IsARM64() +} + var ( dynlib []string ldflag []string @@ -543,7 +552,7 @@ func (ctxt *Link) loadlib() { } // Add non-package symbols and references of externally defined symbols. - ctxt.loader.LoadNonpkgSyms(ctxt.Arch) + ctxt.loader.LoadSyms(ctxt.Arch) // Load symbols from shared libraries, after all Go object symbols are loaded. for _, lib := range ctxt.Library { @@ -831,7 +840,12 @@ func (ctxt *Link) mangleTypeSym() { ldr := ctxt.loader for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ { - if !ldr.AttrReachable(s) { + if !ldr.AttrReachable(s) && !ctxt.linkShared { + // If -linkshared, the GCProg generation code may need to reach + // out to the shared library for the type descriptor's data, even + // the type descriptor itself is not actually needed at run time + // (therefore not reachable). We still need to mangle its name, + // so it is consistent with the one stored in the shared library. continue } name := ldr.SymName(s) @@ -1249,7 +1263,9 @@ func (ctxt *Link) hostlink() { // -headerpad is incompatible with -fembed-bitcode. argv = append(argv, "-Wl,-headerpad,1144") } - if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) { + if ctxt.DynlinkingGo() && objabi.GOOS != "ios" { + // -flat_namespace is deprecated on iOS. + // It is useful for supporting plugins. We don't support plugins on iOS. argv = append(argv, "-Wl,-flat_namespace") } if !combineDwarf { @@ -1285,6 +1301,17 @@ func (ctxt *Link) hostlink() { argv = append(argv, "-Wl,-bbigtoc") } + // Enable ASLR on Windows. + addASLRargs := func(argv []string) []string { + // Enable ASLR. + argv = append(argv, "-Wl,--dynamicbase") + // enable high-entropy ASLR on 64-bit. + if ctxt.Arch.PtrSize >= 8 { + argv = append(argv, "-Wl,--high-entropy-va") + } + return argv + } + switch ctxt.BuildMode { case BuildModeExe: if ctxt.HeadType == objabi.Hdarwin { @@ -1297,15 +1324,7 @@ func (ctxt *Link) hostlink() { switch ctxt.HeadType { case objabi.Hdarwin, objabi.Haix: case objabi.Hwindows: - // Enable ASLR. - argv = append(argv, "-Wl,--dynamicbase") - // enable high-entropy ASLR on 64-bit. - if ctxt.Arch.PtrSize >= 8 { - argv = append(argv, "-Wl,--high-entropy-va") - } - // Work around binutils limitation that strips relocation table for dynamicbase. - // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011 - argv = append(argv, "-Wl,--export-all-symbols") + argv = addASLRargs(argv) default: // ELF. if ctxt.UseRelro() { @@ -1316,9 +1335,6 @@ func (ctxt *Link) hostlink() { case BuildModeCShared: if ctxt.HeadType == objabi.Hdarwin { argv = append(argv, "-dynamiclib") - if ctxt.Arch.Family != sys.AMD64 { - argv = append(argv, "-Wl,-read_only_relocs,suppress") - } } else { // ELF. argv = append(argv, "-Wl,-Bsymbolic") @@ -1326,7 +1342,11 @@ func (ctxt *Link) hostlink() { argv = append(argv, "-Wl,-z,relro") } argv = append(argv, "-shared") - if ctxt.HeadType != objabi.Hwindows { + if ctxt.HeadType == objabi.Hwindows { + if *flagAslr { + argv = addASLRargs(argv) + } + } else { // Pass -z nodelete to mark the shared library as // non-closeable: a dlclose will do nothing. argv = append(argv, "-Wl,-z,nodelete") @@ -1596,12 +1616,12 @@ func (ctxt *Link) hostlink() { if combineDwarf { dsym := filepath.Join(*flagTmpdir, "go.dwarf") - if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { + if out, err := exec.Command("xcrun", "dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil { Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out) } // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil). // They contain temporary file paths and make the build not reproducible. - if out, err := exec.Command("strip", "-S", *flagOutfile).CombinedOutput(); err != nil { + if out, err := exec.Command("xcrun", "strip", "-S", *flagOutfile).CombinedOutput(); err != nil { Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out) } // Skip combining if `dsymutil` didn't generate a file. See #11994. @@ -1627,6 +1647,12 @@ func (ctxt *Link) hostlink() { Exitf("%s: %v", os.Args[0], err) } } + if ctxt.NeedCodeSign() { + err := machoCodeSign(ctxt, *flagOutfile) + if err != nil { + Exitf("%s: code signing failed: %v", os.Args[0], err) + } + } } var createTrivialCOnce sync.Once @@ -1752,12 +1778,12 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) if magic == 0x7f454c46 { // \x7F E L F ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { - textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.flags) + textp, flags, err := loadelf.Load(ctxt.loader, ctxt.Arch, ctxt.IncVersion(), f, pkg, length, pn, ehdr.Flags) if err != nil { Errorf(nil, "%v", err) return } - ehdr.flags = flags + ehdr.Flags = flags ctxt.Textp = append(ctxt.Textp, textp...) } return ldhostobj(ldelf, ctxt.HeadType, f, pkg, length, pn, file) @@ -2254,7 +2280,7 @@ func (sc *stkChk) check(up *chain, depth int) int { var ch1 chain pcsp := obj.NewPCIter(uint32(ctxt.Arch.MinLC)) ri := 0 - for pcsp.Init(info.Pcsp()); !pcsp.Done; pcsp.Next() { + for pcsp.Init(ldr.Data(info.Pcsp())); !pcsp.Done; pcsp.Next() { // pcsp.value is in effect for [pcsp.pc, pcsp.nextpc). // Check stack size in effect for this span. @@ -2502,16 +2528,22 @@ func AddGotSym(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, if target.Arch.PtrSize == 8 { rela := ldr.MakeSymbolUpdater(syms.Rela) rela.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) - rela.AddUint64(target.Arch, ELF64_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) + rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) rela.AddUint64(target.Arch, 0) } else { rel := ldr.MakeSymbolUpdater(syms.Rel) rel.AddAddrPlus(target.Arch, got.Sym(), int64(ldr.SymGot(s))) - rel.AddUint32(target.Arch, ELF32_R_INFO(uint32(ldr.SymDynid(s)), elfRelocTyp)) + rel.AddUint32(target.Arch, elf.R_INFO32(uint32(ldr.SymDynid(s)), elfRelocTyp)) } } else if target.IsDarwin() { leg := ldr.MakeSymbolUpdater(syms.LinkEditGOT) leg.AddUint32(target.Arch, uint32(ldr.SymDynid(s))) + if target.IsPIE() && target.IsInternal() { + // Mach-O relocations are a royal pain to lay out. + // They use a compact stateful bytecode representation. + // Here we record what are needed and encode them later. + MachoAddBind(int64(ldr.SymGot(s)), s) + } } else { ldr.Errorf(s, "addgotsym: unsupported binary format") } |
