cmd/link: put symbol data types in new package

For #22095

Change-Id: I07c288208d94dabae164c2ca0a067402a8e5c2e6
Reviewed-on: https://go-review.googlesource.com/68331
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
David Crawshaw 2017-10-04 17:54:04 -04:00
parent 24e4a128c9
commit 475d92ba4d
36 changed files with 1536 additions and 1457 deletions

View file

@ -70,6 +70,7 @@ var bootstrapDirs = []string{
"cmd/link/internal/mips64",
"cmd/link/internal/ppc64",
"cmd/link/internal/s390x",
"cmd/link/internal/sym",
"cmd/link/internal/x86",
"debug/pe",
"math/big",

View file

@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"debug/elf"
"log"
)
@ -42,8 +43,8 @@ func PADDR(x uint32) uint32 {
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)
@ -60,16 +61,16 @@ func gentext(ctxt *ld.Link) {
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)
@ -91,28 +92,28 @@ func gentext(ctxt *ld.Link) {
}
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
@ -120,10 +121,10 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -133,7 +134,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -142,7 +143,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -165,7 +166,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -178,13 +179,13 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
// 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)
@ -201,13 +202,13 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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 {
@ -223,7 +224,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
// 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)
@ -236,7 +237,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
}
@ -247,7 +248,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -308,7 +309,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
// 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
}
}
@ -345,7 +346,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -360,7 +361,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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()
@ -389,7 +390,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
}
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 {
@ -403,7 +404,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
}
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)
@ -423,14 +424,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
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
}
@ -439,7 +440,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
} 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
}
}
@ -486,13 +487,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
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
}
@ -523,11 +524,11 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff
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
}
@ -559,7 +560,7 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
@ -627,7 +628,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
}
func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}
@ -838,7 +839,7 @@ func asmb(ctxt *ld.Link) {
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,
//

View file

@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"fmt"
"log"
)
@ -64,16 +65,16 @@ func gentext(ctxt *ld.Link) {
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)
}
@ -101,9 +102,9 @@ func gentext(ctxt *ld.Link) {
}
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)
}
@ -113,13 +114,13 @@ func braddoff(a int32, b int32) int32 {
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
}
@ -127,7 +128,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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))
@ -140,7 +141,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -152,7 +153,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -177,7 +178,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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))
@ -192,7 +193,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -211,7 +212,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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))
@ -221,7 +222,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
}
// Handle references to ELF symbols from our own object files.
if targ.Type != ld.SDYNIMPORT {
if targ.Type != sym.SDYNIMPORT {
return true
}
@ -233,7 +234,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
return true
case objabi.R_ADDR:
if s.Type != ld.SDATA {
if s.Type != sym.SDATA {
break
}
if ld.Iself {
@ -250,7 +251,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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()
@ -321,13 +322,13 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
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
}
@ -356,9 +357,9 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
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
}
@ -367,7 +368,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
} 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
}
}
@ -422,7 +423,7 @@ func immrot(v uint32) uint32 {
}
// 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
@ -433,11 +434,11 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
// 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
}
@ -475,12 +476,12 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
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)
@ -502,7 +503,7 @@ func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
}
// 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
@ -523,7 +524,7 @@ func gentramppic(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
}
// 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
@ -562,7 +563,7 @@ func gentrampdyn(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
}
}
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:
@ -578,7 +579,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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
@ -642,27 +643,27 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.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 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
}
@ -701,7 +702,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
}
func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) {
func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}
@ -717,7 +718,7 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) {
}
}
func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}

View file

@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"log"
@ -44,16 +45,16 @@ func gentext(ctxt *ld.Link) {
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)
}
@ -81,18 +82,18 @@ func gentext(ctxt *ld.Link) {
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()
@ -143,7 +144,7 @@ func elfsetupplt(ctxt *ld.Link) {
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
@ -151,9 +152,9 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
// 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
}
@ -162,7 +163,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
} 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
}
}
@ -215,7 +216,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
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:
@ -237,7 +238,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
// (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)
}
@ -261,7 +262,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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
@ -367,7 +368,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.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 -1
}

View file

