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/mips64",
|
||||||
"cmd/link/internal/ppc64",
|
"cmd/link/internal/ppc64",
|
||||||
"cmd/link/internal/s390x",
|
"cmd/link/internal/s390x",
|
||||||
|
"cmd/link/internal/sym",
|
||||||
"cmd/link/internal/x86",
|
"cmd/link/internal/x86",
|
||||||
"debug/pe",
|
"debug/pe",
|
||||||
"math/big",
|
"math/big",
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
@ -42,8 +43,8 @@ func PADDR(x uint32) uint32 {
|
||||||
return x &^ 0x80000000
|
return x &^ 0x80000000
|
||||||
}
|
}
|
||||||
|
|
||||||
func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 {
|
func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 {
|
||||||
s.Attr |= ld.AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
i := s.Size
|
i := s.Size
|
||||||
s.Size += 4
|
s.Size += 4
|
||||||
s.Grow(s.Size)
|
s.Grow(s.Size)
|
||||||
|
|
@ -60,16 +61,16 @@ func gentext(ctxt *ld.Link) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
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
|
// we're linking a module containing the runtime -> no need for
|
||||||
// an init function
|
// an init function
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata.Attr |= ld.AttrReachable
|
addmoduledata.Attr |= sym.AttrReachable
|
||||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||||
initfunc.Type = ld.STEXT
|
initfunc.Type = sym.STEXT
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= sym.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= sym.AttrReachable
|
||||||
o := func(op ...uint8) {
|
o := func(op ...uint8) {
|
||||||
for _, op1 := range op {
|
for _, op1 := range op {
|
||||||
initfunc.AddUint8(op1)
|
initfunc.AddUint8(op1)
|
||||||
|
|
@ -91,28 +92,28 @@ func gentext(ctxt *ld.Link) {
|
||||||
}
|
}
|
||||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= sym.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= sym.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = sym.SINITARR
|
||||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
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
|
targ := r.Sym
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
if r.Type >= 256 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle relocations found in ELF object files.
|
// Handle relocations found in ELF object files.
|
||||||
case 256 + ld.R_X86_64_PC32:
|
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)
|
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)
|
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
|
|
@ -120,10 +121,10 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_X86_64_PC64:
|
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)
|
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)
|
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_PCREL
|
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:
|
case 256 + ld.R_X86_64_PLT32:
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
r.Add += 4
|
r.Add += 4
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add += int64(targ.Plt)
|
r.Add += int64(targ.Plt)
|
||||||
|
|
@ -142,7 +143,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_X86_64_GOTPCREL, 256 + ld.R_X86_64_GOTPCRELX, 256 + ld.R_X86_64_REX_GOTPCRELX:
|
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
|
// have symbol
|
||||||
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
|
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
|
||||||
// turn MOVQ of GOT entry into LEAQ of symbol itself
|
// 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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_X86_64_64:
|
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)
|
ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_ADDR
|
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?
|
// TODO: What is the difference between all these?
|
||||||
r.Type = objabi.R_ADDR
|
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)
|
ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
|
case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add = int64(targ.Plt)
|
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:
|
512 + ld.MACHO_X86_64_RELOC_SIGNED_4*2 + 1:
|
||||||
r.Type = objabi.R_PCREL
|
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)
|
ld.Errorf(s, "unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 512 + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
|
case 512 + ld.MACHO_X86_64_RELOC_GOT_LOAD*2 + 1:
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
// have symbol
|
// have symbol
|
||||||
// turn MOVQ of GOT entry into LEAQ of symbol itself
|
// turn MOVQ of GOT entry into LEAQ of symbol itself
|
||||||
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
|
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
|
// fall through
|
||||||
case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
|
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)
|
ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
addgotsym(ctxt, targ)
|
addgotsym(ctxt, targ)
|
||||||
|
|
@ -236,7 +237,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case objabi.R_CALL,
|
case objabi.R_CALL,
|
||||||
objabi.R_PCREL:
|
objabi.R_PCREL:
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
// nothing to do, the relocation will be laid out in reloc
|
// nothing to do, the relocation will be laid out in reloc
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -247,7 +248,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case objabi.R_ADDR:
|
case objabi.R_ADDR:
|
||||||
if s.Type == ld.STEXT && ld.Iself {
|
if s.Type == sym.STEXT && ld.Iself {
|
||||||
if ld.Headtype == objabi.Hsolaris {
|
if ld.Headtype == objabi.Hsolaris {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
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
|
// linking, in which case the relocation will be
|
||||||
// prepared in the 'reloc' phase and passed to the
|
// prepared in the 'reloc' phase and passed to the
|
||||||
// external linker in the 'asmb' phase.
|
// 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
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -345,7 +346,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
ld.Adddynsym(ctxt, targ)
|
ld.Adddynsym(ctxt, targ)
|
||||||
|
|
||||||
got := ctxt.Syms.Lookup(".got", 0)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Type = got.Type | ld.SSUB
|
s.Type = got.Type | sym.SSUB
|
||||||
s.Outer = got
|
s.Outer = got
|
||||||
s.Sub = got.Sub
|
s.Sub = got.Sub
|
||||||
got.Sub = s
|
got.Sub = s
|
||||||
|
|
@ -360,7 +361,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return false
|
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))
|
ctxt.Out.Write64(uint64(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
elfsym := r.Xsym.ElfsymForReloc()
|
||||||
|
|
@ -389,7 +390,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
|
||||||
}
|
}
|
||||||
case objabi.R_CALL:
|
case objabi.R_CALL:
|
||||||
if r.Siz == 4 {
|
if r.Siz == 4 {
|
||||||
if r.Xsym.Type == ld.SDYNIMPORT {
|
if r.Xsym.Type == sym.SDYNIMPORT {
|
||||||
if ctxt.DynlinkingGo() {
|
if ctxt.DynlinkingGo() {
|
||||||
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
|
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -403,7 +404,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
|
||||||
}
|
}
|
||||||
case objabi.R_PCREL:
|
case objabi.R_PCREL:
|
||||||
if r.Siz == 4 {
|
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)
|
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
|
||||||
} else {
|
} else {
|
||||||
ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
|
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
|
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
|
var v uint32
|
||||||
|
|
||||||
rs := r.Xsym
|
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 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,7 +440,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
} else {
|
} else {
|
||||||
v = uint32(rs.Sect.Extnum)
|
v = uint32(rs.Sect.Extnum)
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -486,13 +487,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
return true
|
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
|
var v uint32
|
||||||
|
|
||||||
rs := r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if rs.Dynid < 0 {
|
if rs.Dynid < 0 {
|
||||||
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
|
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,11 +524,11 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff
|
||||||
return true
|
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
|
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")
|
log.Fatalf("unexpected relocation variant")
|
||||||
return t
|
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 {
|
if s.Plt >= 0 {
|
||||||
return
|
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 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -838,7 +839,7 @@ func asmb(ctxt *ld.Link) {
|
||||||
ctxt.Out.Flush()
|
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.
|
// Transform the PC-relative instruction into a constant load.
|
||||||
// That is,
|
// That is,
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
@ -64,16 +65,16 @@ func gentext(ctxt *ld.Link) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
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
|
// we're linking a module containing the runtime -> no need for
|
||||||
// an init function
|
// an init function
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata.Attr |= ld.AttrReachable
|
addmoduledata.Attr |= sym.AttrReachable
|
||||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||||
initfunc.Type = ld.STEXT
|
initfunc.Type = sym.STEXT
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= sym.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= sym.AttrReachable
|
||||||
o := func(op uint32) {
|
o := func(op uint32) {
|
||||||
initfunc.AddUint32(ctxt.Arch, op)
|
initfunc.AddUint32(ctxt.Arch, op)
|
||||||
}
|
}
|
||||||
|
|
@ -101,9 +102,9 @@ func gentext(ctxt *ld.Link) {
|
||||||
}
|
}
|
||||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= sym.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= sym.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = sym.SINITARR
|
||||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
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))
|
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
|
targ := r.Sym
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
if r.Type >= 256 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +128,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
case 256 + ld.R_ARM_PLT32:
|
case 256 + ld.R_ARM_PLT32:
|
||||||
r.Type = objabi.R_CALLARM
|
r.Type = objabi.R_CALLARM
|
||||||
|
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
|
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
|
return false
|
||||||
|
|
||||||
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL
|
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
addgotsyminternal(ctxt, targ)
|
addgotsyminternal(ctxt, targ)
|
||||||
} else {
|
} else {
|
||||||
addgotsym(ctxt, targ)
|
addgotsym(ctxt, targ)
|
||||||
|
|
@ -152,7 +153,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil
|
case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
addgotsyminternal(ctxt, targ)
|
addgotsyminternal(ctxt, targ)
|
||||||
} else {
|
} else {
|
||||||
addgotsym(ctxt, targ)
|
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:
|
case 256 + ld.R_ARM_CALL:
|
||||||
r.Type = objabi.R_CALLARM
|
r.Type = objabi.R_CALLARM
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
|
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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_ARM_ABS32:
|
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)
|
ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_ADDR
|
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,
|
case 256 + ld.R_ARM_PC24,
|
||||||
256 + ld.R_ARM_JUMP24:
|
256 + ld.R_ARM_JUMP24:
|
||||||
r.Type = objabi.R_CALLARM
|
r.Type = objabi.R_CALLARM
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
|
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.
|
// Handle references to ELF symbols from our own object files.
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,7 +234,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case objabi.R_ADDR:
|
case objabi.R_ADDR:
|
||||||
if s.Type != ld.SDATA {
|
if s.Type != sym.SDATA {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
|
|
@ -250,7 +251,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return false
|
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))
|
ctxt.Out.Write32(uint32(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
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
|
var v uint32
|
||||||
|
|
||||||
rs := r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if r.Type == objabi.R_PCREL {
|
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")
|
ld.Errorf(s, "pc-relative relocation of external symbol is not supported")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -356,9 +357,9 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
return true
|
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 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,7 +368,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
} else {
|
} else {
|
||||||
v = uint32(rs.Sect.Extnum)
|
v = uint32(rs.Sect.Extnum)
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
||||||
return false
|
return 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
|
// 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 {
|
switch r.Type {
|
||||||
case objabi.R_CALLARM:
|
case objabi.R_CALLARM:
|
||||||
// r.Add is the instruction
|
// 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
|
// look up existing trampolines first. if we found one within the range
|
||||||
// of direct call, we can reuse it. otherwise create a new one.
|
// of direct call, we can reuse it. otherwise create a new one.
|
||||||
offset := (signext24(r.Add&0xffffff) + 2) * 4
|
offset := (signext24(r.Add&0xffffff) + 2) * 4
|
||||||
var tramp *ld.Symbol
|
var tramp *sym.Symbol
|
||||||
for i := 0; ; i++ {
|
for i := 0; ; i++ {
|
||||||
name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
|
name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
|
||||||
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
|
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
|
// don't reuse trampoline defined in other module
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -475,12 +476,12 @@ func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
|
||||||
r.Done = false
|
r.Done = false
|
||||||
}
|
}
|
||||||
default:
|
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
|
// 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.Size = 12 // 3 instructions
|
||||||
tramp.P = make([]byte, tramp.Size)
|
tramp.P = make([]byte, tramp.Size)
|
||||||
t := ld.Symaddr(target) + int64(offset)
|
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
|
// 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.Size = 16 // 4 instructions
|
||||||
tramp.P = make([]byte, tramp.Size)
|
tramp.P = make([]byte, tramp.Size)
|
||||||
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 4) // MOVW 4(R15), R11 // R15 is actual pc + 8
|
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)
|
// 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
|
tramp.Size = 20 // 5 instructions
|
||||||
o1 := uint32(0xe5900000 | 11<<12 | 15<<16 | 8) // MOVW 8(R15), R11 // R15 is actual pc + 8
|
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
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case objabi.R_CALLARM:
|
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
|
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)
|
ld.Errorf(s, "missing section for %s", rs.Name)
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
r.Xsym = rs
|
||||||
|
|
@ -642,27 +643,27 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
log.Fatalf("unexpected relocation variant")
|
log.Fatalf("unexpected relocation variant")
|
||||||
return t
|
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 := plt.AddRel()
|
||||||
r.Sym = got
|
r.Sym = got
|
||||||
r.Off = int32(plt.Size)
|
r.Off = int32(plt.Size)
|
||||||
r.Siz = 4
|
r.Siz = 4
|
||||||
r.Type = typ
|
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.Size += 4
|
||||||
plt.Grow(plt.Size)
|
plt.Grow(plt.Size)
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||||
if s.Plt >= 0 {
|
if s.Plt >= 0 {
|
||||||
return
|
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 {
|
if s.Got >= 0 {
|
||||||
return
|
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 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
@ -44,16 +45,16 @@ func gentext(ctxt *ld.Link) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
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
|
// we're linking a module containing the runtime -> no need for
|
||||||
// an init function
|
// an init function
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata.Attr |= ld.AttrReachable
|
addmoduledata.Attr |= sym.AttrReachable
|
||||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||||
initfunc.Type = ld.STEXT
|
initfunc.Type = sym.STEXT
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= sym.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= sym.AttrReachable
|
||||||
o := func(op uint32) {
|
o := func(op uint32) {
|
||||||
initfunc.AddUint32(ctxt.Arch, op)
|
initfunc.AddUint32(ctxt.Arch, op)
|
||||||
}
|
}
|
||||||
|
|
@ -81,18 +82,18 @@ func gentext(ctxt *ld.Link) {
|
||||||
|
|
||||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= sym.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= sym.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = sym.SINITARR
|
||||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
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")
|
log.Fatalf("adddynrel not implemented")
|
||||||
return false
|
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))
|
ctxt.Out.Write64(uint64(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
elfsym := r.Xsym.ElfsymForReloc()
|
||||||
|
|
@ -143,7 +144,7 @@ func elfsetupplt(ctxt *ld.Link) {
|
||||||
return
|
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
|
var v uint32
|
||||||
|
|
||||||
rs := r.Xsym
|
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.
|
// 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
|
// see cmd/internal/ld/data.go for details. The workaround is that don't use !extern
|
||||||
// UNSIGNED relocation at all.
|
// 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 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,7 +163,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
} else {
|
} else {
|
||||||
v = uint32(rs.Sect.Extnum)
|
v = uint32(rs.Sect.Extnum)
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +216,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
return true
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
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
|
// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
|
||||||
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
|
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
|
||||||
// add + R_ADDRARM64.
|
// 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 {
|
if o2&0xffc00000 != 0xf9400000 {
|
||||||
ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
|
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
|
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)
|
ld.Errorf(s, "missing section for %s", rs.Name)
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
r.Xsym = rs
|
||||||
|
|
@ -367,7 +368,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
log.Fatalf("unexpected relocation variant")
|
log.Fatalf("unexpected relocation variant")
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -105,7 +106,7 @@ func hostArchive(ctxt *Link, name string) {
|
||||||
var load []uint64
|
var load []uint64
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
for _, s := range ctxt.Syms.Allsym {
|
||||||
for _, r := range s.R {
|
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] {
|
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
|
||||||
load = append(load, off)
|
load = append(load, off)
|
||||||
loaded[off] = true
|
loaded[off] = true
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,7 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
@ -112,13 +113,13 @@ func deadcode(ctxt *Link) {
|
||||||
// (When BuildmodeShared, always keep itablinks.)
|
// (When BuildmodeShared, always keep itablinks.)
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
for _, s := range ctxt.Syms.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.itablink.") {
|
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).
|
// 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 {
|
for _, s := range ctxt.Textp {
|
||||||
if s.Attr.Reachable() {
|
if s.Attr.Reachable() {
|
||||||
textp = append(textp, s)
|
textp = append(textp, s)
|
||||||
|
|
@ -132,11 +133,11 @@ func deadcode(ctxt *Link) {
|
||||||
// the reflect.method struct: mtyp, ifn, and tfn.
|
// the reflect.method struct: mtyp, ifn, and tfn.
|
||||||
type methodref struct {
|
type methodref struct {
|
||||||
m methodsig
|
m methodsig
|
||||||
src *Symbol // receiver type symbol
|
src *sym.Symbol // receiver type symbol
|
||||||
r [3]*Reloc // R_METHODOFF relocations to fields of runtime.method
|
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 {
|
func (m methodref) isExported() bool {
|
||||||
for _, r := range m.m {
|
for _, r := range m.m {
|
||||||
|
|
@ -148,13 +149,13 @@ func (m methodref) isExported() bool {
|
||||||
// deadcodepass holds state for the deadcode flood fill.
|
// deadcodepass holds state for the deadcode flood fill.
|
||||||
type deadcodepass struct {
|
type deadcodepass struct {
|
||||||
ctxt *Link
|
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
|
ifaceMethod map[methodsig]bool // methods declared in reached interfaces
|
||||||
markableMethods []methodref // methods of reached types
|
markableMethods []methodref // methods of reached types
|
||||||
reflectMethod bool
|
reflectMethod bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deadcodepass) cleanupReloc(r *Reloc) {
|
func (d *deadcodepass) cleanupReloc(r *sym.Reloc) {
|
||||||
if r.Sym.Attr.Reachable() {
|
if r.Sym.Attr.Reachable() {
|
||||||
r.Type = objabi.R_ADDROFF
|
r.Type = objabi.R_ADDROFF
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -167,7 +168,7 @@ func (d *deadcodepass) cleanupReloc(r *Reloc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark appends a symbol to the mark queue for flood filling.
|
// 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() {
|
if s == nil || s.Attr.Reachable() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +182,7 @@ func (d *deadcodepass) mark(s, parent *Symbol) {
|
||||||
}
|
}
|
||||||
fmt.Printf("%s -> %s\n", p, s.Name)
|
fmt.Printf("%s -> %s\n", p, s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Reachparent = parent
|
s.Reachparent = parent
|
||||||
d.markQueue = append(d.markQueue, s)
|
d.markQueue = append(d.markQueue, s)
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +209,7 @@ func (d *deadcodepass) init() {
|
||||||
// Mark all symbols defined in this library as reachable when
|
// Mark all symbols defined in this library as reachable when
|
||||||
// building a shared library.
|
// building a shared library.
|
||||||
for _, s := range d.ctxt.Syms.Allsym {
|
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)
|
d.mark(s, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -257,7 +258,7 @@ func (d *deadcodepass) flood() {
|
||||||
for len(d.markQueue) > 0 {
|
for len(d.markQueue) > 0 {
|
||||||
s := d.markQueue[0]
|
s := d.markQueue[0]
|
||||||
d.markQueue = d.markQueue[1:]
|
d.markQueue = d.markQueue[1:]
|
||||||
if s.Type == STEXT {
|
if s.Type == sym.STEXT {
|
||||||
if d.ctxt.Debugvlog > 1 {
|
if d.ctxt.Debugvlog > 1 {
|
||||||
d.ctxt.Logf("marktext %s\n", s.Name)
|
d.ctxt.Logf("marktext %s\n", s.Name)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
@ -28,7 +29,7 @@ const (
|
||||||
tflagExtraStar = 1 << 1
|
tflagExtraStar = 1 << 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func decodeReloc(s *Symbol, off int32) *Reloc {
|
func decodeReloc(s *sym.Symbol, off int32) *sym.Reloc {
|
||||||
for i := range s.R {
|
for i := range s.R {
|
||||||
if s.R[i].Off == off {
|
if s.R[i].Off == off {
|
||||||
return &s.R[i]
|
return &s.R[i]
|
||||||
|
|
@ -37,7 +38,7 @@ func decodeReloc(s *Symbol, off int32) *Reloc {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeRelocSym(s *Symbol, off int32) *Symbol {
|
func decodeRelocSym(s *sym.Symbol, off int32) *sym.Symbol {
|
||||||
r := decodeReloc(s, off)
|
r := decodeReloc(s, off)
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return 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
|
func uncommonSize() int { return 4 + 2 + 2 + 4 + 4 } // runtime.uncommontype
|
||||||
|
|
||||||
// Type.commonType.kind
|
// 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
|
return s.P[2*arch.PtrSize+7] & objabi.KindMask // 0x13 / 0x1f
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.commonType.kind
|
// 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
|
return s.P[2*arch.PtrSize+7] & objabi.KindGCProg // 0x13 / 0x1f
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.commonType.size
|
// 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
|
return int64(decodeInuxi(arch, s.P, arch.PtrSize)) // 0x8 / 0x10
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.commonType.ptrdata
|
// 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
|
return int64(decodeInuxi(arch, s.P[arch.PtrSize:], arch.PtrSize)) // 0x8 / 0x10
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.commonType.tflag
|
// 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
|
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
|
// Type.commonType.gc
|
||||||
func decodetypeGcprog(ctxt *Link, s *Symbol) []byte {
|
func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
addr := decodetypeGcprogShlib(ctxt, s)
|
addr := decodetypeGcprogShlib(ctxt, s)
|
||||||
sect := findShlibSection(ctxt, s.File, addr)
|
sect := findShlibSection(ctxt, s.File, addr)
|
||||||
if sect != nil {
|
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
|
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 {
|
if ctxt.Arch.Family == sys.ARM64 {
|
||||||
for _, shlib := range ctxt.Shlibs {
|
for _, shlib := range ctxt.Shlibs {
|
||||||
if shlib.Path == s.File {
|
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)
|
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 {
|
func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
addr := decodetypeGcprogShlib(ctxt, s)
|
addr := decodetypeGcprogShlib(ctxt, s)
|
||||||
ptrdata := decodetypePtrdata(ctxt.Arch, s)
|
ptrdata := decodetypePtrdata(ctxt.Arch, s)
|
||||||
sect := findShlibSection(ctxt, s.File, addr)
|
sect := findShlibSection(ctxt, s.File, addr)
|
||||||
|
|
@ -152,48 +153,48 @@ func decodetypeGcmask(ctxt *Link, s *Symbol) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.ArrayType.elem and Type.SliceType.Elem
|
// 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
|
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))
|
return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.PtrType.elem
|
// 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
|
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.MapType.key, elem
|
// 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
|
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
|
return decodeRelocSym(s, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.ChanType.elem
|
// 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
|
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.FuncType.dotdotdot
|
// 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
|
return uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2))&(1<<15) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.FuncType.inCount
|
// 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))
|
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))
|
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
|
uadd := commonsize(arch) + 4
|
||||||
if arch.PtrSize == 8 {
|
if arch.PtrSize == 8 {
|
||||||
uadd += 4
|
uadd += 4
|
||||||
|
|
@ -204,16 +205,16 @@ func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol {
|
||||||
return decodeRelocSym(s, int32(uadd+i*arch.PtrSize))
|
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))
|
return decodetypeFuncInType(arch, s, i+decodetypeFuncInCount(arch, s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type.StructType.fields.Slice::length
|
// 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))
|
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
|
off := commonsize(arch) + 4*arch.PtrSize
|
||||||
if decodetypeHasUncommon(arch, s) {
|
if decodetypeHasUncommon(arch, s) {
|
||||||
off += uncommonSize()
|
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).
|
// 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)
|
str := decodetypeName(s, 4*arch.PtrSize+8)
|
||||||
if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 {
|
if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 {
|
||||||
return str[1:]
|
return str[1:]
|
||||||
|
|
@ -232,7 +233,7 @@ func decodetypeStr(arch *sys.Arch, s *Symbol) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodetypeName decodes the name from a reflect.name.
|
// 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))
|
r := decodeReloc(s, int32(off))
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
@ -243,27 +244,27 @@ func decodetypeName(s *Symbol, off int) string {
|
||||||
return string(data[3 : 3+namelen])
|
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)
|
off := decodetypeStructFieldArrayOff(arch, s, i)
|
||||||
return decodetypeName(s, off)
|
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)
|
off := decodetypeStructFieldArrayOff(arch, s, i)
|
||||||
return decodeRelocSym(s, int32(off+arch.PtrSize))
|
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
|
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)
|
off := decodetypeStructFieldArrayOff(arch, s, i)
|
||||||
return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize))
|
return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InterfaceType.methods.length
|
// 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))
|
return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,7 +291,7 @@ const (
|
||||||
// the function type.
|
// the function type.
|
||||||
//
|
//
|
||||||
// Conveniently this is the layout of both runtime.method and runtime.imethod.
|
// 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 buf bytes.Buffer
|
||||||
var methods []methodsig
|
var methods []methodsig
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
|
|
@ -322,7 +323,7 @@ func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsi
|
||||||
return methods
|
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 {
|
if decodetypeKind(arch, s)&kindMask != kindInterface {
|
||||||
panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
|
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)
|
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) {
|
if !decodetypeHasUncommon(arch, s) {
|
||||||
panic(fmt.Sprintf("no methods on %q", s.Name))
|
panic(fmt.Sprintf("no methods on %q", s.Name))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"cmd/internal/dwarf"
|
"cmd/internal/dwarf"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -31,37 +32,37 @@ func (c dwctxt) PtrSize() int {
|
||||||
return c.linkctxt.Arch.PtrSize
|
return c.linkctxt.Arch.PtrSize
|
||||||
}
|
}
|
||||||
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
|
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
|
||||||
ls := s.(*Symbol)
|
ls := s.(*sym.Symbol)
|
||||||
ls.addUintXX(c.linkctxt.Arch, uint64(i), size)
|
ls.AddUintXX(c.linkctxt.Arch, uint64(i), size)
|
||||||
}
|
}
|
||||||
func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
|
func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
|
||||||
ls := s.(*Symbol)
|
ls := s.(*sym.Symbol)
|
||||||
ls.AddBytes(b)
|
ls.AddBytes(b)
|
||||||
}
|
}
|
||||||
func (c dwctxt) AddString(s dwarf.Sym, v string) {
|
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 {
|
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) {
|
func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
|
||||||
if value != 0 {
|
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) {
|
func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
|
||||||
ls := s.(*Symbol)
|
ls := s.(*sym.Symbol)
|
||||||
switch size {
|
switch size {
|
||||||
default:
|
default:
|
||||||
Errorf(ls, "invalid size %d in adddwarfref\n", size)
|
Errorf(ls, "invalid size %d in adddwarfref\n", size)
|
||||||
fallthrough
|
fallthrough
|
||||||
case c.linkctxt.Arch.PtrSize:
|
case c.linkctxt.Arch.PtrSize:
|
||||||
ls.AddAddr(c.linkctxt.Arch, t.(*Symbol))
|
ls.AddAddr(c.linkctxt.Arch, t.(*sym.Symbol))
|
||||||
case 4:
|
case 4:
|
||||||
ls.AddAddrPlus4(t.(*Symbol), 0)
|
ls.AddAddrPlus4(t.(*sym.Symbol), 0)
|
||||||
}
|
}
|
||||||
r := &ls.R[len(ls.R)-1]
|
r := &ls.R[len(ls.R)-1]
|
||||||
r.Type = objabi.R_DWARFREF
|
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 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 := ctxt.Syms.Lookup(".debug_abbrev", 0)
|
||||||
s.Type = SDWARFSECT
|
s.Type = sym.SDWARFSECT
|
||||||
s.AddBytes(dwarf.GetAbbrev())
|
s.AddBytes(dwarf.GetAbbrev())
|
||||||
return s
|
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 name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) {
|
||||||
if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 {
|
if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 {
|
||||||
sym := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
|
s := ctxt.Syms.Lookup(dwarf.InfoPrefix+name, version)
|
||||||
sym.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
sym.Type = SDWARFINFO
|
s.Type = sym.SDWARFINFO
|
||||||
die.Sym = sym
|
die.Sym = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,7 +163,7 @@ func walktypedef(die *dwarf.DWDie) *dwarf.DWDie {
|
||||||
return die
|
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 {
|
if t := ctxt.Syms.ROLookup(s.Name+"..def", int(s.Version)); t != nil {
|
||||||
return t
|
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
|
// Used to avoid string allocation when looking up dwarf symbols
|
||||||
var prefixBuf = []byte(dwarf.InfoPrefix)
|
var prefixBuf = []byte(dwarf.InfoPrefix)
|
||||||
|
|
||||||
func find(ctxt *Link, name string) *Symbol {
|
func find(ctxt *Link, name string) *sym.Symbol {
|
||||||
n := append(prefixBuf, name...)
|
n := append(prefixBuf, name...)
|
||||||
// The string allocation below is optimized away because it is only used in a map lookup.
|
// The string allocation below is optimized away because it is only used in a map lookup.
|
||||||
s := ctxt.Syms.ROLookup(string(n), 0)
|
s := ctxt.Syms.ROLookup(string(n), 0)
|
||||||
prefixBuf = n[:len(dwarf.InfoPrefix)]
|
prefixBuf = n[:len(dwarf.InfoPrefix)]
|
||||||
if s != nil && s.Type == SDWARFINFO {
|
if s != nil && s.Type == sym.SDWARFINFO {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustFind(ctxt *Link, name string) *Symbol {
|
func mustFind(ctxt *Link, name string) *sym.Symbol {
|
||||||
r := find(ctxt, name)
|
r := find(ctxt, name)
|
||||||
if r == nil {
|
if r == nil {
|
||||||
Exitf("dwarf find: cannot find %s", name)
|
Exitf("dwarf find: cannot find %s", name)
|
||||||
|
|
@ -206,7 +207,7 @@ func mustFind(ctxt *Link, name string) *Symbol {
|
||||||
return r
|
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
|
var result int64
|
||||||
switch size {
|
switch size {
|
||||||
default:
|
default:
|
||||||
|
|
@ -222,14 +223,14 @@ func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 {
|
||||||
return result
|
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 {
|
if ref == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
|
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 {
|
for ; die != nil; die = die.Link {
|
||||||
syms = putdie(linkctxt, ctxt, syms, die)
|
syms = putdie(linkctxt, ctxt, syms, die)
|
||||||
}
|
}
|
||||||
|
|
@ -238,14 +239,14 @@ func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDi
|
||||||
return syms
|
return syms
|
||||||
}
|
}
|
||||||
|
|
||||||
func dtolsym(s dwarf.Sym) *Symbol {
|
func dtolsym(s dwarf.Sym) *sym.Symbol {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return 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)
|
s := dtolsym(die.Sym)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
s = syms[len(syms)-1]
|
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() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
}
|
}
|
||||||
dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
|
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
|
// GDB doesn't like FORM_addr for AT_location, so emit a
|
||||||
// location expression that evals to a const.
|
// 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)
|
newattr(die, dwarf.DW_AT_location, dwarf.DW_CLS_ADDRESS, addr, sym)
|
||||||
// below
|
// below
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup predefined types
|
// Lookup predefined types
|
||||||
func lookupOrDiag(ctxt *Link, n string) *Symbol {
|
func lookupOrDiag(ctxt *Link, n string) *sym.Symbol {
|
||||||
s := ctxt.Syms.ROLookup(n, 0)
|
s := ctxt.Syms.ROLookup(n, 0)
|
||||||
if s == nil || s.Size == 0 {
|
if s == nil || s.Size == 0 {
|
||||||
Exitf("dwarf: missing type: %s", n)
|
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")
|
Errorf(nil, "dwarf: bad def in dotypedef")
|
||||||
}
|
}
|
||||||
|
|
||||||
sym := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
|
s := ctxt.Syms.Lookup(dtolsym(def.Sym).Name+"..def", 0)
|
||||||
sym.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
sym.Type = SDWARFINFO
|
s.Type = sym.SDWARFINFO
|
||||||
def.Sym = sym
|
def.Sym = s
|
||||||
|
|
||||||
// The typedef entry must be created after the def,
|
// The typedef entry must be created after the def,
|
||||||
// so that future lookups will find the typedef instead
|
// 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.
|
// circular definition loops, so that gdb can understand them.
|
||||||
die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0)
|
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.
|
// 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 {
|
if gotype == nil {
|
||||||
return mustFind(ctxt, "<unspecified>")
|
return mustFind(ctxt, "<unspecified>")
|
||||||
}
|
}
|
||||||
|
|
@ -358,10 +359,10 @@ func defgotype(ctxt *Link, gotype *Symbol) *Symbol {
|
||||||
return sdie
|
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
|
name := gotype.Name[5:] // could also decode from Type.string
|
||||||
kind := decodetypeKind(ctxt.Arch, gotype)
|
kind := decodetypeKind(ctxt.Arch, gotype)
|
||||||
bytesize := decodetypeSize(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"))
|
newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "void"))
|
||||||
nfields := decodetypeFuncInCount(ctxt.Arch, gotype)
|
nfields := decodetypeFuncInCount(ctxt.Arch, gotype)
|
||||||
var fld *dwarf.DWDie
|
var fld *dwarf.DWDie
|
||||||
var s *Symbol
|
var s *sym.Symbol
|
||||||
for i := 0; i < nfields; i++ {
|
for i := 0; i < nfields; i++ {
|
||||||
s = decodetypeFuncInType(ctxt.Arch, gotype, i)
|
s = decodetypeFuncInType(ctxt.Arch, gotype, i)
|
||||||
fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
|
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)
|
dotypedef(ctxt, &dwtypes, name, die)
|
||||||
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
|
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
|
||||||
nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype))
|
nfields := int(decodetypeIfaceMethodCount(ctxt.Arch, gotype))
|
||||||
var s *Symbol
|
var s *sym.Symbol
|
||||||
if nfields == 0 {
|
if nfields == 0 {
|
||||||
s = lookupOrDiag(ctxt, "type.runtime.eface")
|
s = lookupOrDiag(ctxt, "type.runtime.eface")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -529,12 +530,12 @@ func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
|
||||||
return die
|
return die
|
||||||
}
|
}
|
||||||
|
|
||||||
func nameFromDIESym(dwtype *Symbol) string {
|
func nameFromDIESym(dwtype *sym.Symbol) string {
|
||||||
return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def")
|
return strings.TrimSuffix(dwtype.Name[len(dwarf.InfoPrefix):], "..def")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find or construct *T given T.
|
// 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)
|
ptrname := "*" + nameFromDIESym(dwtype)
|
||||||
die := find(ctxt, ptrname)
|
die := find(ctxt, ptrname)
|
||||||
if die == nil {
|
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
|
// Search children (assumed to have TAG_member) for the one named
|
||||||
// field and set its AT_type to dwtype
|
// 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)
|
child := findchild(structdie, field)
|
||||||
if child == nil {
|
if child == nil {
|
||||||
Exitf("dwarf substitutetype: %s does not have member %s",
|
Exitf("dwarf substitutetype: %s does not have member %s",
|
||||||
|
|
@ -620,7 +621,7 @@ func synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
copychildren(ctxt, die, prototype)
|
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))
|
substitutetype(die, "array", defptrto(ctxt, elem))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -644,11 +645,11 @@ const (
|
||||||
BucketSize = 8
|
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)
|
name := mkinternaltypename(typename, keyname, valname)
|
||||||
symname := dwarf.InfoPrefix + name
|
symname := dwarf.InfoPrefix + name
|
||||||
s := ctxt.Syms.ROLookup(symname, 0)
|
s := ctxt.Syms.ROLookup(symname, 0)
|
||||||
if s != nil && s.Type == SDWARFINFO {
|
if s != nil && s.Type == sym.SDWARFINFO {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
die := newdie(ctxt, &dwtypes, abbrev, name, 0)
|
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 {
|
if die.Abbrev != dwarf.DW_ABRV_MAPTYPE {
|
||||||
continue
|
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)
|
keytype := decodetypeMapKey(ctxt.Arch, gotype)
|
||||||
valtype := decodetypeMapValue(ctxt.Arch, gotype)
|
valtype := decodetypeMapValue(ctxt.Arch, gotype)
|
||||||
keysize, valsize := decodetypeSize(ctxt.Arch, keytype), decodetypeSize(ctxt.Arch, valtype)
|
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 {
|
if die.Abbrev != dwarf.DW_ABRV_CHANTYPE {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
|
elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*sym.Symbol)
|
||||||
elemname := elemgotype.Name[5:]
|
elemname := elemgotype.Name[5:]
|
||||||
elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
|
elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
|
||||||
|
|
||||||
|
|
@ -797,30 +798,30 @@ func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// For use with pass.c::genasmsym
|
// For use with pass.c::genasmsym
|
||||||
func defdwsymb(ctxt *Link, sym *Symbol, s string, t SymbolType, v int64, gotype *Symbol) {
|
func defdwsymb(ctxt *Link, s *sym.Symbol, str string, t SymbolType, v int64, gotype *sym.Symbol) {
|
||||||
if strings.HasPrefix(s, "go.string.") {
|
if strings.HasPrefix(str, "go.string.") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(s, "runtime.gcbits.") {
|
if strings.HasPrefix(str, "runtime.gcbits.") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
|
if strings.HasPrefix(str, "type.") && str != "type.*" && !strings.HasPrefix(str, "type..") {
|
||||||
defgotype(ctxt, sym)
|
defgotype(ctxt, s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var dv *dwarf.DWDie
|
var dv *dwarf.DWDie
|
||||||
|
|
||||||
var dt *Symbol
|
var dt *sym.Symbol
|
||||||
switch t {
|
switch t {
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
|
|
||||||
case DataSym, BSSSym:
|
case DataSym, BSSSym:
|
||||||
dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, s, int(sym.Version))
|
dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, str, int(s.Version))
|
||||||
newabslocexprattr(dv, v, sym)
|
newabslocexprattr(dv, v, s)
|
||||||
if sym.Version == 0 {
|
if s.Version == 0 {
|
||||||
newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
|
newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
@ -847,7 +848,7 @@ func movetomodule(parent *dwarf.DWDie) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the pcln table contains runtime/proc.go, use that to set gdbscript path.
|
// 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 != "" {
|
if gdbscript != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -875,7 +876,7 @@ const (
|
||||||
OPCODE_BASE = 10
|
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
|
// Choose a special opcode that minimizes the number of bytes needed to
|
||||||
// encode the remaining PC delta and LC delta.
|
// encode the remaining PC delta and LC delta.
|
||||||
var opcode int64
|
var opcode int64
|
||||||
|
|
@ -976,9 +977,9 @@ func getCompilationDir() string {
|
||||||
return "/"
|
return "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
func importInfoSymbol(ctxt *Link, dsym *Symbol) {
|
func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) {
|
||||||
dsym.Attr |= AttrNotInSymbolTable | AttrReachable
|
dsym.Attr |= sym.AttrNotInSymbolTable | sym.AttrReachable
|
||||||
dsym.Type = SDWARFINFO
|
dsym.Type = sym.SDWARFINFO
|
||||||
for _, r := range dsym.R {
|
for _, r := range dsym.R {
|
||||||
if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 {
|
if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 {
|
||||||
if Buildmode == BuildmodeShared {
|
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}
|
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||||
ls := ctxt.Syms.Lookup(".debug_line", 0)
|
ls := ctxt.Syms.Lookup(".debug_line", 0)
|
||||||
ls.Type = SDWARFSECT
|
ls.Type = sym.SDWARFSECT
|
||||||
ls.R = ls.R[:0]
|
ls.R = ls.R[:0]
|
||||||
|
|
||||||
syms = append(syms, ls)
|
syms = append(syms, ls)
|
||||||
var funcs []*Symbol
|
var funcs []*sym.Symbol
|
||||||
|
|
||||||
unitstart := int64(-1)
|
unitstart := int64(-1)
|
||||||
headerstart := int64(-1)
|
headerstart := int64(-1)
|
||||||
headerend := int64(-1)
|
headerend := int64(-1)
|
||||||
epc := int64(0)
|
epc := int64(0)
|
||||||
var epcs *Symbol
|
var epcs *sym.Symbol
|
||||||
var dwinfo *dwarf.DWDie
|
var dwinfo *dwarf.DWDie
|
||||||
|
|
||||||
lang := dwarf.DW_LANG_Go
|
lang := dwarf.DW_LANG_Go
|
||||||
|
|
@ -1161,10 +1162,10 @@ func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
|
func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
||||||
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
var dwarfctxt dwarf.Context = dwctxt{ctxt}
|
||||||
fs := ctxt.Syms.Lookup(".debug_frame", 0)
|
fs := ctxt.Syms.Lookup(".debug_frame", 0)
|
||||||
fs.Type = SDWARFSECT
|
fs.Type = sym.SDWARFSECT
|
||||||
fs.R = fs.R[:0]
|
fs.R = fs.R[:0]
|
||||||
syms = append(syms, fs)
|
syms = append(syms, fs)
|
||||||
|
|
||||||
|
|
@ -1267,29 +1268,29 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
fs.AddUint32(ctxt.Arch, 0) // CIE offset
|
fs.AddUint32(ctxt.Arch, 0) // CIE offset
|
||||||
}
|
}
|
||||||
fs.AddAddr(ctxt.Arch, s)
|
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)
|
fs.AddBytes(deltaBuf)
|
||||||
}
|
}
|
||||||
return syms
|
return syms
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeranges(ctxt *Link, syms []*Symbol) []*Symbol {
|
func writeranges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
|
||||||
empty := true
|
empty := true
|
||||||
for _, s := range ctxt.Textp {
|
for _, s := range ctxt.Textp {
|
||||||
rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
|
rangeSym := ctxt.Syms.Lookup(dwarf.RangePrefix+s.Name, int(s.Version))
|
||||||
if rangeSym.Size == 0 {
|
if rangeSym.Size == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
rangeSym.Attr |= AttrReachable | AttrNotInSymbolTable
|
rangeSym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
|
||||||
rangeSym.Type = SDWARFRANGE
|
rangeSym.Type = sym.SDWARFRANGE
|
||||||
syms = append(syms, rangeSym)
|
syms = append(syms, rangeSym)
|
||||||
empty = false
|
empty = false
|
||||||
}
|
}
|
||||||
if !empty {
|
if !empty {
|
||||||
// PE does not like empty sections
|
// PE does not like empty sections
|
||||||
rangesec := ctxt.Syms.Lookup(".debug_ranges", 0)
|
rangesec := ctxt.Syms.Lookup(".debug_ranges", 0)
|
||||||
rangesec.Type = SDWARFRANGE
|
rangesec.Type = sym.SDWARFRANGE
|
||||||
rangesec.Attr |= AttrReachable
|
rangesec.Attr |= sym.AttrReachable
|
||||||
rangesec.R = rangesec.R[:0]
|
rangesec.R = rangesec.R[:0]
|
||||||
|
|
||||||
syms = append(syms, rangesec)
|
syms = append(syms, rangesec)
|
||||||
|
|
@ -1304,11 +1305,11 @@ const (
|
||||||
COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
|
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 := ctxt.Syms.Lookup(".debug_info", 0)
|
||||||
infosec.R = infosec.R[:0]
|
infosec.R = infosec.R[:0]
|
||||||
infosec.Type = SDWARFINFO
|
infosec.Type = sym.SDWARFINFO
|
||||||
infosec.Attr |= AttrReachable
|
infosec.Attr |= sym.AttrReachable
|
||||||
syms = append(syms, infosec)
|
syms = append(syms, infosec)
|
||||||
|
|
||||||
arangessec := ctxt.Syms.Lookup(".dwarfaranges", 0)
|
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.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
|
||||||
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
|
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
|
||||||
|
|
||||||
cu := []*Symbol{s}
|
cu := []*sym.Symbol{s}
|
||||||
if funcs != nil {
|
if funcs != nil {
|
||||||
cu = append(cu, funcs...)
|
cu = append(cu, funcs...)
|
||||||
funcs = nil
|
funcs = nil
|
||||||
|
|
@ -1373,9 +1374,9 @@ func ispubtype(die *dwarf.DWDie) bool {
|
||||||
return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
|
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 := ctxt.Syms.Lookup(sname, 0)
|
||||||
s.Type = SDWARFSECT
|
s.Type = sym.SDWARFSECT
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
||||||
for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link {
|
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,
|
* emit .debug_aranges. _info must have been written before,
|
||||||
* because we need die->offs of dwarf.DW_globals.
|
* 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 := 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
|
// The first tuple is aligned to a multiple of the size of a single tuple
|
||||||
// (twice the size of an address)
|
// (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
|
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.AddUint8(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.AddAddrPlus(ctxt.Arch, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
|
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, 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.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
|
s.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
|
||||||
}
|
}
|
||||||
if s.Size > 0 {
|
if s.Size > 0 {
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
@ -1455,7 +1456,7 @@ func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
return syms
|
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 {
|
if Linkmode == LinkExternal && Headtype == objabi.Hwindows && Buildmode == BuildmodeCArchive {
|
||||||
// gcc on Windows places .debug_gdb_scripts in the wrong location, which
|
// gcc on Windows places .debug_gdb_scripts in the wrong location, which
|
||||||
// causes the program not to run. See https://golang.org/issue/20183
|
// 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 != "" {
|
if gdbscript != "" {
|
||||||
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
|
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
|
||||||
s.Type = SDWARFSECT
|
s.Type = sym.SDWARFSECT
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
s.AddUint8(1) // magic 1 byte?
|
s.AddUint8(1) // magic 1 byte?
|
||||||
Addstring(s, gdbscript)
|
Addstring(s, gdbscript)
|
||||||
|
|
@ -1556,7 +1557,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
|
||||||
|
|
||||||
genasmsym(ctxt, defdwsymb)
|
genasmsym(ctxt, defdwsymb)
|
||||||
|
|
||||||
var consts []*Symbol
|
var consts []*sym.Symbol
|
||||||
for _, lib := range ctxt.Library {
|
for _, lib := range ctxt.Library {
|
||||||
if s := ctxt.Syms.Lookup(dwarf.ConstInfoPrefix+lib.Pkg, 0); s != nil {
|
if s := ctxt.Syms.Lookup(dwarf.ConstInfoPrefix+lib.Pkg, 0); s != nil {
|
||||||
importInfoSymbol(ctxt, s)
|
importInfoSymbol(ctxt, s)
|
||||||
|
|
@ -1565,7 +1566,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
|
||||||
}
|
}
|
||||||
|
|
||||||
abbrev := writeabbrev(ctxt)
|
abbrev := writeabbrev(ctxt)
|
||||||
syms := []*Symbol{abbrev}
|
syms := []*sym.Symbol{abbrev}
|
||||||
syms, funcs := writelines(ctxt, syms)
|
syms, funcs := writelines(ctxt, syms)
|
||||||
syms = writeframes(ctxt, syms)
|
syms = writeframes(ctxt, syms)
|
||||||
|
|
||||||
|
|
@ -1581,7 +1582,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
|
||||||
movetomodule(&dwtypes)
|
movetomodule(&dwtypes)
|
||||||
movetomodule(&dwglobals)
|
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)
|
// (but we need to generate dies before writepub)
|
||||||
infosyms := writeinfo(ctxt, nil, funcs, consts, abbrev)
|
infosyms := writeinfo(ctxt, nil, funcs, consts, abbrev)
|
||||||
|
|
||||||
|
|
@ -1595,12 +1596,12 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
|
||||||
dwarfp = syms
|
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
|
empty := true
|
||||||
for _, fn := range funcs {
|
for _, fn := range funcs {
|
||||||
for _, reloc := range fn.R {
|
for _, reloc := range fn.R {
|
||||||
if reloc.Type == objabi.R_DWARFREF && strings.HasPrefix(reloc.Sym.Name, dwarf.LocPrefix) {
|
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)
|
syms = append(syms, reloc.Sym)
|
||||||
empty = false
|
empty = false
|
||||||
// One location list entry per function, but many relocations to it. Don't duplicate.
|
// 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 {
|
if !empty {
|
||||||
locsym := ctxt.Syms.Lookup(".debug_loc", 0)
|
locsym := ctxt.Syms.Lookup(".debug_loc", 0)
|
||||||
locsym.R = locsym.R[:0]
|
locsym.R = locsym.R[:0]
|
||||||
locsym.Type = SDWARFLOC
|
locsym.Type = sym.SDWARFLOC
|
||||||
locsym.Attr |= AttrReachable
|
locsym.Attr |= sym.AttrReachable
|
||||||
syms = append(syms, locsym)
|
syms = append(syms, locsym)
|
||||||
}
|
}
|
||||||
return syms
|
return syms
|
||||||
|
|
@ -1622,7 +1623,7 @@ func collectlocs(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
|
||||||
/*
|
/*
|
||||||
* Elf.
|
* Elf.
|
||||||
*/
|
*/
|
||||||
func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
|
func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
|
||||||
if *FlagW { // disable dwarf
|
if *FlagW { // disable dwarf
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -1658,20 +1659,20 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sym := ctxt.Syms.Lookup(".debug_info", 0)
|
s := ctxt.Syms.Lookup(".debug_info", 0)
|
||||||
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
|
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
|
||||||
sym = ctxt.Syms.Lookup(".debug_abbrev", 0)
|
s = ctxt.Syms.Lookup(".debug_abbrev", 0)
|
||||||
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
|
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
|
||||||
sym = ctxt.Syms.Lookup(".debug_line", 0)
|
s = ctxt.Syms.Lookup(".debug_line", 0)
|
||||||
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
|
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
|
||||||
sym = ctxt.Syms.Lookup(".debug_frame", 0)
|
s = ctxt.Syms.Lookup(".debug_frame", 0)
|
||||||
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
|
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
|
||||||
sym = ctxt.Syms.Lookup(".debug_loc", 0)
|
s = ctxt.Syms.Lookup(".debug_loc", 0)
|
||||||
if sym.Sect != nil {
|
if s.Sect != nil {
|
||||||
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
|
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
|
||||||
}
|
}
|
||||||
sym = ctxt.Syms.Lookup(".debug_ranges", 0)
|
s = ctxt.Syms.Lookup(".debug_ranges", 0)
|
||||||
if sym.Sect != nil {
|
if s.Sect != nil {
|
||||||
putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
|
putelfsectionsym(ctxt.Out, s, s.Sect.Elfsect.(*ElfShdr).shnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
@ -809,7 +810,7 @@ type ElfShdr struct {
|
||||||
addralign uint64
|
addralign uint64
|
||||||
entsize uint64
|
entsize uint64
|
||||||
shnum int
|
shnum int
|
||||||
secsym *Symbol
|
secsym *sym.Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1060,7 +1061,7 @@ func elfwriteshdrs(out *OutBuf) uint32 {
|
||||||
return uint32(ehdr.shnum) * ELF32SHDRSIZE
|
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) {
|
if nelfstr >= len(elfstr) {
|
||||||
Errorf(s, "too many elf strings")
|
Errorf(s, "too many elf strings")
|
||||||
errorexit()
|
errorexit()
|
||||||
|
|
@ -1175,7 +1176,7 @@ func elfhash(name string) uint32 {
|
||||||
return h
|
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 {
|
if elf64 {
|
||||||
s.AddUint64(ctxt.Arch, uint64(tag))
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||||
s.AddUint64(ctxt.Arch, val)
|
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)
|
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 {
|
if elf64 {
|
||||||
s.AddUint64(ctxt.Arch, uint64(tag))
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1198,7 +1199,7 @@ func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64)
|
||||||
s.AddAddrPlus(ctxt.Arch, t, add)
|
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 {
|
if elf64 {
|
||||||
s.AddUint64(ctxt.Arch, uint64(tag))
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1446,8 +1447,8 @@ func elfdynhash(ctxt *Link) {
|
||||||
|
|
||||||
nsym := Nelfsym
|
nsym := Nelfsym
|
||||||
s := ctxt.Syms.Lookup(".hash", 0)
|
s := ctxt.Syms.Lookup(".hash", 0)
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
i := nsym
|
i := nsym
|
||||||
nbucket := 1
|
nbucket := 1
|
||||||
|
|
@ -1575,7 +1576,7 @@ func elfdynhash(ctxt *Link) {
|
||||||
Elfwritedynent(ctxt, s, DT_NULL, 0)
|
Elfwritedynent(ctxt, s, DT_NULL, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfphload(seg *Segment) *ElfPhdr {
|
func elfphload(seg *sym.Segment) *ElfPhdr {
|
||||||
ph := newElfPhdr()
|
ph := newElfPhdr()
|
||||||
ph.type_ = PT_LOAD
|
ph.type_ = PT_LOAD
|
||||||
if seg.Rwx&4 != 0 {
|
if seg.Rwx&4 != 0 {
|
||||||
|
|
@ -1597,7 +1598,7 @@ func elfphload(seg *Segment) *ElfPhdr {
|
||||||
return ph
|
return ph
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfphrelro(seg *Segment) {
|
func elfphrelro(seg *sym.Segment) {
|
||||||
ph := newElfPhdr()
|
ph := newElfPhdr()
|
||||||
ph.type_ = PT_GNU_RELRO
|
ph.type_ = PT_GNU_RELRO
|
||||||
ph.vaddr = seg.Vaddr
|
ph.vaddr = seg.Vaddr
|
||||||
|
|
@ -1640,20 +1641,20 @@ func elfshnamedup(name string) *ElfShdr {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfshalloc(sect *Section) *ElfShdr {
|
func elfshalloc(sect *sym.Section) *ElfShdr {
|
||||||
sh := elfshname(sect.Name)
|
sh := elfshname(sect.Name)
|
||||||
sect.Elfsect = sh
|
sect.Elfsect = sh
|
||||||
return sh
|
return sh
|
||||||
}
|
}
|
||||||
|
|
||||||
func elfshbits(sect *Section) *ElfShdr {
|
func elfshbits(sect *sym.Section) *ElfShdr {
|
||||||
var sh *ElfShdr
|
var sh *ElfShdr
|
||||||
|
|
||||||
if sect.Name == ".text" {
|
if sect.Name == ".text" {
|
||||||
if sect.Elfsect == nil {
|
if sect.Elfsect == nil {
|
||||||
sect.Elfsect = elfshnamedup(sect.Name)
|
sect.Elfsect = elfshnamedup(sect.Name)
|
||||||
}
|
}
|
||||||
sh = sect.Elfsect
|
sh = sect.Elfsect.(*ElfShdr)
|
||||||
} else {
|
} else {
|
||||||
sh = elfshalloc(sect)
|
sh = elfshalloc(sect)
|
||||||
}
|
}
|
||||||
|
|
@ -1712,7 +1713,7 @@ func elfshbits(sect *Section) *ElfShdr {
|
||||||
return sh
|
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.
|
// If main section is SHT_NOBITS, nothing to relocate.
|
||||||
// Also nothing to relocate in .shstrtab or notes.
|
// Also nothing to relocate in .shstrtab or notes.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
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" {
|
if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if sect.Elfsect.type_ == SHT_NOTE {
|
if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1737,7 +1738,7 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
|
||||||
// its own .rela.text.
|
// its own .rela.text.
|
||||||
|
|
||||||
if sect.Name == ".text" {
|
if sect.Name == ".text" {
|
||||||
if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
|
if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) {
|
||||||
sh = elfshnamedup(elfRelType + sect.Name)
|
sh = elfshnamedup(elfRelType + sect.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1748,14 +1749,14 @@ func elfshreloc(arch *sys.Arch, sect *Section) *ElfShdr {
|
||||||
sh.entsize += uint64(arch.RegSize)
|
sh.entsize += uint64(arch.RegSize)
|
||||||
}
|
}
|
||||||
sh.link = uint32(elfshname(".symtab").shnum)
|
sh.link = uint32(elfshname(".symtab").shnum)
|
||||||
sh.info = uint32(sect.Elfsect.shnum)
|
sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum)
|
||||||
sh.off = sect.Reloff
|
sh.off = sect.Reloff
|
||||||
sh.size = sect.Rellen
|
sh.size = sect.Rellen
|
||||||
sh.addralign = uint64(arch.RegSize)
|
sh.addralign = uint64(arch.RegSize)
|
||||||
return sh
|
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.
|
// If main section is SHT_NOBITS, nothing to relocate.
|
||||||
// Also nothing to relocate in .shstrtab.
|
// Also nothing to relocate in .shstrtab.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
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)
|
eaddr := int32(sect.Vaddr + sect.Length)
|
||||||
for _, sym := range syms {
|
for _, s := range syms {
|
||||||
if !sym.Attr.Reachable() {
|
if !s.Attr.Reachable() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if sym.Value >= int64(eaddr) {
|
if s.Value >= int64(eaddr) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for ri := 0; ri < len(sym.R); ri++ {
|
for ri := 0; ri < len(s.R); ri++ {
|
||||||
r := &sym.R[ri]
|
r := &s.R[ri]
|
||||||
if r.Done {
|
if r.Done {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if r.Xsym == nil {
|
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
|
continue
|
||||||
}
|
}
|
||||||
if r.Xsym.ElfsymForReloc() == 0 {
|
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() {
|
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)) {
|
if !Thearch.Elfreloc1(ctxt, r, int64(uint64(s.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)
|
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) {
|
func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
|
||||||
s := ctxt.Syms.Lookup(sectionName, 0)
|
s := ctxt.Syms.Lookup(sectionName, 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
// namesz
|
// namesz
|
||||||
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
|
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
|
||||||
// descsz
|
// descsz
|
||||||
|
|
@ -1867,8 +1868,8 @@ func (ctxt *Link) doelf() {
|
||||||
/* predefine strings we need for section headers */
|
/* predefine strings we need for section headers */
|
||||||
shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
|
shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
|
||||||
|
|
||||||
shstrtab.Type = SELFROSECT
|
shstrtab.Type = sym.SELFROSECT
|
||||||
shstrtab.Attr |= AttrReachable
|
shstrtab.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
Addstring(shstrtab, "")
|
Addstring(shstrtab, "")
|
||||||
Addstring(shstrtab, ".text")
|
Addstring(shstrtab, ".text")
|
||||||
|
|
@ -1975,8 +1976,8 @@ func (ctxt *Link) doelf() {
|
||||||
/* dynamic symbol table - first entry all zeros */
|
/* dynamic symbol table - first entry all zeros */
|
||||||
s := ctxt.Syms.Lookup(".dynsym", 0)
|
s := ctxt.Syms.Lookup(".dynsym", 0)
|
||||||
|
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
if elf64 {
|
if elf64 {
|
||||||
s.Size += ELF64SYMSIZE
|
s.Size += ELF64SYMSIZE
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1986,8 +1987,8 @@ func (ctxt *Link) doelf() {
|
||||||
/* dynamic string table */
|
/* dynamic string table */
|
||||||
s = ctxt.Syms.Lookup(".dynstr", 0)
|
s = ctxt.Syms.Lookup(".dynstr", 0)
|
||||||
|
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
if s.Size == 0 {
|
if s.Size == 0 {
|
||||||
Addstring(s, "")
|
Addstring(s, "")
|
||||||
}
|
}
|
||||||
|
|
@ -1995,62 +1996,62 @@ func (ctxt *Link) doelf() {
|
||||||
|
|
||||||
/* relocation table */
|
/* relocation table */
|
||||||
s = ctxt.Syms.Lookup(elfRelType, 0)
|
s = ctxt.Syms.Lookup(elfRelType, 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
|
|
||||||
/* global offset table */
|
/* global offset table */
|
||||||
s = ctxt.Syms.Lookup(".got", 0)
|
s = ctxt.Syms.Lookup(".got", 0)
|
||||||
|
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFGOT // writable
|
s.Type = sym.SELFGOT // writable
|
||||||
|
|
||||||
/* ppc64 glink resolver */
|
/* ppc64 glink resolver */
|
||||||
if ctxt.Arch.Family == sys.PPC64 {
|
if ctxt.Arch.Family == sys.PPC64 {
|
||||||
s := ctxt.Syms.Lookup(".glink", 0)
|
s := ctxt.Syms.Lookup(".glink", 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFRXSECT
|
s.Type = sym.SELFRXSECT
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hash */
|
/* hash */
|
||||||
s = ctxt.Syms.Lookup(".hash", 0)
|
s = ctxt.Syms.Lookup(".hash", 0)
|
||||||
|
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".got.plt", 0)
|
s = ctxt.Syms.Lookup(".got.plt", 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFSECT // writable
|
s.Type = sym.SELFSECT // writable
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".plt", 0)
|
s = ctxt.Syms.Lookup(".plt", 0)
|
||||||
|
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
if ctxt.Arch.Family == sys.PPC64 {
|
if ctxt.Arch.Family == sys.PPC64 {
|
||||||
// In the ppc64 ABI, .plt is a data section
|
// In the ppc64 ABI, .plt is a data section
|
||||||
// written by the dynamic linker.
|
// written by the dynamic linker.
|
||||||
s.Type = SELFSECT
|
s.Type = sym.SELFSECT
|
||||||
} else {
|
} else {
|
||||||
s.Type = SELFRXSECT
|
s.Type = sym.SELFRXSECT
|
||||||
}
|
}
|
||||||
|
|
||||||
Thearch.Elfsetupplt(ctxt)
|
Thearch.Elfsetupplt(ctxt)
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
|
s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".gnu.version", 0)
|
s = ctxt.Syms.Lookup(".gnu.version", 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".gnu.version_r", 0)
|
s = ctxt.Syms.Lookup(".gnu.version_r", 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = sym.SELFROSECT
|
||||||
|
|
||||||
/* define dynamic elf table */
|
/* define dynamic elf table */
|
||||||
s = ctxt.Syms.Lookup(".dynamic", 0)
|
s = ctxt.Syms.Lookup(".dynamic", 0)
|
||||||
|
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SELFSECT // writable
|
s.Type = sym.SELFSECT // writable
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* .dynamic table
|
* .dynamic table
|
||||||
|
|
@ -2102,10 +2103,10 @@ func (ctxt *Link) doelf() {
|
||||||
// The go.link.abihashbytes symbol will be pointed at the appropriate
|
// The go.link.abihashbytes symbol will be pointed at the appropriate
|
||||||
// part of the .note.go.abihash section in data.go:func address().
|
// part of the .note.go.abihash section in data.go:func address().
|
||||||
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
||||||
s.Attr |= AttrLocal
|
s.Attr |= sym.AttrLocal
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Attr |= AttrSpecial
|
s.Attr |= sym.AttrSpecial
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Size = int64(sha1.Size)
|
s.Size = int64(sha1.Size)
|
||||||
|
|
||||||
sort.Sort(byPkg(ctxt.Library))
|
sort.Sort(byPkg(ctxt.Library))
|
||||||
|
|
@ -2128,7 +2129,7 @@ func (ctxt *Link) doelf() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not write DT_NULL. elfdynhash will finish it.
|
// 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)
|
addr := Symaddr(s)
|
||||||
if sh.flags&SHF_ALLOC != 0 {
|
if sh.flags&SHF_ALLOC != 0 {
|
||||||
sh.addr = uint64(addr)
|
sh.addr = uint64(addr)
|
||||||
|
|
@ -2579,7 +2580,7 @@ elfobj:
|
||||||
elfshreloc(ctxt.Arch, sect)
|
elfshreloc(ctxt.Arch, sect)
|
||||||
}
|
}
|
||||||
for _, s := range dwarfp {
|
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)
|
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 {
|
if elf64 {
|
||||||
s.Dynid = int32(Nelfsym)
|
s.Dynid = int32(Nelfsym)
|
||||||
Nelfsym++
|
Nelfsym++
|
||||||
|
|
@ -2695,7 +2696,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
/* type */
|
/* type */
|
||||||
t := STB_GLOBAL << 4
|
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
|
t |= STT_FUNC
|
||||||
} else {
|
} else {
|
||||||
t |= STT_OBJECT
|
t |= STT_OBJECT
|
||||||
|
|
@ -2706,14 +2707,14 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
d.AddUint8(0)
|
d.AddUint8(0)
|
||||||
|
|
||||||
/* section where symbol is defined */
|
/* section where symbol is defined */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
||||||
} else {
|
} else {
|
||||||
d.AddUint16(ctxt.Arch, 1)
|
d.AddUint16(ctxt.Arch, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* value */
|
/* value */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
d.AddUint64(ctxt.Arch, 0)
|
d.AddUint64(ctxt.Arch, 0)
|
||||||
} else {
|
} else {
|
||||||
d.AddAddr(ctxt.Arch, s)
|
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)))
|
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
|
||||||
|
|
||||||
/* value */
|
/* value */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
d.AddUint32(ctxt.Arch, 0)
|
d.AddUint32(ctxt.Arch, 0)
|
||||||
} else {
|
} else {
|
||||||
d.AddAddr(ctxt.Arch, s)
|
d.AddAddr(ctxt.Arch, s)
|
||||||
|
|
@ -2750,9 +2751,9 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
t := STB_GLOBAL << 4
|
t := STB_GLOBAL << 4
|
||||||
|
|
||||||
// TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386.
|
// 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
|
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
|
t |= STT_FUNC
|
||||||
} else {
|
} else {
|
||||||
t |= STT_OBJECT
|
t |= STT_OBJECT
|
||||||
|
|
@ -2761,7 +2762,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
d.AddUint8(0)
|
d.AddUint8(0)
|
||||||
|
|
||||||
/* shndx */
|
/* shndx */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
||||||
} else {
|
} else {
|
||||||
d.AddUint16(ctxt.Arch, 1)
|
d.AddUint16(ctxt.Arch, 1)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -128,7 +129,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
|
||||||
var next string
|
var next string
|
||||||
var q string
|
var q string
|
||||||
var lib string
|
var lib string
|
||||||
var s *Symbol
|
var s *sym.Symbol
|
||||||
|
|
||||||
p0 := ""
|
p0 := ""
|
||||||
for ; p != ""; p = next {
|
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:]
|
remote, q = remote[:i], remote[i+1:]
|
||||||
}
|
}
|
||||||
s = ctxt.Syms.Lookup(local, 0)
|
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.Dynimplib = lib
|
||||||
s.Extname = remote
|
s.Extname = remote
|
||||||
s.Dynimpvers = q
|
s.Dynimpvers = q
|
||||||
if s.Type != SHOSTOBJ {
|
if s.Type != sym.SHOSTOBJ {
|
||||||
s.Type = SDYNIMPORT
|
s.Type = sym.SDYNIMPORT
|
||||||
}
|
}
|
||||||
havedynamic = 1
|
havedynamic = 1
|
||||||
}
|
}
|
||||||
|
|
@ -203,7 +204,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
|
||||||
}
|
}
|
||||||
local := f[1]
|
local := f[1]
|
||||||
s = ctxt.Syms.Lookup(local, 0)
|
s = ctxt.Syms.Lookup(local, 0)
|
||||||
s.Type = SHOSTOBJ
|
s.Type = sym.SHOSTOBJ
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -248,9 +249,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if f[0] == "cgo_export_static" {
|
if f[0] == "cgo_export_static" {
|
||||||
s.Attr |= AttrCgoExportStatic
|
s.Attr |= sym.AttrCgoExportStatic
|
||||||
} else {
|
} else {
|
||||||
s.Attr |= AttrCgoExportDynamic
|
s.Attr |= sym.AttrCgoExportDynamic
|
||||||
}
|
}
|
||||||
continue
|
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 {
|
if s.Dynid >= 0 || Linkmode == LinkExternal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -329,8 +330,8 @@ func fieldtrack(ctxt *Link) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
for _, s := range ctxt.Syms.Allsym {
|
||||||
if strings.HasPrefix(s.Name, "go.track.") {
|
if strings.HasPrefix(s.Name, "go.track.") {
|
||||||
s.Attr |= AttrSpecial // do not lay out in data segment
|
s.Attr |= sym.AttrSpecial // do not lay out in data segment
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
if s.Attr.Reachable() {
|
if s.Attr.Reachable() {
|
||||||
buf.WriteString(s.Name[9:])
|
buf.WriteString(s.Name[9:])
|
||||||
for p := s.Reachparent; p != nil; p = p.Reachparent {
|
for p := s.Reachparent; p != nil; p = p.Reachparent {
|
||||||
|
|
@ -340,7 +341,7 @@ func fieldtrack(ctxt *Link) {
|
||||||
buf.WriteString("\n")
|
buf.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Type = SCONST
|
s.Type = sym.SCONST
|
||||||
s.Value = 0
|
s.Value = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +354,7 @@ func fieldtrack(ctxt *Link) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addstrdata(ctxt, *flagFieldTrack, buf.String())
|
addstrdata(ctxt, *flagFieldTrack, buf.String())
|
||||||
s.Type = SDATA
|
s.Type = sym.SDATA
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctxt *Link) addexport() {
|
func (ctxt *Link) addexport() {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -266,7 +267,7 @@ type ElfSect struct {
|
||||||
align uint64
|
align uint64
|
||||||
entsize uint64
|
entsize uint64
|
||||||
base []byte
|
base []byte
|
||||||
sym *Symbol
|
sym *sym.Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
type ElfObj struct {
|
type ElfObj struct {
|
||||||
|
|
@ -305,7 +306,7 @@ type ElfSym struct {
|
||||||
type_ uint8
|
type_ uint8
|
||||||
other uint8
|
other uint8
|
||||||
shndx uint16
|
shndx uint16
|
||||||
sym *Symbol
|
sym *sym.Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'}
|
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
|
return
|
||||||
|
|
||||||
case ElfSectFlagAlloc:
|
case ElfSectFlagAlloc:
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
|
|
||||||
case ElfSectFlagAlloc + ElfSectFlagWrite:
|
case ElfSectFlagAlloc + ElfSectFlagWrite:
|
||||||
if sect.type_ == ElfSectNobits {
|
if sect.type_ == ElfSectNobits {
|
||||||
s.Type = SNOPTRBSS
|
s.Type = sym.SNOPTRBSS
|
||||||
} else {
|
} else {
|
||||||
s.Type = SNOPTRDATA
|
s.Type = sym.SNOPTRDATA
|
||||||
}
|
}
|
||||||
|
|
||||||
case ElfSectFlagAlloc + ElfSectFlagExec:
|
case ElfSectFlagAlloc + ElfSectFlagExec:
|
||||||
s.Type = STEXT
|
s.Type = sym.STEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
if sect.name == ".got" || sect.name == ".toc" {
|
if sect.name == ".got" || sect.name == ".toc" {
|
||||||
s.Type = SELFGOT
|
s.Type = sym.SELFGOT
|
||||||
}
|
}
|
||||||
if sect.type_ == ElfSectProgbits {
|
if sect.type_ == ElfSectProgbits {
|
||||||
s.P = sect.base
|
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.
|
// enter sub-symbols into symbol table.
|
||||||
// symbol 0 is the null symbol.
|
// symbol 0 is the null symbol.
|
||||||
symbols := make([]*Symbol, elfobj.nsymtab)
|
symbols := make([]*sym.Symbol, elfobj.nsymtab)
|
||||||
|
|
||||||
for i := 1; i < elfobj.nsymtab; i++ {
|
for i := 1; i < elfobj.nsymtab; i++ {
|
||||||
var sym ElfSym
|
var elfsym ElfSym
|
||||||
if err := readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
|
if err := readelfsym(ctxt, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
|
||||||
Errorf(nil, "%s: malformed elf file: %v", pn, err)
|
Errorf(nil, "%s: malformed elf file: %v", pn, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
symbols[i] = sym.sym
|
symbols[i] = elfsym.sym
|
||||||
if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon {
|
if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon {
|
if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon {
|
||||||
s := sym.sym
|
s := elfsym.sym
|
||||||
if uint64(s.Size) < sym.size {
|
if uint64(s.Size) < elfsym.size {
|
||||||
s.Size = int64(sym.size)
|
s.Size = int64(elfsym.size)
|
||||||
}
|
}
|
||||||
if s.Type == 0 || s.Type == SXREF {
|
if s.Type == 0 || s.Type == sym.SXREF {
|
||||||
s.Type = SNOPTRBSS
|
s.Type = sym.SNOPTRBSS
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 {
|
if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols
|
// 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
|
continue
|
||||||
}
|
}
|
||||||
sect = &elfobj.sect[sym.shndx]
|
sect = &elfobj.sect[elfsym.shndx]
|
||||||
if sect.sym == nil {
|
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
|
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.
|
// This reportedly happens with clang 3.7 on ARM.
|
||||||
// See issue 13139.
|
// See issue 13139.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
|
if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
|
||||||
continue
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s := sym.sym
|
s := elfsym.sym
|
||||||
if s.Outer != nil {
|
if s.Outer != nil {
|
||||||
if s.Attr.DuplicateOK() {
|
if s.Attr.DuplicateOK() {
|
||||||
continue
|
continue
|
||||||
|
|
@ -799,26 +800,26 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
|
||||||
|
|
||||||
s.Sub = sect.sym.Sub
|
s.Sub = sect.sym.Sub
|
||||||
sect.sym.Sub = s
|
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() {
|
if !s.Attr.CgoExportDynamic() {
|
||||||
s.Dynimplib = "" // satisfy dynimport
|
s.Dynimplib = "" // satisfy dynimport
|
||||||
}
|
}
|
||||||
s.Value = int64(sym.value)
|
s.Value = int64(elfsym.value)
|
||||||
s.Size = int64(sym.size)
|
s.Size = int64(elfsym.size)
|
||||||
s.Outer = sect.sym
|
s.Outer = sect.sym
|
||||||
if sect.sym.Type == STEXT {
|
if sect.sym.Type == sym.STEXT {
|
||||||
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
||||||
Errorf(s, "%s: duplicate symbol definition", pn)
|
Errorf(s, "%s: duplicate symbol definition", pn)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrExternal
|
s.Attr |= sym.AttrExternal
|
||||||
}
|
}
|
||||||
|
|
||||||
if elfobj.machine == ElfMachPower64 {
|
if elfobj.machine == ElfMachPower64 {
|
||||||
flag := int(sym.other) >> 5
|
flag := int(elfsym.other) >> 5
|
||||||
if 2 <= flag && flag <= 6 {
|
if 2 <= flag && flag <= 6 {
|
||||||
s.Localentry = 1 << uint(flag-2)
|
s.Localentry = 1 << uint(flag-2)
|
||||||
} else if flag == 7 {
|
} 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 {
|
if s.Sub != nil {
|
||||||
s.Sub = listsort(s.Sub)
|
s.Sub = listsort(s.Sub)
|
||||||
}
|
}
|
||||||
if s.Type == STEXT {
|
if s.Type == sym.STEXT {
|
||||||
if s.Attr.OnList() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
ctxt.Textp = append(ctxt.Textp, s)
|
ctxt.Textp = append(ctxt.Textp, s)
|
||||||
for s = s.Sub; s != nil; s = s.Sub {
|
for s = s.Sub; s != nil; s = s.Sub {
|
||||||
if s.Attr.OnList() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
ctxt.Textp = append(ctxt.Textp, s)
|
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
|
rela = 1
|
||||||
}
|
}
|
||||||
n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
|
n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela))
|
||||||
r := make([]Reloc, n)
|
r := make([]sym.Reloc, n)
|
||||||
p := rsect.base
|
p := rsect.base
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
var add uint64
|
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
|
if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
|
||||||
rp.Sym = nil
|
rp.Sym = nil
|
||||||
} else {
|
} else {
|
||||||
var sym ElfSym
|
var elfsym ElfSym
|
||||||
if err := readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
|
if err := readelfsym(ctxt, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
|
||||||
Errorf(nil, "%s: malformed elf file: %v", pn, err)
|
Errorf(nil, "%s: malformed elf file: %v", pn, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sym.sym = symbols[info>>32]
|
elfsym.sym = symbols[info>>32]
|
||||||
if sym.sym == nil {
|
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), sym.name, sym.shndx, sym.type_)
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
rp.Sym = sym.sym
|
rp.Sym = elfsym.sym
|
||||||
}
|
}
|
||||||
|
|
||||||
rp.Type = 256 + objabi.RelocType(info)
|
rp.Type = 256 + objabi.RelocType(info)
|
||||||
|
|
@ -985,7 +986,7 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
|
||||||
return nil
|
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 {
|
if i >= elfobj.nsymtab || i < 0 {
|
||||||
err = fmt.Errorf("invalid elf symbol index")
|
err = fmt.Errorf("invalid elf symbol index")
|
||||||
return err
|
return err
|
||||||
|
|
@ -998,44 +999,44 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, loc
|
||||||
if elfobj.is64 != 0 {
|
if elfobj.is64 != 0 {
|
||||||
b := new(ElfSymBytes64)
|
b := new(ElfSymBytes64)
|
||||||
binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b)
|
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[:]):])
|
elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
|
||||||
sym.value = elfobj.e.Uint64(b.Value[:])
|
elfsym.value = elfobj.e.Uint64(b.Value[:])
|
||||||
sym.size = elfobj.e.Uint64(b.Size[:])
|
elfsym.size = elfobj.e.Uint64(b.Size[:])
|
||||||
sym.shndx = elfobj.e.Uint16(b.Shndx[:])
|
elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
|
||||||
sym.bind = b.Info >> 4
|
elfsym.bind = b.Info >> 4
|
||||||
sym.type_ = b.Info & 0xf
|
elfsym.type_ = b.Info & 0xf
|
||||||
sym.other = b.Other
|
elfsym.other = b.Other
|
||||||
} else {
|
} else {
|
||||||
b := new(ElfSymBytes)
|
b := new(ElfSymBytes)
|
||||||
binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b)
|
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[:]):])
|
elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):])
|
||||||
sym.value = uint64(elfobj.e.Uint32(b.Value[:]))
|
elfsym.value = uint64(elfobj.e.Uint32(b.Value[:]))
|
||||||
sym.size = uint64(elfobj.e.Uint32(b.Size[:]))
|
elfsym.size = uint64(elfobj.e.Uint32(b.Size[:]))
|
||||||
sym.shndx = elfobj.e.Uint16(b.Shndx[:])
|
elfsym.shndx = elfobj.e.Uint16(b.Shndx[:])
|
||||||
sym.bind = b.Info >> 4
|
elfsym.bind = b.Info >> 4
|
||||||
sym.type_ = b.Info & 0xf
|
elfsym.type_ = b.Info & 0xf
|
||||||
sym.other = b.Other
|
elfsym.other = b.Other
|
||||||
}
|
}
|
||||||
|
|
||||||
var s *Symbol
|
var s *sym.Symbol
|
||||||
if sym.name == "_GLOBAL_OFFSET_TABLE_" {
|
if elfsym.name == "_GLOBAL_OFFSET_TABLE_" {
|
||||||
sym.name = ".got"
|
elfsym.name = ".got"
|
||||||
}
|
}
|
||||||
if sym.name == ".TOC." {
|
if elfsym.name == ".TOC." {
|
||||||
// Magic symbol on ppc64. Will be set to this object
|
// Magic symbol on ppc64. Will be set to this object
|
||||||
// file's .got+0x8000.
|
// file's .got+0x8000.
|
||||||
sym.bind = ElfSymBindLocal
|
elfsym.bind = ElfSymBindLocal
|
||||||
}
|
}
|
||||||
|
|
||||||
switch sym.type_ {
|
switch elfsym.type_ {
|
||||||
case ElfSymTypeSection:
|
case ElfSymTypeSection:
|
||||||
s = elfobj.sect[sym.shndx].sym
|
s = elfobj.sect[elfsym.shndx].sym
|
||||||
|
|
||||||
case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
|
case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon:
|
||||||
switch sym.bind {
|
switch elfsym.bind {
|
||||||
case ElfSymBindGlobal:
|
case ElfSymBindGlobal:
|
||||||
if needSym != 0 {
|
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
|
// for global scoped hidden symbols we should insert it into
|
||||||
// symbol hash table, but mark them as hidden.
|
// 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
|
// TODO(minux): correctly handle __i686.get_pc_thunk.bx without
|
||||||
// set dupok generally. See http://codereview.appspot.com/5823055/
|
// set dupok generally. See http://codereview.appspot.com/5823055/
|
||||||
// comment #5 for details.
|
// comment #5 for details.
|
||||||
if s != nil && sym.other == 2 {
|
if s != nil && elfsym.other == 2 {
|
||||||
s.Type |= SHIDDEN
|
s.Type |= sym.SHIDDEN
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= sym.AttrDuplicateOK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case ElfSymBindLocal:
|
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
|
// binutils for arm generate these mapping
|
||||||
// symbols, ignore these
|
// symbols, ignore these
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if sym.name == ".TOC." {
|
if elfsym.name == ".TOC." {
|
||||||
// We need to be able to look this up,
|
// We need to be able to look this up,
|
||||||
// so put it in the hash table.
|
// so put it in the hash table.
|
||||||
if needSym != 0 {
|
if needSym != 0 {
|
||||||
s = ctxt.Syms.Lookup(sym.name, localSymVersion)
|
s = ctxt.Syms.Lookup(elfsym.name, localSymVersion)
|
||||||
s.Type |= SHIDDEN
|
s.Type |= sym.SHIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
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
|
// local names and hidden global names are unique
|
||||||
// and should only be referenced by their index, not name, so we
|
// and should only be referenced by their index, not name, so we
|
||||||
// don't bother to add them into the hash table
|
// 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:
|
case ElfSymBindWeak:
|
||||||
if needSym != 0 {
|
if needSym != 0 {
|
||||||
s = ctxt.Syms.Lookup(sym.name, 0)
|
s = ctxt.Syms.Lookup(elfsym.name, 0)
|
||||||
if sym.other == 2 {
|
if elfsym.other == 2 {
|
||||||
s.Type |= SHIDDEN
|
s.Type |= sym.SHIDDEN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection {
|
if s != nil && s.Type == 0 && elfsym.type_ != ElfSymTypeSection {
|
||||||
s.Type = SXREF
|
s.Type = sym.SXREF
|
||||||
}
|
}
|
||||||
sym.sym = s
|
elfsym.sym = s
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type rbyoff []Reloc
|
type rbyoff []sym.Reloc
|
||||||
|
|
||||||
func (x rbyoff) Len() int {
|
func (x rbyoff) Len() int {
|
||||||
return len(x)
|
return len(x)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -92,7 +93,7 @@ type ldMachoSect struct {
|
||||||
flags uint32
|
flags uint32
|
||||||
res1 uint32
|
res1 uint32
|
||||||
res2 uint32
|
res2 uint32
|
||||||
sym *Symbol
|
sym *sym.Symbol
|
||||||
rel []ldMachoRel
|
rel []ldMachoRel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,7 +124,7 @@ type ldMachoSym struct {
|
||||||
desc uint16
|
desc uint16
|
||||||
kind int8
|
kind int8
|
||||||
value uint64
|
value uint64
|
||||||
sym *Symbol
|
sym *sym.Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
type ldMachoDysymtab struct {
|
type ldMachoDysymtab struct {
|
||||||
|
|
@ -428,15 +429,14 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
|
||||||
var sect *ldMachoSect
|
var sect *ldMachoSect
|
||||||
var rel *ldMachoRel
|
var rel *ldMachoRel
|
||||||
var rpi int
|
var rpi int
|
||||||
var s *Symbol
|
var s *sym.Symbol
|
||||||
var s1 *Symbol
|
var s1 *sym.Symbol
|
||||||
var outer *Symbol
|
var outer *sym.Symbol
|
||||||
var c *ldMachoCmd
|
var c *ldMachoCmd
|
||||||
var symtab *ldMachoSymtab
|
var symtab *ldMachoSymtab
|
||||||
var dsymtab *ldMachoDysymtab
|
var dsymtab *ldMachoDysymtab
|
||||||
var sym *ldMachoSym
|
var r []sym.Reloc
|
||||||
var r []Reloc
|
var rp *sym.Reloc
|
||||||
var rp *Reloc
|
|
||||||
var name string
|
var name string
|
||||||
|
|
||||||
localSymVersion := ctxt.Syms.IncVersion()
|
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.segname == "__TEXT" {
|
||||||
if sect.name == "__text" {
|
if sect.name == "__text" {
|
||||||
s.Type = STEXT
|
s.Type = sym.STEXT
|
||||||
} else {
|
} else {
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if sect.name == "__bss" {
|
if sect.name == "__bss" {
|
||||||
s.Type = SNOPTRBSS
|
s.Type = sym.SNOPTRBSS
|
||||||
s.P = s.P[:0]
|
s.P = s.P[:0]
|
||||||
} else {
|
} 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.
|
// enter sub-symbols into symbol table.
|
||||||
// have to guess sizes from next symbol.
|
// have to guess sizes from next symbol.
|
||||||
for i := 0; uint32(i) < symtab.nsym; i++ {
|
for i := 0; uint32(i) < symtab.nsym; i++ {
|
||||||
sym = &symtab.sym[i]
|
machsym := &symtab.sym[i]
|
||||||
if sym.type_&N_STAB != 0 {
|
if machsym.type_&N_STAB != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check sym->type against outer->type.
|
// TODO: check sym->type against outer->type.
|
||||||
name = sym.name
|
name = machsym.name
|
||||||
|
|
||||||
if name[0] == '_' && name[1] != '\x00' {
|
if name[0] == '_' && name[1] != '\x00' {
|
||||||
name = name[1:]
|
name = name[1:]
|
||||||
}
|
}
|
||||||
v := 0
|
v := 0
|
||||||
if sym.type_&N_EXT == 0 {
|
if machsym.type_&N_EXT == 0 {
|
||||||
v = localSymVersion
|
v = localSymVersion
|
||||||
}
|
}
|
||||||
s = ctxt.Syms.Lookup(name, v)
|
s = ctxt.Syms.Lookup(name, v)
|
||||||
if sym.type_&N_EXT == 0 {
|
if machsym.type_&N_EXT == 0 {
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= sym.AttrDuplicateOK
|
||||||
}
|
}
|
||||||
sym.sym = s
|
machsym.sym = s
|
||||||
if sym.sectnum == 0 { // undefined
|
if machsym.sectnum == 0 { // undefined
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if uint32(sym.sectnum) > c.seg.nsect {
|
if uint32(machsym.sectnum) > c.seg.nsect {
|
||||||
err = fmt.Errorf("reference to invalid section %d", sym.sectnum)
|
err = fmt.Errorf("reference to invalid section %d", machsym.sectnum)
|
||||||
goto bad
|
goto bad
|
||||||
}
|
}
|
||||||
|
|
||||||
sect = &c.seg.sect[sym.sectnum-1]
|
sect = &c.seg.sect[machsym.sectnum-1]
|
||||||
outer = sect.sym
|
outer = sect.sym
|
||||||
if outer == nil {
|
if outer == nil {
|
||||||
err = fmt.Errorf("reference to invalid section %s/%s", sect.segname, sect.name)
|
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)
|
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
|
s.Sub = outer.Sub
|
||||||
outer.Sub = s
|
outer.Sub = s
|
||||||
s.Outer = outer
|
s.Outer = outer
|
||||||
s.Value = int64(sym.value - sect.addr)
|
s.Value = int64(machsym.value - sect.addr)
|
||||||
if !s.Attr.CgoExportDynamic() {
|
if !s.Attr.CgoExportDynamic() {
|
||||||
s.Dynimplib = "" // satisfy dynimport
|
s.Dynimplib = "" // satisfy dynimport
|
||||||
}
|
}
|
||||||
if outer.Type == STEXT {
|
if outer.Type == sym.STEXT {
|
||||||
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
||||||
Errorf(s, "%s: duplicate symbol definition", pn)
|
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.
|
// 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() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
ctxt.Textp = append(ctxt.Textp, s)
|
ctxt.Textp = append(ctxt.Textp, s)
|
||||||
for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
|
for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
|
||||||
if s1.Attr.OnList() {
|
if s1.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s1.Name)
|
log.Fatalf("symbol %s listed multiple times", s1.Name)
|
||||||
}
|
}
|
||||||
s1.Attr |= AttrOnList
|
s1.Attr |= sym.AttrOnList
|
||||||
ctxt.Textp = append(ctxt.Textp, s1)
|
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 {
|
if sect.rel == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r = make([]Reloc, sect.nreloc)
|
r = make([]sym.Reloc, sect.nreloc)
|
||||||
rpi = 0
|
rpi = 0
|
||||||
Reloc:
|
Reloc:
|
||||||
for j = 0; uint32(j) < sect.nreloc; j++ {
|
for j = 0; uint32(j) < sect.nreloc; j++ {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"debug/pe"
|
"debug/pe"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -132,7 +133,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
|
||||||
|
|
||||||
localSymVersion := ctxt.Syms.IncVersion()
|
localSymVersion := ctxt.Syms.IncVersion()
|
||||||
|
|
||||||
sectsyms := make(map[*pe.Section]*Symbol)
|
sectsyms := make(map[*pe.Section]*sym.Symbol)
|
||||||
sectdata := make(map[*pe.Section][]byte)
|
sectdata := make(map[*pe.Section][]byte)
|
||||||
|
|
||||||
// Some input files are archives containing multiple of
|
// 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) {
|
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
|
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
|
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
|
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
|
case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text
|
||||||
s.Type = STEXT
|
s.Type = sym.STEXT
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)
|
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()
|
data, err := sect.Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -214,7 +215,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
rs := make([]Reloc, rsect.NumberOfRelocations)
|
rs := make([]sym.Reloc, rsect.NumberOfRelocations)
|
||||||
for j, r := range rsect.Relocs {
|
for j, r := range rsect.Relocs {
|
||||||
rp := &rs[j]
|
rp := &rs[j]
|
||||||
if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
|
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 pesym.SectionNumber == 0 { // extern
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
s.Plt = -2 // flag for dynimport in PE object files.
|
s.Plt = -2 // flag for dynimport in PE object files.
|
||||||
}
|
}
|
||||||
if s.Type == SXREF && pesym.Value > 0 { // global data
|
if s.Type == sym.SXREF && pesym.Value > 0 { // global data
|
||||||
s.Type = SNOPTRDATA
|
s.Type = sym.SNOPTRDATA
|
||||||
s.Size = int64(pesym.Value)
|
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]
|
sectsym := sectsyms[sect]
|
||||||
s.Sub = sectsym.Sub
|
s.Sub = sectsym.Sub
|
||||||
sectsym.Sub = s
|
sectsym.Sub = s
|
||||||
s.Type = sectsym.Type | SSUB
|
s.Type = sectsym.Type | sym.SSUB
|
||||||
s.Value = int64(pesym.Value)
|
s.Value = int64(pesym.Value)
|
||||||
s.Size = 4
|
s.Size = 4
|
||||||
s.Outer = sectsym
|
s.Outer = sectsym
|
||||||
if sectsym.Type == STEXT {
|
if sectsym.Type == sym.STEXT {
|
||||||
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
||||||
Errorf(s, "%s: duplicate symbol definition", pn)
|
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 {
|
if s.Sub != nil {
|
||||||
s.Sub = listsort(s.Sub)
|
s.Sub = listsort(s.Sub)
|
||||||
}
|
}
|
||||||
if s.Type == STEXT {
|
if s.Type == sym.STEXT {
|
||||||
if s.Attr.OnList() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
ctxt.Textp = append(ctxt.Textp, s)
|
ctxt.Textp = append(ctxt.Textp, s)
|
||||||
for s = s.Sub; s != nil; s = s.Sub {
|
for s = s.Sub; s != nil; s = s.Sub {
|
||||||
if s.Attr.OnList() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
ctxt.Textp = append(ctxt.Textp, s)
|
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] == '.'
|
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) {
|
func readpesym(ctxt *Link, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) {
|
||||||
symname, err := sym.FullName(f.StringTable)
|
symname, err := pesym.FullName(f.StringTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var name string
|
var name string
|
||||||
if issect(sym) {
|
if issect(pesym) {
|
||||||
name = sectsyms[f.Sections[sym.SectionNumber-1]].Name
|
name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name
|
||||||
} else {
|
} else {
|
||||||
name = symname
|
name = symname
|
||||||
if strings.HasPrefix(name, "__imp_") {
|
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]
|
name = name[:i]
|
||||||
}
|
}
|
||||||
|
|
||||||
var s *Symbol
|
var s *sym.Symbol
|
||||||
switch sym.Type {
|
switch pesym.Type {
|
||||||
default:
|
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:
|
case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
|
||||||
switch sym.StorageClass {
|
switch pesym.StorageClass {
|
||||||
case IMAGE_SYM_CLASS_EXTERNAL: //global
|
case IMAGE_SYM_CLASS_EXTERNAL: //global
|
||||||
s = ctxt.Syms.Lookup(name, 0)
|
s = ctxt.Syms.Lookup(name, 0)
|
||||||
|
|
||||||
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
|
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
|
||||||
s = ctxt.Syms.Lookup(name, localSymVersion)
|
s = ctxt.Syms.Lookup(name, localSymVersion)
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= sym.AttrDuplicateOK
|
||||||
|
|
||||||
default:
|
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) {
|
if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
|
||||||
s.Type = SXREF
|
s.Type = sym.SXREF
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(symname, "__imp_") {
|
if strings.HasPrefix(symname, "__imp_") {
|
||||||
s.Got = -2 // flag for __imp_
|
s.Got = -2 // flag for __imp_
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import (
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
|
@ -97,17 +98,17 @@ type Arch struct {
|
||||||
Openbsddynld string
|
Openbsddynld string
|
||||||
Dragonflydynld string
|
Dragonflydynld string
|
||||||
Solarisdynld string
|
Solarisdynld string
|
||||||
Adddynrel func(*Link, *Symbol, *Reloc) bool
|
Adddynrel func(*Link, *sym.Symbol, *sym.Reloc) bool
|
||||||
Archinit func(*Link)
|
Archinit func(*Link)
|
||||||
Archreloc func(*Link, *Reloc, *Symbol, *int64) bool
|
Archreloc func(*Link, *sym.Reloc, *sym.Symbol, *int64) bool
|
||||||
Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64
|
Archrelocvariant func(*Link, *sym.Reloc, *sym.Symbol, int64) int64
|
||||||
Trampoline func(*Link, *Reloc, *Symbol)
|
Trampoline func(*Link, *sym.Reloc, *sym.Symbol)
|
||||||
Asmb func(*Link)
|
Asmb func(*Link)
|
||||||
Elfreloc1 func(*Link, *Reloc, int64) bool
|
Elfreloc1 func(*Link, *sym.Reloc, int64) bool
|
||||||
Elfsetupplt func(*Link)
|
Elfsetupplt func(*Link)
|
||||||
Gentext func(*Link)
|
Gentext func(*Link)
|
||||||
Machoreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool
|
Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||||
PEreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool
|
PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||||
|
|
||||||
// TLSIEtoLE converts a TLS Initial Executable relocation to
|
// TLSIEtoLE converts a TLS Initial Executable relocation to
|
||||||
// a TLS Local Executable relocation.
|
// a TLS Local Executable relocation.
|
||||||
|
|
@ -115,7 +116,7 @@ type Arch struct {
|
||||||
// This is possible when a TLS IE relocation refers to a local
|
// This is possible when a TLS IE relocation refers to a local
|
||||||
// symbol in an executable, which is typical when internally
|
// symbol in an executable, which is typical when internally
|
||||||
// linking PIE binaries.
|
// linking PIE binaries.
|
||||||
TLSIEtoLE func(s *Symbol, off, size int)
|
TLSIEtoLE func(s *sym.Symbol, off, size int)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -126,37 +127,10 @@ var (
|
||||||
Symsize int32
|
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 (
|
const (
|
||||||
MINFUNC = 16 // minimum size for a function
|
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
|
// DynlinkingGo returns whether we are producing Go code that can live
|
||||||
// in separate shared libraries linked together at runtime.
|
// in separate shared libraries linked together at runtime.
|
||||||
func (ctxt *Link) DynlinkingGo() bool {
|
func (ctxt *Link) DynlinkingGo() bool {
|
||||||
|
|
@ -183,7 +157,7 @@ func UseRelro() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dynexp []*Symbol
|
dynexp []*sym.Symbol
|
||||||
dynlib []string
|
dynlib []string
|
||||||
ldflag []string
|
ldflag []string
|
||||||
havedynamic int
|
havedynamic int
|
||||||
|
|
@ -201,11 +175,11 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Segtext Segment
|
Segtext sym.Segment
|
||||||
Segrodata Segment
|
Segrodata sym.Segment
|
||||||
Segrelrodata Segment
|
Segrelrodata sym.Segment
|
||||||
Segdata Segment
|
Segdata sym.Segment
|
||||||
Segdwarf Segment
|
Segdwarf sym.Segment
|
||||||
)
|
)
|
||||||
|
|
||||||
/* whence for ldpkg */
|
/* whence for ldpkg */
|
||||||
|
|
@ -359,11 +333,11 @@ func (ctxt *Link) loadlib() {
|
||||||
switch Buildmode {
|
switch Buildmode {
|
||||||
case BuildmodeCShared, BuildmodePlugin:
|
case BuildmodeCShared, BuildmodePlugin:
|
||||||
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
|
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= sym.AttrDuplicateOK
|
||||||
s.AddUint8(1)
|
s.AddUint8(1)
|
||||||
case BuildmodeCArchive:
|
case BuildmodeCArchive:
|
||||||
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
|
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= sym.AttrDuplicateOK
|
||||||
s.AddUint8(1)
|
s.AddUint8(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -414,7 +388,7 @@ func (ctxt *Link) loadlib() {
|
||||||
|
|
||||||
if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
|
if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
|
||||||
toc := ctxt.Syms.Lookup(".TOC.", 0)
|
toc := ctxt.Syms.Lookup(".TOC.", 0)
|
||||||
toc.Type = SDYNIMPORT
|
toc.Type = sym.SDYNIMPORT
|
||||||
}
|
}
|
||||||
|
|
||||||
if Linkmode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
|
if Linkmode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
|
||||||
|
|
@ -438,13 +412,13 @@ func (ctxt *Link) loadlib() {
|
||||||
// Drop all the cgo_import_static declarations.
|
// Drop all the cgo_import_static declarations.
|
||||||
// Turns out we won't be needing them.
|
// Turns out we won't be needing them.
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
for _, s := range ctxt.Syms.Allsym {
|
||||||
if s.Type == SHOSTOBJ {
|
if s.Type == sym.SHOSTOBJ {
|
||||||
// If a symbol was marked both
|
// If a symbol was marked both
|
||||||
// cgo_import_static and cgo_import_dynamic,
|
// cgo_import_static and cgo_import_dynamic,
|
||||||
// then we want to make it cgo_import_dynamic
|
// then we want to make it cgo_import_dynamic
|
||||||
// now.
|
// now.
|
||||||
if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
|
if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
|
||||||
s.Type = SDYNIMPORT
|
s.Type = sym.SDYNIMPORT
|
||||||
} else {
|
} else {
|
||||||
s.Type = 0
|
s.Type = 0
|
||||||
}
|
}
|
||||||
|
|
@ -457,22 +431,22 @@ func (ctxt *Link) loadlib() {
|
||||||
// runtime.tlsg is used for external linking on platforms that do not define
|
// runtime.tlsg is used for external linking on platforms that do not define
|
||||||
// a variable to hold g in assembly (currently only intel).
|
// a variable to hold g in assembly (currently only intel).
|
||||||
if tlsg.Type == 0 {
|
if tlsg.Type == 0 {
|
||||||
tlsg.Type = STLSBSS
|
tlsg.Type = sym.STLSBSS
|
||||||
tlsg.Size = int64(ctxt.Arch.PtrSize)
|
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)
|
Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
|
||||||
}
|
}
|
||||||
tlsg.Attr |= AttrReachable
|
tlsg.Attr |= sym.AttrReachable
|
||||||
ctxt.Tlsg = tlsg
|
ctxt.Tlsg = tlsg
|
||||||
|
|
||||||
var moduledata *Symbol
|
var moduledata *sym.Symbol
|
||||||
if Buildmode == BuildmodePlugin {
|
if Buildmode == BuildmodePlugin {
|
||||||
moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
|
moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
|
||||||
moduledata.Attr |= AttrLocal
|
moduledata.Attr |= sym.AttrLocal
|
||||||
} else {
|
} else {
|
||||||
moduledata = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
|
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
|
// If the module (toolchain-speak for "executable or shared
|
||||||
// library") we are linking contains the runtime package, it
|
// library") we are linking contains the runtime package, it
|
||||||
// will define the runtime.firstmoduledata symbol and we
|
// will define the runtime.firstmoduledata symbol and we
|
||||||
|
|
@ -484,14 +458,14 @@ func (ctxt *Link) loadlib() {
|
||||||
// recording the value of GOARM.
|
// recording the value of GOARM.
|
||||||
if ctxt.Arch.Family == sys.ARM {
|
if ctxt.Arch.Family == sys.ARM {
|
||||||
s := ctxt.Syms.Lookup("runtime.goarm", 0)
|
s := ctxt.Syms.Lookup("runtime.goarm", 0)
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.AddUint8(uint8(objabi.GOARM))
|
s.AddUint8(uint8(objabi.GOARM))
|
||||||
}
|
}
|
||||||
|
|
||||||
if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
|
if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
|
||||||
s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
|
s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.AddUint8(1)
|
s.AddUint8(1)
|
||||||
}
|
}
|
||||||
|
|
@ -499,19 +473,19 @@ func (ctxt *Link) loadlib() {
|
||||||
// If OTOH the module does not contain the runtime package,
|
// If OTOH the module does not contain the runtime package,
|
||||||
// create a local symbol for the moduledata.
|
// create a local symbol for the moduledata.
|
||||||
moduledata = ctxt.Syms.Lookup("local.moduledata", 0)
|
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
|
// In all cases way we mark the moduledata as noptrdata to hide it from
|
||||||
// the GC.
|
// the GC.
|
||||||
moduledata.Type = SNOPTRDATA
|
moduledata.Type = sym.SNOPTRDATA
|
||||||
moduledata.Attr |= AttrReachable
|
moduledata.Attr |= sym.AttrReachable
|
||||||
ctxt.Moduledata = moduledata
|
ctxt.Moduledata = moduledata
|
||||||
|
|
||||||
// Now that we know the link mode, trim the dynexp list.
|
// Now that we know the link mode, trim the dynexp list.
|
||||||
x := AttrCgoExportDynamic
|
x := sym.AttrCgoExportDynamic
|
||||||
|
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
x = AttrCgoExportStatic
|
x = sym.AttrCgoExportStatic
|
||||||
}
|
}
|
||||||
w := 0
|
w := 0
|
||||||
for i := 0; i < len(dynexp); i++ {
|
for i := 0; i < len(dynexp); i++ {
|
||||||
|
|
@ -531,7 +505,7 @@ func (ctxt *Link) loadlib() {
|
||||||
any := false
|
any := false
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
for _, s := range ctxt.Syms.Allsym {
|
||||||
for _, r := range s.R {
|
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
|
any = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -618,8 +592,8 @@ func (ctxt *Link) loadlib() {
|
||||||
if ctxt.Arch == sys.Arch386 {
|
if ctxt.Arch == sys.Arch386 {
|
||||||
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
|
if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
|
||||||
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
||||||
got.Type = SDYNIMPORT
|
got.Type = sym.SDYNIMPORT
|
||||||
got.Attr |= AttrReachable
|
got.Attr |= sym.AttrReachable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -638,7 +612,7 @@ func (ctxt *Link) loadlib() {
|
||||||
for _, s := range lib.dupTextSyms {
|
for _, s := range lib.dupTextSyms {
|
||||||
if !s.Attr.OnList() {
|
if !s.Attr.OnList() {
|
||||||
ctxt.Textp = append(ctxt.Textp, s)
|
ctxt.Textp = append(ctxt.Textp, s)
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
// dupok symbols may be defined in multiple packages. its
|
// dupok symbols may be defined in multiple packages. its
|
||||||
// associated package is chosen sort of arbitrarily (the
|
// associated package is chosen sort of arbitrarily (the
|
||||||
// first containing package that the linker loads). canonicalize
|
// 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
|
// 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
|
// autogenerated type equality/hashing functions) and we don't want to generated
|
||||||
// pcln table entries for these any more so remove them from Textp.
|
// 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 {
|
for _, s := range ctxt.Textp {
|
||||||
if s.Type != SDYNIMPORT {
|
if s.Type != sym.SDYNIMPORT {
|
||||||
textp = append(textp, s)
|
textp = append(textp, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -676,12 +650,12 @@ func (ctxt *Link) loadlib() {
|
||||||
// packages. All Go binaries contain these symbols, but only only
|
// packages. All Go binaries contain these symbols, but only only
|
||||||
// those programs loaded dynamically in multiple parts need these
|
// those programs loaded dynamically in multiple parts need these
|
||||||
// symbols to have entries in the symbol table.
|
// 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
|
return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || syms.ROLookup("plugin.Open", 0) != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// typeSymbolMangle mangles the given symbol name into something shorter.
|
// 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) {
|
if !typeSymbolMangling(syms) {
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
@ -1181,7 +1155,7 @@ func (l *Link) hostlink() {
|
||||||
|
|
||||||
// Do not let the host linker generate COPY relocations. These
|
// Do not let the host linker generate COPY relocations. These
|
||||||
// can move symbols out of sections that rely on stable offsets
|
// 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")
|
argv = append(argv, "-Wl,-znocopyreloc")
|
||||||
|
|
||||||
if l.Arch.InFamily(sys.ARM, sys.ARM64) {
|
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)
|
Errorf(nil, "cannot read symbols from shared library: %s", libpath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gcdataLocations := make(map[uint64]*Symbol)
|
gcdataLocations := make(map[uint64]*sym.Symbol)
|
||||||
for _, elfsym := range syms {
|
for _, elfsym := range syms {
|
||||||
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
|
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1636,10 +1610,10 @@ func ldshlibsyms(ctxt *Link, shlib string) {
|
||||||
// libraries, any non-dynimport symbols we find that duplicate symbols
|
// libraries, any non-dynimport symbols we find that duplicate symbols
|
||||||
// already loaded should be ignored (the symbols from the .a files
|
// already loaded should be ignored (the symbols from the .a files
|
||||||
// "win").
|
// "win").
|
||||||
if lsym.Type != 0 && lsym.Type != SDYNIMPORT {
|
if lsym.Type != 0 && lsym.Type != sym.SDYNIMPORT {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
lsym.Type = SDYNIMPORT
|
lsym.Type = sym.SDYNIMPORT
|
||||||
lsym.ElfType = elf.ST_TYPE(elfsym.Info)
|
lsym.ElfType = elf.ST_TYPE(elfsym.Info)
|
||||||
lsym.Size = int64(elfsym.Size)
|
lsym.Size = int64(elfsym.Size)
|
||||||
if elfsym.Section != elf.SHN_UNDEF {
|
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 {
|
if ctxt.Arch.Family == sys.ARM64 {
|
||||||
for _, sect := range f.Sections {
|
for _, sect := range f.Sections {
|
||||||
if sect.Type == elf.SHT_RELA {
|
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})
|
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 {
|
func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
|
||||||
sect := new(Section)
|
sect := new(sym.Section)
|
||||||
sect.Rwx = uint8(rwx)
|
sect.Rwx = uint8(rwx)
|
||||||
sect.Name = name
|
sect.Name = name
|
||||||
sect.Seg = seg
|
sect.Seg = seg
|
||||||
|
|
@ -1713,12 +1687,12 @@ func Be32(b []byte) uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
type chain struct {
|
type chain struct {
|
||||||
sym *Symbol
|
sym *sym.Symbol
|
||||||
up *chain
|
up *chain
|
||||||
limit int // limit on entry to sym
|
limit int // limit on entry to sym
|
||||||
}
|
}
|
||||||
|
|
||||||
var morestack *Symbol
|
var morestack *sym.Symbol
|
||||||
|
|
||||||
// TODO: Record enough information in new object files to
|
// TODO: Record enough information in new object files to
|
||||||
// allow stack checks here.
|
// allow stack checks here.
|
||||||
|
|
@ -1785,7 +1759,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
||||||
if s.Attr.StackCheck() {
|
if s.Attr.StackCheck() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
s.Attr |= AttrStackCheck
|
s.Attr |= sym.AttrStackCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
if depth > 100 {
|
if depth > 100 {
|
||||||
|
|
@ -1799,7 +1773,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
||||||
// should never be called directly.
|
// should never be called directly.
|
||||||
// onlyctxt.Diagnose the direct caller.
|
// onlyctxt.Diagnose the direct caller.
|
||||||
// TODO(mwhudson): actually think about this.
|
// 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 {
|
Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
|
||||||
|
|
||||||
Errorf(s, "call to external function")
|
Errorf(s, "call to external function")
|
||||||
|
|
@ -1845,7 +1819,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
|
||||||
endr := len(s.R)
|
endr := len(s.R)
|
||||||
var ch1 chain
|
var ch1 chain
|
||||||
var pcsp Pciter
|
var pcsp Pciter
|
||||||
var r *Reloc
|
var r *sym.Reloc
|
||||||
for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
|
for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
|
||||||
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
|
// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
|
||||||
|
|
||||||
|
|
@ -1947,11 +1921,11 @@ const (
|
||||||
AutoSym = 'a'
|
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
|
// 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)
|
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
|
// We've already included this symbol in ctxt.Textp
|
||||||
// if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin.
|
// if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin.
|
||||||
// See data.go:/textaddress
|
// See data.go:/textaddress
|
||||||
|
|
@ -1975,14 +1949,14 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
|
||||||
if s == nil {
|
if s == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if s.Type == STEXT {
|
if s.Type == sym.STEXT {
|
||||||
put(ctxt, s, s.Name, TextSym, s.Value, nil)
|
put(ctxt, s, s.Name, TextSym, s.Value, nil)
|
||||||
}
|
}
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup("runtime.etext", 0)
|
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
|
// We've already included this symbol in ctxt.Textp
|
||||||
// if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin.
|
// if ctxt.DynlinkingGo() && Headtype == objabi.Hdarwin.
|
||||||
// See data.go:/textaddress
|
// 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." {
|
if (s.Name == "" || s.Name[0] == '.') && s.Version == 0 && s.Name != ".rathole" && s.Name != ".TOC." {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
switch s.Type & SMASK {
|
switch s.Type & sym.SMASK {
|
||||||
case SCONST,
|
case sym.SCONST,
|
||||||
SRODATA,
|
sym.SRODATA,
|
||||||
SSYMTAB,
|
sym.SSYMTAB,
|
||||||
SPCLNTAB,
|
sym.SPCLNTAB,
|
||||||
SINITARR,
|
sym.SINITARR,
|
||||||
SDATA,
|
sym.SDATA,
|
||||||
SNOPTRDATA,
|
sym.SNOPTRDATA,
|
||||||
SELFROSECT,
|
sym.SELFROSECT,
|
||||||
SMACHOGOT,
|
sym.SMACHOGOT,
|
||||||
STYPE,
|
sym.STYPE,
|
||||||
SSTRING,
|
sym.SSTRING,
|
||||||
SGOSTRING,
|
sym.SGOSTRING,
|
||||||
SGOFUNC,
|
sym.SGOFUNC,
|
||||||
SGCBITS,
|
sym.SGCBITS,
|
||||||
STYPERELRO,
|
sym.STYPERELRO,
|
||||||
SSTRINGRELRO,
|
sym.SSTRINGRELRO,
|
||||||
SGOSTRINGRELRO,
|
sym.SGOSTRINGRELRO,
|
||||||
SGOFUNCRELRO,
|
sym.SGOFUNCRELRO,
|
||||||
SGCBITSRELRO,
|
sym.SGCBITSRELRO,
|
||||||
SRODATARELRO,
|
sym.SRODATARELRO,
|
||||||
STYPELINK,
|
sym.STYPELINK,
|
||||||
SITABLINK,
|
sym.SITABLINK,
|
||||||
SWINDOWS:
|
sym.SWINDOWS:
|
||||||
if !s.Attr.Reachable() {
|
if !s.Attr.Reachable() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
|
put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
|
||||||
|
|
||||||
case SBSS, SNOPTRBSS:
|
case sym.SBSS, sym.SNOPTRBSS:
|
||||||
if !s.Attr.Reachable() {
|
if !s.Attr.Reachable() {
|
||||||
continue
|
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)
|
put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
|
||||||
|
|
||||||
case SHOSTOBJ:
|
case sym.SHOSTOBJ:
|
||||||
if Headtype == objabi.Hwindows || Iself {
|
if Headtype == objabi.Hwindows || Iself {
|
||||||
put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
|
put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
case SDYNIMPORT:
|
case sym.SDYNIMPORT:
|
||||||
if !s.Attr.Reachable() {
|
if !s.Attr.Reachable() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
|
put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
|
||||||
|
|
||||||
case STLSBSS:
|
case sym.STLSBSS:
|
||||||
if Linkmode == LinkExternal {
|
if Linkmode == LinkExternal {
|
||||||
put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
|
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() {
|
if !s.Attr.Reachable() {
|
||||||
Errorf(s, "unreachable symbol in symaddr")
|
Errorf(s, "unreachable symbol in symaddr")
|
||||||
}
|
}
|
||||||
return s.Value
|
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 := ctxt.Syms.Lookup(p, 0)
|
||||||
s.Type = t
|
s.Type = t
|
||||||
s.Value = v
|
s.Value = v
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Attr |= AttrSpecial
|
s.Attr |= sym.AttrSpecial
|
||||||
s.Attr |= AttrLocal
|
s.Attr |= sym.AttrLocal
|
||||||
}
|
}
|
||||||
|
|
||||||
func datoff(s *Symbol, addr int64) int64 {
|
func datoff(s *sym.Symbol, addr int64) int64 {
|
||||||
if uint64(addr) >= Segdata.Vaddr {
|
if uint64(addr) >= Segdata.Vaddr {
|
||||||
return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
|
return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
|
||||||
}
|
}
|
||||||
|
|
@ -2139,21 +2113,21 @@ func Entryvalue(ctxt *Link) int64 {
|
||||||
if s.Type == 0 {
|
if s.Type == 0 {
|
||||||
return *FlagTextAddr
|
return *FlagTextAddr
|
||||||
}
|
}
|
||||||
if s.Type != STEXT {
|
if s.Type != sym.STEXT {
|
||||||
Errorf(s, "entry not text")
|
Errorf(s, "entry not text")
|
||||||
}
|
}
|
||||||
return s.Value
|
return s.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
func undefsym(ctxt *Link, s *Symbol) {
|
func undefsym(ctxt *Link, s *sym.Symbol) {
|
||||||
var r *Reloc
|
var r *sym.Reloc
|
||||||
|
|
||||||
for i := 0; i < len(s.R); i++ {
|
for i := 0; i < len(s.R); i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
if r.Sym == nil { // happens for some external ARM relocs
|
if r.Sym == nil { // happens for some external ARM relocs
|
||||||
continue
|
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)
|
Errorf(s, "undefined: %q", r.Sym.Name)
|
||||||
}
|
}
|
||||||
if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
|
if !r.Sym.Attr.Reachable() && r.Type != objabi.R_WEAKADDROFF {
|
||||||
|
|
@ -2180,14 +2154,14 @@ func (ctxt *Link) callgraph() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
var r *Reloc
|
var r *sym.Reloc
|
||||||
for _, s := range ctxt.Textp {
|
for _, s := range ctxt.Textp {
|
||||||
for i = 0; i < len(s.R); i++ {
|
for i = 0; i < len(s.R); i++ {
|
||||||
r = &s.R[i]
|
r = &s.R[i]
|
||||||
if r.Sym == nil {
|
if r.Sym == nil {
|
||||||
continue
|
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)
|
ctxt.Logf("%s calls %s\n", s.Name, r.Sym.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,124 +34,17 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"fmt"
|
"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 {
|
type Shlib struct {
|
||||||
Path string
|
Path string
|
||||||
Hash []byte
|
Hash []byte
|
||||||
Deps []string
|
Deps []string
|
||||||
File *elf.File
|
File *elf.File
|
||||||
gcdataAddresses map[*Symbol]uint64
|
gcdataAddresses map[*sym.Symbol]uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link holds the context for writing object code from a compiler
|
// Link holds the context for writing object code from a compiler
|
||||||
|
|
@ -159,7 +52,7 @@ type Shlib struct {
|
||||||
type Link struct {
|
type Link struct {
|
||||||
Out *OutBuf
|
Out *OutBuf
|
||||||
|
|
||||||
Syms *Symbols
|
Syms *sym.Symbols
|
||||||
|
|
||||||
Arch *sys.Arch
|
Arch *sys.Arch
|
||||||
Debugvlog int
|
Debugvlog int
|
||||||
|
|
@ -167,20 +60,20 @@ type Link struct {
|
||||||
|
|
||||||
Loaded bool // set after all inputs have been loaded as symbols
|
Loaded bool // set after all inputs have been loaded as symbols
|
||||||
|
|
||||||
Tlsg *Symbol
|
Tlsg *sym.Symbol
|
||||||
Libdir []string
|
Libdir []string
|
||||||
Library []*Library
|
Library []*Library
|
||||||
LibraryByPkg map[string]*Library
|
LibraryByPkg map[string]*Library
|
||||||
Shlibs []Shlib
|
Shlibs []Shlib
|
||||||
Tlsoffset int
|
Tlsoffset int
|
||||||
Textp []*Symbol
|
Textp []*sym.Symbol
|
||||||
Filesyms []*Symbol
|
Filesyms []*sym.Symbol
|
||||||
Moduledata *Symbol
|
Moduledata *sym.Symbol
|
||||||
|
|
||||||
PackageFile map[string]string
|
PackageFile map[string]string
|
||||||
PackageShlib 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
|
// The smallest possible offset from the hardware stack pointer to a local
|
||||||
|
|
@ -214,8 +107,8 @@ type Library struct {
|
||||||
hash string
|
hash string
|
||||||
importStrings []string
|
importStrings []string
|
||||||
imports []*Library
|
imports []*Library
|
||||||
textp []*Symbol // text symbols defined in this library
|
textp []*sym.Symbol // text symbols defined in this library
|
||||||
dupTextSyms []*Symbol // dupok text symbols defined in this library
|
dupTextSyms []*sym.Symbol // dupok text symbols defined in this library
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l Library) String() string {
|
func (l Library) String() string {
|
||||||
|
|
@ -233,35 +126,8 @@ func (l *Library) addImports(ctxt *Link, pn string) {
|
||||||
l.importStrings = nil
|
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 {
|
type Pciter struct {
|
||||||
d Pcdata
|
d sym.Pcdata
|
||||||
p []byte
|
p []byte
|
||||||
pc uint32
|
pc uint32
|
||||||
nextpc uint32
|
nextpc uint32
|
||||||
|
|
@ -270,66 +136,3 @@ type Pciter struct {
|
||||||
start int
|
start int
|
||||||
done 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 (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -169,7 +170,7 @@ const (
|
||||||
|
|
||||||
var nkind [NumSymKind]int
|
var nkind [NumSymKind]int
|
||||||
|
|
||||||
var sortsym []*Symbol
|
var sortsym []*sym.Symbol
|
||||||
|
|
||||||
var nsortsym int
|
var nsortsym int
|
||||||
|
|
||||||
|
|
@ -346,32 +347,32 @@ func (ctxt *Link) domacho() {
|
||||||
// empirically, string table must begin with " \x00".
|
// empirically, string table must begin with " \x00".
|
||||||
s := ctxt.Syms.Lookup(".machosymstr", 0)
|
s := ctxt.Syms.Lookup(".machosymstr", 0)
|
||||||
|
|
||||||
s.Type = SMACHOSYMSTR
|
s.Type = sym.SMACHOSYMSTR
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.AddUint8(' ')
|
s.AddUint8(' ')
|
||||||
s.AddUint8('\x00')
|
s.AddUint8('\x00')
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".machosymtab", 0)
|
s = ctxt.Syms.Lookup(".machosymtab", 0)
|
||||||
s.Type = SMACHOSYMTAB
|
s.Type = sym.SMACHOSYMTAB
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
if Linkmode != LinkExternal {
|
if Linkmode != LinkExternal {
|
||||||
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
|
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
|
||||||
s.Type = SMACHOPLT
|
s.Type = sym.SMACHOPLT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
|
s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
|
||||||
s.Type = SMACHOGOT
|
s.Type = sym.SMACHOGOT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Align = 4
|
s.Align = 4
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
|
s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
|
||||||
s.Type = SMACHOINDIRECTPLT
|
s.Type = sym.SMACHOINDIRECTPLT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
|
s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
|
||||||
s.Type = SMACHOINDIRECTGOT
|
s.Type = sym.SMACHOINDIRECTGOT
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,7 +397,7 @@ func machoadddynlib(lib string) {
|
||||||
dylib = append(dylib, lib)
|
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)
|
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
|
||||||
|
|
||||||
var msect *MachoSect
|
var msect *MachoSect
|
||||||
|
|
@ -647,8 +648,8 @@ func Asmbmacho(ctxt *Link) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func symkind(s *Symbol) int {
|
func symkind(s *sym.Symbol) int {
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == sym.SDYNIMPORT {
|
||||||
return SymKindUndef
|
return SymKindUndef
|
||||||
}
|
}
|
||||||
if s.Attr.CgoExport() {
|
if s.Attr.CgoExport() {
|
||||||
|
|
@ -657,7 +658,7 @@ func symkind(s *Symbol) int {
|
||||||
return SymKindLocal
|
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 {
|
if s == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -678,7 +679,7 @@ func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, go
|
||||||
nsortsym++
|
nsortsym++
|
||||||
}
|
}
|
||||||
|
|
||||||
type machoscmp []*Symbol
|
type machoscmp []*sym.Symbol
|
||||||
|
|
||||||
func (x machoscmp) Len() int {
|
func (x machoscmp) Len() int {
|
||||||
return len(x)
|
return len(x)
|
||||||
|
|
@ -704,7 +705,7 @@ func (x machoscmp) Less(i, j int) bool {
|
||||||
func machogenasmsym(ctxt *Link) {
|
func machogenasmsym(ctxt *Link) {
|
||||||
genasmsym(ctxt, addsym)
|
genasmsym(ctxt, addsym)
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
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() {
|
if s.Attr.Reachable() {
|
||||||
addsym(ctxt, s, "", DataSym, 0, nil)
|
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
|
// So we sort them here and pre-allocate dynid for them
|
||||||
// See https://golang.org/issue/4029
|
// See https://golang.org/issue/4029
|
||||||
for i := 0; i < len(dynexp); i++ {
|
for i := 0; i < len(dynexp); i++ {
|
||||||
dynexp[i].Attr |= AttrReachable
|
dynexp[i].Attr |= sym.AttrReachable
|
||||||
}
|
}
|
||||||
machogenasmsym(ctxt)
|
machogenasmsym(ctxt)
|
||||||
sortsym = make([]*Symbol, nsortsym)
|
sortsym = make([]*sym.Symbol, nsortsym)
|
||||||
nsortsym = 0
|
nsortsym = 0
|
||||||
machogenasmsym(ctxt)
|
machogenasmsym(ctxt)
|
||||||
sort.Sort(machoscmp(sortsym[:nsortsym]))
|
sort.Sort(machoscmp(sortsym[:nsortsym]))
|
||||||
|
|
@ -733,7 +734,7 @@ func machosymorder(ctxt *Link) {
|
||||||
//
|
//
|
||||||
// When dynamically linking, all non-local variables and plugin-exported
|
// When dynamically linking, all non-local variables and plugin-exported
|
||||||
// symbols need to be 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() {
|
if !ctxt.DynlinkingGo() || s.Attr.Local() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -752,7 +753,7 @@ func machoShouldExport(ctxt *Link, s *Symbol) bool {
|
||||||
if strings.HasPrefix(s.Name, "go.link.pkghash") {
|
if strings.HasPrefix(s.Name, "go.link.pkghash") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return s.Type >= SELFSECT // only writable sections
|
return s.Type >= sym.SELFSECT // only writable sections
|
||||||
}
|
}
|
||||||
|
|
||||||
func machosymtab(ctxt *Link) {
|
func machosymtab(ctxt *Link) {
|
||||||
|
|
@ -780,11 +781,11 @@ func machosymtab(ctxt *Link) {
|
||||||
// replace "·" as ".", because DTrace cannot handle it.
|
// replace "·" as ".", because DTrace cannot handle it.
|
||||||
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
|
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(0x01) // type N_EXT, external symbol
|
||||||
symtab.AddUint8(0) // no section
|
symtab.AddUint8(0) // no section
|
||||||
symtab.AddUint16(ctxt.Arch, 0) // desc
|
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 {
|
} else {
|
||||||
if s.Attr.CgoExport() || export {
|
if s.Attr.CgoExport() || export {
|
||||||
symtab.AddUint8(0x0f)
|
symtab.AddUint8(0x0f)
|
||||||
|
|
@ -802,7 +803,7 @@ func machosymtab(ctxt *Link) {
|
||||||
symtab.AddUint8(uint8(o.Sect.Extnum))
|
symtab.AddUint8(uint8(o.Sect.Extnum))
|
||||||
}
|
}
|
||||||
symtab.AddUint16(ctxt.Arch, 0) // desc
|
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))
|
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 main section has no bits, nothing to relocate.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||||
return
|
return
|
||||||
|
|
@ -907,27 +908,27 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
eaddr := int32(sect.Vaddr + sect.Length)
|
eaddr := int32(sect.Vaddr + sect.Length)
|
||||||
for _, sym := range syms {
|
for _, s := range syms {
|
||||||
if !sym.Attr.Reachable() {
|
if !s.Attr.Reachable() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if sym.Value >= int64(eaddr) {
|
if s.Value >= int64(eaddr) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for ri := 0; ri < len(sym.R); ri++ {
|
for ri := 0; ri < len(s.R); ri++ {
|
||||||
r := &sym.R[ri]
|
r := &s.R[ri]
|
||||||
if r.Done {
|
if r.Done {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if r.Xsym == nil {
|
if r.Xsym == nil {
|
||||||
Errorf(sym, "missing xsym in relocation")
|
Errorf(s, "missing xsym in relocation")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !r.Xsym.Attr.Reachable() {
|
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)) {
|
if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.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)
|
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/dwarf"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -30,27 +31,27 @@ var emptyPkg = []byte(`"".`)
|
||||||
type objReader struct {
|
type objReader struct {
|
||||||
rd *bufio.Reader
|
rd *bufio.Reader
|
||||||
arch *sys.Arch
|
arch *sys.Arch
|
||||||
syms *Symbols
|
syms *sym.Symbols
|
||||||
lib *Library
|
lib *Library
|
||||||
pn string
|
pn string
|
||||||
dupSym *Symbol
|
dupSym *sym.Symbol
|
||||||
localSymVersion int
|
localSymVersion int
|
||||||
|
|
||||||
// rdBuf is used by readString and readSymName as scratch for reading strings.
|
// rdBuf is used by readString and readSymName as scratch for reading strings.
|
||||||
rdBuf []byte
|
rdBuf []byte
|
||||||
|
|
||||||
// List of symbol references for the file being read.
|
// List of symbol references for the file being read.
|
||||||
refs []*Symbol
|
refs []*sym.Symbol
|
||||||
data []byte
|
data []byte
|
||||||
reloc []Reloc
|
reloc []sym.Reloc
|
||||||
pcdata []Pcdata
|
pcdata []sym.Pcdata
|
||||||
autom []Auto
|
autom []sym.Auto
|
||||||
funcdata []*Symbol
|
funcdata []*sym.Symbol
|
||||||
funcdataoff []int64
|
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()
|
start := f.Offset()
|
||||||
r := &objReader{
|
r := &objReader{
|
||||||
rd: f.Reader,
|
rd: f.Reader,
|
||||||
|
|
@ -58,7 +59,7 @@ func LoadObjFile(arch *sys.Arch, syms *Symbols, f *bio.Reader, lib *Library, len
|
||||||
arch: arch,
|
arch: arch,
|
||||||
syms: syms,
|
syms: syms,
|
||||||
pn: pn,
|
pn: pn,
|
||||||
dupSym: &Symbol{Name: ".dup"},
|
dupSym: &sym.Symbol{Name: ".dup"},
|
||||||
localSymVersion: syms.IncVersion(),
|
localSymVersion: syms.IncVersion(),
|
||||||
}
|
}
|
||||||
r.loadObjFile()
|
r.loadObjFile()
|
||||||
|
|
@ -90,8 +91,8 @@ func (r *objReader) loadObjFile() {
|
||||||
r.lib.importStrings = append(r.lib.importStrings, lib)
|
r.lib.importStrings = append(r.lib.importStrings, lib)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Symbol references
|
// sym.Symbol references
|
||||||
r.refs = []*Symbol{nil} // zeroth ref is nil
|
r.refs = []*sym.Symbol{nil} // zeroth ref is nil
|
||||||
for {
|
for {
|
||||||
c, err := r.rd.Peek(1)
|
c, err := r.rd.Peek(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -134,16 +135,16 @@ func (r *objReader) readSlices() {
|
||||||
n := r.readInt()
|
n := r.readInt()
|
||||||
r.data = make([]byte, n)
|
r.data = make([]byte, n)
|
||||||
n = r.readInt()
|
n = r.readInt()
|
||||||
r.reloc = make([]Reloc, n)
|
r.reloc = make([]sym.Reloc, n)
|
||||||
n = r.readInt()
|
n = r.readInt()
|
||||||
r.pcdata = make([]Pcdata, n)
|
r.pcdata = make([]sym.Pcdata, n)
|
||||||
n = r.readInt()
|
n = r.readInt()
|
||||||
r.autom = make([]Auto, n)
|
r.autom = make([]sym.Auto, n)
|
||||||
n = r.readInt()
|
n = r.readInt()
|
||||||
r.funcdata = make([]*Symbol, n)
|
r.funcdata = make([]*sym.Symbol, n)
|
||||||
r.funcdataoff = make([]int64, n)
|
r.funcdataoff = make([]int64, n)
|
||||||
n = r.readInt()
|
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.
|
// 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 {
|
if c, err = r.rd.ReadByte(); err != nil {
|
||||||
log.Fatalln("error reading input: ", err)
|
log.Fatalln("error reading input: ", err)
|
||||||
}
|
}
|
||||||
t := abiSymKindToSymKind[c]
|
t := sym.AbiSymKindToSymKind[c]
|
||||||
s := r.readSymIndex()
|
s := r.readSymIndex()
|
||||||
flags := r.readInt()
|
flags := r.readInt()
|
||||||
dupok := flags&1 != 0
|
dupok := flags&1 != 0
|
||||||
|
|
@ -171,9 +172,9 @@ func (r *objReader) readSym() {
|
||||||
pkg := objabi.PathToPrefix(r.lib.Pkg)
|
pkg := objabi.PathToPrefix(r.lib.Pkg)
|
||||||
isdup := false
|
isdup := false
|
||||||
|
|
||||||
var dup *Symbol
|
var dup *sym.Symbol
|
||||||
if s.Type != 0 && s.Type != SXREF {
|
if s.Type != 0 && s.Type != sym.SXREF {
|
||||||
if (t == SDATA || t == SBSS || t == SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
|
if (t == sym.SDATA || t == sym.SBSS || t == sym.SNOPTRBSS) && len(data) == 0 && nreloc == 0 {
|
||||||
if s.Size < int64(size) {
|
if s.Size < int64(size) {
|
||||||
s.Size = int64(size)
|
s.Size = int64(size)
|
||||||
}
|
}
|
||||||
|
|
@ -183,10 +184,10 @@ func (r *objReader) readSym() {
|
||||||
return
|
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
|
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)
|
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 {
|
if len(s.P) > 0 {
|
||||||
|
|
@ -199,23 +200,23 @@ func (r *objReader) readSym() {
|
||||||
overwrite:
|
overwrite:
|
||||||
s.File = pkg
|
s.File = pkg
|
||||||
if dupok {
|
if dupok {
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= sym.AttrDuplicateOK
|
||||||
}
|
}
|
||||||
if t == SXREF {
|
if t == sym.SXREF {
|
||||||
log.Fatalf("bad sxref")
|
log.Fatalf("bad sxref")
|
||||||
}
|
}
|
||||||
if t == 0 {
|
if t == 0 {
|
||||||
log.Fatalf("missing type for %s in %s", s.Name, r.pn)
|
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
|
t = s.Type
|
||||||
}
|
}
|
||||||
s.Type = t
|
s.Type = t
|
||||||
if s.Size < int64(size) {
|
if s.Size < int64(size) {
|
||||||
s.Size = int64(size)
|
s.Size = int64(size)
|
||||||
}
|
}
|
||||||
s.Attr.Set(AttrLocal, local)
|
s.Attr.Set(sym.AttrLocal, local)
|
||||||
s.Attr.Set(AttrMakeTypelink, makeTypelink)
|
s.Attr.Set(sym.AttrMakeTypelink, makeTypelink)
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
s.Gotype = typ
|
s.Gotype = typ
|
||||||
}
|
}
|
||||||
|
|
@ -230,7 +231,7 @@ overwrite:
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < nreloc; i++ {
|
for i := 0; i < nreloc; i++ {
|
||||||
s.R[i] = Reloc{
|
s.R[i] = sym.Reloc{
|
||||||
Off: r.readInt32(),
|
Off: r.readInt32(),
|
||||||
Siz: r.readUint8(),
|
Siz: r.readUint8(),
|
||||||
Type: objabi.RelocType(r.readInt32()),
|
Type: objabi.RelocType(r.readInt32()),
|
||||||
|
|
@ -240,21 +241,21 @@ overwrite:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Type == STEXT {
|
if s.Type == sym.STEXT {
|
||||||
s.FuncInfo = new(FuncInfo)
|
s.FuncInfo = new(sym.FuncInfo)
|
||||||
pc := s.FuncInfo
|
pc := s.FuncInfo
|
||||||
|
|
||||||
pc.Args = r.readInt32()
|
pc.Args = r.readInt32()
|
||||||
pc.Locals = r.readInt32()
|
pc.Locals = r.readInt32()
|
||||||
if r.readUint8() != 0 {
|
if r.readUint8() != 0 {
|
||||||
s.Attr |= AttrNoSplit
|
s.Attr |= sym.AttrNoSplit
|
||||||
}
|
}
|
||||||
flags := r.readInt()
|
flags := r.readInt()
|
||||||
if flags&(1<<2) != 0 {
|
if flags&(1<<2) != 0 {
|
||||||
s.Attr |= AttrReflectMethod
|
s.Attr |= sym.AttrReflectMethod
|
||||||
}
|
}
|
||||||
if flags&(1<<3) != 0 {
|
if flags&(1<<3) != 0 {
|
||||||
s.Attr |= AttrShared
|
s.Attr |= sym.AttrShared
|
||||||
}
|
}
|
||||||
n := r.readInt()
|
n := r.readInt()
|
||||||
pc.Autom = r.autom[:n:n]
|
pc.Autom = r.autom[:n:n]
|
||||||
|
|
@ -263,7 +264,7 @@ overwrite:
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
pc.Autom[i] = Auto{
|
pc.Autom[i] = sym.Auto{
|
||||||
Asym: r.readSymIndex(),
|
Asym: r.readSymIndex(),
|
||||||
Aoffset: r.readInt32(),
|
Aoffset: r.readInt32(),
|
||||||
Name: r.readInt16(),
|
Name: r.readInt16(),
|
||||||
|
|
@ -305,7 +306,7 @@ overwrite:
|
||||||
pc.File[i] = r.readSymIndex()
|
pc.File[i] = r.readSymIndex()
|
||||||
}
|
}
|
||||||
n = r.readInt()
|
n = r.readInt()
|
||||||
pc.InlTree = make([]InlinedCall, n)
|
pc.InlTree = make([]sym.InlinedCall, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
pc.InlTree[i].Parent = r.readInt32()
|
pc.InlTree[i].Parent = r.readInt32()
|
||||||
pc.InlTree[i].File = r.readSymIndex()
|
pc.InlTree[i].File = r.readSymIndex()
|
||||||
|
|
@ -317,7 +318,7 @@ overwrite:
|
||||||
if s.Attr.OnList() {
|
if s.Attr.OnList() {
|
||||||
log.Fatalf("symbol %s listed multiple times", s.Name)
|
log.Fatalf("symbol %s listed multiple times", s.Name)
|
||||||
}
|
}
|
||||||
s.Attr |= AttrOnList
|
s.Attr |= sym.AttrOnList
|
||||||
r.lib.textp = append(r.lib.textp, s)
|
r.lib.textp = append(r.lib.textp, s)
|
||||||
} else {
|
} else {
|
||||||
// there may ba a dup in another package
|
// 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)
|
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
|
// This is kind of ugly. Really the package name should not
|
||||||
// even be included here.
|
// even be included here.
|
||||||
if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
|
if s.Size < 1 || s.P[0] != dwarf.DW_ABRV_FUNCTION {
|
||||||
|
|
@ -392,8 +393,8 @@ func (r *objReader) readRef() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
|
log.Panicf("failed to parse $-symbol %s: %v", s.Name, err)
|
||||||
}
|
}
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Attr |= AttrLocal
|
s.Attr |= sym.AttrLocal
|
||||||
switch s.Name[:5] {
|
switch s.Name[:5] {
|
||||||
case "$f32.":
|
case "$f32.":
|
||||||
if uint64(uint32(x)) != x {
|
if uint64(uint32(x)) != x {
|
||||||
|
|
@ -405,10 +406,10 @@ func (r *objReader) readRef() {
|
||||||
default:
|
default:
|
||||||
log.Panicf("unrecognized $-symbol: %s", s.Name)
|
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.") {
|
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
|
// 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()
|
i := r.readInt()
|
||||||
return r.refs[i]
|
return r.refs[i]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -58,7 +59,7 @@ func pciternext(it *Pciter) {
|
||||||
it.nextpc = it.pc + v*it.pcscale
|
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.d = *d
|
||||||
it.p = it.d.P
|
it.p = it.d.P
|
||||||
it.pc = 0
|
it.pc = 0
|
||||||
|
|
@ -70,7 +71,7 @@ func pciterinit(ctxt *Link, it *Pciter, d *Pcdata) {
|
||||||
pciternext(it)
|
pciternext(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addvarint(d *Pcdata, val uint32) {
|
func addvarint(d *sym.Pcdata, val uint32) {
|
||||||
n := int32(0)
|
n := int32(0)
|
||||||
for v := val; v >= 0x80; v >>= 7 {
|
for v := val; v >= 0x80; v >>= 7 {
|
||||||
n++
|
n++
|
||||||
|
|
@ -92,7 +93,7 @@ func addvarint(d *Pcdata, val uint32) {
|
||||||
p[0] = byte(v)
|
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
|
var start int32
|
||||||
if len(d.P) > 0 {
|
if len(d.P) > 0 {
|
||||||
start = int32(len(ftab.P))
|
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)))
|
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
|
n := int32(len(s)) + 1
|
||||||
start := int32(len(ftab.P))
|
start := int32(len(ftab.P))
|
||||||
ftab.Grow(int64(start) + int64(n) + 1)
|
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.
|
// numberfile assigns a file number to the file if it hasn't been assigned already.
|
||||||
func numberfile(ctxt *Link, file *Symbol) {
|
func numberfile(ctxt *Link, file *sym.Symbol) {
|
||||||
if file.Type != SFILEPATH {
|
if file.Type != sym.SFILEPATH {
|
||||||
ctxt.Filesyms = append(ctxt.Filesyms, file)
|
ctxt.Filesyms = append(ctxt.Filesyms, file)
|
||||||
file.Value = int64(len(ctxt.Filesyms))
|
file.Value = int64(len(ctxt.Filesyms))
|
||||||
file.Type = SFILEPATH
|
file.Type = sym.SFILEPATH
|
||||||
path := file.Name[len(src.FileSymPrefix):]
|
path := file.Name[len(src.FileSymPrefix):]
|
||||||
file.Name = expandGoroot(path)
|
file.Name = expandGoroot(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) {
|
func renumberfiles(ctxt *Link, files []*sym.Symbol, d *sym.Pcdata) {
|
||||||
var f *Symbol
|
var f *sym.Symbol
|
||||||
|
|
||||||
// Give files numbers.
|
// Give files numbers.
|
||||||
for i := 0; i < len(files); i++ {
|
for i := 0; i < len(files); i++ {
|
||||||
|
|
@ -130,7 +131,7 @@ func renumberfiles(ctxt *Link, files []*Symbol, d *Pcdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
newval := int32(-1)
|
newval := int32(-1)
|
||||||
var out Pcdata
|
var out sym.Pcdata
|
||||||
var it Pciter
|
var it Pciter
|
||||||
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
|
for pciterinit(ctxt, &it, d); it.done == 0; pciternext(&it) {
|
||||||
// value delta
|
// 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
|
// onlycsymbol reports whether this is a cgo symbol provided by the
|
||||||
// runtime and only used from C code.
|
// runtime and only used from C code.
|
||||||
func onlycsymbol(s *Symbol) bool {
|
func onlycsymbol(s *sym.Symbol) bool {
|
||||||
switch s.Name {
|
switch s.Name {
|
||||||
case "_cgo_topofstack", "_cgo_panic", "crosscall2":
|
case "_cgo_topofstack", "_cgo_panic", "crosscall2":
|
||||||
return true
|
return true
|
||||||
|
|
@ -171,7 +172,7 @@ func onlycsymbol(s *Symbol) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func emitPcln(s *Symbol) bool {
|
func emitPcln(s *sym.Symbol) bool {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -180,7 +181,7 @@ func emitPcln(s *Symbol) bool {
|
||||||
}
|
}
|
||||||
// We want to generate func table entries only for the "lowest level" symbols,
|
// We want to generate func table entries only for the "lowest level" symbols,
|
||||||
// not containers of subsymbols.
|
// not containers of subsymbols.
|
||||||
if s.Type&SCONTAINER != 0 {
|
if s.Type&sym.SCONTAINER != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
@ -189,20 +190,20 @@ func emitPcln(s *Symbol) bool {
|
||||||
// pclntab initializes the pclntab symbol with
|
// pclntab initializes the pclntab symbol with
|
||||||
// runtime function and file name information.
|
// 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.
|
// These variables are used to initialize runtime.firstmoduledata, see symtab.go:symtab.
|
||||||
var pclntabNfunc int32
|
var pclntabNfunc int32
|
||||||
var pclntabFiletabOffset int32
|
var pclntabFiletabOffset int32
|
||||||
var pclntabPclntabOffset int32
|
var pclntabPclntabOffset int32
|
||||||
var pclntabFirstFunc *Symbol
|
var pclntabFirstFunc *sym.Symbol
|
||||||
var pclntabLastFunc *Symbol
|
var pclntabLastFunc *sym.Symbol
|
||||||
|
|
||||||
func (ctxt *Link) pclntab() {
|
func (ctxt *Link) pclntab() {
|
||||||
funcdataBytes := int64(0)
|
funcdataBytes := int64(0)
|
||||||
ftab := ctxt.Syms.Lookup("runtime.pclntab", 0)
|
ftab := ctxt.Syms.Lookup("runtime.pclntab", 0)
|
||||||
ftab.Type = SPCLNTAB
|
ftab.Type = sym.SPCLNTAB
|
||||||
ftab.Attr |= AttrReachable
|
ftab.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
// See golang.org/s/go12symtab for the format. Briefly:
|
// See golang.org/s/go12symtab for the format. Briefly:
|
||||||
// 8-byte header
|
// 8-byte header
|
||||||
|
|
@ -212,10 +213,10 @@ func (ctxt *Link) pclntab() {
|
||||||
// offset to file table [4 bytes]
|
// offset to file table [4 bytes]
|
||||||
nfunc := int32(0)
|
nfunc := int32(0)
|
||||||
|
|
||||||
// Find container symbols, mark them with SCONTAINER
|
// Find container symbols, mark them with sym.SCONTAINER
|
||||||
for _, s := range ctxt.Textp {
|
for _, s := range ctxt.Textp {
|
||||||
if s.Outer != nil {
|
if s.Outer != nil {
|
||||||
s.Outer.Type |= SCONTAINER
|
s.Outer.Type |= sym.SCONTAINER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,7 +245,7 @@ func (ctxt *Link) pclntab() {
|
||||||
}
|
}
|
||||||
|
|
||||||
nfunc = 0
|
nfunc = 0
|
||||||
var last *Symbol
|
var last *sym.Symbol
|
||||||
for _, s := range ctxt.Textp {
|
for _, s := range ctxt.Textp {
|
||||||
last = s
|
last = s
|
||||||
if !emitPcln(s) {
|
if !emitPcln(s) {
|
||||||
|
|
@ -262,14 +263,14 @@ func (ctxt *Link) pclntab() {
|
||||||
if len(pcln.InlTree) > 0 {
|
if len(pcln.InlTree) > 0 {
|
||||||
if len(pcln.Pcdata) <= objabi.PCDATA_InlTreeIndex {
|
if len(pcln.Pcdata) <= objabi.PCDATA_InlTreeIndex {
|
||||||
// Create inlining pcdata table.
|
// Create inlining pcdata table.
|
||||||
pcdata := make([]Pcdata, objabi.PCDATA_InlTreeIndex+1)
|
pcdata := make([]sym.Pcdata, objabi.PCDATA_InlTreeIndex+1)
|
||||||
copy(pcdata, pcln.Pcdata)
|
copy(pcdata, pcln.Pcdata)
|
||||||
pcln.Pcdata = pcdata
|
pcln.Pcdata = pcdata
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(pcln.Funcdataoff) <= objabi.FUNCDATA_InlTree {
|
if len(pcln.Funcdataoff) <= objabi.FUNCDATA_InlTree {
|
||||||
// Create inline tree funcdata.
|
// 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)
|
funcdataoff := make([]int64, objabi.FUNCDATA_InlTree+1)
|
||||||
copy(funcdata, pcln.Funcdata)
|
copy(funcdata, pcln.Funcdata)
|
||||||
copy(funcdataoff, pcln.Funcdataoff)
|
copy(funcdataoff, pcln.Funcdataoff)
|
||||||
|
|
@ -334,8 +335,8 @@ func (ctxt *Link) pclntab() {
|
||||||
|
|
||||||
if len(pcln.InlTree) > 0 {
|
if len(pcln.InlTree) > 0 {
|
||||||
inlTreeSym := ctxt.Syms.Lookup("inltree."+s.Name, 0)
|
inlTreeSym := ctxt.Syms.Lookup("inltree."+s.Name, 0)
|
||||||
inlTreeSym.Type = SRODATA
|
inlTreeSym.Type = sym.SRODATA
|
||||||
inlTreeSym.Attr |= AttrReachable | AttrDuplicateOK
|
inlTreeSym.Attr |= sym.AttrReachable | sym.AttrDuplicateOK
|
||||||
|
|
||||||
for i, call := range pcln.InlTree {
|
for i, call := range pcln.InlTree {
|
||||||
// Usually, call.File is already numbered since the file
|
// 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.
|
// function for a pc. See src/runtime/symtab.go:findfunc for details.
|
||||||
func (ctxt *Link) findfunctab() {
|
func (ctxt *Link) findfunctab() {
|
||||||
t := ctxt.Syms.Lookup("runtime.findfunctab", 0)
|
t := ctxt.Syms.Lookup("runtime.findfunctab", 0)
|
||||||
t.Type = SRODATA
|
t.Type = sym.SRODATA
|
||||||
t.Attr |= AttrReachable
|
t.Attr |= sym.AttrReachable
|
||||||
t.Attr |= AttrLocal
|
t.Attr |= sym.AttrLocal
|
||||||
|
|
||||||
// find min and max address
|
// find min and max address
|
||||||
min := ctxt.Textp[0].Value
|
min := ctxt.Textp[0].Value
|
||||||
|
|
@ -468,7 +469,7 @@ func (ctxt *Link) findfunctab() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
p := s.Value
|
p := s.Value
|
||||||
var e *Symbol
|
var e *sym.Symbol
|
||||||
i++
|
i++
|
||||||
if i < len(ctxt.Textp) {
|
if i < len(ctxt.Textp) {
|
||||||
e = ctxt.Textp[i]
|
e = ctxt.Textp[i]
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"debug/pe"
|
"debug/pe"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -231,7 +232,7 @@ var dosstub = []uint8{
|
||||||
}
|
}
|
||||||
|
|
||||||
type Imp struct {
|
type Imp struct {
|
||||||
s *Symbol
|
s *sym.Symbol
|
||||||
off uint64
|
off uint64
|
||||||
next *Imp
|
next *Imp
|
||||||
argsize int
|
argsize int
|
||||||
|
|
@ -246,12 +247,12 @@ type Dll struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rsrcsym *Symbol
|
rsrcsym *sym.Symbol
|
||||||
PESECTHEADR int32
|
PESECTHEADR int32
|
||||||
PEFILEHEADR int32
|
PEFILEHEADR int32
|
||||||
pe64 int
|
pe64 int
|
||||||
dr *Dll
|
dr *Dll
|
||||||
dexport [1024]*Symbol
|
dexport [1024]*sym.Symbol
|
||||||
nexport int
|
nexport int
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -308,7 +309,7 @@ func (sect *peSection) checkOffset(off int64) {
|
||||||
|
|
||||||
// checkSegment verifies COFF section sect matches address
|
// checkSegment verifies COFF section sect matches address
|
||||||
// and file offset provided in segment seg.
|
// 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) {
|
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)))
|
Errorf(nil, "%s.VirtualAddress = %#x, want %#x", sect.name, uint64(int64(sect.virtualAddress)), uint64(int64(seg.Vaddr-PEBASE)))
|
||||||
errorexit()
|
errorexit()
|
||||||
|
|
@ -481,7 +482,7 @@ func (f *peFile) emitRelocations(ctxt *Link) {
|
||||||
|
|
||||||
// relocsect relocates symbols from first in section sect, and returns
|
// relocsect relocates symbols from first in section sect, and returns
|
||||||
// the total number of relocations emitted.
|
// 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 main section has no bits, nothing to relocate.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||||
return 0
|
return 0
|
||||||
|
|
@ -574,7 +575,7 @@ dwarfLoop:
|
||||||
|
|
||||||
// writeSymbol appends symbol s to file f symbol table.
|
// writeSymbol appends symbol s to file f symbol table.
|
||||||
// It also sets s.Dynid to written symbol number.
|
// 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 {
|
if len(s.Name) > 8 {
|
||||||
out.Write32(0)
|
out.Write32(0)
|
||||||
out.Write32(uint32(f.stringTable.add(s.Name)))
|
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.
|
// mapToPESection searches peFile f for s symbol's location.
|
||||||
// It returns PE section index, and offset within that section.
|
// 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 {
|
if s.Sect == nil {
|
||||||
return 0, 0, fmt.Errorf("could not map %s symbol with no section", s.Name)
|
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 {
|
if Linkmode != LinkExternal {
|
||||||
return f.dataSect.index, int64(v), nil
|
return f.dataSect.index, int64(v), nil
|
||||||
}
|
}
|
||||||
if s.Type == SDATA {
|
if s.Type == sym.SDATA {
|
||||||
return f.dataSect.index, int64(v), nil
|
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.
|
// it still belongs to the .data section, not the .bss section.
|
||||||
if v < Segdata.Filelen {
|
if v < Segdata.Filelen {
|
||||||
return f.dataSect.index, int64(v), nil
|
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.
|
// writeSymbols writes all COFF symbol table records.
|
||||||
func (f *peFile) writeSymbols(ctxt *Link) {
|
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 {
|
if s == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -638,7 +639,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
|
||||||
// Only windows/386 requires underscore prefix on external symbols.
|
// Only windows/386 requires underscore prefix on external symbols.
|
||||||
if ctxt.Arch.Family == sys.I386 &&
|
if ctxt.Arch.Family == sys.I386 &&
|
||||||
Linkmode == LinkExternal &&
|
Linkmode == LinkExternal &&
|
||||||
(s.Type == SHOSTOBJ || s.Attr.CgoExport()) {
|
(s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) {
|
||||||
s.Name = "_" + s.Name
|
s.Name = "_" + s.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -659,7 +660,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class := IMAGE_SYM_CLASS_EXTERNAL
|
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
|
class = IMAGE_SYM_CLASS_STATIC
|
||||||
}
|
}
|
||||||
f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
|
f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
|
||||||
|
|
@ -897,8 +898,8 @@ func Peinit(ctxt *Link) {
|
||||||
|
|
||||||
if Linkmode == LinkInternal {
|
if Linkmode == LinkInternal {
|
||||||
// some mingw libs depend on this symbol, for example, FindPESectionByName
|
// some mingw libs depend on this symbol, for example, FindPESectionByName
|
||||||
ctxt.xdefine("__image_base__", SDATA, PEBASE)
|
ctxt.xdefine("__image_base__", sym.SDATA, PEBASE)
|
||||||
ctxt.xdefine("_image_base__", SDATA, PEBASE)
|
ctxt.xdefine("_image_base__", sym.SDATA, PEBASE)
|
||||||
}
|
}
|
||||||
|
|
||||||
HEADR = PEFILEHEADR
|
HEADR = PEFILEHEADR
|
||||||
|
|
@ -947,7 +948,7 @@ func initdynimport(ctxt *Link) *Dll {
|
||||||
dr = nil
|
dr = nil
|
||||||
var m *Imp
|
var m *Imp
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
for _, s := range ctxt.Syms.Allsym {
|
||||||
if !s.Attr.Reachable() || s.Type != SDYNIMPORT {
|
if !s.Attr.Reachable() || s.Type != sym.SDYNIMPORT {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for d = dr; d != nil; d = d.next {
|
for d = dr; d != nil; d = d.next {
|
||||||
|
|
@ -989,7 +990,7 @@ func initdynimport(ctxt *Link) *Dll {
|
||||||
// Add real symbol name
|
// Add real symbol name
|
||||||
for d := dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
for m = d.ms; m != nil; m = m.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))
|
m.s.Grow(int64(ctxt.Arch.PtrSize))
|
||||||
dynName := m.s.Extname
|
dynName := m.s.Extname
|
||||||
// only windows/386 requires stdcall decoration
|
// only windows/386 requires stdcall decoration
|
||||||
|
|
@ -997,8 +998,8 @@ func initdynimport(ctxt *Link) *Dll {
|
||||||
dynName += fmt.Sprintf("@%d", m.argsize)
|
dynName += fmt.Sprintf("@%d", m.argsize)
|
||||||
}
|
}
|
||||||
dynSym := ctxt.Syms.Lookup(dynName, 0)
|
dynSym := ctxt.Syms.Lookup(dynName, 0)
|
||||||
dynSym.Attr |= AttrReachable
|
dynSym.Attr |= sym.AttrReachable
|
||||||
dynSym.Type = SHOSTOBJ
|
dynSym.Type = sym.SHOSTOBJ
|
||||||
r := m.s.AddRel()
|
r := m.s.AddRel()
|
||||||
r.Sym = dynSym
|
r.Sym = dynSym
|
||||||
r.Off = 0
|
r.Off = 0
|
||||||
|
|
@ -1008,11 +1009,11 @@ func initdynimport(ctxt *Link) *Dll {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
|
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
|
||||||
dynamic.Attr |= AttrReachable
|
dynamic.Attr |= sym.AttrReachable
|
||||||
dynamic.Type = SWINDOWS
|
dynamic.Type = sym.SWINDOWS
|
||||||
for d := dr; d != nil; d = d.next {
|
for d := dr; d != nil; d = d.next {
|
||||||
for m = d.ms; m != nil; m = m.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
|
m.s.Sub = dynamic.Sub
|
||||||
dynamic.Sub = m.s
|
dynamic.Sub = m.s
|
||||||
m.s.Value = dynamic.Size
|
m.s.Value = dynamic.Size
|
||||||
|
|
@ -1143,7 +1144,7 @@ func addimports(ctxt *Link, datsect *peSection) {
|
||||||
out.SeekSet(endoff)
|
out.SeekSet(endoff)
|
||||||
}
|
}
|
||||||
|
|
||||||
type byExtname []*Symbol
|
type byExtname []*sym.Symbol
|
||||||
|
|
||||||
func (s byExtname) Len() int { return len(s) }
|
func (s byExtname) Len() int { return len(s) }
|
||||||
func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
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 */
|
/* relocation table */
|
||||||
rel := ctxt.Syms.Lookup(".rel", 0)
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
||||||
|
|
||||||
rel.Attr |= AttrReachable
|
rel.Attr |= sym.AttrReachable
|
||||||
rel.Type = SELFROSECT
|
rel.Type = sym.SELFROSECT
|
||||||
|
|
||||||
initdynimport(ctxt)
|
initdynimport(ctxt)
|
||||||
initdynexport(ctxt)
|
initdynexport(ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setpersrc(ctxt *Link, sym *Symbol) {
|
func setpersrc(ctxt *Link, sym *sym.Symbol) {
|
||||||
if rsrcsym != nil {
|
if rsrcsym != nil {
|
||||||
Errorf(sym, "too many .rsrc sections")
|
Errorf(sym, "too many .rsrc sections")
|
||||||
}
|
}
|
||||||
|
|
@ -1263,7 +1264,7 @@ func addpersrc(ctxt *Link) {
|
||||||
|
|
||||||
// relocation
|
// relocation
|
||||||
var p []byte
|
var p []byte
|
||||||
var r *Reloc
|
var r *sym.Reloc
|
||||||
var val uint32
|
var val uint32
|
||||||
for ri := 0; ri < len(rsrcsym.R); ri++ {
|
for ri := 0; ri < len(rsrcsym.R); ri++ {
|
||||||
r = &rsrcsym.R[ri]
|
r = &rsrcsym.R[ri]
|
||||||
|
|
|
||||||
|
|
@ -34,19 +34,13 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func linknew(arch *sys.Arch) *Link {
|
func linknew(arch *sys.Arch) *Link {
|
||||||
ctxt := &Link{
|
ctxt := &Link{
|
||||||
Syms: &Symbols{
|
Syms: sym.NewSymbols(),
|
||||||
hash: []map[string]*Symbol{
|
|
||||||
// preallocate about 2mb for hash of
|
|
||||||
// non static symbols
|
|
||||||
make(map[string]*Symbol, 100000),
|
|
||||||
},
|
|
||||||
Allsym: make([]*Symbol, 0, 100000),
|
|
||||||
},
|
|
||||||
Out: &OutBuf{arch: arch},
|
Out: &OutBuf{arch: arch},
|
||||||
Arch: arch,
|
Arch: arch,
|
||||||
LibraryByPkg: make(map[string]*Library),
|
LibraryByPkg: make(map[string]*Library),
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ package ld
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -76,7 +77,7 @@ var numelfsym int = 1 // 0 is reserved
|
||||||
|
|
||||||
var elfbind int
|
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
|
var typ int
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
|
|
@ -109,7 +110,7 @@ func putelfsym(ctxt *Link, x *Symbol, s string, t SymbolType, addr int64, go_ *S
|
||||||
}
|
}
|
||||||
|
|
||||||
var elfshnum int
|
var elfshnum int
|
||||||
if xo.Type == SDYNIMPORT || xo.Type == SHOSTOBJ {
|
if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ {
|
||||||
elfshnum = SHN_UNDEF
|
elfshnum = SHN_UNDEF
|
||||||
} else {
|
} else {
|
||||||
if xo.Sect == nil {
|
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")
|
Errorf(x, "missing ELF section in putelfsym")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
elfshnum = xo.Sect.Elfsect.shnum
|
elfshnum = xo.Sect.Elfsect.(*ElfShdr).shnum
|
||||||
}
|
}
|
||||||
|
|
||||||
// One pass for each binding: STB_LOCAL, STB_GLOBAL,
|
// One pass for each binding: STB_LOCAL, STB_GLOBAL,
|
||||||
// maybe one day STB_WEAK.
|
// maybe one day STB_WEAK.
|
||||||
bind := STB_GLOBAL
|
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
|
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)
|
addr -= int64(xo.Sect.Vaddr)
|
||||||
}
|
}
|
||||||
other := STV_DEFAULT
|
other := STV_DEFAULT
|
||||||
if x.Type&SHIDDEN != 0 {
|
if x.Type&sym.SHIDDEN != 0 {
|
||||||
other = STV_HIDDEN
|
other = STV_HIDDEN
|
||||||
}
|
}
|
||||||
if ctxt.Arch.Family == sys.PPC64 && typ == STT_FUNC && x.Attr.Shared() && x.Name != "runtime.duffzero" && x.Name != "runtime.duffcopy" {
|
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)
|
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
|
// When dynamically linking, we want references to functions defined
|
||||||
// in this module to always be to the function object, not to the
|
// 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
|
// PLT. We force this by writing an additional local symbol for every
|
||||||
// global function symbol and making all relocations against the
|
// global function symbol and making all relocations against the
|
||||||
// global symbol refer to this local symbol instead (see
|
// 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
|
// ELF linker -Bsymbolic-functions option, but that is buggy on
|
||||||
// several platforms.
|
// several platforms.
|
||||||
putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
|
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++
|
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)
|
putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
|
||||||
s.Elfsym = int32(numelfsym)
|
s.Elfsym = int32(numelfsym)
|
||||||
numelfsym++
|
numelfsym++
|
||||||
|
|
@ -214,7 +215,7 @@ func Asmelfsym(ctxt *Link) {
|
||||||
genasmsym(ctxt, putelfsym)
|
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)
|
t := int(typ)
|
||||||
switch typ {
|
switch typ {
|
||||||
case TextSym, DataSym, BSSSym:
|
case TextSym, DataSym, BSSSym:
|
||||||
|
|
@ -247,7 +248,7 @@ func Asmplan9sym(ctxt *Link) {
|
||||||
genasmsym(ctxt, putplan9sym)
|
genasmsym(ctxt, putplan9sym)
|
||||||
}
|
}
|
||||||
|
|
||||||
var symt *Symbol
|
var symt *sym.Symbol
|
||||||
|
|
||||||
type byPkg []*Library
|
type byPkg []*Library
|
||||||
|
|
||||||
|
|
@ -268,8 +269,8 @@ func (libs byPkg) Swap(a, b int) {
|
||||||
func textsectionmap(ctxt *Link) uint32 {
|
func textsectionmap(ctxt *Link) uint32 {
|
||||||
|
|
||||||
t := ctxt.Syms.Lookup("runtime.textsectionmap", 0)
|
t := ctxt.Syms.Lookup("runtime.textsectionmap", 0)
|
||||||
t.Type = SRODATA
|
t.Type = sym.SRODATA
|
||||||
t.Attr |= AttrReachable
|
t.Attr |= sym.AttrReachable
|
||||||
nsections := int64(0)
|
nsections := int64(0)
|
||||||
|
|
||||||
for _, sect := range Segtext.Sections {
|
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.
|
// Define these so that they'll get put into the symbol table.
|
||||||
// data.c:/^address will provide the actual values.
|
// 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.etext", sym.STEXT, 0)
|
||||||
ctxt.xdefine("runtime.itablink", SRODATA, 0)
|
ctxt.xdefine("runtime.itablink", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.eitablink", SRODATA, 0)
|
ctxt.xdefine("runtime.eitablink", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.rodata", SRODATA, 0)
|
ctxt.xdefine("runtime.rodata", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.erodata", SRODATA, 0)
|
ctxt.xdefine("runtime.erodata", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.types", SRODATA, 0)
|
ctxt.xdefine("runtime.types", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.etypes", SRODATA, 0)
|
ctxt.xdefine("runtime.etypes", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.noptrdata", SNOPTRDATA, 0)
|
ctxt.xdefine("runtime.noptrdata", sym.SNOPTRDATA, 0)
|
||||||
ctxt.xdefine("runtime.enoptrdata", SNOPTRDATA, 0)
|
ctxt.xdefine("runtime.enoptrdata", sym.SNOPTRDATA, 0)
|
||||||
ctxt.xdefine("runtime.data", SDATA, 0)
|
ctxt.xdefine("runtime.data", sym.SDATA, 0)
|
||||||
ctxt.xdefine("runtime.edata", SDATA, 0)
|
ctxt.xdefine("runtime.edata", sym.SDATA, 0)
|
||||||
ctxt.xdefine("runtime.bss", SBSS, 0)
|
ctxt.xdefine("runtime.bss", sym.SBSS, 0)
|
||||||
ctxt.xdefine("runtime.ebss", SBSS, 0)
|
ctxt.xdefine("runtime.ebss", sym.SBSS, 0)
|
||||||
ctxt.xdefine("runtime.noptrbss", SNOPTRBSS, 0)
|
ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, 0)
|
||||||
ctxt.xdefine("runtime.enoptrbss", SNOPTRBSS, 0)
|
ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, 0)
|
||||||
ctxt.xdefine("runtime.end", SBSS, 0)
|
ctxt.xdefine("runtime.end", sym.SBSS, 0)
|
||||||
ctxt.xdefine("runtime.epclntab", SRODATA, 0)
|
ctxt.xdefine("runtime.epclntab", sym.SRODATA, 0)
|
||||||
ctxt.xdefine("runtime.esymtab", SRODATA, 0)
|
ctxt.xdefine("runtime.esymtab", sym.SRODATA, 0)
|
||||||
|
|
||||||
// garbage collection symbols
|
// garbage collection symbols
|
||||||
s := ctxt.Syms.Lookup("runtime.gcdata", 0)
|
s := ctxt.Syms.Lookup("runtime.gcdata", 0)
|
||||||
|
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
ctxt.xdefine("runtime.egcdata", SRODATA, 0)
|
ctxt.xdefine("runtime.egcdata", sym.SRODATA, 0)
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup("runtime.gcbss", 0)
|
s = ctxt.Syms.Lookup("runtime.gcbss", 0)
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
ctxt.xdefine("runtime.egcbss", SRODATA, 0)
|
ctxt.xdefine("runtime.egcbss", sym.SRODATA, 0)
|
||||||
|
|
||||||
// pseudo-symbols to mark locations of type, string, and go string data.
|
// pseudo-symbols to mark locations of type, string, and go string data.
|
||||||
var symtype *Symbol
|
var symtype *sym.Symbol
|
||||||
var symtyperel *Symbol
|
var symtyperel *sym.Symbol
|
||||||
if UseRelro() && (Buildmode == BuildmodeCArchive || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) {
|
if UseRelro() && (Buildmode == BuildmodeCArchive || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) {
|
||||||
s = ctxt.Syms.Lookup("type.*", 0)
|
s = ctxt.Syms.Lookup("type.*", 0)
|
||||||
|
|
||||||
s.Type = STYPE
|
s.Type = sym.STYPE
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
symtype = s
|
symtype = s
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup("typerel.*", 0)
|
s = ctxt.Syms.Lookup("typerel.*", 0)
|
||||||
|
|
||||||
s.Type = STYPERELRO
|
s.Type = sym.STYPERELRO
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
symtyperel = s
|
symtyperel = s
|
||||||
} else if !ctxt.DynlinkingGo() {
|
} else if !ctxt.DynlinkingGo() {
|
||||||
s = ctxt.Syms.Lookup("type.*", 0)
|
s = ctxt.Syms.Lookup("type.*", 0)
|
||||||
|
|
||||||
s.Type = STYPE
|
s.Type = sym.STYPE
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
symtype = s
|
symtype = s
|
||||||
symtyperel = 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 := ctxt.Syms.Lookup(name, 0)
|
||||||
s.Type = t
|
s.Type = t
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrLocal | AttrReachable
|
s.Attr |= sym.AttrLocal | sym.AttrReachable
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
symgostring = groupSym("go.string.*", SGOSTRING)
|
symgostring = groupSym("go.string.*", sym.SGOSTRING)
|
||||||
symgofunc = groupSym("go.func.*", SGOFUNC)
|
symgofunc = groupSym("go.func.*", sym.SGOFUNC)
|
||||||
symgcbits = groupSym("runtime.gcbits.*", SGCBITS)
|
symgcbits = groupSym("runtime.gcbits.*", sym.SGCBITS)
|
||||||
)
|
)
|
||||||
|
|
||||||
var symgofuncrel *Symbol
|
var symgofuncrel *sym.Symbol
|
||||||
if !ctxt.DynlinkingGo() {
|
if !ctxt.DynlinkingGo() {
|
||||||
if UseRelro() {
|
if UseRelro() {
|
||||||
symgofuncrel = groupSym("go.funcrel.*", SGOFUNCRELRO)
|
symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
|
||||||
} else {
|
} else {
|
||||||
symgofuncrel = symgofunc
|
symgofuncrel = symgofunc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
symitablink := ctxt.Syms.Lookup("runtime.itablink", 0)
|
symitablink := ctxt.Syms.Lookup("runtime.itablink", 0)
|
||||||
symitablink.Type = SITABLINK
|
symitablink.Type = sym.SITABLINK
|
||||||
|
|
||||||
symt = ctxt.Syms.Lookup("runtime.symtab", 0)
|
symt = ctxt.Syms.Lookup("runtime.symtab", 0)
|
||||||
symt.Attr |= AttrLocal
|
symt.Attr |= sym.AttrLocal
|
||||||
symt.Type = SSYMTAB
|
symt.Type = sym.SSYMTAB
|
||||||
symt.Size = 0
|
symt.Size = 0
|
||||||
symt.Attr |= AttrReachable
|
symt.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
nitablinks := 0
|
nitablinks := 0
|
||||||
|
|
||||||
|
|
@ -424,53 +425,53 @@ func (ctxt *Link) symtab() {
|
||||||
// just defined above will be first.
|
// just defined above will be first.
|
||||||
// hide the specific symbols.
|
// hide the specific symbols.
|
||||||
for _, s := range ctxt.Syms.Allsym {
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(s.Name, "type."):
|
case strings.HasPrefix(s.Name, "type."):
|
||||||
if !ctxt.DynlinkingGo() {
|
if !ctxt.DynlinkingGo() {
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
}
|
}
|
||||||
if UseRelro() {
|
if UseRelro() {
|
||||||
s.Type = STYPERELRO
|
s.Type = sym.STYPERELRO
|
||||||
s.Outer = symtyperel
|
s.Outer = symtyperel
|
||||||
} else {
|
} else {
|
||||||
s.Type = STYPE
|
s.Type = sym.STYPE
|
||||||
s.Outer = symtype
|
s.Outer = symtype
|
||||||
}
|
}
|
||||||
|
|
||||||
case strings.HasPrefix(s.Name, "go.importpath.") && UseRelro():
|
case strings.HasPrefix(s.Name, "go.importpath.") && UseRelro():
|
||||||
// Keep go.importpath symbols in the same section as types and
|
// Keep go.importpath symbols in the same section as types and
|
||||||
// names, as they can be referred to by a section offset.
|
// 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."):
|
case strings.HasPrefix(s.Name, "go.itablink."):
|
||||||
nitablinks++
|
nitablinks++
|
||||||
s.Type = SITABLINK
|
s.Type = sym.SITABLINK
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
s.Outer = symitablink
|
s.Outer = symitablink
|
||||||
|
|
||||||
case strings.HasPrefix(s.Name, "go.string."):
|
case strings.HasPrefix(s.Name, "go.string."):
|
||||||
s.Type = SGOSTRING
|
s.Type = sym.SGOSTRING
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
s.Outer = symgostring
|
s.Outer = symgostring
|
||||||
|
|
||||||
case strings.HasPrefix(s.Name, "runtime.gcbits."):
|
case strings.HasPrefix(s.Name, "runtime.gcbits."):
|
||||||
s.Type = SGCBITS
|
s.Type = sym.SGCBITS
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
s.Outer = symgcbits
|
s.Outer = symgcbits
|
||||||
|
|
||||||
case strings.HasSuffix(s.Name, "·f"):
|
case strings.HasSuffix(s.Name, "·f"):
|
||||||
if !ctxt.DynlinkingGo() {
|
if !ctxt.DynlinkingGo() {
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
}
|
}
|
||||||
if UseRelro() {
|
if UseRelro() {
|
||||||
s.Type = SGOFUNCRELRO
|
s.Type = sym.SGOFUNCRELRO
|
||||||
s.Outer = symgofuncrel
|
s.Outer = symgofuncrel
|
||||||
} else {
|
} else {
|
||||||
s.Type = SGOFUNC
|
s.Type = sym.SGOFUNC
|
||||||
s.Outer = symgofunc
|
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, "gclocals·"),
|
strings.HasPrefix(s.Name, "gclocals·"),
|
||||||
strings.HasPrefix(s.Name, "inltree."):
|
strings.HasPrefix(s.Name, "inltree."):
|
||||||
s.Type = SGOFUNC
|
s.Type = sym.SGOFUNC
|
||||||
s.Attr |= AttrNotInSymbolTable
|
s.Attr |= sym.AttrNotInSymbolTable
|
||||||
s.Outer = symgofunc
|
s.Outer = symgofunc
|
||||||
s.Align = 4
|
s.Align = 4
|
||||||
liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
|
liveness += (s.Size + int64(s.Align) - 1) &^ (int64(s.Align) - 1)
|
||||||
|
|
@ -488,8 +489,8 @@ func (ctxt *Link) symtab() {
|
||||||
|
|
||||||
if Buildmode == BuildmodeShared {
|
if Buildmode == BuildmodeShared {
|
||||||
abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
|
abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
|
||||||
abihashgostr.Attr |= AttrReachable
|
abihashgostr.Attr |= sym.AttrReachable
|
||||||
abihashgostr.Type = SRODATA
|
abihashgostr.Type = sym.SRODATA
|
||||||
hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
||||||
abihashgostr.AddAddr(ctxt.Arch, hashsym)
|
abihashgostr.AddAddr(ctxt.Arch, hashsym)
|
||||||
abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
|
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 {
|
if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
|
||||||
for _, l := range ctxt.Library {
|
for _, l := range ctxt.Library {
|
||||||
s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
|
s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
s.Type = SRODATA
|
s.Type = sym.SRODATA
|
||||||
s.Size = int64(len(l.hash))
|
s.Size = int64(len(l.hash))
|
||||||
s.P = []byte(l.hash)
|
s.P = []byte(l.hash)
|
||||||
str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
|
str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
|
||||||
str.Attr |= AttrReachable
|
str.Attr |= sym.AttrReachable
|
||||||
str.Type = SRODATA
|
str.Type = sym.SRODATA
|
||||||
str.AddAddr(ctxt.Arch, s)
|
str.AddAddr(ctxt.Arch, s)
|
||||||
str.AddUint(ctxt.Arch, uint64(len(l.hash)))
|
str.AddUint(ctxt.Arch, uint64(len(l.hash)))
|
||||||
}
|
}
|
||||||
|
|
@ -567,8 +568,8 @@ func (ctxt *Link) symtab() {
|
||||||
moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
|
moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
|
||||||
// The ptab slice
|
// The ptab slice
|
||||||
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
|
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
|
||||||
ptab.Attr |= AttrLocal
|
ptab.Attr |= sym.AttrLocal
|
||||||
ptab.Type = SRODATA
|
ptab.Type = sym.SRODATA
|
||||||
|
|
||||||
nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
|
nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
|
||||||
moduledata.AddAddr(ctxt.Arch, ptab)
|
moduledata.AddAddr(ctxt.Arch, ptab)
|
||||||
|
|
@ -583,9 +584,9 @@ func (ctxt *Link) symtab() {
|
||||||
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
|
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
|
||||||
|
|
||||||
pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
|
pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
|
||||||
pkghashes.Attr |= AttrReachable
|
pkghashes.Attr |= sym.AttrReachable
|
||||||
pkghashes.Attr |= AttrLocal
|
pkghashes.Attr |= sym.AttrLocal
|
||||||
pkghashes.Type = SRODATA
|
pkghashes.Type = sym.SRODATA
|
||||||
|
|
||||||
for i, l := range ctxt.Library {
|
for i, l := range ctxt.Library {
|
||||||
// pkghashes[i].name
|
// pkghashes[i].name
|
||||||
|
|
@ -617,9 +618,9 @@ func (ctxt *Link) symtab() {
|
||||||
addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
|
addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
|
||||||
|
|
||||||
modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0)
|
modulehashes := ctxt.Syms.Lookup("go.link.abihashes", 0)
|
||||||
modulehashes.Attr |= AttrReachable
|
modulehashes.Attr |= sym.AttrReachable
|
||||||
modulehashes.Attr |= AttrLocal
|
modulehashes.Attr |= sym.AttrLocal
|
||||||
modulehashes.Type = SRODATA
|
modulehashes.Type = sym.SRODATA
|
||||||
|
|
||||||
for i, shlib := range ctxt.Shlibs {
|
for i, shlib := range ctxt.Shlibs {
|
||||||
// modulehashes[i].modulename
|
// modulehashes[i].modulename
|
||||||
|
|
@ -631,7 +632,7 @@ func (ctxt *Link) symtab() {
|
||||||
|
|
||||||
// modulehashes[i].runtimehash
|
// modulehashes[i].runtimehash
|
||||||
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
|
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
|
||||||
abihash.Attr |= AttrReachable
|
abihash.Attr |= sym.AttrReachable
|
||||||
modulehashes.AddAddr(ctxt.Arch, abihash)
|
modulehashes.AddAddr(ctxt.Arch, abihash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,8 +650,8 @@ func (ctxt *Link) symtab() {
|
||||||
moduledata.Grow(moduledata.Size)
|
moduledata.Grow(moduledata.Size)
|
||||||
|
|
||||||
lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
|
lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
|
||||||
if lastmoduledatap.Type != SDYNIMPORT {
|
if lastmoduledatap.Type != sym.SDYNIMPORT {
|
||||||
lastmoduledatap.Type = SNOPTRDATA
|
lastmoduledatap.Type = sym.SNOPTRDATA
|
||||||
lastmoduledatap.Size = 0 // overwrite existing value
|
lastmoduledatap.Size = 0 // overwrite existing value
|
||||||
lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
|
lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package ld
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -13,7 +14,7 @@ type byTypeStr []typelinkSortKey
|
||||||
|
|
||||||
type typelinkSortKey struct {
|
type typelinkSortKey struct {
|
||||||
TypeStr string
|
TypeStr string
|
||||||
Type *Symbol
|
Type *sym.Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
|
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)
|
sort.Sort(typelinks)
|
||||||
|
|
||||||
tl := ctxt.Syms.Lookup("runtime.typelink", 0)
|
tl := ctxt.Syms.Lookup("runtime.typelink", 0)
|
||||||
tl.Type = STYPELINK
|
tl.Type = sym.STYPELINK
|
||||||
tl.Attr |= AttrReachable | AttrLocal
|
tl.Attr |= sym.AttrReachable | sym.AttrLocal
|
||||||
tl.Size = int64(4 * len(typelinks))
|
tl.Size = int64(4 * len(typelinks))
|
||||||
tl.P = make([]byte, tl.Size)
|
tl.P = make([]byte, tl.Size)
|
||||||
tl.R = make([]Reloc, len(typelinks))
|
tl.R = make([]sym.Reloc, len(typelinks))
|
||||||
for i, s := range typelinks {
|
for i, s := range typelinks {
|
||||||
r := &tl.R[i]
|
r := &tl.R[i]
|
||||||
r.Sym = s.Type
|
r.Sym = s.Type
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package ld
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -102,7 +103,7 @@ func Exitf(format string, a ...interface{}) {
|
||||||
//
|
//
|
||||||
// Logging an error means that on exit cmd/link will delete any
|
// Logging an error means that on exit cmd/link will delete any
|
||||||
// output file and return a non-zero error code.
|
// 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 {
|
if s != nil {
|
||||||
format = s.Name + ": " + format
|
format = s.Name + ": " + format
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
@ -42,12 +43,12 @@ func gentext(ctxt *ld.Link) {
|
||||||
return
|
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")
|
log.Fatalf("adddynrel not implemented")
|
||||||
return false
|
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))
|
ctxt.Out.Write32(uint32(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
elfsym := r.Xsym.ElfsymForReloc()
|
||||||
|
|
@ -76,11 +77,11 @@ func elfsetupplt(ctxt *ld.Link) {
|
||||||
return
|
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
|
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:])
|
o := arch.ByteOrder.Uint32(s.P[r.Off:])
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case objabi.R_ADDRMIPS, objabi.R_ADDRMIPSTLS:
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
|
|
@ -108,7 +109,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
rs = rs.Outer
|
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)
|
ld.Errorf(s, "missing section for %s", rs.Name)
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
r.Xsym = rs
|
||||||
|
|
@ -161,7 +162,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,18 +34,19 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func gentext(ctxt *ld.Link) {}
|
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")
|
log.Fatalf("adddynrel not implemented")
|
||||||
return false
|
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)
|
// mips64 ELF relocation (endian neutral)
|
||||||
// offset uint64
|
// offset uint64
|
||||||
// sym uint32
|
// sym uint32
|
||||||
|
|
@ -93,11 +94,11 @@ func elfsetupplt(ctxt *ld.Link) {
|
||||||
return
|
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
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
|
|
@ -114,7 +115,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
rs = rs.Outer
|
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)
|
ld.Errorf(s, "missing section for %s", rs.Name)
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
r.Xsym = rs
|
||||||
|
|
@ -168,7 +169,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
@ -88,11 +89,11 @@ func genplt(ctxt *ld.Link) {
|
||||||
//
|
//
|
||||||
// This assumes "case 1" from the ABI, where the caller needs
|
// This assumes "case 1" from the ABI, where the caller needs
|
||||||
// us to save and restore the TOC pointer.
|
// us to save and restore the TOC pointer.
|
||||||
var stubs []*ld.Symbol
|
var stubs []*sym.Symbol
|
||||||
for _, s := range ctxt.Textp {
|
for _, s := range ctxt.Textp {
|
||||||
for i := range s.R {
|
for i := range s.R {
|
||||||
r := &s.R[i]
|
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
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,7 +106,7 @@ func genplt(ctxt *ld.Link) {
|
||||||
|
|
||||||
stub := ctxt.Syms.Lookup(n, 0)
|
stub := ctxt.Syms.Lookup(n, 0)
|
||||||
if s.Attr.Reachable() {
|
if s.Attr.Reachable() {
|
||||||
stub.Attr |= ld.AttrReachable
|
stub.Attr |= sym.AttrReachable
|
||||||
}
|
}
|
||||||
if stub.Size == 0 {
|
if stub.Size == 0 {
|
||||||
// Need outer to resolve .TOC.
|
// Need outer to resolve .TOC.
|
||||||
|
|
@ -132,14 +133,14 @@ func genplt(ctxt *ld.Link) {
|
||||||
|
|
||||||
func genaddmoduledata(ctxt *ld.Link) {
|
func genaddmoduledata(ctxt *ld.Link) {
|
||||||
addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0)
|
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
|
return
|
||||||
}
|
}
|
||||||
addmoduledata.Attr |= ld.AttrReachable
|
addmoduledata.Attr |= sym.AttrReachable
|
||||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||||
initfunc.Type = ld.STEXT
|
initfunc.Type = sym.STEXT
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= sym.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= sym.AttrReachable
|
||||||
o := func(op uint32) {
|
o := func(op uint32) {
|
||||||
initfunc.AddUint32(ctxt.Arch, op)
|
initfunc.AddUint32(ctxt.Arch, op)
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +149,7 @@ func genaddmoduledata(ctxt *ld.Link) {
|
||||||
rel.Off = int32(initfunc.Size)
|
rel.Off = int32(initfunc.Size)
|
||||||
rel.Siz = 8
|
rel.Siz = 8
|
||||||
rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
|
rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
|
||||||
rel.Sym.Attr |= ld.AttrReachable
|
rel.Sym.Attr |= sym.AttrReachable
|
||||||
rel.Type = objabi.R_ADDRPOWER_PCREL
|
rel.Type = objabi.R_ADDRPOWER_PCREL
|
||||||
o(0x3c4c0000)
|
o(0x3c4c0000)
|
||||||
// addi r2, r2, .TOC.-func@l
|
// addi r2, r2, .TOC.-func@l
|
||||||
|
|
@ -166,8 +167,8 @@ func genaddmoduledata(ctxt *ld.Link) {
|
||||||
} else {
|
} else {
|
||||||
rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
|
rel.Sym = ctxt.Syms.Lookup("runtime.firstmoduledata", 0)
|
||||||
}
|
}
|
||||||
rel.Sym.Attr |= ld.AttrReachable
|
rel.Sym.Attr |= sym.AttrReachable
|
||||||
rel.Sym.Attr |= ld.AttrLocal
|
rel.Sym.Attr |= sym.AttrLocal
|
||||||
rel.Type = objabi.R_ADDRPOWER_GOT
|
rel.Type = objabi.R_ADDRPOWER_GOT
|
||||||
o(0x3c620000)
|
o(0x3c620000)
|
||||||
// ld r3, local.moduledata@got@l(r3)
|
// 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)
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= sym.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= sym.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = sym.SINITARR
|
||||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
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
|
// Construct a call stub in stub that calls symbol targ via its PLT
|
||||||
// entry.
|
// 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 abicase != 1 {
|
||||||
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
|
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
|
||||||
// relocations, we'll need to implement cases 2 and 3.
|
// 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)
|
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||||
|
|
||||||
stub.Type = ld.STEXT
|
stub.Type = sym.STEXT
|
||||||
|
|
||||||
// Save TOC pointer in TOC save slot
|
// Save TOC pointer in TOC save slot
|
||||||
stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1)
|
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.Off += int32(r.Siz)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_POWER_TOC
|
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
|
stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
|
||||||
r = stub.AddRel()
|
r = stub.AddRel()
|
||||||
r.Off = int32(stub.Size)
|
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.Off += int32(r.Siz)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_POWER_TOC
|
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)
|
stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
|
||||||
|
|
||||||
// Jump to the loaded pointer
|
// 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
|
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
|
targ := r.Sym
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
if r.Type >= 256 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,7 +279,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
// to use r12 to compute r2.)
|
// to use r12 to compute r2.)
|
||||||
r.Add += int64(r.Sym.Localentry) * 4
|
r.Add += int64(r.Sym.Localentry) * 4
|
||||||
|
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
// Should have been handled in elfsetupplt
|
// Should have been handled in elfsetupplt
|
||||||
ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
|
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.Type = objabi.R_PCREL
|
||||||
r.Add += 4
|
r.Add += 4
|
||||||
|
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
|
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:
|
case 256 + ld.R_PPC64_ADDR64:
|
||||||
r.Type = objabi.R_ADDR
|
r.Type = objabi.R_ADDR
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
// These happen in .toc sections
|
// These happen in .toc sections
|
||||||
ld.Adddynsym(ctxt, targ)
|
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:
|
case 256 + ld.R_PPC64_TOC16:
|
||||||
r.Type = objabi.R_POWER_TOC
|
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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_TOC16_LO:
|
case 256 + ld.R_PPC64_TOC16_LO:
|
||||||
r.Type = objabi.R_POWER_TOC
|
r.Type = objabi.R_POWER_TOC
|
||||||
r.Variant = ld.RV_POWER_LO
|
r.Variant = sym.RV_POWER_LO
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_TOC16_HA:
|
case 256 + ld.R_PPC64_TOC16_HA:
|
||||||
r.Type = objabi.R_POWER_TOC
|
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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_TOC16_HI:
|
case 256 + ld.R_PPC64_TOC16_HI:
|
||||||
r.Type = objabi.R_POWER_TOC
|
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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_TOC16_DS:
|
case 256 + ld.R_PPC64_TOC16_DS:
|
||||||
r.Type = objabi.R_POWER_TOC
|
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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_TOC16_LO_DS:
|
case 256 + ld.R_PPC64_TOC16_LO_DS:
|
||||||
r.Type = objabi.R_POWER_TOC
|
r.Type = objabi.R_POWER_TOC
|
||||||
r.Variant = ld.RV_POWER_DS
|
r.Variant = sym.RV_POWER_DS
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_REL16_LO:
|
case 256 + ld.R_PPC64_REL16_LO:
|
||||||
r.Type = objabi.R_PCREL
|
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
|
r.Add += 2 // Compensate for relocation size of 2
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_REL16_HI:
|
case 256 + ld.R_PPC64_REL16_HI:
|
||||||
r.Type = objabi.R_PCREL
|
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
|
r.Add += 2
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_PPC64_REL16_HA:
|
case 256 + ld.R_PPC64_REL16_HA:
|
||||||
r.Type = objabi.R_PCREL
|
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
|
r.Add += 2
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle references to ELF symbols from our own object files.
|
// Handle references to ELF symbols from our own object files.
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,7 +370,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return false
|
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))
|
ctxt.Out.Write64(uint64(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
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 false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the value of .TOC. for symbol s
|
// Return the value of .TOC. for symbol s
|
||||||
func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 {
|
func symtoc(ctxt *ld.Link, s *sym.Symbol) int64 {
|
||||||
var toc *ld.Symbol
|
var toc *sym.Symbol
|
||||||
|
|
||||||
if s.Outer != nil {
|
if s.Outer != nil {
|
||||||
toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version))
|
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
|
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
|
var o1, o2 uint32
|
||||||
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = uint32(*val >> 32)
|
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
|
// 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.
|
// 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.
|
// 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 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) {
|
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++ {
|
for i := 0; ; i++ {
|
||||||
|
|
||||||
// Using r.Add as part of the name is significant in functions like duffzero where the call
|
// 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
|
r.Done = false
|
||||||
}
|
}
|
||||||
default:
|
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
|
// Used for default build mode for an executable
|
||||||
// Address of the call target is generated using
|
// Address of the call target is generated using
|
||||||
// relocation and doesn't depend on r2 (TOC).
|
// 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)
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
|
|
@ -646,7 +647,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
rs = rs.Outer
|
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)
|
ld.Errorf(s, "missing section for %s", rs.Name)
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
r.Xsym = rs
|
||||||
|
|
@ -704,17 +705,17 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
switch r.Variant & ld.RV_TYPE_MASK {
|
switch r.Variant & sym.RV_TYPE_MASK {
|
||||||
default:
|
default:
|
||||||
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
|
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case ld.RV_NONE:
|
case sym.RV_NONE:
|
||||||
return t
|
return t
|
||||||
|
|
||||||
case ld.RV_POWER_LO:
|
case sym.RV_POWER_LO:
|
||||||
if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
|
if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
|
||||||
// Whether to check for signed or unsigned
|
// Whether to check for signed or unsigned
|
||||||
// overflow depends on the instruction
|
// overflow depends on the instruction
|
||||||
var o1 uint32
|
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))
|
return int64(int16(t))
|
||||||
|
|
||||||
case ld.RV_POWER_HA:
|
case sym.RV_POWER_HA:
|
||||||
t += 0x8000
|
t += 0x8000
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
// Fallthrough
|
// Fallthrough
|
||||||
case ld.RV_POWER_HI:
|
case sym.RV_POWER_HI:
|
||||||
t >>= 16
|
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
|
// Whether to check for signed or unsigned
|
||||||
// overflow depends on the instruction
|
// overflow depends on the instruction
|
||||||
var o1 uint32
|
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))
|
return int64(int16(t))
|
||||||
|
|
||||||
case ld.RV_POWER_DS:
|
case sym.RV_POWER_DS:
|
||||||
var o1 uint32
|
var o1 uint32
|
||||||
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
if ctxt.Arch.ByteOrder == binary.BigEndian {
|
||||||
o1 = uint32(ld.Be16(s.P[r.Off:]))
|
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 {
|
if t&3 != 0 {
|
||||||
ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
|
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
|
goto overflow
|
||||||
}
|
}
|
||||||
return int64(o1)&0x3 | int64(int16(t))
|
return int64(o1)&0x3 | int64(int16(t))
|
||||||
|
|
@ -795,7 +796,7 @@ overflow:
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||||
if s.Plt >= 0 {
|
if s.Plt >= 0 {
|
||||||
return
|
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
|
// 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)
|
glink := ctxt.Syms.Lookup(".glink", 0)
|
||||||
if glink.Size != 0 {
|
if glink.Size != 0 {
|
||||||
return glink
|
return glink
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"debug/elf"
|
"debug/elf"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
@ -53,16 +54,16 @@ func gentext(ctxt *ld.Link) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
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
|
// we're linking a module containing the runtime -> no need for
|
||||||
// an init function
|
// an init function
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addmoduledata.Attr |= ld.AttrReachable
|
addmoduledata.Attr |= sym.AttrReachable
|
||||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||||
initfunc.Type = ld.STEXT
|
initfunc.Type = sym.STEXT
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= sym.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
// larl %r2, <local.moduledata>
|
// larl %r2, <local.moduledata>
|
||||||
initfunc.AddUint8(0xc0)
|
initfunc.AddUint8(0xc0)
|
||||||
|
|
@ -72,7 +73,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
lmd.Siz = 4
|
lmd.Siz = 4
|
||||||
lmd.Sym = ctxt.Moduledata
|
lmd.Sym = ctxt.Moduledata
|
||||||
lmd.Type = objabi.R_PCREL
|
lmd.Type = objabi.R_PCREL
|
||||||
lmd.Variant = ld.RV_390_DBL
|
lmd.Variant = sym.RV_390_DBL
|
||||||
lmd.Add = 2 + int64(lmd.Siz)
|
lmd.Add = 2 + int64(lmd.Siz)
|
||||||
initfunc.AddUint32(ctxt.Arch, 0)
|
initfunc.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
|
|
@ -84,7 +85,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||||
rel.Type = objabi.R_CALL
|
rel.Type = objabi.R_CALL
|
||||||
rel.Variant = ld.RV_390_DBL
|
rel.Variant = sym.RV_390_DBL
|
||||||
rel.Add = 2 + int64(rel.Siz)
|
rel.Add = 2 + int64(rel.Siz)
|
||||||
initfunc.AddUint32(ctxt.Arch, 0)
|
initfunc.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
|
|
@ -95,13 +96,13 @@ func gentext(ctxt *ld.Link) {
|
||||||
}
|
}
|
||||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= sym.AttrLocal
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= sym.AttrReachable
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = sym.SINITARR
|
||||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
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
|
targ := r.Sym
|
||||||
|
|
||||||
switch r.Type {
|
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_16,
|
||||||
256 + ld.R_390_32,
|
256 + ld.R_390_32,
|
||||||
256 + ld.R_390_64:
|
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)
|
ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_ADDR
|
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,
|
case 256 + ld.R_390_PC16,
|
||||||
256 + ld.R_390_PC32,
|
256 + ld.R_390_PC32,
|
||||||
256 + ld.R_390_PC64:
|
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)
|
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)
|
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_PCREL
|
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,
|
case 256 + ld.R_390_PLT16DBL,
|
||||||
256 + ld.R_390_PLT32DBL:
|
256 + ld.R_390_PLT32DBL:
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
r.Variant = ld.RV_390_DBL
|
r.Variant = sym.RV_390_DBL
|
||||||
r.Add += int64(r.Siz)
|
r.Add += int64(r.Siz)
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add += int64(targ.Plt)
|
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:
|
256 + ld.R_390_PLT64:
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
r.Add += int64(r.Siz)
|
r.Add += int64(r.Siz)
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add += int64(targ.Plt)
|
r.Add += int64(targ.Plt)
|
||||||
|
|
@ -186,7 +187,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return false
|
return false
|
||||||
|
|
||||||
case 256 + ld.R_390_GOTOFF:
|
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)
|
ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_GOTOFF
|
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,
|
case 256 + ld.R_390_PC16DBL,
|
||||||
256 + ld.R_390_PC32DBL:
|
256 + ld.R_390_PC32DBL:
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
r.Variant = ld.RV_390_DBL
|
r.Variant = sym.RV_390_DBL
|
||||||
r.Add += int64(r.Siz)
|
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)
|
ld.Errorf(s, "unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_390_GOTPCDBL:
|
case 256 + ld.R_390_GOTPCDBL:
|
||||||
r.Type = objabi.R_PCREL
|
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.Sym = ctxt.Syms.Lookup(".got", 0)
|
||||||
r.Add += int64(r.Siz)
|
r.Add += int64(r.Siz)
|
||||||
return true
|
return true
|
||||||
|
|
@ -219,21 +220,21 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
addgotsym(ctxt, targ)
|
addgotsym(ctxt, targ)
|
||||||
|
|
||||||
r.Type = objabi.R_PCREL
|
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.Sym = ctxt.Syms.Lookup(".got", 0)
|
||||||
r.Add += int64(targ.Got)
|
r.Add += int64(targ.Got)
|
||||||
r.Add += int64(r.Siz)
|
r.Add += int64(r.Siz)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Handle references to ELF symbols from our own object files.
|
// Handle references to ELF symbols from our own object files.
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
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))
|
ctxt.Out.Write64(uint64(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
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:
|
case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
|
||||||
elfrel := ld.R_390_NONE
|
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
|
// TODO(mundaym): all DBL style relocations should be
|
||||||
// signalled using the variant - see issue 14218.
|
// signalled using the variant - see issue 14218.
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
case objabi.R_PCRELDBL, objabi.R_CALL:
|
case objabi.R_PCRELDBL, objabi.R_CALL:
|
||||||
isdbl = true
|
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 {
|
if isdbl {
|
||||||
switch r.Siz {
|
switch r.Siz {
|
||||||
case 2:
|
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
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -398,16 +399,16 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
switch r.Variant & ld.RV_TYPE_MASK {
|
switch r.Variant & sym.RV_TYPE_MASK {
|
||||||
default:
|
default:
|
||||||
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
|
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
case ld.RV_NONE:
|
case sym.RV_NONE:
|
||||||
return t
|
return t
|
||||||
|
|
||||||
case ld.RV_390_DBL:
|
case sym.RV_390_DBL:
|
||||||
if (t & 1) != 0 {
|
if (t & 1) != 0 {
|
||||||
ld.Errorf(s, "%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
|
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 {
|
if s.Plt >= 0 {
|
||||||
return
|
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 {
|
if s.Got >= 0 {
|
||||||
return
|
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
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package ld
|
package sym
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
|
|
@ -105,19 +105,19 @@ func (s *Symbol) AddUint8(v uint8) int64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) 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 {
|
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 {
|
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 {
|
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 {
|
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]
|
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
|
off := s.Size
|
||||||
s.setUintXX(arch, off, v, int64(wid))
|
s.setUintXX(arch, off, v, int64(wid))
|
||||||
return off
|
return off
|
||||||
|
|
@ -263,3 +263,37 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
|
||||||
|
|
||||||
return off + wid
|
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
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
package ld
|
package sym
|
||||||
|
|
||||||
type Symbols struct {
|
type Symbols struct {
|
||||||
symbolBatch []Symbol
|
symbolBatch []Symbol
|
||||||
|
|
@ -39,7 +39,18 @@ type Symbols struct {
|
||||||
Allsym []*Symbol
|
Allsym []*Symbol
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syms *Symbols) newsym(name string, v int) *Symbol {
|
func NewSymbols() *Symbols {
|
||||||
|
return &Symbols{
|
||||||
|
hash: []map[string]*Symbol{
|
||||||
|
// preallocate about 2mb for hash of
|
||||||
|
// non static symbols
|
||||||
|
make(map[string]*Symbol, 100000),
|
||||||
|
},
|
||||||
|
Allsym: make([]*Symbol, 0, 100000),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (syms *Symbols) Newsym(name string, v int) *Symbol {
|
||||||
batch := syms.symbolBatch
|
batch := syms.symbolBatch
|
||||||
if len(batch) == 0 {
|
if len(batch) == 0 {
|
||||||
batch = make([]Symbol, 1000)
|
batch = make([]Symbol, 1000)
|
||||||
|
|
@ -65,7 +76,7 @@ func (syms *Symbols) Lookup(name string, v int) *Symbol {
|
||||||
if s != nil {
|
if s != nil {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
s = syms.newsym(name, v)
|
s = syms.Newsym(name, v)
|
||||||
s.Extname = s.Name
|
s.Extname = s.Name
|
||||||
m[name] = s
|
m[name] = s
|
||||||
return s
|
return s
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
package ld
|
package sym
|
||||||
|
|
||||||
// A SymKind describes the kind of memory represented by a symbol.
|
// A SymKind describes the kind of memory represented by a symbol.
|
||||||
type SymKind int16
|
type SymKind int16
|
||||||
|
|
@ -111,9 +111,9 @@ const (
|
||||||
SCONTAINER = SymKind(1 << 10) // has a sub-symbol
|
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.
|
// of type cmd/internal/objabi.SymKind) to values of type SymKind.
|
||||||
var abiSymKindToSymKind = [...]SymKind{
|
var AbiSymKindToSymKind = [...]SymKind{
|
||||||
Sxxx,
|
Sxxx,
|
||||||
STEXT,
|
STEXT,
|
||||||
SRODATA,
|
SRODATA,
|
||||||
|
|
@ -127,10 +127,10 @@ var abiSymKindToSymKind = [...]SymKind{
|
||||||
SDWARFLOC,
|
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
|
// cases, if they will require relocations, they are transformed into
|
||||||
// rel-ro sections using relROMap.
|
// rel-ro sections using relROMap.
|
||||||
var readOnly = []SymKind{
|
var ReadOnly = []SymKind{
|
||||||
STYPE,
|
STYPE,
|
||||||
SSTRING,
|
SSTRING,
|
||||||
SGOSTRING,
|
SGOSTRING,
|
||||||
|
|
@ -140,9 +140,9 @@ var readOnly = []SymKind{
|
||||||
SFUNCTAB,
|
SFUNCTAB,
|
||||||
}
|
}
|
||||||
|
|
||||||
// relROMap describes the transformation of read-only symbols to rel-ro
|
// RelROMap describes the transformation of read-only symbols to rel-ro
|
||||||
// symbols.
|
// symbols.
|
||||||
var relROMap = map[SymKind]SymKind{
|
var RelROMap = map[SymKind]SymKind{
|
||||||
STYPE: STYPERELRO,
|
STYPE: STYPERELRO,
|
||||||
SSTRING: SSTRINGRELRO,
|
SSTRING: SSTRINGRELRO,
|
||||||
SGOSTRING: SGOSTRINGRELRO,
|
SGOSTRING: SGOSTRINGRELRO,
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
|
// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
|
||||||
|
|
||||||
package ld
|
package sym
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
|
@ -34,12 +34,13 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/ld"
|
"cmd/link/internal/ld"
|
||||||
|
"cmd/link/internal/sym"
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
|
// 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) {
|
func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
|
||||||
s.Attr |= ld.AttrReachable
|
s.Attr |= sym.AttrReachable
|
||||||
i := s.Size
|
i := s.Size
|
||||||
s.Size += 4
|
s.Size += 4
|
||||||
s.Grow(s.Size)
|
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.
|
// 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 {
|
for _, r := range [...]struct {
|
||||||
name string
|
name string
|
||||||
num uint8
|
num uint8
|
||||||
|
|
@ -82,9 +83,9 @@ func gentext(ctxt *ld.Link) {
|
||||||
{"di", 7},
|
{"di", 7},
|
||||||
} {
|
} {
|
||||||
thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
|
thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
|
||||||
thunkfunc.Type = ld.STEXT
|
thunkfunc.Type = sym.STEXT
|
||||||
thunkfunc.Attr |= ld.AttrLocal
|
thunkfunc.Attr |= sym.AttrLocal
|
||||||
thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
|
thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
|
||||||
o := func(op ...uint8) {
|
o := func(op ...uint8) {
|
||||||
for _, op1 := range op {
|
for _, op1 := range op {
|
||||||
thunkfunc.AddUint8(op1)
|
thunkfunc.AddUint8(op1)
|
||||||
|
|
@ -101,18 +102,18 @@ func gentext(ctxt *ld.Link) {
|
||||||
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
|
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
|
||||||
|
|
||||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
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
|
// we're linking a module containing the runtime -> no need for
|
||||||
// an init function
|
// an init function
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
addmoduledata.Attr |= ld.AttrReachable
|
addmoduledata.Attr |= sym.AttrReachable
|
||||||
|
|
||||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||||
initfunc.Type = ld.STEXT
|
initfunc.Type = sym.STEXT
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= sym.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= sym.AttrReachable
|
||||||
o := func(op ...uint8) {
|
o := func(op ...uint8) {
|
||||||
for _, op1 := range op {
|
for _, op1 := range op {
|
||||||
initfunc.AddUint8(op1)
|
initfunc.AddUint8(op1)
|
||||||
|
|
@ -159,28 +160,28 @@ func gentext(ctxt *ld.Link) {
|
||||||
}
|
}
|
||||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= sym.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= sym.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = sym.SINITARR
|
||||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
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
|
targ := r.Sym
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
if r.Type >= 256 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle relocations found in ELF object files.
|
// Handle relocations found in ELF object files.
|
||||||
case 256 + ld.R_386_PC32:
|
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)
|
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)
|
ld.Errorf(s, "unknown symbol %s in pcrel", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_PCREL
|
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:
|
case 256 + ld.R_386_PLT32:
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
r.Add += 4
|
r.Add += 4
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add += int64(targ.Plt)
|
r.Add += int64(targ.Plt)
|
||||||
|
|
@ -199,7 +200,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_386_GOT32, 256 + ld.R_386_GOT32X:
|
case 256 + ld.R_386_GOT32, 256 + ld.R_386_GOT32X:
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
// have symbol
|
// have symbol
|
||||||
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
|
if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
|
||||||
// turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
|
// 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
|
return true
|
||||||
|
|
||||||
case 256 + ld.R_386_32:
|
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)
|
ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_ADDR
|
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:
|
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
|
||||||
r.Type = objabi.R_ADDR
|
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)
|
ld.Errorf(s, "unexpected reloc for dynamic symbol %s", targ.Name)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
|
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
|
||||||
if targ.Type == ld.SDYNIMPORT {
|
if targ.Type == sym.SDYNIMPORT {
|
||||||
addpltsym(ctxt, targ)
|
addpltsym(ctxt, targ)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Add = int64(targ.Plt)
|
r.Add = int64(targ.Plt)
|
||||||
|
|
@ -266,7 +267,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case 512 + ld.MACHO_FAKE_GOTPCREL:
|
case 512 + ld.MACHO_FAKE_GOTPCREL:
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
// have symbol
|
// have symbol
|
||||||
// turn MOVL of GOT entry into LEAL of symbol itself
|
// turn MOVL of GOT entry into LEAL of symbol itself
|
||||||
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
|
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.
|
// Handle references to ELF symbols from our own object files.
|
||||||
if targ.Type != ld.SDYNIMPORT {
|
if targ.Type != sym.SDYNIMPORT {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
switch r.Type {
|
switch r.Type {
|
||||||
|
|
@ -299,7 +300,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return true
|
return true
|
||||||
|
|
||||||
case objabi.R_ADDR:
|
case objabi.R_ADDR:
|
||||||
if s.Type != ld.SDATA {
|
if s.Type != sym.SDATA {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
|
|
@ -326,7 +327,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
ld.Adddynsym(ctxt, targ)
|
ld.Adddynsym(ctxt, targ)
|
||||||
|
|
||||||
got := ctxt.Syms.Lookup(".got", 0)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Type = got.Type | ld.SSUB
|
s.Type = got.Type | sym.SSUB
|
||||||
s.Outer = got
|
s.Outer = got
|
||||||
s.Sub = got.Sub
|
s.Sub = got.Sub
|
||||||
got.Sub = s
|
got.Sub = s
|
||||||
|
|
@ -341,7 +342,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
return false
|
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))
|
ctxt.Out.Write32(uint32(sectoff))
|
||||||
|
|
||||||
elfsym := r.Xsym.ElfsymForReloc()
|
elfsym := r.Xsym.ElfsymForReloc()
|
||||||
|
|
@ -366,7 +367,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
|
||||||
}
|
}
|
||||||
case objabi.R_CALL:
|
case objabi.R_CALL:
|
||||||
if r.Siz == 4 {
|
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)
|
ctxt.Out.Write32(ld.R_386_PLT32 | uint32(elfsym)<<8)
|
||||||
} else {
|
} else {
|
||||||
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8)
|
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
|
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
|
var v uint32
|
||||||
|
|
||||||
rs := r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if rs.Type == ld.SHOSTOBJ {
|
if rs.Type == sym.SHOSTOBJ {
|
||||||
if rs.Dynid < 0 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -415,7 +416,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
} else {
|
} else {
|
||||||
v = uint32(rs.Sect.Extnum)
|
v = uint32(rs.Sect.Extnum)
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -449,13 +450,13 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
|
||||||
return true
|
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
|
var v uint32
|
||||||
|
|
||||||
rs := r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
if rs.Dynid < 0 {
|
if rs.Dynid < 0 {
|
||||||
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
|
ld.Errorf(s, "reloc %d (%s) to non-coff symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,7 +483,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff
|
||||||
return true
|
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 {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -498,7 +499,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
|
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
||||||
log.Fatalf("unexpected relocation variant")
|
log.Fatalf("unexpected relocation variant")
|
||||||
return t
|
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 {
|
if s.Plt >= 0 {
|
||||||
return
|
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 {
|
if s.Got >= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue