mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
24e4a128c9
commit
475d92ba4d
36 changed files with 1536 additions and 1457 deletions
1
src/cmd/dist/buildtool.go
vendored
1
src/cmd/dist/buildtool.go
vendored
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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++ {
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
83
src/cmd/link/internal/sym/attribute.go
Normal file
83
src/cmd/link/internal/sym/attribute.go
Normal 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
|
||||
}
|
||||
}
|
||||
97
src/cmd/link/internal/sym/reloc.go
Normal file
97
src/cmd/link/internal/sym/reloc.go
Normal 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()
|
||||
}
|
||||
58
src/cmd/link/internal/sym/segment.go
Normal file
58
src/cmd/link/internal/sym/segment.go
Normal 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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
|
||||
|
||||
package ld
|
||||
package sym
|
||||
|
||||
import "fmt"
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue