]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert asmb2 pass to new style on windows
authorCherry Zhang <cherryyz@google.com>
Fri, 8 May 2020 02:22:54 +0000 (22:22 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 8 May 2020 19:15:21 +0000 (19:15 +0000)
Now we no longer do loadlibfull on windows.

Change-Id: Ideb015597c28f27538bd50829e089ea728017162
Reviewed-on: https://go-review.googlesource.com/c/go/+/232979
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/x86/asm.go

index f2b76fb78b4059e559c2bd0eae58c79dc74c7b75..30fab9de1c4f6d1a75f74f7648c3561775571e96 100644 (file)
@@ -522,20 +522,21 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sy
        return true
 }
 
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func pereloc1(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.Dynid < 0 {
-               ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+       if ldr.SymDynid(rs) < 0 {
+               ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
                return false
        }
 
        out.Write32(uint32(sectoff))
-       out.Write32(uint32(rs.Dynid))
+       out.Write32(uint32(ldr.SymDynid(rs)))
 
-       switch r.Type {
+       switch rt {
        default:
                return false
 
@@ -543,7 +544,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
                v = ld.IMAGE_REL_AMD64_SECREL
 
        case objabi.R_ADDR:
-               if r.Siz == 8 {
+               if r.Siz() == 8 {
                        v = ld.IMAGE_REL_AMD64_ADDR64
                } else {
                        v = ld.IMAGE_REL_AMD64_ADDR32
index e01124f0a9fcce5651cc88d445ebb546585127eb..e910d3785fdb2875d37b19e699e06d769c88d6d2 100644 (file)
@@ -322,19 +322,20 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
        return false
 }
 
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
        rs := r.Xsym
+       rt := r.Type()
 
-       if rs.Dynid < 0 {
-               ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+       if ldr.SymDynid(rs) < 0 {
+               ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
                return false
        }
 
        out.Write32(uint32(sectoff))
-       out.Write32(uint32(rs.Dynid))
+       out.Write32(uint32(ldr.SymDynid(rs)))
 
        var v uint32
-       switch r.Type {
+       switch rt {
        default:
                // unsupported relocation type
                return false
index 8fc1f737c2f435b9edf60b7022b7474d9a042e42..3c9914a21924a4356732ae4fec9d99a5b0b03469 100644 (file)
@@ -278,7 +278,7 @@ type Arch struct {
        Gentext     func(*Link)
        Gentext2    func(*Link, *loader.Loader)
        Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
-       PEreloc1    func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
+       PEreloc1    func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
        Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
 
        // TLSIEtoLE converts a TLS Initial Executable relocation to
index 75d6bbf05de429e48098619e79c0c1d4e7dc82b4..176c3b00bffed1816af74cb97e9996c5dac85cac 100644 (file)
@@ -319,16 +319,15 @@ 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() || ctxt.IsPPC64()
-       newasmb2 := ctxt.IsDarwin()
+       newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows()
        if newreloc {
                bench.Start("reloc")
                ctxt.reloc()
                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()
+                       // Wasm is an exception, where it applies text relocations in Asmb2.
+                       needReloc := 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)
index 362d2fd0a5b9a8f9617d74d2f05455585e5262cb..5edba67a59b88bc3fcda3bd6d5a080662d3a5d5f 100644 (file)
@@ -472,8 +472,8 @@ func (f *peFile) addInitArray(ctxt *Link) *peSection {
        ctxt.Out.SeekSet(int64(sect.pointerToRawData))
        sect.checkOffset(ctxt.Out.Offset())
 
-       init_entry := ctxt.Syms.Lookup(*flagEntrySymbol, 0)
-       addr := uint64(init_entry.Value) - init_entry.Sect.Vaddr
+       init_entry := ctxt.loader.Lookup(*flagEntrySymbol, 0)
+       addr := uint64(ctxt.loader.SymValue(init_entry)) - ctxt.loader.SymSect(init_entry).Vaddr
        switch objabi.GOARCH {
        case "386", "arm":
                ctxt.Out.Write32(uint32(addr))
@@ -489,62 +489,62 @@ func (f *peFile) emitRelocations(ctxt *Link) {
                ctxt.Out.Write8(0)
        }
 
+       ldr := ctxt.loader
+
        // relocsect relocates symbols from first in section sect, and returns
        // the total number of relocations emitted.
-       relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) int {
+       relocsect := func(sect *sym.Section, syms []loader.Sym, base uint64) int {
                // If main section has no bits, nothing to relocate.
                if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
                        return 0
                }
-               relocs := 0
+               nrelocs := 0
                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
                        }
                }
                eaddr := int32(sect.Vaddr + sect.Length)
-               for _, sym := range syms {
-                       if !sym.Attr.Reachable() {
+               for _, s := range syms {
+                       if !ldr.AttrReachable(s) {
                                continue
                        }
-                       if sym.Value >= int64(eaddr) {
+                       if ldr.SymValue(s) >= int64(eaddr) {
                                break
                        }
-                       for ri := range sym.R {
-                               r := &sym.R[ri]
-                               if r.Done {
+                       relocs := ldr.ExtRelocs(s)
+                       for ri := 0; ri < relocs.Count(); ri++ {
+                               r := relocs.At(ri)
+                               if r.Xsym == 0 {
+                                       ctxt.Errorf(s, "missing xsym in relocation")
                                        continue
                                }
-                               if r.Xsym == nil {
-                                       Errorf(sym, "missing xsym in relocation")
-                                       continue
+                               if ldr.SymDynid(r.Xsym) < 0 {
+                                       ctxt.Errorf(s, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(r.Xsym), ldr.SymType(r.Sym()))
                                }
-                               if r.Xsym.Dynid < 0 {
-                                       Errorf(sym, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
+                               if !thearch.PEreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
+                                       ctxt.Errorf(s, "unsupported obj reloc %d/%d to %s", r.Type(), r.Siz(), ldr.SymName(r.Sym()))
                                }
-                               if !thearch.PEreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
-                                       Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
-                               }
-                               relocs++
+                               nrelocs++
                        }
                }
                sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
-               return relocs
+               return nrelocs
        }
 
        sects := []struct {
                peSect *peSection
                seg    *sym.Segment
-               syms   []*sym.Symbol
+               syms   []loader.Sym
        }{
-               {f.textSect, &Segtext, ctxt.Textp},
-               {f.rdataSect, &Segrodata, ctxt.datap},
-               {f.dataSect, &Segdata, ctxt.datap},
+               {f.textSect, &Segtext, ctxt.Textp2},
+               {f.rdataSect, &Segrodata, ctxt.datap2},
+               {f.dataSect, &Segdata, ctxt.datap2},
        }
        for _, s := range sects {
                s.peSect.emitRelocations(ctxt.Out, func() int {
@@ -559,9 +559,9 @@ func (f *peFile) emitRelocations(ctxt *Link) {
 dwarfLoop:
        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) ||
+                       ldr.SymSect(si.secSym()) != sect {
                        panic("inconsistency between dwarfp and Segdwarf")
                }
                for _, pesect := range f.sections {
@@ -576,12 +576,12 @@ dwarfLoop:
        }
 
        f.ctorsSect.emitRelocations(ctxt.Out, func() int {
-               dottext := ctxt.Syms.Lookup(".text", 0)
+               dottext := ldr.Lookup(".text", 0)
                ctxt.Out.Write32(0)
-               ctxt.Out.Write32(uint32(dottext.Dynid))
+               ctxt.Out.Write32(uint32(ldr.SymDynid(dottext)))
                switch objabi.GOARCH {
                default:
-                       Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
+                       ctxt.Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
                case "386":
                        ctxt.Out.Write16(IMAGE_REL_I386_DIR32)
                case "amd64":
@@ -595,12 +595,12 @@ dwarfLoop:
 
 // writeSymbol appends symbol s to file f symbol table.
 // It also sets s.Dynid to written symbol number.
-func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx int, typ uint16, class uint8) {
-       if len(s.Name) > 8 {
+func (f *peFile) writeSymbol(out *OutBuf, ldr *loader.Loader, s loader.Sym, name string, value int64, sectidx int, typ uint16, class uint8) {
+       if len(name) > 8 {
                out.Write32(0)
-               out.Write32(uint32(f.stringTable.add(s.Name)))
+               out.Write32(uint32(f.stringTable.add(name)))
        } else {
-               out.WriteStringN(s.Name, 8)
+               out.WriteStringN(name, 8)
        }
        out.Write32(uint32(value))
        out.Write16(uint16(sectidx))
@@ -608,31 +608,32 @@ func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx in
        out.Write8(class)
        out.Write8(0) // no aux entries
 
-       s.Dynid = int32(f.symbolCount)
+       ldr.SetSymDynid(s, int32(f.symbolCount))
 
        f.symbolCount++
 }
 
 // mapToPESection searches peFile f for s symbol's location.
 // It returns PE section index, and offset within that section.
-func (f *peFile) mapToPESection(s *sym.Symbol, linkmode LinkMode) (pesectidx int, offset int64, err error) {
-       if s.Sect == nil {
-               return 0, 0, fmt.Errorf("could not map %s symbol with no section", s.Name)
+func (f *peFile) mapToPESection(ldr *loader.Loader, s loader.Sym, linkmode LinkMode) (pesectidx int, offset int64, err error) {
+       sect := ldr.SymSect(s)
+       if sect == nil {
+               return 0, 0, fmt.Errorf("could not map %s symbol with no section", ldr.SymName(s))
        }
-       if s.Sect.Seg == &Segtext {
-               return f.textSect.index, int64(uint64(s.Value) - Segtext.Vaddr), nil
+       if sect.Seg == &Segtext {
+               return f.textSect.index, int64(uint64(ldr.SymValue(s)) - Segtext.Vaddr), nil
        }
-       if s.Sect.Seg == &Segrodata {
-               return f.rdataSect.index, int64(uint64(s.Value) - Segrodata.Vaddr), nil
+       if sect.Seg == &Segrodata {
+               return f.rdataSect.index, int64(uint64(ldr.SymValue(s)) - Segrodata.Vaddr), nil
        }
-       if s.Sect.Seg != &Segdata {
-               return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .rdata or .data section", s.Name)
+       if sect.Seg != &Segdata {
+               return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .rdata or .data section", ldr.SymName(s))
        }
-       v := uint64(s.Value) - Segdata.Vaddr
+       v := uint64(ldr.SymValue(s)) - Segdata.Vaddr
        if linkmode != LinkExternal {
                return f.dataSect.index, int64(v), nil
        }
-       if s.Type == sym.SDATA {
+       if ldr.SymType(s) == sym.SDATA {
                return f.dataSect.index, int64(v), nil
        }
        // Note: although address of runtime.edata (type sym.SDATA) is at the start of .bss section
@@ -645,60 +646,100 @@ func (f *peFile) mapToPESection(s *sym.Symbol, linkmode LinkMode) (pesectidx int
 
 // writeSymbols writes all COFF symbol table records.
 func (f *peFile) writeSymbols(ctxt *Link) {
-
-       put := func(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64) {
-               if s == nil {
-                       return
-               }
-               if s.Sect == nil && type_ != UndefinedSym {
-                       return
-               }
-               switch type_ {
-               default:
+       ldr := ctxt.loader
+       addsym := func(s loader.Sym) {
+               t := ldr.SymType(s)
+               if ldr.SymSect(s) == nil && t != sym.SDYNIMPORT && t != sym.SHOSTOBJ && t != sym.SUNDEFEXT {
                        return
-               case DataSym, BSSSym, TextSym, UndefinedSym:
                }
 
+               name := ldr.SymName(s)
+
                // Only windows/386 requires underscore prefix on external symbols.
-               if ctxt.Arch.Family == sys.I386 &&
-                       ctxt.LinkMode == LinkExternal &&
-                       (s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT || s.Attr.CgoExport()) {
-                       s.Name = "_" + s.Name
+               if ctxt.Is386() && ctxt.IsExternal() &&
+                       (t == sym.SHOSTOBJ || t == sym.SUNDEFEXT || ldr.AttrCgoExport(s)) {
+                       name = "_" + name
                }
 
-               var typ uint16
-               if ctxt.LinkMode == LinkExternal {
-                       typ = IMAGE_SYM_TYPE_NULL
+               var peSymType uint16
+               if ctxt.IsExternal() {
+                       peSymType = IMAGE_SYM_TYPE_NULL
                } else {
                        // TODO: fix IMAGE_SYM_DTYPE_ARRAY value and use following expression, instead of 0x0308
-                       typ = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
-                       typ = 0x0308 // "array of structs"
+                       // peSymType = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
+                       peSymType = 0x0308 // "array of structs"
                }
-               sect, value, err := f.mapToPESection(s, ctxt.LinkMode)
+               sect, value, err := f.mapToPESection(ldr, s, ctxt.LinkMode)
                if err != nil {
-                       if type_ == UndefinedSym {
-                               typ = IMAGE_SYM_DTYPE_FUNCTION
+                       if t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
+                               peSymType = IMAGE_SYM_DTYPE_FUNCTION
                        } else {
-                               Errorf(s, "addpesym: %v", err)
+                               ctxt.Errorf(s, "addpesym: %v", err)
                        }
                }
                class := IMAGE_SYM_CLASS_EXTERNAL
-               if s.IsFileLocal() || s.Attr.VisibilityHidden() || s.Attr.Local() {
+               if ldr.IsFileLocal(s) || ldr.AttrVisibilityHidden(s) || ldr.AttrLocal(s) {
                        class = IMAGE_SYM_CLASS_STATIC
                }
-               f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
+               f.writeSymbol(ctxt.Out, ldr, s, name, value, sect, peSymType, uint8(class))
        }
 
        if ctxt.LinkMode == LinkExternal {
                // Include section symbols as external, because
                // .ctors and .debug_* section relocations refer to it.
                for _, pesect := range f.sections {
-                       sym := ctxt.Syms.Lookup(pesect.name, 0)
-                       f.writeSymbol(ctxt.Out, sym, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
+                       s := ldr.LookupOrCreateSym(pesect.name, 0)
+                       f.writeSymbol(ctxt.Out, ldr, s, pesect.name, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
+               }
+       }
+
+       // Add special runtime.text and runtime.etext symbols.
+       s := ldr.Lookup("runtime.text", 0)
+       if ldr.SymType(s) == sym.STEXT {
+               addsym(s)
+       }
+       s = ldr.Lookup("runtime.etext", 0)
+       if ldr.SymType(s) == sym.STEXT {
+               addsym(s)
+       }
+
+       // Add text symbols.
+       for _, s := range ctxt.Textp2 {
+               addsym(s)
+       }
+
+       shouldBeInSymbolTable := func(s loader.Sym) bool {
+               if ldr.AttrNotInSymbolTable(s) {
+                       return false
                }
+               name := ldr.RawSymName(s) // TODO: try not to read the name
+               if name == "" || name[0] == '.' {
+                       return false
+               }
+               return true
        }
 
-       genasmsym(ctxt, put)
+       // Add data symbols and external references.
+       for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+               if !ldr.AttrReachable(s) {
+                       continue
+               }
+               t := ldr.SymType(s)
+               if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata
+                       if t == sym.STLSBSS {
+                               continue
+                       }
+                       if !shouldBeInSymbolTable(s) {
+                               continue
+                       }
+                       addsym(s)
+               }
+
+               switch t {
+               case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT, sym.SCONST:
+                       addsym(s)
+               }
+       }
 }
 
 // writeSymbolTableAndStringTable writes out symbol and string tables for peFile f.
@@ -800,8 +841,8 @@ func (f *peFile) writeOptionalHeader(ctxt *Link) {
        oh64.SizeOfUninitializedData = 0
        oh.SizeOfUninitializedData = 0
        if ctxt.LinkMode != LinkExternal {
-               oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
-               oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
+               oh64.AddressOfEntryPoint = uint32(Entryvalue2(ctxt) - PEBASE)
+               oh.AddressOfEntryPoint = uint32(Entryvalue2(ctxt) - PEBASE)
        }
        oh64.BaseOfCode = f.textSect.virtualAddress
        oh.BaseOfCode = f.textSect.virtualAddress
@@ -1109,7 +1150,7 @@ func peimporteddlls() []string {
 func addimports(ctxt *Link, datsect *peSection) {
        ldr := ctxt.loader
        startoff := ctxt.Out.Offset()
-       dynamic := ctxt.Syms.Lookup(".windynamic", 0)
+       dynamic := ldr.LookupOrCreateSym(".windynamic", 0)
 
        // skip import descriptor table (will write it later)
        n := uint64(0)
@@ -1130,7 +1171,7 @@ func addimports(ctxt *Link, datsect *peSection) {
                for m := d.ms; m != nil; m = m.next {
                        m.off = uint64(pefile.nextSectOffset) + uint64(ctxt.Out.Offset()) - uint64(startoff)
                        ctxt.Out.Write16(0) // hint
-                       strput(ctxt.Out, ldr.Syms[m.s].Extname())
+                       strput(ctxt.Out, ldr.SymExtname(m.s))
                }
        }
 
@@ -1165,7 +1206,7 @@ func addimports(ctxt *Link, datsect *peSection) {
        endoff := ctxt.Out.Offset()
 
        // write FirstThunks (allocated in .data section)
-       ftbase := uint64(dynamic.Value) - uint64(datsect.virtualAddress) - PEBASE
+       ftbase := uint64(ldr.SymValue(dynamic)) - uint64(datsect.virtualAddress) - PEBASE
 
        ctxt.Out.SeekSet(int64(uint64(datsect.pointerToRawData) + ftbase))
        for d := dr; d != nil; d = d.next {
@@ -1205,8 +1246,8 @@ func addimports(ctxt *Link, datsect *peSection) {
        // update data directory
        pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect.virtualAddress
        pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect.virtualSize
-       pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(dynamic.Value - PEBASE)
-       pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(dynamic.Size)
+       pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(ldr.SymValue(dynamic) - PEBASE)
+       pefile.dataDirectory[pe.IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(ldr.SymSize(dynamic))
 
        out.SeekSet(endoff)
 }
@@ -1235,7 +1276,7 @@ func addexports(ctxt *Link) {
        nexport := len(dexport)
        size := binary.Size(&e) + 10*nexport + len(*flagOutfile) + 1
        for _, s := range dexport {
-               size += len(ldr.Syms[s].Extname()) + 1
+               size += len(ldr.SymExtname(s)) + 1
        }
 
        if nexport == 0 {
@@ -1271,7 +1312,7 @@ func addexports(ctxt *Link) {
 
        // put EXPORT Address Table
        for _, s := range dexport {
-               out.Write32(uint32(ldr.Syms[s].Value - PEBASE))
+               out.Write32(uint32(ldr.SymValue(s) - PEBASE))
        }
 
        // put EXPORT Name Pointer Table
@@ -1279,7 +1320,7 @@ func addexports(ctxt *Link) {
 
        for _, s := range dexport {
                out.Write32(uint32(v))
-               v += len(ldr.Syms[s].Extname()) + 1
+               v += len(ldr.SymExtname(s)) + 1
        }
 
        // put EXPORT Ordinal Table
@@ -1291,8 +1332,8 @@ func addexports(ctxt *Link) {
        out.WriteStringN(*flagOutfile, len(*flagOutfile)+1)
 
        for _, s := range dexport {
-               ss := ldr.Syms[s]
-               out.WriteStringN(ss.Extname(), len(ss.Extname())+1)
+               name := ldr.SymExtname(s)
+               out.WriteStringN(name, len(name)+1)
        }
        sect.pad(out, uint32(size))
 }
@@ -1300,8 +1341,6 @@ func addexports(ctxt *Link) {
 // peBaseRelocEntry represents a single relocation entry.
 type peBaseRelocEntry struct {
        typeOff uint16
-       rel     *sym.Reloc
-       sym     *sym.Symbol // For debug
 }
 
 // peBaseRelocBlock represents a Base Relocation Block. A block
@@ -1338,13 +1377,13 @@ func (rt *peBaseRelocTable) init(ctxt *Link) {
        rt.blocks = make(map[uint32]peBaseRelocBlock)
 }
 
-func (rt *peBaseRelocTable) addentry(ctxt *Link, s *sym.Symbol, r *sym.Reloc) {
+func (rt *peBaseRelocTable) addentry(ldr *loader.Loader, s loader.Sym, r *loader.Reloc2) {
        // pageSize is the size in bytes of a page
        // described by a base relocation block.
        const pageSize = 0x1000
        const pageMask = pageSize - 1
 
-       addr := s.Value + int64(r.Off) - int64(PEBASE)
+       addr := ldr.SymValue(s) + int64(r.Off()) - int64(PEBASE)
        page := uint32(addr &^ pageMask)
        off := uint32(addr & pageMask)
 
@@ -1355,12 +1394,10 @@ func (rt *peBaseRelocTable) addentry(ctxt *Link, s *sym.Symbol, r *sym.Reloc) {
 
        e := peBaseRelocEntry{
                typeOff: uint16(off & 0xFFF),
-               rel:     r,
-               sym:     s,
        }
 
        // Set entry type
-       switch r.Siz {
+       switch r.Siz() {
        default:
                Exitf("unsupported relocation size %d\n", r.Siz)
        case 4:
@@ -1392,30 +1429,32 @@ func (rt *peBaseRelocTable) write(ctxt *Link) {
        }
 }
 
-func addPEBaseRelocSym(ctxt *Link, s *sym.Symbol, rt *peBaseRelocTable) {
-       for ri := 0; ri < len(s.R); ri++ {
-               r := &s.R[ri]
-
-               if r.Sym == nil {
+func addPEBaseRelocSym(ldr *loader.Loader, s loader.Sym, rt *peBaseRelocTable) {
+       relocs := ldr.Relocs(s)
+       for ri := 0; ri < relocs.Count(); ri++ {
+               r := relocs.At2(ri)
+               if r.Type() >= objabi.ElfRelocOffset {
                        continue
                }
-               if !r.Sym.Attr.Reachable() {
+               if r.Siz() == 0 { // informational relocation
                        continue
                }
-               if r.Type >= objabi.ElfRelocOffset {
+               if r.Type() == objabi.R_DWARFFILEREF {
                        continue
                }
-               if r.Siz == 0 { // informational relocation
+               rs := r.Sym()
+               rs = ldr.ResolveABIAlias(rs)
+               if rs == 0 {
                        continue
                }
-               if r.Type == objabi.R_DWARFFILEREF {
+               if !ldr.AttrReachable(s) {
                        continue
                }
 
-               switch r.Type {
+               switch r.Type() {
                default:
                case objabi.R_ADDR:
-                       rt.addentry(ctxt, s, r)
+                       rt.addentry(ldr, s, &r)
                }
        }
 }
@@ -1437,11 +1476,12 @@ func addPEBaseReloc(ctxt *Link) {
        rt.init(ctxt)
 
        // Get relocation information
-       for _, s := range ctxt.Textp {
-               addPEBaseRelocSym(ctxt, s, &rt)
+       ldr := ctxt.loader
+       for _, s := range ctxt.Textp2 {
+               addPEBaseRelocSym(ldr, s, &rt)
        }
-       for _, s := range ctxt.datap {
-               addPEBaseRelocSym(ctxt, s, &rt)
+       for _, s := range ctxt.datap2 {
+               addPEBaseRelocSym(ldr, s, &rt)
        }
 
        // Write relocation information
index 02cd0b89d825e828c4eeeb05306d04f3f44f9431..0990768903b4ccb3d926e4711f0bf9875a4fbf35 100644 (file)
@@ -692,6 +692,8 @@ func (l *Loader) SymVersion(i Sym) int {
        return int(abiToVer(r.Sym(li).ABI(), r.version))
 }
 
+func (l *Loader) IsFileLocal(i Sym) bool { return l.SymVersion(i) >= sym.SymVerStatic }
+
 // Returns the type of the i-th symbol.
 func (l *Loader) SymType(i Sym) sym.SymKind {
        if l.IsExternal(i) {
index 5297d15e39cfdde9e3b9cced18c901d421facad6..b42bfd3dc2d416e9a7ece3948fd0f88edf2f6e2a 100644 (file)
@@ -402,20 +402,21 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
        return false
 }
 
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
+func pereloc1(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.Dynid < 0 {
-               ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+       if ldr.SymDynid(rs) < 0 {
+               ldr.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", rt, sym.RelocName(arch, rt), ldr.SymName(rs), ldr.SymType(rs), ldr.SymType(rs))
                return false
        }
 
        out.Write32(uint32(sectoff))
-       out.Write32(uint32(rs.Dynid))
+       out.Write32(uint32(ldr.SymDynid(rs)))
 
-       switch r.Type {
+       switch rt {
        default:
                return false