From 75ca90e309117b132bf2c95c691b55502bf2eaca Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Wed, 6 May 2020 12:33:36 -0400 Subject: [PATCH] [dev.link] cmd/link: convert asmb2 pass to new style on darwin Now we no longer do loadlibfull on darwin. While here, remove residual darwin/386 and darwin/arm code. Change-Id: I6efdcd81baeeca29d1fe91c4fab0cc8241a58e2d Reviewed-on: https://go-review.googlesource.com/c/go/+/232597 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Jeremy Faller Reviewed-by: Than McIntosh --- src/cmd/link/internal/amd64/asm.go | 19 +-- src/cmd/link/internal/arm/asm.go | 2 +- src/cmd/link/internal/arm64/asm.go | 24 ++-- src/cmd/link/internal/ld/lib.go | 18 ++- src/cmd/link/internal/ld/macho.go | 194 ++++++++++++--------------- src/cmd/link/internal/ld/main.go | 21 +-- src/cmd/link/internal/mips/asm.go | 2 +- src/cmd/link/internal/mips64/asm.go | 2 +- src/cmd/link/internal/ppc64/asm.go | 2 +- src/cmd/link/internal/riscv64/asm.go | 2 +- src/cmd/link/internal/s390x/asm.go | 2 +- src/cmd/link/internal/x86/asm.go | 2 +- 12 files changed, 148 insertions(+), 142 deletions(-) diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go index c2d54703c1..f2b76fb78b 100644 --- a/src/cmd/link/internal/amd64/asm.go +++ b/src/cmd/link/internal/amd64/asm.go @@ -458,28 +458,29 @@ func elfreloc2(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym, r loader.ExtRelo return true } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { var v uint32 rs := r.Xsym + rt := r.Type() - if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL || r.Type == objabi.R_CALL { - if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_PCREL || rt == objabi.R_GOTPCREL || rt == objabi.R_CALL { + if ldr.SymDynid(rs) < 0 { + 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)) return false } - v = uint32(rs.Dynid) + v = uint32(ldr.SymDynid(rs)) v |= 1 << 27 // external relocation } else { - v = uint32(rs.Sect.Extnum) + v = uint32(ldr.SymSect(rs).Extnum) if v == 0 { - ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) + ldr.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymSect(rs).Name, ldr.SymType(rs), ldr.SymType(rs)) return false } } - switch r.Type { + switch rt { default: return false @@ -499,7 +500,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se v |= ld.MACHO_X86_64_RELOC_GOT_LOAD << 28 } - switch r.Siz { + switch r.Siz() { default: return false diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index d33ea9d54a..e01124f0a9 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -318,7 +318,7 @@ func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.S } } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { return false } diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 54a9d9556e..d28e3efbb4 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -371,41 +371,43 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { return true } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool { var v uint32 rs := r.Xsym + rt := r.Type() + siz := r.Siz() - if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 { - if rs.Dynid < 0 { - ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type) + if ldr.SymType(rs) == sym.SHOSTOBJ || rt == objabi.R_CALLARM64 || rt == objabi.R_ADDRARM64 { + if ldr.SymDynid(rs) < 0 { + 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)) return false } - v = uint32(rs.Dynid) + v = uint32(ldr.SymDynid(rs)) v |= 1 << 27 // external relocation } else { - v = uint32(rs.Sect.Extnum) + v = uint32(ldr.SymSect(rs).Extnum) if v == 0 { - ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type) + ldr.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymSect(rs).Name, ldr.SymType(rs), ldr.SymType(rs)) return false } } - switch r.Type { + switch rt { default: return false case objabi.R_ADDR: v |= ld.MACHO_ARM64_RELOC_UNSIGNED << 28 case objabi.R_CALLARM64: if r.Xadd != 0 { - ld.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd) + ldr.Errorf(s, "ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", ldr.SymName(rs), r.Xadd) } v |= 1 << 24 // pc-relative bit v |= ld.MACHO_ARM64_RELOC_BRANCH26 << 28 case objabi.R_ADDRARM64: - r.Siz = 4 + siz = 4 // Two relocation entries: MACHO_ARM64_RELOC_PAGEOFF12 MACHO_ARM64_RELOC_PAGE21 // if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND. if r.Xadd != 0 { @@ -422,7 +424,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28 } - switch r.Siz { + switch siz { default: return false case 1: diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index a612bfadec..8fc1f737c2 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -277,7 +277,7 @@ type Arch struct { Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) Gentext func(*Link) Gentext2 func(*Link, *loader.Loader) - Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool + Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool @@ -2692,6 +2692,22 @@ func Entryvalue(ctxt *Link) int64 { return s.Value } +func Entryvalue2(ctxt *Link) int64 { + a := *flagEntrySymbol + if a[0] >= '0' && a[0] <= '9' { + return atolwhex(a) + } + s := ctxt.loader.Lookup(a, 0) + typ := ctxt.loader.SymType(s) + if typ == 0 { + return *FlagTextAddr + } + if ctxt.HeadType != objabi.Haix && typ != sym.STEXT { + ctxt.Errorf(s, "entry not text") + } + return ctxt.loader.SymValue(s) +} + func (ctxt *Link) callgraph() { if !*FlagC { return diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 4dc7f819eb..badb388b8f 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -501,9 +501,8 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) var msect *MachoSect if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 || - ctxt.Arch.Family == sys.ARM || (ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe)) { - // Darwin external linker on arm and arm64, and on amd64 in c-shared/c-archive buildmode + // Darwin external linker on arm64, and on amd64 in c-shared/c-archive buildmode // complains about absolute relocs in __TEXT, so if the section is not // executable, put it in __DATA segment. msect = newMachoSect(mseg, buf, "__DATA") @@ -551,7 +550,7 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) if sect.Name == ".got" { msect.name = "__nl_symbol_ptr" msect.flag = S_NON_LAZY_SYMBOL_POINTERS - msect.res1 = uint32(ctxt.Syms.Lookup(".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */ + msect.res1 = uint32(ctxt.loader.SymSize(ctxt.ArchSyms.LinkEditPLT2) / 4) /* offset into indirect symbol table */ } if sect.Name == ".init_array" { @@ -584,10 +583,6 @@ func Asmbmacho(ctxt *Link) { default: Exitf("unknown macho architecture: %v", ctxt.Arch.Family) - case sys.ARM: - mh.cpu = MACHO_CPU_ARM - mh.subcpu = MACHO_SUBCPU_ARMV7 - case sys.AMD64: mh.cpu = MACHO_CPU_AMD64 mh.subcpu = MACHO_SUBCPU_X86 @@ -595,10 +590,6 @@ func Asmbmacho(ctxt *Link) { case sys.ARM64: mh.cpu = MACHO_CPU_ARM64 mh.subcpu = MACHO_SUBCPU_ARM64_ALL - - case sys.I386: - mh.cpu = MACHO_CPU_386 - mh.subcpu = MACHO_SUBCPU_X86 } var ms *MachoSeg @@ -669,45 +660,35 @@ func Asmbmacho(ctxt *Link) { default: Exitf("unknown macho architecture: %v", ctxt.Arch.Family) - case sys.ARM: - ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 17+2) - ml.data[0] = 1 /* thread type */ - ml.data[1] = 17 /* word count */ - ml.data[2+15] = uint32(Entryvalue(ctxt)) /* start pc */ - case sys.AMD64: ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 42+2) - ml.data[0] = 4 /* thread type */ - ml.data[1] = 42 /* word count */ - ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */ - ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32) + ml.data[0] = 4 /* thread type */ + ml.data[1] = 42 /* word count */ + ml.data[2+32] = uint32(Entryvalue2(ctxt)) /* start pc */ + ml.data[2+32+1] = uint32(Entryvalue2(ctxt) >> 32) case sys.ARM64: ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 68+2) - ml.data[0] = 6 /* thread type */ - ml.data[1] = 68 /* word count */ - ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */ - ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32) - - case sys.I386: - ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 16+2) - ml.data[0] = 1 /* thread type */ - ml.data[1] = 16 /* word count */ - ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */ + ml.data[0] = 6 /* thread type */ + ml.data[1] = 68 /* word count */ + ml.data[2+64] = uint32(Entryvalue2(ctxt)) /* start pc */ + ml.data[2+64+1] = uint32(Entryvalue2(ctxt) >> 32) } } if !*FlagD { + ldr := ctxt.loader + // must match domacholink below - s1 := ctxt.Syms.Lookup(".machosymtab", 0) - s2 := ctxt.Syms.Lookup(".linkedit.plt", 0) - s3 := ctxt.Syms.Lookup(".linkedit.got", 0) - s4 := ctxt.Syms.Lookup(".machosymstr", 0) + s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0)) + s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT2) + s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT2) + s4 := ldr.SymSize(ldr.Lookup(".machosymstr", 0)) if ctxt.LinkMode != LinkExternal { ms := newMachoSeg("__LINKEDIT", 0) ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound))) - ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size) + ms.vsize = uint64(s1) + uint64(s2) + uint64(s3) + uint64(s4) ms.fileoffset = uint64(linkoff) ms.filesize = ms.vsize ms.prot1 = 7 @@ -715,10 +696,10 @@ func Asmbmacho(ctxt *Link) { } ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4) - ml.data[0] = uint32(linkoff) /* symoff */ - ml.data[1] = uint32(nsortsym) /* nsyms */ - ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */ - ml.data[3] = uint32(s4.Size) /* strsize */ + ml.data[0] = uint32(linkoff) /* symoff */ + ml.data[1] = uint32(nsortsym) /* nsyms */ + ml.data[2] = uint32(linkoff + s1 + s2 + s3) /* stroff */ + ml.data[3] = uint32(s4) /* strsize */ machodysymtab(ctxt) @@ -870,38 +851,39 @@ func machosymorder(ctxt *Link) { // // When dynamically linking, all non-local variables and plugin-exported // symbols need to be exported. -func machoShouldExport(ctxt *Link, s *sym.Symbol) bool { - if !ctxt.DynlinkingGo() || s.Attr.Local() { +func machoShouldExport(ctxt *Link, ldr *loader.Loader, s loader.Sym) bool { + if !ctxt.DynlinkingGo() || ldr.AttrLocal(s) { return false } - if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname(), objabi.PathToPrefix(*flagPluginPath)) { + if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(ldr.SymExtname(s), objabi.PathToPrefix(*flagPluginPath)) { return true } - if strings.HasPrefix(s.Name, "go.itab.") { + name := ldr.RawSymName(s) + if strings.HasPrefix(name, "go.itab.") { return true } - if strings.HasPrefix(s.Name, "type.") && !strings.HasPrefix(s.Name, "type..") { + if strings.HasPrefix(name, "type.") && !strings.HasPrefix(name, "type..") { // reduce runtime typemap pressure, but do not // export alg functions (type..*), as these // appear in pclntable. return true } - if strings.HasPrefix(s.Name, "go.link.pkghash") { + if strings.HasPrefix(name, "go.link.pkghash") { return true } - return s.Type >= sym.SFirstWritable // only writable sections + return ldr.SymType(s) >= sym.SFirstWritable // only writable sections } func machosymtab(ctxt *Link) { - symtab := ctxt.Syms.Lookup(".machosymtab", 0) - symstr := ctxt.Syms.Lookup(".machosymstr", 0) + ldr := ctxt.loader + symtab := ldr.CreateSymForUpdate(".machosymtab", 0) + symstr := ldr.CreateSymForUpdate(".machosymstr", 0) - for i := 0; i < nsortsym; i++ { - s := ctxt.loader.Syms[sortsym[i]] - symtab.AddUint32(ctxt.Arch, uint32(symstr.Size)) + for _, s := range sortsym[:nsortsym] { + symtab.AddUint32(ctxt.Arch, uint32(symstr.Size())) - export := machoShouldExport(ctxt, s) - isGoSymbol := strings.Contains(s.Extname(), ".") + export := machoShouldExport(ctxt, ldr, s) + isGoSymbol := strings.Contains(ldr.SymExtname(s), ".") // In normal buildmodes, only add _ to C symbols, as // Go symbols have dot in the name. @@ -910,37 +892,37 @@ func machosymtab(ctxt *Link) { // symbols like crosscall2 are in pclntab and end up // pointing at the host binary, breaking unwinding. // See Issue #18190. - cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s.Name)) + cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(ldr.SymName(s))) if cexport || export || isGoSymbol { symstr.AddUint8('_') } // replace "·" as ".", because DTrace cannot handle it. - Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1)) + symstr.Addstring(strings.Replace(ldr.SymExtname(s), "·", ".", -1)) - if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT { + if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT { symtab.AddUint8(0x01) // type N_EXT, external symbol symtab.AddUint8(0) // no section symtab.AddUint16(ctxt.Arch, 0) // desc symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value } else { - if s.Attr.CgoExport() || export { + if ldr.AttrCgoExport(s) || export { symtab.AddUint8(0x0f) } else { symtab.AddUint8(0x0e) } o := s - for o.Outer != nil { - o = o.Outer + if outer := ldr.OuterSym(o); outer != 0 { + o = outer } - if o.Sect == nil { - Errorf(s, "missing section for symbol") + if ldr.SymSect(o) == nil { + ldr.Errorf(s, "missing section for symbol") symtab.AddUint8(0) } else { - symtab.AddUint8(uint8(o.Sect.Extnum)) + symtab.AddUint8(uint8(ldr.SymSect(o).Extnum)) } symtab.AddUint16(ctxt.Arch, 0) // desc - symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize) + symtab.AddUintXX(ctxt.Arch, uint64(ldr.SymAddr(s)), ctxt.Arch.PtrSize) } } } @@ -967,13 +949,14 @@ func machodysymtab(ctxt *Link) { ml.data[10] = 0 /* extrefsymoff */ ml.data[11] = 0 /* nextrefsyms */ - // must match domacholink below - s1 := ctxt.Syms.Lookup(".machosymtab", 0) + ldr := ctxt.loader - s2 := ctxt.Syms.Lookup(".linkedit.plt", 0) - s3 := ctxt.Syms.Lookup(".linkedit.got", 0) - ml.data[12] = uint32(linkoff + s1.Size) /* indirectsymoff */ - ml.data[13] = uint32((s2.Size + s3.Size) / 4) /* nindirectsyms */ + // must match domacholink below + s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0)) + s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT2) + s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT2) + ml.data[12] = uint32(linkoff + s1) /* indirectsymoff */ + ml.data[13] = uint32((s2 + s3) / 4) /* nindirectsyms */ ml.data[14] = 0 /* extreloff */ ml.data[15] = 0 /* nextrel */ @@ -984,12 +967,13 @@ func machodysymtab(ctxt *Link) { func Domacholink(ctxt *Link) int64 { machosymtab(ctxt) - // write data that will be linkedit section - s1 := ctxt.Syms.Lookup(".machosymtab", 0) + ldr := ctxt.loader - s2 := ctxt.Syms.Lookup(".linkedit.plt", 0) - s3 := ctxt.Syms.Lookup(".linkedit.got", 0) - s4 := ctxt.Syms.Lookup(".machosymstr", 0) + // write data that will be linkedit section + s1 := ldr.Lookup(".machosymtab", 0) + s2 := ctxt.ArchSyms.LinkEditPLT2 + s3 := ctxt.ArchSyms.LinkEditGOT2 + s4 := ldr.Lookup(".machosymstr", 0) // Force the linkedit section to end on a 16-byte // boundary. This allows pure (non-cgo) Go binaries @@ -1008,26 +992,27 @@ func Domacholink(ctxt *Link) int64 { // boundary, codesign_allocate will not need to apply // any alignment padding itself, working around the // issue. - for s4.Size%16 != 0 { - s4.AddUint8(0) + s4b := ldr.MakeSymbolUpdater(s4) + for s4b.Size()%16 != 0 { + s4b.AddUint8(0) } - size := int(s1.Size + s2.Size + s3.Size + s4.Size) + size := int(ldr.SymSize(s1) + ldr.SymSize(s2) + ldr.SymSize(s3) + ldr.SymSize(s4)) if size > 0 { linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound)) ctxt.Out.SeekSet(linkoff) - ctxt.Out.Write(s1.P[:s1.Size]) - ctxt.Out.Write(s2.P[:s2.Size]) - ctxt.Out.Write(s3.P[:s3.Size]) - ctxt.Out.Write(s4.P[:s4.Size]) + ctxt.Out.Write(ldr.Data(s1)) + ctxt.Out.Write(ldr.Data(s2)) + ctxt.Out.Write(ldr.Data(s3)) + ctxt.Out.Write(ldr.Data(s4)) } return Rnd(int64(size), int64(*FlagRound)) } -func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { +func machorelocsect(ctxt *Link, ldr *loader.Loader, sect *sym.Section, syms []loader.Sym) { // If main section has no bits, nothing to relocate. if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { return @@ -1035,10 +1020,10 @@ func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { sect.Reloff = uint64(ctxt.Out.Offset()) for i, s := range syms { - if !s.Attr.Reachable() { + if !ldr.AttrReachable(s) { continue } - if uint64(s.Value) >= sect.Vaddr { + if uint64(ldr.SymValue(s)) >= sect.Vaddr { syms = syms[i:] break } @@ -1046,26 +1031,24 @@ func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { eaddr := int32(sect.Vaddr + sect.Length) for _, s := range syms { - if !s.Attr.Reachable() { + if !ldr.AttrReachable(s) { continue } - if s.Value >= int64(eaddr) { + if ldr.SymValue(s) >= int64(eaddr) { break } - for ri := range s.R { - r := &s.R[ri] - if r.Done { + relocs := ldr.ExtRelocs(s) + for ri := 0; ri < relocs.Count(); ri++ { + r := relocs.At(ri) + if r.Xsym == 0 { + ldr.Errorf(s, "missing xsym in relocation") continue } - if r.Xsym == nil { - Errorf(s, "missing xsym in relocation") - continue + if !ldr.AttrReachable(r.Xsym) { + ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(r.Xsym)) } - if !r.Xsym.Attr.Reachable() { - Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name) - } - if !thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) { - Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) + if !thearch.Machoreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-sect.Vaddr)) { + ldr.Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), r.Siz(), ldr.SymName(r.Sym())) } } } @@ -1078,21 +1061,22 @@ func Machoemitreloc(ctxt *Link) { ctxt.Out.Write8(0) } - machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp) + ldr := ctxt.loader + machorelocsect(ctxt, ldr, Segtext.Sections[0], ctxt.Textp2) for _, sect := range Segtext.Sections[1:] { - machorelocsect(ctxt, sect, ctxt.datap) + machorelocsect(ctxt, ldr, sect, ctxt.datap2) } for _, sect := range Segdata.Sections { - machorelocsect(ctxt, sect, ctxt.datap) + machorelocsect(ctxt, ldr, sect, ctxt.datap2) } for i := 0; i < len(Segdwarf.Sections); i++ { sect := Segdwarf.Sections[i] - si := dwarfp[i] - if si.secSym() != sect.Sym || - si.secSym().Sect != sect { + si := dwarfp2[i] + if si.secSym() != loader.Sym(sect.Sym2) || + ctxt.loader.SymSect(si.secSym()) != sect { panic("inconsistency between dwarfp and Segdwarf") } - machorelocsect(ctxt, sect, si.syms) + machorelocsect(ctxt, ldr, sect, si.syms) } } diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index 7d3f25540d..838f92af9e 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -319,18 +319,21 @@ func Main(arch *sys.Arch, theArch Arch) { ctxt.loader.InitOutData() thearch.Asmb(ctxt, ctxt.loader) newreloc := ctxt.Is386() || ctxt.IsAMD64() || ctxt.IsARM() || ctxt.IsARM64() || ctxt.IsMIPS() || ctxt.IsMIPS64() || ctxt.IsRISCV64() || ctxt.IsS390X() || ctxt.IsWasm() + newasmb2 := ctxt.IsDarwin() if newreloc { bench.Start("reloc") ctxt.reloc() - bench.Start("loadlibfull") - // We don't need relocations at this point. - // An exception is internal linking on Windows, see pe.go:addPEBaseRelocSym - // Wasm is another exception, where it applies text relocations in Asmb2. - needReloc := (ctxt.IsWindows() && ctxt.IsInternal()) || ctxt.IsWasm() - // On AMD64 ELF, we directly use the loader's ExtRelocs, so we don't - // need conversion. Otherwise we do. - needExtReloc := ctxt.IsExternal() && !(ctxt.IsAMD64() && ctxt.IsELF) - ctxt.loadlibfull(symGroupType, needReloc, needExtReloc) // XXX do it here for now + if !newasmb2 { + bench.Start("loadlibfull") + // We don't need relocations at this point. + // An exception is internal linking on Windows, see pe.go:addPEBaseRelocSym + // Wasm is another exception, where it applies text relocations in Asmb2. + needReloc := (ctxt.IsWindows() && ctxt.IsInternal()) || ctxt.IsWasm() + // On AMD64 ELF, we directly use the loader's ExtRelocs, so we don't + // need conversion. Otherwise we do. + needExtReloc := ctxt.IsExternal() && !(ctxt.IsAMD64() && ctxt.IsELF) + ctxt.loadlibfull(symGroupType, needReloc, needExtReloc) // XXX do it here for now + } } else { bench.Start("loadlibfull") ctxt.loadlibfull(symGroupType, true, false) // XXX do it here for now diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go index ae37d3cdaf..65f32ad940 100644 --- a/src/cmd/link/internal/mips/asm.go +++ b/src/cmd/link/internal/mips/asm.go @@ -80,7 +80,7 @@ func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loade return } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { return false } diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go index 9024ef0060..c23360ea3b 100644 --- a/src/cmd/link/internal/mips64/asm.go +++ b/src/cmd/link/internal/mips64/asm.go @@ -97,7 +97,7 @@ func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loade return } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { return false } diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index dae1a07590..ab923c324e 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -528,7 +528,7 @@ func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.S } } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { return false } diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go index e259ef40f2..88c6d8790e 100644 --- a/src/cmd/link/internal/riscv64/asm.go +++ b/src/cmd/link/internal/riscv64/asm.go @@ -37,7 +37,7 @@ func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loade log.Fatalf("elfsetuplt") } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { log.Fatalf("machoreloc1 not implemented") return false } diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index 91455cc6c2..e1e7f0b249 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -363,7 +363,7 @@ func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.S } } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { return false } diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index 21ea5780cb..5297d15e39 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -398,7 +398,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { return true } -func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool { +func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool { return false }