"cmd/link/internal/mips64",
"cmd/link/internal/ppc64",
"cmd/link/internal/s390x",
+ "cmd/link/internal/sym",
"cmd/link/internal/x86",
"debug/pe",
"math/big",
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"debug/elf"
"log"
)
return x &^ 0x80000000
}
-func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 {
- s.Attr |= ld.AttrReachable
+func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 {
+ s.Attr |= sym.AttrReachable
i := s.Size
s.Size += 4
s.Grow(s.Size)
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
- addmoduledata.Attr |= ld.AttrReachable
+ addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
- initfunc.Type = ld.STEXT
- initfunc.Attr |= ld.AttrLocal
- initfunc.Attr |= ld.AttrReachable
+ initfunc.Type = sym.STEXT
+ initfunc.Attr |= sym.AttrLocal
+ initfunc.Attr |= sym.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
initfunc.AddUint8(op1)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
- initarray_entry.Attr |= ld.AttrReachable
- initarray_entry.Attr |= ld.AttrLocal
- initarray_entry.Type = ld.SINITARR
+ initarray_entry.Attr |= sym.AttrReachable
+ initarray_entry.Attr |= sym.AttrLocal
+ initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= 256 {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
return false
}
// Handle relocations found in ELF object files.
case 256 + ld.R_X86_64_PC32:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
}
- if targ.Type == 0 || targ.Type == ld.SXREF {
+ if targ.Type == 0 || targ.Type == sym.SXREF {
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
}
r.Type = objabi.R_PCREL
return true
case 256 + ld.R_X86_64_PC64:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name)
}
- if targ.Type == 0 || targ.Type == ld.SXREF {
+ if targ.Type == 0 || targ.Type == sym.SXREF {
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
}
r.Type = objabi.R_PCREL
case 256 + ld.R_X86_64_PLT32:
r.Type = objabi.R_PCREL
r.Add += 4
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add += int64(targ.Plt)
return true
case 256 + ld.R_X86_64_GOTPCREL, 256 + ld.R_X86_64_GOTPCRELX, 256 + ld.R_X86_64_REX_GOTPCRELX:
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
// have symbol
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
// turn MOVQ of GOT entry into LEAQ of symbol itself
return true
case 256 + ld.R_X86_64_64:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_ADDR
// TODO: What is the difference between all these?
r.Type = objabi.R_ADDR
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
}
return true
case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add = int64(targ.Plt)
512 + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
r.Type = objabi.R_PCREL
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
}
return true
case 512 + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
// have symbol
// turn MOVQ of GOT entry into LEAQ of symbol itself
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
// fall through
case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
}
addgotsym(ctxt, targ)
switch r.Type {
case objabi.R_CALL,
objabi.R_PCREL:
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
// nothing to do, the relocation will be laid out in reloc
return true
}
return true
case objabi.R_ADDR:
- if s.Type == ld.STEXT && ld.Iself {
+ if s.Type == sym.STEXT && ld.Iself {
if ld.Headtype == objabi.Hsolaris {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
// linking, in which case the relocation will be
// prepared in the 'reloc' phase and passed to the
// external linker in the 'asmb' phase.
- if s.Type != ld.SDATA && s.Type != ld.SRODATA {
+ if s.Type != sym.SDATA && s.Type != sym.SRODATA {
break
}
}
ld.Adddynsym(ctxt, targ)
got := ctxt.Syms.Lookup(".got", 0)
- s.Type = got.Type | ld.SSUB
+ s.Type = got.Type | sym.SSUB
s.Outer = got
s.Sub = got.Sub
got.Sub = s
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
}
case objabi.R_CALL:
if r.Siz == 4 {
- if r.Xsym.Type == ld.SDYNIMPORT {
+ if r.Xsym.Type == sym.SDYNIMPORT {
if ctxt.DynlinkingGo() {
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
} else {
}
case objabi.R_PCREL:
if r.Siz == 4 {
- if r.Xsym.Type == ld.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
+ if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
} else {
ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
return true
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
- if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL {
+ if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_PCREL || r.Type == objabi.R_GOTPCREL {
if rs.Dynid < 0 {
- ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+ 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)
return false
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+ 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)
return false
}
}
return true
}
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Dynid < 0 {
- ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+ 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)
return false
}
return true
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant")
return t
}
}
}
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
}
}
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}
ctxt.Out.Flush()
}
-func tlsIEtoLE(s *ld.Symbol, off, size int) {
+func tlsIEtoLE(s *sym.Symbol, off, size int) {
// Transform the PC-relative instruction into a constant load.
// That is,
//
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"fmt"
"log"
)
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
- addmoduledata.Attr |= ld.AttrReachable
+ addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
- initfunc.Type = ld.STEXT
- initfunc.Attr |= ld.AttrLocal
- initfunc.Attr |= ld.AttrReachable
+ initfunc.Type = sym.STEXT
+ initfunc.Attr |= sym.AttrLocal
+ initfunc.Attr |= sym.AttrReachable
o := func(op uint32) {
initfunc.AddUint32(ctxt.Arch, op)
}
}
ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
- initarray_entry.Attr |= ld.AttrReachable
- initarray_entry.Attr |= ld.AttrLocal
- initarray_entry.Type = ld.SINITARR
+ initarray_entry.Attr |= sym.AttrReachable
+ initarray_entry.Attr |= sym.AttrLocal
+ initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= 256 {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
return false
}
case 256 + ld.R_ARM_PLT32:
r.Type = objabi.R_CALLARM
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
return false
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
addgotsyminternal(ctxt, targ)
} else {
addgotsym(ctxt, targ)
return true
case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
addgotsyminternal(ctxt, targ)
} else {
addgotsym(ctxt, targ)
case 256 + ld.R_ARM_CALL:
r.Type = objabi.R_CALLARM
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
return true
case 256 + ld.R_ARM_ABS32:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_ADDR
case 256 + ld.R_ARM_PC24,
256 + ld.R_ARM_JUMP24:
r.Type = objabi.R_CALLARM
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
}
// Handle references to ELF symbols from our own object files.
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
return true
}
return true
case objabi.R_ADDR:
- if s.Type != ld.SDATA {
+ if s.Type != sym.SDATA {
break
}
if ld.Iself {
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write32(uint32(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
}
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if r.Type == objabi.R_PCREL {
- if rs.Type == ld.SHOSTOBJ {
+ if rs.Type == sym.SHOSTOBJ {
ld.Errorf(s, "pc-relative relocation of external symbol is not supported")
return false
}
return true
}
- if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM {
+ if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM {
if rs.Dynid < 0 {
- ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+ 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)
return false
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+ 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)
return false
}
}
}
// Convert the direct jump relocation r to refer to a trampoline if the target is too far
-func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
+func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
switch r.Type {
case objabi.R_CALLARM:
// r.Add is the instruction
// look up existing trampolines first. if we found one within the range
// of direct call, we can reuse it. otherwise create a new one.
offset := (signext24(r.Add&0xffffff) + 2) * 4
- var tramp *ld.Symbol
+ var tramp *sym.Symbol
for i := 0; ; i++ {
name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
- if tramp.Type == ld.SDYNIMPORT {
+ if tramp.Type == sym.SDYNIMPORT {
// don't reuse trampoline defined in other module
continue
}
r.Done = false
}
default:
- ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
}
// generate a trampoline to target+offset
-func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
+func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
tramp.Size = 12 // 3 instructions
tramp.P = make([]byte, tramp.Size)
t := ld.Symaddr(target) + int64(offset)
}
// generate a trampoline to target+offset in position independent code
-func gentramppic(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
+func gentramppic(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
tramp.Size = 16 // 4 instructions
tramp.P = make([]byte, tramp.Size)
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4) // MOVW 4(R15), R11 // R15 is actual pc + 8
}
// generate a trampoline to target+offset in dynlink mode (using GOT)
-func gentrampdyn(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
+func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
tramp.Size = 20 // 5 instructions
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8) // MOVW 8(R15), R11 // R15 is actual pc + 8
o2 := uint32(0xe0800000 | 11<<12 | 15<<16 | 11) // ADD R15, R11, R11
}
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
case objabi.R_CALLARM:
rs = rs.Outer
}
- if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant")
return t
}
-func addpltreloc(ctxt *ld.Link, plt *ld.Symbol, got *ld.Symbol, sym *ld.Symbol, typ objabi.RelocType) *ld.Reloc {
+func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) *sym.Reloc {
r := plt.AddRel()
r.Sym = got
r.Off = int32(plt.Size)
r.Siz = 4
r.Type = typ
- r.Add = int64(sym.Got) - 8
+ r.Add = int64(s.Got) - 8
- plt.Attr |= ld.AttrReachable
+ plt.Attr |= sym.AttrReachable
plt.Size += 4
plt.Grow(plt.Size)
return r
}
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
}
}
-func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}
}
}
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"encoding/binary"
"fmt"
"log"
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == ld.STEXT {
+ if addmoduledata.Type == sym.STEXT {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
- addmoduledata.Attr |= ld.AttrReachable
+ addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
- initfunc.Type = ld.STEXT
- initfunc.Attr |= ld.AttrLocal
- initfunc.Attr |= ld.AttrReachable
+ initfunc.Type = sym.STEXT
+ initfunc.Attr |= sym.AttrLocal
+ initfunc.Attr |= sym.AttrReachable
o := func(op uint32) {
initfunc.AddUint32(ctxt.Arch, op)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
- initarray_entry.Attr |= ld.AttrReachable
- initarray_entry.Attr |= ld.AttrLocal
- initarray_entry.Type = ld.SINITARR
+ initarray_entry.Attr |= sym.AttrReachable
+ initarray_entry.Attr |= sym.AttrLocal
+ initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
return
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
// ld64 has a bug handling MACHO_ARM64_RELOC_UNSIGNED with !extern relocation.
// see cmd/internal/ld/data.go for details. The workaround is that don't use !extern
// UNSIGNED relocation at all.
- if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
+ if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
if rs.Dynid < 0 {
- ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+ 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)
return false
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+ 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)
return false
}
}
return true
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
// add + R_ADDRARM64.
- if !(r.Sym.Version != 0 || (r.Sym.Type&ld.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == ld.STEXT && ctxt.DynlinkingGo() {
+ if !(r.Sym.Version != 0 || (r.Sym.Type&sym.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() {
if o2&0xffc00000 != 0xf9400000 {
ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
}
rs = rs.Outer
}
- if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant")
return -1
}
import (
"cmd/internal/bio"
"cmd/internal/objabi"
+ "cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
var load []uint64
for _, s := range ctxt.Syms.Allsym {
for _, r := range s.R {
- if r.Sym != nil && r.Sym.Type&SMASK == SXREF {
+ if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF {
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
load = append(load, off)
loaded[off] = true
"cmd/internal/gcprog"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"fmt"
"log"
"os"
)
/*
- * divide-and-conquer list-link (by Sub) sort of Symbol* by Value.
+ * divide-and-conquer list-link (by Sub) sort of sym.Symbol* by Value.
* Used for sub-symbols when loading host objects (see e.g. ldelf.go).
*/
-func listsort(l *Symbol) *Symbol {
+func listsort(l *sym.Symbol) *sym.Symbol {
if l == nil || l.Sub == nil {
return l
}
// Estimate the max size needed to hold any new trampolines created for this function. This
// is used to determine when the section can be split if it becomes too large, to ensure that
// the trampolines are in the same section as the function that uses them.
-func maxSizeTrampolinesPPC64(s *Symbol, isTramp bool) uint64 {
+func maxSizeTrampolinesPPC64(s *sym.Symbol, isTramp bool) uint64 {
// If Thearch.Trampoline is nil, then trampoline support is not available on this arch.
// A trampoline does not need any dependent trampolines.
if Thearch.Trampoline == nil || isTramp {
// ARM, PPC64 & PPC64LE support trampoline insertion for internal and external linking
// On PPC64 & PPC64LE the text sections might be split but will still insert trampolines
// where necessary.
-func trampoline(ctxt *Link, s *Symbol) {
+func trampoline(ctxt *Link, s *sym.Symbol) {
if Thearch.Trampoline == nil {
return // no need or no support of trampolines on this arch
}
if !r.Type.IsDirectJump() {
continue
}
- if Symaddr(r.Sym) == 0 && r.Sym.Type != SDYNIMPORT {
+ if Symaddr(r.Sym) == 0 && r.Sym.Type != sym.SDYNIMPORT {
if r.Sym.File != s.File {
if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
Errorf(s, "unresolved inter-package jump to %s(%s)", r.Sym, r.Sym.File)
}
// resolve relocations in s.
-func relocsym(ctxt *Link, s *Symbol) {
+func relocsym(ctxt *Link, s *sym.Symbol) {
for ri := int32(0); ri < int32(len(s.R)); ri++ {
r := &s.R[ri]
r.Done = true
continue
}
- if r.Sym != nil && (r.Sym.Type&(SMASK|SHIDDEN) == 0 || r.Sym.Type&SMASK == SXREF) {
+ if r.Sym != nil && (r.Sym.Type&(sym.SMASK|sym.SHIDDEN) == 0 || r.Sym.Type&sym.SMASK == sym.SXREF) {
// When putting the runtime but not main into a shared library
// these symbols are undefined and that's OK.
if Buildmode == BuildmodeShared {
if r.Sym.Name == "main.main" || r.Sym.Name == "main.init" {
- r.Sym.Type = SDYNIMPORT
+ r.Sym.Type = sym.SDYNIMPORT
} else if strings.HasPrefix(r.Sym.Name, "go.info.") {
// Skip go.info symbols. They are only needed to communicate
// DWARF info between the compiler and linker.
// We need to be able to reference dynimport symbols when linking against
// shared libraries, and Solaris needs it always
- if Headtype != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == SDYNIMPORT && !ctxt.DynlinkingGo() {
+ if Headtype != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() {
if !(ctxt.Arch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") {
- Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, RelocName(ctxt.Arch, r.Type))
+ Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
}
- if r.Sym != nil && r.Sym.Type != STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
+ if r.Sym != nil && r.Sym.Type != sym.STLSBSS && r.Type != objabi.R_WEAKADDROFF && !r.Sym.Attr.Reachable() {
Errorf(s, "unreachable sym in relocation: %s", r.Sym.Name)
}
switch r.Type {
case objabi.R_PCRELDBL:
r.Type = objabi.R_PCREL
- r.Variant = RV_390_DBL
+ r.Variant = sym.RV_390_DBL
case objabi.R_CALL:
- r.Variant = RV_390_DBL
+ r.Variant = sym.RV_390_DBL
}
}
o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
}
if !Thearch.Archreloc(ctxt, r, s, &o) {
- Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, RelocName(ctxt.Arch, r.Type))
+ Errorf(s, "unknown reloc to %v: %d (%s)", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
case objabi.R_TLS_LE:
isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386))
log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
}
case objabi.R_ADDR:
- if Linkmode == LinkExternal && r.Sym.Type != SCONST {
+ if Linkmode == LinkExternal && r.Sym.Type != sym.SCONST {
r.Done = false
// set up addend for eventual relocation via outer symbol.
rs = rs.Outer
}
- if rs.Type != SHOSTOBJ && rs.Type != SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
Errorf(s, "missing section for relocation target %s", rs.Name)
}
r.Xsym = rs
// table, then it will add o twice into the relocated value.
// The workaround is that on arm64 don't ever add symaddr to o and always use
// extern relocation by requiring rs->dynid >= 0.
- if rs.Type != SHOSTOBJ {
+ if rs.Type != sym.SHOSTOBJ {
if ctxt.Arch.Family == sys.ARM64 && rs.Dynid < 0 {
Errorf(s, "R_ADDR reloc to %s+%d is not supported on darwin/arm64", rs.Name, o)
}
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
case objabi.R_GOTPCREL:
- if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != SCONST {
+ if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin && r.Sym != nil && r.Sym.Type != sym.SCONST {
r.Done = false
r.Xadd = r.Add
r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
}
fallthrough
case objabi.R_CALL, objabi.R_PCREL:
- if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
+ if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
r.Done = false
// set up addend for eventual relocation via outer symbol.
}
r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
- if rs.Type != SHOSTOBJ && rs.Type != SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
Errorf(s, "missing section for relocation target %s", rs.Name)
}
r.Xsym = rs
}
} else if Headtype == objabi.Hdarwin {
if r.Type == objabi.R_CALL {
- if rs.Type != SHOSTOBJ {
+ if rs.Type != sym.SHOSTOBJ {
o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
}
o -= int64(r.Off) // relative to section offset, not symbol
o = r.Sym.Size + r.Add
}
- if r.Variant != RV_NONE {
+ if r.Variant != sym.RV_NONE {
o = Thearch.Archrelocvariant(ctxt, r, s, o)
}
if r.Sym != nil {
nam = r.Sym.Name
}
- fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, RelocName(ctxt.Arch, r.Type), r.Variant, o)
+ fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d (%s)/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Variant, o)
}
switch siz {
default:
for _, s := range ctxt.Textp {
relocsym(ctxt, s)
}
- for _, sym := range datap {
- relocsym(ctxt, sym)
+ for _, s := range datap {
+ relocsym(ctxt, s)
}
for _, s := range dwarfp {
relocsym(ctxt, s)
}
}
-func windynrelocsym(ctxt *Link, s *Symbol) {
+func windynrelocsym(ctxt *Link, s *sym.Symbol) {
rel := ctxt.Syms.Lookup(".rel", 0)
if s == rel {
return
}
}
-func dynrelocsym(ctxt *Link, s *Symbol) {
+func dynrelocsym(ctxt *Link, s *sym.Symbol) {
if Headtype == objabi.Hwindows {
if Linkmode == LinkInternal {
windynrelocsym(ctxt, s)
Thearch.Adddynrel(ctxt, s, r)
continue
}
- if r.Sym != nil && r.Sym.Type == SDYNIMPORT || r.Type >= 256 {
+ if r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT || r.Type >= 256 {
if r.Sym != nil && !r.Sym.Attr.Reachable() {
Errorf(s, "dynamic relocation to unreachable symbol %s", r.Sym.Name)
}
if !Thearch.Adddynrel(ctxt, s, r) {
- Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type)
+ Errorf(s, "unsupported dynamic relocation for symbol %s (type=%d (%s) stype=%d (%s))", r.Sym.Name, r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Type, r.Sym.Type)
}
}
}
}
-func dynreloc(ctxt *Link, data *[SXREF][]*Symbol) {
+func dynreloc(ctxt *Link, data *[sym.SXREF][]*sym.Symbol) {
// -d suppresses dynamic loader format, so we may as well not
// compute these sections or mark their symbols as reachable.
if *FlagD && Headtype != objabi.Hwindows {
dynrelocsym(ctxt, s)
}
for _, syms := range data {
- for _, sym := range syms {
- dynrelocsym(ctxt, sym)
+ for _, s := range syms {
+ dynrelocsym(ctxt, s)
}
}
if Iself {
}
syms := ctxt.Textp
- for i, sym := range syms {
- if !sym.Attr.Reachable() {
+ for i, s := range syms {
+ if !s.Attr.Reachable() {
continue
}
- if sym.Value >= addr {
+ if s.Value >= addr {
syms = syms[i:]
break
}
eaddr := addr + size
var q []byte
- for _, sym := range syms {
- if !sym.Attr.Reachable() {
+ for _, s := range syms {
+ if !s.Attr.Reachable() {
continue
}
- if sym.Value >= eaddr {
+ if s.Value >= eaddr {
break
}
- if addr < sym.Value {
+ if addr < s.Value {
ctxt.Logf("%-20s %.8x|", "_", uint64(addr))
- for ; addr < sym.Value; addr++ {
+ for ; addr < s.Value; addr++ {
ctxt.Logf(" %.2x", 0)
}
ctxt.Logf("\n")
}
- ctxt.Logf("%.6x\t%-20s\n", uint64(addr), sym.Name)
- q = sym.P
+ ctxt.Logf("%.6x\t%-20s\n", uint64(addr), s.Name)
+ q = s.P
for len(q) >= 16 {
ctxt.Logf("%.6x\t% x\n", uint64(addr), q[:16])
}
}
-func blk(ctxt *Link, syms []*Symbol, addr, size int64, pad []byte) {
+func blk(ctxt *Link, syms []*sym.Symbol, addr, size int64, pad []byte) {
for i, s := range syms {
- if s.Type&SSUB == 0 && s.Value >= addr {
+ if s.Type&sym.SSUB == 0 && s.Value >= addr {
syms = syms[i:]
break
}
eaddr := addr + size
for _, s := range syms {
- if s.Type&SSUB != 0 {
+ if s.Type&sym.SSUB != 0 {
continue
}
if s.Value >= eaddr {
var zeros [512]byte
-var strdata []*Symbol
+var strdata []*sym.Symbol
func addstrdata1(ctxt *Link, arg string) {
eq := strings.IndexByte(arg, '=')
sp := ctxt.Syms.Lookup(p, 0)
Addstring(sp, value)
- sp.Type = SRODATA
+ sp.Type = sym.SRODATA
s := ctxt.Syms.Lookup(name, 0)
s.Size = 0
- s.Attr |= AttrDuplicateOK
+ s.Attr |= sym.AttrDuplicateOK
reachable := s.Attr.Reachable()
s.AddAddr(ctxt.Arch, sp)
s.AddUint(ctxt.Arch, uint64(len(value)))
// addstring, addaddr, etc., mark the symbols as reachable.
// In this case that is not necessarily true, so stick to what
// we know before entering this function.
- s.Attr.Set(AttrReachable, reachable)
+ s.Attr.Set(sym.AttrReachable, reachable)
strdata = append(strdata, s)
- sp.Attr.Set(AttrReachable, reachable)
+ sp.Attr.Set(sym.AttrReachable, reachable)
}
func (ctxt *Link) checkstrdata() {
for _, s := range strdata {
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
Errorf(s, "cannot use -X with text symbol")
} else if s.Gotype != nil && s.Gotype.Name != "type.string" {
Errorf(s, "cannot use -X with non-string symbol")
}
}
-func Addstring(s *Symbol, str string) int64 {
+func Addstring(s *sym.Symbol, str string) int64 {
if s.Type == 0 {
- s.Type = SNOPTRDATA
+ s.Type = sym.SNOPTRDATA
}
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrReachable
r := s.Size
if s.Name == ".shstrtab" {
elfsetstring(s, str, int(r))
// addgostring adds str, as a Go string value, to s. symname is the name of the
// symbol used to define the string data and must be unique per linked object.
-func addgostring(ctxt *Link, s *Symbol, symname, str string) {
- sym := ctxt.Syms.Lookup(symname, 0)
- if sym.Type != Sxxx {
+func addgostring(ctxt *Link, s *sym.Symbol, symname, str string) {
+ sdata := ctxt.Syms.Lookup(symname, 0)
+ if sdata.Type != sym.Sxxx {
Errorf(s, "duplicate symname in addgostring: %s", symname)
}
- sym.Attr |= AttrReachable
- sym.Attr |= AttrLocal
- sym.Type = SRODATA
- sym.Size = int64(len(str))
- sym.P = []byte(str)
- s.AddAddr(ctxt.Arch, sym)
+ sdata.Attr |= sym.AttrReachable
+ sdata.Attr |= sym.AttrLocal
+ sdata.Type = sym.SRODATA
+ sdata.Size = int64(len(str))
+ sdata.P = []byte(str)
+ s.AddAddr(ctxt.Arch, sdata)
s.AddUint(ctxt.Arch, uint64(len(str)))
}
-func addinitarrdata(ctxt *Link, s *Symbol) {
+func addinitarrdata(ctxt *Link, s *sym.Symbol) {
p := s.Name + ".ptr"
sp := ctxt.Syms.Lookup(p, 0)
- sp.Type = SINITARR
+ sp.Type = sym.SINITARR
sp.Size = 0
- sp.Attr |= AttrDuplicateOK
+ sp.Attr |= sym.AttrDuplicateOK
sp.AddAddr(ctxt.Arch, s)
}
}
// symalign returns the required alignment for the given symbol s.
-func symalign(s *Symbol) int32 {
+func symalign(s *sym.Symbol) int32 {
min := int32(Thearch.Minalign)
if s.Align >= min {
return s.Align
return align
}
-func aligndatsize(datsize int64, s *Symbol) int64 {
+func aligndatsize(datsize int64, s *sym.Symbol) int64 {
return Rnd(datsize, int64(symalign(s)))
}
type GCProg struct {
ctxt *Link
- sym *Symbol
+ sym *sym.Symbol
w gcprog.Writer
}
}
}
-func (p *GCProg) AddSym(s *Symbol) {
+func (p *GCProg) AddSym(s *sym.Symbol) {
typ := s.Gotype
- // Things without pointers should be in SNOPTRDATA or SNOPTRBSS;
+ // Things without pointers should be in sym.SNOPTRDATA or sym.SNOPTRBSS;
// everything we see should have pointers and should therefore have a type.
if typ == nil {
switch s.Name {
p.w.Append(prog[4:], nptr)
}
-// dataSortKey is used to sort a slice of data symbol *Symbol pointers.
+// dataSortKey is used to sort a slice of data symbol *sym.Symbol pointers.
// The sort keys are kept inline to improve cache behavior while sorting.
type dataSortKey struct {
size int64
name string
- sym *Symbol
+ sym *sym.Symbol
}
type bySizeAndName []dataSortKey
const cutoff int64 = 2e9 // 2 GB (or so; looks better in errors than 2^31)
-func checkdatsize(ctxt *Link, datsize int64, symn SymKind) {
+func checkdatsize(ctxt *Link, datsize int64, symn sym.SymKind) {
if datsize > cutoff {
Errorf(nil, "too much data in section %v (over %d bytes)", symn, cutoff)
}
// datap is a collection of reachable data symbols in address order.
// Generated by dodata.
-var datap []*Symbol
+var datap []*sym.Symbol
func (ctxt *Link) dodata() {
if ctxt.Debugvlog != 0 {
// as normal symbols, and give them a little size.
bss := ctxt.Syms.Lookup("runtime.bss", 0)
bss.Size = 8
- bss.Attr.Set(AttrSpecial, false)
+ bss.Attr.Set(sym.AttrSpecial, false)
- ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(AttrSpecial, false)
+ ctxt.Syms.Lookup("runtime.ebss", 0).Attr.Set(sym.AttrSpecial, false)
data := ctxt.Syms.Lookup("runtime.data", 0)
data.Size = 8
- data.Attr.Set(AttrSpecial, false)
+ data.Attr.Set(sym.AttrSpecial, false)
- ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(AttrSpecial, false)
+ ctxt.Syms.Lookup("runtime.edata", 0).Attr.Set(sym.AttrSpecial, false)
types := ctxt.Syms.Lookup("runtime.types", 0)
- types.Type = STYPE
+ types.Type = sym.STYPE
types.Size = 8
- types.Attr.Set(AttrSpecial, false)
+ types.Attr.Set(sym.AttrSpecial, false)
etypes := ctxt.Syms.Lookup("runtime.etypes", 0)
- etypes.Type = SFUNCTAB
- etypes.Attr.Set(AttrSpecial, false)
+ etypes.Type = sym.SFUNCTAB
+ etypes.Attr.Set(sym.AttrSpecial, false)
}
// Collect data symbols by type into data.
- var data [SXREF][]*Symbol
+ var data [sym.SXREF][]*sym.Symbol
for _, s := range ctxt.Syms.Allsym {
if !s.Attr.Reachable() || s.Attr.Special() {
continue
}
- if s.Type <= STEXT || s.Type >= SXREF {
+ if s.Type <= sym.STEXT || s.Type >= sym.SXREF {
continue
}
data[s.Type] = append(data[s.Type], s)
// "read only" data with relocations needs to go in its own section
// when building a shared library. We do this by boosting objects of
// type SXXX with relocations to type SXXXRELRO.
- for _, symnro := range readOnly {
- symnrelro := relROMap[symnro]
+ for _, symnro := range sym.ReadOnly {
+ symnrelro := sym.RelROMap[symnro]
- ro := []*Symbol{}
+ ro := []*sym.Symbol{}
relro := data[symnrelro]
for _, s := range data[symnro] {
isRelro := len(s.R) > 0
switch s.Type {
- case STYPE, STYPERELRO, SGOFUNCRELRO:
+ case sym.STYPE, sym.STYPERELRO, sym.SGOFUNCRELRO:
// Symbols are not sorted yet, so it is possible
// that an Outer symbol has been changed to a
// relro Type before it reaches here.
}
// Sort symbols.
- var dataMaxAlign [SXREF]int32
+ var dataMaxAlign [sym.SXREF]int32
var wg sync.WaitGroup
for symn := range data {
- symn := SymKind(symn)
+ symn := sym.SymKind(symn)
wg.Add(1)
go func() {
data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn])
datsize := int64(0)
// Writable data sections that do not need any specialized handling.
- writable := []SymKind{
- SELFSECT,
- SMACHO,
- SMACHOGOT,
- SWINDOWS,
+ writable := []sym.SymKind{
+ sym.SELFSECT,
+ sym.SMACHO,
+ sym.SMACHOGOT,
+ sym.SWINDOWS,
}
for _, symn := range writable {
for _, s := range data[symn] {
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
- s.Type = SDATA
+ s.Type = sym.SDATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
// .got (and .toc on ppc64)
- if len(data[SELFGOT]) > 0 {
+ if len(data[sym.SELFGOT]) > 0 {
sect := addsection(ctxt.Arch, &Segdata, ".got", 06)
- sect.Align = dataMaxAlign[SELFGOT]
+ sect.Align = dataMaxAlign[sym.SELFGOT]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- var toc *Symbol
- for _, s := range data[SELFGOT] {
+ var toc *sym.Symbol
+ for _, s := range data[sym.SELFGOT] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
- s.Type = SDATA
+ s.Type = sym.SDATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
// Resolve .TOC. symbol for this object file (ppc64)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SELFGOT)
+ checkdatsize(ctxt, datsize, sym.SELFGOT)
sect.Length = uint64(datsize) - sect.Vaddr
}
/* pointer-free data */
sect := addsection(ctxt.Arch, &Segdata, ".noptrdata", 06)
- sect.Align = dataMaxAlign[SNOPTRDATA]
+ sect.Align = dataMaxAlign[sym.SNOPTRDATA]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.noptrdata", 0).Sect = sect
ctxt.Syms.Lookup("runtime.enoptrdata", 0).Sect = sect
- for _, s := range data[SNOPTRDATA] {
+ for _, s := range data[sym.SNOPTRDATA] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
- s.Type = SDATA
+ s.Type = sym.SDATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SNOPTRDATA)
+ checkdatsize(ctxt, datsize, sym.SNOPTRDATA)
sect.Length = uint64(datsize) - sect.Vaddr
hasinitarr := *FlagLinkshared
}
if hasinitarr {
sect := addsection(ctxt.Arch, &Segdata, ".init_array", 06)
- sect.Align = dataMaxAlign[SINITARR]
+ sect.Align = dataMaxAlign[sym.SINITARR]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- for _, s := range data[SINITARR] {
+ for _, s := range data[sym.SINITARR] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
- checkdatsize(ctxt, datsize, SINITARR)
+ checkdatsize(ctxt, datsize, sym.SINITARR)
}
/* data */
sect = addsection(ctxt.Arch, &Segdata, ".data", 06)
- sect.Align = dataMaxAlign[SDATA]
+ sect.Align = dataMaxAlign[sym.SDATA]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.data", 0).Sect = sect
ctxt.Syms.Lookup("runtime.edata", 0).Sect = sect
var gc GCProg
gc.Init(ctxt, "runtime.gcdata")
- for _, s := range data[SDATA] {
+ for _, s := range data[sym.SDATA] {
s.Sect = sect
- s.Type = SDATA
+ s.Type = sym.SDATA
datsize = aligndatsize(datsize, s)
s.Value = int64(uint64(datsize) - sect.Vaddr)
gc.AddSym(s)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SDATA)
+ checkdatsize(ctxt, datsize, sym.SDATA)
sect.Length = uint64(datsize) - sect.Vaddr
gc.End(int64(sect.Length))
/* bss */
sect = addsection(ctxt.Arch, &Segdata, ".bss", 06)
- sect.Align = dataMaxAlign[SBSS]
+ sect.Align = dataMaxAlign[sym.SBSS]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.bss", 0).Sect = sect
ctxt.Syms.Lookup("runtime.ebss", 0).Sect = sect
gc = GCProg{}
gc.Init(ctxt, "runtime.gcbss")
- for _, s := range data[SBSS] {
+ for _, s := range data[sym.SBSS] {
s.Sect = sect
datsize = aligndatsize(datsize, s)
s.Value = int64(uint64(datsize) - sect.Vaddr)
gc.AddSym(s)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SBSS)
+ checkdatsize(ctxt, datsize, sym.SBSS)
sect.Length = uint64(datsize) - sect.Vaddr
gc.End(int64(sect.Length))
/* pointer-free bss */
sect = addsection(ctxt.Arch, &Segdata, ".noptrbss", 06)
- sect.Align = dataMaxAlign[SNOPTRBSS]
+ sect.Align = dataMaxAlign[sym.SNOPTRBSS]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.noptrbss", 0).Sect = sect
ctxt.Syms.Lookup("runtime.enoptrbss", 0).Sect = sect
- for _, s := range data[SNOPTRBSS] {
+ for _, s := range data[sym.SNOPTRBSS] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
sect.Length = uint64(datsize) - sect.Vaddr
ctxt.Syms.Lookup("runtime.end", 0).Sect = sect
- checkdatsize(ctxt, datsize, SNOPTRBSS)
+ checkdatsize(ctxt, datsize, sym.SNOPTRBSS)
- if len(data[STLSBSS]) > 0 {
- var sect *Section
+ if len(data[sym.STLSBSS]) > 0 {
+ var sect *sym.Section
if Iself && (Linkmode == LinkExternal || !*FlagD) {
sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
sect.Align = int32(ctxt.Arch.PtrSize)
}
datsize = 0
- for _, s := range data[STLSBSS] {
+ for _, s := range data[sym.STLSBSS] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = datsize
datsize += s.Size
}
- checkdatsize(ctxt, datsize, STLSBSS)
+ checkdatsize(ctxt, datsize, sym.STLSBSS)
if sect != nil {
sect.Length = uint64(datsize)
* since it's not our decision; that code expects the sections in
* segtext.
*/
- var segro *Segment
+ var segro *sym.Segment
if Iself && Linkmode == LinkInternal {
segro = &Segrodata
} else {
datsize = 0
/* read-only executable ELF, Mach-O sections */
- if len(data[STEXT]) != 0 {
- Errorf(nil, "dodata found an STEXT symbol: %s", data[STEXT][0].Name)
+ if len(data[sym.STEXT]) != 0 {
+ Errorf(nil, "dodata found an sym.STEXT symbol: %s", data[sym.STEXT][0].Name)
}
- for _, s := range data[SELFRXSECT] {
+ for _, s := range data[sym.SELFRXSECT] {
sect := addsection(ctxt.Arch, &Segtext, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
- checkdatsize(ctxt, datsize, SELFRXSECT)
+ checkdatsize(ctxt, datsize, sym.SELFRXSECT)
}
/* read-only data */
ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
}
- for _, symn := range readOnly {
+ for _, symn := range sym.ReadOnly {
align := dataMaxAlign[symn]
if sect.Align < align {
sect.Align = align
}
}
datsize = Rnd(datsize, int64(sect.Align))
- for _, symn := range readOnly {
+ for _, symn := range sym.ReadOnly {
for _, s := range data[symn] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
/* read-only ELF, Mach-O sections */
- for _, s := range data[SELFROSECT] {
+ for _, s := range data[sym.SELFROSECT] {
sect = addsection(ctxt.Arch, segro, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(ctxt, datsize, SELFROSECT)
+ checkdatsize(ctxt, datsize, sym.SELFROSECT)
- for _, s := range data[SMACHOPLT] {
+ for _, s := range data[sym.SMACHOPLT] {
sect = addsection(ctxt.Arch, segro, s.Name, 04)
sect.Align = symalign(s)
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(ctxt, datsize, SMACHOPLT)
+ checkdatsize(ctxt, datsize, sym.SMACHOPLT)
// There is some data that are conceptually read-only but are written to by
// relocations. On GNU systems, we can arrange for the dynamic linker to
// situation.
// TODO(mwhudson): It would make sense to do this more widely, but it makes
// the system linker segfault on darwin.
- addrelrosection := func(suffix string) *Section {
+ addrelrosection := func(suffix string) *sym.Section {
return addsection(ctxt.Arch, segro, suffix, 04)
}
if UseRelro() {
- addrelrosection = func(suffix string) *Section {
+ addrelrosection = func(suffix string) *sym.Section {
seg := &Segrelrodata
if Linkmode == LinkExternal {
// Using a separate segment with an external
sect.Vaddr = 0
ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
- for _, symnro := range readOnly {
- symn := relROMap[symnro]
+ for _, symnro := range sym.ReadOnly {
+ symn := sym.RelROMap[symnro]
align := dataMaxAlign[symn]
if sect.Align < align {
sect.Align = align
}
}
datsize = Rnd(datsize, int64(sect.Align))
- for _, symnro := range readOnly {
- symn := relROMap[symnro]
+ for _, symnro := range sym.ReadOnly {
+ symn := sym.RelROMap[symnro]
for _, s := range data[symn] {
datsize = aligndatsize(datsize, s)
if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect {
Errorf(s, "s.Outer (%s) in different section from s, %s != %s", s.Outer.Name, s.Outer.Sect.Name, sect.Name)
}
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
/* typelink */
sect = addrelrosection(".typelink")
- sect.Align = dataMaxAlign[STYPELINK]
+ sect.Align = dataMaxAlign[sym.STYPELINK]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
typelink := ctxt.Syms.Lookup("runtime.typelink", 0)
typelink.Sect = sect
- typelink.Type = SRODATA
+ typelink.Type = sym.SRODATA
datsize += typelink.Size
- checkdatsize(ctxt, datsize, STYPELINK)
+ checkdatsize(ctxt, datsize, sym.STYPELINK)
sect.Length = uint64(datsize) - sect.Vaddr
/* itablink */
sect = addrelrosection(".itablink")
- sect.Align = dataMaxAlign[SITABLINK]
+ sect.Align = dataMaxAlign[sym.SITABLINK]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.itablink", 0).Sect = sect
ctxt.Syms.Lookup("runtime.eitablink", 0).Sect = sect
- for _, s := range data[SITABLINK] {
+ for _, s := range data[sym.SITABLINK] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SITABLINK)
+ checkdatsize(ctxt, datsize, sym.SITABLINK)
sect.Length = uint64(datsize) - sect.Vaddr
/* gosymtab */
sect = addrelrosection(".gosymtab")
- sect.Align = dataMaxAlign[SSYMTAB]
+ sect.Align = dataMaxAlign[sym.SSYMTAB]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.symtab", 0).Sect = sect
ctxt.Syms.Lookup("runtime.esymtab", 0).Sect = sect
- for _, s := range data[SSYMTAB] {
+ for _, s := range data[sym.SSYMTAB] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SSYMTAB)
+ checkdatsize(ctxt, datsize, sym.SSYMTAB)
sect.Length = uint64(datsize) - sect.Vaddr
/* gopclntab */
sect = addrelrosection(".gopclntab")
- sect.Align = dataMaxAlign[SPCLNTAB]
+ sect.Align = dataMaxAlign[sym.SPCLNTAB]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
ctxt.Syms.Lookup("runtime.pclntab", 0).Sect = sect
ctxt.Syms.Lookup("runtime.epclntab", 0).Sect = sect
- for _, s := range data[SPCLNTAB] {
+ for _, s := range data[sym.SPCLNTAB] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(ctxt, datsize, SRODATA)
+ checkdatsize(ctxt, datsize, sym.SRODATA)
sect.Length = uint64(datsize) - sect.Vaddr
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
Errorf(nil, "read-only data segment too large: %d", datsize)
}
- for symn := SELFRXSECT; symn < SXREF; symn++ {
+ for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
datap = append(datap, data[symn]...)
}
var i int
for ; i < len(dwarfp); i++ {
s := dwarfp[i]
- if s.Type != SDWARFSECT {
+ if s.Type != sym.SDWARFSECT {
break
}
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(ctxt, datsize, SDWARFSECT)
+ checkdatsize(ctxt, datsize, sym.SDWARFSECT)
for i < len(dwarfp) {
curType := dwarfp[i].Type
- var sect *Section
+ var sect *sym.Section
switch curType {
- case SDWARFINFO:
+ case sym.SDWARFINFO:
sect = addsection(ctxt.Arch, &Segdwarf, ".debug_info", 04)
- case SDWARFRANGE:
+ case sym.SDWARFRANGE:
sect = addsection(ctxt.Arch, &Segdwarf, ".debug_ranges", 04)
- case SDWARFLOC:
+ case sym.SDWARFLOC:
sect = addsection(ctxt.Arch, &Segdwarf, ".debug_loc", 04)
default:
Errorf(dwarfp[i], "unknown DWARF section %v", curType)
break
}
s.Sect = sect
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- s.Attr |= AttrLocal
+ s.Attr |= sym.AttrLocal
datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
}
}
-func dodataSect(ctxt *Link, symn SymKind, syms []*Symbol) (result []*Symbol, maxAlign int32) {
+func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym.Symbol, maxAlign int32) {
if Headtype == objabi.Hdarwin {
// Some symbols may no longer belong in syms
// due to movement in machosymorder.
- newSyms := make([]*Symbol, 0, len(syms))
+ newSyms := make([]*sym.Symbol, 0, len(syms))
for _, s := range syms {
if s.Type == symn {
newSyms = append(newSyms, s)
syms = newSyms
}
- var head, tail *Symbol
+ var head, tail *sym.Symbol
symsSort := make([]dataSortKey, 0, len(syms))
for _, s := range syms {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
switch {
case s.Size < int64(len(s.P)):
Errorf(s, "initialize bounds (%d < %d)", s.Size, len(s.P))
}
switch s.Type {
- case SELFGOT:
+ case sym.SELFGOT:
// For ppc64, we want to interleave the .got and .toc sections
- // from input files. Both are type SELFGOT, so in that case
+ // from input files. Both are type sym.SELFGOT, so in that case
// we skip size comparison and fall through to the name
// comparison (conveniently, .got sorts before .toc).
key.size = 0
syms[len(syms)-1] = tail
}
- if Iself && symn == SELFROSECT {
+ if Iself && symn == sym.SELFROSECT {
// Make .rela and .rela.plt contiguous, the ELF ABI requires this
// and Solaris actually cares.
reli, plti := -1, -1
return
}
- sym := ctxt.Syms.Lookup("go.buildid", 0)
- sym.Attr |= AttrReachable
+ s := ctxt.Syms.Lookup("go.buildid", 0)
+ s.Attr |= sym.AttrReachable
// The \xff is invalid UTF-8, meant to make it less likely
// to find one of these accidentally.
data := "\xff Go build ID: " + strconv.Quote(*flagBuildid) + "\n \xff"
- sym.Type = STEXT
- sym.P = []byte(data)
- sym.Size = int64(len(sym.P))
+ s.Type = sym.STEXT
+ s.P = []byte(data)
+ s.Size = int64(len(s.P))
ctxt.Textp = append(ctxt.Textp, nil)
copy(ctxt.Textp[1:], ctxt.Textp)
- ctxt.Textp[0] = sym
+ ctxt.Textp[0] = s
}
// assign addresses to text
n := 1
sect.Vaddr = va
ntramps := 0
- for _, sym := range ctxt.Textp {
- sect, n, va = assignAddress(ctxt, sect, n, sym, va, false)
+ for _, s := range ctxt.Textp {
+ sect, n, va = assignAddress(ctxt, sect, n, s, va, false)
- trampoline(ctxt, sym) // resolve jumps, may add trampolines if jump too far
+ trampoline(ctxt, s) // resolve jumps, may add trampolines if jump too far
// lay down trampolines after each function
for ; ntramps < len(ctxt.tramps); ntramps++ {
// merge tramps into Textp, keeping Textp in address order
if ntramps != 0 {
- newtextp := make([]*Symbol, 0, len(ctxt.Textp)+ntramps)
+ newtextp := make([]*sym.Symbol, 0, len(ctxt.Textp)+ntramps)
i := 0
- for _, sym := range ctxt.Textp {
- for ; i < ntramps && ctxt.tramps[i].Value < sym.Value; i++ {
+ for _, s := range ctxt.Textp {
+ for ; i < ntramps && ctxt.tramps[i].Value < s.Value; i++ {
newtextp = append(newtextp, ctxt.tramps[i])
}
- newtextp = append(newtextp, sym)
+ newtextp = append(newtextp, s)
}
newtextp = append(newtextp, ctxt.tramps[i:ntramps]...)
// assigns address for a text symbol, returns (possibly new) section, its number, and the address
// Note: once we have trampoline insertion support for external linking, this function
// will not need to create new text sections, and so no need to return sect and n.
-func assignAddress(ctxt *Link, sect *Section, n int, sym *Symbol, va uint64, isTramp bool) (*Section, int, uint64) {
- sym.Sect = sect
- if sym.Type&SSUB != 0 {
+func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint64, isTramp bool) (*sym.Section, int, uint64) {
+ s.Sect = sect
+ if s.Type&sym.SSUB != 0 {
return sect, n, va
}
- if sym.Align != 0 {
- va = uint64(Rnd(int64(va), int64(sym.Align)))
+ if s.Align != 0 {
+ va = uint64(Rnd(int64(va), int64(s.Align)))
} else {
va = uint64(Rnd(int64(va), int64(Funcalign)))
}
- sym.Value = 0
- for sub := sym; sub != nil; sub = sub.Sub {
+ s.Value = 0
+ for sub := s; sub != nil; sub = sub.Sub {
sub.Value += int64(va)
}
funcsize := uint64(MINFUNC) // spacing required for findfunctab
- if sym.Size > MINFUNC {
- funcsize = uint64(sym.Size)
+ if s.Size > MINFUNC {
+ funcsize = uint64(s.Size)
}
// On ppc64x a text section should not be larger than 2^26 bytes due to the size of
// Only break at outermost syms.
- if ctxt.Arch.InFamily(sys.PPC64) && sym.Outer == nil && Iself && Linkmode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(sym, isTramp) > 0x1c00000 {
+ if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && Iself && Linkmode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 {
// Set the length for the previous text section
sect.Length = va - sect.Vaddr
// Create new section, set the starting Vaddr
sect = addsection(ctxt.Arch, &Segtext, ".text", 05)
sect.Vaddr = va
- sym.Sect = sect
+ s.Sect = sect
// Create a symbol for the start of the secondary text sections
ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect
if Headtype == objabi.Hplan9 {
Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen
}
- var data *Section
- var noptr *Section
- var bss *Section
- var noptrbss *Section
+ var data *sym.Section
+ var noptr *sym.Section
+ var bss *sym.Section
+ var noptrbss *sym.Section
for i, s := range Segdata.Sections {
if Iself && s.Name == ".tbss" {
continue
}
}
- for _, sym := range dwarfp {
- if sym.Sect != nil {
- sym.Value += int64(sym.Sect.Vaddr)
+ for _, s := range dwarfp {
+ if s.Sect != nil {
+ s.Value += int64(s.Sect.Vaddr)
}
- for sub := sym.Sub; sub != nil; sub = sub.Sub {
- sub.Value += sym.Value
+ for sub := s.Sub; sub != nil; sub = sub.Sub {
+ sub.Value += s.Value
}
}
s.Value = int64(sectSym.Sect.Vaddr + 16)
}
- ctxt.xdefine("runtime.text", STEXT, int64(text.Vaddr))
- ctxt.xdefine("runtime.etext", STEXT, int64(lasttext.Vaddr+lasttext.Length))
+ ctxt.xdefine("runtime.text", sym.STEXT, int64(text.Vaddr))
+ ctxt.xdefine("runtime.etext", sym.STEXT, int64(lasttext.Vaddr+lasttext.Length))
// If there are multiple text sections, create runtime.text.n for
// their section Vaddr, using n for index
for _, sect := range Segtext.Sections[1:] {
if sect.Name == ".text" {
symname := fmt.Sprintf("runtime.text.%d", n)
- ctxt.xdefine(symname, STEXT, int64(sect.Vaddr))
+ ctxt.xdefine(symname, sym.STEXT, int64(sect.Vaddr))
n++
} else {
break
}
}
- ctxt.xdefine("runtime.rodata", SRODATA, int64(rodata.Vaddr))
- ctxt.xdefine("runtime.erodata", SRODATA, int64(rodata.Vaddr+rodata.Length))
- ctxt.xdefine("runtime.types", SRODATA, int64(types.Vaddr))
- ctxt.xdefine("runtime.etypes", SRODATA, int64(types.Vaddr+types.Length))
- ctxt.xdefine("runtime.itablink", SRODATA, int64(itablink.Vaddr))
- ctxt.xdefine("runtime.eitablink", SRODATA, int64(itablink.Vaddr+itablink.Length))
-
- sym := ctxt.Syms.Lookup("runtime.gcdata", 0)
- sym.Attr |= AttrLocal
- ctxt.xdefine("runtime.egcdata", SRODATA, Symaddr(sym)+sym.Size)
- ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = sym.Sect
-
- sym = ctxt.Syms.Lookup("runtime.gcbss", 0)
- sym.Attr |= AttrLocal
- ctxt.xdefine("runtime.egcbss", SRODATA, Symaddr(sym)+sym.Size)
- ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = sym.Sect
-
- ctxt.xdefine("runtime.symtab", SRODATA, int64(symtab.Vaddr))
- ctxt.xdefine("runtime.esymtab", SRODATA, int64(symtab.Vaddr+symtab.Length))
- ctxt.xdefine("runtime.pclntab", SRODATA, int64(pclntab.Vaddr))
- ctxt.xdefine("runtime.epclntab", SRODATA, int64(pclntab.Vaddr+pclntab.Length))
- ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, int64(noptr.Vaddr))
- ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
- ctxt.xdefine("runtime.bss", SBSS, int64(bss.Vaddr))
- ctxt.xdefine("runtime.ebss", SBSS, int64(bss.Vaddr+bss.Length))
- ctxt.xdefine("runtime.data", SDATA, int64(data.Vaddr))
- ctxt.xdefine("runtime.edata", SDATA, int64(data.Vaddr+data.Length))
- ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, int64(noptrbss.Vaddr))
- ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
- ctxt.xdefine("runtime.end", SBSS, int64(Segdata.Vaddr+Segdata.Length))
+ ctxt.xdefine("runtime.rodata", sym.SRODATA, int64(rodata.Vaddr))
+ ctxt.xdefine("runtime.erodata", sym.SRODATA, int64(rodata.Vaddr+rodata.Length))
+ ctxt.xdefine("runtime.types", sym.SRODATA, int64(types.Vaddr))
+ ctxt.xdefine("runtime.etypes", sym.SRODATA, int64(types.Vaddr+types.Length))
+ ctxt.xdefine("runtime.itablink", sym.SRODATA, int64(itablink.Vaddr))
+ ctxt.xdefine("runtime.eitablink", sym.SRODATA, int64(itablink.Vaddr+itablink.Length))
+
+ s := ctxt.Syms.Lookup("runtime.gcdata", 0)
+ s.Attr |= sym.AttrLocal
+ ctxt.xdefine("runtime.egcdata", sym.SRODATA, Symaddr(s)+s.Size)
+ ctxt.Syms.Lookup("runtime.egcdata", 0).Sect = s.Sect
+
+ s = ctxt.Syms.Lookup("runtime.gcbss", 0)
+ s.Attr |= sym.AttrLocal
+ ctxt.xdefine("runtime.egcbss", sym.SRODATA, Symaddr(s)+s.Size)
+ ctxt.Syms.Lookup("runtime.egcbss", 0).Sect = s.Sect
+
+ ctxt.xdefine("runtime.symtab", sym.SRODATA, int64(symtab.Vaddr))
+ ctxt.xdefine("runtime.esymtab", sym.SRODATA, int64(symtab.Vaddr+symtab.Length))
+ ctxt.xdefine("runtime.pclntab", sym.SRODATA, int64(pclntab.Vaddr))
+ ctxt.xdefine("runtime.epclntab", sym.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
+ ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr))
+ ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
+ ctxt.xdefine("runtime.bss", sym.SBSS, int64(bss.Vaddr))
+ ctxt.xdefine("runtime.ebss", sym.SBSS, int64(bss.Vaddr+bss.Length))
+ ctxt.xdefine("runtime.data", sym.SDATA, int64(data.Vaddr))
+ ctxt.xdefine("runtime.edata", sym.SDATA, int64(data.Vaddr+data.Length))
+ ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr))
+ ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
+ ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length))
}
// add a trampoline with symbol s (to be laid down after the current function)
-func (ctxt *Link) AddTramp(s *Symbol) {
- s.Type = STEXT
- s.Attr |= AttrReachable
- s.Attr |= AttrOnList
+func (ctxt *Link) AddTramp(s *sym.Symbol) {
+ s.Type = sym.STEXT
+ s.Attr |= sym.AttrReachable
+ s.Attr |= sym.AttrOnList
ctxt.tramps = append(ctxt.tramps, s)
if *FlagDebugTramp > 0 && ctxt.Debugvlog > 0 {
ctxt.Logf("trampoline %s inserted\n", s)
import (
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"fmt"
"strings"
"unicode"
// (When BuildmodeShared, always keep itablinks.)
for _, s := range ctxt.Syms.Allsym {
if strings.HasPrefix(s.Name, "go.itablink.") {
- s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
+ s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
}
}
}
// Remove dead text but keep file information (z symbols).
- textp := make([]*Symbol, 0, len(ctxt.Textp))
+ textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
for _, s := range ctxt.Textp {
if s.Attr.Reachable() {
textp = append(textp, s)
// the reflect.method struct: mtyp, ifn, and tfn.
type methodref struct {
m methodsig
- src *Symbol // receiver type symbol
- r [3]*Reloc // R_METHODOFF relocations to fields of runtime.method
+ src *sym.Symbol // receiver type symbol
+ r [3]*sym.Reloc // R_METHODOFF relocations to fields of runtime.method
}
-func (m methodref) ifn() *Symbol { return m.r[1].Sym }
+func (m methodref) ifn() *sym.Symbol { return m.r[1].Sym }
func (m methodref) isExported() bool {
for _, r := range m.m {
// deadcodepass holds state for the deadcode flood fill.
type deadcodepass struct {
ctxt *Link
- markQueue []*Symbol // symbols to flood fill in next pass
+ markQueue []*sym.Symbol // symbols to flood fill in next pass
ifaceMethod map[methodsig]bool // methods declared in reached interfaces
markableMethods []methodref // methods of reached types
reflectMethod bool
}
-func (d *deadcodepass) cleanupReloc(r *Reloc) {
+func (d *deadcodepass) cleanupReloc(r *sym.Reloc) {
if r.Sym.Attr.Reachable() {
r.Type = objabi.R_ADDROFF
} else {
}
// mark appends a symbol to the mark queue for flood filling.
-func (d *deadcodepass) mark(s, parent *Symbol) {
+func (d *deadcodepass) mark(s, parent *sym.Symbol) {
if s == nil || s.Attr.Reachable() {
return
}
}
fmt.Printf("%s -> %s\n", p, s.Name)
}
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrReachable
s.Reachparent = parent
d.markQueue = append(d.markQueue, s)
}
// Mark all symbols defined in this library as reachable when
// building a shared library.
for _, s := range d.ctxt.Syms.Allsym {
- if s.Type != 0 && s.Type != SDYNIMPORT {
+ if s.Type != 0 && s.Type != sym.SDYNIMPORT {
d.mark(s, nil)
}
}
for len(d.markQueue) > 0 {
s := d.markQueue[0]
d.markQueue = d.markQueue[1:]
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
if d.ctxt.Debugvlog > 1 {
d.ctxt.Logf("marktext %s\n", s.Name)
}
"bytes"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"debug/elf"
"fmt"
)
tflagExtraStar = 1 << 1
)
-func decodeReloc(s *Symbol, off int32) *Reloc {
+func decodeReloc(s *sym.Symbol, off int32) *sym.Reloc {
for i := range s.R {
if s.R[i].Off == off {
return &s.R[i]
return nil
}
-func decodeRelocSym(s *Symbol, off int32) *Symbol {
+func decodeRelocSym(s *sym.Symbol, off int32) *sym.Symbol {
r := decodeReloc(s, off)
if r == nil {
return nil
func uncommonSize() int { return 4 + 2 + 2 + 4 + 4 } // runtime.uncommontype
// Type.commonType.kind
-func decodetypeKind(arch *sys.Arch, s *Symbol) uint8 {
+func decodetypeKind(arch *sys.Arch, s *sym.Symbol) uint8 {
return s.P[2*arch.PtrSize+7] & objabi.KindMask // 0x13 / 0x1f
}
// Type.commonType.kind
-func decodetypeUsegcprog(arch *sys.Arch, s *Symbol) uint8 {
+func decodetypeUsegcprog(arch *sys.Arch, s *sym.Symbol) uint8 {
return s.P[2*arch.PtrSize+7] & objabi.KindGCProg // 0x13 / 0x1f
}
// Type.commonType.size
-func decodetypeSize(arch *sys.Arch, s *Symbol) int64 {
+func decodetypeSize(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P, arch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.ptrdata
-func decodetypePtrdata(arch *sys.Arch, s *Symbol) int64 {
+func decodetypePtrdata(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P[arch.PtrSize:], arch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.tflag
-func decodetypeHasUncommon(arch *sys.Arch, s *Symbol) bool {
+func decodetypeHasUncommon(arch *sys.Arch, s *sym.Symbol) bool {
return s.P[2*arch.PtrSize+4]&tflagUncommon != 0
}
}
// Type.commonType.gc
-func decodetypeGcprog(ctxt *Link, s *Symbol) []byte {
- if s.Type == SDYNIMPORT {
+func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
+ if s.Type == sym.SDYNIMPORT {
addr := decodetypeGcprogShlib(ctxt, s)
sect := findShlibSection(ctxt, s.File, addr)
if sect != nil {
return decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize)).P
}
-func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 {
+func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 {
if ctxt.Arch.Family == sys.ARM64 {
for _, shlib := range ctxt.Shlibs {
if shlib.Path == s.File {
return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
}
-func decodetypeGcmask(ctxt *Link, s *Symbol) []byte {
- if s.Type == SDYNIMPORT {
+func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
+ if s.Type == sym.SDYNIMPORT {
addr := decodetypeGcprogShlib(ctxt, s)
ptrdata := decodetypePtrdata(ctxt.Arch, s)
sect := findShlibSection(ctxt, s.File, addr)
}
// Type.ArrayType.elem and Type.SliceType.Elem
-func decodetypeArrayElem(arch *sys.Arch, s *Symbol) *Symbol {
+func decodetypeArrayElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
-func decodetypeArrayLen(arch *sys.Arch, s *Symbol) int64 {
+func decodetypeArrayLen(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
}
// Type.PtrType.elem
-func decodetypePtrElem(arch *sys.Arch, s *Symbol) *Symbol {
+func decodetypePtrElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
// Type.MapType.key, elem
-func decodetypeMapKey(arch *sys.Arch, s *Symbol) *Symbol {
+func decodetypeMapKey(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
-func decodetypeMapValue(arch *sys.Arch, s *Symbol) *Symbol {
+func decodetypeMapValue(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
}
// Type.ChanType.elem
-func decodetypeChanElem(arch *sys.Arch, s *Symbol) *Symbol {
+func decodetypeChanElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
// Type.FuncType.dotdotdot
-func decodetypeFuncDotdotdot(arch *sys.Arch, s *Symbol) bool {
+func decodetypeFuncDotdotdot(arch *sys.Arch, s *sym.Symbol) bool {
return uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2))&(1<<15) != 0
}
// Type.FuncType.inCount
-func decodetypeFuncInCount(arch *sys.Arch, s *Symbol) int {
+func decodetypeFuncInCount(arch *sys.Arch, s *sym.Symbol) int {
return int(decodeInuxi(arch, s.P[commonsize(arch):], 2))
}
-func decodetypeFuncOutCount(arch *sys.Arch, s *Symbol) int {
+func decodetypeFuncOutCount(arch *sys.Arch, s *sym.Symbol) int {
return int(uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2)) & (1<<15 - 1))
}
-func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol {
+func decodetypeFuncInType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
uadd := commonsize(arch) + 4
if arch.PtrSize == 8 {
uadd += 4
return decodeRelocSym(s, int32(uadd+i*arch.PtrSize))
}
-func decodetypeFuncOutType(arch *sys.Arch, s *Symbol, i int) *Symbol {
+func decodetypeFuncOutType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
return decodetypeFuncInType(arch, s, i+decodetypeFuncInCount(arch, s))
}
// Type.StructType.fields.Slice::length
-func decodetypeStructFieldCount(arch *sys.Arch, s *Symbol) int {
+func decodetypeStructFieldCount(arch *sys.Arch, s *sym.Symbol) int {
return int(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
}
-func decodetypeStructFieldArrayOff(arch *sys.Arch, s *Symbol, i int) int {
+func decodetypeStructFieldArrayOff(arch *sys.Arch, s *sym.Symbol, i int) int {
off := commonsize(arch) + 4*arch.PtrSize
if decodetypeHasUncommon(arch, s) {
off += uncommonSize()
}
// decodetypeStr returns the contents of an rtype's str field (a nameOff).
-func decodetypeStr(arch *sys.Arch, s *Symbol) string {
+func decodetypeStr(arch *sys.Arch, s *sym.Symbol) string {
str := decodetypeName(s, 4*arch.PtrSize+8)
if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 {
return str[1:]
}
// decodetypeName decodes the name from a reflect.name.
-func decodetypeName(s *Symbol, off int) string {
+func decodetypeName(s *sym.Symbol, off int) string {
r := decodeReloc(s, int32(off))
if r == nil {
return ""
return string(data[3 : 3+namelen])
}
-func decodetypeStructFieldName(arch *sys.Arch, s *Symbol, i int) string {
+func decodetypeStructFieldName(arch *sys.Arch, s *sym.Symbol, i int) string {
off := decodetypeStructFieldArrayOff(arch, s, i)
return decodetypeName(s, off)
}
-func decodetypeStructFieldType(arch *sys.Arch, s *Symbol, i int) *Symbol {
+func decodetypeStructFieldType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
off := decodetypeStructFieldArrayOff(arch, s, i)
return decodeRelocSym(s, int32(off+arch.PtrSize))
}
-func decodetypeStructFieldOffs(arch *sys.Arch, s *Symbol, i int) int64 {
+func decodetypeStructFieldOffs(arch *sys.Arch, s *sym.Symbol, i int) int64 {
return decodetypeStructFieldOffsAnon(arch, s, i) >> 1
}
-func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *Symbol, i int) int64 {
+func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *sym.Symbol, i int) int64 {
off := decodetypeStructFieldArrayOff(arch, s, i)
return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize))
}
// InterfaceType.methods.length
-func decodetypeIfaceMethodCount(arch *sys.Arch, s *Symbol) int64 {
+func decodetypeIfaceMethodCount(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
}
// the function type.
//
// Conveniently this is the layout of both runtime.method and runtime.imethod.
-func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsig {
+func decodeMethodSig(arch *sys.Arch, s *sym.Symbol, off, size, count int) []methodsig {
var buf bytes.Buffer
var methods []methodsig
for i := 0; i < count; i++ {
return methods
}
-func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig {
+func decodeIfaceMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
if decodetypeKind(arch, s)&kindMask != kindInterface {
panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
}
return decodeMethodSig(arch, s, off, sizeofIMethod, numMethods)
}
-func decodetypeMethods(arch *sys.Arch, s *Symbol) []methodsig {
+func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
if !decodetypeHasUncommon(arch, s) {
panic(fmt.Sprintf("no methods on %q", s.Name))
}
"cmd/internal/dwarf"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"fmt"
"log"
"os"
return c.linkctxt.Arch.PtrSize
}
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
- ls := s.(*Symbol)
- ls.addUintXX(c.linkctxt.Arch, uint64(i), size)
+ ls := s.(*sym.Symbol)
+ ls.AddUintXX(c.linkctxt.Arch, uint64(i), size)
}
func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
- ls := s.(*Symbol)
+ ls := s.(*sym.Symbol)
ls.AddBytes(b)
}
func (c dwctxt) AddString(s dwarf.Sym, v string) {
- Addstring(s.(*Symbol), v)
+ Addstring(s.(*sym.Symbol), v)
}
func (c dwctxt) SymValue(s dwarf.Sym) int64 {
- return s.(*Symbol).Value
+ return s.(*sym.Symbol).Value
}
func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
if value != 0 {
- value -= (data.(*Symbol)).Value
+ value -= (data.(*sym.Symbol)).Value
}
- s.(*Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*Symbol), value)
+ s.(*sym.Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value)
}
func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
- ls := s.(*Symbol)
+ ls := s.(*sym.Symbol)
switch size {
default:
Errorf(ls, "invalid size %d in adddwarfref\n", size)
fallthrough
case c.linkctxt.Arch.PtrSize:
- ls.AddAddr(c.linkctxt.Arch, t.(*Symbol))
+ ls.AddAddr(c.linkctxt.Arch, t.(*sym.Symbol))
case 4:
- ls.AddAddrPlus4(t.(*Symbol), 0)
+ ls.AddAddrPlus4(t.(*sym.Symbol), 0)
}
r := &ls.R[len(ls.R)-1]
r.Type = objabi.R_DWARFREF
var gdbscript string
-var dwarfp []*Symbol
+var dwarfp []*sym.Symbol
-func writeabbrev(ctxt *Link) *Symbol {
+func writeabbrev(ctxt *Link) *sym.Symbol {
s := ctxt.Syms.Lookup(".debug_abbrev", 0)
- s.Type = SDWARFSECT
+ s.Type = sym.SDWARFSECT
s.AddBytes(dwarf.GetAbbrev())
return s
}
if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) {
if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 {
- sym := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
- sym.Attr |= AttrNotInSymbolTable
- sym.Type = SDWARFINFO
- die.Sym = sym
+ s := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
+ s.Attr |= sym.AttrNotInSymbolTable
+ s.Type = sym.SDWARFINFO
+ die.Sym = s
}
}
return die
}
-func walksymtypedef(ctxt *Link, s *Symbol) *Symbol {
+func walksymtypedef(ctxt *Link, s *sym.Symbol) *sym.Symbol {
if t := ctxt.Syms.ROLookup(s.Name+"..def", int(s.Version)); t != nil {
return t
}
// Used to avoid string allocation when looking up dwarf symbols
var prefixBuf = []byte(dwarf.InfoPrefix)
-func find(ctxt *Link, name string) *Symbol {
+func find(ctxt *Link, name string) *sym.Symbol {
n := append(prefixBuf, name...)
// The string allocation below is optimized away because it is only used in a map lookup.
s := ctxt.Syms.ROLookup(string(n), 0)
prefixBuf = n[:len(dwarf.InfoPrefix)]
- if s != nil && s.Type == SDWARFINFO {
+ if s != nil && s.Type == sym.SDWARFINFO {
return s
}
return nil
}
-func mustFind(ctxt *Link, name string) *Symbol {
+func mustFind(ctxt *Link, name string) *sym.Symbol {
r := find(ctxt, name)
if r == nil {
Exitf("dwarf find: cannot find %s", name)
return r
}
-func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 {
+func adddwarfref(ctxt *Link, s *sym.Symbol, t *sym.Symbol, size int) int64 {
var result int64
switch size {
default:
return result
}
-func newrefattr(die *dwarf.DWDie, attr uint16, ref *Symbol) *dwarf.DWAttr {
+func newrefattr(die *dwarf.DWDie, attr uint16, ref *sym.Symbol) *dwarf.DWAttr {
if ref == nil {
return nil
}
return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
}
-func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
+func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
for ; die != nil; die = die.Link {
syms = putdie(linkctxt, ctxt, syms, die)
}
return syms
}
-func dtolsym(s dwarf.Sym) *Symbol {
+func dtolsym(s dwarf.Sym) *sym.Symbol {
if s == nil {
return nil
}
- return s.(*Symbol)
+ return s.(*sym.Symbol)
}
-func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
+func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*sym.Symbol, die *dwarf.DWDie) []*sym.Symbol {
s := dtolsym(die.Sym)
if s == nil {
s = syms[len(syms)-1]
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
syms = append(syms, s)
}
dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
// GDB doesn't like FORM_addr for AT_location, so emit a
// location expression that evals to a const.
-func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *Symbol) {
+func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *sym.Symbol) {
newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, sym)
// below
}
// Lookup predefined types
-func lookupOrDiag(ctxt *Link, n string) *Symbol {
+func lookupOrDiag(ctxt *Link, n string) *sym.Symbol {
s := ctxt.Syms.ROLookup(n, 0)
if s == nil || s.Size == 0 {
Exitf("dwarf: missing type: %s", n)
Errorf(nil, "dwarf: bad def in dotypedef")
}
- sym := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
- sym.Attr |= AttrNotInSymbolTable
- sym.Type = SDWARFINFO
- def.Sym = sym
+ s := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
+ s.Attr |= sym.AttrNotInSymbolTable
+ s.Type = sym.SDWARFINFO
+ def.Sym = s
// The typedef entry must be created after the def,
// so that future lookups will find the typedef instead
// circular definition loops, so that gdb can understand them.
die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0)
- newrefattr(die, dwarf.DW_AT_type, sym)
+ newrefattr(die, dwarf.DW_AT_type, s)
}
// Define gotype, for composite ones recurse into constituents.
-func defgotype(ctxt *Link, gotype *Symbol) *Symbol {
+func defgotype(ctxt *Link, gotype *sym.Symbol) *sym.Symbol {
if gotype == nil {
return mustFind(ctxt, "<unspecified>")
}
return sdie
}
- return newtype(ctxt, gotype).Sym.(*Symbol)
+ return newtype(ctxt, gotype).Sym.(*sym.Symbol)
}
-func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
+func newtype(ctxt *Link, gotype *sym.Symbol) *dwarf.DWDie {
name := gotype.Name[5:] // could also decode from Type.string
kind := decodetypeKind(ctxt.Arch, gotype)
bytesize := decodetypeSize(ctxt.Arch, gotype)
newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "void"))
nfields := decodetypeFuncInCount(ctxt.Arch, gotype)
var fld *dwarf.DWDie
- var s *Symbol
+ var s *sym.Symbol
for i := 0; i < nfields; i++ {
s = decodetypeFuncInType(ctxt.Arch, gotype, i)
fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
dotypedef(ctxt, &dwtypes, name, die)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype))
- var s *Symbol
+ var s *sym.Symbol
if nfields == 0 {
s = lookupOrDiag(ctxt, "type.runtime.eface")
} else {
return die
}
-func nameFromDIESym(dwtype *Symbol) string {
+func nameFromDIESym(dwtype *sym.Symbol) string {
return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def")
}
// Find or construct *T given T.
-func defptrto(ctxt *Link, dwtype *Symbol) *Symbol {
+func defptrto(ctxt *Link, dwtype *sym.Symbol) *sym.Symbol {
ptrname := "*" + nameFromDIESym(dwtype)
die := find(ctxt, ptrname)
if die == nil {
// Search children (assumed to have TAG_member) for the one named
// field and set its AT_type to dwtype
-func substitutetype(structdie *dwarf.DWDie, field string, dwtype *Symbol) {
+func substitutetype(structdie *dwarf.DWDie, field string, dwtype *sym.Symbol) {
child := findchild(structdie, field)
if child == nil {
Exitf("dwarf substitutetype: %s does not have member %s",
continue
}
copychildren(ctxt, die, prototype)
- elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*Symbol)
+ elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*sym.Symbol)
substitutetype(die, "array", defptrto(ctxt, elem))
}
}
BucketSize = 8
)
-func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *Symbol {
+func mkinternaltype(ctxt *Link, abbrev int, typename, keyname, valname string, f func(*dwarf.DWDie)) *sym.Symbol {
name := mkinternaltypename(typename, keyname, valname)
symname := dwarf.InfoPrefix + name
s := ctxt.Syms.ROLookup(symname, 0)
- if s != nil && s.Type == SDWARFINFO {
+ if s != nil && s.Type == sym.SDWARFINFO {
return s
}
die := newdie(ctxt, &dwtypes, abbrev, name, 0)
if die.Abbrev != dwarf.DW_ABRV_MAPTYPE {
continue
}
- gotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
+ gotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
keytype := decodetypeMapKey(ctxt.Arch, gotype)
valtype := decodetypeMapValue(ctxt.Arch, gotype)
keysize, valsize := decodetypeSize(ctxt.Arch, keytype), decodetypeSize(ctxt.Arch, valtype)
if die.Abbrev != dwarf.DW_ABRV_CHANTYPE {
continue
}
- elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
+ elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
elemname := elemgotype.Name[5:]
elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
}
// For use with pass.c::genasmsym
-func defdwsymb(ctxt *Link, sym *Symbol, s string, t SymbolType, v int64, gotype *Symbol) {
- if strings.HasPrefix(s, "go.string.") {
+func defdwsymb(ctxt *Link, s *sym.Symbol, str string, t SymbolType, v int64, gotype *sym.Symbol) {
+ if strings.HasPrefix(str, "go.string.") {
return
}
- if strings.HasPrefix(s, "runtime.gcbits.") {
+ if strings.HasPrefix(str, "runtime.gcbits.") {
return
}
- if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
- defgotype(ctxt, sym)
+ if strings.HasPrefix(str, "type.") && str != "type.*" && !strings.HasPrefix(str, "type..") {
+ defgotype(ctxt, s)
return
}
var dv *dwarf.DWDie
- var dt *Symbol
+ var dt *sym.Symbol
switch t {
default:
return
case DataSym, BSSSym:
- dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, s, int(sym.Version))
- newabslocexprattr(dv, v, sym)
- if sym.Version == 0 {
+ dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, str, int(s.Version))
+ newabslocexprattr(dv, v, s)
+ if s.Version == 0 {
newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
}
fallthrough
}
// If the pcln table contains runtime/proc.go, use that to set gdbscript path.
-func finddebugruntimepath(s *Symbol) {
+func finddebugruntimepath(s *sym.Symbol) {
if gdbscript != "" {
return
}
OPCODE_BASE = 10
)
-func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *Symbol, deltaPC uint64, deltaLC int64) {
+func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *sym.Symbol, deltaPC uint64, deltaLC int64) {
// Choose a special opcode that minimizes the number of bytes needed to
// encode the remaining PC delta and LC delta.
var opcode int64
return "/"
}
-func importInfoSymbol(ctxt *Link, dsym *Symbol) {
- dsym.Attr |= AttrNotInSymbolTable | AttrReachable
- dsym.Type = SDWARFINFO
+func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) {
+ dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable
+ dsym.Type = sym.SDWARFINFO
for _, r := range dsym.R {
if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 {
if Buildmode == BuildmodeShared {
}
}
-func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
+func writelines(ctxt *Link, syms []*sym.Symbol) ([]*sym.Symbol, []*sym.Symbol) {
var dwarfctxt dwarf.Context = dwctxt{ctxt}
ls := ctxt.Syms.Lookup(".debug_line", 0)
- ls.Type = SDWARFSECT
+ ls.Type = sym.SDWARFSECT
ls.R = ls.R[:0]
syms = append(syms, ls)
- var funcs []*Symbol
+ var funcs []*sym.Symbol
unitstart := int64(-1)
headerstart := int64(-1)
headerend := int64(-1)
epc := int64(0)
- var epcs *Symbol
+ var epcs *sym.Symbol
var dwinfo *dwarf.DWDie
lang := dwarf.DW_LANG_Go
return b
}
-func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
+func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
var dwarfctxt dwarf.Context = dwctxt{ctxt}
fs := ctxt.Syms.Lookup(".debug_frame", 0)
- fs.Type = SDWARFSECT
+ fs.Type = sym.SDWARFSECT
fs.R = fs.R[:0]
syms = append(syms, fs)
fs.AddUint32(ctxt.Arch, 0) // CIE offset
}
fs.AddAddr(ctxt.Arch, s)
- fs.addUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
+ fs.AddUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
fs.AddBytes(deltaBuf)
}
return syms
}
-func writeranges(ctxt *Link, syms []*Symbol) []*Symbol {
+func writeranges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
empty := true
for _, s := range ctxt.Textp {
rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
if rangeSym.Size == 0 {
continue
}
- rangeSym.Attr |= AttrReachable | AttrNotInSymbolTable
- rangeSym.Type = SDWARFRANGE
+ rangeSym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
+ rangeSym.Type = sym.SDWARFRANGE
syms = append(syms, rangeSym)
empty = false
}
if !empty {
// PE does not like empty sections
rangesec := ctxt.Syms.Lookup(".debug_ranges", 0)
- rangesec.Type = SDWARFRANGE
- rangesec.Attr |= AttrReachable
+ rangesec.Type = sym.SDWARFRANGE
+ rangesec.Attr |= sym.AttrReachable
rangesec.R = rangesec.R[:0]
syms = append(syms, rangesec)
COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
)
-func writeinfo(ctxt *Link, syms []*Symbol, funcs, consts []*Symbol, abbrevsym *Symbol) []*Symbol {
+func writeinfo(ctxt *Link, syms []*sym.Symbol, funcs, consts []*sym.Symbol, abbrevsym *sym.Symbol) []*sym.Symbol {
infosec := ctxt.Syms.Lookup(".debug_info", 0)
infosec.R = infosec.R[:0]
- infosec.Type = SDWARFINFO
- infosec.Attr |= AttrReachable
+ infosec.Type = sym.SDWARFINFO
+ infosec.Attr |= sym.AttrReachable
syms = append(syms, infosec)
arangessec := ctxt.Syms.Lookup(".dwarfaranges", 0)
dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
- cu := []*Symbol{s}
+ cu := []*sym.Symbol{s}
if funcs != nil {
cu = append(cu, funcs...)
funcs = nil
return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
}
-func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Symbol {
+func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*sym.Symbol) []*sym.Symbol {
s := ctxt.Syms.Lookup(sname, 0)
- s.Type = SDWARFSECT
+ s.Type = sym.SDWARFSECT
syms = append(syms, s)
for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link {
* emit .debug_aranges. _info must have been written before,
* because we need die->offs of dwarf.DW_globals.
*/
-func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
+func writearanges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
s := ctxt.Syms.Lookup(".debug_aranges", 0)
- s.Type = SDWARFSECT
+ s.Type = sym.SDWARFSECT
// The first tuple is aligned to a multiple of the size of a single tuple
// (twice the size of an address)
headersize := int(Rnd(4+2+4+1+1, int64(ctxt.Arch.PtrSize*2))) // don't count unit_length field itself
s.AddUint8(0)
}
- s.AddAddrPlus(ctxt.Arch, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
- s.addUintXX(ctxt.Arch, uint64(e.Value-b.Value), ctxt.Arch.PtrSize)
- s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
- s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
+ s.AddAddrPlus(ctxt.Arch, b.Data.(*sym.Symbol), b.Value-(b.Data.(*sym.Symbol)).Value)
+ s.AddUintXX(ctxt.Arch, uint64(e.Value-b.Value), ctxt.Arch.PtrSize)
+ s.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
+ s.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
}
if s.Size > 0 {
syms = append(syms, s)
return syms
}
-func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol {
+func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
if Linkmode == LinkExternal && Headtype == objabi.Hwindows && Buildmode == BuildmodeCArchive {
// gcc on Windows places .debug_gdb_scripts in the wrong location, which
// causes the program not to run. See https://golang.org/issue/20183
if gdbscript != "" {
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
- s.Type = SDWARFSECT
+ s.Type = sym.SDWARFSECT
syms = append(syms, s)
s.AddUint8(1) // magic 1 byte?
Addstring(s, gdbscript)
genasmsym(ctxt, defdwsymb)
- var consts []*Symbol
+ var consts []*sym.Symbol
for _, lib := range ctxt.Library {
if s := ctxt.Syms.Lookup(dwarf.ConstInfoPrefix+lib.Pkg, 0); s != nil {
importInfoSymbol(ctxt, s)
}
abbrev := writeabbrev(ctxt)
- syms := []*Symbol{abbrev}
+ syms := []*sym.Symbol{abbrev}
syms, funcs := writelines(ctxt, syms)
syms = writeframes(ctxt, syms)
movetomodule(&dwtypes)
movetomodule(&dwglobals)
- // Need to reorder symbols so SDWARFINFO is after all SDWARFSECT
+ // Need to reorder symbols so sym.SDWARFINFO is after all sym.SDWARFSECT
// (but we need to generate dies before writepub)
infosyms := writeinfo(ctxt, nil, funcs, consts, abbrev)
dwarfp = syms
}
-func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
+func collectlocs(ctxt *Link, syms []*sym.Symbol, funcs []*sym.Symbol) []*sym.Symbol {
empty := true
for _, fn := range funcs {
for _, reloc := range fn.R {
if reloc.Type == objabi.R_DWARFREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) {
- reloc.Sym.Attr |= AttrReachable | AttrNotInSymbolTable
+ reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
syms = append(syms, reloc.Sym)
empty = false
// One location list entry per function, but many relocations to it. Don't duplicate.
if !empty {
locsym := ctxt.Syms.Lookup(".debug_loc", 0)
locsym.R = locsym.R[:0]
- locsym.Type = SDWARFLOC
- locsym.Attr |= AttrReachable
+ locsym.Type = sym.SDWARFLOC
+ locsym.Attr |= sym.AttrReachable
syms = append(syms, locsym)
}
return syms
/*
* Elf.
*/
-func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
+func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
if *FlagW { // disable dwarf
return
}
if Linkmode != LinkExternal {
return
}
- sym := ctxt.Syms.Lookup(".debug_info", 0)
- putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
- sym = ctxt.Syms.Lookup(".debug_abbrev", 0)
- putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
- sym = ctxt.Syms.Lookup(".debug_line", 0)
- putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
- sym = ctxt.Syms.Lookup(".debug_frame", 0)
- putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
- sym = ctxt.Syms.Lookup(".debug_loc", 0)
- if sym.Sect != nil {
- putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
- }
- sym = ctxt.Syms.Lookup(".debug_ranges", 0)
- if sym.Sect != nil {
- putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
+ s := ctxt.Syms.Lookup(".debug_info", 0)
+ putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+ s = ctxt.Syms.Lookup(".debug_abbrev", 0)
+ putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+ s = ctxt.Syms.Lookup(".debug_line", 0)
+ putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+ s = ctxt.Syms.Lookup(".debug_frame", 0)
+ putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+ s = ctxt.Syms.Lookup(".debug_loc", 0)
+ if s.Sect != nil {
+ putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
+ }
+ s = ctxt.Syms.Lookup(".debug_ranges", 0)
+ if s.Sect != nil {
+ putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
}
}
import (
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"crypto/sha1"
"encoding/binary"
"encoding/hex"
addralign uint64
entsize uint64
shnum int
- secsym *Symbol
+ secsym *sym.Symbol
}
/*
return uint32(ehdr.shnum) * ELF32SHDRSIZE
}
-func elfsetstring(s *Symbol, str string, off int) {
+func elfsetstring(s *sym.Symbol, str string, off int) {
if nelfstr >= len(elfstr) {
Errorf(s, "too many elf strings")
errorexit()
return h
}
-func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
+func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) {
if elf64 {
s.AddUint64(ctxt.Arch, uint64(tag))
s.AddUint64(ctxt.Arch, val)
}
}
-func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) {
+func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
Elfwritedynentsymplus(ctxt, s, tag, t, 0)
}
-func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
+func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) {
if elf64 {
s.AddUint64(ctxt.Arch, uint64(tag))
} else {
s.AddAddrPlus(ctxt.Arch, t, add)
}
-func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
+func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) {
if elf64 {
s.AddUint64(ctxt.Arch, uint64(tag))
} else {
nsym := Nelfsym
s := ctxt.Syms.Lookup(".hash", 0)
- s.Type = SELFROSECT
- s.Attr |= AttrReachable
+ s.Type = sym.SELFROSECT
+ s.Attr |= sym.AttrReachable
i := nsym
nbucket := 1
Elfwritedynent(ctxt, s, DT_NULL, 0)
}
-func elfphload(seg *Segment) *ElfPhdr {
+func elfphload(seg *sym.Segment) *ElfPhdr {
ph := newElfPhdr()
ph.type_ = PT_LOAD
if seg.Rwx&4 != 0 {
return ph
}
-func elfphrelro(seg *Segment) {
+func elfphrelro(seg *sym.Segment) {
ph := newElfPhdr()
ph.type_ = PT_GNU_RELRO
ph.vaddr = seg.Vaddr
return nil
}
-func elfshalloc(sect *Section) *ElfShdr {
+func elfshalloc(sect *sym.Section) *ElfShdr {
sh := elfshname(sect.Name)
sect.Elfsect = sh
return sh
}
-func elfshbits(sect *Section) *ElfShdr {
+func elfshbits(sect *sym.Section) *ElfShdr {
var sh *ElfShdr
if sect.Name == ".text" {
if sect.Elfsect == nil {
sect.Elfsect = elfshnamedup(sect.Name)
}
- sh = sect.Elfsect
+ sh = sect.Elfsect.(*ElfShdr)
} else {
sh = elfshalloc(sect)
}
return sh
}
-func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
+func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr {
// If main section is SHT_NOBITS, nothing to relocate.
// Also nothing to relocate in .shstrtab or notes.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
return nil
}
- if sect.Elfsect.type_ == SHT_NOTE {
+ if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
return nil
}
// its own .rela.text.
if sect.Name == ".text" {
- if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
+ if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
sh = elfshnamedup(elfRelType + sect.Name)
}
}
sh.entsize += uint64(arch.RegSize)
}
sh.link = uint32(elfshname(".symtab").shnum)
- sh.info = uint32(sect.Elfsect.shnum)
+ sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum)
sh.off = sect.Reloff
sh.size = sect.Rellen
sh.addralign = uint64(arch.RegSize)
return sh
}
-func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
+func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
// If main section is SHT_NOBITS, nothing to relocate.
// Also nothing to relocate in .shstrtab.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
}
eaddr := int32(sect.Vaddr + sect.Length)
- for _, sym := range syms {
- if !sym.Attr.Reachable() {
+ for _, s := range syms {
+ if !s.Attr.Reachable() {
continue
}
- if sym.Value >= int64(eaddr) {
+ if s.Value >= int64(eaddr) {
break
}
- for ri := 0; ri < len(sym.R); ri++ {
- r := &sym.R[ri]
+ for ri := 0; ri < len(s.R); ri++ {
+ r := &s.R[ri]
if r.Done {
continue
}
if r.Xsym == nil {
- Errorf(sym, "missing xsym in relocation %#v %#v", r.Sym.Name, sym)
+ Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s)
continue
}
if r.Xsym.ElfsymForReloc() == 0 {
- Errorf(sym, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type)
+ Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type)
}
if !r.Xsym.Attr.Reachable() {
- Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
+ Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
}
- if !Thearch.Elfreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
- Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
+ if !Thearch.Elfreloc1(ctxt, 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)
}
}
}
func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
s := ctxt.Syms.Lookup(sectionName, 0)
- s.Attr |= AttrReachable
- s.Type = SELFROSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFROSECT
// namesz
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
// descsz
/* predefine strings we need for section headers */
shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
- shstrtab.Type = SELFROSECT
- shstrtab.Attr |= AttrReachable
+ shstrtab.Type = sym.SELFROSECT
+ shstrtab.Attr |= sym.AttrReachable
Addstring(shstrtab, "")
Addstring(shstrtab, ".text")
/* dynamic symbol table - first entry all zeros */
s := ctxt.Syms.Lookup(".dynsym", 0)
- s.Type = SELFROSECT
- s.Attr |= AttrReachable
+ s.Type = sym.SELFROSECT
+ s.Attr |= sym.AttrReachable
if elf64 {
s.Size += ELF64SYMSIZE
} else {
/* dynamic string table */
s = ctxt.Syms.Lookup(".dynstr", 0)
- s.Type = SELFROSECT
- s.Attr |= AttrReachable
+ s.Type = sym.SELFROSECT
+ s.Attr |= sym.AttrReachable
if s.Size == 0 {
Addstring(s, "")
}
/* relocation table */
s = ctxt.Syms.Lookup(elfRelType, 0)
- s.Attr |= AttrReachable
- s.Type = SELFROSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFROSECT
/* global offset table */
s = ctxt.Syms.Lookup(".got", 0)
- s.Attr |= AttrReachable
- s.Type = SELFGOT // writable
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFGOT // writable
/* ppc64 glink resolver */
if ctxt.Arch.Family == sys.PPC64 {
s := ctxt.Syms.Lookup(".glink", 0)
- s.Attr |= AttrReachable
- s.Type = SELFRXSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFRXSECT
}
/* hash */
s = ctxt.Syms.Lookup(".hash", 0)
- s.Attr |= AttrReachable
- s.Type = SELFROSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFROSECT
s = ctxt.Syms.Lookup(".got.plt", 0)
- s.Attr |= AttrReachable
- s.Type = SELFSECT // writable
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFSECT // writable
s = ctxt.Syms.Lookup(".plt", 0)
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrReachable
if ctxt.Arch.Family == sys.PPC64 {
// In the ppc64 ABI, .plt is a data section
// written by the dynamic linker.
- s.Type = SELFSECT
+ s.Type = sym.SELFSECT
} else {
- s.Type = SELFRXSECT
+ s.Type = sym.SELFRXSECT
}
Thearch.Elfsetupplt(ctxt)
s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
- s.Attr |= AttrReachable
- s.Type = SELFROSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFROSECT
s = ctxt.Syms.Lookup(".gnu.version", 0)
- s.Attr |= AttrReachable
- s.Type = SELFROSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFROSECT
s = ctxt.Syms.Lookup(".gnu.version_r", 0)
- s.Attr |= AttrReachable
- s.Type = SELFROSECT
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFROSECT
/* define dynamic elf table */
s = ctxt.Syms.Lookup(".dynamic", 0)
- s.Attr |= AttrReachable
- s.Type = SELFSECT // writable
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SELFSECT // writable
/*
* .dynamic table
// 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 |= AttrLocal
- s.Type = SRODATA
- s.Attr |= AttrSpecial
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrLocal
+ s.Type = sym.SRODATA
+ s.Attr |= sym.AttrSpecial
+ s.Attr |= sym.AttrReachable
s.Size = int64(sha1.Size)
sort.Sort(byPkg(ctxt.Library))
}
// Do not write DT_NULL. elfdynhash will finish it.
-func shsym(sh *ElfShdr, s *Symbol) {
+func shsym(sh *ElfShdr, s *sym.Symbol) {
addr := Symaddr(s)
if sh.flags&SHF_ALLOC != 0 {
sh.addr = uint64(addr)
elfshreloc(ctxt.Arch, sect)
}
for _, s := range dwarfp {
- if len(s.R) > 0 || s.Type == SDWARFINFO || s.Type == SDWARFLOC {
+ if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC {
elfshreloc(ctxt.Arch, s.Sect)
}
}
}
}
-func elfadddynsym(ctxt *Link, s *Symbol) {
+func elfadddynsym(ctxt *Link, s *sym.Symbol) {
if elf64 {
s.Dynid = int32(Nelfsym)
Nelfsym++
/* type */
t := STB_GLOBAL << 4
- if s.Attr.CgoExport() && s.Type&SMASK == STEXT {
+ if s.Attr.CgoExport() && s.Type&sym.SMASK == sym.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT
d.AddUint8(0)
/* section where symbol is defined */
- if s.Type == SDYNIMPORT {
+ if s.Type == sym.SDYNIMPORT {
d.AddUint16(ctxt.Arch, SHN_UNDEF)
} else {
d.AddUint16(ctxt.Arch, 1)
}
/* value */
- if s.Type == SDYNIMPORT {
+ if s.Type == sym.SDYNIMPORT {
d.AddUint64(ctxt.Arch, 0)
} else {
d.AddAddr(ctxt.Arch, s)
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
/* value */
- if s.Type == SDYNIMPORT {
+ if s.Type == sym.SDYNIMPORT {
d.AddUint32(ctxt.Arch, 0)
} else {
d.AddAddr(ctxt.Arch, s)
t := STB_GLOBAL << 4
// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
- if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&SMASK == STEXT {
+ if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&sym.SMASK == sym.STEXT {
t |= STT_FUNC
- } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&SMASK == STEXT {
+ } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&sym.SMASK == sym.STEXT {
t |= STT_FUNC
} else {
t |= STT_OBJECT
d.AddUint8(0)
/* shndx */
- if s.Type == SDYNIMPORT {
+ if s.Type == sym.SDYNIMPORT {
d.AddUint16(ctxt.Arch, SHN_UNDEF)
} else {
d.AddUint16(ctxt.Arch, 1)
"bytes"
"cmd/internal/bio"
"cmd/internal/objabi"
+ "cmd/link/internal/sym"
"fmt"
"io"
"os"
var next string
var q string
var lib string
- var s *Symbol
+ var s *sym.Symbol
p0 := ""
for ; p != ""; p = next {
remote, q = remote[:i], remote[i+1:]
}
s = ctxt.Syms.Lookup(local, 0)
- if s.Type == 0 || s.Type == SXREF || s.Type == SHOSTOBJ {
+ if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
s.Dynimplib = lib
s.Extname = remote
s.Dynimpvers = q
- if s.Type != SHOSTOBJ {
- s.Type = SDYNIMPORT
+ if s.Type != sym.SHOSTOBJ {
+ s.Type = sym.SDYNIMPORT
}
havedynamic = 1
}
}
local := f[1]
s = ctxt.Syms.Lookup(local, 0)
- s.Type = SHOSTOBJ
+ s.Type = sym.SHOSTOBJ
s.Size = 0
continue
}
}
if f[0] == "cgo_export_static" {
- s.Attr |= AttrCgoExportStatic
+ s.Attr |= sym.AttrCgoExportStatic
} else {
- s.Attr |= AttrCgoExportDynamic
+ s.Attr |= sym.AttrCgoExportDynamic
}
continue
}
}
}
-func Adddynsym(ctxt *Link, s *Symbol) {
+func Adddynsym(ctxt *Link, s *sym.Symbol) {
if s.Dynid >= 0 || Linkmode == LinkExternal {
return
}
var buf bytes.Buffer
for _, s := range ctxt.Syms.Allsym {
if strings.HasPrefix(s.Name, "go.track.") {
- s.Attr |= AttrSpecial // do not lay out in data segment
- s.Attr |= AttrNotInSymbolTable
+ s.Attr |= sym.AttrSpecial // do not lay out in data segment
+ s.Attr |= sym.AttrNotInSymbolTable
if s.Attr.Reachable() {
buf.WriteString(s.Name[9:])
for p := s.Reachparent; p != nil; p = p.Reachparent {
buf.WriteString("\n")
}
- s.Type = SCONST
+ s.Type = sym.SCONST
s.Value = 0
}
}
return
}
addstrdata(ctxt, *flagFieldTrack, buf.String())
- s.Type = SDATA
+ s.Type = sym.SDATA
}
func (ctxt *Link) addexport() {
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
align uint64
entsize uint64
base []byte
- sym *Symbol
+ sym *sym.Symbol
}
type ElfObj struct {
type_ uint8
other uint8
shndx uint16
- sym *Symbol
+ sym *sym.Symbol
}
var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
return
case ElfSectFlagAlloc:
- s.Type = SRODATA
+ s.Type = sym.SRODATA
case ElfSectFlagAlloc + ElfSectFlagWrite:
if sect.type_ == ElfSectNobits {
- s.Type = SNOPTRBSS
+ s.Type = sym.SNOPTRBSS
} else {
- s.Type = SNOPTRDATA
+ s.Type = sym.SNOPTRDATA
}
case ElfSectFlagAlloc + ElfSectFlagExec:
- s.Type = STEXT
+ s.Type = sym.STEXT
}
if sect.name == ".got" || sect.name == ".toc" {
- s.Type = SELFGOT
+ s.Type = sym.SELFGOT
}
if sect.type_ == ElfSectProgbits {
s.P = sect.base
// enter sub-symbols into symbol table.
// symbol 0 is the null symbol.
- symbols := make([]*Symbol, elfobj.nsymtab)
+ symbols := make([]*sym.Symbol, elfobj.nsymtab)
for i := 1; i < elfobj.nsymtab; i++ {
- var sym ElfSym
- if err := readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
+ var elfsym ElfSym
+ if err := readelfsym(ctxt, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err)
return
}
- symbols[i] = sym.sym
- if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
+ symbols[i] = elfsym.sym
+ if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
continue
}
- if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
- s := sym.sym
- if uint64(s.Size) < sym.size {
- s.Size = int64(sym.size)
+ if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon {
+ s := elfsym.sym
+ if uint64(s.Size) < elfsym.size {
+ s.Size = int64(elfsym.size)
}
- if s.Type == 0 || s.Type == SXREF {
- s.Type = SNOPTRBSS
+ if s.Type == 0 || s.Type == sym.SXREF {
+ s.Type = sym.SNOPTRBSS
}
continue
}
- if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
+ if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
continue
}
// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
- if sym.sym == nil {
+ if elfsym.sym == nil {
continue
}
- sect = &elfobj.sect[sym.shndx]
+ sect = &elfobj.sect[elfsym.shndx]
if sect.sym == nil {
- if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this
+ if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this
continue
}
- if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" {
+ if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" {
// This reportedly happens with clang 3.7 on ARM.
// See issue 13139.
continue
}
- if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
+ if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
continue
}
- Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_)
+ Errorf(elfsym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, elfsym.shndx, elfsym.type_)
continue
}
- s := sym.sym
+ s := elfsym.sym
if s.Outer != nil {
if s.Attr.DuplicateOK() {
continue
s.Sub = sect.sym.Sub
sect.sym.Sub = s
- s.Type = sect.sym.Type | s.Type&^SMASK | SSUB
+ s.Type = sect.sym.Type | s.Type&^sym.SMASK | sym.SSUB
if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
}
- s.Value = int64(sym.value)
- s.Size = int64(sym.size)
+ s.Value = int64(elfsym.value)
+ s.Size = int64(elfsym.size)
s.Outer = sect.sym
- if sect.sym.Type == STEXT {
+ if sect.sym.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
Errorf(s, "%s: duplicate symbol definition", pn)
}
- s.Attr |= AttrExternal
+ s.Attr |= sym.AttrExternal
}
if elfobj.machine == ElfMachPower64 {
- flag := int(sym.other) >> 5
+ flag := int(elfsym.other) >> 5
if 2 <= flag && flag <= 6 {
s.Localentry = 1 << uint(flag-2)
} else if flag == 7 {
- Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other)
+ Errorf(s, "%s: invalid sym.other 0x%x", pn, elfsym.other)
}
}
}
if s.Sub != nil {
s.Sub = listsort(s.Sub)
}
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
for s = s.Sub; s != nil; s = s.Sub {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
}
}
rela = 1
}
n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
- r := make([]Reloc, n)
+ r := make([]sym.Reloc, n)
p := rsect.base
for j := 0; j < n; j++ {
var add uint64
if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
rp.Sym = nil
} else {
- var sym ElfSym
- if err := readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
+ var elfsym ElfSym
+ if err := readelfsym(ctxt, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err)
return
}
- sym.sym = symbols[info>>32]
- if sym.sym == nil {
- Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_)
+ elfsym.sym = symbols[info>>32]
+ if elfsym.sym == nil {
+ Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_)
return
}
- rp.Sym = sym.sym
+ rp.Sym = elfsym.sym
}
rp.Type = 256 + objabi.RelocType(info)
return nil
}
-func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) {
+func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
if i >= elfobj.nsymtab || i < 0 {
err = fmt.Errorf("invalid elf symbol index")
return err
if elfobj.is64 != 0 {
b := new(ElfSymBytes64)
binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
- sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
- sym.value = elfobj.e.Uint64(b.Value[:])
- sym.size = elfobj.e.Uint64(b.Size[:])
- sym.shndx = elfobj.e.Uint16(b.Shndx[:])
- sym.bind = b.Info >> 4
- sym.type_ = b.Info & 0xf
- sym.other = b.Other
+ elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
+ elfsym.value = elfobj.e.Uint64(b.Value[:])
+ elfsym.size = elfobj.e.Uint64(b.Size[:])
+ elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
+ elfsym.bind = b.Info >> 4
+ elfsym.type_ = b.Info & 0xf
+ elfsym.other = b.Other
} else {
b := new(ElfSymBytes)
binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
- sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
- sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
- sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
- sym.shndx = elfobj.e.Uint16(b.Shndx[:])
- sym.bind = b.Info >> 4
- sym.type_ = b.Info & 0xf
- sym.other = b.Other
+ elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
+ elfsym.value = uint64(elfobj.e.Uint32(b.Value[:]))
+ elfsym.size = uint64(elfobj.e.Uint32(b.Size[:]))
+ elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
+ elfsym.bind = b.Info >> 4
+ elfsym.type_ = b.Info & 0xf
+ elfsym.other = b.Other
}
- var s *Symbol
- if sym.name == "_GLOBAL_OFFSET_TABLE_" {
- sym.name = ".got"
+ var s *sym.Symbol
+ if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
+ elfsym.name = ".got"
}
- if sym.name == ".TOC." {
+ if elfsym.name == ".TOC." {
// Magic symbol on ppc64. Will be set to this object
// file's .got+0x8000.
- sym.bind = ElfSymBindLocal
+ elfsym.bind = ElfSymBindLocal
}
- switch sym.type_ {
+ switch elfsym.type_ {
case ElfSymTypeSection:
- s = elfobj.sect[sym.shndx].sym
+ s = elfobj.sect[elfsym.shndx].sym
case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
- switch sym.bind {
+ switch elfsym.bind {
case ElfSymBindGlobal:
if needSym != 0 {
- s = ctxt.Syms.Lookup(sym.name, 0)
+ s = ctxt.Syms.Lookup(elfsym.name, 0)
// for global scoped hidden symbols we should insert it into
// symbol hash table, but mark them as hidden.
// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
// set dupok generally. See http://codereview.appspot.com/5823055/
// comment #5 for details.
- if s != nil && sym.other == 2 {
- s.Type |= SHIDDEN
- s.Attr |= AttrDuplicateOK
+ if s != nil && elfsym.other == 2 {
+ s.Type |= sym.SHIDDEN
+ s.Attr |= sym.AttrDuplicateOK
}
}
case ElfSymBindLocal:
- if ctxt.Arch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) {
+ if ctxt.Arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) {
// binutils for arm generate these mapping
// symbols, ignore these
break
}
- if sym.name == ".TOC." {
+ if elfsym.name == ".TOC." {
// We need to be able to look this up,
// so put it in the hash table.
if needSym != 0 {
- s = ctxt.Syms.Lookup(sym.name, localSymVersion)
- s.Type |= SHIDDEN
+ s = ctxt.Syms.Lookup(elfsym.name, localSymVersion)
+ s.Type |= sym.SHIDDEN
}
break
// local names and hidden global names are unique
// and should only be referenced by their index, not name, so we
// don't bother to add them into the hash table
- s = ctxt.Syms.newsym(sym.name, localSymVersion)
+ s = ctxt.Syms.Newsym(elfsym.name, localSymVersion)
- s.Type |= SHIDDEN
+ s.Type |= sym.SHIDDEN
}
case ElfSymBindWeak:
if needSym != 0 {
- s = ctxt.Syms.Lookup(sym.name, 0)
- if sym.other == 2 {
- s.Type |= SHIDDEN
+ s = ctxt.Syms.Lookup(elfsym.name, 0)
+ if elfsym.other == 2 {
+ s.Type |= sym.SHIDDEN
}
}
default:
- err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind)
+ err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind)
return err
}
}
- if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
- s.Type = SXREF
+ if s != nil && s.Type == 0 && elfsym.type_ != ElfSymTypeSection {
+ s.Type = sym.SXREF
}
- sym.sym = s
+ elfsym.sym = s
return nil
}
-type rbyoff []Reloc
+type rbyoff []sym.Reloc
func (x rbyoff) Len() int {
return len(x)
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
flags uint32
res1 uint32
res2 uint32
- sym *Symbol
+ sym *sym.Symbol
rel []ldMachoRel
}
desc uint16
kind int8
value uint64
- sym *Symbol
+ sym *sym.Symbol
}
type ldMachoDysymtab struct {
var sect *ldMachoSect
var rel *ldMachoRel
var rpi int
- var s *Symbol
- var s1 *Symbol
- var outer *Symbol
+ var s *sym.Symbol
+ var s1 *sym.Symbol
+ var outer *sym.Symbol
var c *ldMachoCmd
var symtab *ldMachoSymtab
var dsymtab *ldMachoDysymtab
- var sym *ldMachoSym
- var r []Reloc
- var rp *Reloc
+ var r []sym.Reloc
+ var rp *sym.Reloc
var name string
localSymVersion := ctxt.Syms.IncVersion()
if sect.segname == "__TEXT" {
if sect.name == "__text" {
- s.Type = STEXT
+ s.Type = sym.STEXT
} else {
- s.Type = SRODATA
+ s.Type = sym.SRODATA
}
} else {
if sect.name == "__bss" {
- s.Type = SNOPTRBSS
+ s.Type = sym.SNOPTRBSS
s.P = s.P[:0]
} else {
- s.Type = SNOPTRDATA
+ s.Type = sym.SNOPTRDATA
}
}
// enter sub-symbols into symbol table.
// have to guess sizes from next symbol.
for i := 0; uint32(i) < symtab.nsym; i++ {
- sym = &symtab.sym[i]
- if sym.type_&N_STAB != 0 {
+ machsym := &symtab.sym[i]
+ if machsym.type_&N_STAB != 0 {
continue
}
// TODO: check sym->type against outer->type.
- name = sym.name
+ name = machsym.name
if name[0] == '_' && name[1] != '\x00' {
name = name[1:]
}
v := 0
- if sym.type_&N_EXT == 0 {
+ if machsym.type_&N_EXT == 0 {
v = localSymVersion
}
s = ctxt.Syms.Lookup(name, v)
- if sym.type_&N_EXT == 0 {
- s.Attr |= AttrDuplicateOK
+ if machsym.type_&N_EXT == 0 {
+ s.Attr |= sym.AttrDuplicateOK
}
- sym.sym = s
- if sym.sectnum == 0 { // undefined
+ machsym.sym = s
+ if machsym.sectnum == 0 { // undefined
continue
}
- if uint32(sym.sectnum) > c.seg.nsect {
- err = fmt.Errorf("reference to invalid section %d", sym.sectnum)
+ if uint32(machsym.sectnum) > c.seg.nsect {
+ err = fmt.Errorf("reference to invalid section %d", machsym.sectnum)
goto bad
}
- sect = &c.seg.sect[sym.sectnum-1]
+ sect = &c.seg.sect[machsym.sectnum-1]
outer = sect.sym
if outer == nil {
err = fmt.Errorf("reference to invalid section %s/%s", sect.segname, sect.name)
Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
}
- s.Type = outer.Type | SSUB
+ s.Type = outer.Type | sym.SSUB
s.Sub = outer.Sub
outer.Sub = s
s.Outer = outer
- s.Value = int64(sym.value - sect.addr)
+ s.Value = int64(machsym.value - sect.addr)
if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
}
- if outer.Type == STEXT {
+ if outer.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
Errorf(s, "%s: duplicate symbol definition", pn)
}
- s.Attr |= AttrExternal
+ s.Attr |= sym.AttrExternal
}
- sym.sym = s
+ machsym.sym = s
}
// Sort outer lists by address, adding to textp.
}
}
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
if s1.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s1.Name)
}
- s1.Attr |= AttrOnList
+ s1.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s1)
}
}
if sect.rel == nil {
continue
}
- r = make([]Reloc, sect.nreloc)
+ r = make([]sym.Reloc, sect.nreloc)
rpi = 0
Reloc:
for j = 0; uint32(j) < sect.nreloc; j++ {
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"debug/pe"
"errors"
"fmt"
localSymVersion := ctxt.Syms.IncVersion()
- sectsyms := make(map[*pe.Section]*Symbol)
+ sectsyms := make(map[*pe.Section]*sym.Symbol)
sectdata := make(map[*pe.Section][]byte)
// Some input files are archives containing multiple of
switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
- s.Type = SRODATA
+ s.Type = sym.SRODATA
case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss
- s.Type = SNOPTRBSS
+ s.Type = sym.SNOPTRBSS
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data
- s.Type = SNOPTRDATA
+ s.Type = sym.SNOPTRDATA
case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text
- s.Type = STEXT
+ s.Type = sym.STEXT
default:
return fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)
}
- if s.Type != SNOPTRBSS {
+ if s.Type != sym.SNOPTRBSS {
data, err := sect.Data()
if err != nil {
return err
continue
}
- rs := make([]Reloc, rsect.NumberOfRelocations)
+ rs := make([]sym.Reloc, rsect.NumberOfRelocations)
for j, r := range rsect.Relocs {
rp := &rs[j]
if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
}
if pesym.SectionNumber == 0 { // extern
- if s.Type == SDYNIMPORT {
+ if s.Type == sym.SDYNIMPORT {
s.Plt = -2 // flag for dynimport in PE object files.
}
- if s.Type == SXREF && pesym.Value > 0 { // global data
- s.Type = SNOPTRDATA
+ if s.Type == sym.SXREF && pesym.Value > 0 { // global data
+ s.Type = sym.SNOPTRDATA
s.Size = int64(pesym.Value)
}
sectsym := sectsyms[sect]
s.Sub = sectsym.Sub
sectsym.Sub = s
- s.Type = sectsym.Type | SSUB
+ s.Type = sectsym.Type | sym.SSUB
s.Value = int64(pesym.Value)
s.Size = 4
s.Outer = sectsym
- if sectsym.Type == STEXT {
+ if sectsym.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
Errorf(s, "%s: duplicate symbol definition", pn)
}
- s.Attr |= AttrExternal
+ s.Attr |= sym.AttrExternal
}
}
if s.Sub != nil {
s.Sub = listsort(s.Sub)
}
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
for s = s.Sub; s != nil; s = s.Sub {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
}
}
return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
}
-func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Section]*Symbol, localSymVersion int) (*Symbol, error) {
- symname, err := sym.FullName(f.StringTable)
+func readpesym(ctxt *Link, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) {
+ symname, err := pesym.FullName(f.StringTable)
if err != nil {
return nil, err
}
var name string
- if issect(sym) {
- name = sectsyms[f.Sections[sym.SectionNumber-1]].Name
+ if issect(pesym) {
+ name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name
} else {
name = symname
if strings.HasPrefix(name, "__imp_") {
name = name[:i]
}
- var s *Symbol
- switch sym.Type {
+ var s *sym.Symbol
+ switch pesym.Type {
default:
- return nil, fmt.Errorf("%s: invalid symbol type %d", symname, sym.Type)
+ return nil, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)
case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
- switch sym.StorageClass {
+ switch pesym.StorageClass {
case IMAGE_SYM_CLASS_EXTERNAL: //global
s = ctxt.Syms.Lookup(name, 0)
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
s = ctxt.Syms.Lookup(name, localSymVersion)
- s.Attr |= AttrDuplicateOK
+ s.Attr |= sym.AttrDuplicateOK
default:
- return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, sym.StorageClass)
+ return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass)
}
}
- if s != nil && s.Type == 0 && (sym.StorageClass != IMAGE_SYM_CLASS_STATIC || sym.Value != 0) {
- s.Type = SXREF
+ if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
+ s.Type = sym.SXREF
}
if strings.HasPrefix(symname, "__imp_") {
s.Got = -2 // flag for __imp_
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"crypto/sha1"
"debug/elf"
"encoding/base64"
Openbsddynld string
Dragonflydynld string
Solarisdynld string
- Adddynrel func(*Link, *Symbol, *Reloc) bool
+ Adddynrel func(*Link, *sym.Symbol, *sym.Reloc) bool
Archinit func(*Link)
- Archreloc func(*Link, *Reloc, *Symbol, *int64) bool
- Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64
- Trampoline func(*Link, *Reloc, *Symbol)
+ Archreloc func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
+ Archrelocvariant func(*Link, *sym.Reloc, *sym.Symbol, int64) int64
+ Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
Asmb func(*Link)
- Elfreloc1 func(*Link, *Reloc, int64) bool
+ Elfreloc1 func(*Link, *sym.Reloc, int64) bool
Elfsetupplt func(*Link)
Gentext func(*Link)
- Machoreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool
- PEreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool
+ Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
+ PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
// TLSIEtoLE converts a TLS Initial Executable relocation to
// a TLS Local Executable relocation.
// This is possible when a TLS IE relocation refers to a local
// symbol in an executable, which is typical when internally
// linking PIE binaries.
- TLSIEtoLE func(s *Symbol, off, size int)
+ TLSIEtoLE func(s *sym.Symbol, off, size int)
}
var (
Symsize int32
)
-// Terrible but standard terminology.
-// A segment describes a block of file to load into memory.
-// A section further describes the pieces of that block for
-// use in debuggers and such.
-
const (
MINFUNC = 16 // minimum size for a function
)
-type Segment struct {
- Rwx uint8 // permission as usual unix bits (5 = r-x etc)
- Vaddr uint64 // virtual address
- Length uint64 // length in memory
- Fileoff uint64 // file offset
- Filelen uint64 // length on disk
- Sections []*Section
-}
-
-type Section struct {
- Rwx uint8
- Extnum int16
- Align int32
- Name string
- Vaddr uint64
- Length uint64
- Seg *Segment
- Elfsect *ElfShdr
- Reloff uint64
- Rellen uint64
-}
-
// DynlinkingGo returns whether we are producing Go code that can live
// in separate shared libraries linked together at runtime.
func (ctxt *Link) DynlinkingGo() bool {
}
var (
- dynexp []*Symbol
+ dynexp []*sym.Symbol
dynlib []string
ldflag []string
havedynamic int
)
var (
- Segtext Segment
- Segrodata Segment
- Segrelrodata Segment
- Segdata Segment
- Segdwarf Segment
+ Segtext sym.Segment
+ Segrodata sym.Segment
+ Segrelrodata sym.Segment
+ Segdata sym.Segment
+ Segdwarf sym.Segment
)
/* whence for ldpkg */
switch Buildmode {
case BuildmodeCShared, BuildmodePlugin:
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
- s.Attr |= AttrDuplicateOK
+ s.Attr |= sym.AttrDuplicateOK
s.AddUint8(1)
case BuildmodeCArchive:
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
- s.Attr |= AttrDuplicateOK
+ s.Attr |= sym.AttrDuplicateOK
s.AddUint8(1)
}
if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
toc := ctxt.Syms.Lookup(".TOC.", 0)
- toc.Type = SDYNIMPORT
+ toc.Type = sym.SDYNIMPORT
}
if Linkmode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
// Drop all the cgo_import_static declarations.
// Turns out we won't be needing them.
for _, s := range ctxt.Syms.Allsym {
- if s.Type == SHOSTOBJ {
+ if s.Type == sym.SHOSTOBJ {
// If a symbol was marked both
// cgo_import_static and cgo_import_dynamic,
// then we want to make it cgo_import_dynamic
// now.
if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
- s.Type = SDYNIMPORT
+ s.Type = sym.SDYNIMPORT
} else {
s.Type = 0
}
// runtime.tlsg is used for external linking on platforms that do not define
// a variable to hold g in assembly (currently only intel).
if tlsg.Type == 0 {
- tlsg.Type = STLSBSS
+ tlsg.Type = sym.STLSBSS
tlsg.Size = int64(ctxt.Arch.PtrSize)
- } else if tlsg.Type != SDYNIMPORT {
+ } else if tlsg.Type != sym.SDYNIMPORT {
Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
}
- tlsg.Attr |= AttrReachable
+ tlsg.Attr |= sym.AttrReachable
ctxt.Tlsg = tlsg
- var moduledata *Symbol
+ var moduledata *sym.Symbol
if Buildmode == BuildmodePlugin {
moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
- moduledata.Attr |= AttrLocal
+ moduledata.Attr |= sym.AttrLocal
} else {
moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
}
- if moduledata.Type != 0 && moduledata.Type != SDYNIMPORT {
+ if moduledata.Type != 0 && moduledata.Type != sym.SDYNIMPORT {
// If the module (toolchain-speak for "executable or shared
// library") we are linking contains the runtime package, it
// will define the runtime.firstmoduledata symbol and we
// recording the value of GOARM.
if ctxt.Arch.Family == sys.ARM {
s := ctxt.Syms.Lookup("runtime.goarm", 0)
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Size = 0
s.AddUint8(uint8(objabi.GOARM))
}
if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Size = 0
s.AddUint8(1)
}
// If OTOH the module does not contain the runtime package,
// create a local symbol for the moduledata.
moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
- moduledata.Attr |= AttrLocal
+ moduledata.Attr |= sym.AttrLocal
}
// In all cases way we mark the moduledata as noptrdata to hide it from
// the GC.
- moduledata.Type = SNOPTRDATA
- moduledata.Attr |= AttrReachable
+ moduledata.Type = sym.SNOPTRDATA
+ moduledata.Attr |= sym.AttrReachable
ctxt.Moduledata = moduledata
// Now that we know the link mode, trim the dynexp list.
- x := AttrCgoExportDynamic
+ x := sym.AttrCgoExportDynamic
if Linkmode == LinkExternal {
- x = AttrCgoExportStatic
+ x = sym.AttrCgoExportStatic
}
w := 0
for i := 0; i < len(dynexp); i++ {
any := false
for _, s := range ctxt.Syms.Allsym {
for _, r := range s.R {
- if r.Sym != nil && r.Sym.Type&SMASK == SXREF && r.Sym.Name != ".got" {
+ if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF && r.Sym.Name != ".got" {
any = true
break
}
if ctxt.Arch == sys.Arch386 {
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
- got.Type = SDYNIMPORT
- got.Attr |= AttrReachable
+ got.Type = sym.SDYNIMPORT
+ got.Attr |= sym.AttrReachable
}
}
for _, s := range lib.dupTextSyms {
if !s.Attr.OnList() {
ctxt.Textp = append(ctxt.Textp, s)
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
// dupok symbols may be defined in multiple packages. its
// associated package is chosen sort of arbitrarily (the
// first containing package that the linker loads). canonicalize
// We might have overwritten some functions above (this tends to happen for the
// autogenerated type equality/hashing functions) and we don't want to generated
// pcln table entries for these any more so remove them from Textp.
- textp := make([]*Symbol, 0, len(ctxt.Textp))
+ textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
for _, s := range ctxt.Textp {
- if s.Type != SDYNIMPORT {
+ if s.Type != sym.SDYNIMPORT {
textp = append(textp, s)
}
}
// packages. All Go binaries contain these symbols, but only only
// those programs loaded dynamically in multiple parts need these
// symbols to have entries in the symbol table.
-func typeSymbolMangling(syms *Symbols) bool {
+func typeSymbolMangling(syms *sym.Symbols) bool {
return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || syms.ROLookup("plugin.Open", 0) != nil
}
// typeSymbolMangle mangles the given symbol name into something shorter.
-func typeSymbolMangle(syms *Symbols, name string) string {
+func typeSymbolMangle(syms *sym.Symbols, name string) string {
if !typeSymbolMangling(syms) {
return name
}
// Do not let the host linker generate COPY relocations. These
// can move symbols out of sections that rely on stable offsets
- // from the beginning of the section (like STYPE).
+ // from the beginning of the section (like sym.STYPE).
argv = append(argv, "-Wl,-znocopyreloc")
if l.Arch.InFamily(sys.ARM, sys.ARM64) {
Errorf(nil, "cannot read symbols from shared library: %s", libpath)
return
}
- gcdataLocations := make(map[uint64]*Symbol)
+ gcdataLocations := make(map[uint64]*sym.Symbol)
for _, elfsym := range syms {
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
continue
// libraries, any non-dynimport symbols we find that duplicate symbols
// already loaded should be ignored (the symbols from the .a files
// "win").
- if lsym.Type != 0 && lsym.Type != SDYNIMPORT {
+ if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
continue
}
- lsym.Type = SDYNIMPORT
+ lsym.Type = sym.SDYNIMPORT
lsym.ElfType = elf.ST_TYPE(elfsym.Info)
lsym.Size = int64(elfsym.Size)
if elfsym.Section != elf.SHN_UNDEF {
}
}
}
- gcdataAddresses := make(map[*Symbol]uint64)
+ gcdataAddresses := make(map[*sym.Symbol]uint64)
if ctxt.Arch.Family == sys.ARM64 {
for _, sect := range f.Sections {
if sect.Type == elf.SHT_RELA {
ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdataAddresses: gcdataAddresses})
}
-func addsection(arch *sys.Arch, seg *Segment, name string, rwx int) *Section {
- sect := new(Section)
+func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
+ sect := new(sym.Section)
sect.Rwx = uint8(rwx)
sect.Name = name
sect.Seg = seg
}
type chain struct {
- sym *Symbol
+ sym *sym.Symbol
up *chain
limit int // limit on entry to sym
}
-var morestack *Symbol
+var morestack *sym.Symbol
// TODO: Record enough information in new object files to
// allow stack checks here.
if s.Attr.StackCheck() {
return 0
}
- s.Attr |= AttrStackCheck
+ s.Attr |= sym.AttrStackCheck
}
if depth > 100 {
// should never be called directly.
// onlyctxt.Diagnose the direct caller.
// TODO(mwhudson): actually think about this.
- if depth == 1 && s.Type != SXREF && !ctxt.DynlinkingGo() &&
+ if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
Errorf(s, "call to external function")
endr := len(s.R)
var ch1 chain
var pcsp Pciter
- var r *Reloc
+ var r *sym.Reloc
for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
AutoSym = 'a'
)
-func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *Symbol)) {
+func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int64, *sym.Symbol)) {
// These symbols won't show up in the first loop below because we
- // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
+ // skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
s := ctxt.Syms.Lookup("runtime.text", 0)
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
// We've already included this symbol in ctxt.Textp
// if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin.
// See data.go:/textaddress
if s == nil {
break
}
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
put(ctxt, s, s.Name, TextSym, s.Value, nil)
}
n++
}
s = ctxt.Syms.Lookup("runtime.etext", 0)
- if s.Type == STEXT {
+ if s.Type == sym.STEXT {
// We've already included this symbol in ctxt.Textp
// if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin.
// See data.go:/textaddress
if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
continue
}
- switch s.Type & SMASK {
- case SCONST,
- SRODATA,
- SSYMTAB,
- SPCLNTAB,
- SINITARR,
- SDATA,
- SNOPTRDATA,
- SELFROSECT,
- SMACHOGOT,
- STYPE,
- SSTRING,
- SGOSTRING,
- SGOFUNC,
- SGCBITS,
- STYPERELRO,
- SSTRINGRELRO,
- SGOSTRINGRELRO,
- SGOFUNCRELRO,
- SGCBITSRELRO,
- SRODATARELRO,
- STYPELINK,
- SITABLINK,
- SWINDOWS:
+ switch s.Type & sym.SMASK {
+ case sym.SCONST,
+ sym.SRODATA,
+ sym.SSYMTAB,
+ sym.SPCLNTAB,
+ sym.SINITARR,
+ sym.SDATA,
+ sym.SNOPTRDATA,
+ sym.SELFROSECT,
+ sym.SMACHOGOT,
+ sym.STYPE,
+ sym.SSTRING,
+ sym.SGOSTRING,
+ sym.SGOFUNC,
+ sym.SGCBITS,
+ sym.STYPERELRO,
+ sym.SSTRINGRELRO,
+ sym.SGOSTRINGRELRO,
+ sym.SGOFUNCRELRO,
+ sym.SGCBITSRELRO,
+ sym.SRODATARELRO,
+ sym.STYPELINK,
+ sym.SITABLINK,
+ sym.SWINDOWS:
if !s.Attr.Reachable() {
continue
}
put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
- case SBSS, SNOPTRBSS:
+ case sym.SBSS, sym.SNOPTRBSS:
if !s.Attr.Reachable() {
continue
}
}
put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
- case SHOSTOBJ:
+ case sym.SHOSTOBJ:
if Headtype == objabi.Hwindows || Iself {
put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
}
- case SDYNIMPORT:
+ case sym.SDYNIMPORT:
if !s.Attr.Reachable() {
continue
}
put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
- case STLSBSS:
+ case sym.STLSBSS:
if Linkmode == LinkExternal {
put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
}
}
}
-func Symaddr(s *Symbol) int64 {
+func Symaddr(s *sym.Symbol) int64 {
if !s.Attr.Reachable() {
Errorf(s, "unreachable symbol in symaddr")
}
return s.Value
}
-func (ctxt *Link) xdefine(p string, t SymKind, v int64) {
+func (ctxt *Link) xdefine(p string, t sym.SymKind, v int64) {
s := ctxt.Syms.Lookup(p, 0)
s.Type = t
s.Value = v
- s.Attr |= AttrReachable
- s.Attr |= AttrSpecial
- s.Attr |= AttrLocal
+ s.Attr |= sym.AttrReachable
+ s.Attr |= sym.AttrSpecial
+ s.Attr |= sym.AttrLocal
}
-func datoff(s *Symbol, addr int64) int64 {
+func datoff(s *sym.Symbol, addr int64) int64 {
if uint64(addr) >= Segdata.Vaddr {
return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
}
if s.Type == 0 {
return *FlagTextAddr
}
- if s.Type != STEXT {
+ if s.Type != sym.STEXT {
Errorf(s, "entry not text")
}
return s.Value
}
-func undefsym(ctxt *Link, s *Symbol) {
- var r *Reloc
+func undefsym(ctxt *Link, s *sym.Symbol) {
+ var r *sym.Reloc
for i := 0; i < len(s.R); i++ {
r = &s.R[i]
if r.Sym == nil { // happens for some external ARM relocs
continue
}
- if r.Sym.Type == Sxxx || r.Sym.Type == SXREF {
+ if r.Sym.Type == sym.Sxxx || r.Sym.Type == sym.SXREF {
Errorf(s, "undefined: %q", r.Sym.Name)
}
if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
}
var i int
- var r *Reloc
+ var r *sym.Reloc
for _, s := range ctxt.Textp {
for i = 0; i < len(s.R); i++ {
r = &s.R[i]
if r.Sym == nil {
continue
}
- if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == STEXT {
+ if (r.Type == objabi.R_CALL || r.Type == objabi.R_CALLARM || r.Type == objabi.R_CALLPOWER || r.Type == objabi.R_CALLMIPS) && r.Sym.Type == sym.STEXT {
ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
}
}
"bufio"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"debug/elf"
"fmt"
)
-// Attribute is a set of common symbol attributes.
-type Attribute int16
-
-const (
- // AttrDuplicateOK marks a symbol that can be present in multiple object
- // files.
- AttrDuplicateOK Attribute = 1 << iota
- // AttrExternal marks function symbols loaded from host object files.
- AttrExternal
- // AttrNoSplit marks functions that cannot split the stack; the linker
- // cares because it checks that there are no call chains of nosplit
- // functions that require more than StackLimit bytes (see
- // lib.go:dostkcheck)
- AttrNoSplit
- // AttrReachable marks symbols that are transitively referenced from the
- // entry points. Unreachable symbols are not written to the output.
- AttrReachable
- // AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
- // by directives written by cgo (in response to //export directives in
- // the source).
- AttrCgoExportDynamic
- AttrCgoExportStatic
- // AttrSpecial marks symbols that do not have their address (i.e. Value)
- // computed by the usual mechanism of data.go:dodata() &
- // data.go:address().
- AttrSpecial
- // AttrStackCheck is used by dostkcheck to only check each NoSplit
- // function's stack usage once.
- AttrStackCheck
- // AttrNotInSymbolTable marks symbols that are not written to the symbol table.
- AttrNotInSymbolTable
- // AttrOnList marks symbols that are on some list (such as the list of
- // all text symbols, or one of the lists of data symbols) and is
- // consulted to avoid bugs where a symbol is put on a list twice.
- AttrOnList
- // AttrLocal marks symbols that are only visible within the module
- // (executable or shared library) being linked. Only relevant when
- // dynamically linking Go code.
- AttrLocal
- // AttrReflectMethod marks certain methods from the reflect package that
- // can be used to call arbitrary methods. If no symbol with this bit set
- // is marked as reachable, more dead code elimination can be done.
- AttrReflectMethod
- // AttrMakeTypelink Amarks types that should be added to the typelink
- // table. See typelinks.go:typelinks().
- AttrMakeTypelink
- // AttrShared marks symbols compiled with the -shared option.
- AttrShared
- // 14 attributes defined so far.
-)
-
-func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
-func (a Attribute) External() bool { return a&AttrExternal != 0 }
-func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
-func (a Attribute) Reachable() bool { return a&AttrReachable != 0 }
-func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
-func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 }
-func (a Attribute) Special() bool { return a&AttrSpecial != 0 }
-func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 }
-func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
-func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
-func (a Attribute) Local() bool { return a&AttrLocal != 0 }
-func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
-func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
-func (a Attribute) Shared() bool { return a&AttrShared != 0 }
-
-func (a Attribute) CgoExport() bool {
- return a.CgoExportDynamic() || a.CgoExportStatic()
-}
-
-func (a *Attribute) Set(flag Attribute, value bool) {
- if value {
- *a |= flag
- } else {
- *a &^= flag
- }
-}
-
-// Reloc is a relocation.
-//
-// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
-// A Reloc is stored in a slice on the Symbol it rewrites.
-//
-// Relocations are generated by the compiler as the type
-// cmd/internal/obj.Reloc, which is encoded into the object file wire
-// format and decoded by the linker into this type. A separate type is
-// used to hold linker-specific state about the relocation.
-//
-// Some relocations are created by cmd/link.
-type Reloc struct {
- Off int32 // offset to rewrite
- Siz uint8 // number of bytes to rewrite, 1, 2, or 4
- Done bool // set to true when relocation is complete
- Variant RelocVariant // variation on Type
- Type objabi.RelocType // the relocation type
- Add int64 // addend
- Xadd int64 // addend passed to external linker
- Sym *Symbol // symbol the relocation addresses
- Xsym *Symbol // symbol passed to external linker
-}
-
-type Auto struct {
- Asym *Symbol
- Gotype *Symbol
- Aoffset int32
- Name int16
-}
-
type Shlib struct {
Path string
Hash []byte
Deps []string
File *elf.File
- gcdataAddresses map[*Symbol]uint64
+ gcdataAddresses map[*sym.Symbol]uint64
}
// Link holds the context for writing object code from a compiler
type Link struct {
Out *OutBuf
- Syms *Symbols
+ Syms *sym.Symbols
Arch *sys.Arch
Debugvlog int
Loaded bool // set after all inputs have been loaded as symbols
- Tlsg *Symbol
+ Tlsg *sym.Symbol
Libdir []string
Library []*Library
LibraryByPkg map[string]*Library
Shlibs []Shlib
Tlsoffset int
- Textp []*Symbol
- Filesyms []*Symbol
- Moduledata *Symbol
+ Textp []*sym.Symbol
+ Filesyms []*sym.Symbol
+ Moduledata *sym.Symbol
PackageFile map[string]string
PackageShlib map[string]string
- tramps []*Symbol // trampolines
+ tramps []*sym.Symbol // trampolines
}
// The smallest possible offset from the hardware stack pointer to a local
hash string
importStrings []string
imports []*Library
- textp []*Symbol // text symbols defined in this library
- dupTextSyms []*Symbol // dupok text symbols defined in this library
+ textp []*sym.Symbol // text symbols defined in this library
+ dupTextSyms []*sym.Symbol // dupok text symbols defined in this library
}
func (l Library) String() string {
l.importStrings = nil
}
-type FuncInfo struct {
- Args int32
- Locals int32
- Autom []Auto
- Pcsp Pcdata
- Pcfile Pcdata
- Pcline Pcdata
- Pcinline Pcdata
- Pcdata []Pcdata
- Funcdata []*Symbol
- Funcdataoff []int64
- File []*Symbol
- InlTree []InlinedCall
-}
-
-// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
-type InlinedCall struct {
- Parent int32 // index of parent in InlTree
- File *Symbol // file of the inlined call
- Line int32 // line number of the inlined call
- Func *Symbol // function that was inlined
-}
-
-type Pcdata struct {
- P []byte
-}
-
type Pciter struct {
- d Pcdata
+ d sym.Pcdata
p []byte
pc uint32
nextpc uint32
start int
done int
}
-
-// RelocVariant is a linker-internal variation on a relocation.
-type RelocVariant uint8
-
-const (
- RV_NONE RelocVariant = iota
- RV_POWER_LO
- RV_POWER_HI
- RV_POWER_HA
- RV_POWER_DS
-
- // RV_390_DBL is a s390x-specific relocation variant that indicates that
- // the value to be placed into the relocatable field should first be
- // divided by 2.
- RV_390_DBL
-
- RV_CHECK_OVERFLOW RelocVariant = 1 << 7
- RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1
-)
-
-func RelocName(arch *sys.Arch, r objabi.RelocType) string {
- // We didn't have some relocation types at Go1.4.
- // Uncomment code when we include those in bootstrap code.
-
- switch {
- case r >= 512: // Mach-O
- // nr := (r - 512)>>1
- // switch ctxt.Arch.Family {
- // case sys.AMD64:
- // return macho.RelocTypeX86_64(nr).String()
- // case sys.ARM:
- // return macho.RelocTypeARM(nr).String()
- // case sys.ARM64:
- // return macho.RelocTypeARM64(nr).String()
- // case sys.I386:
- // return macho.RelocTypeGeneric(nr).String()
- // default:
- // panic("unreachable")
- // }
- case r >= 256: // ELF
- nr := r - 256
- switch arch.Family {
- case sys.AMD64:
- return elf.R_X86_64(nr).String()
- case sys.ARM:
- return elf.R_ARM(nr).String()
- case sys.ARM64:
- return elf.R_AARCH64(nr).String()
- case sys.I386:
- return elf.R_386(nr).String()
- case sys.MIPS, sys.MIPS64:
- // return elf.R_MIPS(nr).String()
- case sys.PPC64:
- // return elf.R_PPC64(nr).String()
- case sys.S390X:
- // return elf.R_390(nr).String()
- default:
- panic("unreachable")
- }
- }
-
- return r.String()
-}
import (
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"sort"
"strings"
)
var nkind [NumSymKind]int
-var sortsym []*Symbol
+var sortsym []*sym.Symbol
var nsortsym int
// empirically, string table must begin with " \x00".
s := ctxt.Syms.Lookup(".machosymstr", 0)
- s.Type = SMACHOSYMSTR
- s.Attr |= AttrReachable
+ s.Type = sym.SMACHOSYMSTR
+ s.Attr |= sym.AttrReachable
s.AddUint8(' ')
s.AddUint8('\x00')
s = ctxt.Syms.Lookup(".machosymtab", 0)
- s.Type = SMACHOSYMTAB
- s.Attr |= AttrReachable
+ s.Type = sym.SMACHOSYMTAB
+ s.Attr |= sym.AttrReachable
if Linkmode != LinkExternal {
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
- s.Type = SMACHOPLT
- s.Attr |= AttrReachable
+ s.Type = sym.SMACHOPLT
+ s.Attr |= sym.AttrReachable
s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
- s.Type = SMACHOGOT
- s.Attr |= AttrReachable
+ s.Type = sym.SMACHOGOT
+ s.Attr |= sym.AttrReachable
s.Align = 4
s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
- s.Type = SMACHOINDIRECTPLT
- s.Attr |= AttrReachable
+ s.Type = sym.SMACHOINDIRECTPLT
+ s.Attr |= sym.AttrReachable
s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
- s.Type = SMACHOINDIRECTGOT
- s.Attr |= AttrReachable
+ s.Type = sym.SMACHOINDIRECTGOT
+ s.Attr |= sym.AttrReachable
}
}
dylib = append(dylib, lib)
}
-func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
+func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) {
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
var msect *MachoSect
}
}
-func symkind(s *Symbol) int {
- if s.Type == SDYNIMPORT {
+func symkind(s *sym.Symbol) int {
+ if s.Type == sym.SDYNIMPORT {
return SymKindUndef
}
if s.Attr.CgoExport() {
return SymKindLocal
}
-func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
+func addsym(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
if s == nil {
return
}
nsortsym++
}
-type machoscmp []*Symbol
+type machoscmp []*sym.Symbol
func (x machoscmp) Len() int {
return len(x)
func machogenasmsym(ctxt *Link) {
genasmsym(ctxt, addsym)
for _, s := range ctxt.Syms.Allsym {
- if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
+ if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
if s.Attr.Reachable() {
addsym(ctxt, s, "", DataSym, 0, nil)
}
// So we sort them here and pre-allocate dynid for them
// See https://golang.org/issue/4029
for i := 0; i < len(dynexp); i++ {
- dynexp[i].Attr |= AttrReachable
+ dynexp[i].Attr |= sym.AttrReachable
}
machogenasmsym(ctxt)
- sortsym = make([]*Symbol, nsortsym)
+ sortsym = make([]*sym.Symbol, nsortsym)
nsortsym = 0
machogenasmsym(ctxt)
sort.Sort(machoscmp(sortsym[:nsortsym]))
//
// When dynamically linking, all non-local variables and plugin-exported
// symbols need to be exported.
-func machoShouldExport(ctxt *Link, s *Symbol) bool {
+func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
if !ctxt.DynlinkingGo() || s.Attr.Local() {
return false
}
if strings.HasPrefix(s.Name, "go.link.pkghash") {
return true
}
- return s.Type >= SELFSECT // only writable sections
+ return s.Type >= sym.SELFSECT // only writable sections
}
func machosymtab(ctxt *Link) {
// replace "·" as ".", because DTrace cannot handle it.
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
- if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
+ if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
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
+ symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
} else {
if s.Attr.CgoExport() || export {
symtab.AddUint8(0x0f)
symtab.AddUint8(uint8(o.Sect.Extnum))
}
symtab.AddUint16(ctxt.Arch, 0) // desc
- symtab.addUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
+ symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
}
}
}
return Rnd(int64(size), int64(*FlagRound))
}
-func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
+func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
// If main section has no bits, nothing to relocate.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
return
}
eaddr := int32(sect.Vaddr + sect.Length)
- for _, sym := range syms {
- if !sym.Attr.Reachable() {
+ for _, s := range syms {
+ if !s.Attr.Reachable() {
continue
}
- if sym.Value >= int64(eaddr) {
+ if s.Value >= int64(eaddr) {
break
}
- for ri := 0; ri < len(sym.R); ri++ {
- r := &sym.R[ri]
+ for ri := 0; ri < len(s.R); ri++ {
+ r := &s.R[ri]
if r.Done {
continue
}
if r.Xsym == nil {
- Errorf(sym, "missing xsym in relocation")
+ Errorf(s, "missing xsym in relocation")
continue
}
if !r.Xsym.Attr.Reachable() {
- Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
+ 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, sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
- Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.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)
}
}
}
"cmd/internal/dwarf"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"io"
"log"
"strconv"
type objReader struct {
rd *bufio.Reader
arch *sys.Arch
- syms *Symbols
+ syms *sym.Symbols
lib *Library
pn string
- dupSym *Symbol
+ dupSym *sym.Symbol
localSymVersion int
// rdBuf is used by readString and readSymName as scratch for reading strings.
rdBuf []byte
// List of symbol references for the file being read.
- refs []*Symbol
+ refs []*sym.Symbol
data []byte
- reloc []Reloc
- pcdata []Pcdata
- autom []Auto
- funcdata []*Symbol
+ reloc []sym.Reloc
+ pcdata []sym.Pcdata
+ autom []sym.Auto
+ funcdata []*sym.Symbol
funcdataoff []int64
- file []*Symbol
+ file []*sym.Symbol
}
-func LoadObjFile(arch *sys.Arch, syms *Symbols, f *bio.Reader, lib *Library, length int64, pn string) {
+func LoadObjFile(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *Library, length int64, pn string) {
start := f.Offset()
r := &objReader{
rd: f.Reader,
arch: arch,
syms: syms,
pn: pn,
- dupSym: &Symbol{Name: ".dup"},
+ dupSym: &sym.Symbol{Name: ".dup"},
localSymVersion: syms.IncVersion(),
}
r.loadObjFile()
r.lib.importStrings = append(r.lib.importStrings, lib)
}
- // Symbol references
- r.refs = []*Symbol{nil} // zeroth ref is nil
+ // sym.Symbol references
+ r.refs = []*sym.Symbol{nil} // zeroth ref is nil
for {
c, err := r.rd.Peek(1)
if err != nil {
n := r.readInt()
r.data = make([]byte, n)
n = r.readInt()
- r.reloc = make([]Reloc, n)
+ r.reloc = make([]sym.Reloc, n)
n = r.readInt()
- r.pcdata = make([]Pcdata, n)
+ r.pcdata = make([]sym.Pcdata, n)
n = r.readInt()
- r.autom = make([]Auto, n)
+ r.autom = make([]sym.Auto, n)
n = r.readInt()
- r.funcdata = make([]*Symbol, n)
+ r.funcdata = make([]*sym.Symbol, n)
r.funcdataoff = make([]int64, n)
n = r.readInt()
- r.file = make([]*Symbol, n)
+ r.file = make([]*sym.Symbol, n)
}
// Symbols are prefixed so their content doesn't get confused with the magic footer.
if c, err = r.rd.ReadByte(); err != nil {
log.Fatalln("error reading input: ", err)
}
- t := abiSymKindToSymKind[c]
+ t := sym.AbiSymKindToSymKind[c]
s := r.readSymIndex()
flags := r.readInt()
dupok := flags&1 != 0
pkg := objabi.PathToPrefix(r.lib.Pkg)
isdup := false
- var dup *Symbol
- if s.Type != 0 && s.Type != SXREF {
- if (t == SDATA || t == SBSS || t == SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
+ var dup *sym.Symbol
+ if s.Type != 0 && s.Type != sym.SXREF {
+ if (t == sym.SDATA || t == sym.SBSS || t == sym.SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
if s.Size < int64(size) {
s.Size = int64(size)
}
return
}
- if (s.Type == SDATA || s.Type == SBSS || s.Type == SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 {
+ if (s.Type == sym.SDATA || s.Type == sym.SBSS || s.Type == sym.SNOPTRBSS) && len(s.P) == 0 && len(s.R) == 0 {
goto overwrite
}
- if s.Type != SBSS && s.Type != SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() {
+ if s.Type != sym.SBSS && s.Type != sym.SNOPTRBSS && !dupok && !s.Attr.DuplicateOK() {
log.Fatalf("duplicate symbol %s (types %d and %d) in %s and %s", s.Name, s.Type, t, s.File, r.pn)
}
if len(s.P) > 0 {
overwrite:
s.File = pkg
if dupok {
- s.Attr |= AttrDuplicateOK
+ s.Attr |= sym.AttrDuplicateOK
}
- if t == SXREF {
+ if t == sym.SXREF {
log.Fatalf("bad sxref")
}
if t == 0 {
log.Fatalf("missing type for %s in %s", s.Name, r.pn)
}
- if t == SBSS && (s.Type == SRODATA || s.Type == SNOPTRBSS) {
+ if t == sym.SBSS && (s.Type == sym.SRODATA || s.Type == sym.SNOPTRBSS) {
t = s.Type
}
s.Type = t
if s.Size < int64(size) {
s.Size = int64(size)
}
- s.Attr.Set(AttrLocal, local)
- s.Attr.Set(AttrMakeTypelink, makeTypelink)
+ s.Attr.Set(sym.AttrLocal, local)
+ s.Attr.Set(sym.AttrMakeTypelink, makeTypelink)
if typ != nil {
s.Gotype = typ
}
}
for i := 0; i < nreloc; i++ {
- s.R[i] = Reloc{
+ s.R[i] = sym.Reloc{
Off: r.readInt32(),
Siz: r.readUint8(),
Type: objabi.RelocType(r.readInt32()),
}
}
- if s.Type == STEXT {
- s.FuncInfo = new(FuncInfo)
+ if s.Type == sym.STEXT {
+ s.FuncInfo = new(sym.FuncInfo)
pc := s.FuncInfo
pc.Args = r.readInt32()
pc.Locals = r.readInt32()
if r.readUint8() != 0 {
- s.Attr |= AttrNoSplit
+ s.Attr |= sym.AttrNoSplit
}
flags := r.readInt()
if flags&(1<<2) != 0 {
- s.Attr |= AttrReflectMethod
+ s.Attr |= sym.AttrReflectMethod
}
if flags&(1<<3) != 0 {
- s.Attr |= AttrShared
+ s.Attr |= sym.AttrShared
}
n := r.readInt()
pc.Autom = r.autom[:n:n]
}
for i := 0; i < n; i++ {
- pc.Autom[i] = Auto{
+ pc.Autom[i] = sym.Auto{
Asym: r.readSymIndex(),
Aoffset: r.readInt32(),
Name: r.readInt16(),
pc.File[i] = r.readSymIndex()
}
n = r.readInt()
- pc.InlTree = make([]InlinedCall, n)
+ pc.InlTree = make([]sym.InlinedCall, n)
for i := 0; i < n; i++ {
pc.InlTree[i].Parent = r.readInt32()
pc.InlTree[i].File = r.readSymIndex()
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
- s.Attr |= AttrOnList
+ s.Attr |= sym.AttrOnList
r.lib.textp = append(r.lib.textp, s)
} else {
// there may ba a dup in another package
}
}
}
- if s.Type == SDWARFINFO {
+ if s.Type == sym.SDWARFINFO {
r.patchDWARFName(s)
}
}
-func (r *objReader) patchDWARFName(s *Symbol) {
+func (r *objReader) patchDWARFName(s *sym.Symbol) {
// This is kind of ugly. Really the package name should not
// even be included here.
if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
if err != nil {
log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
}
- s.Type = SRODATA
- s.Attr |= AttrLocal
+ s.Type = sym.SRODATA
+ s.Attr |= sym.AttrLocal
switch s.Name[:5] {
case "$f32.":
if uint64(uint32(x)) != x {
default:
log.Panicf("unrecognized $-symbol: %s", s.Name)
}
- s.Attr.Set(AttrReachable, false)
+ s.Attr.Set(sym.AttrReachable, false)
}
if strings.HasPrefix(s.Name, "runtime.gcbits.") {
- s.Attr |= AttrLocal
+ s.Attr |= sym.AttrLocal
}
}
}
// Reads the index of a symbol reference and resolves it to a symbol
-func (r *objReader) readSymIndex() *Symbol {
+func (r *objReader) readSymIndex() *sym.Symbol {
i := r.readInt()
return r.refs[i]
}
import (
"cmd/internal/objabi"
"cmd/internal/src"
+ "cmd/link/internal/sym"
"log"
"os"
"path/filepath"
it.nextpc = it.pc + v*it.pcscale
}
-func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
+func pciterinit(ctxt *Link, it *Pciter, d *sym.Pcdata) {
it.d = *d
it.p = it.d.P
it.pc = 0
pciternext(it)
}
-func addvarint(d *Pcdata, val uint32) {
+func addvarint(d *sym.Pcdata, val uint32) {
n := int32(0)
for v := val; v >= 0x80; v >>= 7 {
n++
p[0] = byte(v)
}
-func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 {
+func addpctab(ctxt *Link, ftab *sym.Symbol, off int32, d *sym.Pcdata) int32 {
var start int32
if len(d.P) > 0 {
start = int32(len(ftab.P))
return int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(start)))
}
-func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 {
+func ftabaddstring(ctxt *Link, ftab *sym.Symbol, s string) int32 {
n := int32(len(s)) + 1
start := int32(len(ftab.P))
ftab.Grow(int64(start) + int64(n) + 1)
}
// numberfile assigns a file number to the file if it hasn't been assigned already.
-func numberfile(ctxt *Link, file *Symbol) {
- if file.Type != SFILEPATH {
+func numberfile(ctxt *Link, file *sym.Symbol) {
+ if file.Type != sym.SFILEPATH {
ctxt.Filesyms = append(ctxt.Filesyms, file)
file.Value = int64(len(ctxt.Filesyms))
- file.Type = SFILEPATH
+ file.Type = sym.SFILEPATH
path := file.Name[len(src.FileSymPrefix):]
file.Name = expandGoroot(path)
}
}
-func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) {
- var f *Symbol
+func renumberfiles(ctxt *Link, files []*sym.Symbol, d *sym.Pcdata) {
+ var f *sym.Symbol
// Give files numbers.
for i := 0; i < len(files); i++ {
}
newval := int32(-1)
- var out Pcdata
+ var out sym.Pcdata
var it Pciter
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
// value delta
// onlycsymbol reports whether this is a cgo symbol provided by the
// runtime and only used from C code.
-func onlycsymbol(s *Symbol) bool {
+func onlycsymbol(s *sym.Symbol) bool {
switch s.Name {
case "_cgo_topofstack", "_cgo_panic", "crosscall2":
return true
return false
}
-func emitPcln(s *Symbol) bool {
+func emitPcln(s *sym.Symbol) bool {
if s == nil {
return true
}
}
// We want to generate func table entries only for the "lowest level" symbols,
// not containers of subsymbols.
- if s.Type&SCONTAINER != 0 {
+ if s.Type&sym.SCONTAINER != 0 {
return false
}
return true
// pclntab initializes the pclntab symbol with
// runtime function and file name information.
-var pclntabZpcln FuncInfo
+var pclntabZpcln sym.FuncInfo
// These variables are used to initialize runtime.firstmoduledata, see symtab.go:symtab.
var pclntabNfunc int32
var pclntabFiletabOffset int32
var pclntabPclntabOffset int32
-var pclntabFirstFunc *Symbol
-var pclntabLastFunc *Symbol
+var pclntabFirstFunc *sym.Symbol
+var pclntabLastFunc *sym.Symbol
func (ctxt *Link) pclntab() {
funcdataBytes := int64(0)
ftab := ctxt.Syms.Lookup("runtime.pclntab", 0)
- ftab.Type = SPCLNTAB
- ftab.Attr |= AttrReachable
+ ftab.Type = sym.SPCLNTAB
+ ftab.Attr |= sym.AttrReachable
// See golang.org/s/go12symtab for the format. Briefly:
// 8-byte header
// offset to file table [4 bytes]
nfunc := int32(0)
- // Find container symbols, mark them with SCONTAINER
+ // Find container symbols, mark them with sym.SCONTAINER
for _, s := range ctxt.Textp {
if s.Outer != nil {
- s.Outer.Type |= SCONTAINER
+ s.Outer.Type |= sym.SCONTAINER
}
}
}
nfunc = 0
- var last *Symbol
+ var last *sym.Symbol
for _, s := range ctxt.Textp {
last = s
if !emitPcln(s) {
if len(pcln.InlTree) > 0 {
if len(pcln.Pcdata) <= objabi.PCDATA_InlTreeIndex {
// Create inlining pcdata table.
- pcdata := make([]Pcdata, objabi.PCDATA_InlTreeIndex+1)
+ pcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1)
copy(pcdata, pcln.Pcdata)
pcln.Pcdata = pcdata
}
if len(pcln.Funcdataoff) <= objabi.FUNCDATA_InlTree {
// Create inline tree funcdata.
- funcdata := make([]*Symbol, objabi.FUNCDATA_InlTree+1)
+ funcdata := make([]*sym.Symbol, objabi.FUNCDATA_InlTree+1)
funcdataoff := make([]int64, objabi.FUNCDATA_InlTree+1)
copy(funcdata, pcln.Funcdata)
copy(funcdataoff, pcln.Funcdataoff)
if len(pcln.InlTree) > 0 {
inlTreeSym := ctxt.Syms.Lookup("inltree."+s.Name, 0)
- inlTreeSym.Type = SRODATA
- inlTreeSym.Attr |= AttrReachable | AttrDuplicateOK
+ inlTreeSym.Type = sym.SRODATA
+ inlTreeSym.Attr |= sym.AttrReachable | sym.AttrDuplicateOK
for i, call := range pcln.InlTree {
// Usually, call.File is already numbered since the file
// function for a pc. See src/runtime/symtab.go:findfunc for details.
func (ctxt *Link) findfunctab() {
t := ctxt.Syms.Lookup("runtime.findfunctab", 0)
- t.Type = SRODATA
- t.Attr |= AttrReachable
- t.Attr |= AttrLocal
+ t.Type = sym.SRODATA
+ t.Attr |= sym.AttrReachable
+ t.Attr |= sym.AttrLocal
// find min and max address
min := ctxt.Textp[0].Value
continue
}
p := s.Value
- var e *Symbol
+ var e *sym.Symbol
i++
if i < len(ctxt.Textp) {
e = ctxt.Textp[i]
import (
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"debug/pe"
"encoding/binary"
"fmt"
}
type Imp struct {
- s *Symbol
+ s *sym.Symbol
off uint64
next *Imp
argsize int
}
var (
- rsrcsym *Symbol
+ rsrcsym *sym.Symbol
PESECTHEADR int32
PEFILEHEADR int32
pe64 int
dr *Dll
- dexport [1024]*Symbol
+ dexport [1024]*sym.Symbol
nexport int
)
// checkSegment verifies COFF section sect matches address
// and file offset provided in segment seg.
-func (sect *peSection) checkSegment(seg *Segment) {
+func (sect *peSection) checkSegment(seg *sym.Segment) {
if seg.Vaddr-PEBASE != uint64(sect.virtualAddress) {
Errorf(nil, "%s.VirtualAddress = %#x, want %#x", sect.name, uint64(int64(sect.virtualAddress)), uint64(int64(seg.Vaddr-PEBASE)))
errorexit()
// relocsect relocates symbols from first in section sect, and returns
// the total number of relocations emitted.
- relocsect := func(sect *Section, syms []*Symbol, base uint64) int {
+ relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) int {
// If main section has no bits, nothing to relocate.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
return 0
// 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 *Symbol, value int64, sectidx int, typ uint16, class uint8) {
+func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx int, typ uint16, class uint8) {
if len(s.Name) > 8 {
out.Write32(0)
out.Write32(uint32(f.stringTable.add(s.Name)))
// mapToPESection searches peFile f for s symbol's location.
// It returns PE section index, and offset within that section.
-func (f *peFile) mapToPESection(s *Symbol) (pesectidx int, offset int64, err error) {
+func (f *peFile) mapToPESection(s *sym.Symbol) (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)
}
if Linkmode != LinkExternal {
return f.dataSect.index, int64(v), nil
}
- if s.Type == SDATA {
+ if s.Type == sym.SDATA {
return f.dataSect.index, int64(v), nil
}
- // Note: although address of runtime.edata (type SDATA) is at the start of .bss section
+ // Note: although address of runtime.edata (type sym.SDATA) is at the start of .bss section
// it still belongs to the .data section, not the .bss section.
if v < Segdata.Filelen {
return f.dataSect.index, int64(v), nil
// writeSymbols writes all COFF symbol table records.
func (f *peFile) writeSymbols(ctxt *Link) {
- put := func(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
+ put := func(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
if s == nil {
return
}
// Only windows/386 requires underscore prefix on external symbols.
if ctxt.Arch.Family == sys.I386 &&
Linkmode == LinkExternal &&
- (s.Type == SHOSTOBJ || s.Attr.CgoExport()) {
+ (s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) {
s.Name = "_" + s.Name
}
}
}
class := IMAGE_SYM_CLASS_EXTERNAL
- if s.Version != 0 || (s.Type&SHIDDEN != 0) || s.Attr.Local() {
+ if s.Version != 0 || (s.Type&sym.SHIDDEN != 0) || s.Attr.Local() {
class = IMAGE_SYM_CLASS_STATIC
}
f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
if Linkmode == LinkInternal {
// some mingw libs depend on this symbol, for example, FindPESectionByName
- ctxt.xdefine("__image_base__", SDATA, PEBASE)
- ctxt.xdefine("_image_base__", SDATA, PEBASE)
+ ctxt.xdefine("__image_base__", sym.SDATA, PEBASE)
+ ctxt.xdefine("_image_base__", sym.SDATA, PEBASE)
}
HEADR = PEFILEHEADR
dr = nil
var m *Imp
for _, s := range ctxt.Syms.Allsym {
- if !s.Attr.Reachable() || s.Type != SDYNIMPORT {
+ if !s.Attr.Reachable() || s.Type != sym.SDYNIMPORT {
continue
}
for d = dr; d != nil; d = d.next {
// Add real symbol name
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
- m.s.Type = SDATA
+ m.s.Type = sym.SDATA
m.s.Grow(int64(ctxt.Arch.PtrSize))
dynName := m.s.Extname
// only windows/386 requires stdcall decoration
dynName += fmt.Sprintf("@%d", m.argsize)
}
dynSym := ctxt.Syms.Lookup(dynName, 0)
- dynSym.Attr |= AttrReachable
- dynSym.Type = SHOSTOBJ
+ dynSym.Attr |= sym.AttrReachable
+ dynSym.Type = sym.SHOSTOBJ
r := m.s.AddRel()
r.Sym = dynSym
r.Off = 0
}
} else {
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
- dynamic.Attr |= AttrReachable
- dynamic.Type = SWINDOWS
+ dynamic.Attr |= sym.AttrReachable
+ dynamic.Type = sym.SWINDOWS
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
- m.s.Type = SWINDOWS | SSUB
+ m.s.Type = sym.SWINDOWS | sym.SSUB
m.s.Sub = dynamic.Sub
dynamic.Sub = m.s
m.s.Value = dynamic.Size
out.SeekSet(endoff)
}
-type byExtname []*Symbol
+type byExtname []*sym.Symbol
func (s byExtname) Len() int { return len(s) }
func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
/* relocation table */
rel := ctxt.Syms.Lookup(".rel", 0)
- rel.Attr |= AttrReachable
- rel.Type = SELFROSECT
+ rel.Attr |= sym.AttrReachable
+ rel.Type = sym.SELFROSECT
initdynimport(ctxt)
initdynexport(ctxt)
}
-func setpersrc(ctxt *Link, sym *Symbol) {
+func setpersrc(ctxt *Link, sym *sym.Symbol) {
if rsrcsym != nil {
Errorf(sym, "too many .rsrc sections")
}
// relocation
var p []byte
- var r *Reloc
+ var r *sym.Reloc
var val uint32
for ri := 0; ri < len(rsrcsym.R); ri++ {
r = &rsrcsym.R[ri]
import (
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"log"
)
func linknew(arch *sys.Arch) *Link {
ctxt := &Link{
- Syms: &Symbols{
- hash: []map[string]*Symbol{
- // preallocate about 2mb for hash of
- // non static symbols
- make(map[string]*Symbol, 100000),
- },
- Allsym: make([]*Symbol, 0, 100000),
- },
+ Syms: sym.NewSymbols(),
Out: &OutBuf{arch: arch},
Arch: arch,
LibraryByPkg: make(map[string]*Library),
import (
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/sym"
"fmt"
"path/filepath"
"strings"
var elfbind int
-func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *Symbol) {
+func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go_ *sym.Symbol) {
var typ int
switch t {
}
var elfshnum int
- if xo.Type == SDYNIMPORT || xo.Type == SHOSTOBJ {
+ if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ {
elfshnum = SHN_UNDEF
} else {
if xo.Sect == nil {
Errorf(x, "missing ELF section in putelfsym")
return
}
- elfshnum = xo.Sect.Elfsect.shnum
+ elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum
}
// One pass for each binding: STB_LOCAL, STB_GLOBAL,
// maybe one day STB_WEAK.
bind := STB_GLOBAL
- if x.Version != 0 || (x.Type&SHIDDEN != 0) || x.Attr.Local() {
+ if x.Version != 0 || (x.Type&sym.SHIDDEN != 0) || x.Attr.Local() {
bind = STB_LOCAL
}
addr -= int64(xo.Sect.Vaddr)
}
other := STV_DEFAULT
- if x.Type&SHIDDEN != 0 {
+ if x.Type&sym.SHIDDEN != 0 {
other = STV_HIDDEN
}
if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
s = strings.Replace(s, "·", ".", -1)
}
- if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == STEXT {
+ if ctxt.DynlinkingGo() && bind == STB_GLOBAL && elfbind == STB_LOCAL && x.Type == sym.STEXT {
// When dynamically linking, we want references to functions defined
// in this module to always be to the function object, not to the
// PLT. We force this by writing an additional local symbol for every
// global function symbol and making all relocations against the
// global symbol refer to this local symbol instead (see
- // (*Symbol).ElfsymForReloc). This is approximately equivalent to the
+ // (*sym.Symbol).ElfsymForReloc). This is approximately equivalent to the
// ELF linker -Bsymbolic-functions option, but that is buggy on
// several platforms.
putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
numelfsym++
}
-func putelfsectionsym(out *OutBuf, s *Symbol, shndx int) {
+func putelfsectionsym(out *OutBuf, s *sym.Symbol, shndx int) {
putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
s.Elfsym = int32(numelfsym)
numelfsym++
genasmsym(ctxt, putelfsym)
}
-func putplan9sym(ctxt *Link, x *Symbol, s string, typ SymbolType, addr int64, go_ *Symbol) {
+func putplan9sym(ctxt *Link, x *sym.Symbol, s string, typ SymbolType, addr int64, go_ *sym.Symbol) {
t := int(typ)
switch typ {
case TextSym, DataSym, BSSSym:
genasmsym(ctxt, putplan9sym)
}
-var symt *Symbol
+var symt *sym.Symbol
type byPkg []*Library
func textsectionmap(ctxt *Link) uint32 {
t := ctxt.Syms.Lookup("runtime.textsectionmap", 0)
- t.Type = SRODATA
- t.Attr |= AttrReachable
+ t.Type = sym.SRODATA
+ t.Attr |= sym.AttrReachable
nsections := int64(0)
for _, sect := range Segtext.Sections {
// Define these so that they'll get put into the symbol table.
// data.c:/^address will provide the actual values.
- ctxt.xdefine("runtime.text", STEXT, 0)
-
- ctxt.xdefine("runtime.etext", STEXT, 0)
- ctxt.xdefine("runtime.itablink", SRODATA, 0)
- ctxt.xdefine("runtime.eitablink", SRODATA, 0)
- ctxt.xdefine("runtime.rodata", SRODATA, 0)
- ctxt.xdefine("runtime.erodata", SRODATA, 0)
- ctxt.xdefine("runtime.types", SRODATA, 0)
- ctxt.xdefine("runtime.etypes", SRODATA, 0)
- ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, 0)
- ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, 0)
- ctxt.xdefine("runtime.data", SDATA, 0)
- ctxt.xdefine("runtime.edata", SDATA, 0)
- ctxt.xdefine("runtime.bss", SBSS, 0)
- ctxt.xdefine("runtime.ebss", SBSS, 0)
- ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, 0)
- ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, 0)
- ctxt.xdefine("runtime.end", SBSS, 0)
- ctxt.xdefine("runtime.epclntab", SRODATA, 0)
- ctxt.xdefine("runtime.esymtab", SRODATA, 0)
+ ctxt.xdefine("runtime.text", sym.STEXT, 0)
+
+ ctxt.xdefine("runtime.etext", sym.STEXT, 0)
+ ctxt.xdefine("runtime.itablink", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.types", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
+ ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0)
+ ctxt.xdefine("runtime.data", sym.SDATA, 0)
+ ctxt.xdefine("runtime.edata", sym.SDATA, 0)
+ ctxt.xdefine("runtime.bss", sym.SBSS, 0)
+ ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
+ ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
+ ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
+ ctxt.xdefine("runtime.end", sym.SBSS, 0)
+ ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
+ ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
// garbage collection symbols
s := ctxt.Syms.Lookup("runtime.gcdata", 0)
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Size = 0
- s.Attr |= AttrReachable
- ctxt.xdefine("runtime.egcdata", SRODATA, 0)
+ s.Attr |= sym.AttrReachable
+ ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
s = ctxt.Syms.Lookup("runtime.gcbss", 0)
- s.Type = SRODATA
+ s.Type = sym.SRODATA
s.Size = 0
- s.Attr |= AttrReachable
- ctxt.xdefine("runtime.egcbss", SRODATA, 0)
+ s.Attr |= sym.AttrReachable
+ ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
// pseudo-symbols to mark locations of type, string, and go string data.
- var symtype *Symbol
- var symtyperel *Symbol
+ var symtype *sym.Symbol
+ var symtyperel *sym.Symbol
if UseRelro() && (Buildmode == BuildmodeCArchive || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) {
s = ctxt.Syms.Lookup("type.*", 0)
- s.Type = STYPE
+ s.Type = sym.STYPE
s.Size = 0
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrReachable
symtype = s
s = ctxt.Syms.Lookup("typerel.*", 0)
- s.Type = STYPERELRO
+ s.Type = sym.STYPERELRO
s.Size = 0
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrReachable
symtyperel = s
} else if !ctxt.DynlinkingGo() {
s = ctxt.Syms.Lookup("type.*", 0)
- s.Type = STYPE
+ s.Type = sym.STYPE
s.Size = 0
- s.Attr |= AttrReachable
+ s.Attr |= sym.AttrReachable
symtype = s
symtyperel = s
}
- groupSym := func(name string, t SymKind) *Symbol {
+ groupSym := func(name string, t sym.SymKind) *sym.Symbol {
s := ctxt.Syms.Lookup(name, 0)
s.Type = t
s.Size = 0
- s.Attr |= AttrLocal | AttrReachable
+ s.Attr |= sym.AttrLocal | sym.AttrReachable
return s
}
var (
- symgostring = groupSym("go.string.*", SGOSTRING)
- symgofunc = groupSym("go.func.*", SGOFUNC)
- symgcbits = groupSym("runtime.gcbits.*", SGCBITS)
+ symgostring = groupSym("go.string.*", sym.SGOSTRING)
+ symgofunc = groupSym("go.func.*", sym.SGOFUNC)
+ symgcbits = groupSym("runtime.gcbits.*", sym.SGCBITS)
)
- var symgofuncrel *Symbol
+ var symgofuncrel *sym.Symbol
if !ctxt.DynlinkingGo() {
if UseRelro() {
- symgofuncrel = groupSym("go.funcrel.*", SGOFUNCRELRO)
+ symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
} else {
symgofuncrel = symgofunc
}
}
symitablink := ctxt.Syms.Lookup("runtime.itablink", 0)
- symitablink.Type = SITABLINK
+ symitablink.Type = sym.SITABLINK
symt = ctxt.Syms.Lookup("runtime.symtab", 0)
- symt.Attr |= AttrLocal
- symt.Type = SSYMTAB
+ symt.Attr |= sym.AttrLocal
+ symt.Type = sym.SSYMTAB
symt.Size = 0
- symt.Attr |= AttrReachable
+ symt.Attr |= sym.AttrReachable
nitablinks := 0
// just defined above will be first.
// hide the specific symbols.
for _, s := range ctxt.Syms.Allsym {
- if !s.Attr.Reachable() || s.Attr.Special() || s.Type != SRODATA {
+ if !s.Attr.Reachable() || s.Attr.Special() || s.Type != sym.SRODATA {
continue
}
switch {
case strings.HasPrefix(s.Name, "type."):
if !ctxt.DynlinkingGo() {
- s.Attr |= AttrNotInSymbolTable
+ s.Attr |= sym.AttrNotInSymbolTable
}
if UseRelro() {
- s.Type = STYPERELRO
+ s.Type = sym.STYPERELRO
s.Outer = symtyperel
} else {
- s.Type = STYPE
+ s.Type = sym.STYPE
s.Outer = symtype
}
case strings.HasPrefix(s.Name, "go.importpath.") && UseRelro():
// Keep go.importpath symbols in the same section as types and
// names, as they can be referred to by a section offset.
- s.Type = STYPERELRO
+ s.Type = sym.STYPERELRO
case strings.HasPrefix(s.Name, "go.itablink."):
nitablinks++
- s.Type = SITABLINK
- s.Attr |= AttrNotInSymbolTable
+ s.Type = sym.SITABLINK
+ s.Attr |= sym.AttrNotInSymbolTable
s.Outer = symitablink
case strings.HasPrefix(s.Name, "go.string."):
- s.Type = SGOSTRING
- s.Attr |= AttrNotInSymbolTable
+ s.Type = sym.SGOSTRING
+ s.Attr |= sym.AttrNotInSymbolTable
s.Outer = symgostring
case strings.HasPrefix(s.Name, "runtime.gcbits."):
- s.Type = SGCBITS
- s.Attr |= AttrNotInSymbolTable
+ s.Type = sym.SGCBITS
+ s.Attr |= sym.AttrNotInSymbolTable
s.Outer = symgcbits
case strings.HasSuffix(s.Name, "·f"):
if !ctxt.DynlinkingGo() {
- s.Attr |= AttrNotInSymbolTable
+ s.Attr |= sym.AttrNotInSymbolTable
}
if UseRelro() {
- s.Type = SGOFUNCRELRO
+ s.Type = sym.SGOFUNCRELRO
s.Outer = symgofuncrel
} else {
- s.Type = SGOFUNC
+ s.Type = sym.SGOFUNC
s.Outer = symgofunc
}
strings.HasPrefix(s.Name, "gclocals."),
strings.HasPrefix(s.Name, "gclocals·"),
strings.HasPrefix(s.Name, "inltree."):
- s.Type = SGOFUNC
- s.Attr |= AttrNotInSymbolTable
+ s.Type = sym.SGOFUNC
+ s.Attr |= sym.AttrNotInSymbolTable
s.Outer = symgofunc
s.Align = 4
liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
if Buildmode == BuildmodeShared {
abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
- abihashgostr.Attr |= AttrReachable
- abihashgostr.Type = SRODATA
+ abihashgostr.Attr |= sym.AttrReachable
+ abihashgostr.Type = sym.SRODATA
hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
abihashgostr.AddAddr(ctxt.Arch, hashsym)
abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
for _, l := range ctxt.Library {
s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
- s.Attr |= AttrReachable
- s.Type = SRODATA
+ s.Attr |= sym.AttrReachable
+ s.Type = sym.SRODATA
s.Size = int64(len(l.hash))
s.P = []byte(l.hash)
str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
- str.Attr |= AttrReachable
- str.Type = SRODATA
+ str.Attr |= sym.AttrReachable
+ str.Type = sym.SRODATA
str.AddAddr(ctxt.Arch, s)
str.AddUint(ctxt.Arch, uint64(len(l.hash)))
}
moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
// The ptab slice
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
- ptab.Attr |= AttrLocal
- ptab.Type = SRODATA
+ ptab.Attr |= sym.AttrLocal
+ ptab.Type = sym.SRODATA
nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
moduledata.AddAddr(ctxt.Arch, ptab)
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
- pkghashes.Attr |= AttrReachable
- pkghashes.Attr |= AttrLocal
- pkghashes.Type = SRODATA
+ pkghashes.Attr |= sym.AttrReachable
+ pkghashes.Attr |= sym.AttrLocal
+ pkghashes.Type = sym.SRODATA
for i, l := range ctxt.Library {
// pkghashes[i].name
addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0)
- modulehashes.Attr |= AttrReachable
- modulehashes.Attr |= AttrLocal
- modulehashes.Type = SRODATA
+ modulehashes.Attr |= sym.AttrReachable
+ modulehashes.Attr |= sym.AttrLocal
+ modulehashes.Type = sym.SRODATA
for i, shlib := range ctxt.Shlibs {
// modulehashes[i].modulename
// modulehashes[i].runtimehash
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
- abihash.Attr |= AttrReachable
+ abihash.Attr |= sym.AttrReachable
modulehashes.AddAddr(ctxt.Arch, abihash)
}
moduledata.Grow(moduledata.Size)
lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
- if lastmoduledatap.Type != SDYNIMPORT {
- lastmoduledatap.Type = SNOPTRDATA
+ if lastmoduledatap.Type != sym.SDYNIMPORT {
+ lastmoduledatap.Type = sym.SNOPTRDATA
lastmoduledatap.Size = 0 // overwrite existing value
lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
}
import (
"cmd/internal/objabi"
+ "cmd/link/internal/sym"
"sort"
)
type typelinkSortKey struct {
TypeStr string
- Type *Symbol
+ Type *sym.Symbol
}
func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
sort.Sort(typelinks)
tl := ctxt.Syms.Lookup("runtime.typelink", 0)
- tl.Type = STYPELINK
- tl.Attr |= AttrReachable | AttrLocal
+ tl.Type = sym.STYPELINK
+ tl.Attr |= sym.AttrReachable | sym.AttrLocal
tl.Size = int64(4 * len(typelinks))
tl.P = make([]byte, tl.Size)
- tl.R = make([]Reloc, len(typelinks))
+ tl.R = make([]sym.Reloc, len(typelinks))
for i, s := range typelinks {
r := &tl.R[i]
r.Sym = s.Type
import (
"bytes"
+ "cmd/link/internal/sym"
"encoding/binary"
"fmt"
"os"
//
// Logging an error means that on exit cmd/link will delete any
// output file and return a non-zero error code.
-func Errorf(s *Symbol, format string, args ...interface{}) {
+func Errorf(s *sym.Symbol, format string, args ...interface{}) {
if s != nil {
format = s.Name + ": " + format
}
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"fmt"
"log"
)
return
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write32(uint32(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
return
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
return false
}
-func applyrel(arch *sys.Arch, r *ld.Reloc, s *ld.Symbol, val *int64, t int64) {
+func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val *int64, t int64) {
o := arch.ByteOrder.Uint32(s.P[r.Off:])
switch r.Type {
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
}
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
rs = rs.Outer
}
- if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
return -1
}
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"fmt"
"log"
)
func gentext(ctxt *ld.Link) {}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
// mips64 ELF relocation (endian neutral)
// offset uint64
// sym uint32
return
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
return false
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
rs = rs.Outer
}
- if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
return -1
}
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"encoding/binary"
"fmt"
"log"
//
// This assumes "case 1" from the ABI, where the caller needs
// us to save and restore the TOC pointer.
- var stubs []*ld.Symbol
+ var stubs []*sym.Symbol
for _, s := range ctxt.Textp {
for i := range s.R {
r := &s.R[i]
- if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != ld.SDYNIMPORT {
+ if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != sym.SDYNIMPORT {
continue
}
stub := ctxt.Syms.Lookup(n, 0)
if s.Attr.Reachable() {
- stub.Attr |= ld.AttrReachable
+ stub.Attr |= sym.AttrReachable
}
if stub.Size == 0 {
// Need outer to resolve .TOC.
func genaddmoduledata(ctxt *ld.Link) {
addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
return
}
- addmoduledata.Attr |= ld.AttrReachable
+ addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
- initfunc.Type = ld.STEXT
- initfunc.Attr |= ld.AttrLocal
- initfunc.Attr |= ld.AttrReachable
+ initfunc.Type = sym.STEXT
+ initfunc.Attr |= sym.AttrLocal
+ initfunc.Attr |= sym.AttrReachable
o := func(op uint32) {
initfunc.AddUint32(ctxt.Arch, op)
}
rel.Off = int32(initfunc.Size)
rel.Siz = 8
rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
- rel.Sym.Attr |= ld.AttrReachable
+ rel.Sym.Attr |= sym.AttrReachable
rel.Type = objabi.R_ADDRPOWER_PCREL
o(0x3c4c0000)
// addi r2, r2, .TOC.-func@l
} else {
rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
}
- rel.Sym.Attr |= ld.AttrReachable
- rel.Sym.Attr |= ld.AttrLocal
+ rel.Sym.Attr |= sym.AttrReachable
+ rel.Sym.Attr |= sym.AttrLocal
rel.Type = objabi.R_ADDRPOWER_GOT
o(0x3c620000)
// ld r3, local.moduledata@got@l(r3)
}
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
ctxt.Textp = append(ctxt.Textp, initfunc)
- initarray_entry.Attr |= ld.AttrReachable
- initarray_entry.Attr |= ld.AttrLocal
- initarray_entry.Type = ld.SINITARR
+ initarray_entry.Attr |= sym.AttrReachable
+ initarray_entry.Attr |= sym.AttrLocal
+ initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
// Construct a call stub in stub that calls symbol targ via its PLT
// entry.
-func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
+func gencallstub(ctxt *ld.Link, abicase int, stub *sym.Symbol, targ *sym.Symbol) {
if abicase != 1 {
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
// relocations, we'll need to implement cases 2 and 3.
plt := ctxt.Syms.Lookup(".plt", 0)
- stub.Type = ld.STEXT
+ stub.Type = sym.STEXT
// Save TOC pointer in TOC save slot
stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1)
r.Off += int32(r.Siz)
}
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_HA
+ r.Variant = sym.RV_POWER_HA
stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
r = stub.AddRel()
r.Off = int32(stub.Size)
r.Off += int32(r.Siz)
}
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_LO
+ r.Variant = sym.RV_POWER_LO
stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
// Jump to the loaded pointer
stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= 256 {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
return false
}
// to use r12 to compute r2.)
r.Add += int64(r.Sym.Localentry) * 4
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
// Should have been handled in elfsetupplt
ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
}
r.Type = objabi.R_PCREL
r.Add += 4
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
}
case 256 + ld.R_PPC64_ADDR64:
r.Type = objabi.R_ADDR
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
// These happen in .toc sections
ld.Adddynsym(ctxt, targ)
case 256 + ld.R_PPC64_TOC16:
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_LO | ld.RV_CHECK_OVERFLOW
+ r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
return true
case 256 + ld.R_PPC64_TOC16_LO:
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_LO
+ r.Variant = sym.RV_POWER_LO
return true
case 256 + ld.R_PPC64_TOC16_HA:
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW
+ r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
return true
case 256 + ld.R_PPC64_TOC16_HI:
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW
+ r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
return true
case 256 + ld.R_PPC64_TOC16_DS:
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_DS | ld.RV_CHECK_OVERFLOW
+ r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
return true
case 256 + ld.R_PPC64_TOC16_LO_DS:
r.Type = objabi.R_POWER_TOC
- r.Variant = ld.RV_POWER_DS
+ r.Variant = sym.RV_POWER_DS
return true
case 256 + ld.R_PPC64_REL16_LO:
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_POWER_LO
+ r.Variant = sym.RV_POWER_LO
r.Add += 2 // Compensate for relocation size of 2
return true
case 256 + ld.R_PPC64_REL16_HI:
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW
+ r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
r.Add += 2
return true
case 256 + ld.R_PPC64_REL16_HA:
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW
+ r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
r.Add += 2
return true
}
// Handle references to ELF symbols from our own object files.
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
return true
}
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
}
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
return false
}
// Return the value of .TOC. for symbol s
-func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 {
- var toc *ld.Symbol
+func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
+ var toc *sym.Symbol
if s.Outer != nil {
toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version))
return toc.Value
}
-func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archrelocaddr(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
var o1, o2 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(*val >> 32)
}
// resolve direct jump relocation r in s, and add trampoline if necessary
-func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
+func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
// Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it.
// For internal linking, trampolines are always created for long calls.
// If branch offset is too far then create a trampoline.
if (ld.Linkmode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ld.Linkmode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
- var tramp *ld.Symbol
+ var tramp *sym.Symbol
for i := 0; ; i++ {
// Using r.Add as part of the name is significant in functions like duffzero where the call
r.Done = false
}
default:
- ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
}
-func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
+func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
// Used for default build mode for an executable
// Address of the call target is generated using
// relocation and doesn't depend on r2 (TOC).
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
rs = rs.Outer
}
- if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
+ if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
- switch r.Variant & ld.RV_TYPE_MASK {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+ switch r.Variant & sym.RV_TYPE_MASK {
default:
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
fallthrough
- case ld.RV_NONE:
+ case sym.RV_NONE:
return t
- case ld.RV_POWER_LO:
- if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
+ case sym.RV_POWER_LO:
+ if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
// Whether to check for signed or unsigned
// overflow depends on the instruction
var o1 uint32
return int64(int16(t))
- case ld.RV_POWER_HA:
+ case sym.RV_POWER_HA:
t += 0x8000
fallthrough
// Fallthrough
- case ld.RV_POWER_HI:
+ case sym.RV_POWER_HI:
t >>= 16
- if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
+ if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
// Whether to check for signed or unsigned
// overflow depends on the instruction
var o1 uint32
return int64(int16(t))
- case ld.RV_POWER_DS:
+ case sym.RV_POWER_DS:
var o1 uint32
if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(ld.Be16(s.P[r.Off:]))
if t&3 != 0 {
ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
}
- if (r.Variant&ld.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
+ if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
goto overflow
}
return int64(o1)&0x3 | int64(int16(t))
return t
}
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
}
// Generate the glink resolver stub if necessary and return the .glink section
-func ensureglinkresolver(ctxt *ld.Link) *ld.Symbol {
+func ensureglinkresolver(ctxt *ld.Link) *sym.Symbol {
glink := ctxt.Syms.Lookup(".glink", 0)
if glink.Size != 0 {
return glink
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"debug/elf"
"fmt"
)
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
- addmoduledata.Attr |= ld.AttrReachable
+ addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
- initfunc.Type = ld.STEXT
- initfunc.Attr |= ld.AttrLocal
- initfunc.Attr |= ld.AttrReachable
+ initfunc.Type = sym.STEXT
+ initfunc.Attr |= sym.AttrLocal
+ initfunc.Attr |= sym.AttrReachable
// larl %r2, <local.moduledata>
initfunc.AddUint8(0xc0)
lmd.Siz = 4
lmd.Sym = ctxt.Moduledata
lmd.Type = objabi.R_PCREL
- lmd.Variant = ld.RV_390_DBL
+ lmd.Variant = sym.RV_390_DBL
lmd.Add = 2 + int64(lmd.Siz)
initfunc.AddUint32(ctxt.Arch, 0)
rel.Siz = 4
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
rel.Type = objabi.R_CALL
- rel.Variant = ld.RV_390_DBL
+ rel.Variant = sym.RV_390_DBL
rel.Add = 2 + int64(rel.Siz)
initfunc.AddUint32(ctxt.Arch, 0)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
- initarray_entry.Attr |= ld.AttrLocal
- initarray_entry.Attr |= ld.AttrReachable
- initarray_entry.Type = ld.SINITARR
+ initarray_entry.Attr |= sym.AttrLocal
+ initarray_entry.Attr |= sym.AttrReachable
+ initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
256 + ld.R_390_16,
256 + ld.R_390_32,
256 + ld.R_390_64:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_ADDR
case 256 + ld.R_390_PC16,
256 + ld.R_390_PC32,
256 + ld.R_390_PC64:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
}
- if targ.Type == 0 || targ.Type == ld.SXREF {
+ if targ.Type == 0 || targ.Type == sym.SXREF {
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
}
r.Type = objabi.R_PCREL
case 256 + ld.R_390_PLT16DBL,
256 + ld.R_390_PLT32DBL:
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_390_DBL
+ r.Variant = sym.RV_390_DBL
r.Add += int64(r.Siz)
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add += int64(targ.Plt)
256 + ld.R_390_PLT64:
r.Type = objabi.R_PCREL
r.Add += int64(r.Siz)
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add += int64(targ.Plt)
return false
case 256 + ld.R_390_GOTOFF:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_GOTOFF
case 256 + ld.R_390_PC16DBL,
256 + ld.R_390_PC32DBL:
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_390_DBL
+ r.Variant = sym.RV_390_DBL
r.Add += int64(r.Siz)
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
}
return true
case 256 + ld.R_390_GOTPCDBL:
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_390_DBL
+ r.Variant = sym.RV_390_DBL
r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += int64(r.Siz)
return true
addgotsym(ctxt, targ)
r.Type = objabi.R_PCREL
- r.Variant = ld.RV_390_DBL
+ r.Variant = sym.RV_390_DBL
r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += int64(targ.Got)
r.Add += int64(r.Siz)
return true
}
// Handle references to ELF symbols from our own object files.
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
return true
}
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
}
case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
elfrel := ld.R_390_NONE
- isdbl := r.Variant&ld.RV_TYPE_MASK == ld.RV_390_DBL
+ isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
// TODO(mundaym): all DBL style relocations should be
// signalled using the variant - see issue 14218.
switch r.Type {
case objabi.R_PCRELDBL, objabi.R_CALL:
isdbl = true
}
- if r.Xsym.Type == ld.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) {
+ if r.Xsym.Type == sym.SDYNIMPORT && (r.Xsym.ElfType == elf.STT_FUNC || r.Type == objabi.R_CALL) {
if isdbl {
switch r.Siz {
case 2:
}
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
return false
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
return false
}
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
- switch r.Variant & ld.RV_TYPE_MASK {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
+ switch r.Variant & sym.RV_TYPE_MASK {
default:
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
return t
- case ld.RV_NONE:
+ case sym.RV_NONE:
return t
- case ld.RV_390_DBL:
+ case sym.RV_390_DBL:
if (t & 1) != 0 {
ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
}
}
}
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
}
}
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sym
+
+// Attribute is a set of common symbol attributes.
+type Attribute int16
+
+const (
+ // AttrDuplicateOK marks a symbol that can be present in multiple object
+ // files.
+ AttrDuplicateOK Attribute = 1 << iota
+ // AttrExternal marks function symbols loaded from host object files.
+ AttrExternal
+ // AttrNoSplit marks functions that cannot split the stack; the linker
+ // cares because it checks that there are no call chains of nosplit
+ // functions that require more than StackLimit bytes (see
+ // lib.go:dostkcheck)
+ AttrNoSplit
+ // AttrReachable marks symbols that are transitively referenced from the
+ // entry points. Unreachable symbols are not written to the output.
+ AttrReachable
+ // AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
+ // by directives written by cgo (in response to //export directives in
+ // the source).
+ AttrCgoExportDynamic
+ AttrCgoExportStatic
+ // AttrSpecial marks symbols that do not have their address (i.e. Value)
+ // computed by the usual mechanism of data.go:dodata() &
+ // data.go:address().
+ AttrSpecial
+ // AttrStackCheck is used by dostkcheck to only check each NoSplit
+ // function's stack usage once.
+ AttrStackCheck
+ // AttrNotInSymbolTable marks symbols that are not written to the symbol table.
+ AttrNotInSymbolTable
+ // AttrOnList marks symbols that are on some list (such as the list of
+ // all text symbols, or one of the lists of data symbols) and is
+ // consulted to avoid bugs where a symbol is put on a list twice.
+ AttrOnList
+ // AttrLocal marks symbols that are only visible within the module
+ // (executable or shared library) being linked. Only relevant when
+ // dynamically linking Go code.
+ AttrLocal
+ // AttrReflectMethod marks certain methods from the reflect package that
+ // can be used to call arbitrary methods. If no symbol with this bit set
+ // is marked as reachable, more dead code elimination can be done.
+ AttrReflectMethod
+ // AttrMakeTypelink Amarks types that should be added to the typelink
+ // table. See typelinks.go:typelinks().
+ AttrMakeTypelink
+ // AttrShared marks symbols compiled with the -shared option.
+ AttrShared
+ // 14 attributes defined so far.
+)
+
+func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
+func (a Attribute) External() bool { return a&AttrExternal != 0 }
+func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
+func (a Attribute) Reachable() bool { return a&AttrReachable != 0 }
+func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
+func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 }
+func (a Attribute) Special() bool { return a&AttrSpecial != 0 }
+func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 }
+func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
+func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
+func (a Attribute) Local() bool { return a&AttrLocal != 0 }
+func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
+func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
+func (a Attribute) Shared() bool { return a&AttrShared != 0 }
+
+func (a Attribute) CgoExport() bool {
+ return a.CgoExportDynamic() || a.CgoExportStatic()
+}
+
+func (a *Attribute) Set(flag Attribute, value bool) {
+ if value {
+ *a |= flag
+ } else {
+ *a &^= flag
+ }
+}
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sym
+
+import (
+ "cmd/internal/objabi"
+ "cmd/internal/sys"
+ "debug/elf"
+)
+
+// Reloc is a relocation.
+//
+// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
+// A Reloc is stored in a slice on the Symbol it rewrites.
+//
+// Relocations are generated by the compiler as the type
+// cmd/internal/obj.Reloc, which is encoded into the object file wire
+// format and decoded by the linker into this type. A separate type is
+// used to hold linker-specific state about the relocation.
+//
+// Some relocations are created by cmd/link.
+type Reloc struct {
+ Off int32 // offset to rewrite
+ Siz uint8 // number of bytes to rewrite, 1, 2, or 4
+ Done bool // set to true when relocation is complete
+ Variant RelocVariant // variation on Type
+ Type objabi.RelocType // the relocation type
+ Add int64 // addend
+ Xadd int64 // addend passed to external linker
+ Sym *Symbol // symbol the relocation addresses
+ Xsym *Symbol // symbol passed to external linker
+}
+
+// RelocVariant is a linker-internal variation on a relocation.
+type RelocVariant uint8
+
+const (
+ RV_NONE RelocVariant = iota
+ RV_POWER_LO
+ RV_POWER_HI
+ RV_POWER_HA
+ RV_POWER_DS
+
+ // RV_390_DBL is a s390x-specific relocation variant that indicates that
+ // the value to be placed into the relocatable field should first be
+ // divided by 2.
+ RV_390_DBL
+
+ RV_CHECK_OVERFLOW RelocVariant = 1 << 7
+ RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1
+)
+
+func RelocName(arch *sys.Arch, r objabi.RelocType) string {
+ // We didn't have some relocation types at Go1.4.
+ // Uncomment code when we include those in bootstrap code.
+
+ switch {
+ case r >= 512: // Mach-O
+ // nr := (r - 512)>>1
+ // switch ctxt.Arch.Family {
+ // case sys.AMD64:
+ // return macho.RelocTypeX86_64(nr).String()
+ // case sys.ARM:
+ // return macho.RelocTypeARM(nr).String()
+ // case sys.ARM64:
+ // return macho.RelocTypeARM64(nr).String()
+ // case sys.I386:
+ // return macho.RelocTypeGeneric(nr).String()
+ // default:
+ // panic("unreachable")
+ // }
+ case r >= 256: // ELF
+ nr := r - 256
+ switch arch.Family {
+ case sys.AMD64:
+ return elf.R_X86_64(nr).String()
+ case sys.ARM:
+ return elf.R_ARM(nr).String()
+ case sys.ARM64:
+ return elf.R_AARCH64(nr).String()
+ case sys.I386:
+ return elf.R_386(nr).String()
+ case sys.MIPS, sys.MIPS64:
+ // return elf.R_MIPS(nr).String()
+ case sys.PPC64:
+ // return elf.R_PPC64(nr).String()
+ case sys.S390X:
+ // return elf.R_390(nr).String()
+ default:
+ panic("unreachable")
+ }
+ }
+
+ return r.String()
+}
--- /dev/null
+// Inferno utils/8l/asm.c
+// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/8l/asm.c
+//
+// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+// Portions Copyright © 1997-1999 Vita Nuova Limited
+// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+// Portions Copyright © 2004,2006 Bruce Ellis
+// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+// Portions Copyright © 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+package sym
+
+// Terrible but standard terminology.
+// A segment describes a block of file to load into memory.
+// A section further describes the pieces of that block for
+// use in debuggers and such.
+
+type Segment struct {
+ Rwx uint8 // permission as usual unix bits (5 = r-x etc)
+ Vaddr uint64 // virtual address
+ Length uint64 // length in memory
+ Fileoff uint64 // file offset
+ Filelen uint64 // length on disk
+ Sections []*Section
+}
+
+type Section struct {
+ Rwx uint8
+ Extnum int16
+ Align int32
+ Name string
+ Vaddr uint64
+ Length uint64
+ Seg *Segment
+ Elfsect interface{} // an *ld.ElfShdr
+ Reloff uint64
+ Rellen uint64
+}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package ld
+package sym
import (
"cmd/internal/objabi"
}
func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
- return s.addUintXX(arch, uint64(v), 2)
+ return s.AddUintXX(arch, uint64(v), 2)
}
func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
- return s.addUintXX(arch, uint64(v), 4)
+ return s.AddUintXX(arch, uint64(v), 4)
}
func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
- return s.addUintXX(arch, v, 8)
+ return s.AddUintXX(arch, v, 8)
}
func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
- return s.addUintXX(arch, v, arch.PtrSize)
+ return s.AddUintXX(arch, v, arch.PtrSize)
}
func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
return &s.R[len(s.R)-1]
}
-func (s *Symbol) addUintXX(arch *sys.Arch, v uint64, wid int) int64 {
+func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
off := s.Size
s.setUintXX(arch, off, v, int64(wid))
return off
return off + wid
}
+
+type FuncInfo struct {
+ Args int32
+ Locals int32
+ Autom []Auto
+ Pcsp Pcdata
+ Pcfile Pcdata
+ Pcline Pcdata
+ Pcinline Pcdata
+ Pcdata []Pcdata
+ Funcdata []*Symbol
+ Funcdataoff []int64
+ File []*Symbol
+ InlTree []InlinedCall
+}
+
+// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
+type InlinedCall struct {
+ Parent int32 // index of parent in InlTree
+ File *Symbol // file of the inlined call
+ Line int32 // line number of the inlined call
+ Func *Symbol // function that was inlined
+}
+
+type Pcdata struct {
+ P []byte
+}
+
+type Auto struct {
+ Asym *Symbol
+ Gotype *Symbol
+ Aoffset int32
+ Name int16
+}
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-package ld
+package sym
type Symbols struct {
symbolBatch []Symbol
Allsym []*Symbol
}
-func (syms *Symbols) newsym(name string, v int) *Symbol {
+func NewSymbols() *Symbols {
+ return &Symbols{
+ hash: []map[string]*Symbol{
+ // preallocate about 2mb for hash of
+ // non static symbols
+ make(map[string]*Symbol, 100000),
+ },
+ Allsym: make([]*Symbol, 0, 100000),
+ }
+}
+
+func (syms *Symbols) Newsym(name string, v int) *Symbol {
batch := syms.symbolBatch
if len(batch) == 0 {
batch = make([]Symbol, 1000)
if s != nil {
return s
}
- s = syms.newsym(name, v)
+ s = syms.Newsym(name, v)
s.Extname = s.Name
m[name] = s
return s
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-package ld
+package sym
// A SymKind describes the kind of memory represented by a symbol.
type SymKind int16
SCONTAINER = SymKind(1 << 10) // has a sub-symbol
)
-// abiSymKindToSymKind maps values read from object files (which are
+// AbiSymKindToSymKind maps values read from object files (which are
// of type cmd/internal/objabi.SymKind) to values of type SymKind.
-var abiSymKindToSymKind = [...]SymKind{
+var AbiSymKindToSymKind = [...]SymKind{
Sxxx,
STEXT,
SRODATA,
SDWARFLOC,
}
-// readOnly are the symbol kinds that form read-only sections. In some
+// ReadOnly are the symbol kinds that form read-only sections. In some
// cases, if they will require relocations, they are transformed into
// rel-ro sections using relROMap.
-var readOnly = []SymKind{
+var ReadOnly = []SymKind{
STYPE,
SSTRING,
SGOSTRING,
SFUNCTAB,
}
-// relROMap describes the transformation of read-only symbols to rel-ro
+// RelROMap describes the transformation of read-only symbols to rel-ro
// symbols.
-var relROMap = map[SymKind]SymKind{
+var RelROMap = map[SymKind]SymKind{
STYPE: STYPERELRO,
SSTRING: SSTRINGRELRO,
SGOSTRING: SGOSTRINGRELRO,
// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
-package ld
+package sym
import "fmt"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
+ "cmd/link/internal/sym"
"log"
)
// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
-func addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) {
- s.Attr |= ld.AttrReachable
+func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
+ s.Attr |= sym.AttrReachable
i := s.Size
s.Size += 4
s.Grow(s.Size)
}
// Generate little thunks that load the PC of the next instruction into a register.
- thunks := make([]*ld.Symbol, 0, 7+len(ctxt.Textp))
+ thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
for _, r := range [...]struct {
name string
num uint8
{"di", 7},
} {
thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
- thunkfunc.Type = ld.STEXT
- thunkfunc.Attr |= ld.AttrLocal
- thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
+ thunkfunc.Type = sym.STEXT
+ thunkfunc.Attr |= sym.AttrLocal
+ thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
o := func(op ...uint8) {
for _, op1 := range op {
thunkfunc.AddUint8(op1)
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == ld.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
- addmoduledata.Attr |= ld.AttrReachable
+ addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
- initfunc.Type = ld.STEXT
- initfunc.Attr |= ld.AttrLocal
- initfunc.Attr |= ld.AttrReachable
+ initfunc.Type = sym.STEXT
+ initfunc.Attr |= sym.AttrLocal
+ initfunc.Attr |= sym.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
initfunc.AddUint8(op1)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
- initarray_entry.Attr |= ld.AttrReachable
- initarray_entry.Attr |= ld.AttrLocal
- initarray_entry.Type = ld.SINITARR
+ initarray_entry.Attr |= sym.AttrReachable
+ initarray_entry.Attr |= sym.AttrLocal
+ initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
+func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= 256 {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, ld.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
return false
}
// Handle relocations found in ELF object files.
case 256 + ld.R_386_PC32:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
}
- if targ.Type == 0 || targ.Type == ld.SXREF {
+ if targ.Type == 0 || targ.Type == sym.SXREF {
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
}
r.Type = objabi.R_PCREL
case 256 + ld.R_386_PLT32:
r.Type = objabi.R_PCREL
r.Add += 4
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add += int64(targ.Plt)
return true
case 256 + ld.R_386_GOT32, 256 + ld.R_386_GOT32X:
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
// have symbol
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
// turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
return true
case 256 + ld.R_386_32:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_ADDR
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
r.Type = objabi.R_ADDR
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
}
return true
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
- if targ.Type == ld.SDYNIMPORT {
+ if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Add = int64(targ.Plt)
return true
case 512 + ld.MACHO_FAKE_GOTPCREL:
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
// have symbol
// turn MOVL of GOT entry into LEAL of symbol itself
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
}
// Handle references to ELF symbols from our own object files.
- if targ.Type != ld.SDYNIMPORT {
+ if targ.Type != sym.SDYNIMPORT {
return true
}
switch r.Type {
return true
case objabi.R_ADDR:
- if s.Type != ld.SDATA {
+ if s.Type != sym.SDATA {
break
}
if ld.Iself {
ld.Adddynsym(ctxt, targ)
got := ctxt.Syms.Lookup(".got", 0)
- s.Type = got.Type | ld.SSUB
+ s.Type = got.Type | sym.SSUB
s.Outer = got
s.Sub = got.Sub
got.Sub = s
return false
}
-func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
+func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write32(uint32(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
}
case objabi.R_CALL:
if r.Siz == 4 {
- if r.Xsym.Type == ld.SDYNIMPORT {
+ if r.Xsym.Type == sym.SDYNIMPORT {
ctxt.Out.Write32(ld.R_386_PLT32 | uint32(elfsym)<<8)
} else {
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8)
return true
}
-func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
- if rs.Type == ld.SHOSTOBJ {
+ if rs.Type == sym.SHOSTOBJ {
if rs.Dynid < 0 {
- ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+ 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)
return false
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
+ 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)
return false
}
}
return true
}
-func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
+func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
if rs.Dynid < 0 {
- ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
+ 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)
return false
}
return true
}
-func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
+func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
return false
}
return false
}
-func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
+func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant")
return t
}
}
}
-func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
+func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
}
}
-func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
+func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}