@ -33,6 +33,7 @@ package ld
import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
@ -105,7 +106,7 @@ func hostArchive(ctxt *Link, name string) {
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

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"fmt"
"strings"
"unicode"
@ -112,13 +113,13 @@ func deadcode(ctxt *Link) {
// (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)
@ -132,11 +133,11 @@ func deadcode(ctxt *Link) {
// 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 {
@ -148,13 +149,13 @@ func (m methodref) isExported() bool {
// 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 {
@ -167,7 +168,7 @@ func (d *deadcodepass) cleanupReloc(r *Reloc) {
}
// 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
}
@ -181,7 +182,7 @@ func (d *deadcodepass) mark(s, parent *Symbol) {
}
fmt.Printf("%s -> %s\n", p, s.Name)
}
s.Attr |= AttrReachable
s.Attr |= sym.AttrReachable
s.Reachparent = parent
d.markQueue = append(d.markQueue, s)
}
@ -208,7 +209,7 @@ func (d *deadcodepass) init() {
// 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)
}
}
@ -257,7 +258,7 @@ func (d *deadcodepass) flood() {
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)
}

View file

@ -8,6 +8,7 @@ import (
"bytes"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/elf"
"fmt"
)
@ -28,7 +29,7 @@ const (
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]
@ -37,7 +38,7 @@ func decodeReloc(s *Symbol, off int32) *Reloc {
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
@ -64,27 +65,27 @@ func structfieldSize(arch *sys.Arch) int { return 3 * arch.PtrSize } // ru
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
}
@ -103,8 +104,8 @@ func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
}
// 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 {
@ -122,7 +123,7 @@ func decodetypeGcprog(ctxt *Link, s *Symbol) []byte {
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 {
@ -134,8 +135,8 @@ func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 {
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)
@ -152,48 +153,48 @@ func decodetypeGcmask(ctxt *Link, s *Symbol) []byte {
}
// 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
@ -204,16 +205,16 @@ func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol {
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()
@ -223,7 +224,7 @@ func decodetypeStructFieldArrayOff(arch *sys.Arch, s *Symbol, i int) int {
}
// 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:]
@ -232,7 +233,7 @@ func decodetypeStr(arch *sys.Arch, s *Symbol) string {
}
// 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 ""
@ -243,27 +244,27 @@ func decodetypeName(s *Symbol, off int) string {
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))
}
@ -290,7 +291,7 @@ const (
// 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++ {
@ -322,7 +323,7 @@ func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsi
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))
}
@ -339,7 +340,7 @@ func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig {
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))
}

View file

@ -17,6 +17,7 @@ import (
"cmd/internal/dwarf"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"fmt"
"log"
"os"
@ -31,37 +32,37 @@ func (c dwctxt) PtrSize() int {
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
@ -70,11 +71,11 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
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
}
@ -136,10 +137,10 @@ func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version in
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
}
}
@ -162,7 +163,7 @@ func walktypedef(die *dwarf.DWDie) *dwarf.DWDie {
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
}
@ -187,18 +188,18 @@ func findchild(die *dwarf.DWDie, name string) *dwarf.DWDie {
// 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)
@ -206,7 +207,7 @@ func mustFind(ctxt *Link, name string) *Symbol {
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:
@ -222,14 +223,14 @@ func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 {
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)
}
@ -238,14 +239,14 @@ func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDi
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]
@ -253,7 +254,7 @@ func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie
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))
@ -292,13 +293,13 @@ func newmemberoffsetattr(die *dwarf.DWDie, offs int32) {
// 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)
@ -325,10 +326,10 @@ func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) {
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
@ -336,11 +337,11 @@ func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) {
// 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>")
}
@ -358,10 +359,10 @@ func defgotype(ctxt *Link, gotype *Symbol) *Symbol {
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)
@ -433,7 +434,7 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
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)
@ -455,7 +456,7 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
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 {
@ -529,12 +530,12 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
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 {
@ -570,7 +571,7 @@ func copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) {
// 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",
@ -620,7 +621,7 @@ func synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
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))
}
}
@ -644,11 +645,11 @@ const (
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)
@ -668,7 +669,7 @@ func synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
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)
@ -764,7 +765,7 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
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))
@ -797,30 +798,30 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
}
// 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
@ -847,7 +848,7 @@ func movetomodule(parent *dwarf.DWDie) {
}
// 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
}
@ -875,7 +876,7 @@ const (
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
@ -976,9 +977,9 @@ func getCompilationDir() string {
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 {
@ -991,20 +992,20 @@ func importInfoSymbol(ctxt *Link, dsym *Symbol) {
}
}
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
@ -1161,10 +1162,10 @@ func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
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)
@ -1267,29 +1268,29 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
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)
@ -1304,11 +1305,11 @@ const (
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)
@ -1333,7 +1334,7 @@ func writeinfo(ctxt *Link, syms []*Symbol, funcs, consts []*Symbol, abbrevsym *S
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
@ -1373,9 +1374,9 @@ func ispubtype(die *dwarf.DWDie) bool {
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 {
@ -1413,9 +1414,9 @@ func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*S
* 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
@ -1444,10 +1445,10 @@ func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
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)
@ -1455,7 +1456,7 @@ func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
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
@ -1468,7 +1469,7 @@ func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol {
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)
@ -1556,7 +1557,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
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)
@ -1565,7 +1566,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
}
abbrev := writeabbrev(ctxt)
syms := []*Symbol{abbrev}
syms := []*sym.Symbol{abbrev}
syms, funcs := writelines(ctxt, syms)
syms = writeframes(ctxt, syms)
@ -1581,7 +1582,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
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)
@ -1595,12 +1596,12 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
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.
@ -1612,8 +1613,8 @@ func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
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
@ -1622,7 +1623,7 @@ func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
/*
* Elf.
*/
func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
if *FlagW { // disable dwarf
return
}
@ -1658,20 +1659,20 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
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)
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)
}
sym = ctxt.Syms.Lookup(".debug_ranges", 0)
if sym.Sect != nil {
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
s = ctxt.Syms.Lookup(".debug_ranges", 0)
if s.Sect != nil {
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
}
}

