]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: convert doelf to new style
authorCherry Zhang <cherryyz@google.com>
Wed, 11 Mar 2020 16:12:41 +0000 (12:12 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 11 Mar 2020 23:24:00 +0000 (23:24 +0000)
Change-Id: I448fe632ae73ddcb79c05793c96f48e358060305
Reviewed-on: https://go-review.googlesource.com/c/go/+/222977
Reviewed-by: Than McIntosh <thanm@google.com>
15 files changed:
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/dwarf2.go
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/main.go
src/cmd/link/internal/ld/target.go
src/cmd/link/internal/loader/symbolbuilder.go
src/cmd/link/internal/mips/asm.go
src/cmd/link/internal/mips64/asm.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/riscv64/asm.go
src/cmd/link/internal/s390x/asm.go
src/cmd/link/internal/x86/asm.go

index 34eb6f10018e9899065bf03ef2474ba1aafacd02..06c4a362a92b850f4e4621f25ac07f3325cc1f52 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "log"
@@ -572,27 +573,25 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
        return t
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
+func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
+       if plt.Size() == 0 {
                // pushq got+8(IP)
                plt.AddUint8(0xff)
 
                plt.AddUint8(0x35)
-               plt.AddPCRelPlus(ctxt.Arch, got, 8)
+               plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 8)
 
                // jmpq got+16(IP)
                plt.AddUint8(0xff)
 
                plt.AddUint8(0x25)
-               plt.AddPCRelPlus(ctxt.Arch, got, 16)
+               plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 16)
 
                // nopl 0(AX)
                plt.AddUint32(ctxt.Arch, 0x00401f0f)
 
                // assume got->size == 0 too
-               got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
+               got.AddAddrPlus(ctxt.Arch, dynamic, 0)
 
                got.AddUint64(ctxt.Arch, 0)
                got.AddUint64(ctxt.Arch, 0)
@@ -611,7 +610,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
                got := ctxt.Syms.Lookup(".got.plt", 0)
                rela := ctxt.Syms.Lookup(".rela.plt", 0)
                if plt.Size == 0 {
-                       elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
+                       panic("plt is not set up")
                }
 
                // jmpq *got+size(IP)
index 56c0a5c6649e7a90d163e5b4f6df2ab393c4ae38..e4a52e5589ab54a49f814f92758c6b3958c31980 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "fmt"
@@ -300,10 +301,8 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        return true
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
+func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
+       if plt.Size() == 0 {
                // str lr, [sp, #-4]!
                plt.AddUint32(ctxt.Arch, 0xe52de004)
 
@@ -317,7 +316,7 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
                plt.AddUint32(ctxt.Arch, 0xe5bef008)
 
                // .word &GLOBAL_OFFSET_TABLE[0] - .
-               plt.AddPCRelPlus(ctxt.Arch, got, 4)
+               plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 4)
 
                // the first .plt entry requires 3 .plt.got entries
                got.AddUint32(ctxt.Arch, 0)
@@ -697,7 +696,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
                got := ctxt.Syms.Lookup(".got.plt", 0)
                rel := ctxt.Syms.Lookup(".rel.plt", 0)
                if plt.Size == 0 {
-                       elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
+                       panic("plt is not set up")
                }
 
                // .got entry
index 0e5da99b974fca2ff33ced27dad8571921401328..0b4ecd6c5f76874f71871a05124115c0db362154 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "fmt"
@@ -711,30 +712,25 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
        return -1
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       gotplt := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
+func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
+       if plt.Size() == 0 {
                // stp     x16, x30, [sp, #-16]!
                // identifying information
                plt.AddUint32(ctxt.Arch, 0xa9bf7bf0)
 
                // the following two instructions (adrp + ldr) load *got[2] into x17
                // adrp    x16, &got[0]
-               plt.AddAddrPlus4(gotplt, 16)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
+               plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 16, objabi.R_ARM64_GOT, 4)
+               plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x90000010)
 
                // <imm> is the offset value of &got[2] to &got[0], the same below
                // ldr     x17, [x16, <imm>]
-               plt.AddAddrPlus4(gotplt, 16)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
+               plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 16, objabi.R_ARM64_GOT, 4)
+               plt.SetUint32(ctxt.Arch, plt.Size()-4, 0xf9400211)
 
                // add     x16, x16, <imm>
-               plt.AddAddrPlus4(gotplt, 16)
-               plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
-               plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
+               plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 16, objabi.R_ARM64_PCREL, 4)
+               plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x91000210)
 
                // br      x17
                plt.AddUint32(ctxt.Arch, 0xd61f0220)
@@ -745,10 +741,10 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
                plt.AddUint32(ctxt.Arch, 0xd503201f)
 
                // check gotplt.size == 0
