作者:xslonepiec
项目:goio
func elfsetupplt() {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0)
if plt.Size == 0 {
// pushl got+4
ld.Adduint8(ld.Ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x35)
ld.Addaddrplus(ld.Ctxt, plt, got, 4)
// jmp *got+8
ld.Adduint8(ld.Ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x25)
ld.Addaddrplus(ld.Ctxt, plt, got, 8)
// zero pad
ld.Adduint32(ld.Ctxt, plt, 0)
// assume got->size == 0 too
ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0)
ld.Adduint32(ld.Ctxt, got, 0)
ld.Adduint32(ld.Ctxt, got, 0)
}
}
作者:kluesk
项目:go-akaro
// Generate the glink resolver stub if necessary and return the .glink section
func ensureglinkresolver() *ld.LSym {
glink := ld.Linklookup(ld.Ctxt, ".glink", 0)
if glink.Size != 0 {
return glink
}
// This is essentially the resolver from the ppc64 ELF ABI.
// At entry, r12 holds the address of the symbol resolver stub
// for the target routine and the argument registers hold the
// arguments for the target routine.
//
// This stub is PIC, so first get the PC of label 1 into r11.
// Other things will be relative to this.
ld.Adduint32(ld.Ctxt, glink, 0x7c0802a6) // mflr r0
ld.Adduint32(ld.Ctxt, glink, 0x429f0005) // bcl 20,31,1f
ld.Adduint32(ld.Ctxt, glink, 0x7d6802a6) // 1: mflr r11
ld.Adduint32(ld.Ctxt, glink, 0x7c0803a6) // mtlf r0
// Compute the .plt array index from the entry point address.
// Because this is PIC, everything is relative to label 1b (in
// r11):
// r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
ld.Adduint32(ld.Ctxt, glink, 0x3800ffd0) // li r0,-(res_0-1b)=-48
ld.Adduint32(ld.Ctxt, glink, 0x7c006214) // add r0,r0,r12
ld.Adduint32(ld.Ctxt, glink, 0x7c0b0050) // sub r0,r0,r11
ld.Adduint32(ld.Ctxt, glink, 0x7800f082) // srdi r0,r0,2
// r11 = address of the first byte of the PLT
r := ld.Addrel(glink)
r.Off = int32(glink.Size)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0)
r.Siz = 8
r.Type = ld.R_ADDRPOWER
// addis r11,0,[email protected]; addi r11,r11,[email protected]
r.Add = 0x3d600000<<32 | 0x396b0000
glink.Size += 8
// Load r12 = dynamic resolver address and r11 = DSO
// identifier from the first two doublewords of the PLT.
ld.Adduint32(ld.Ctxt, glink, 0xe98b0000) // ld r12,0(r11)
ld.Adduint32(ld.Ctxt, glink, 0xe96b0008) // ld r11,8(r11)
// Jump to the dynamic resolver
ld.Adduint32(ld.Ctxt, glink, 0x7d8903a6) // mtctr r12
ld.Adduint32(ld.Ctxt, glink, 0x4e800420) // bctr
// The symbol resolvers must immediately follow.
// res_0:
// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
// before the first symbol resolver stub.
s := ld.Linklookup(ld.Ctxt, ".dynamic", 0)
ld.Elfwritedynentsymplus(s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
return glink
}
作者:tidatid
项目:g
func elfsetupplt() {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0)
if plt.Size == 0 {
// pushq got+8(IP)
ld.Adduint8(ld.Ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x35)
ld.Addpcrelplus(ld.Ctxt, plt, got, 8)
// jmpq got+16(IP)
ld.Adduint8(ld.Ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x25)
ld.Addpcrelplus(ld.Ctxt, plt, got, 16)
// nopl 0(AX)
ld.Adduint32(ld.Ctxt, plt, 0x00401f0f)
// assume got->size == 0 too
ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0)
ld.Adduint64(ld.Ctxt, got, 0)
ld.Adduint64(ld.Ctxt, got, 0)
}
}
作者:tidatid
项目:g
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
if s.Dynid >= 0 {
return
}
if ld.Iself {
s.Dynid = int32(ld.Nelfsym)
ld.Nelfsym++
d := ld.Linklookup(ctxt, ".dynsym", 0)
name := s.Extname
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
/* type */
t := ld.STB_GLOBAL << 4
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
t |= ld.STT_FUNC
} else {
t |= ld.STT_OBJECT
}
ld.Adduint8(ctxt, d, uint8(t))
/* reserved */
ld.Adduint8(ctxt, d, 0)
/* section where symbol is defined */
if s.Type == ld.SDYNIMPORT {
ld.Adduint16(ctxt, d, ld.SHN_UNDEF)
} else {
ld.Adduint16(ctxt, d, 1)
}
/* value */
if s.Type == ld.SDYNIMPORT {
ld.Adduint64(ctxt, d, 0)
} else {
ld.Addaddr(ctxt, d, s)
}
/* size of object */
ld.Adduint64(ctxt, d, uint64(s.Size))
if s.Cgoexport&ld.CgoExportDynamic == 0 && s.Dynimplib != "" && needlib(s.Dynimplib) != 0 {
ld.Elfwritedynent(ld.Linklookup(ctxt, ".dynamic", 0), ld.DT_NEEDED, uint64(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
}
} else if ld.HEADTYPE == ld.Hdarwin {
ld.Diag("adddynsym: missed symbol %s (%s)", s.Name, s.Extname)
} else if ld.HEADTYPE == ld.Hwindows {
} else // already taken care of
{
ld.Diag("adddynsym: unsupported binary format")
}
}
作者:xslonepiec
项目:goio
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
if s.Dynid >= 0 {
return
}
if ld.Iself {
s.Dynid = int32(ld.Nelfsym)
ld.Nelfsym++
d := ld.Linklookup(ctxt, ".dynsym", 0)
/* name */
name := s.Extname
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
/* value */
if s.Type == ld.SDYNIMPORT {
ld.Adduint32(ctxt, d, 0)
} else {
ld.Addaddr(ctxt, d, s)
}
/* size */
ld.Adduint32(ctxt, d, 0)
/* type */
t := ld.STB_GLOBAL << 4
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
t |= ld.STT_FUNC
} else {
t |= ld.STT_OBJECT
}
ld.Adduint8(ctxt, d, uint8(t))
ld.Adduint8(ctxt, d, 0)
/* shndx */
if s.Type == ld.SDYNIMPORT {
ld.Adduint16(ctxt, d, ld.SHN_UNDEF)
} else {
ld.Adduint16(ctxt, d, 1)
}
} else if ld.HEADTYPE == ld.Hdarwin {
ld.Diag("adddynsym: missed symbol %s (%s)", s.Name, s.Extname)
} else if ld.HEADTYPE == ld.Hwindows {
} else // already taken care of
{
ld.Diag("adddynsym: unsupported binary format")
}
}
作者:kluesk
项目:go-akaro
func adddynlib(lib string) {
if needlib(lib) == 0 {
return
}
if ld.Iself {
s := ld.Linklookup(ld.Ctxt, ".dynstr", 0)
if s.Size == 0 {
ld.Addstring(s, "")
}
ld.Elfwritedynent(ld.Linklookup(ld.Ctxt, ".dynamic", 0), ld.DT_NEEDED, uint64(ld.Addstring(s, lib)))
} else {
ld.Diag("adddynlib: unsupported binary format")
}
}
作者:kluesk
项目:go-akaro
func adddynsym(ctxt *ld.Link, s *ld.LSym) {
if s.Dynid >= 0 {
return
}
if ld.Iself {
s.Dynid = int32(ld.Nelfsym)
ld.Nelfsym++
d := ld.Linklookup(ctxt, ".dynsym", 0)
name := s.Extname
ld.Adduint32(ctxt, d, uint32(ld.Addstring(ld.Linklookup(ctxt, ".dynstr", 0), name)))
/* type */
t := ld.STB_GLOBAL << 4
if s.Cgoexport != 0 && s.Type&ld.SMASK == ld.STEXT {
t |= ld.STT_FUNC
} else {
t |= ld.STT_OBJECT
}
ld.Adduint8(ctxt, d, uint8(t))
/* reserved */
ld.Adduint8(ctxt, d, 0)
/* section where symbol is defined */
if s.Type == ld.SDYNIMPORT {
ld.Adduint16(ctxt, d, ld.SHN_UNDEF)
} else {
ld.Adduint16(ctxt, d, 1)
}
/* value */
if s.Type == ld.SDYNIMPORT {
ld.Adduint64(ctxt, d, 0)
} else {
ld.Addaddr(ctxt, d, s)
}
/* size of object */
ld.Adduint64(ctxt, d, uint64(s.Size))
} else {
ld.Diag("adddynsym: unsupported binary format")
}
}
作者:xslonepiec
项目:goio
func addgotsym(ctxt *ld.Link, s *ld.LSym) {
if s.Got >= 0 {
return
}
adddynsym(ctxt, s)
got := ld.Linklookup(ctxt, ".got", 0)
s.Got = int32(got.Size)
ld.Adduint32(ctxt, got, 0)
if ld.Iself {
rel := ld.Linklookup(ctxt, ".rel", 0)
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
} else {
ld.Diag("addgotsym: unsupported binary format")
}
}
作者:kluesk
项目:go-akaro
func addpltsym(ctxt *ld.Link, s *ld.LSym) {
if s.Plt >= 0 {
return
}
adddynsym(ctxt, s)
if ld.Iself {
plt := ld.Linklookup(ctxt, ".plt", 0)
rela := ld.Linklookup(ctxt, ".rela.plt", 0)
if plt.Size == 0 {
elfsetupplt()
}
// Create the glink resolver if necessary
glink := ensureglinkresolver()
// Write symbol resolver stub (just a branch to the
// glink resolver stub)
r := ld.Addrel(glink)
r.Sym = glink
r.Off = int32(glink.Size)
r.Siz = 4
r.Type = ld.R_CALLPOWER
ld.Adduint32(ctxt, glink, 0x48000000) // b .glink
// In the ppc64 ABI, the dynamic linker is responsible
// for writing the entire PLT. We just need to
// reserve 8 bytes for each PLT entry and generate a
// JMP_SLOT dynamic relocation for it.
//
// TODO(austin): ABI v1 is different
s.Plt = int32(plt.Size)
plt.Size += 8
ld.Addaddrplus(ctxt, rela, plt, int64(s.Plt))
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
ld.Adduint64(ctxt, rela, 0)
} else {
ld.Diag("addpltsym: unsupported binary format")
}
}
作者:xslonepiec
项目:goio
func gentext() {
if !ld.DynlinkingGo() {
return
}
addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == ld.STEXT {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
addmoduledata.Reachable = true
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0)
initfunc.Type = ld.STEXT
initfunc.Local = true
initfunc.Reachable = true
o := func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ld.Ctxt, initfunc, op1)
}
}
// 0000000000000000 <local.dso_init>:
// 0: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 7 <local.dso_init+0x7>
// 3: R_X86_64_PC32 runtime.firstmoduledata-0x4
o(0x48, 0x8d, 0x3d)
ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Linklookup(ld.Ctxt, "runtime.firstmoduledata", 0), 0)
// 7: e8 00 00 00 00 callq c <local.dso_init+0xc>
// 8: R_X86_64_PLT32 runtime.addmoduledata-0x4
o(0xe8)
Addcall(ld.Ctxt, initfunc, addmoduledata)
// c: c3 retq
o(0xc3)
if ld.Ctxt.Etextp != nil {
ld.Ctxt.Etextp.Next = initfunc
} else {
ld.Ctxt.Textp = initfunc
}
ld.Ctxt.Etextp = initfunc
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Reachable = true
initarray_entry.Local = true
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc)
}
作者:kluesk
项目:go-akaro
func elfsetupplt() {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
if plt.Size == 0 {
// The dynamic linker stores the address of the
// dynamic resolver and the DSO identifier in the two
// doublewords at the beginning of the .plt section
// before the PLT array. Reserve space for these.
plt.Size = 16
}
}
作者:tidatid
项目:g
func addgotsym(s *ld.LSym) {
if s.Got >= 0 {
return
}
adddynsym(ld.Ctxt, s)
got := ld.Linklookup(ld.Ctxt, ".got", 0)
s.Got = int32(got.Size)
ld.Adduint64(ld.Ctxt, got, 0)
if ld.Iself {
rela := ld.Linklookup(ld.Ctxt, ".rela", 0)
ld.Addaddrplus(ld.Ctxt, rela, got, int64(s.Got))
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
ld.Adduint64(ld.Ctxt, rela, 0)
} else if ld.HEADTYPE == ld.Hdarwin {
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.got", 0), uint32(s.Dynid))
} else {
ld.Diag("addgotsym: unsupported binary format")
}
}
作者:xslonepiec
项目:goio
func addpltsym(ctxt *ld.Link, s *ld.LSym) {
if s.Plt >= 0 {
return
}
adddynsym(ctxt, s)
if ld.Iself {
plt := ld.Linklookup(ctxt, ".plt", 0)
got := ld.Linklookup(ctxt, ".got.plt", 0)
rel := ld.Linklookup(ctxt, ".rel.plt", 0)
if plt.Size == 0 {
elfsetupplt()
}
// jmpq *got+size
ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, got, got.Size)
// add to got: pointer to current pos in plt
ld.Addaddrplus(ctxt, got, plt, plt.Size)
// pushl $x
ld.Adduint8(ctxt, plt, 0x68)
ld.Adduint32(ctxt, plt, uint32(rel.Size))
// jmp .plt
ld.Adduint8(ctxt, plt, 0xe9)
ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4)))
// rel
ld.Addaddrplus(ctxt, rel, got, got.Size-4)
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT))
s.Plt = int32(plt.Size - 16)
} else if ld.HEADTYPE == ld.Hdarwin {
// Same laziness as in 6l.
plt := ld.Linklookup(ctxt, ".plt", 0)
addgotsym(ctxt, s)
ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.plt", 0), uint32(s.Dynid))
// jmpq *got+size(IP)
s.Plt = int32(plt.Size)
ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, ld.Linklookup(ctxt, ".got", 0), int64(s.Got))
} else {
ld.Diag("addpltsym: unsupported binary format")
}
}
作者:xslonepiec
项目:goio
func addgotsyminternal(ctxt *ld.Link, s *ld.LSym) {
if s.Got >= 0 {
return
}
got := ld.Linklookup(ctxt, ".got", 0)
s.Got = int32(got.Size)
ld.Addaddrplus(ctxt, got, s, 0)
if ld.Iself {
} else {
ld.Diag("addgotsyminternal: unsupported binary format")
}
}
作者:xslonepiec
项目:goio
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
if ld.Linkmode == ld.LinkExternal {
return -1
}
switch r.Type {
case ld.R_CONST:
*val = r.Add
return 0
case ld.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
}
return -1
}
作者:xslonepiec
项目:goio
func needlib(name string) int {
if name[0] == '\x00' {
return 0
}
/* reuse hash code in symbol table */
p := fmt.Sprintf(".dynlib.%s", name)
s := ld.Linklookup(ld.Ctxt, p, 0)
if s.Type == 0 {
s.Type = 100 // avoid SDATA, etc.
return 1
}
return 0
}
作者:kluesk
项目:go-akaro
// Construct a call stub in stub that calls symbol targ via its PLT
// entry.
func gencallstub(abicase int, stub *ld.LSym, targ *ld.LSym) {
if abicase != 1 {
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
// relocations, we'll need to implement cases 2 and 3.
log.Fatalf("gencallstub only implements case 1 calls")
}
plt := ld.Linklookup(ld.Ctxt, ".plt", 0)
stub.Type = ld.STEXT
// Save TOC pointer in TOC save slot
ld.Adduint32(ld.Ctxt, stub, 0xf8410018) // std r2,24(r1)
// Load the function pointer from the PLT.
r := ld.Addrel(stub)
r.Off = int32(stub.Size)
r.Sym = plt
r.Add = int64(targ.Plt)
r.Siz = 2
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
r.Off += int32(r.Siz)
}
r.Type = ld.R_POWER_TOC
r.Variant = ld.RV_POWER_HA
ld.Adduint32(ld.Ctxt, stub, 0x3d820000) // addis r12,r2,[email protected]@[email protected]
r = ld.Addrel(stub)
r.Off = int32(stub.Size)
r.Sym = plt
r.Add = int64(targ.Plt)
r.Siz = 2
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
r.Off += int32(r.Siz)
}
r.Type = ld.R_POWER_TOC
r.Variant = ld.RV_POWER_LO
ld.Adduint32(ld.Ctxt, stub, 0xe98c0000) // ld r12,[email protected]@[email protected](r12)
// Jump to the loaded pointer
ld.Adduint32(ld.Ctxt, stub, 0x7d8903a6) // mtctr r12
ld.Adduint32(ld.Ctxt, stub, 0x4e800420) // bctr
}
作者:kluesk
项目:go-akaro
func archreloc(r *ld.Reloc, s *ld.LSym, val *int64) int {
if ld.Linkmode == ld.LinkExternal {
// TODO(minux): translate R_CALLARM64 into standard ELF relocation.
return -1
}
switch r.Type {
case ld.R_CONST:
*val = r.Add
return 0
case ld.R_GOTOFF:
*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
case ld.R_CALLARM64:
*val = int64((0xfc000000 & uint32(r.Add)) | uint32((ld.Symaddr(r.Sym)+r.Add*4-(s.Value+int64(r.Off)))/4))
return 0
}
return -1
}
作者:xslonepiec
项目:goio
//.........这里部分代码省略.........
// TODO: rationalize
if ld.Debug['v'] != 0 {
fmt.Fprintf(&ld.Bso, "%5.2f sym\n", obj.Cputime())
}
ld.Bflush(&ld.Bso)
switch ld.HEADTYPE {
default:
if ld.Iself {
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
symo = uint32(ld.Rnd(int64(symo), int64(ld.INITRND)))
}
case ld.Hplan9:
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
case ld.Hdarwin:
symo = uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Filelen), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)) + int64(machlink))
}
ld.Cseek(int64(symo))
switch ld.HEADTYPE {
default:
if ld.Iself {
if ld.Debug['v'] != 0 {
fmt.Fprintf(&ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
ld.Asmelfsym()
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
if ld.Debug['v'] != 0 {
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
}
ld.Dwarfemitdebugsections()
if ld.Linkmode == ld.LinkExternal {
ld.Elfemitreloc()
}
}
case ld.Hplan9:
ld.Asmplan9sym()
ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
if sym != nil {
ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ {
ld.Cput(uint8(sym.P[i]))
}
ld.Cflush()
}
case ld.Hdarwin:
if ld.Linkmode == ld.LinkExternal {
ld.Machoemitreloc()
}
}
}
ld.Ctxt.Cursym = nil
if ld.Debug['v'] != 0 {
fmt.Fprintf(&ld.Bso, "%5.2f header\n", obj.Cputime())
}
ld.Bflush(&ld.Bso)
ld.Cseek(0)
switch ld.HEADTYPE {
default:
case ld.Hplan9: /* plan 9 */
ld.Thearch.Lput(0x647) /* magic */
ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
ld.Thearch.Lput(uint32(ld.Symsize)) /* nsyms */
ld.Thearch.Lput(uint32(ld.Entryvalue())) /* va of entry */
ld.Thearch.Lput(0)
ld.Thearch.Lput(uint32(ld.Lcsize))
case ld.Hlinux,
ld.Hfreebsd,
ld.Hnetbsd,
ld.Hopenbsd,
ld.Hnacl:
ld.Asmbelf(int64(symo))
case ld.Hdarwin:
ld.Asmbmacho()
}
ld.Cflush()
if ld.Debug['c'] != 0 {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
fmt.Printf("symsize=%d\n", ld.Symsize)
fmt.Printf("lcsize=%d\n", ld.Lcsize)
fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
}
}
作者:xslonepiec
项目:goio
func adddynrel(s *ld.LSym, r *ld.Reloc) {
targ := r.Sym
ld.Ctxt.Cursym = s
switch r.Type {
default:
if r.Type >= 256 {
ld.Diag("unexpected relocation type %d", r.Type)
return
}
// Handle relocations found in ELF object files.
case 256 + ld.R_ARM_PLT32:
r.Type = ld.R_CALLARM
if targ.Type == ld.SDYNIMPORT {
addpltsym(ld.Ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
}
return
case 256 + ld.R_ARM_THM_PC22: // R_ARM_THM_CALL
ld.Diag("R_ARM_THM_CALL, are you using -marm?")
ld.Errorexit()
return
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL
if targ.Type != ld.SDYNIMPORT {
addgotsyminternal(ld.Ctxt, targ)
} else {
addgotsym(ld.Ctxt, targ)
}
r.Type = ld.R_CONST // write r->add during relocsym
r.Sym = nil
r.Add += int64(targ.Got)
return
case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil
if targ.Type != ld.SDYNIMPORT {
addgotsyminternal(ld.Ctxt, targ)
} else {
addgotsym(ld.Ctxt, targ)
}
r.Type = ld.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0)
r.Add += int64(targ.Got) + 4
return
case 256 + ld.R_ARM_GOTOFF: // R_ARM_GOTOFF32
r.Type = ld.R_GOTOFF
return
case 256 + ld.R_ARM_GOTPC: // R_ARM_BASE_PREL
r.Type = ld.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0)
r.Add += 4
return
case 256 + ld.R_ARM_CALL:
r.Type = ld.R_CALLARM
if targ.Type == ld.SDYNIMPORT {
addpltsym(ld.Ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
}
return
case 256 + ld.R_ARM_REL32: // R_ARM_REL32
r.Type = ld.R_PCREL
r.Add += 4
return
case 256 + ld.R_ARM_ABS32:
if targ.Type == ld.SDYNIMPORT {
ld.Diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
}
r.Type = ld.R_ADDR
return
// we can just ignore this, because we are targeting ARM V5+ anyway
case 256 + ld.R_ARM_V4BX:
if r.Sym != nil {
// R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
r.Sym.Type = 0
}
r.Sym = nil
return
case 256 + ld.R_ARM_PC24,
256 + ld.R_ARM_JUMP24:
//.........这里部分代码省略.........