View file

@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"crypto/sha1"
"encoding/binary"
"encoding/hex"
@ -809,7 +810,7 @@ type ElfShdr struct {
addralign uint64
entsize uint64
shnum int
secsym *Symbol
secsym *sym.Symbol
}
/*
@ -1060,7 +1061,7 @@ func elfwriteshdrs(out *OutBuf) uint32 {
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()
@ -1175,7 +1176,7 @@ func elfhash(name string) uint32 {
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)
@ -1185,11 +1186,11 @@ func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
}
}
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 {
@ -1198,7 +1199,7 @@ func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64)
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 {
@ -1446,8 +1447,8 @@ func elfdynhash(ctxt *Link) {
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
@ -1575,7 +1576,7 @@ func elfdynhash(ctxt *Link) {
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 {
@ -1597,7 +1598,7 @@ func elfphload(seg *Segment) *ElfPhdr {
return ph
}
func elfphrelro(seg *Segment) {
func elfphrelro(seg *sym.Segment) {
ph := newElfPhdr()
ph.type_ = PT_GNU_RELRO
ph.vaddr = seg.Vaddr
@ -1640,20 +1641,20 @@ func elfshnamedup(name string) *ElfShdr {
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)
}
@ -1712,7 +1713,7 @@ func elfshbits(sect *Section) *ElfShdr {
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 {
@ -1721,7 +1722,7 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
return nil
}
if sect.Elfsect.type_ == SHT_NOTE {
if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
return nil
}
@ -1737,7 +1738,7 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
// 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)
}
}
@ -1748,14 +1749,14 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
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 {
@ -1777,30 +1778,30 @@ func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
}
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)
}
}
}
@ -1837,8 +1838,8 @@ func Elfemitreloc(ctxt *Link) {
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
@ -1867,8 +1868,8 @@ func (ctxt *Link) doelf() {
/* 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")
@ -1975,8 +1976,8 @@ func (ctxt *Link) doelf() {
/* 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 {
@ -1986,8 +1987,8 @@ func (ctxt *Link) doelf() {
/* 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, "")
}
@ -1995,62 +1996,62 @@ func (ctxt *Link) doelf() {
/* 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
@ -2102,10 +2103,10 @@ func (ctxt *Link) doelf() {
// 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))
@ -2128,7 +2129,7 @@ func (ctxt *Link) doelf() {
}
// 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)
@ -2579,7 +2580,7 @@ elfobj:
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)
}
}
@ -2682,7 +2683,7 @@ elfobj:
}
}
func elfadddynsym(ctxt *Link, s *Symbol) {
func elfadddynsym(ctxt *Link, s *sym.Symbol) {
if elf64 {
s.Dynid = int32(Nelfsym)
Nelfsym++
@ -2695,7 +2696,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
/* 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
@ -2706,14 +2707,14 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
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)
@ -2737,7 +2738,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
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)
@ -2750,9 +2751,9 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
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
@ -2761,7 +2762,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
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)

View file

@ -10,6 +10,7 @@ import (
"bytes"
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/link/internal/sym"
"fmt"
"io"
"os"
@ -128,7 +129,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
var next string
var q string
var lib string
var s *Symbol
var s *sym.Symbol
p0 := ""
for ; p != ""; p = next {
@ -184,12 +185,12 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
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
}
@ -203,7 +204,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
}
local := f[1]
s = ctxt.Syms.Lookup(local, 0)
s.Type = SHOSTOBJ
s.Type = sym.SHOSTOBJ
s.Size = 0
continue
}
@ -248,9 +249,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
}
if f[0] == "cgo_export_static" {
s.Attr |= AttrCgoExportStatic
s.Attr |= sym.AttrCgoExportStatic
} else {
s.Attr |= AttrCgoExportDynamic
s.Attr |= sym.AttrCgoExportDynamic
}
continue
}
@ -308,7 +309,7 @@ func adddynlib(ctxt *Link, lib string) {
}
}
func Adddynsym(ctxt *Link, s *Symbol) {
func Adddynsym(ctxt *Link, s *sym.Symbol) {
if s.Dynid >= 0 || Linkmode == LinkExternal {
return
}
@ -329,8 +330,8 @@ func fieldtrack(ctxt *Link) {
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 {
@ -340,7 +341,7 @@ func fieldtrack(ctxt *Link) {
buf.WriteString("\n")
}
s.Type = SCONST
s.Type = sym.SCONST
s.Value = 0
}
}
@ -353,7 +354,7 @@ func fieldtrack(ctxt *Link) {
return
}
addstrdata(ctxt, *flagFieldTrack, buf.String())
s.Type = SDATA
s.Type = sym.SDATA
}
func (ctxt *Link) addexport() {

View file

@ -5,6 +5,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
@ -266,7 +267,7 @@ type ElfSect struct {
align uint64
entsize uint64
base []byte
sym *Symbol
sym *sym.Symbol
}
type ElfObj struct {
@ -305,7 +306,7 @@ type ElfSym struct {
type_ uint8
other uint8
shndx uint16
sym *Symbol
sym *sym.Symbol
}
var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
@ -711,21 +712,21 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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
@ -739,57 +740,57 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
// 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
@ -799,26 +800,26 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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)
}
}
}
@ -833,17 +834,17 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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)
}
}
@ -868,7 +869,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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
@ -908,18 +909,18 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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)
@ -985,7 +986,7 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
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
@ -998,44 +999,44 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc
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.
@ -1044,25 +1045,25 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc
// 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
@ -1072,34 +1073,34 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc
// 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)

View file

@ -4,6 +4,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
@ -92,7 +93,7 @@ type ldMachoSect struct {
flags uint32
res1 uint32
res2 uint32
sym *Symbol
sym *sym.Symbol
rel []ldMachoRel
}
@ -123,7 +124,7 @@ type ldMachoSym struct {
desc uint16
kind int8
value uint64
sym *Symbol
sym *sym.Symbol
}
type ldMachoDysymtab struct {
@ -428,15 +429,14 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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()
@ -597,16 +597,16 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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
}
}
@ -616,35 +616,35 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
// 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)
@ -658,22 +658,22 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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.
@ -697,17 +697,17 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
}
}
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)
}
}
@ -724,7 +724,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
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++ {

View file

@ -8,6 +8,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/pe"
"errors"
"fmt"
@ -132,7 +133,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
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
@ -167,22 +168,22 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
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
@ -214,7 +215,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
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) {
@ -314,11 +315,11 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
}
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)
}
@ -346,15 +347,15 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
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
}
}
@ -368,17 +369,17 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
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)
}
}
@ -391,14 +392,14 @@ func issect(s *pe.COFFSymbol) bool {
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_") {
@ -414,27 +415,27 @@ func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Sect
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_

View file

@ -36,6 +36,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"crypto/sha1"
"debug/elf"
"encoding/base64"
@ -97,17 +98,17 @@ type Arch struct {
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.
@ -115,7 +116,7 @@ type Arch struct {
// 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 (
@ -126,37 +127,10 @@ 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 {
@ -183,7 +157,7 @@ func UseRelro() bool {
}
var (
dynexp []*Symbol
dynexp []*sym.Symbol
dynlib []string
ldflag []string
havedynamic int
@ -201,11 +175,11 @@ var (
)
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 */
@ -359,11 +333,11 @@ func (ctxt *Link) loadlib() {
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)
}
@ -414,7 +388,7 @@ func (ctxt *Link) loadlib() {
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 {
@ -438,13 +412,13 @@ func (ctxt *Link) loadlib() {
// 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
}
@ -457,22 +431,22 @@ func (ctxt *Link) loadlib() {
// 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
@ -484,14 +458,14 @@ func (ctxt *Link) loadlib() {
// 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)
}
@ -499,19 +473,19 @@ func (ctxt *Link) loadlib() {
// 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++ {
@ -531,7 +505,7 @@ func (ctxt *Link) loadlib() {
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
}
@ -618,8 +592,8 @@ func (ctxt *Link) loadlib() {
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
}
}
@ -638,7 +612,7 @@ func (ctxt *Link) loadlib() {
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
@ -654,9 +628,9 @@ func (ctxt *Link) loadlib() {
// 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)
}
}
@ -676,12 +650,12 @@ func (ctxt *Link) loadlib() {
// 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
}
@ -1181,7 +1155,7 @@ func (l *Link) hostlink() {
// 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) {
@ -1626,7 +1600,7 @@ func ldshlibsyms(ctxt *Link, shlib string) {
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
@ -1636,10 +1610,10 @@ func ldshlibsyms(ctxt *Link, shlib string) {
// 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 {
@ -1653,7 +1627,7 @@ func ldshlibsyms(ctxt *Link, shlib string) {
}
}
}
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 {
@ -1682,8 +1656,8 @@ func ldshlibsyms(ctxt *Link, shlib string) {
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
@ -1713,12 +1687,12 @@ func Be32(b []byte) uint32 {
}
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.
@ -1785,7 +1759,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
if s.Attr.StackCheck() {
return 0
}
s.Attr |= AttrStackCheck
s.Attr |= sym.AttrStackCheck
}
if depth > 100 {
@ -1799,7 +1773,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
// 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")
@ -1845,7 +1819,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
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).
@ -1947,11 +1921,11 @@ const (
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
@ -1975,14 +1949,14 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
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
@ -1998,36 +1972,36 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
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
}
@ -2036,18 +2010,18 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
}
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)
}
@ -2103,23 +2077,23 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
}
}
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)
}
@ -2139,21 +2113,21 @@ func Entryvalue(ctxt *Link) int64 {
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 {
@ -2180,14 +2154,14 @@ func (ctxt *Link) callgraph() {
}
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)
}
}

View file

@ -34,124 +34,17 @@ import (
"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
@ -159,7 +52,7 @@ type Shlib struct {
type Link struct {
Out *OutBuf
Syms *Symbols
Syms *sym.Symbols
Arch *sys.Arch
Debugvlog int
@ -167,20 +60,20 @@ type Link struct {
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
@ -214,8 +107,8 @@ type Library struct {
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 {
@ -233,35 +126,8 @@ func (l *Library) addImports(ctxt *Link, pn 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
@ -270,66 +136,3 @@ type Pciter struct {
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()
}

View file

@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"sort"
"strings"
)
@ -169,7 +170,7 @@ const (
var nkind [NumSymKind]int
var sortsym []*Symbol
var sortsym []*sym.Symbol
var nsortsym int
@ -346,32 +347,32 @@ func (ctxt *Link) domacho() {
// 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
}
}
@ -396,7 +397,7 @@ func machoadddynlib(lib string) {
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
@ -647,8 +648,8 @@ func Asmbmacho(ctxt *Link) {
}
}
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() {
@ -657,7 +658,7 @@ func symkind(s *Symbol) int {
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
}
@ -678,7 +679,7 @@ func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, go
nsortsym++
}
type machoscmp []*Symbol
type machoscmp []*sym.Symbol
func (x machoscmp) Len() int {
return len(x)
@ -704,7 +705,7 @@ func (x machoscmp) Less(i, j int) bool {
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)
}
@ -717,10 +718,10 @@ func machosymorder(ctxt *Link) {
// 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]))
@ -733,7 +734,7 @@ func machosymorder(ctxt *Link) {
//
// 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
}
@ -752,7 +753,7 @@ func machoShouldExport(ctxt *Link, s *Symbol) bool {
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) {
@ -780,11 +781,11 @@ 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)
@ -802,7 +803,7 @@ func machosymtab(ctxt *Link) {
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)
}
}
}
@ -889,7 +890,7 @@ func Domacholink(ctxt *Link) int64 {
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
@ -907,27 +908,27 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
}
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)
}
}
}

View file

@ -13,6 +13,7 @@ import (
"cmd/internal/dwarf"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"io"
"log"
"strconv"
@ -30,27 +31,27 @@ var emptyPkg = []byte(`"".`)
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,
@ -58,7 +59,7 @@ func LoadObjFile(arch *sys.Arch, syms *Symbols, f *bio.Reader, lib *Library, len
arch: arch,
syms: syms,
pn: pn,
dupSym: &Symbol{Name: ".dup"},
dupSym: &sym.Symbol{Name: ".dup"},
localSymVersion: syms.IncVersion(),
}
r.loadObjFile()
@ -90,8 +91,8 @@ func (r *objReader) 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 {
@ -134,16 +135,16 @@ func (r *objReader) readSlices() {
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.
@ -158,7 +159,7 @@ func (r *objReader) readSym() {
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
@ -171,9 +172,9 @@ func (r *objReader) readSym() {
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)
}
@ -183,10 +184,10 @@ func (r *objReader) readSym() {
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 {
@ -199,23 +200,23 @@ func (r *objReader) readSym() {
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
}
@ -230,7 +231,7 @@ overwrite:
}
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()),
@ -240,21 +241,21 @@ overwrite:
}
}
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]
@ -263,7 +264,7 @@ overwrite:
}
for i := 0; i < n; i++ {
pc.Autom[i] = Auto{
pc.Autom[i] = sym.Auto{
Asym: r.readSymIndex(),
Aoffset: r.readInt32(),
Name: r.readInt16(),
@ -305,7 +306,7 @@ overwrite:
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()
@ -317,7 +318,7 @@ overwrite:
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
@ -329,12 +330,12 @@ overwrite:
}
}
}
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 {
@ -392,8 +393,8 @@ func (r *objReader) readRef() {
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 {
@ -405,10 +406,10 @@ func (r *objReader) readRef() {
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
}
}
@ -521,7 +522,7 @@ func (r *objReader) readSymName() string {
}
// 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]
}

View file

@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/src"
"cmd/link/internal/sym"
"log"
"os"
"path/filepath"
@ -58,7 +59,7 @@ func pciternext(it *Pciter) {
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
@ -70,7 +71,7 @@ func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
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++
@ -92,7 +93,7 @@ func addvarint(d *Pcdata, val uint32) {
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))
@ -101,7 +102,7 @@ func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 {
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)
@ -110,18 +111,18 @@ func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 {
}
// 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++ {
@ -130,7 +131,7 @@ func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) {
}
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
@ -163,7 +164,7 @@ func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) {
// 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
@ -171,7 +172,7 @@ func onlycsymbol(s *Symbol) bool {
return false
}
func emitPcln(s *Symbol) bool {
func emitPcln(s *sym.Symbol) bool {
if s == nil {
return true
}
@ -180,7 +181,7 @@ func emitPcln(s *Symbol) bool {
}
// 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
@ -189,20 +190,20 @@ func emitPcln(s *Symbol) bool {
// 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
@ -212,10 +213,10 @@ func (ctxt *Link) pclntab() {
// 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
}
}
@ -244,7 +245,7 @@ func (ctxt *Link) pclntab() {
}
nfunc = 0
var last *Symbol
var last *sym.Symbol
for _, s := range ctxt.Textp {
last = s
if !emitPcln(s) {
@ -262,14 +263,14 @@ func (ctxt *Link) pclntab() {
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)
@ -334,8 +335,8 @@ func (ctxt *Link) pclntab() {
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
@ -443,9 +444,9 @@ const (
// 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
@ -468,7 +469,7 @@ func (ctxt *Link) findfunctab() {
continue
}
p := s.Value
var e *Symbol
var e *sym.Symbol
i++
if i < len(ctxt.Textp) {
e = ctxt.Textp[i]

View file

@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/pe"
"encoding/binary"
"fmt"
@ -231,7 +232,7 @@ var dosstub = []uint8{
}
type Imp struct {
s *Symbol
s *sym.Symbol
off uint64
next *Imp
argsize int
@ -246,12 +247,12 @@ type Dll struct {
}
var (
rsrcsym *Symbol
rsrcsym *sym.Symbol
PESECTHEADR int32
PEFILEHEADR int32
pe64 int
dr *Dll
dexport [1024]*Symbol
dexport [1024]*sym.Symbol
nexport int
)
@ -308,7 +309,7 @@ func (sect *peSection) checkOffset(off int64) {
// 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()
@ -481,7 +482,7 @@ func (f *peFile) emitRelocations(ctxt *Link) {
// 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
@ -574,7 +575,7 @@ dwarfLoop:
// writeSymbol appends symbol s to file f symbol table.
// It also sets s.Dynid to written symbol number.
func (f *peFile) writeSymbol(out *OutBuf, s *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)))
@ -594,7 +595,7 @@ func (f *peFile) writeSymbol(out *OutBuf, s *Symbol, value int64, sectidx int, t
// 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)
}
@ -608,10 +609,10 @@ func (f *peFile) mapToPESection(s *Symbol) (pesectidx int, offset int64, err err
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
@ -622,7 +623,7 @@ func (f *peFile) mapToPESection(s *Symbol) (pesectidx int, offset int64, err err
// 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
}
@ -638,7 +639,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
// 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
}
@ -659,7 +660,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
}
}
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))
@ -897,8 +898,8 @@ func Peinit(ctxt *Link) {
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
@ -947,7 +948,7 @@ func initdynimport(ctxt *Link) *Dll {
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 {
@ -989,7 +990,7 @@ func initdynimport(ctxt *Link) *Dll {
// 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
@ -997,8 +998,8 @@ func initdynimport(ctxt *Link) *Dll {
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
@ -1008,11 +1009,11 @@ func initdynimport(ctxt *Link) *Dll {
}
} 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
@ -1143,7 +1144,7 @@ func addimports(ctxt *Link, datsect *peSection) {
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] }
@ -1237,14 +1238,14 @@ func (ctxt *Link) dope() {
/* 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")
}
@ -1263,7 +1264,7 @@ func addpersrc(ctxt *Link) {
// 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]

View file

@ -34,19 +34,13 @@ package ld
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),

View file

@ -33,6 +33,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"fmt"
"path/filepath"
"strings"
@ -76,7 +77,7 @@ var numelfsym int = 1 // 0 is reserved
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 {
@ -109,7 +110,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
}
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 {
@ -120,14 +121,14 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
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
}
@ -144,7 +145,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
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" {
@ -165,13 +166,13 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
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)
@ -187,7 +188,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
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++
@ -214,7 +215,7 @@ func Asmelfsym(ctxt *Link) {
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:
@ -247,7 +248,7 @@ func Asmplan9sym(ctxt *Link) {
genasmsym(ctxt, putplan9sym)
}
var symt *Symbol
var symt *sym.Symbol
type byPkg []*Library
@ -268,8 +269,8 @@ func (libs byPkg) Swap(a, b int) {
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 {
@ -324,98 +325,98 @@ func (ctxt *Link) symtab() {
// 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.text", sym.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.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
@ -424,53 +425,53 @@ func (ctxt *Link) symtab() {
// 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
}
@ -478,8 +479,8 @@ func (ctxt *Link) symtab() {
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)
@ -488,8 +489,8 @@ func (ctxt *Link) symtab() {
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))
@ -497,13 +498,13 @@ func (ctxt *Link) symtab() {
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)))
}
@ -567,8 +568,8 @@ func (ctxt *Link) symtab() {
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)
@ -583,9 +584,9 @@ func (ctxt *Link) symtab() {
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
@ -617,9 +618,9 @@ func (ctxt *Link) symtab() {
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
@ -631,7 +632,7 @@ func (ctxt *Link) symtab() {
// modulehashes[i].runtimehash
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
abihash.Attr |= AttrReachable
abihash.Attr |= sym.AttrReachable
modulehashes.AddAddr(ctxt.Arch, abihash)
}
@ -649,8 +650,8 @@ func (ctxt *Link) symtab() {
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)
}

View file

@ -6,6 +6,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/link/internal/sym"
"sort"
)
@ -13,7 +14,7 @@ type byTypeStr []typelinkSortKey
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 }
@ -33,11 +34,11 @@ func (ctxt *Link) typelink() {
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

View file

@ -6,6 +6,7 @@ package ld
import (
"bytes"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"os"
@ -102,7 +103,7 @@ func Exitf(format string, a ...interface{}) {
//
// 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
}

View file

@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"fmt"
"log"
)
@ -42,12 +43,12 @@ func gentext(ctxt *ld.Link) {
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()
@ -76,11 +77,11 @@ func elfsetupplt(ctxt *ld.Link) {
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:
@ -92,7 +93,7 @@ func applyrel(arch *sys.Arch, r *ld.Reloc, s *ld.Symbol, val *int64, t int64) {
}
}
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:
@ -108,7 +109,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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
@ -161,7 +162,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.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 {
return -1
}

View file

@ -34,18 +34,19 @@ import (
"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
@ -93,11 +94,11 @@ func elfsetupplt(ctxt *ld.Link) {
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:
@ -114,7 +115,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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
@ -168,7 +169,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.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 {
return -1
}

View file

@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"log"
@ -88,11 +89,11 @@ func genplt(ctxt *ld.Link) {
//
// 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
}
@ -105,7 +106,7 @@ func genplt(ctxt *ld.Link) {
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.
@ -132,14 +133,14 @@ func genplt(ctxt *ld.Link) {
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)
}
@ -148,7 +149,7 @@ func genaddmoduledata(ctxt *ld.Link) {
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
@ -166,8 +167,8 @@ func genaddmoduledata(ctxt *ld.Link) {
} 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)
@ -195,9 +196,9 @@ func genaddmoduledata(ctxt *ld.Link) {
}
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)
}
@ -213,7 +214,7 @@ func gentext(ctxt *ld.Link) {
// 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.
@ -222,7 +223,7 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
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)
@ -238,7 +239,7 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
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)
@ -249,7 +250,7 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
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
@ -257,13 +258,13 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
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
}
@ -278,7 +279,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
// 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")
}
@ -289,7 +290,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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")
}
@ -297,7 +298,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -312,55 +313,55 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
}
@ -369,7 +370,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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()
@ -448,13 +449,13 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
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))
@ -470,7 +471,7 @@ func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 {
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)
@ -518,7 +519,7 @@ func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
}
// 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.
@ -536,7 +537,7 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
// 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
@ -579,11 +580,11 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
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).
@ -619,7 +620,7 @@ func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
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:
@ -646,7 +647,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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
@ -704,17 +705,17 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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
@ -740,15 +741,15 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
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
@ -774,7 +775,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
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:]))
@ -784,7 +785,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
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))
@ -795,7 +796,7 @@ overflow:
return t
}
func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
@ -841,7 +842,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
// 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

View file

@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"debug/elf"
"fmt"
)
@ -53,16 +54,16 @@ func gentext(ctxt *ld.Link) {
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)
@ -72,7 +73,7 @@ func gentext(ctxt *ld.Link) {
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)
@ -84,7 +85,7 @@ func gentext(ctxt *ld.Link) {
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)
@ -95,13 +96,13 @@ func gentext(ctxt *ld.Link) {
}
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 {
@ -121,7 +122,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -130,10 +131,10 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -149,9 +150,9 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -162,7 +163,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -186,7 +187,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -201,16 +202,16 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -219,21 +220,21 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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()
@ -275,14 +276,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
}
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:
@ -377,11 +378,11 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
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
}
@ -398,16 +399,16 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
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)
}
@ -415,7 +416,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
}
}
func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
@ -478,7 +479,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
}
func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}

View file

@ -0,0 +1,83 @@
// 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
}
}

View file

@ -0,0 +1,97 @@
// 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()
}

View file

@ -0,0 +1,58 @@
// 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
}

View file

@ -2,7 +2,7 @@
// 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"
@ -105,19 +105,19 @@ func (s *Symbol) AddUint8(v uint8) int64 {
}
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 {
@ -234,7 +234,7 @@ func (s *Symbol) AddRel() *Reloc {
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
@ -263,3 +263,37 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
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
}

View file

@ -28,7 +28,7 @@
// 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
@ -39,7 +39,18 @@ type Symbols struct {
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)
@ -65,7 +76,7 @@ func (syms *Symbols) Lookup(name string, v int) *Symbol {
if s != nil {
return s
}
s = syms.newsym(name, v)
s = syms.Newsym(name, v)
s.Extname = s.Name
m[name] = s
return s

View file

@ -28,7 +28,7 @@
// 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
@ -111,9 +111,9 @@ const (
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,
@ -127,10 +127,10 @@ var abiSymKindToSymKind = [...]SymKind{
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,
@ -140,9 +140,9 @@ var readOnly = []SymKind{
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,

View file

@ -1,6 +1,6 @@
// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
package ld
package sym
import "fmt"

View file

@ -34,12 +34,13 @@ import (
"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)
@ -67,7 +68,7 @@ func gentext(ctxt *ld.Link) {
}
// 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
@ -82,9 +83,9 @@ func gentext(ctxt *ld.Link) {
{"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)
@ -101,18 +102,18 @@ func gentext(ctxt *ld.Link) {
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)
@ -159,28 +160,28 @@ func gentext(ctxt *ld.Link) {
}
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
@ -190,7 +191,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -199,7 +200,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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.
@ -240,7 +241,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -248,13 +249,13 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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)
@ -266,7 +267,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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 {
@ -287,7 +288,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
}
// 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 {
@ -299,7 +300,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
return true
case objabi.R_ADDR:
if s.Type != ld.SDATA {
if s.Type != sym.SDATA {
break
}
if ld.Iself {
@ -326,7 +327,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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
@ -341,7 +342,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
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()
@ -366,7 +367,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
}
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)
@ -399,14 +400,14 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
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
}
@ -415,7 +416,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
} 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
}
}
@ -449,13 +450,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
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
}
@ -482,7 +483,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff
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
}
@ -498,7 +499,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.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
}
@ -530,7 +531,7 @@ func elfsetupplt(ctxt *ld.Link) {
}
}
func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Plt >= 0 {
return
}
@ -590,7 +591,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
}
func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if s.Got >= 0 {
return
}