-               if gotplt.Size != 0 {
-                       ld.Errorf(gotplt, "got.plt is not empty at the very beginning")
+               if gotplt.Size() != 0 {
+                       ctxt.Errorf(gotplt.Sym(), "got.plt is not empty at the very beginning")
                }
-               gotplt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
+               gotplt.AddAddrPlus(ctxt.Arch, dynamic, 0)
 
                gotplt.AddUint64(ctxt.Arch, 0)
                gotplt.AddUint64(ctxt.Arch, 0)
@@ -767,7 +763,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
                gotplt := ctxt.Syms.Lookup(".got.plt", 0)
                rela := ctxt.Syms.Lookup(".rela.plt", 0)
                if plt.Size == 0 {
-                       elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
+                       panic("plt is not set up")
                }
 
                // adrp    x16, &got.plt[0]
index ac971849b4debb0f1bfde024c97f7235b29c25c4..233cd6a7848eda077519bbf6aeb0e32d5dfbf0db 100644 (file)
@@ -15,6 +15,7 @@ package ld
 
 import (
        "cmd/internal/objabi"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "log"
 )
@@ -28,18 +29,18 @@ var dwarfp []*sym.Symbol
 /*
  *  Elf.
  */
-func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
+func dwarfaddshstrings(ctxt *Link, shstrtab *loader.SymbolBuilder) {
        if *FlagW { // disable dwarf
                return
        }
 
        secs := []string{"abbrev", "frame", "info", "loc", "line", "pubnames", "pubtypes", "gdb_scripts", "ranges"}
        for _, sec := range secs {
-               Addstring(shstrtab, ".debug_"+sec)
-               if ctxt.LinkMode == LinkExternal {
-                       Addstring(shstrtab, elfRelType+".debug_"+sec)
+               shstrtab.Addstring(".debug_" + sec)
+               if ctxt.IsExternal() {
+                       shstrtab.Addstring(elfRelType + ".debug_" + sec)
                } else {
-                       Addstring(shstrtab, ".zdebug_"+sec)
+                       shstrtab.Addstring(".zdebug_" + sec)
                }
        }
 }
index 6146bed284ea3cc621712fa418a8731e04b6ebf5..b0710892546279daa0810faf0ce13808cb08bb8a 100644 (file)
@@ -7,6 +7,7 @@ package ld
 import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "crypto/sha1"
        "encoding/binary"
@@ -774,6 +775,39 @@ func elfWriteDynEntSymSize(arch *sys.Arch, s *sym.Symbol, tag int, t *sym.Symbol
        s.AddSize(arch, t)
 }
 
+// temporary
+func Elfwritedynent2(ctxt *Link, s *loader.SymbolBuilder, tag int, val uint64) {
+       if elf64 {
+               s.AddUint64(ctxt.Arch, uint64(tag))
+               s.AddUint64(ctxt.Arch, val)
+       } else {
+               s.AddUint32(ctxt.Arch, uint32(tag))
+               s.AddUint32(ctxt.Arch, uint32(val))
+       }
+}
+
+func elfwritedynentsym2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
+       Elfwritedynentsymplus2(ctxt, s, tag, t, 0)
+}
+
+func Elfwritedynentsymplus2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym, add int64) {
+       if elf64 {
+               s.AddUint64(ctxt.Arch, uint64(tag))
+       } else {
+               s.AddUint32(ctxt.Arch, uint32(tag))
+       }
+       s.AddAddrPlus(ctxt.Arch, t, add)
+}
+
+func elfwritedynentsymsize2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
+       if elf64 {
+               s.AddUint64(ctxt.Arch, uint64(tag))
+       } else {
+               s.AddUint32(ctxt.Arch, uint32(tag))
+       }
+       s.AddSize(ctxt.Arch, t)
+}
+
 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
        interp = p
        n := len(interp) + 1
@@ -1400,9 +1434,10 @@ func Elfemitreloc(ctxt *Link) {
 }
 
 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
-       s := ctxt.Syms.Lookup(sectionName, 0)
-       s.Attr |= sym.AttrReachable
-       s.Type = sym.SELFROSECT
+       ldr := ctxt.loader
+       s := ldr.CreateSymForUpdate(sectionName, 0)
+       s.SetReachable(true)
+       s.SetType(sym.SELFROSECT)
        // namesz
        s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
        // descsz
@@ -1410,93 +1445,91 @@ func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
        // tag
        s.AddUint32(ctxt.Arch, tag)
        // name + padding
-       s.P = append(s.P, ELF_NOTE_GO_NAME...)
-       for len(s.P)%4 != 0 {
-               s.P = append(s.P, 0)
+       s.AddBytes(ELF_NOTE_GO_NAME)
+       for len(s.Data())%4 != 0 {
+               s.AddUint8(0)
        }
        // desc + padding
-       s.P = append(s.P, desc...)
-       for len(s.P)%4 != 0 {
-               s.P = append(s.P, 0)
+       s.AddBytes(desc)
+       for len(s.Data())%4 != 0 {
+               s.AddUint8(0)
        }
-       s.Size = int64(len(s.P))
-       s.Align = 4
+       s.SetSize(int64(len(s.Data())))
+       s.SetAlign(4)
 }
 
 func (ctxt *Link) doelf() {
-       if !ctxt.IsELF {
-               return
-       }
+       ldr := ctxt.loader
 
        /* predefine strings we need for section headers */
-       shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
+       shstrtab := ldr.CreateSymForUpdate(".shstrtab", 0)
 
-       shstrtab.Type = sym.SELFROSECT
-       shstrtab.Attr |= sym.AttrReachable
+       shstrtab.SetType(sym.SELFROSECT)
+       shstrtab.SetReachable(true)
 
-       Addstring(shstrtab, "")
-       Addstring(shstrtab, ".text")
-       Addstring(shstrtab, ".noptrdata")
-       Addstring(shstrtab, ".data")
-       Addstring(shstrtab, ".bss")
-       Addstring(shstrtab, ".noptrbss")
-       Addstring(shstrtab, "__libfuzzer_extra_counters")
-       Addstring(shstrtab, ".go.buildinfo")
+       shstrtab.Addstring("")
+       shstrtab.Addstring(".text")
+       shstrtab.Addstring(".noptrdata")
+       shstrtab.Addstring(".data")
+       shstrtab.Addstring(".bss")
+       shstrtab.Addstring(".noptrbss")
+       shstrtab.Addstring("__libfuzzer_extra_counters")
+       shstrtab.Addstring(".go.buildinfo")
 
        // generate .tbss section for dynamic internal linker or external
        // linking, so that various binutils could correctly calculate
        // PT_TLS size. See https://golang.org/issue/5200.
-       if !*FlagD || ctxt.LinkMode == LinkExternal {
-               Addstring(shstrtab, ".tbss")
+       if !*FlagD || ctxt.IsExternal() {
+               shstrtab.Addstring(".tbss")
        }
-       if ctxt.HeadType == objabi.Hnetbsd {
-               Addstring(shstrtab, ".note.netbsd.ident")
+       if ctxt.IsNetbsd() {
+               shstrtab.Addstring(".note.netbsd.ident")
        }
-       if ctxt.HeadType == objabi.Hopenbsd {
-               Addstring(shstrtab, ".note.openbsd.ident")
+       if ctxt.IsOpenbsd() {
+               shstrtab.Addstring(".note.openbsd.ident")
        }
        if len(buildinfo) > 0 {
-               Addstring(shstrtab, ".note.gnu.build-id")
+               shstrtab.Addstring(".note.gnu.build-id")
        }
        if *flagBuildid != "" {
-               Addstring(shstrtab, ".note.go.buildid")
+               shstrtab.Addstring(".note.go.buildid")
        }
-       Addstring(shstrtab, ".elfdata")
-       Addstring(shstrtab, ".rodata")
+       shstrtab.Addstring(".elfdata")
+       shstrtab.Addstring(".rodata")
        // See the comment about data.rel.ro.FOO section names in data.go.
        relro_prefix := ""
        if ctxt.UseRelro() {
-               Addstring(shstrtab, ".data.rel.ro")
+               shstrtab.Addstring(".data.rel.ro")
                relro_prefix = ".data.rel.ro"
        }
-       Addstring(shstrtab, relro_prefix+".typelink")
-       Addstring(shstrtab, relro_prefix+".itablink")
-       Addstring(shstrtab, relro_prefix+".gosymtab")
-       Addstring(shstrtab, relro_prefix+".gopclntab")
+       shstrtab.Addstring(relro_prefix + ".typelink")
+       shstrtab.Addstring(relro_prefix + ".itablink")
+       shstrtab.Addstring(relro_prefix + ".gosymtab")
+       shstrtab.Addstring(relro_prefix + ".gopclntab")
 
-       if ctxt.LinkMode == LinkExternal {
+       if ctxt.IsExternal() {
                *FlagD = true
 
-               Addstring(shstrtab, elfRelType+".text")
-               Addstring(shstrtab, elfRelType+".rodata")
-               Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
-               Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
-               Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
-               Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
-               Addstring(shstrtab, elfRelType+".noptrdata")
-               Addstring(shstrtab, elfRelType+".data")
+               shstrtab.Addstring(elfRelType + ".text")
+               shstrtab.Addstring(elfRelType + ".rodata")
+               shstrtab.Addstring(elfRelType + relro_prefix + ".typelink")
+               shstrtab.Addstring(elfRelType + relro_prefix + ".itablink")
+               shstrtab.Addstring(elfRelType + relro_prefix + ".gosymtab")
+               shstrtab.Addstring(elfRelType + relro_prefix + ".gopclntab")
+               shstrtab.Addstring(elfRelType + ".noptrdata")
+               shstrtab.Addstring(elfRelType + ".data")
                if ctxt.UseRelro() {
-                       Addstring(shstrtab, elfRelType+".data.rel.ro")
+                       shstrtab.Addstring(elfRelType + ".data.rel.ro")
                }
-               Addstring(shstrtab, elfRelType+".go.buildinfo")
+               shstrtab.Addstring(elfRelType + ".go.buildinfo")
 
                // add a .note.GNU-stack section to mark the stack as non-executable
-               Addstring(shstrtab, ".note.GNU-stack")
+               shstrtab.Addstring(".note.GNU-stack")
 
-               if ctxt.BuildMode == BuildModeShared {
-                       Addstring(shstrtab, ".note.go.abihash")
-                       Addstring(shstrtab, ".note.go.pkg-list")
-                       Addstring(shstrtab, ".note.go.deps")
+               if ctxt.IsShared() {
+                       shstrtab.Addstring(".note.go.abihash")
+                       shstrtab.Addstring(".note.go.pkg-list")
+                       shstrtab.Addstring(".note.go.deps")
                }
        }
 
@@ -1509,171 +1542,169 @@ func (ctxt *Link) doelf() {
        }
 
        if hasinitarr {
-               Addstring(shstrtab, ".init_array")
-               Addstring(shstrtab, elfRelType+".init_array")
+               shstrtab.Addstring(".init_array")
+               shstrtab.Addstring(elfRelType + ".init_array")
        }
 
        if !*FlagS {
-               Addstring(shstrtab, ".symtab")
-               Addstring(shstrtab, ".strtab")
+               shstrtab.Addstring(".symtab")
+               shstrtab.Addstring(".strtab")
                dwarfaddshstrings(ctxt, shstrtab)
        }
 
-       Addstring(shstrtab, ".shstrtab")
+       shstrtab.Addstring(".shstrtab")
 
        if !*FlagD { /* -d suppresses dynamic loader format */
-               Addstring(shstrtab, ".interp")
-               Addstring(shstrtab, ".hash")
-               Addstring(shstrtab, ".got")
-               if ctxt.Arch.Family == sys.PPC64 {
-                       Addstring(shstrtab, ".glink")
-               }
-               Addstring(shstrtab, ".got.plt")
-               Addstring(shstrtab, ".dynamic")
-               Addstring(shstrtab, ".dynsym")
-               Addstring(shstrtab, ".dynstr")
-               Addstring(shstrtab, elfRelType)
-               Addstring(shstrtab, elfRelType+".plt")
-
-               Addstring(shstrtab, ".plt")
-               Addstring(shstrtab, ".gnu.version")
-               Addstring(shstrtab, ".gnu.version_r")
+               shstrtab.Addstring(".interp")
+               shstrtab.Addstring(".hash")
+               shstrtab.Addstring(".got")
+               if ctxt.IsPPC64() {
+                       shstrtab.Addstring(".glink")
+               }
+               shstrtab.Addstring(".got.plt")
+               shstrtab.Addstring(".dynamic")
+               shstrtab.Addstring(".dynsym")
+               shstrtab.Addstring(".dynstr")
+               shstrtab.Addstring(elfRelType)
+               shstrtab.Addstring(elfRelType + ".plt")
+
+               shstrtab.Addstring(".plt")
+               shstrtab.Addstring(".gnu.version")
+               shstrtab.Addstring(".gnu.version_r")
 
                /* dynamic symbol table - first entry all zeros */
-               s := ctxt.Syms.Lookup(".dynsym", 0)
+               dynsym := ldr.CreateSymForUpdate(".dynsym", 0)
 
-               s.Type = sym.SELFROSECT
-               s.Attr |= sym.AttrReachable
+               dynsym.SetType(sym.SELFROSECT)
+               dynsym.SetReachable(true)
                if elf64 {
-                       s.Size += ELF64SYMSIZE
+                       dynsym.SetSize(dynsym.Size() + ELF64SYMSIZE)
                } else {
-                       s.Size += ELF32SYMSIZE
+                       dynsym.SetSize(dynsym.Size() + ELF32SYMSIZE)
                }
 
                /* dynamic string table */
-               s = ctxt.Syms.Lookup(".dynstr", 0)
+               dynstr := ldr.CreateSymForUpdate(".dynstr", 0)
 
-               s.Type = sym.SELFROSECT
-               s.Attr |= sym.AttrReachable
-               if s.Size == 0 {
-                       Addstring(s, "")
+               dynstr.SetType(sym.SELFROSECT)
+               dynstr.SetReachable(true)
+               if dynstr.Size() == 0 {
+                       dynstr.Addstring("")
                }
-               dynstr := s
 
                /* relocation table */
-               s = ctxt.Syms.Lookup(elfRelType, 0)
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFROSECT
+               s := ldr.CreateSymForUpdate(elfRelType, 0)
+               s.SetReachable(true)
+               s.SetType(sym.SELFROSECT)
 
                /* global offset table */
-               s = ctxt.Syms.Lookup(".got", 0)
-
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFGOT // writable
+               got := ldr.CreateSymForUpdate(".got", 0)
+               got.SetReachable(true)
+               got.SetType(sym.SELFGOT) // writable
 
                /* ppc64 glink resolver */
-               if ctxt.Arch.Family == sys.PPC64 {
-                       s := ctxt.Syms.Lookup(".glink", 0)
-                       s.Attr |= sym.AttrReachable
-                       s.Type = sym.SELFRXSECT
+               if ctxt.IsPPC64() {
+                       s := ldr.CreateSymForUpdate(".glink", 0)
+                       s.SetReachable(true)
+                       s.SetType(sym.SELFRXSECT)
                }
 
                /* hash */
-               s = ctxt.Syms.Lookup(".hash", 0)
+               hash := ldr.CreateSymForUpdate(".hash", 0)
+               hash.SetReachable(true)
+               hash.SetType(sym.SELFROSECT)
 
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFROSECT
+               gotplt := ldr.CreateSymForUpdate(".got.plt", 0)
+               gotplt.SetReachable(true)
+               gotplt.SetType(sym.SELFSECT) // writable
 
-               s = ctxt.Syms.Lookup(".got.plt", 0)
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFSECT // writable
-
-               s = ctxt.Syms.Lookup(".plt", 0)
-
-               s.Attr |= sym.AttrReachable
-               if ctxt.Arch.Family == sys.PPC64 {
+               plt := ldr.CreateSymForUpdate(".plt", 0)
+               plt.SetReachable(true)
+               if ctxt.IsPPC64() {
                        // In the ppc64 ABI, .plt is a data section
                        // written by the dynamic linker.
-                       s.Type = sym.SELFSECT
+                       plt.SetType(sym.SELFSECT)
                } else {
-                       s.Type = sym.SELFRXSECT
+                       plt.SetType(sym.SELFRXSECT)
                }
 
-               thearch.Elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
-
-               s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFROSECT
+               s = ldr.CreateSymForUpdate(elfRelType+".plt", 0)
+               s.SetReachable(true)
+               s.SetType(sym.SELFROSECT)
 
-               s = ctxt.Syms.Lookup(".gnu.version", 0)
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFROSECT
+               s = ldr.CreateSymForUpdate(".gnu.version", 0)
+               s.SetReachable(true)
+               s.SetType(sym.SELFROSECT)
 
-               s = ctxt.Syms.Lookup(".gnu.version_r", 0)
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFROSECT
+               s = ldr.CreateSymForUpdate(".gnu.version_r", 0)
+               s.SetReachable(true)
+               s.SetType(sym.SELFROSECT)
 
                /* define dynamic elf table */
-               s = ctxt.Syms.Lookup(".dynamic", 0)
+               dynamic := ldr.CreateSymForUpdate(".dynamic", 0)
+               dynamic.SetReachable(true)
+               dynamic.SetType(sym.SELFSECT) // writable
 
-               s.Attr |= sym.AttrReachable
-               s.Type = sym.SELFSECT // writable
+               thearch.Elfsetupplt(ctxt, plt, gotplt, dynamic.Sym())
 
                /*
                 * .dynamic table
                 */
-               elfWriteDynEntSym(ctxt.Arch, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0))
+               elfwritedynentsym2(ctxt, dynamic, DT_HASH, hash.Sym())
 
-               elfWriteDynEntSym(ctxt.Arch, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0))
+               elfwritedynentsym2(ctxt, dynamic, DT_SYMTAB, dynsym.Sym())
                if elf64 {
-                       elfWriteDynEnt(ctxt.Arch, s, DT_SYMENT, ELF64SYMSIZE)
+                       Elfwritedynent2(ctxt, dynamic, DT_SYMENT, ELF64SYMSIZE)
                } else {
-                       elfWriteDynEnt(ctxt.Arch, s, DT_SYMENT, ELF32SYMSIZE)
+                       Elfwritedynent2(ctxt, dynamic, DT_SYMENT, ELF32SYMSIZE)
                }
-               elfWriteDynEntSym(ctxt.Arch, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0))
-               elfWriteDynEntSymSize(ctxt.Arch, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0))
+               elfwritedynentsym2(ctxt, dynamic, DT_STRTAB, dynstr.Sym())
+               elfwritedynentsymsize2(ctxt, dynamic, DT_STRSZ, dynstr.Sym())
                if elfRelType == ".rela" {
-                       elfWriteDynEntSym(ctxt.Arch, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0))
-                       elfWriteDynEntSymSize(ctxt.Arch, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0))
-                       elfWriteDynEnt(ctxt.Arch, s, DT_RELAENT, ELF64RELASIZE)
+                       rela := ldr.LookupOrCreateSym(".rela", 0)
+                       elfwritedynentsym2(ctxt, dynamic, DT_RELA, rela)
+                       elfwritedynentsymsize2(ctxt, dynamic, DT_RELASZ, rela)
+                       Elfwritedynent2(ctxt, dynamic, DT_RELAENT, ELF64RELASIZE)
                } else {
-                       elfWriteDynEntSym(ctxt.Arch, s, DT_REL, ctxt.Syms.Lookup(".rel", 0))
-                       elfWriteDynEntSymSize(ctxt.Arch, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0))
-                       elfWriteDynEnt(ctxt.Arch, s, DT_RELENT, ELF32RELSIZE)
+                       rel := ldr.LookupOrCreateSym(".rel", 0)
+                       elfwritedynentsym2(ctxt, dynamic, DT_REL, rel)
+                       elfwritedynentsymsize2(ctxt, dynamic, DT_RELSZ, rel)
+                       Elfwritedynent2(ctxt, dynamic, DT_RELENT, ELF32RELSIZE)
                }
 
                if rpath.val != "" {
-                       elfWriteDynEnt(ctxt.Arch, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
+                       Elfwritedynent2(ctxt, dynamic, DT_RUNPATH, uint64(dynstr.Addstring(rpath.val)))
                }
 
-               if ctxt.Arch.Family == sys.PPC64 {
-                       elfWriteDynEntSym(ctxt.Arch, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
-               } else if ctxt.Arch.Family == sys.S390X {
-                       elfWriteDynEntSym(ctxt.Arch, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
+               if ctxt.IsPPC64() {
+                       elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, plt.Sym())
+               } else if ctxt.IsS390X() {
+                       elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, got.Sym())
                } else {
-                       elfWriteDynEntSym(ctxt.Arch, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
+                       elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, gotplt.Sym())
                }
 
-               if ctxt.Arch.Family == sys.PPC64 {
-                       elfWriteDynEnt(ctxt.Arch, s, DT_PPC64_OPT, 0)
+               if ctxt.IsPPC64() {
+                       Elfwritedynent2(ctxt, dynamic, DT_PPC64_OPT, 0)
                }
 
                // Solaris dynamic linker can't handle an empty .rela.plt if
                // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
                // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
                // size of .rel(a).plt section.
-               elfWriteDynEnt(ctxt.Arch, s, DT_DEBUG, 0)
+               Elfwritedynent2(ctxt, dynamic, DT_DEBUG, 0)
        }
 
-       if ctxt.BuildMode == BuildModeShared {
+       if ctxt.IsShared() {
                // The go.link.abihashbytes symbol will be pointed at the appropriate
                // part of the .note.go.abihash section in data.go:func address().
-               s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
-               s.Attr |= sym.AttrLocal
-               s.Type = sym.SRODATA
-               s.Attr |= sym.AttrSpecial
-               s.Attr |= sym.AttrReachable
-               s.Size = int64(sha1.Size)
+               s := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
+               sb := ldr.MakeSymbolUpdater(s)
+               ldr.SetAttrLocal(s, true)
+               sb.SetType(sym.SRODATA)
+               ldr.SetAttrSpecial(s, true)
+               sb.SetReachable(true)
+               sb.SetSize(sha1.Size)
 
                sort.Sort(byPkg(ctxt.Library))
                h := sha1.New()
index bf8f240b006bfcbb10b4dad0d7c5cd105e876240..6f222ce10c8790a6ff2427d5ebe25d3364b6a8cc 100644 (file)
@@ -174,7 +174,7 @@ type Arch struct {
        Asmb2 func(*Link)
 
        Elfreloc1   func(*Link, *sym.Reloc, int64) bool
-       Elfsetupplt func(*Link, *Target, *ArchSyms)
+       Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym)
        Gentext     func(*Link)
        Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
        PEreloc1    func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
index 8e7b9b811384858c6308bab21ce0ef10bb2364ba..e2c795ac6965ffc3991c72ce46936ea6f74eb884 100644 (file)
@@ -250,7 +250,7 @@ func Main(arch *sys.Arch, theArch Arch) {
        bench.Start("dostkcheck")
        ctxt.dostkcheck()
 
-       if !ctxt.IsDarwin() {
+       if !ctxt.IsELF && !ctxt.IsDarwin() {
                bench.Start("loadlibfull")
                ctxt.loadlibfull() // XXX do it here for now
        }
@@ -258,6 +258,8 @@ func Main(arch *sys.Arch, theArch Arch) {
        if ctxt.IsELF {
                bench.Start("doelf")
                ctxt.doelf()
+               bench.Start("loadlibfull")
+               ctxt.loadlibfull() // XXX do it here for now
        }
        if ctxt.IsDarwin() {
                bench.Start("domacho")
index 0caf2976df47b88ee1c5a7480d0b50b164bd6b10..69c15e56ee9b0606c7556321b6a52832c30a401c 100644 (file)
@@ -112,6 +112,14 @@ func (t *Target) IsSolaris() bool {
        return t.HeadType == objabi.Hsolaris
 }
 
+func (t *Target) IsNetbsd() bool {
+       return t.HeadType == objabi.Hnetbsd
+}
+
+func (t *Target) IsOpenbsd() bool {
+       return t.HeadType == objabi.Hopenbsd
+}
+
 //
 // MISC
 //
index 2560198aa68c0de0c21b7ac81849a157d5ef2d01..aeaec8b7b04f377072862e2b34216904a2616b97 100644 (file)
@@ -60,6 +60,13 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) *SymbolBuilder {
        return sb
 }
 
+// CreateSymForUpdate creates a symbol with given name and version,
+// returns a CreateSymForUpdate for update. If the symbol already
+// exists, it will update in-place.
+func (l *Loader) CreateSymForUpdate(name string, version int) *SymbolBuilder {
+       return l.MakeSymbolUpdater(l.LookupOrCreateSym(name, version))
+}
+
 // Getters for properties of the symbol we're working on.
 
 func (sb *SymbolBuilder) Sym() Sym               { return sb.symIdx }
@@ -271,7 +278,7 @@ func (sb *SymbolBuilder) addRel() *Reloc {
        return &sb.relocs[len(sb.relocs)-1]
 }
 
-func (sb *SymbolBuilder) addAddrPlus(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
+func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
        if sb.kind == 0 {
                sb.kind = sym.SDATA
        }
@@ -290,17 +297,34 @@ func (sb *SymbolBuilder) addAddrPlus(tgt Sym, add int64, typ objabi.RelocType, r
        return i + int64(r.Size)
 }
 
+// Add a symbol reference (relocation) with given type, addend, and size
+// (the most generic form).
+func (sb *SymbolBuilder) AddSymRef(arch *sys.Arch, tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
+       sb.setReachable()
+       return sb.addSymRef(tgt, add, typ, rsize)
+}
+
 func (sb *SymbolBuilder) AddAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
        sb.setReachable()
-       return sb.addAddrPlus(tgt, add, objabi.R_ADDR, arch.PtrSize)
+       return sb.addSymRef(tgt, add, objabi.R_ADDR, arch.PtrSize)
 }
 
 func (sb *SymbolBuilder) AddAddrPlus4(arch *sys.Arch, tgt Sym, add int64) int64 {
        sb.setReachable()
-       return sb.addAddrPlus(tgt, add, objabi.R_ADDR, 4)
+       return sb.addSymRef(tgt, add, objabi.R_ADDR, 4)
+}
+
+func (sb *SymbolBuilder) AddPCRelPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
+       sb.setReachable()
+       return sb.addSymRef(tgt, add, objabi.R_PCREL, 4)
 }
 
 func (sb *SymbolBuilder) AddCURelativeAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
        sb.setReachable()
-       return sb.addAddrPlus(tgt, add, objabi.R_ADDRCUOFF, arch.PtrSize)
+       return sb.addSymRef(tgt, add, objabi.R_ADDRCUOFF, arch.PtrSize)
+}
+
+func (sb *SymbolBuilder) AddSize(arch *sys.Arch, tgt Sym) int64 {
+       sb.setReachable()
+       return sb.addSymRef(tgt, 0, objabi.R_SIZE, arch.PtrSize)
 }
index aceed343017cc0a710c163e6e346ef896cfa8afb..c2cabc8291490a08bbe8f3ef6fc58944bf9ea5fe 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "fmt"
@@ -74,7 +75,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        return true
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
+func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
        return
 }
 
index d62ff8ec36d47eba5f8243b9012df0a23da60cf5..a6abec15f6631ecd64c8fe8b25fd632d81ee4adb 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "fmt"
@@ -91,7 +92,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        return true
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
+func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
        return
 }
 
index 21c9ad3e48d8035e98c57f1d3b10ea8f57117771..d0993e32678b4ff1dbc4f677a91893fb306ece58 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "encoding/binary"
@@ -498,14 +499,13 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        return true
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       if plt.Size == 0 {
+func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
+       if plt.Size() == 0 {
                // The dynamic linker stores the address of the
                // dynamic resolver and the DSO identifier in the two
                // doublewords at the beginning of the .plt section
                // before the PLT array. Reserve space for these.
-               plt.Size = 16
+               plt.SetSize(16)
        }
 }
 
@@ -949,7 +949,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
                plt := ctxt.Syms.Lookup(".plt", 0)
                rela := ctxt.Syms.Lookup(".rela.plt", 0)
                if plt.Size == 0 {
-                       elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
+                       panic("plt is not set up")
                }
 
                // Create the glink resolver if necessary
index 704435ffd080a843adb5819111427f6e03a8ae8e..bd8380bfe2d6fd52543a29a78b12a5bc67ae77bb 100644 (file)
@@ -9,6 +9,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "fmt"
        "log"
@@ -31,7 +32,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        return false
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
+func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
        log.Fatalf("elfsetuplt")
 }
 
index 9bf3c5bde62b7f0400ebdf40f9feacb2decefdff..c5060fa02c9eb34a90eba8042604b2c1f5b3c58a 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "fmt"
@@ -333,10 +334,8 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
        return true
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got", 0)
-       if plt.Size == 0 {
+func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
+       if plt.Size() == 0 {
                // stg     %r1,56(%r15)
                plt.AddUint8(0xe3)
                plt.AddUint8(0x10)
@@ -347,7 +346,7 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
                // larl    %r1,_GLOBAL_OFFSET_TABLE_
                plt.AddUint8(0xc0)
                plt.AddUint8(0x10)
-               plt.AddPCRelPlus(ctxt.Arch, got, 6)
+               plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 6)
                // mvc     48(8,%r15),8(%r1)
                plt.AddUint8(0xd2)
                plt.AddUint8(0x07)
@@ -376,7 +375,7 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
                plt.AddUint8(0x00)
 
                // assume got->size == 0 too
-               got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
+               got.AddAddrPlus(ctxt.Arch, dynamic, 0)
 
                got.AddUint64(ctxt.Arch, 0)
                got.AddUint64(ctxt.Arch, 0)
@@ -431,7 +430,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
                got := ctxt.Syms.Lookup(".got", 0)
                rela := ctxt.Syms.Lookup(".rela.plt", 0)
                if plt.Size == 0 {
-                       elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
+                       panic("plt is not set up")
                }
                // larl    %r1,_GLOBAL_OFFSET_TABLE_+index
 
index 267e048b40aa297f7213960a3e5ad1577074b565..1e407d05c0a32ff86bc02634001dadd49d96d8b2 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/ld"
+       "cmd/link/internal/loader"
        "cmd/link/internal/sym"
        "debug/elf"
        "log"
@@ -511,27 +512,25 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
        return t
 }
 
-func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
-       plt := ctxt.Syms.Lookup(".plt", 0)
-       got := ctxt.Syms.Lookup(".got.plt", 0)
-       if plt.Size == 0 {
+func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
+       if plt.Size() == 0 {
                // pushl got+4
                plt.AddUint8(0xff)
 
                plt.AddUint8(0x35)
-               plt.AddAddrPlus(ctxt.Arch, got, 4)
+               plt.AddAddrPlus(ctxt.Arch, got.Sym(), 4)
 
                // jmp *got+8
                plt.AddUint8(0xff)
 
                plt.AddUint8(0x25)
-               plt.AddAddrPlus(ctxt.Arch, got, 8)
+               plt.AddAddrPlus(ctxt.Arch, got.Sym(), 8)
 
                // zero pad
                plt.AddUint32(ctxt.Arch, 0)
 
                // assume got->size == 0 too
-               got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
+               got.AddAddrPlus(ctxt.Arch, dynamic, 0)
 
                got.AddUint32(ctxt.Arch, 0)
                got.AddUint32(ctxt.Arch, 0)
@@ -550,7 +549,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
                got := ctxt.Syms.Lookup(".got.plt", 0)
                rel := ctxt.Syms.Lookup(".rel.plt", 0)
                if plt.Size == 0 {
-                       elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
+                       panic("plt is not set up")
                }
 
                // jmpq *got+size