Ctxt is a global defined in cmd/link/internal/ld of type *ld.Link.
Start threading a *ld.Link through function calls instead of
relying on the global variable.
Ctxt is still used as a global by the architecture-specific packages,
but I plan to fix that in a subsequent CL.
Change-Id: I77a3a58bd396fafd959fa1d8b1c83008a9f5a7fb
Reviewed-on: https://go-review.googlesource.com/27408
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
switch r.Type {
default:
if r.Type >= 256 {
- ld.Diag("unexpected relocation type %d", r.Type)
+ ld.Ctxt.Diag("unexpected relocation type %d", r.Type)
return
}
// Handle relocations found in ELF object files.
case 256 + ld.R_X86_64_PC32:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
}
if targ.Type == 0 || targ.Type == obj.SXREF {
- ld.Diag("unknown symbol %s in pcrel", targ.Name)
+ ld.Ctxt.Diag("unknown symbol %s in pcrel", targ.Name)
}
r.Type = obj.R_PCREL
r.Add += 4
case 256 + ld.R_X86_64_64:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
}
r.Type = obj.R_ADDR
return
r.Type = obj.R_ADDR
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected reloc for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected reloc for dynamic symbol %s", targ.Name)
}
return
r.Type = obj.R_PCREL
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
}
return
// have symbol
// turn MOVQ of GOT entry into LEAQ of symbol itself
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
- ld.Diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ.Name)
return
}
// fall through
case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
if targ.Type != obj.SDYNIMPORT {
- ld.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
}
addgotsym(targ)
r.Type = obj.R_PCREL
}
ld.Ctxt.Cursym = s
- ld.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
+ ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
}
func elfreloc1(r *ld.Reloc, sectoff int64) int {
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_PCREL {
if rs.Dynid < 0 {
- ld.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1
}
}
rs := r.Xsym
if rs.Dynid < 0 {
- ld.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
return false
}
ld.Adduint8(ld.Ctxt, plt, 0x25)
ld.Addpcrelplus(ld.Ctxt, plt, ld.Linklookup(ld.Ctxt, ".got", 0), int64(s.Got))
} else {
- ld.Diag("addpltsym: unsupported binary format")
+ ld.Ctxt.Diag("addpltsym: unsupported binary format")
}
}
} else if ld.HEADTYPE == obj.Hdarwin {
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.got", 0), uint32(s.Dynid))
} else {
- ld.Diag("addgotsym: unsupported binary format")
+ ld.Ctxt.Diag("addgotsym: unsupported binary format")
}
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// 0xCC is INT $3 - breakpoint instruction
- ld.CodeblkPad(int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
+ ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
machlink := int64(0)
if ld.HEADTYPE == obj.Hdarwin {
- machlink = ld.Domacholink()
+ machlink = ld.Domacholink(ctxt)
}
switch ld.HEADTYPE {
default:
- ld.Diag("unknown header type %d", ld.HEADTYPE)
+ ld.Ctxt.Diag("unknown header type %d", ld.HEADTYPE)
fallthrough
case obj.Hplan9:
default:
if ld.Iself {
ld.Cseek(symo)
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
}
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
case obj.Hplan9:
- ld.Asmplan9sym()
+ ld.Asmplan9sym(ctxt)
ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
case obj.Hdarwin:
if ld.Linkmode == ld.LinkExternal {
- ld.Machoemitreloc()
+ ld.Machoemitreloc(ctxt)
}
}
}
ld.Lputb(uint32(ld.Segdata.Filelen))
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
ld.Lputb(uint32(ld.Symsize)) /* nsyms */
- vl := ld.Entryvalue()
+ vl := ld.Entryvalue(ctxt)
ld.Lputb(PADDR(uint32(vl))) /* va of entry */
ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
ld.Vputb(uint64(vl)) /* va of entry */
case obj.Hdarwin:
- ld.Asmbmacho()
+ ld.Asmbmacho(ctxt)
case obj.Hlinux,
obj.Hfreebsd,
obj.Hdragonfly,
obj.Hsolaris,
obj.Hnacl:
- ld.Asmbelf(symo)
+ ld.Asmbelf(ctxt, symo)
case obj.Hwindows:
- ld.Asmbpe()
+ ld.Asmbpe(ctxt)
}
ld.Cflush()
}
func archinit() {
+ ctxt := ld.Ctxt
+
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
obj.Hopenbsd, /* openbsd */
obj.Hdragonfly, /* dragonfly */
obj.Hsolaris: /* solaris */
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
}
case obj.Hnacl:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.Debug['w']++ // disable dwarf, which gets confused and is useless anyway
ld.HEADR = 0x10000
ld.Funcalign = 32
}
case obj.Hwindows: /* PE executable */
- ld.Peinit()
+ ld.Peinit(ctxt)
ld.HEADR = ld.PEFILEHEADR
if ld.INITTEXT == -1 {
switch r.Type {
default:
if r.Type >= 256 {
- ld.Diag("unexpected relocation type %d", r.Type)
+ ld.Ctxt.Diag("unexpected relocation type %d", r.Type)
return
}
case 256 + ld.R_ARM_ABS32:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
}
r.Type = obj.R_ADDR
return
}
ld.Ctxt.Cursym = s
- ld.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
+ ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
}
func elfreloc1(r *ld.Reloc, sectoff int64) int {
if r.Type == obj.R_PCREL {
if rs.Type == obj.SHOSTOBJ {
- ld.Diag("pc-relative relocation of external symbol is not supported")
+ ld.Ctxt.Diag("pc-relative relocation of external symbol is not supported")
return -1
}
if r.Siz != 4 {
o2 |= 2 << 28 // size = 4
ld.Thearch.Lput(o1)
- ld.Thearch.Lput(uint32(ld.Symaddr(rs)))
+ ld.Thearch.Lput(uint32(ld.Symaddr(ld.Ctxt, rs)))
ld.Thearch.Lput(o2)
ld.Thearch.Lput(uint32(ld.Ctxt.Cursym.Value + int64(r.Off)))
return 0
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM {
if rs.Dynid < 0 {
- ld.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1
}
}
}
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
+ ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
case obj.R_CALLARM:
}
r.Xadd *= 4
for rs.Outer != nil {
- r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
+ r.Xadd += ld.Symaddr(ctxt, rs) - ld.Symaddr(ctxt, rs.Outer)
rs = rs.Outer
}
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
- ld.Diag("missing section for %s", rs.Name)
+ ld.Ctxt.Diag("missing section for %s", rs.Name)
}
r.Xsym = rs
// we need to compensate that by removing the instruction's address
// from addend.
if ld.HEADTYPE == obj.Hdarwin {
- r.Xadd -= ld.Symaddr(s) + int64(r.Off)
+ r.Xadd -= ld.Symaddr(ctxt, s) + int64(r.Off)
}
*val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32(r.Xadd/4))))
return 0
case obj.R_GOTOFF:
- *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
+ *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
// The following three arch specific relocations are only for generation of
// Linux/ARM ELF's PLT entry (3 assembler instruction)
case obj.R_PLT0: // add ip, pc, #0xXX00000
- if ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got.plt", 0)) < ld.Symaddr(ld.Linklookup(ld.Ctxt, ".plt", 0)) {
- ld.Diag(".got.plt should be placed after .plt section.")
+ if ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got.plt", 0)) < ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0)) {
+ ld.Ctxt.Diag(".got.plt should be placed after .plt section.")
}
- *val = 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add)) >> 20))
+ *val = 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add)) >> 20))
return 0
case obj.R_PLT1: // add ip, ip, #0xYY000
- *val = 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add+4)) >> 12))
+ *val = 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add+4)) >> 12))
return 0
case obj.R_PLT2: // ldr pc, [ip, #0xZZZ]!
- *val = 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(r.Sym)-(ld.Symaddr(ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add+8)))
+ *val = 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add+8)))
return 0
case obj.R_CALLARM: // bl XXXXXX or b YYYYYY
- *val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32((ld.Symaddr(r.Sym)+int64((uint32(r.Add))*4)-(s.Value+int64(r.Off)))/4))))
+ *val = int64(braddoff(int32(0xff000000&uint32(r.Add)), int32(0xffffff&uint32((ld.Symaddr(ctxt, r.Sym)+int64((uint32(r.Add))*4)-(s.Value+int64(r.Off)))/4))))
return 0
}
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT))
} else {
- ld.Diag("addpltsym: unsupported binary format")
+ ld.Ctxt.Diag("addpltsym: unsupported binary format")
}
}
if ld.Iself {
} else {
- ld.Diag("addgotsyminternal: unsupported binary format")
+ ld.Ctxt.Diag("addgotsyminternal: unsupported binary format")
}
}
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")
+ ld.Ctxt.Diag("addgotsym: unsupported binary format")
}
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
machlink := uint32(0)
if ld.HEADTYPE == obj.Hdarwin {
- machlink = uint32(ld.Domacholink())
+ machlink = uint32(ld.Domacholink(ctxt))
}
/* output symbol table */
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
case obj.Hplan9:
- ld.Asmplan9sym()
+ ld.Asmplan9sym(ctxt)
ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
case obj.Hdarwin:
if ld.Linkmode == ld.LinkExternal {
- ld.Machoemitreloc()
+ ld.Machoemitreloc(ctxt)
}
}
}
ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
ld.Lputb(uint32(ld.Segdata.Filelen))
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
- ld.Lputb(uint32(ld.Symsize)) /* nsyms */
- ld.Lputb(uint32(ld.Entryvalue())) /* va of entry */
+ ld.Lputb(uint32(ld.Symsize)) /* nsyms */
+ ld.Lputb(uint32(ld.Entryvalue(ctxt))) /* va of entry */
ld.Lputb(0)
ld.Lputb(uint32(ld.Lcsize))
obj.Hnetbsd,
obj.Hopenbsd,
obj.Hnacl:
- ld.Asmbelf(int64(symo))
+ ld.Asmbelf(ctxt, int64(symo))
case obj.Hdarwin:
- ld.Asmbmacho()
+ ld.Asmbmacho(ctxt)
}
ld.Cflush()
obj.Hopenbsd:
ld.Debug['d'] = 0
// with dynamic linking
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR)
}
case obj.Hnacl:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = 0x10000
ld.Funcalign = 16
if ld.INITTEXT == -1 {
// UNSIGNED relocation at all.
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM64 || r.Type == obj.R_ADDRARM64 || r.Type == obj.R_ADDR {
if rs.Dynid < 0 {
- ld.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1
}
}
case obj.R_CALLARM64:
if r.Xadd != 0 {
- ld.Diag("ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd)
+ ld.Ctxt.Diag("ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd)
}
v |= 1 << 24 // pc-relative bit
}
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
+ ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
rs := r.Sym
r.Xadd = r.Add
for rs.Outer != nil {
- r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
+ r.Xadd += ld.Symaddr(ctxt, rs) - ld.Symaddr(ctxt, rs.Outer)
rs = rs.Outer
}
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
- ld.Diag("missing section for %s", rs.Name)
+ ld.Ctxt.Diag("missing section for %s", rs.Name)
}
r.Xsym = rs
return 0
case obj.R_GOTOFF:
- *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
+ *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
case obj.R_ADDRARM64:
- t := ld.Symaddr(r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
+ t := ld.Symaddr(ctxt, r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
if t >= 1<<32 || t < -1<<32 {
- ld.Diag("program too large, address relocation distance = %d", t)
+ ld.Ctxt.Diag("program too large, address relocation distance = %d", t)
}
var o0, o1 uint32
case obj.R_ARM64_TLS_LE:
r.Done = 0
if ld.HEADTYPE != obj.Hlinux {
- ld.Diag("TLS reloc on unsupported OS %s", ld.Headstr(int(ld.HEADTYPE)))
+ ld.Ctxt.Diag("TLS reloc on unsupported OS %s", ld.Headstr(int(ld.HEADTYPE)))
}
// The TCB is two pointers. This is not documented anywhere, but is
// de facto part of the ABI.
v := r.Sym.Value + int64(2*ld.SysArch.PtrSize)
if v < 0 || v >= 32678 {
- ld.Diag("TLS offset out of range %d", v)
+ ld.Ctxt.Diag("TLS offset out of range %d", v)
}
*val |= v << 5
return 0
case obj.R_CALLARM64:
- t := (ld.Symaddr(r.Sym) + r.Add) - (s.Value + int64(r.Off))
+ t := (ld.Symaddr(ctxt, r.Sym) + r.Add) - (s.Value + int64(r.Off))
if t >= 1<<27 || t < -1<<27 {
- ld.Diag("program too large, call relocation distance = %d", t)
+ ld.Ctxt.Diag("program too large, call relocation distance = %d", t)
}
*val |= (t >> 2) & 0x03ffffff
return 0
return -1
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
machlink := uint32(0)
if ld.HEADTYPE == obj.Hdarwin {
- machlink = uint32(ld.Domacholink())
+ machlink = uint32(ld.Domacholink(ctxt))
}
/* output symbol table */
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
case obj.Hplan9:
- ld.Asmplan9sym()
+ ld.Asmplan9sym(ctxt)
ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
case obj.Hdarwin:
if ld.Linkmode == ld.LinkExternal {
- ld.Machoemitreloc()
+ ld.Machoemitreloc(ctxt)
}
}
}
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(uint32(ld.Symsize)) /* nsyms */
+ ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
ld.Thearch.Lput(0)
ld.Thearch.Lput(uint32(ld.Lcsize))
obj.Hnetbsd,
obj.Hopenbsd,
obj.Hnacl:
- ld.Asmbelf(int64(symo))
+ ld.Asmbelf(ctxt, int64(symo))
case obj.Hdarwin:
- ld.Asmbmacho()
+ ld.Asmbmacho(ctxt)
}
ld.Cflush()
}
case obj.Hlinux: /* arm64 elf */
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR)
}
case obj.Hnacl:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = 0x10000
ld.Funcalign = 16
if ld.INITTEXT == -1 {
// file, but it has an armap listing symbols and the objects that
// define them. This is used for the compiler support library
// libgcc.a.
-func hostArchive(name string) {
+func hostArchive(ctxt *Link, name string) {
f, err := bio.Open(name)
if err != nil {
if os.IsNotExist(err) {
any := true
for any {
var load []uint64
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
for _, r := range s.R {
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF {
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
pname := fmt.Sprintf("%s(%s)", name, arhdr.name)
l = atolwhex(arhdr.size)
- h := ldobj(f, "libgcc", l, pname, name, ArchiveObj)
+ h := ldobj(ctxt, f, "libgcc", l, pname, name, ArchiveObj)
f.Seek(h.off, 0)
- h.ld(f, h.pkg, h.length, h.pn)
+ h.ld(ctxt, f, h.pkg, h.length, h.pn)
}
any = len(load) > 0
return l
}
-func relocsym(s *Symbol) {
+func relocsym(ctxt *Link, s *Symbol) {
var r *Reloc
var rs *Symbol
var i16 int16
var fl int32
var o int64
- Ctxt.Cursym = s
+ ctxt.Cursym = s
for ri := int32(0); ri < int32(len(s.R)); ri++ {
r = &s.R[ri]
r.Done = 1
off = r.Off
siz = int32(r.Siz)
if off < 0 || off+siz > int32(len(s.P)) {
- Diag("%s: invalid relocation %d+%d not in [%d,%d)", s.Name, off, siz, 0, len(s.P))
+ ctxt.Diag("%s: invalid relocation %d+%d not in [%d,%d)", s.Name, off, siz, 0, len(s.P))
continue
}
continue
}
} else {
- Diag("%s: not defined", r.Sym.Name)
+ ctxt.Diag("%s: not defined", r.Sym.Name)
continue
}
}
// shared libraries, and Solaris needs it always
if HEADTYPE != obj.Hsolaris && r.Sym != nil && r.Sym.Type == obj.SDYNIMPORT && !DynlinkingGo() {
if !(SysArch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") {
- Diag("unhandled relocation for %s (type %d rtype %d)", r.Sym.Name, r.Sym.Type, r.Type)
+ ctxt.Diag("unhandled relocation for %s (type %d rtype %d)", r.Sym.Name, r.Sym.Type, r.Type)
}
}
if r.Sym != nil && r.Sym.Type != obj.STLSBSS && !r.Sym.Attr.Reachable() {
- Diag("unreachable sym in relocation: %s %s", s.Name, r.Sym.Name)
+ ctxt.Diag("unreachable sym in relocation: %s %s", s.Name, r.Sym.Name)
}
// TODO(mundaym): remove this special case - see issue 14218.
default:
switch siz {
default:
- Diag("bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
+ ctxt.Diag("bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
case 1:
o = int64(s.P[off])
case 2:
- o = int64(Ctxt.Arch.ByteOrder.Uint16(s.P[off:]))
+ o = int64(ctxt.Arch.ByteOrder.Uint16(s.P[off:]))
case 4:
- o = int64(Ctxt.Arch.ByteOrder.Uint32(s.P[off:]))
+ o = int64(ctxt.Arch.ByteOrder.Uint32(s.P[off:]))
case 8:
- o = int64(Ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
+ o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
}
if Thearch.Archreloc(r, s, &o) < 0 {
- Diag("unknown reloc %d", r.Type)
+ ctxt.Diag("unknown reloc %d", r.Type)
}
case obj.R_TLS_LE:
if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 {
r.Done = 0
if r.Sym == nil {
- r.Sym = Ctxt.Tlsg
+ r.Sym = ctxt.Tlsg
}
r.Xsym = r.Sym
r.Xadd = r.Add
// related to the fact that our own TLS storage happens
// to take up 8 bytes.
o = 8 + r.Sym.Value
- } else if Iself || Ctxt.Headtype == obj.Hplan9 || Ctxt.Headtype == obj.Hdarwin || isAndroidX86 {
- o = int64(Ctxt.Tlsoffset) + r.Add
- } else if Ctxt.Headtype == obj.Hwindows {
+ } else if Iself || ctxt.Headtype == obj.Hplan9 || ctxt.Headtype == obj.Hdarwin || isAndroidX86 {
+ o = int64(ctxt.Tlsoffset) + r.Add
+ } else if ctxt.Headtype == obj.Hwindows {
o = r.Add
} else {
- log.Fatalf("unexpected R_TLS_LE relocation for %s", Headstr(Ctxt.Headtype))
+ log.Fatalf("unexpected R_TLS_LE relocation for %s", Headstr(ctxt.Headtype))
}
case obj.R_TLS_IE:
if Linkmode == LinkExternal && Iself && HEADTYPE != obj.Hopenbsd && !isAndroidX86 {
r.Done = 0
if r.Sym == nil {
- r.Sym = Ctxt.Tlsg
+ r.Sym = ctxt.Tlsg
}
r.Xsym = r.Sym
r.Xadd = r.Add
r.Xadd = r.Add
for rs.Outer != nil {
- r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
+ r.Xadd += Symaddr(ctxt, rs) - Symaddr(ctxt, rs.Outer)
rs = rs.Outer
}
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
- Diag("missing section for %s", rs.Name)
+ ctxt.Diag("missing section for %s", rs.Name)
}
r.Xsym = rs
// extern relocation by requiring rs->dynid >= 0.
if rs.Type != obj.SHOSTOBJ {
if SysArch.Family == sys.ARM64 && rs.Dynid < 0 {
- Diag("R_ADDR reloc to %s+%d is not supported on darwin/arm64", rs.Name, o)
+ ctxt.Diag("R_ADDR reloc to %s+%d is not supported on darwin/arm64", rs.Name, o)
}
if SysArch.Family != sys.ARM64 {
- o += Symaddr(rs)
+ o += Symaddr(ctxt, rs)
}
}
} else if HEADTYPE == obj.Hwindows {
// nothing to do
} else {
- Diag("unhandled pcrel relocation for %s", headstring)
+ ctxt.Diag("unhandled pcrel relocation for %s", headstring)
}
break
}
- o = Symaddr(r.Sym) + r.Add
+ o = Symaddr(ctxt, r.Sym) + r.Add
// On amd64, 4-byte offsets will be sign-extended, so it is impossible to
// access more than 2GB of static data; fail at link time is better than
// Instead of special casing only amd64, we treat this as an error on all
// 64-bit architectures so as to be future-proof.
if int32(o) < 0 && SysArch.PtrSize > 4 && siz == 4 {
- Diag("non-pc-relative relocation address is too big: %#x (%#x + %#x)", uint64(o), Symaddr(r.Sym), r.Add)
+ ctxt.Diag("non-pc-relative relocation address is too big: %#x (%#x + %#x)", uint64(o), Symaddr(ctxt, r.Sym), r.Add)
errorexit()
}
case obj.R_DWARFREF:
if r.Sym.Sect == nil {
- Diag("missing DWARF section: %s from %s", r.Sym.Name, s.Name)
+ ctxt.Diag("missing DWARF section: %s from %s", r.Sym.Name, s.Name)
}
if Linkmode == LinkExternal {
r.Done = 0
r.Type = obj.R_ADDR
- r.Xsym = Linkrlookup(Ctxt, r.Sym.Sect.Name, 0)
- r.Xadd = r.Add + Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr)
+ r.Xsym = Linkrlookup(ctxt, r.Sym.Sect.Name, 0)
+ r.Xadd = r.Add + Symaddr(ctxt, r.Sym) - int64(r.Sym.Sect.Vaddr)
o = r.Xadd
rs = r.Xsym
if Iself && SysArch.Family == sys.AMD64 {
}
break
}
- o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
+ o = Symaddr(ctxt, r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
case obj.R_ADDROFF:
- o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
+ o = Symaddr(ctxt, r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
case obj.R_CALL, obj.R_GOTPCREL, obj.R_PCREL:
- if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != obj.SCONST && (r.Sym.Sect != Ctxt.Cursym.Sect || r.Type == obj.R_GOTPCREL) {
+ if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != obj.SCONST && (r.Sym.Sect != ctxt.Cursym.Sect || r.Type == obj.R_GOTPCREL) {
r.Done = 0
// set up addend for eventual relocation via outer symbol.
r.Xadd = r.Add
for rs.Outer != nil {
- r.Xadd += Symaddr(rs) - Symaddr(rs.Outer)
+ r.Xadd += Symaddr(ctxt, rs) - Symaddr(ctxt, rs.Outer)
rs = rs.Outer
}
r.Xadd -= int64(r.Siz) // relative to address after the relocated chunk
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
- Diag("missing section for %s", rs.Name)
+ ctxt.Diag("missing section for %s", rs.Name)
}
r.Xsym = rs
} else if HEADTYPE == obj.Hdarwin {
if r.Type == obj.R_CALL {
if rs.Type != obj.SHOSTOBJ {
- o += int64(uint64(Symaddr(rs)) - rs.Sect.Vaddr)
+ o += int64(uint64(Symaddr(ctxt, rs)) - rs.Sect.Vaddr)
}
o -= int64(r.Off) // relative to section offset, not symbol
} else if SysArch.Family == sys.ARM {
// see ../arm/asm.go:/machoreloc1
- o += Symaddr(rs) - int64(Ctxt.Cursym.Value) - int64(r.Off)
+ o += Symaddr(ctxt, rs) - int64(ctxt.Cursym.Value) - int64(r.Off)
} else {
o += int64(r.Siz)
}
// relocated address, compensate that.
o -= int64(s.Sect.Vaddr - PEBASE)
} else {
- Diag("unhandled pcrel relocation for %s", headstring)
+ ctxt.Diag("unhandled pcrel relocation for %s", headstring)
}
break
o = 0
if r.Sym != nil {
- o += Symaddr(r.Sym)
+ o += Symaddr(ctxt, r.Sym)
}
// NOTE: The (int32) cast on the next line works around a bug in Plan 9's 8c
if r.Sym != nil {
nam = r.Sym.Name
}
- fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(r.Sym), r.Add, r.Type, r.Variant, o)
+ fmt.Printf("relocate %s %#x (%#x+%#x, size %d) => %s %#x +%#x [type %d/%d, %x]\n", s.Name, s.Value+int64(off), s.Value, r.Off, r.Siz, nam, Symaddr(ctxt, r.Sym), r.Add, r.Type, r.Variant, o)
}
switch siz {
default:
- Ctxt.Cursym = s
- Diag("bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
+ ctxt.Cursym = s
+ ctxt.Diag("bad reloc size %#x for %s", uint32(siz), r.Sym.Name)
fallthrough
// TODO(rsc): Remove.
case 2:
if o != int64(int16(o)) {
- Diag("relocation address is too big: %#x", o)
+ ctxt.Diag("relocation address is too big: %#x", o)
}
i16 = int16(o)
- Ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16))
+ ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i16))
case 4:
if r.Type == obj.R_PCREL || r.Type == obj.R_CALL {
if o != int64(int32(o)) {
- Diag("pc-relative relocation address is too big: %#x", o)
+ ctxt.Diag("pc-relative relocation address is too big: %#x", o)
}
} else {
if o != int64(int32(o)) && o != int64(uint32(o)) {
- Diag("non-pc-relative relocation address is too big: %#x", uint64(o))
+ ctxt.Diag("non-pc-relative relocation address is too big: %#x", uint64(o))
}
}
fl = int32(o)
- Ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
+ ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(fl))
case 8:
- Ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
+ ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(o))
}
}
}
-func reloc() {
+func (ctxt *Link) reloc() {
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "%5.2f reloc\n", obj.Cputime())
}
Bso.Flush()
- for _, s := range Ctxt.Textp {
- relocsym(s)
+ for _, s := range ctxt.Textp {
+ relocsym(ctxt, s)
}
for _, sym := range datap {
- relocsym(sym)
+ relocsym(ctxt, sym)
}
for s := dwarfp; s != nil; s = s.Next {
- relocsym(s)
+ relocsym(ctxt, s)
}
}
-func dynrelocsym(s *Symbol) {
+func dynrelocsym(ctxt *Link, s *Symbol) {
if HEADTYPE == obj.Hwindows && Linkmode != LinkExternal {
- rel := Linklookup(Ctxt, ".rel", 0)
+ rel := Linklookup(ctxt, ".rel", 0)
if s == rel {
return
}
continue
}
if !targ.Attr.Reachable() {
- Diag("internal inconsistency: dynamic symbol %s is not reachable.", targ.Name)
+ ctxt.Diag("internal inconsistency: dynamic symbol %s is not reachable.", targ.Name)
}
if r.Sym.Plt == -2 && r.Sym.Got != -2 { // make dynimport JMP table for PE object files.
targ.Plt = int32(rel.Size)
// jmp *addr
if SysArch.Family == sys.I386 {
- Adduint8(Ctxt, rel, 0xff)
- Adduint8(Ctxt, rel, 0x25)
- Addaddr(Ctxt, rel, targ)
- Adduint8(Ctxt, rel, 0x90)
- Adduint8(Ctxt, rel, 0x90)
+ Adduint8(ctxt, rel, 0xff)
+ Adduint8(ctxt, rel, 0x25)
+ Addaddr(ctxt, rel, targ)
+ Adduint8(ctxt, rel, 0x90)
+ Adduint8(ctxt, rel, 0x90)
} else {
- Adduint8(Ctxt, rel, 0xff)
- Adduint8(Ctxt, rel, 0x24)
- Adduint8(Ctxt, rel, 0x25)
- addaddrplus4(Ctxt, rel, targ, 0)
- Adduint8(Ctxt, rel, 0x90)
+ Adduint8(ctxt, rel, 0xff)
+ Adduint8(ctxt, rel, 0x24)
+ Adduint8(ctxt, rel, 0x25)
+ addaddrplus4(ctxt, rel, targ, 0)
+ Adduint8(ctxt, rel, 0x90)
}
} else if r.Sym.Plt >= 0 {
r.Sym = rel
r := &s.R[ri]
if r.Sym != nil && r.Sym.Type == obj.SDYNIMPORT || r.Type >= 256 {
if r.Sym != nil && !r.Sym.Attr.Reachable() {
- Diag("internal inconsistency: dynamic symbol %s is not reachable.", r.Sym.Name)
+ ctxt.Diag("internal inconsistency: dynamic symbol %s is not reachable.", r.Sym.Name)
}
Thearch.Adddynrel(s, r)
}
}
}
-func dynreloc(data *[obj.SXREF][]*Symbol) {
+func dynreloc(ctxt *Link, data *[obj.SXREF][]*Symbol) {
// -d suppresses dynamic loader format, so we may as well not
// compute these sections or mark their symbols as reachable.
if Debug['d'] != 0 && HEADTYPE != obj.Hwindows {
}
Bso.Flush()
- for _, s := range Ctxt.Textp {
- dynrelocsym(s)
+ for _, s := range ctxt.Textp {
+ dynrelocsym(ctxt, s)
}
for _, syms := range data {
for _, sym := range syms {
- dynrelocsym(sym)
+ dynrelocsym(ctxt, sym)
}
}
if Iself {
- elfdynhash()
+ elfdynhash(ctxt)
}
}
-func blk(start *Symbol, addr int64, size int64) {
+func blk(ctxt *Link, start *Symbol, addr int64, size int64) {
var sym *Symbol
for sym = start; sym != nil; sym = sym.Next {
if sym.Value >= eaddr {
break
}
- Ctxt.Cursym = sym
+ ctxt.Cursym = sym
if sym.Value < addr {
- Diag("phase error: addr=%#x but sym=%#x type=%d", addr, sym.Value, sym.Type)
+ ctxt.Diag("phase error: addr=%#x but sym=%#x type=%d", addr, sym.Value, sym.Type)
errorexit()
}
addr = sym.Value + sym.Size
}
if addr != sym.Value+sym.Size {
- Diag("phase error: addr=%#x value+size=%#x", addr, sym.Value+sym.Size)
+ ctxt.Diag("phase error: addr=%#x value+size=%#x", addr, sym.Value+sym.Size)
errorexit()
}
Cflush()
}
-func Codeblk(addr int64, size int64) {
- CodeblkPad(addr, size, zeros[:])
+func Codeblk(ctxt *Link, addr int64, size int64) {
+ CodeblkPad(ctxt, addr, size, zeros[:])
}
-func CodeblkPad(addr int64, size int64, pad []byte) {
+func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) {
if Debug['a'] != 0 {
fmt.Fprintf(Bso, "codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
}
- blkSlice(Ctxt.Textp, addr, size, pad)
+ blkSlice(ctxt, ctxt.Textp, addr, size, pad)
/* again for printing */
if Debug['a'] == 0 {
return
}
- syms := Ctxt.Textp
+ syms := ctxt.Textp
for i, sym := range syms {
if !sym.Attr.Reachable() {
continue
// blkSlice is a variant of blk that processes slices.
// After text symbols are converted from a linked list to a slice,
// delete blk and give this function its name.
-func blkSlice(syms []*Symbol, addr, size int64, pad []byte) {
+func blkSlice(ctxt *Link, syms []*Symbol, addr, size int64, pad []byte) {
for i, s := range syms {
if s.Type&obj.SSUB == 0 && s.Value >= addr {
syms = syms[i:]
if s.Value >= eaddr {
break
}
- Ctxt.Cursym = s
+ ctxt.Cursym = s
if s.Value < addr {
- Diag("phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type)
+ ctxt.Diag("phase error: addr=%#x but sym=%#x type=%d", addr, s.Value, s.Type)
errorexit()
}
if addr < s.Value {
addr = s.Value + s.Size
}
if addr != s.Value+s.Size {
- Diag("phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size)
+ ctxt.Diag("phase error: addr=%#x value+size=%#x", addr, s.Value+s.Size)
errorexit()
}
if s.Value+s.Size >= eaddr {
Cflush()
}
-func Datblk(addr int64, size int64) {
+func Datblk(ctxt *Link, addr int64, size int64) {
if Debug['a'] != 0 {
fmt.Fprintf(Bso, "datblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
}
- blkSlice(datap, addr, size, zeros[:])
+ blkSlice(ctxt, datap, addr, size, zeros[:])
/* again for printing */
if Debug['a'] == 0 {
fmt.Fprintf(Bso, "\t%.8x|\n", uint(eaddr))
}
-func Dwarfblk(addr int64, size int64) {
+func Dwarfblk(ctxt *Link, addr int64, size int64) {
if Debug['a'] != 0 {
fmt.Fprintf(Bso, "dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, Cpos())
}
- blk(dwarfp, addr, size)
+ blk(ctxt, dwarfp, addr, size)
}
var zeros [512]byte
var strdata []*Symbol
-func addstrdata1(arg string) {
+func addstrdata1(ctxt *Link, arg string) {
i := strings.Index(arg, "=")
if i < 0 {
Exitf("-X flag requires argument of the form importpath.name=value")
}
- addstrdata(arg[:i], arg[i+1:])
+ addstrdata(ctxt, arg[:i], arg[i+1:])
}
-func addstrdata(name string, value string) {
+func addstrdata(ctxt *Link, name string, value string) {
p := fmt.Sprintf("%s.str", name)
- sp := Linklookup(Ctxt, p, 0)
+ sp := Linklookup(ctxt, p, 0)
- Addstring(sp, value)
+ Addstring(ctxt, sp, value)
sp.Type = obj.SRODATA
- s := Linklookup(Ctxt, name, 0)
+ s := Linklookup(ctxt, name, 0)
s.Size = 0
s.Attr |= AttrDuplicateOK
reachable := s.Attr.Reachable()
- Addaddr(Ctxt, s, sp)
- adduintxx(Ctxt, s, uint64(len(value)), SysArch.PtrSize)
+ Addaddr(ctxt, s, sp)
+ adduintxx(ctxt, s, uint64(len(value)), SysArch.PtrSize)
// addstring, addaddr, etc., mark the symbols as reachable.
// In this case that is not necessarily true, so stick to what
sp.Attr.Set(AttrReachable, reachable)
}
-func checkstrdata() {
+func (ctxt *Link) checkstrdata() {
for _, s := range strdata {
if s.Type == obj.STEXT {
- Diag("cannot use -X with text symbol %s", s.Name)
+ ctxt.Diag("cannot use -X with text symbol %s", s.Name)
} else if s.Gotype != nil && s.Gotype.Name != "type.string" {
- Diag("cannot use -X with non-string symbol %s", s.Name)
+ ctxt.Diag("cannot use -X with non-string symbol %s", s.Name)
}
}
}
-func Addstring(s *Symbol, str string) int64 {
+func Addstring(ctxt *Link, s *Symbol, str string) int64 {
if s.Type == 0 {
s.Type = obj.SNOPTRDATA
}
s.Attr |= AttrReachable
r := s.Size
if s.Name == ".shstrtab" {
- elfsetstring(str, int(r))
+ elfsetstring(ctxt, str, int(r))
}
s.P = append(s.P, str...)
s.P = append(s.P, 0)
// addgostring adds str, as a Go string value, to s. symname is the name of the
// symbol used to define the string data and must be unique per linked object.
-func addgostring(s *Symbol, symname, str string) {
- sym := Linklookup(Ctxt, symname, 0)
+func addgostring(ctxt *Link, s *Symbol, symname, str string) {
+ sym := Linklookup(ctxt, symname, 0)
if sym.Type != obj.Sxxx {
- Diag("duplicate symname in addgostring: %s", symname)
+ ctxt.Diag("duplicate symname in addgostring: %s", symname)
}
sym.Attr |= AttrReachable
sym.Attr |= AttrLocal
sym.Type = obj.SRODATA
sym.Size = int64(len(str))
sym.P = []byte(str)
- Addaddr(Ctxt, s, sym)
- adduint(Ctxt, s, uint64(len(str)))
+ Addaddr(ctxt, s, sym)
+ adduint(ctxt, s, uint64(len(str)))
}
-func addinitarrdata(s *Symbol) {
+func addinitarrdata(ctxt *Link, s *Symbol) {
p := s.Name + ".ptr"
- sp := Linklookup(Ctxt, p, 0)
+ sp := Linklookup(ctxt, p, 0)
sp.Type = obj.SINITARR
sp.Size = 0
sp.Attr |= AttrDuplicateOK
- Addaddr(Ctxt, sp, s)
+ Addaddr(ctxt, sp, s)
}
-func dosymtype() {
- for _, s := range Ctxt.Allsym {
+func dosymtype(ctxt *Link) {
+ for _, s := range ctxt.Allsym {
if len(s.P) > 0 {
if s.Type == obj.SBSS {
s.Type = obj.SDATA
switch Buildmode {
case BuildmodeCArchive, BuildmodeCShared:
if s.Name == INITENTRY {
- addinitarrdata(s)
+ addinitarrdata(ctxt, s)
}
}
}
const debugGCProg = false
type GCProg struct {
- sym *Symbol
- w gcprog.Writer
+ ctxt *Link
+ sym *Symbol
+ w gcprog.Writer
}
-func (p *GCProg) Init(name string) {
- p.sym = Linklookup(Ctxt, name, 0)
- p.w.Init(p.writeByte)
+func (p *GCProg) Init(ctxt *Link, name string) {
+ p.ctxt = ctxt
+ p.sym = Linklookup(ctxt, name, 0)
+ p.w.Init(p.writeByte(ctxt))
if debugGCProg {
fmt.Fprintf(os.Stderr, "ld: start GCProg %s\n", name)
p.w.Debug(os.Stderr)
}
}
-func (p *GCProg) writeByte(x byte) {
- Adduint8(Ctxt, p.sym, x)
+func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
+ return func(x byte) {
+ Adduint8(ctxt, p.sym, x)
+ }
}
func (p *GCProg) End(size int64) {
// Things without pointers should be in SNOPTRDATA or SNOPTRBSS;
// everything we see should have pointers and should therefore have a type.
if typ == nil {
- Diag("missing Go type information for global symbol: %s size %d", s.Name, int(s.Size))
+ p.ctxt.Diag("missing Go type information for global symbol: %s size %d", s.Name, int(s.Size))
return
}
ptrsize := int64(SysArch.PtrSize)
- nptr := decodetype_ptrdata(typ) / ptrsize
+ nptr := decodetype_ptrdata(p.ctxt.Arch, typ) / ptrsize
if debugGCProg {
fmt.Fprintf(os.Stderr, "gcprog sym: %s at %d (ptr=%d+%d)\n", s.Name, s.Value, s.Value/ptrsize, nptr)
if decodetype_usegcprog(typ) == 0 {
// Copy pointers from mask into program.
- mask := decodetype_gcmask(typ)
+ mask := decodetype_gcmask(p.ctxt, typ)
for i := int64(0); i < nptr; i++ {
if (mask[i/8]>>uint(i%8))&1 != 0 {
p.w.Ptr(s.Value/ptrsize + i)
}
// Copy program.
- prog := decodetype_gcprog(typ)
+ prog := decodetype_gcprog(p.ctxt, typ)
p.w.ZeroUntil(s.Value / ptrsize)
p.w.Append(prog[4:], nptr)
}
const cutoff int64 = 2e9 // 2 GB (or so; looks better in errors than 2^31)
-func checkdatsize(datsize int64, symn int) {
+func checkdatsize(ctxt *Link, datsize int64, symn int) {
if datsize > cutoff {
- Diag("too much data in section %v (over %d bytes)", symn, cutoff)
+ ctxt.Diag("too much data in section %v (over %d bytes)", symn, cutoff)
}
}
// Generated by dodata.
var datap []*Symbol
-func dodata() {
+func (ctxt *Link) dodata() {
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "%5.2f dodata\n", obj.Cputime())
}
// Collect data symbols by type into data.
var data [obj.SXREF][]*Symbol
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
if !s.Attr.Reachable() || s.Attr.Special() {
continue
}
//
// On darwin, we need the symbol table numbers for dynreloc.
if HEADTYPE == obj.Hdarwin {
- machosymorder()
+ machosymorder(ctxt)
}
- dynreloc(&data)
+ dynreloc(ctxt, &data)
if UseRelro() {
// "read only" data with relocations needs to go in its own section
// symbol and the outer end up in the same section).
for _, s := range relro {
if s.Outer != nil && s.Outer.Type != s.Type {
- Diag("inconsistent types for %s and its Outer %s (%d != %d)",
+ ctxt.Diag("inconsistent types for %s and its Outer %s (%d != %d)",
s.Name, s.Outer.Name, s.Type, s.Outer.Type)
}
}
symn := symn
wg.Add(1)
go func() {
- data[symn], dataMaxAlign[symn] = dodataSect(symn, data[symn])
+ data[symn], dataMaxAlign[symn] = dodataSect(ctxt, symn, data[symn])
wg.Done()
}()
}
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(datsize, symn)
+ checkdatsize(ctxt, datsize, symn)
}
// .got (and .toc on ppc64)
s.Value = int64(uint64(datsize) - sect.Vaddr)
// Resolve .TOC. symbol for this object file (ppc64)
- toc = Linkrlookup(Ctxt, ".TOC.", int(s.Version))
+ toc = Linkrlookup(ctxt, ".TOC.", int(s.Version))
if toc != nil {
toc.Sect = sect
toc.Outer = s
datsize += s.Size
}
- checkdatsize(datsize, obj.SELFGOT)
+ checkdatsize(ctxt, datsize, obj.SELFGOT)
sect.Length = uint64(datsize) - sect.Vaddr
}
sect.Align = dataMaxAlign[obj.SNOPTRDATA]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.noptrdata", 0).Sect = sect
- Linklookup(Ctxt, "runtime.enoptrdata", 0).Sect = sect
+ Linklookup(ctxt, "runtime.noptrdata", 0).Sect = sect
+ Linklookup(ctxt, "runtime.enoptrdata", 0).Sect = sect
for _, s := range data[obj.SNOPTRDATA] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, obj.SNOPTRDATA)
+ checkdatsize(ctxt, datsize, obj.SNOPTRDATA)
sect.Length = uint64(datsize) - sect.Vaddr
hasinitarr := Linkshared
datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
- checkdatsize(datsize, obj.SINITARR)
+ checkdatsize(ctxt, datsize, obj.SINITARR)
}
/* data */
sect.Align = dataMaxAlign[obj.SDATA]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.data", 0).Sect = sect
- Linklookup(Ctxt, "runtime.edata", 0).Sect = sect
+ Linklookup(ctxt, "runtime.data", 0).Sect = sect
+ Linklookup(ctxt, "runtime.edata", 0).Sect = sect
var gc GCProg
- gc.Init("runtime.gcdata")
+ gc.Init(ctxt, "runtime.gcdata")
for _, s := range data[obj.SDATA] {
s.Sect = sect
s.Type = obj.SDATA
gc.AddSym(s)
datsize += s.Size
}
- checkdatsize(datsize, obj.SDATA)
+ checkdatsize(ctxt, datsize, obj.SDATA)
sect.Length = uint64(datsize) - sect.Vaddr
gc.End(int64(sect.Length))
sect.Align = dataMaxAlign[obj.SBSS]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.bss", 0).Sect = sect
- Linklookup(Ctxt, "runtime.ebss", 0).Sect = sect
+ Linklookup(ctxt, "runtime.bss", 0).Sect = sect
+ Linklookup(ctxt, "runtime.ebss", 0).Sect = sect
gc = GCProg{}
- gc.Init("runtime.gcbss")
+ gc.Init(ctxt, "runtime.gcbss")
for _, s := range data[obj.SBSS] {
s.Sect = sect
datsize = aligndatsize(datsize, s)
gc.AddSym(s)
datsize += s.Size
}
- checkdatsize(datsize, obj.SBSS)
+ checkdatsize(ctxt, datsize, obj.SBSS)
sect.Length = uint64(datsize) - sect.Vaddr
gc.End(int64(sect.Length))
sect.Align = dataMaxAlign[obj.SNOPTRBSS]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.noptrbss", 0).Sect = sect
- Linklookup(Ctxt, "runtime.enoptrbss", 0).Sect = sect
+ Linklookup(ctxt, "runtime.noptrbss", 0).Sect = sect
+ Linklookup(ctxt, "runtime.enoptrbss", 0).Sect = sect
for _, s := range data[obj.SNOPTRBSS] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
}
sect.Length = uint64(datsize) - sect.Vaddr
- Linklookup(Ctxt, "runtime.end", 0).Sect = sect
- checkdatsize(datsize, obj.SNOPTRBSS)
+ Linklookup(ctxt, "runtime.end", 0).Sect = sect
+ checkdatsize(ctxt, datsize, obj.SNOPTRBSS)
if len(data[obj.STLSBSS]) > 0 {
var sect *Section
s.Value = datsize
datsize += s.Size
}
- checkdatsize(datsize, obj.STLSBSS)
+ checkdatsize(ctxt, datsize, obj.STLSBSS)
if sect != nil {
sect.Length = uint64(datsize)
/* read-only executable ELF, Mach-O sections */
if len(data[obj.STEXT]) != 0 {
- Diag("dodata found an STEXT symbol: %s", data[obj.STEXT][0].Name)
+ ctxt.Diag("dodata found an STEXT symbol: %s", data[obj.STEXT][0].Name)
}
for _, s := range data[obj.SELFRXSECT] {
sect := addsection(&Segtext, s.Name, 04)
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
- checkdatsize(datsize, obj.SELFRXSECT)
+ checkdatsize(ctxt, datsize, obj.SELFRXSECT)
}
/* read-only data */
sect = addsection(segro, ".rodata", 04)
sect.Vaddr = 0
- Linklookup(Ctxt, "runtime.rodata", 0).Sect = sect
- Linklookup(Ctxt, "runtime.erodata", 0).Sect = sect
+ Linklookup(ctxt, "runtime.rodata", 0).Sect = sect
+ Linklookup(ctxt, "runtime.erodata", 0).Sect = sect
if !UseRelro() {
- Linklookup(Ctxt, "runtime.types", 0).Sect = sect
- Linklookup(Ctxt, "runtime.etypes", 0).Sect = sect
+ Linklookup(ctxt, "runtime.types", 0).Sect = sect
+ Linklookup(ctxt, "runtime.etypes", 0).Sect = sect
}
roSects := []int{
obj.STYPE,
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, symn)
+ checkdatsize(ctxt, datsize, symn)
}
sect.Length = uint64(datsize) - sect.Vaddr
sect = addsection(segro, ".data.rel.ro", 06)
sect.Vaddr = 0
- Linklookup(Ctxt, "runtime.types", 0).Sect = sect
- Linklookup(Ctxt, "runtime.etypes", 0).Sect = sect
+ Linklookup(ctxt, "runtime.types", 0).Sect = sect
+ Linklookup(ctxt, "runtime.etypes", 0).Sect = sect
relroSects := []int{
obj.STYPERELRO,
obj.SSTRINGRELRO,
for _, s := range data[symn] {
datsize = aligndatsize(datsize, s)
if s.Outer != nil && s.Outer.Sect != nil && s.Outer.Sect != sect {
- Diag("s.Outer (%s) in different section from s (%s)", s.Outer.Name, s.Name)
+ ctxt.Diag("s.Outer (%s) in different section from s (%s)", s.Outer.Name, s.Name)
}
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, symn)
+ checkdatsize(ctxt, datsize, symn)
}
sect.Length = uint64(datsize) - sect.Vaddr
sect.Align = dataMaxAlign[obj.STYPELINK]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.typelink", 0).Sect = sect
- Linklookup(Ctxt, "runtime.etypelink", 0).Sect = sect
+ Linklookup(ctxt, "runtime.typelink", 0).Sect = sect
+ Linklookup(ctxt, "runtime.etypelink", 0).Sect = sect
for _, s := range data[obj.STYPELINK] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, obj.STYPELINK)
+ checkdatsize(ctxt, datsize, obj.STYPELINK)
sect.Length = uint64(datsize) - sect.Vaddr
/* itablink */
sect.Align = dataMaxAlign[obj.SITABLINK]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.itablink", 0).Sect = sect
- Linklookup(Ctxt, "runtime.eitablink", 0).Sect = sect
+ Linklookup(ctxt, "runtime.itablink", 0).Sect = sect
+ Linklookup(ctxt, "runtime.eitablink", 0).Sect = sect
for _, s := range data[obj.SITABLINK] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, obj.SITABLINK)
+ checkdatsize(ctxt, datsize, obj.SITABLINK)
sect.Length = uint64(datsize) - sect.Vaddr
/* gosymtab */
sect.Align = dataMaxAlign[obj.SSYMTAB]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.symtab", 0).Sect = sect
- Linklookup(Ctxt, "runtime.esymtab", 0).Sect = sect
+ Linklookup(ctxt, "runtime.symtab", 0).Sect = sect
+ Linklookup(ctxt, "runtime.esymtab", 0).Sect = sect
for _, s := range data[obj.SSYMTAB] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, obj.SSYMTAB)
+ checkdatsize(ctxt, datsize, obj.SSYMTAB)
sect.Length = uint64(datsize) - sect.Vaddr
/* gopclntab */
sect.Align = dataMaxAlign[obj.SPCLNTAB]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
- Linklookup(Ctxt, "runtime.pclntab", 0).Sect = sect
- Linklookup(Ctxt, "runtime.epclntab", 0).Sect = sect
+ Linklookup(ctxt, "runtime.pclntab", 0).Sect = sect
+ Linklookup(ctxt, "runtime.epclntab", 0).Sect = sect
for _, s := range data[obj.SPCLNTAB] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
datsize += s.Size
}
- checkdatsize(datsize, obj.SRODATA)
+ checkdatsize(ctxt, datsize, obj.SRODATA)
sect.Length = uint64(datsize) - sect.Vaddr
/* read-only ELF, Mach-O sections */
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(datsize, obj.SELFROSECT)
+ checkdatsize(ctxt, datsize, obj.SELFROSECT)
for _, s := range data[obj.SMACHOPLT] {
sect = addsection(segro, s.Name, 04)
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(datsize, obj.SMACHOPLT)
+ checkdatsize(ctxt, datsize, obj.SMACHOPLT)
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
if datsize != int64(uint32(datsize)) {
- Diag("read-only data segment too large")
+ ctxt.Diag("read-only data segment too large")
}
for symn := obj.SELFRXSECT; symn < obj.SXREF; symn++ {
datap = append(datap, data[symn]...)
}
- dwarfgeneratedebugsyms()
+ dwarfgeneratedebugsyms(ctxt)
var s *Symbol
for s = dwarfp; s != nil && s.Type == obj.SDWARFSECT; s = s.Next {
datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
- checkdatsize(datsize, obj.SDWARFSECT)
+ checkdatsize(ctxt, datsize, obj.SDWARFSECT)
if s != nil {
sect = addsection(&Segdwarf, ".debug_info", 04)
datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
- checkdatsize(datsize, obj.SDWARFINFO)
+ checkdatsize(ctxt, datsize, obj.SDWARFINFO)
}
/* number the sections */
}
}
-func dodataSect(symn int, syms []*Symbol) (result []*Symbol, maxAlign int32) {
+func dodataSect(ctxt *Link, symn int, syms []*Symbol) (result []*Symbol, maxAlign int32) {
if HEADTYPE == obj.Hdarwin {
// Some symbols may no longer belong in syms
// due to movement in machosymorder.
s.Attr |= AttrOnList
switch {
case s.Size < int64(len(s.P)):
- Diag("%s: initialize bounds (%d < %d)", s.Name, s.Size, len(s.P))
+ ctxt.Diag("%s: initialize bounds (%d < %d)", s.Name, s.Size, len(s.P))
case s.Size < 0:
- Diag("%s: negative size (%d bytes)", s.Name, s.Size)
+ ctxt.Diag("%s: negative size (%d bytes)", s.Name, s.Size)
case s.Size > cutoff:
- Diag("%s: symbol too large (%d bytes)", s.Name, s.Size)
+ ctxt.Diag("%s: symbol too large (%d bytes)", s.Name, s.Size)
}
symsSort[i] = dataSortKey{
// give us a place to put the Go build ID. On those systems, we put it
// at the very beginning of the text segment.
// This ``header'' is read by cmd/go.
-func textbuildid() {
+func (ctxt *Link) textbuildid() {
if Iself || buildid == "" {
return
}
- sym := Linklookup(Ctxt, "go.buildid", 0)
+ sym := Linklookup(ctxt, "go.buildid", 0)
sym.Attr |= AttrReachable
// The \xff is invalid UTF-8, meant to make it less likely
// to find one of these accidentally.
sym.P = []byte(data)
sym.Size = int64(len(sym.P))
- Ctxt.Textp = append(Ctxt.Textp, nil)
- copy(Ctxt.Textp[1:], Ctxt.Textp)
- Ctxt.Textp[0] = sym
+ ctxt.Textp = append(ctxt.Textp, nil)
+ copy(ctxt.Textp[1:], ctxt.Textp)
+ ctxt.Textp[0] = sym
}
// assign addresses to text
-func textaddress() {
+func (ctxt *Link) textaddress() {
addsection(&Segtext, ".text", 05)
// Assign PCs in text segment.
sect := Segtext.Sect
sect.Align = int32(Funcalign)
- Linklookup(Ctxt, "runtime.text", 0).Sect = sect
- Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
+ Linklookup(ctxt, "runtime.text", 0).Sect = sect
+ Linklookup(ctxt, "runtime.etext", 0).Sect = sect
if HEADTYPE == obj.Hwindows {
- Linklookup(Ctxt, ".text", 0).Sect = sect
+ Linklookup(ctxt, ".text", 0).Sect = sect
}
va := uint64(INITTEXT)
sect.Vaddr = va
- for _, sym := range Ctxt.Textp {
+ for _, sym := range ctxt.Textp {
sym.Sect = sect
if sym.Type&obj.SSUB != 0 {
continue
sub.Value += int64(va)
}
if sym.Size == 0 && sym.Sub != nil {
- Ctxt.Cursym = sym
+ ctxt.Cursym = sym
}
if sym.Size < MINFUNC {
va += MINFUNC // spacing required for findfunctab
}
// assign addresses
-func address() {
+func (ctxt *Link) address() {
va := uint64(INITTEXT)
Segtext.Rwx = 05
Segtext.Vaddr = va
pclntab := symtab.Next
for _, s := range datap {
- Ctxt.Cursym = s
+ ctxt.Cursym = s
if s.Sect != nil {
s.Value += int64(s.Sect.Vaddr)
}
}
for sym := dwarfp; sym != nil; sym = sym.Next {
- Ctxt.Cursym = sym
+ ctxt.Cursym = sym
if sym.Sect != nil {
sym.Value += int64(sym.Sect.Vaddr)
}
}
if Buildmode == BuildmodeShared {
- s := Linklookup(Ctxt, "go.link.abihashbytes", 0)
- sectSym := Linklookup(Ctxt, ".note.go.abihash", 0)
+ s := Linklookup(ctxt, "go.link.abihashbytes", 0)
+ sectSym := Linklookup(ctxt, ".note.go.abihash", 0)
s.Sect = sectSym.Sect
s.Value = int64(sectSym.Sect.Vaddr + 16)
}
types = rodata
}
- xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
- xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length))
+ ctxt.xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
+ ctxt.xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length))
if HEADTYPE == obj.Hwindows {
- xdefine(".text", obj.STEXT, int64(text.Vaddr))
- }
- xdefine("runtime.rodata", obj.SRODATA, int64(rodata.Vaddr))
- xdefine("runtime.erodata", obj.SRODATA, int64(rodata.Vaddr+rodata.Length))
- xdefine("runtime.types", obj.SRODATA, int64(types.Vaddr))
- xdefine("runtime.etypes", obj.SRODATA, int64(types.Vaddr+types.Length))
- xdefine("runtime.typelink", obj.SRODATA, int64(typelink.Vaddr))
- xdefine("runtime.etypelink", obj.SRODATA, int64(typelink.Vaddr+typelink.Length))
- xdefine("runtime.itablink", obj.SRODATA, int64(itablink.Vaddr))
- xdefine("runtime.eitablink", obj.SRODATA, int64(itablink.Vaddr+itablink.Length))
-
- sym := Linklookup(Ctxt, "runtime.gcdata", 0)
+ ctxt.xdefine(".text", obj.STEXT, int64(text.Vaddr))
+ }
+ ctxt.xdefine("runtime.rodata", obj.SRODATA, int64(rodata.Vaddr))
+ ctxt.xdefine("runtime.erodata", obj.SRODATA, int64(rodata.Vaddr+rodata.Length))
+ ctxt.xdefine("runtime.types", obj.SRODATA, int64(types.Vaddr))
+ ctxt.xdefine("runtime.etypes", obj.SRODATA, int64(types.Vaddr+types.Length))
+ ctxt.xdefine("runtime.typelink", obj.SRODATA, int64(typelink.Vaddr))
+ ctxt.xdefine("runtime.etypelink", obj.SRODATA, int64(typelink.Vaddr+typelink.Length))
+ ctxt.xdefine("runtime.itablink", obj.SRODATA, int64(itablink.Vaddr))
+ ctxt.xdefine("runtime.eitablink", obj.SRODATA, int64(itablink.Vaddr+itablink.Length))
+
+ sym := Linklookup(ctxt, "runtime.gcdata", 0)
sym.Attr |= AttrLocal
- xdefine("runtime.egcdata", obj.SRODATA, Symaddr(sym)+sym.Size)
- Linklookup(Ctxt, "runtime.egcdata", 0).Sect = sym.Sect
+ ctxt.xdefine("runtime.egcdata", obj.SRODATA, Symaddr(ctxt, sym)+sym.Size)
+ Linklookup(ctxt, "runtime.egcdata", 0).Sect = sym.Sect
- sym = Linklookup(Ctxt, "runtime.gcbss", 0)
+ sym = Linklookup(ctxt, "runtime.gcbss", 0)
sym.Attr |= AttrLocal
- xdefine("runtime.egcbss", obj.SRODATA, Symaddr(sym)+sym.Size)
- Linklookup(Ctxt, "runtime.egcbss", 0).Sect = sym.Sect
-
- xdefine("runtime.symtab", obj.SRODATA, int64(symtab.Vaddr))
- xdefine("runtime.esymtab", obj.SRODATA, int64(symtab.Vaddr+symtab.Length))
- xdefine("runtime.pclntab", obj.SRODATA, int64(pclntab.Vaddr))
- xdefine("runtime.epclntab", obj.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
- xdefine("runtime.noptrdata", obj.SNOPTRDATA, int64(noptr.Vaddr))
- xdefine("runtime.enoptrdata", obj.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
- xdefine("runtime.bss", obj.SBSS, int64(bss.Vaddr))
- xdefine("runtime.ebss", obj.SBSS, int64(bss.Vaddr+bss.Length))
- xdefine("runtime.data", obj.SDATA, int64(data.Vaddr))
- xdefine("runtime.edata", obj.SDATA, int64(data.Vaddr+data.Length))
- xdefine("runtime.noptrbss", obj.SNOPTRBSS, int64(noptrbss.Vaddr))
- xdefine("runtime.enoptrbss", obj.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
- xdefine("runtime.end", obj.SBSS, int64(Segdata.Vaddr+Segdata.Length))
+ ctxt.xdefine("runtime.egcbss", obj.SRODATA, Symaddr(ctxt, sym)+sym.Size)
+ Linklookup(ctxt, "runtime.egcbss", 0).Sect = sym.Sect
+
+ ctxt.xdefine("runtime.symtab", obj.SRODATA, int64(symtab.Vaddr))
+ ctxt.xdefine("runtime.esymtab", obj.SRODATA, int64(symtab.Vaddr+symtab.Length))
+ ctxt.xdefine("runtime.pclntab", obj.SRODATA, int64(pclntab.Vaddr))
+ ctxt.xdefine("runtime.epclntab", obj.SRODATA, int64(pclntab.Vaddr+pclntab.Length))
+ ctxt.xdefine("runtime.noptrdata", obj.SNOPTRDATA, int64(noptr.Vaddr))
+ ctxt.xdefine("runtime.enoptrdata", obj.SNOPTRDATA, int64(noptr.Vaddr+noptr.Length))
+ ctxt.xdefine("runtime.bss", obj.SBSS, int64(bss.Vaddr))
+ ctxt.xdefine("runtime.ebss", obj.SBSS, int64(bss.Vaddr+bss.Length))
+ ctxt.xdefine("runtime.data", obj.SDATA, int64(data.Vaddr))
+ ctxt.xdefine("runtime.edata", obj.SDATA, int64(data.Vaddr+data.Length))
+ ctxt.xdefine("runtime.noptrbss", obj.SNOPTRBSS, int64(noptrbss.Vaddr))
+ ctxt.xdefine("runtime.enoptrbss", obj.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length))
+ ctxt.xdefine("runtime.end", obj.SBSS, int64(Segdata.Vaddr+Segdata.Length))
}
if strings.HasPrefix(s.Name, "type.") && s.Name[5] != '.' {
if decodetype_kind(s)&kindMask == kindInterface {
- for _, sig := range decodetype_ifacemethods(s) {
+ for _, sig := range decodetype_ifacemethods(d.ctxt.Arch, s) {
if Debug['v'] > 1 {
fmt.Fprintf(d.ctxt.Bso, "reached iface method: %s\n", sig)
}
// Decode runtime type information for type methods
// to help work out which methods can be called
// dynamically via interfaces.
- methodsigs := decodetype_methods(s)
+ methodsigs := decodetype_methods(d.ctxt.Arch, s)
if len(methods) != len(methodsigs) {
panic(fmt.Sprintf("%q has %d method relocations for %d methods", s.Name, len(methods), len(methodsigs)))
}
return r.Sym
}
-func decode_inuxi(p []byte, sz int) uint64 {
+func decode_inuxi(arch *sys.Arch, p []byte, sz int) uint64 {
switch sz {
case 2:
- return uint64(Ctxt.Arch.ByteOrder.Uint16(p))
+ return uint64(arch.ByteOrder.Uint16(p))
case 4:
- return uint64(Ctxt.Arch.ByteOrder.Uint32(p))
+ return uint64(arch.ByteOrder.Uint32(p))
case 8:
- return Ctxt.Arch.ByteOrder.Uint64(p)
+ return arch.ByteOrder.Uint64(p)
default:
Exitf("dwarf: decode inuxi %d", sz)
panic("unreachable")
}
// Type.commonType.size
-func decodetype_size(s *Symbol) int64 {
- return int64(decode_inuxi(s.P, SysArch.PtrSize)) // 0x8 / 0x10
+func decodetype_size(arch *sys.Arch, s *Symbol) int64 {
+ return int64(decode_inuxi(arch, s.P, SysArch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.ptrdata
-func decodetype_ptrdata(s *Symbol) int64 {
- return int64(decode_inuxi(s.P[SysArch.PtrSize:], SysArch.PtrSize)) // 0x8 / 0x10
+func decodetype_ptrdata(arch *sys.Arch, s *Symbol) int64 {
+ return int64(decode_inuxi(arch, s.P[SysArch.PtrSize:], SysArch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.tflag
}
// Find the elf.Section of a given shared library that contains a given address.
-func findShlibSection(path string, addr uint64) *elf.Section {
- for _, shlib := range Ctxt.Shlibs {
+func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
+ for _, shlib := range ctxt.Shlibs {
if shlib.Path == path {
for _, sect := range shlib.File.Sections {
if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
}
// Type.commonType.gc
-func decodetype_gcprog(s *Symbol) []byte {
+func decodetype_gcprog(ctxt *Link, s *Symbol) []byte {
if s.Type == obj.SDYNIMPORT {
- addr := decodetype_gcprog_shlib(s)
- sect := findShlibSection(s.File, addr)
+ addr := decodetype_gcprog_shlib(ctxt, s)
+ sect := findShlibSection(ctxt, s.File, addr)
if sect != nil {
// A gcprog is a 4-byte uint32 indicating length, followed by
// the actual program.
progsize := make([]byte, 4)
sect.ReadAt(progsize, int64(addr-sect.Addr))
- progbytes := make([]byte, Ctxt.Arch.ByteOrder.Uint32(progsize))
+ progbytes := make([]byte, ctxt.Arch.ByteOrder.Uint32(progsize))
sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
return append(progsize, progbytes...)
}
return decode_reloc_sym(s, 2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize)).P
}
-func decodetype_gcprog_shlib(s *Symbol) uint64 {
+func decodetype_gcprog_shlib(ctxt *Link, s *Symbol) uint64 {
if SysArch.Family == sys.ARM64 {
- for _, shlib := range Ctxt.Shlibs {
+ for _, shlib := range ctxt.Shlibs {
if shlib.Path == s.File {
return shlib.gcdata_addresses[s]
}
}
return 0
}
- return decode_inuxi(s.P[2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize):], SysArch.PtrSize)
+ return decode_inuxi(ctxt.Arch, s.P[2*int32(SysArch.PtrSize)+8+1*int32(SysArch.PtrSize):], SysArch.PtrSize)
}
-func decodetype_gcmask(s *Symbol) []byte {
+func decodetype_gcmask(ctxt *Link, s *Symbol) []byte {
if s.Type == obj.SDYNIMPORT {
- addr := decodetype_gcprog_shlib(s)
- ptrdata := decodetype_ptrdata(s)
- sect := findShlibSection(s.File, addr)
+ addr := decodetype_gcprog_shlib(ctxt, s)
+ ptrdata := decodetype_ptrdata(ctxt.Arch, s)
+ sect := findShlibSection(ctxt, s.File, addr)
if sect != nil {
r := make([]byte, ptrdata/int64(SysArch.PtrSize))
sect.ReadAt(r, int64(addr-sect.Addr))
return decode_reloc_sym(s, int32(commonsize())) // 0x1c / 0x30
}
-func decodetype_arraylen(s *Symbol) int64 {
- return int64(decode_inuxi(s.P[commonsize()+2*SysArch.PtrSize:], SysArch.PtrSize))
+func decodetype_arraylen(arch *sys.Arch, s *Symbol) int64 {
+ return int64(decode_inuxi(arch, s.P[commonsize()+2*SysArch.PtrSize:], SysArch.PtrSize))
}
// Type.PtrType.elem
}
// Type.FuncType.dotdotdot
-func decodetype_funcdotdotdot(s *Symbol) bool {
- return uint16(decode_inuxi(s.P[commonsize()+2:], 2))&(1<<15) != 0
+func decodetype_funcdotdotdot(arch *sys.Arch, s *Symbol) bool {
+ return uint16(decode_inuxi(arch, s.P[commonsize()+2:], 2))&(1<<15) != 0
}
// Type.FuncType.inCount
-func decodetype_funcincount(s *Symbol) int {
- return int(decode_inuxi(s.P[commonsize():], 2))
+func decodetype_funcincount(arch *sys.Arch, s *Symbol) int {
+ return int(decode_inuxi(arch, s.P[commonsize():], 2))
}
-func decodetype_funcoutcount(s *Symbol) int {
- return int(uint16(decode_inuxi(s.P[commonsize()+2:], 2)) & (1<<15 - 1))
+func decodetype_funcoutcount(arch *sys.Arch, s *Symbol) int {
+ return int(uint16(decode_inuxi(arch, s.P[commonsize()+2:], 2)) & (1<<15 - 1))
}
func decodetype_funcintype(s *Symbol, i int) *Symbol {
return decode_reloc_sym(s, int32(uadd+i*SysArch.PtrSize))
}
-func decodetype_funcouttype(s *Symbol, i int) *Symbol {
- return decodetype_funcintype(s, i+decodetype_funcincount(s))
+func decodetype_funcouttype(arch *sys.Arch, s *Symbol, i int) *Symbol {
+ return decodetype_funcintype(s, i+decodetype_funcincount(arch, s))
}
// Type.StructType.fields.Slice::length
-func decodetype_structfieldcount(s *Symbol) int {
- return int(decode_inuxi(s.P[commonsize()+2*SysArch.PtrSize:], SysArch.IntSize))
+func decodetype_structfieldcount(arch *sys.Arch, s *Symbol) int {
+ return int(decode_inuxi(arch, s.P[commonsize()+2*SysArch.PtrSize:], SysArch.IntSize))
}
func decodetype_structfieldarrayoff(s *Symbol, i int) int {
return decode_reloc_sym(s, int32(off+SysArch.PtrSize))
}
-func decodetype_structfieldoffs(s *Symbol, i int) int64 {
+func decodetype_structfieldoffs(arch *sys.Arch, s *Symbol, i int) int64 {
off := decodetype_structfieldarrayoff(s, i)
- return int64(decode_inuxi(s.P[off+2*SysArch.PtrSize:], SysArch.IntSize))
+ return int64(decode_inuxi(arch, s.P[off+2*SysArch.PtrSize:], SysArch.IntSize))
}
// InterfaceType.methods.length
-func decodetype_ifacemethodcount(s *Symbol) int64 {
- return int64(decode_inuxi(s.P[commonsize()+2*SysArch.PtrSize:], SysArch.IntSize))
+func decodetype_ifacemethodcount(arch *sys.Arch, s *Symbol) int64 {
+ return int64(decode_inuxi(arch, s.P[commonsize()+2*SysArch.PtrSize:], SysArch.IntSize))
}
// methodsig is a fully qualified typed method signature, like
// the function type.
//
// Conveniently this is the layout of both runtime.method and runtime.imethod.
-func decode_methodsig(s *Symbol, off, size, count int) []methodsig {
+func decode_methodsig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsig {
var buf bytes.Buffer
var methods []methodsig
for i := 0; i < count; i++ {
mtypSym := decode_reloc_sym(s, int32(off+4))
buf.WriteRune('(')
- inCount := decodetype_funcincount(mtypSym)
+ inCount := decodetype_funcincount(arch, mtypSym)
for i := 0; i < inCount; i++ {
if i > 0 {
buf.WriteString(", ")
buf.WriteString(decodetype_funcintype(mtypSym, i).Name)
}
buf.WriteString(") (")
- outCount := decodetype_funcoutcount(mtypSym)
+ outCount := decodetype_funcoutcount(arch, mtypSym)
for i := 0; i < outCount; i++ {
if i > 0 {
buf.WriteString(", ")
}
- buf.WriteString(decodetype_funcouttype(mtypSym, i).Name)
+ buf.WriteString(decodetype_funcouttype(arch, mtypSym, i).Name)
}
buf.WriteRune(')')
return methods
}
-func decodetype_ifacemethods(s *Symbol) []methodsig {
+func decodetype_ifacemethods(arch *sys.Arch, s *Symbol) []methodsig {
if decodetype_kind(s)&kindMask != kindInterface {
panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
}
panic(fmt.Sprintf("imethod slice pointer in %q leads to a different symbol", s.Name))
}
off := int(r.Add) // array of reflect.imethod values
- numMethods := int(decodetype_ifacemethodcount(s))
+ numMethods := int(decodetype_ifacemethodcount(arch, s))
sizeofIMethod := 4 + 4
- return decode_methodsig(s, off, sizeofIMethod, numMethods)
+ return decode_methodsig(arch, s, off, sizeofIMethod, numMethods)
}
-func decodetype_methods(s *Symbol) []methodsig {
+func decodetype_methods(arch *sys.Arch, s *Symbol) []methodsig {
if !decodetype_hasUncommon(s) {
panic(fmt.Sprintf("no methods on %q", s.Name))
}
// just Sizeof(rtype)
}
- mcount := int(decode_inuxi(s.P[off+4:], 2))
- moff := int(decode_inuxi(s.P[off+4+2+2:], 4))
+ mcount := int(decode_inuxi(arch, s.P[off+4:], 2))
+ moff := int(decode_inuxi(arch, s.P[off+4+2+2:], 4))
off += moff // offset to array of reflect.method values
const sizeofMethod = 4 * 4 // sizeof reflect.method in program
- return decode_methodsig(s, off, sizeofMethod, mcount)
+ return decode_methodsig(arch, s, off, sizeofMethod, mcount)
}
"strings"
)
-type dwCtxt struct{}
+type dwctxt struct {
+ linkctxt *Link
+}
-func (c dwCtxt) PtrSize() int {
+func (c dwctxt) PtrSize() int {
return SysArch.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)
- adduintxx(Ctxt, ls, uint64(i), size)
+ adduintxx(c.linkctxt, ls, uint64(i), size)
}
-func (c dwCtxt) AddBytes(s dwarf.Sym, b []byte) {
+func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
ls := s.(*Symbol)
- Addbytes(Ctxt, ls, b)
+ Addbytes(c.linkctxt, ls, b)
}
-func (c dwCtxt) AddString(s dwarf.Sym, v string) {
- Addstring(s.(*Symbol), v)
+func (c dwctxt) AddString(s dwarf.Sym, v string) {
+ Addstring(c.linkctxt, s.(*Symbol), v)
}
-func (c dwCtxt) SymValue(s dwarf.Sym) int64 {
+func (c dwctxt) SymValue(s dwarf.Sym) int64 {
return s.(*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 {
value -= (data.(*Symbol)).Value
}
- Addaddrplus(Ctxt, s.(*Symbol), data.(*Symbol), value)
+ Addaddrplus(c.linkctxt, s.(*Symbol), data.(*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)
switch size {
default:
- Diag("invalid size %d in adddwarfref\n", size)
+ c.linkctxt.Diag("invalid size %d in adddwarfref\n", size)
fallthrough
case SysArch.PtrSize:
- Addaddr(Ctxt, ls, t.(*Symbol))
+ Addaddr(c.linkctxt, ls, t.(*Symbol))
case 4:
- addaddrplus4(Ctxt, ls, t.(*Symbol), 0)
+ addaddrplus4(c.linkctxt, ls, t.(*Symbol), 0)
}
r := &ls.R[len(ls.R)-1]
r.Type = obj.R_DWARFREF
var dwarfp *Symbol
-func writeabbrev(syms []*Symbol) []*Symbol {
- s := Linklookup(Ctxt, ".debug_abbrev", 0)
+func writeabbrev(ctxt *Link, syms []*Symbol) []*Symbol {
+ s := Linklookup(ctxt, ".debug_abbrev", 0)
s.Type = obj.SDWARFSECT
abbrevsym = s
- Addbytes(Ctxt, s, dwarf.GetAbbrev())
+ Addbytes(ctxt, s, dwarf.GetAbbrev())
return append(syms, s)
}
// Every DIE has at least a AT_name attribute (but it will only be
// written out if it is listed in the abbrev).
-func newdie(parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie {
+func newdie(ctxt *Link, parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DWDie {
die := new(dwarf.DWDie)
die.Abbrev = abbrev
die.Link = parent.Child
if name != "" && (abbrev <= dwarf.DW_ABRV_VARIABLE || abbrev >= dwarf.DW_ABRV_NULLTYPE) {
if abbrev != dwarf.DW_ABRV_VARIABLE || version == 0 {
- sym := Linklookup(Ctxt, dwarf.InfoPrefix+name, version)
+ sym := Linklookup(ctxt, dwarf.InfoPrefix+name, version)
sym.Attr |= AttrHidden
sym.Type = obj.SDWARFINFO
die.Sym = sym
return die
}
-func walksymtypedef(s *Symbol) *Symbol {
- if t := Linkrlookup(Ctxt, s.Name+"..def", int(s.Version)); t != nil {
+func walksymtypedef(ctxt *Link, s *Symbol) *Symbol {
+ if t := Linkrlookup(ctxt, s.Name+"..def", int(s.Version)); t != nil {
return t
}
return s
// Used to avoid string allocation when looking up dwarf symbols
var prefixBuf = []byte(dwarf.InfoPrefix)
-func find(name string) *Symbol {
+func find(ctxt *Link, name string) *Symbol {
n := append(prefixBuf, name...)
// The string allocation below is optimized away because it is only used in a map lookup.
- s := Linkrlookup(Ctxt, string(n), 0)
+ s := Linkrlookup(ctxt, string(n), 0)
prefixBuf = n[:len(dwarf.InfoPrefix)]
if s != nil && s.Type == obj.SDWARFINFO {
return s
return nil
}
-func mustFind(name string) *Symbol {
- r := find(name)
+func mustFind(ctxt *Link, name string) *Symbol {
+ r := find(ctxt, name)
if r == nil {
Exitf("dwarf find: cannot find %s", name)
}
var result int64
switch size {
default:
- Diag("invalid size %d in adddwarfref\n", size)
+ ctxt.Diag("invalid size %d in adddwarfref\n", size)
fallthrough
case SysArch.PtrSize:
result = Addaddr(ctxt, s, t)
return newattr(die, attr, dwarf.DW_CLS_REFERENCE, 0, ref)
}
-func putdies(ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
+func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
for ; die != nil; die = die.Link {
- syms = putdie(ctxt, syms, die)
+ syms = putdie(linkctxt, ctxt, syms, die)
}
- Adduint8(Ctxt, syms[len(syms)-1], 0)
+ Adduint8(linkctxt, syms[len(syms)-1], 0)
return syms
}
return s.(*Symbol)
}
-func putdie(ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
+func putdie(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol {
s := dtolsym(die.Sym)
if s == nil {
s = syms[len(syms)-1]
dwarf.Uleb128put(ctxt, s, int64(die.Abbrev))
dwarf.PutAttrs(ctxt, s, die.Abbrev, die.Attr)
if dwarf.HasChildren(die) {
- return putdies(ctxt, syms, die.Child)
+ return putdies(linkctxt, ctxt, syms, die.Child)
}
return syms
}
}
// Lookup predefined types
-func lookup_or_diag(n string) *Symbol {
- s := Linkrlookup(Ctxt, n, 0)
+func lookup_or_diag(ctxt *Link, n string) *Symbol {
+ s := Linkrlookup(ctxt, n, 0)
if s == nil || s.Size == 0 {
Exitf("dwarf: missing type: %s", n)
}
return s
}
-func dotypedef(parent *dwarf.DWDie, name string, def *dwarf.DWDie) {
+func dotypedef(ctxt *Link, parent *dwarf.DWDie, name string, def *dwarf.DWDie) {
// Only emit typedefs for real names.
if strings.HasPrefix(name, "map[") {
return
return
}
if def == nil {
- Diag("dwarf: bad def in dotypedef")
+ ctxt.Diag("dwarf: bad def in dotypedef")
}
- sym := Linklookup(Ctxt, dtolsym(def.Sym).Name+"..def", 0)
+ sym := Linklookup(ctxt, dtolsym(def.Sym).Name+"..def", 0)
sym.Attr |= AttrHidden
sym.Type = obj.SDWARFINFO
def.Sym = sym
// so that future lookups will find the typedef instead
// of the real definition. This hooks the typedef into any
// circular definition loops, so that gdb can understand them.
- die := newdie(parent, dwarf.DW_ABRV_TYPEDECL, name, 0)
+ die := newdie(ctxt, parent, dwarf.DW_ABRV_TYPEDECL, name, 0)
newrefattr(die, dwarf.DW_AT_type, sym)
}
// Define gotype, for composite ones recurse into constituents.
-func defgotype(gotype *Symbol) *Symbol {
+func defgotype(ctxt *Link, gotype *Symbol) *Symbol {
if gotype == nil {
- return mustFind("<unspecified>")
+ return mustFind(ctxt, "<unspecified>")
}
if !strings.HasPrefix(gotype.Name, "type.") {
- Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name)
- return mustFind("<unspecified>")
+ ctxt.Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name)
+ return mustFind(ctxt, "<unspecified>")
}
name := gotype.Name[5:] // could also decode from Type.string
- sdie := find(name)
+ sdie := find(ctxt, name)
if sdie != nil {
return sdie
}
- return newtype(gotype).Sym.(*Symbol)
+ return newtype(ctxt, gotype).Sym.(*Symbol)
}
-func newtype(gotype *Symbol) *dwarf.DWDie {
+func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
name := gotype.Name[5:] // could also decode from Type.string
kind := decodetype_kind(gotype)
- bytesize := decodetype_size(gotype)
+ bytesize := decodetype_size(ctxt.Arch, gotype)
var die *dwarf.DWDie
switch kind {
case obj.KindBool:
- die = newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_boolean, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
obj.KindInt16,
obj.KindInt32,
obj.KindInt64:
- die = newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_signed, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
obj.KindUint32,
obj.KindUint64,
obj.KindUintptr:
- die = newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
case obj.KindFloat32,
obj.KindFloat64:
- die = newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_float, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
case obj.KindComplex64,
obj.KindComplex128:
- die = newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_complex_float, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
case obj.KindArray:
- die = newdie(&dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name, 0)
- dotypedef(&dwtypes, name, die)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name, 0)
+ dotypedef(ctxt, &dwtypes, name, die)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
s := decodetype_arrayelem(gotype)
- newrefattr(die, dwarf.DW_AT_type, defgotype(s))
- fld := newdie(die, dwarf.DW_ABRV_ARRAYRANGE, "range", 0)
+ newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
+ fld := newdie(ctxt, die, dwarf.DW_ABRV_ARRAYRANGE, "range", 0)
// use actual length not upper bound; correct for 0-length arrays.
- newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0)
+ newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetype_arraylen(ctxt.Arch, gotype), 0)
- newrefattr(fld, dwarf.DW_AT_type, mustFind("uintptr"))
+ newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
case obj.KindChan:
- die = newdie(&dwtypes, dwarf.DW_ABRV_CHANTYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_CHANTYPE, name, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
s := decodetype_chanelem(gotype)
- newrefattr(die, dwarf.DW_AT_go_elem, defgotype(s))
+ newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s))
// Save elem type for synthesizechantypes. We could synthesize here
// but that would change the order of DIEs we output.
newrefattr(die, dwarf.DW_AT_type, s)
case obj.KindFunc:
- die = newdie(&dwtypes, dwarf.DW_ABRV_FUNCTYPE, name, 0)
- dotypedef(&dwtypes, name, die)
- newrefattr(die, dwarf.DW_AT_type, mustFind("void"))
- nfields := decodetype_funcincount(gotype)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_FUNCTYPE, name, 0)
+ dotypedef(ctxt, &dwtypes, name, die)
+ newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "void"))
+ nfields := decodetype_funcincount(ctxt.Arch, gotype)
var fld *dwarf.DWDie
var s *Symbol
for i := 0; i < nfields; i++ {
s = decodetype_funcintype(gotype, i)
- fld = newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
- newrefattr(fld, dwarf.DW_AT_type, defgotype(s))
+ fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
+ newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s))
}
- if decodetype_funcdotdotdot(gotype) {
- newdie(die, dwarf.DW_ABRV_DOTDOTDOT, "...", 0)
+ if decodetype_funcdotdotdot(ctxt.Arch, gotype) {
+ newdie(ctxt, die, dwarf.DW_ABRV_DOTDOTDOT, "...", 0)
}
- nfields = decodetype_funcoutcount(gotype)
+ nfields = decodetype_funcoutcount(ctxt.Arch, gotype)
for i := 0; i < nfields; i++ {
- s = decodetype_funcouttype(gotype, i)
- fld = newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
- newrefattr(fld, dwarf.DW_AT_type, defptrto(defgotype(s)))
+ s = decodetype_funcouttype(ctxt.Arch, gotype, i)
+ fld = newdie(ctxt, die, dwarf.DW_ABRV_FUNCTYPEPARAM, s.Name[5:], 0)
+ newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, defgotype(ctxt, s)))
}
case obj.KindInterface:
- die = newdie(&dwtypes, dwarf.DW_ABRV_IFACETYPE, name, 0)
- dotypedef(&dwtypes, name, die)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_IFACETYPE, name, 0)
+ dotypedef(ctxt, &dwtypes, name, die)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
- nfields := int(decodetype_ifacemethodcount(gotype))
+ nfields := int(decodetype_ifacemethodcount(ctxt.Arch, gotype))
var s *Symbol
if nfields == 0 {
- s = lookup_or_diag("type.runtime.eface")
+ s = lookup_or_diag(ctxt, "type.runtime.eface")
} else {
- s = lookup_or_diag("type.runtime.iface")
+ s = lookup_or_diag(ctxt, "type.runtime.iface")
}
- newrefattr(die, dwarf.DW_AT_type, defgotype(s))
+ newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
case obj.KindMap:
- die = newdie(&dwtypes, dwarf.DW_ABRV_MAPTYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_MAPTYPE, name, 0)
s := decodetype_mapkey(gotype)
- newrefattr(die, dwarf.DW_AT_go_key, defgotype(s))
+ newrefattr(die, dwarf.DW_AT_go_key, defgotype(ctxt, s))
s = decodetype_mapvalue(gotype)
- newrefattr(die, dwarf.DW_AT_go_elem, defgotype(s))
+ newrefattr(die, dwarf.DW_AT_go_elem, defgotype(ctxt, s))
// Save gotype for use in synthesizemaptypes. We could synthesize here,
// but that would change the order of the DIEs.
newrefattr(die, dwarf.DW_AT_type, gotype)
case obj.KindPtr:
- die = newdie(&dwtypes, dwarf.DW_ABRV_PTRTYPE, name, 0)
- dotypedef(&dwtypes, name, die)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, name, 0)
+ dotypedef(ctxt, &dwtypes, name, die)
s := decodetype_ptrelem(gotype)
- newrefattr(die, dwarf.DW_AT_type, defgotype(s))
+ newrefattr(die, dwarf.DW_AT_type, defgotype(ctxt, s))
case obj.KindSlice:
- die = newdie(&dwtypes, dwarf.DW_ABRV_SLICETYPE, name, 0)
- dotypedef(&dwtypes, name, die)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_SLICETYPE, name, 0)
+ dotypedef(ctxt, &dwtypes, name, die)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
s := decodetype_arrayelem(gotype)
- elem := defgotype(s)
+ elem := defgotype(ctxt, s)
newrefattr(die, dwarf.DW_AT_go_elem, elem)
case obj.KindString:
- die = newdie(&dwtypes, dwarf.DW_ABRV_STRINGTYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_STRINGTYPE, name, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
case obj.KindStruct:
- die = newdie(&dwtypes, dwarf.DW_ABRV_STRUCTTYPE, name, 0)
- dotypedef(&dwtypes, name, die)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_STRUCTTYPE, name, 0)
+ dotypedef(ctxt, &dwtypes, name, die)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
- nfields := decodetype_structfieldcount(gotype)
+ nfields := decodetype_structfieldcount(ctxt.Arch, gotype)
var f string
var fld *dwarf.DWDie
var s *Symbol
if f == "" {
f = s.Name[5:] // skip "type."
}
- fld = newdie(die, dwarf.DW_ABRV_STRUCTFIELD, f, 0)
- newrefattr(fld, dwarf.DW_AT_type, defgotype(s))
- newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(gotype, i)))
+ fld = newdie(ctxt, die, dwarf.DW_ABRV_STRUCTFIELD, f, 0)
+ newrefattr(fld, dwarf.DW_AT_type, defgotype(ctxt, s))
+ newmemberoffsetattr(fld, int32(decodetype_structfieldoffs(ctxt.Arch, gotype, i)))
}
case obj.KindUnsafePointer:
- die = newdie(&dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, name, 0)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, name, 0)
default:
- Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
- die = newdie(&dwtypes, dwarf.DW_ABRV_TYPEDECL, name, 0)
- newrefattr(die, dwarf.DW_AT_type, mustFind("<unspecified>"))
+ ctxt.Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
+ die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_TYPEDECL, name, 0)
+ newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "<unspecified>"))
}
newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(kind), 0)
}
// Find or construct *T given T.
-func defptrto(dwtype *Symbol) *Symbol {
+func defptrto(ctxt *Link, dwtype *Symbol) *Symbol {
ptrname := "*" + nameFromDIESym(dwtype)
- die := find(ptrname)
+ die := find(ctxt, ptrname)
if die == nil {
- pdie := newdie(&dwtypes, dwarf.DW_ABRV_PTRTYPE, ptrname, 0)
+ pdie := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_PTRTYPE, ptrname, 0)
newrefattr(pdie, dwarf.DW_AT_type, dwtype)
return dtolsym(pdie.Sym)
}
// Copies src's children into dst. Copies attributes by value.
// DWAttr.data is copied as pointer only. If except is one of
// the top-level children, it will not be copied.
-func copychildrenexcept(dst *dwarf.DWDie, src *dwarf.DWDie, except *dwarf.DWDie) {
+func copychildrenexcept(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie, except *dwarf.DWDie) {
for src = src.Child; src != nil; src = src.Link {
if src == except {
continue
}
- c := newdie(dst, src.Abbrev, getattr(src, dwarf.DW_AT_name).Data.(string), 0)
+ c := newdie(ctxt, dst, src.Abbrev, getattr(src, dwarf.DW_AT_name).Data.(string), 0)
for a := src.Attr; a != nil; a = a.Link {
newattr(c, a.Atr, int(a.Cls), a.Value, a.Data)
}
- copychildrenexcept(c, src, nil)
+ copychildrenexcept(ctxt, c, src, nil)
}
reverselist(&dst.Child)
}
-func copychildren(dst *dwarf.DWDie, src *dwarf.DWDie) {
- copychildrenexcept(dst, src, nil)
+func copychildren(ctxt *Link, dst *dwarf.DWDie, src *dwarf.DWDie) {
+ copychildrenexcept(ctxt, dst, src, nil)
}
// Search children (assumed to have TAG_member) for the one named
}
}
-func findprotodie(name string) *dwarf.DWDie {
+func findprotodie(ctxt *Link, name string) *dwarf.DWDie {
die, ok := prototypedies[name]
if ok && die == nil {
- defgotype(lookup_or_diag(name))
+ defgotype(ctxt, lookup_or_diag(ctxt, name))
die = prototypedies[name]
}
return die
}
-func synthesizestringtypes(die *dwarf.DWDie) {
- prototype := walktypedef(findprotodie("type.runtime.stringStructDWARF"))
+func synthesizestringtypes(ctxt *Link, die *dwarf.DWDie) {
+ prototype := walktypedef(findprotodie(ctxt, "type.runtime.stringStructDWARF"))
if prototype == nil {
return
}
if die.Abbrev != dwarf.DW_ABRV_STRINGTYPE {
continue
}
- copychildren(die, prototype)
+ copychildren(ctxt, die, prototype)
}
}
-func synthesizeslicetypes(die *dwarf.DWDie) {
- prototype := walktypedef(findprotodie("type.runtime.slice"))
+func synthesizeslicetypes(ctxt *Link, die *dwarf.DWDie) {
+ prototype := walktypedef(findprotodie(ctxt, "type.runtime.slice"))
if prototype == nil {
return
}
if die.Abbrev != dwarf.DW_ABRV_SLICETYPE {
continue
}
- copychildren(die, prototype)
+ copychildren(ctxt, die, prototype)
elem := getattr(die, dwarf.DW_AT_go_elem).Data.(*Symbol)
- substitutetype(die, "array", defptrto(elem))
+ substitutetype(die, "array", defptrto(ctxt, elem))
}
}
BucketSize = 8
)
-func mkinternaltype(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)) *Symbol {
name := mkinternaltypename(typename, keyname, valname)
symname := dwarf.InfoPrefix + name
- s := Linkrlookup(Ctxt, symname, 0)
+ s := Linkrlookup(ctxt, symname, 0)
if s != nil && s.Type == obj.SDWARFINFO {
return s
}
- die := newdie(&dwtypes, abbrev, name, 0)
+ die := newdie(ctxt, &dwtypes, abbrev, name, 0)
f(die)
return dtolsym(die.Sym)
}
-func synthesizemaptypes(die *dwarf.DWDie) {
- hash := walktypedef(findprotodie("type.runtime.hmap"))
- bucket := walktypedef(findprotodie("type.runtime.bmap"))
+func synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
+ hash := walktypedef(findprotodie(ctxt, "type.runtime.hmap"))
+ bucket := walktypedef(findprotodie(ctxt, "type.runtime.bmap"))
if hash == nil {
return
gotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
keytype := decodetype_mapkey(gotype)
valtype := decodetype_mapvalue(gotype)
- keysize, valsize := decodetype_size(keytype), decodetype_size(valtype)
- keytype, valtype = walksymtypedef(defgotype(keytype)), walksymtypedef(defgotype(valtype))
+ keysize, valsize := decodetype_size(ctxt.Arch, keytype), decodetype_size(ctxt.Arch, valtype)
+ keytype, valtype = walksymtypedef(ctxt, defgotype(ctxt, keytype)), walksymtypedef(ctxt, defgotype(ctxt, valtype))
// compute size info like hashmap.c does.
indirect_key, indirect_val := false, false
// Construct type to represent an array of BucketSize keys
keyname := nameFromDIESym(keytype)
- dwhks := mkinternaltype(dwarf.DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *dwarf.DWDie) {
+ dwhks := mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]key", keyname, "", func(dwhk *dwarf.DWDie) {
newattr(dwhk, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize*keysize, 0)
t := keytype
if indirect_key {
- t = defptrto(keytype)
+ t = defptrto(ctxt, keytype)
}
newrefattr(dwhk, dwarf.DW_AT_type, t)
- fld := newdie(dwhk, dwarf.DW_ABRV_ARRAYRANGE, "size", 0)
+ fld := newdie(ctxt, dwhk, dwarf.DW_ABRV_ARRAYRANGE, "size", 0)
newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, BucketSize, 0)
- newrefattr(fld, dwarf.DW_AT_type, mustFind("uintptr"))
+ newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
})
// Construct type to represent an array of BucketSize values
valname := nameFromDIESym(valtype)
- dwhvs := mkinternaltype(dwarf.DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *dwarf.DWDie) {
+ dwhvs := mkinternaltype(ctxt, dwarf.DW_ABRV_ARRAYTYPE, "[]val", valname, "", func(dwhv *dwarf.DWDie) {
newattr(dwhv, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, BucketSize*valsize, 0)
t := valtype
if indirect_val {
- t = defptrto(valtype)
+ t = defptrto(ctxt, valtype)
}
newrefattr(dwhv, dwarf.DW_AT_type, t)
- fld := newdie(dwhv, dwarf.DW_ABRV_ARRAYRANGE, "size", 0)
+ fld := newdie(ctxt, dwhv, dwarf.DW_ABRV_ARRAYRANGE, "size", 0)
newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, BucketSize, 0)
- newrefattr(fld, dwarf.DW_AT_type, mustFind("uintptr"))
+ newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
})
// Construct bucket<K,V>
- dwhbs := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) {
+ dwhbs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) {
// Copy over all fields except the field "data" from the generic
// bucket. "data" will be replaced with keys/values below.
- copychildrenexcept(dwhb, bucket, findchild(bucket, "data"))
+ copychildrenexcept(ctxt, dwhb, bucket, findchild(bucket, "data"))
- fld := newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys", 0)
+ fld := newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys", 0)
newrefattr(fld, dwarf.DW_AT_type, dwhks)
newmemberoffsetattr(fld, BucketSize)
- fld = newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values", 0)
+ fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values", 0)
newrefattr(fld, dwarf.DW_AT_type, dwhvs)
newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
- fld = newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0)
- newrefattr(fld, dwarf.DW_AT_type, defptrto(dtolsym(dwhb.Sym)))
+ fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0)
+ newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, dtolsym(dwhb.Sym)))
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
if SysArch.RegSize > SysArch.PtrSize {
- fld = newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0)
- newrefattr(fld, dwarf.DW_AT_type, mustFind("uintptr"))
+ fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0)
+ newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize))
}
})
// Construct hash<K,V>
- dwhs := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) {
- copychildren(dwh, hash)
- substitutetype(dwh, "buckets", defptrto(dwhbs))
- substitutetype(dwh, "oldbuckets", defptrto(dwhbs))
+ dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) {
+ copychildren(ctxt, dwh, hash)
+ substitutetype(dwh, "buckets", defptrto(ctxt, dwhbs))
+ substitutetype(dwh, "oldbuckets", defptrto(ctxt, dwhbs))
newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hash, dwarf.DW_AT_byte_size).Value, nil)
})
// make map type a pointer to hash<K,V>
- newrefattr(die, dwarf.DW_AT_type, defptrto(dwhs))
+ newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs))
}
}
-func synthesizechantypes(die *dwarf.DWDie) {
- sudog := walktypedef(findprotodie("type.runtime.sudog"))
- waitq := walktypedef(findprotodie("type.runtime.waitq"))
- hchan := walktypedef(findprotodie("type.runtime.hchan"))
+func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
+ sudog := walktypedef(findprotodie(ctxt, "type.runtime.sudog"))
+ waitq := walktypedef(findprotodie(ctxt, "type.runtime.waitq"))
+ hchan := walktypedef(findprotodie(ctxt, "type.runtime.hchan"))
if sudog == nil || waitq == nil || hchan == nil {
return
}
continue
}
elemgotype := getattr(die, dwarf.DW_AT_type).Data.(*Symbol)
- elemsize := decodetype_size(elemgotype)
+ elemsize := decodetype_size(ctxt.Arch, elemgotype)
elemname := elemgotype.Name[5:]
- elemtype := walksymtypedef(defgotype(elemgotype))
+ elemtype := walksymtypedef(ctxt, defgotype(ctxt, elemgotype))
// sudog<T>
- dwss := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
- copychildren(dws, sudog)
+ dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
+ copychildren(ctxt, dws, sudog)
substitutetype(dws, "elem", elemtype)
if elemsize > 8 {
elemsize -= 8
})
// waitq<T>
- dwws := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) {
+ dwws := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) {
- copychildren(dww, waitq)
- substitutetype(dww, "first", defptrto(dwss))
- substitutetype(dww, "last", defptrto(dwss))
+ copychildren(ctxt, dww, waitq)
+ substitutetype(dww, "first", defptrto(ctxt, dwss))
+ substitutetype(dww, "last", defptrto(ctxt, dwss))
newattr(dww, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(waitq, dwarf.DW_AT_byte_size).Value, nil)
})
// hchan<T>
- dwhs := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) {
- copychildren(dwh, hchan)
+ dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) {
+ copychildren(ctxt, dwh, hchan)
substitutetype(dwh, "recvq", dwws)
substitutetype(dwh, "sendq", dwws)
newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hchan, dwarf.DW_AT_byte_size).Value, nil)
})
- newrefattr(die, dwarf.DW_AT_type, defptrto(dwhs))
+ newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs))
}
}
// For use with pass.c::genasmsym
-func defdwsymb(sym *Symbol, s string, t int, v int64, size int64, ver int, gotype *Symbol) {
+func defdwsymb(ctxt *Link, sym *Symbol, s string, t int, v int64, size int64, ver int, gotype *Symbol) {
if strings.HasPrefix(s, "go.string.") {
return
}
}
if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") {
- defgotype(sym)
+ defgotype(ctxt, sym)
return
}
return
case 'd', 'b', 'D', 'B':
- dv = newdie(&dwglobals, dwarf.DW_ABRV_VARIABLE, s, ver)
+ dv = newdie(ctxt, &dwglobals, dwarf.DW_ABRV_VARIABLE, s, ver)
newabslocexprattr(dv, v, sym)
if ver == 0 {
newattr(dv, dwarf.DW_AT_external, dwarf.DW_CLS_FLAG, 1, 0)
fallthrough
case 'a', 'p':
- dt = defgotype(gotype)
+ dt = defgotype(ctxt, gotype)
}
if dv != nil {
OPCODE_BASE = 10
)
-func putpclcdelta(ctxt dwarf.Context, s *Symbol, delta_pc int64, delta_lc int64) {
+func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *Symbol, delta_pc int64, delta_lc int64) {
if LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE {
var opcode int64 = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc)
if OPCODE_BASE <= opcode && opcode < 256 {
- Adduint8(Ctxt, s, uint8(opcode))
+ Adduint8(linkctxt, s, uint8(opcode))
return
}
}
if delta_pc != 0 {
- Adduint8(Ctxt, s, dwarf.DW_LNS_advance_pc)
+ Adduint8(linkctxt, s, dwarf.DW_LNS_advance_pc)
dwarf.Sleb128put(ctxt, s, delta_pc)
}
- Adduint8(Ctxt, s, dwarf.DW_LNS_advance_line)
+ Adduint8(linkctxt, s, dwarf.DW_LNS_advance_line)
dwarf.Sleb128put(ctxt, s, delta_lc)
- Adduint8(Ctxt, s, dwarf.DW_LNS_copy)
+ Adduint8(linkctxt, s, dwarf.DW_LNS_copy)
}
/*
return "/"
}
-func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) {
- var dwarfctxt dwarf.Context = dwCtxt{}
+func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
+ var dwarfctxt dwarf.Context = dwctxt{ctxt}
if linesec == nil {
- linesec = Linklookup(Ctxt, ".debug_line", 0)
+ linesec = Linklookup(ctxt, ".debug_line", 0)
}
linesec.Type = obj.SDWARFSECT
linesec.R = linesec.R[:0]
lang := dwarf.DW_LANG_Go
- s := Ctxt.Textp[0]
+ s := ctxt.Textp[0]
- dwinfo = newdie(&dwroot, dwarf.DW_ABRV_COMPUNIT, "go", 0)
+ dwinfo = newdie(ctxt, &dwroot, dwarf.DW_ABRV_COMPUNIT, "go", 0)
newattr(dwinfo, dwarf.DW_AT_language, dwarf.DW_CLS_CONSTANT, int64(lang), 0)
newattr(dwinfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, 0, linesec)
newattr(dwinfo, dwarf.DW_AT_low_pc, dwarf.DW_CLS_ADDRESS, s.Value, s)
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
unit_length_offset := ls.Size
- Adduint32(Ctxt, ls, 0) // unit_length (*), filled in at end.
+ Adduint32(ctxt, ls, 0) // unit_length (*), filled in at end.
unitstart = ls.Size
- Adduint16(Ctxt, ls, 2) // dwarf version (appendix F)
+ Adduint16(ctxt, ls, 2) // dwarf version (appendix F)
header_length_offset := ls.Size
- Adduint32(Ctxt, ls, 0) // header_length (*), filled in at end.
+ Adduint32(ctxt, ls, 0) // header_length (*), filled in at end.
headerstart = ls.Size
// cpos == unitstart + 4 + 2 + 4
- Adduint8(Ctxt, ls, 1) // minimum_instruction_length
- Adduint8(Ctxt, ls, 1) // default_is_stmt
- Adduint8(Ctxt, ls, LINE_BASE&0xFF) // line_base
- Adduint8(Ctxt, ls, LINE_RANGE) // line_range
- Adduint8(Ctxt, ls, OPCODE_BASE) // opcode_base
- Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[1]
- Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[2]
- Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[3]
- Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[4]
- Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[5]
- Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[6]
- Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[7]
- Adduint8(Ctxt, ls, 0) // standard_opcode_lengths[8]
- Adduint8(Ctxt, ls, 1) // standard_opcode_lengths[9]
- Adduint8(Ctxt, ls, 0) // include_directories (empty)
-
- for _, f := range Ctxt.Filesyms {
- Addstring(ls, f.Name)
- Adduint8(Ctxt, ls, 0)
- Adduint8(Ctxt, ls, 0)
- Adduint8(Ctxt, ls, 0)
+ Adduint8(ctxt, ls, 1) // minimum_instruction_length
+ Adduint8(ctxt, ls, 1) // default_is_stmt
+ Adduint8(ctxt, ls, LINE_BASE&0xFF) // line_base
+ Adduint8(ctxt, ls, LINE_RANGE) // line_range
+ Adduint8(ctxt, ls, OPCODE_BASE) // opcode_base
+ Adduint8(ctxt, ls, 0) // standard_opcode_lengths[1]
+ Adduint8(ctxt, ls, 1) // standard_opcode_lengths[2]
+ Adduint8(ctxt, ls, 1) // standard_opcode_lengths[3]
+ Adduint8(ctxt, ls, 1) // standard_opcode_lengths[4]
+ Adduint8(ctxt, ls, 1) // standard_opcode_lengths[5]
+ Adduint8(ctxt, ls, 0) // standard_opcode_lengths[6]
+ Adduint8(ctxt, ls, 0) // standard_opcode_lengths[7]
+ Adduint8(ctxt, ls, 0) // standard_opcode_lengths[8]
+ Adduint8(ctxt, ls, 1) // standard_opcode_lengths[9]
+ Adduint8(ctxt, ls, 0) // include_directories (empty)
+
+ for _, f := range ctxt.Filesyms {
+ Addstring(ctxt, ls, f.Name)
+ Adduint8(ctxt, ls, 0)
+ Adduint8(ctxt, ls, 0)
+ Adduint8(ctxt, ls, 0)
}
// 4 zeros: the string termination + 3 fields.
- Adduint8(Ctxt, ls, 0)
+ Adduint8(ctxt, ls, 0)
// terminate file_names.
headerend = ls.Size
- Adduint8(Ctxt, ls, 0) // start extended opcode
+ Adduint8(ctxt, ls, 0) // start extended opcode
dwarf.Uleb128put(dwarfctxt, ls, 1+int64(SysArch.PtrSize))
- Adduint8(Ctxt, ls, dwarf.DW_LNE_set_address)
+ Adduint8(ctxt, ls, dwarf.DW_LNE_set_address)
pc := s.Value
line := 1
file := 1
- Addaddr(Ctxt, ls, s)
+ Addaddr(ctxt, ls, s)
var pcfile Pciter
var pcline Pciter
- for _, Ctxt.Cursym = range Ctxt.Textp {
- s := Ctxt.Cursym
+ for _, ctxt.Cursym = range ctxt.Textp {
+ s := ctxt.Cursym
epc = s.Value + s.Size
epcs = s
- dsym := Linklookup(Ctxt, dwarf.InfoPrefix+s.Name, int(s.Version))
+ dsym := Linklookup(ctxt, dwarf.InfoPrefix+s.Name, int(s.Version))
dsym.Attr |= AttrHidden
dsym.Type = obj.SDWARFINFO
for _, r := range dsym.R {
continue
}
n := nameFromDIESym(r.Sym)
- defgotype(Linklookup(Ctxt, "type."+n, 0))
+ defgotype(ctxt, Linklookup(ctxt, "type."+n, 0))
}
}
funcs = append(funcs, dsym)
finddebugruntimepath(s)
- pciterinit(Ctxt, &pcfile, &s.FuncInfo.Pcfile)
- pciterinit(Ctxt, &pcline, &s.FuncInfo.Pcline)
+ pciterinit(ctxt, &pcfile, &s.FuncInfo.Pcfile)
+ pciterinit(ctxt, &pcline, &s.FuncInfo.Pcline)
epc = pc
for pcfile.done == 0 && pcline.done == 0 {
if epc-s.Value >= int64(pcfile.nextpc) {
}
if int32(file) != pcfile.value {
- Adduint8(Ctxt, ls, dwarf.DW_LNS_set_file)
+ Adduint8(ctxt, ls, dwarf.DW_LNS_set_file)
dwarf.Uleb128put(dwarfctxt, ls, int64(pcfile.value))
file = int(pcfile.value)
}
- putpclcdelta(dwarfctxt, ls, s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
+ putpclcdelta(ctxt, dwarfctxt, ls, s.Value+int64(pcline.pc)-pc, int64(pcline.value)-int64(line))
pc = s.Value + int64(pcline.pc)
line = int(pcline.value)
}
}
- Adduint8(Ctxt, ls, 0) // start extended opcode
+ Adduint8(ctxt, ls, 0) // start extended opcode
dwarf.Uleb128put(dwarfctxt, ls, 1)
- Adduint8(Ctxt, ls, dwarf.DW_LNE_end_sequence)
+ Adduint8(ctxt, ls, dwarf.DW_LNE_end_sequence)
newattr(dwinfo, dwarf.DW_AT_high_pc, dwarf.DW_CLS_ADDRESS, epc+1, epcs)
- setuint32(Ctxt, ls, unit_length_offset, uint32(ls.Size-unitstart))
- setuint32(Ctxt, ls, header_length_offset, uint32(headerend-headerstart))
+ setuint32(ctxt, ls, unit_length_offset, uint32(ls.Size-unitstart))
+ setuint32(ctxt, ls, header_length_offset, uint32(headerend-headerstart))
return syms, funcs
}
return b
}
-func writeframes(syms []*Symbol) []*Symbol {
- var dwarfctxt dwarf.Context = dwCtxt{}
+func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
+ var dwarfctxt dwarf.Context = dwctxt{ctxt}
if framesec == nil {
- framesec = Linklookup(Ctxt, ".debug_frame", 0)
+ framesec = Linklookup(ctxt, ".debug_frame", 0)
}
framesec.Type = obj.SDWARFSECT
framesec.R = framesec.R[:0]
// Emit the CIE, Section 6.4.1
cieReserve := uint32(16)
- if haslinkregister() {
+ if haslinkregister(ctxt) {
cieReserve = 32
}
- Adduint32(Ctxt, fs, cieReserve) // initial length, must be multiple of thearch.ptrsize
- Adduint32(Ctxt, fs, 0xffffffff) // cid.
- Adduint8(Ctxt, fs, 3) // dwarf version (appendix F)
- Adduint8(Ctxt, fs, 0) // augmentation ""
+ Adduint32(ctxt, fs, cieReserve) // initial length, must be multiple of thearch.ptrsize
+ Adduint32(ctxt, fs, 0xffffffff) // cid.
+ Adduint8(ctxt, fs, 3) // dwarf version (appendix F)
+ Adduint8(ctxt, fs, 0) // augmentation ""
dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor
dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor) // all CFI offset calculations include multiplication with this factor
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // return_address_register
- Adduint8(Ctxt, fs, dwarf.DW_CFA_def_cfa) // Set the current frame address..
+ Adduint8(ctxt, fs, dwarf.DW_CFA_def_cfa) // Set the current frame address..
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
- if haslinkregister() {
+ if haslinkregister(ctxt) {
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset.
- Adduint8(Ctxt, fs, dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
+ Adduint8(ctxt, fs, dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr))
- Adduint8(Ctxt, fs, dwarf.DW_CFA_val_offset) // The previous value...
+ Adduint8(ctxt, fs, dwarf.DW_CFA_val_offset) // The previous value...
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...of the platform's SP register...
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...is CFA+0.
} else {
dwarf.Uleb128put(dwarfctxt, fs, int64(SysArch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
- Adduint8(Ctxt, fs, dwarf.DW_CFA_offset_extended) // The previous value...
+ Adduint8(ctxt, fs, dwarf.DW_CFA_offset_extended) // The previous value...
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // ...of the return address...
dwarf.Uleb128put(dwarfctxt, fs, int64(-SysArch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
}
Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
}
- Addbytes(Ctxt, fs, zeros[:pad])
+ Addbytes(ctxt, fs, zeros[:pad])
var deltaBuf []byte
var pcsp Pciter
- for _, Ctxt.Cursym = range Ctxt.Textp {
- s := Ctxt.Cursym
+ for _, ctxt.Cursym = range ctxt.Textp {
+ s := ctxt.Cursym
if s.FuncInfo == nil {
continue
}
// Emit a FDE, Section 6.4.1.
// First build the section contents into a byte buffer.
deltaBuf = deltaBuf[:0]
- for pciterinit(Ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
+ for pciterinit(ctxt, &pcsp, &s.FuncInfo.Pcsp); pcsp.done == 0; pciternext(&pcsp) {
nextpc := pcsp.nextpc
// pciterinit goes up to the end of the function,
}
}
- if haslinkregister() {
+ if haslinkregister(ctxt) {
// TODO(bryanpkc): This is imprecise. In general, the instruction
// that stores the return address to the stack frame is not the
// same one that allocates the frame.
// 4 bytes: Pointer to the CIE above, at offset 0
// ptrsize: initial location
// ptrsize: address range
- Adduint32(Ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself)
+ Adduint32(ctxt, fs, uint32(4+2*SysArch.PtrSize+len(deltaBuf))) // length (excludes itself)
if Linkmode == LinkExternal {
- adddwarfref(Ctxt, fs, framesec, 4)
+ adddwarfref(ctxt, fs, framesec, 4)
} else {
- Adduint32(Ctxt, fs, 0) // CIE offset
+ Adduint32(ctxt, fs, 0) // CIE offset
}
- Addaddr(Ctxt, fs, s)
- adduintxx(Ctxt, fs, uint64(s.Size), SysArch.PtrSize) // address range
- Addbytes(Ctxt, fs, deltaBuf)
+ Addaddr(ctxt, fs, s)
+ adduintxx(ctxt, fs, uint64(s.Size), SysArch.PtrSize) // address range
+ Addbytes(ctxt, fs, deltaBuf)
}
return syms
}
COMPUNITHEADERSIZE = 4 + 2 + 4 + 1
)
-func writeinfo(syms []*Symbol, funcs []*Symbol) []*Symbol {
+func writeinfo(ctxt *Link, syms []*Symbol, funcs []*Symbol) []*Symbol {
if infosec == nil {
- infosec = Linklookup(Ctxt, ".debug_info", 0)
+ infosec = Linklookup(ctxt, ".debug_info", 0)
}
infosec.R = infosec.R[:0]
infosec.Type = obj.SDWARFINFO
syms = append(syms, infosec)
if arangessec == nil {
- arangessec = Linklookup(Ctxt, ".dwarfaranges", 0)
+ arangessec = Linklookup(ctxt, ".dwarfaranges", 0)
}
arangessec.R = arangessec.R[:0]
- var dwarfctxt dwarf.Context = dwCtxt{}
+ var dwarfctxt dwarf.Context = dwctxt{ctxt}
for compunit := dwroot.Child; compunit != nil; compunit = compunit.Link {
s := dtolsym(compunit.Sym)
// Write .debug_info Compilation Unit Header (sec 7.5.1)
// Fields marked with (*) must be changed for 64-bit dwarf
// This must match COMPUNITHEADERSIZE above.
- Adduint32(Ctxt, s, 0) // unit_length (*), will be filled in later.
- Adduint16(Ctxt, s, 2) // dwarf version (appendix F)
+ Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
+ Adduint16(ctxt, s, 2) // dwarf version (appendix F)
// debug_abbrev_offset (*)
- adddwarfref(Ctxt, s, abbrevsym, 4)
+ adddwarfref(ctxt, s, abbrevsym, 4)
- Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size
+ Adduint8(ctxt, s, uint8(SysArch.PtrSize)) // address_size
dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
cu = append(cu, funcs...)
funcs = nil
}
- cu = putdies(dwarfctxt, cu, compunit.Child)
+ cu = putdies(ctxt, dwarfctxt, cu, compunit.Child)
var cusize int64
for _, child := range cu {
cusize += child.Size
}
cusize -= 4 // exclude the length field.
- setuint32(Ctxt, s, 0, uint32(cusize))
+ setuint32(ctxt, s, 0, uint32(cusize))
newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0)
syms = append(syms, cu...)
}
return die.Abbrev >= dwarf.DW_ABRV_NULLTYPE
}
-func writepub(sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Symbol {
- s := Linklookup(Ctxt, sname, 0)
+func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Symbol {
+ s := Linklookup(ctxt, sname, 0)
s.Type = obj.SDWARFSECT
syms = append(syms, s)
culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
// Write .debug_pubnames/types Header (sec 6.1.1)
- Adduint32(Ctxt, s, 0) // unit_length (*), will be filled in later.
- Adduint16(Ctxt, s, 2) // dwarf version (appendix F)
- adddwarfref(Ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header)
- Adduint32(Ctxt, s, culength) // debug_info_length
+ Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
+ Adduint16(ctxt, s, 2) // dwarf version (appendix F)
+ adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header)
+ Adduint32(ctxt, s, culength) // debug_info_length
for die := compunit.Child; die != nil; die = die.Link {
if !ispub(die) {
if die.Sym == nil {
fmt.Println("Missing sym for ", name)
}
- adddwarfref(Ctxt, s, dtolsym(die.Sym), 4)
- Addstring(s, name)
+ adddwarfref(ctxt, s, dtolsym(die.Sym), 4)
+ Addstring(ctxt, s, name)
}
- Adduint32(Ctxt, s, 0)
+ Adduint32(ctxt, s, 0)
- setuint32(Ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
+ setuint32(ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
}
return syms
* emit .debug_aranges. _info must have been written before,
* because we need die->offs of dwarf.DW_globals.
*/
-func writearanges(syms []*Symbol) []*Symbol {
- s := Linklookup(Ctxt, ".debug_aranges", 0)
+func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
+ s := Linklookup(ctxt, ".debug_aranges", 0)
s.Type = obj.SDWARFSECT
// The first tuple is aligned to a multiple of the size of a single tuple
// (twice the size of an address)
// Write .debug_aranges Header + entry (sec 6.1.2)
unitlength := uint32(headersize) + 4*uint32(SysArch.PtrSize) - 4
- Adduint32(Ctxt, s, unitlength) // unit_length (*)
- Adduint16(Ctxt, s, 2) // dwarf version (appendix F)
+ Adduint32(ctxt, s, unitlength) // unit_length (*)
+ Adduint16(ctxt, s, 2) // dwarf version (appendix F)
- adddwarfref(Ctxt, s, dtolsym(compunit.Sym), 4)
+ adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4)
- Adduint8(Ctxt, s, uint8(SysArch.PtrSize)) // address_size
- Adduint8(Ctxt, s, 0) // segment_size
+ Adduint8(ctxt, s, uint8(SysArch.PtrSize)) // address_size
+ Adduint8(ctxt, s, 0) // segment_size
padding := headersize - (4 + 2 + 4 + 1 + 1)
for i := 0; i < padding; i++ {
- Adduint8(Ctxt, s, 0)
+ Adduint8(ctxt, s, 0)
}
- Addaddrplus(Ctxt, s, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
- adduintxx(Ctxt, s, uint64(e.Value-b.Value), SysArch.PtrSize)
- adduintxx(Ctxt, s, 0, SysArch.PtrSize)
- adduintxx(Ctxt, s, 0, SysArch.PtrSize)
+ Addaddrplus(ctxt, s, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
+ adduintxx(ctxt, s, uint64(e.Value-b.Value), SysArch.PtrSize)
+ adduintxx(ctxt, s, 0, SysArch.PtrSize)
+ adduintxx(ctxt, s, 0, SysArch.PtrSize)
}
if s.Size > 0 {
syms = append(syms, s)
return syms
}
-func writegdbscript(syms []*Symbol) []*Symbol {
+func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol {
if gdbscript != "" {
- s := Linklookup(Ctxt, ".debug_gdb_scripts", 0)
+ s := Linklookup(ctxt, ".debug_gdb_scripts", 0)
s.Type = obj.SDWARFSECT
syms = append(syms, s)
- Adduint8(Ctxt, s, 1) // magic 1 byte?
- Addstring(s, gdbscript)
+ Adduint8(ctxt, s, 1) // magic 1 byte?
+ Addstring(ctxt, s, gdbscript)
}
return syms
* passes.
*
*/
-func dwarfgeneratedebugsyms() {
+func dwarfgeneratedebugsyms(ctxt *Link) {
if Debug['w'] != 0 { // disable dwarf
return
}
fmt.Fprintf(Bso, "%5.2f dwarf\n", obj.Cputime())
}
- // For diagnostic messages.
+ // Forctxt.Diagnostic messages.
newattr(&dwtypes, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len("dwtypes")), "dwtypes")
// Some types that must exist to define other ones.
- newdie(&dwtypes, dwarf.DW_ABRV_NULLTYPE, "<unspecified>", 0)
+ newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "<unspecified>", 0)
- newdie(&dwtypes, dwarf.DW_ABRV_NULLTYPE, "void", 0)
- newdie(&dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0)
+ newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "void", 0)
+ newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0)
- die := newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
+ die := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0)
newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, obj.KindUintptr, 0)
}
// Needed by the prettyprinter code for interface inspection.
- defgotype(lookup_or_diag("type.runtime._type"))
+ defgotype(ctxt, lookup_or_diag(ctxt, "type.runtime._type"))
- defgotype(lookup_or_diag("type.runtime.interfacetype"))
- defgotype(lookup_or_diag("type.runtime.itab"))
+ defgotype(ctxt, lookup_or_diag(ctxt, "type.runtime.interfacetype"))
+ defgotype(ctxt, lookup_or_diag(ctxt, "type.runtime.itab"))
- genasmsym(defdwsymb)
+ genasmsym(ctxt, defdwsymb)
- syms := writeabbrev(nil)
- syms, funcs := writelines(syms)
- syms = writeframes(syms)
+ syms := writeabbrev(ctxt, nil)
+ syms, funcs := writelines(ctxt, syms)
+ syms = writeframes(ctxt, syms)
- synthesizestringtypes(dwtypes.Child)
- synthesizeslicetypes(dwtypes.Child)
- synthesizemaptypes(dwtypes.Child)
- synthesizechantypes(dwtypes.Child)
+ synthesizestringtypes(ctxt, dwtypes.Child)
+ synthesizeslicetypes(ctxt, dwtypes.Child)
+ synthesizemaptypes(ctxt, dwtypes.Child)
+ synthesizechantypes(ctxt, dwtypes.Child)
reversetree(&dwroot.Child)
reversetree(&dwtypes.Child)
// Need to reorder symbols so SDWARFINFO is after all SDWARFSECT
// (but we need to generate dies before writepub)
- infosyms := writeinfo(nil, funcs)
+ infosyms := writeinfo(ctxt, nil, funcs)
- syms = writepub(".debug_pubnames", ispubname, syms)
- syms = writepub(".debug_pubtypes", ispubtype, syms)
- syms = writearanges(syms)
- syms = writegdbscript(syms)
+ syms = writepub(ctxt, ".debug_pubnames", ispubname, syms)
+ syms = writepub(ctxt, ".debug_pubtypes", ispubtype, syms)
+ syms = writearanges(ctxt, syms)
+ syms = writegdbscript(ctxt, syms)
syms = append(syms, infosyms...)
dwarfp = syms[0]
for i := 1; i < len(syms); i++ {
/*
* Elf.
*/
-func dwarfaddshstrings(shstrtab *Symbol) {
+func dwarfaddshstrings(ctxt *Link, shstrtab *Symbol) {
if Debug['w'] != 0 { // disable dwarf
return
}
- Addstring(shstrtab, ".debug_abbrev")
- Addstring(shstrtab, ".debug_aranges")
- Addstring(shstrtab, ".debug_frame")
- Addstring(shstrtab, ".debug_info")
- Addstring(shstrtab, ".debug_line")
- Addstring(shstrtab, ".debug_pubnames")
- Addstring(shstrtab, ".debug_pubtypes")
- Addstring(shstrtab, ".debug_gdb_scripts")
+ Addstring(ctxt, shstrtab, ".debug_abbrev")
+ Addstring(ctxt, shstrtab, ".debug_aranges")
+ Addstring(ctxt, shstrtab, ".debug_frame")
+ Addstring(ctxt, shstrtab, ".debug_info")
+ Addstring(ctxt, shstrtab, ".debug_line")
+ Addstring(ctxt, shstrtab, ".debug_pubnames")
+ Addstring(ctxt, shstrtab, ".debug_pubtypes")
+ Addstring(ctxt, shstrtab, ".debug_gdb_scripts")
if Linkmode == LinkExternal {
- Addstring(shstrtab, elfRelType+".debug_info")
- Addstring(shstrtab, elfRelType+".debug_aranges")
- Addstring(shstrtab, elfRelType+".debug_line")
- Addstring(shstrtab, elfRelType+".debug_frame")
- Addstring(shstrtab, elfRelType+".debug_pubnames")
- Addstring(shstrtab, elfRelType+".debug_pubtypes")
+ Addstring(ctxt, shstrtab, elfRelType+".debug_info")
+ Addstring(ctxt, shstrtab, elfRelType+".debug_aranges")
+ Addstring(ctxt, shstrtab, elfRelType+".debug_line")
+ Addstring(ctxt, shstrtab, elfRelType+".debug_frame")
+ Addstring(ctxt, shstrtab, elfRelType+".debug_pubnames")
+ Addstring(ctxt, shstrtab, elfRelType+".debug_pubtypes")
}
}
// Add section symbols for DWARF debug info. This is called before
// dwarfaddelfheaders.
-func dwarfaddelfsectionsyms() {
+func dwarfaddelfsectionsyms(ctxt *Link) {
if Debug['w'] != 0 { // disable dwarf
return
}
if Linkmode != LinkExternal {
return
}
- sym := Linklookup(Ctxt, ".debug_info", 0)
+ sym := Linklookup(ctxt, ".debug_info", 0)
putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
- sym = Linklookup(Ctxt, ".debug_abbrev", 0)
+ sym = Linklookup(ctxt, ".debug_abbrev", 0)
putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
- sym = Linklookup(Ctxt, ".debug_line", 0)
+ sym = Linklookup(ctxt, ".debug_line", 0)
putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
- sym = Linklookup(Ctxt, ".debug_frame", 0)
+ sym = Linklookup(ctxt, ".debug_frame", 0)
putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
}
/*
* Windows PE
*/
-func dwarfaddpeheaders() {
+func dwarfaddpeheaders(ctxt *Link) {
if Debug['w'] != 0 { // disable dwarf
return
}
for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
- h := newPEDWARFSection(sect.Name, int64(sect.Length))
+ h := newPEDWARFSection(ctxt, sect.Name, int64(sect.Length))
fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff
if uint64(h.PointerToRawData) != fileoff {
- Diag("%s.PointerToRawData = %#x, want %#x", sect.Name, h.PointerToRawData, fileoff)
+ ctxt.Diag("%s.PointerToRawData = %#x, want %#x", sect.Name, h.PointerToRawData, fileoff)
errorexit()
}
}
Initialize the global variable that describes the ELF header. It will be updated as
we write section and prog headers.
*/
-func Elfinit() {
+func Elfinit(ctxt *Link) {
Iself = true
if SysArch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
switch SysArch.Family {
// 64-bit architectures
case sys.PPC64, sys.S390X:
- if Ctxt.Arch.ByteOrder == binary.BigEndian {
+ if ctxt.Arch.ByteOrder == binary.BigEndian {
ehdr.flags = 1 /* Version 1 ABI */
} else {
ehdr.flags = 2 /* Version 2 ABI */
return uint32(ehdr.shnum) * ELF32SHDRSIZE
}
-func elfsetstring(s string, off int) {
+func elfsetstring(ctxt *Link, s string, off int) {
if nelfstr >= len(elfstr) {
- Diag("too many elf strings")
+ ctxt.Diag("too many elf strings")
errorexit()
}
return uint32(ehdr.phnum) * ELF32PHDRSIZE
}
-func newElfPhdr() *ElfPhdr {
+func newElfPhdr(ctxt *Link) *ElfPhdr {
e := new(ElfPhdr)
if ehdr.phnum >= NSECT {
- Diag("too many phdrs")
+ ctxt.Diag("too many phdrs")
} else {
phdr[ehdr.phnum] = e
ehdr.phnum++
return e
}
-func newElfShdr(name int64) *ElfShdr {
+func newElfShdr(ctxt *Link, name int64) *ElfShdr {
e := new(ElfShdr)
e.name = uint32(name)
e.shnum = int(ehdr.shnum)
if ehdr.shnum >= NSECT {
- Diag("too many shdrs")
+ ctxt.Diag("too many shdrs")
} else {
shdr[ehdr.shnum] = e
ehdr.shnum++
return h
}
-func Elfwritedynent(s *Symbol, tag int, val uint64) {
+func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
if elf64 {
- Adduint64(Ctxt, s, uint64(tag))
- Adduint64(Ctxt, s, val)
+ Adduint64(ctxt, s, uint64(tag))
+ Adduint64(ctxt, s, val)
} else {
- Adduint32(Ctxt, s, uint32(tag))
- Adduint32(Ctxt, s, uint32(val))
+ Adduint32(ctxt, s, uint32(tag))
+ Adduint32(ctxt, s, uint32(val))
}
}
-func elfwritedynentsym(s *Symbol, tag int, t *Symbol) {
- Elfwritedynentsymplus(s, tag, t, 0)
+func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) {
+ Elfwritedynentsymplus(ctxt, s, tag, t, 0)
}
-func Elfwritedynentsymplus(s *Symbol, tag int, t *Symbol, add int64) {
+func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
if elf64 {
- Adduint64(Ctxt, s, uint64(tag))
+ Adduint64(ctxt, s, uint64(tag))
} else {
- Adduint32(Ctxt, s, uint32(tag))
+ Adduint32(ctxt, s, uint32(tag))
}
- Addaddrplus(Ctxt, s, t, add)
+ Addaddrplus(ctxt, s, t, add)
}
-func elfwritedynentsymsize(s *Symbol, tag int, t *Symbol) {
+func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
if elf64 {
- Adduint64(Ctxt, s, uint64(tag))
+ Adduint64(ctxt, s, uint64(tag))
} else {
- Adduint32(Ctxt, s, uint32(tag))
+ Adduint32(ctxt, s, uint32(tag))
}
- addsize(Ctxt, s, t)
+ addsize(ctxt, s, t)
}
func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
return n
}
-func elfwriteinterp() int {
- sh := elfshname(".interp")
+func elfwriteinterp(ctxt *Link) int {
+ sh := elfshname(ctxt, ".interp")
Cseek(int64(sh.off))
coutbuf.WriteString(interp)
Cput(0)
return int(n)
}
-func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
- sh := elfshname(str)
+func elfwritenotehdr(ctxt *Link, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
+ sh := elfshname(ctxt, str)
// Write Elf_Note header.
Cseek(int64(sh.off))
return elfnote(sh, startva, resoff, n, true)
}
-func elfwritenetbsdsig() int {
+func elfwritenetbsdsig(ctxt *Link) int {
// Write Elf_Note header.
- sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
+ sh := elfwritenotehdr(ctxt, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
if sh == nil {
return 0
return elfnote(sh, startva, resoff, n, true)
}
-func elfwriteopenbsdsig() int {
+func elfwriteopenbsdsig(ctxt *Link) int {
// Write Elf_Note header.
- sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
+ sh := elfwritenotehdr(ctxt, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
if sh == nil {
return 0
return elfnote(sh, startva, resoff, n, true)
}
-func elfwritebuildinfo() int {
- sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
+func elfwritebuildinfo(ctxt *Link) int {
+ sh := elfwritenotehdr(ctxt, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
if sh == nil {
return 0
}
return int(sh.size)
}
-func elfwritegobuildid() int {
- sh := elfwritenotehdr(".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(buildid)), ELF_NOTE_GOBUILDID_TAG)
+func elfwritegobuildid(ctxt *Link) int {
+ sh := elfwritenotehdr(ctxt, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(buildid)), ELF_NOTE_GOBUILDID_TAG)
if sh == nil {
return 0
}
return aux
}
-func elfdynhash() {
+func elfdynhash(ctxt *Link) {
if !Iself {
return
}
nsym := Nelfsym
- s := Linklookup(Ctxt, ".hash", 0)
+ s := Linklookup(ctxt, ".hash", 0)
s.Type = obj.SELFROSECT
s.Attr |= AttrReachable
buckets := make([]uint32, nbucket)
var b int
- for _, sy := range Ctxt.Allsym {
+ for _, sy := range ctxt.Allsym {
if sy.Dynid <= 0 {
continue
}
// s390x (ELF64) hash table entries are 8 bytes
if SysArch.Family == sys.S390X {
- Adduint64(Ctxt, s, uint64(nbucket))
- Adduint64(Ctxt, s, uint64(nsym))
+ Adduint64(ctxt, s, uint64(nbucket))
+ Adduint64(ctxt, s, uint64(nsym))
for i := 0; i < nbucket; i++ {
- Adduint64(Ctxt, s, uint64(buckets[i]))
+ Adduint64(ctxt, s, uint64(buckets[i]))
}
for i := 0; i < nsym; i++ {
- Adduint64(Ctxt, s, uint64(chain[i]))
+ Adduint64(ctxt, s, uint64(chain[i]))
}
} else {
- Adduint32(Ctxt, s, uint32(nbucket))
- Adduint32(Ctxt, s, uint32(nsym))
+ Adduint32(ctxt, s, uint32(nbucket))
+ Adduint32(ctxt, s, uint32(nsym))
for i := 0; i < nbucket; i++ {
- Adduint32(Ctxt, s, buckets[i])
+ Adduint32(ctxt, s, buckets[i])
}
for i := 0; i < nsym; i++ {
- Adduint32(Ctxt, s, chain[i])
+ Adduint32(ctxt, s, chain[i])
}
}
// version symbols
- dynstr := Linklookup(Ctxt, ".dynstr", 0)
+ dynstr := Linklookup(ctxt, ".dynstr", 0)
- s = Linklookup(Ctxt, ".gnu.version_r", 0)
+ s = Linklookup(ctxt, ".gnu.version_r", 0)
i = 2
nfile := 0
var j int
nfile++
// header
- Adduint16(Ctxt, s, 1) // table version
+ Adduint16(ctxt, s, 1) // table version
j = 0
for x = l.aux; x != nil; x = x.next {
j++
}
- Adduint16(Ctxt, s, uint16(j)) // aux count
- Adduint32(Ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
- Adduint32(Ctxt, s, 16) // offset from header to first aux
+ Adduint16(ctxt, s, uint16(j)) // aux count
+ Adduint32(ctxt, s, uint32(Addstring(ctxt, dynstr, l.file))) // file string offset
+ Adduint32(ctxt, s, 16) // offset from header to first aux
if l.next != nil {
- Adduint32(Ctxt, s, 16+uint32(j)*16) // offset from this header to next
+ Adduint32(ctxt, s, 16+uint32(j)*16) // offset from this header to next
} else {
- Adduint32(Ctxt, s, 0)
+ Adduint32(ctxt, s, 0)
}
for x = l.aux; x != nil; x = x.next {
i++
// aux struct
- Adduint32(Ctxt, s, elfhash(x.vers)) // hash
- Adduint16(Ctxt, s, 0) // flags
- Adduint16(Ctxt, s, uint16(x.num)) // other - index we refer to this by
- Adduint32(Ctxt, s, uint32(Addstring(dynstr, x.vers))) // version string offset
+ Adduint32(ctxt, s, elfhash(x.vers)) // hash
+ Adduint16(ctxt, s, 0) // flags
+ Adduint16(ctxt, s, uint16(x.num)) // other - index we refer to this by
+ Adduint32(ctxt, s, uint32(Addstring(ctxt, dynstr, x.vers))) // version string offset
if x.next != nil {
- Adduint32(Ctxt, s, 16) // offset from this aux to next
+ Adduint32(ctxt, s, 16) // offset from this aux to next
} else {
- Adduint32(Ctxt, s, 0)
+ Adduint32(ctxt, s, 0)
}
}
}
// version references
- s = Linklookup(Ctxt, ".gnu.version", 0)
+ s = Linklookup(ctxt, ".gnu.version", 0)
for i := 0; i < nsym; i++ {
if i == 0 {
- Adduint16(Ctxt, s, 0) // first entry - no symbol
+ Adduint16(ctxt, s, 0) // first entry - no symbol
} else if need[i] == nil {
- Adduint16(Ctxt, s, 1) // global
+ Adduint16(ctxt, s, 1) // global
} else {
- Adduint16(Ctxt, s, uint16(need[i].num))
+ Adduint16(ctxt, s, uint16(need[i].num))
}
}
- s = Linklookup(Ctxt, ".dynamic", 0)
+ s = Linklookup(ctxt, ".dynamic", 0)
elfverneed = nfile
if elfverneed != 0 {
- elfwritedynentsym(s, DT_VERNEED, Linklookup(Ctxt, ".gnu.version_r", 0))
- Elfwritedynent(s, DT_VERNEEDNUM, uint64(nfile))
- elfwritedynentsym(s, DT_VERSYM, Linklookup(Ctxt, ".gnu.version", 0))
+ elfwritedynentsym(ctxt, s, DT_VERNEED, Linklookup(ctxt, ".gnu.version_r", 0))
+ Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile))
+ elfwritedynentsym(ctxt, s, DT_VERSYM, Linklookup(ctxt, ".gnu.version", 0))
}
- sy := Linklookup(Ctxt, elfRelType+".plt", 0)
+ sy := Linklookup(ctxt, elfRelType+".plt", 0)
if sy.Size > 0 {
if elfRelType == ".rela" {
- Elfwritedynent(s, DT_PLTREL, DT_RELA)
+ Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA)
} else {
- Elfwritedynent(s, DT_PLTREL, DT_REL)
+ Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL)
}
- elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
- elfwritedynentsym(s, DT_JMPREL, sy)
+ elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy)
+ elfwritedynentsym(ctxt, s, DT_JMPREL, sy)
}
- Elfwritedynent(s, DT_NULL, 0)
+ Elfwritedynent(ctxt, s, DT_NULL, 0)
}
-func elfphload(seg *Segment) *ElfPhdr {
- ph := newElfPhdr()
+func elfphload(ctxt *Link, seg *Segment) *ElfPhdr {
+ ph := newElfPhdr(ctxt)
ph.type_ = PT_LOAD
if seg.Rwx&4 != 0 {
ph.flags |= PF_R
return ph
}
-func elfshname(name string) *ElfShdr {
+func elfshname(ctxt *Link, name string) *ElfShdr {
var off int
var sh *ElfShdr
}
}
- sh = newElfShdr(int64(off))
+ sh = newElfShdr(ctxt, int64(off))
return sh
}
}
- Diag("cannot find elf name %s", name)
+ ctxt.Diag("cannot find elf name %s", name)
errorexit()
return nil
}
-func elfshalloc(sect *Section) *ElfShdr {
- sh := elfshname(sect.Name)
+func elfshalloc(ctxt *Link, sect *Section) *ElfShdr {
+ sh := elfshname(ctxt, sect.Name)
sect.Elfsect = sh
return sh
}
-func elfshbits(sect *Section) *ElfShdr {
- sh := elfshalloc(sect)
+func elfshbits(ctxt *Link, sect *Section) *ElfShdr {
+ sh := elfshalloc(ctxt, sect)
// If this section has already been set up as a note, we assume type_ and
// flags are already correct, but the other fields still need filling in.
if sh.type_ == SHT_NOTE {
// list note). The real fix is probably to define new values
// for LSym.Type corresponding to mapped and unmapped notes
// and handle them in dodata().
- Diag("sh.type_ == SHT_NOTE in elfshbits when linking internally")
+ ctxt.Diag("sh.type_ == SHT_NOTE in elfshbits when linking internally")
}
sh.addralign = uint64(sect.Align)
sh.size = sect.Length
return sh
}
-func elfshreloc(sect *Section) *ElfShdr {
+func elfshreloc(ctxt *Link, sect *Section) *ElfShdr {
// If main section is SHT_NOBITS, nothing to relocate.
// Also nothing to relocate in .shstrtab or notes.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
typ = SHT_REL
}
- sh := elfshname(elfRelType + sect.Name)
+ sh := elfshname(ctxt, elfRelType+sect.Name)
sh.type_ = uint32(typ)
sh.entsize = uint64(SysArch.RegSize) * 2
if typ == SHT_RELA {
sh.entsize += uint64(SysArch.RegSize)
}
- sh.link = uint32(elfshname(".symtab").shnum)
+ sh.link = uint32(elfshname(ctxt, ".symtab").shnum)
sh.info = uint32(sect.Elfsect.shnum)
sh.off = sect.Reloff
sh.size = sect.Rellen
return sh
}
-func elfrelocsect(sect *Section, syms []*Symbol) {
+func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
// If main section is SHT_NOBITS, nothing to relocate.
// Also nothing to relocate in .shstrtab.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
if sym.Value >= int64(eaddr) {
break
}
- Ctxt.Cursym = sym
+ ctxt.Cursym = sym
for ri := 0; ri < len(sym.R); ri++ {
r := &sym.R[ri]
continue
}
if r.Xsym == nil {
- Diag("missing xsym in relocation")
+ ctxt.Diag("missing xsym in relocation")
continue
}
if r.Xsym.ElfsymForReloc() == 0 {
- Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
+ ctxt.Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
}
if Thearch.Elfreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
- Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
+ ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
}
}
}
sect.Rellen = uint64(Cpos()) - sect.Reloff
}
-func Elfemitreloc() {
+func Elfemitreloc(ctxt *Link) {
for Cpos()&7 != 0 {
Cput(0)
}
- elfrelocsect(Segtext.Sect, Ctxt.Textp)
+ elfrelocsect(ctxt, Segtext.Sect, ctxt.Textp)
for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
- elfrelocsect(sect, datap)
+ elfrelocsect(ctxt, sect, datap)
}
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
- elfrelocsect(sect, datap)
+ elfrelocsect(ctxt, sect, datap)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- elfrelocsect(sect, datap)
+ elfrelocsect(ctxt, sect, datap)
}
for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
- elfrelocsect(sect, list2slice(dwarfp))
+ elfrelocsect(ctxt, sect, list2slice(dwarfp))
}
}
-func addgonote(sectionName string, tag uint32, desc []byte) {
- s := Linklookup(Ctxt, sectionName, 0)
+func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
+ s := Linklookup(ctxt, sectionName, 0)
s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
// namesz
- Adduint32(Ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
+ Adduint32(ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
// descsz
- Adduint32(Ctxt, s, uint32(len(desc)))
+ Adduint32(ctxt, s, uint32(len(desc)))
// tag
- Adduint32(Ctxt, s, tag)
+ Adduint32(ctxt, s, tag)
// name + padding
s.P = append(s.P, ELF_NOTE_GO_NAME...)
for len(s.P)%4 != 0 {
s.Size = int64(len(s.P))
}
-func doelf() {
+func (ctxt *Link) doelf() {
if !Iself {
return
}
/* predefine strings we need for section headers */
- shstrtab := Linklookup(Ctxt, ".shstrtab", 0)
+ shstrtab := Linklookup(ctxt, ".shstrtab", 0)
shstrtab.Type = obj.SELFROSECT
shstrtab.Attr |= AttrReachable
- Addstring(shstrtab, "")
- Addstring(shstrtab, ".text")
- Addstring(shstrtab, ".noptrdata")
- Addstring(shstrtab, ".data")
- Addstring(shstrtab, ".bss")
- Addstring(shstrtab, ".noptrbss")
+ Addstring(ctxt, shstrtab, "")
+ Addstring(ctxt, shstrtab, ".text")
+ Addstring(ctxt, shstrtab, ".noptrdata")
+ Addstring(ctxt, shstrtab, ".data")
+ Addstring(ctxt, shstrtab, ".bss")
+ Addstring(ctxt, shstrtab, ".noptrbss")
// generate .tbss section (except for OpenBSD where it's not supported)
// for dynamic internal linker or external linking, so that various
// see https://golang.org/issue/5200.
if HEADTYPE != obj.Hopenbsd {
if Debug['d'] == 0 || Linkmode == LinkExternal {
- Addstring(shstrtab, ".tbss")
+ Addstring(ctxt, shstrtab, ".tbss")
}
}
if HEADTYPE == obj.Hnetbsd {
- Addstring(shstrtab, ".note.netbsd.ident")
+ Addstring(ctxt, shstrtab, ".note.netbsd.ident")
}
if HEADTYPE == obj.Hopenbsd {
- Addstring(shstrtab, ".note.openbsd.ident")
+ Addstring(ctxt, shstrtab, ".note.openbsd.ident")
}
if len(buildinfo) > 0 {
- Addstring(shstrtab, ".note.gnu.build-id")
+ Addstring(ctxt, shstrtab, ".note.gnu.build-id")
}
if buildid != "" {
- Addstring(shstrtab, ".note.go.buildid")
+ Addstring(ctxt, shstrtab, ".note.go.buildid")
}
- Addstring(shstrtab, ".elfdata")
- Addstring(shstrtab, ".rodata")
+ Addstring(ctxt, shstrtab, ".elfdata")
+ Addstring(ctxt, shstrtab, ".rodata")
// See the comment about data.rel.ro.FOO section names in data.go.
relro_prefix := ""
if UseRelro() {
- Addstring(shstrtab, ".data.rel.ro")
+ Addstring(ctxt, shstrtab, ".data.rel.ro")
relro_prefix = ".data.rel.ro"
}
- Addstring(shstrtab, relro_prefix+".typelink")
- Addstring(shstrtab, relro_prefix+".itablink")
- Addstring(shstrtab, relro_prefix+".gosymtab")
- Addstring(shstrtab, relro_prefix+".gopclntab")
+ Addstring(ctxt, shstrtab, relro_prefix+".typelink")
+ Addstring(ctxt, shstrtab, relro_prefix+".itablink")
+ Addstring(ctxt, shstrtab, relro_prefix+".gosymtab")
+ Addstring(ctxt, shstrtab, relro_prefix+".gopclntab")
if Linkmode == LinkExternal {
Debug['d'] = 1
- Addstring(shstrtab, elfRelType+".text")
- Addstring(shstrtab, elfRelType+".rodata")
- Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
- Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
- Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
- Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
- Addstring(shstrtab, elfRelType+".noptrdata")
- Addstring(shstrtab, elfRelType+".data")
+ Addstring(ctxt, shstrtab, elfRelType+".text")
+ Addstring(ctxt, shstrtab, elfRelType+".rodata")
+ Addstring(ctxt, shstrtab, elfRelType+relro_prefix+".typelink")
+ Addstring(ctxt, shstrtab, elfRelType+relro_prefix+".itablink")
+ Addstring(ctxt, shstrtab, elfRelType+relro_prefix+".gosymtab")
+ Addstring(ctxt, shstrtab, elfRelType+relro_prefix+".gopclntab")
+ Addstring(ctxt, shstrtab, elfRelType+".noptrdata")
+ Addstring(ctxt, shstrtab, elfRelType+".data")
if UseRelro() {
- Addstring(shstrtab, elfRelType+".data.rel.ro")
+ Addstring(ctxt, shstrtab, elfRelType+".data.rel.ro")
}
// add a .note.GNU-stack section to mark the stack as non-executable
- Addstring(shstrtab, ".note.GNU-stack")
+ Addstring(ctxt, shstrtab, ".note.GNU-stack")
if Buildmode == BuildmodeShared {
- Addstring(shstrtab, ".note.go.abihash")
- Addstring(shstrtab, ".note.go.pkg-list")
- Addstring(shstrtab, ".note.go.deps")
+ Addstring(ctxt, shstrtab, ".note.go.abihash")
+ Addstring(ctxt, shstrtab, ".note.go.pkg-list")
+ Addstring(ctxt, shstrtab, ".note.go.deps")
}
}
}
if hasinitarr {
- Addstring(shstrtab, ".init_array")
- Addstring(shstrtab, elfRelType+".init_array")
+ Addstring(ctxt, shstrtab, ".init_array")
+ Addstring(ctxt, shstrtab, elfRelType+".init_array")
}
if Debug['s'] == 0 {
- Addstring(shstrtab, ".symtab")
- Addstring(shstrtab, ".strtab")
- dwarfaddshstrings(shstrtab)
+ Addstring(ctxt, shstrtab, ".symtab")
+ Addstring(ctxt, shstrtab, ".strtab")
+ dwarfaddshstrings(ctxt, shstrtab)
}
- Addstring(shstrtab, ".shstrtab")
+ Addstring(ctxt, shstrtab, ".shstrtab")
if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
- Addstring(shstrtab, ".interp")
- Addstring(shstrtab, ".hash")
- Addstring(shstrtab, ".got")
+ Addstring(ctxt, shstrtab, ".interp")
+ Addstring(ctxt, shstrtab, ".hash")
+ Addstring(ctxt, shstrtab, ".got")
if SysArch.Family == sys.PPC64 {
- Addstring(shstrtab, ".glink")
+ Addstring(ctxt, shstrtab, ".glink")
}
- Addstring(shstrtab, ".got.plt")
- Addstring(shstrtab, ".dynamic")
- Addstring(shstrtab, ".dynsym")
- Addstring(shstrtab, ".dynstr")
- Addstring(shstrtab, elfRelType)
- Addstring(shstrtab, elfRelType+".plt")
+ Addstring(ctxt, shstrtab, ".got.plt")
+ Addstring(ctxt, shstrtab, ".dynamic")
+ Addstring(ctxt, shstrtab, ".dynsym")
+ Addstring(ctxt, shstrtab, ".dynstr")
+ Addstring(ctxt, shstrtab, elfRelType)
+ Addstring(ctxt, shstrtab, elfRelType+".plt")
- Addstring(shstrtab, ".plt")
- Addstring(shstrtab, ".gnu.version")
- Addstring(shstrtab, ".gnu.version_r")
+ Addstring(ctxt, shstrtab, ".plt")
+ Addstring(ctxt, shstrtab, ".gnu.version")
+ Addstring(ctxt, shstrtab, ".gnu.version_r")
/* dynamic symbol table - first entry all zeros */
- s := Linklookup(Ctxt, ".dynsym", 0)
+ s := Linklookup(ctxt, ".dynsym", 0)
s.Type = obj.SELFROSECT
s.Attr |= AttrReachable
}
/* dynamic string table */
- s = Linklookup(Ctxt, ".dynstr", 0)
+ s = Linklookup(ctxt, ".dynstr", 0)
s.Type = obj.SELFROSECT
s.Attr |= AttrReachable
if s.Size == 0 {
- Addstring(s, "")
+ Addstring(ctxt, s, "")
}
dynstr := s
/* relocation table */
- s = Linklookup(Ctxt, elfRelType, 0)
+ s = Linklookup(ctxt, elfRelType, 0)
s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
/* global offset table */
- s = Linklookup(Ctxt, ".got", 0)
+ s = Linklookup(ctxt, ".got", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFGOT // writable
/* ppc64 glink resolver */
if SysArch.Family == sys.PPC64 {
- s := Linklookup(Ctxt, ".glink", 0)
+ s := Linklookup(ctxt, ".glink", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFRXSECT
}
/* hash */
- s = Linklookup(Ctxt, ".hash", 0)
+ s = Linklookup(ctxt, ".hash", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
- s = Linklookup(Ctxt, ".got.plt", 0)
+ s = Linklookup(ctxt, ".got.plt", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFSECT // writable
- s = Linklookup(Ctxt, ".plt", 0)
+ s = Linklookup(ctxt, ".plt", 0)
s.Attr |= AttrReachable
if SysArch.Family == sys.PPC64 {
Thearch.Elfsetupplt()
- s = Linklookup(Ctxt, elfRelType+".plt", 0)
+ s = Linklookup(ctxt, elfRelType+".plt", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
- s = Linklookup(Ctxt, ".gnu.version", 0)
+ s = Linklookup(ctxt, ".gnu.version", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
- s = Linklookup(Ctxt, ".gnu.version_r", 0)
+ s = Linklookup(ctxt, ".gnu.version_r", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFROSECT
/* define dynamic elf table */
- s = Linklookup(Ctxt, ".dynamic", 0)
+ s = Linklookup(ctxt, ".dynamic", 0)
s.Attr |= AttrReachable
s.Type = obj.SELFSECT // writable
/*
* .dynamic table
*/
- elfwritedynentsym(s, DT_HASH, Linklookup(Ctxt, ".hash", 0))
+ elfwritedynentsym(ctxt, s, DT_HASH, Linklookup(ctxt, ".hash", 0))
- elfwritedynentsym(s, DT_SYMTAB, Linklookup(Ctxt, ".dynsym", 0))
+ elfwritedynentsym(ctxt, s, DT_SYMTAB, Linklookup(ctxt, ".dynsym", 0))
if elf64 {
- Elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE)
+ Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE)
} else {
- Elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE)
+ Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE)
}
- elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0))
- elfwritedynentsymsize(s, DT_STRSZ, Linklookup(Ctxt, ".dynstr", 0))
+ elfwritedynentsym(ctxt, s, DT_STRTAB, Linklookup(ctxt, ".dynstr", 0))
+ elfwritedynentsymsize(ctxt, s, DT_STRSZ, Linklookup(ctxt, ".dynstr", 0))
if elfRelType == ".rela" {
- elfwritedynentsym(s, DT_RELA, Linklookup(Ctxt, ".rela", 0))
- elfwritedynentsymsize(s, DT_RELASZ, Linklookup(Ctxt, ".rela", 0))
- Elfwritedynent(s, DT_RELAENT, ELF64RELASIZE)
+ elfwritedynentsym(ctxt, s, DT_RELA, Linklookup(ctxt, ".rela", 0))
+ elfwritedynentsymsize(ctxt, s, DT_RELASZ, Linklookup(ctxt, ".rela", 0))
+ Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE)
} else {
- elfwritedynentsym(s, DT_REL, Linklookup(Ctxt, ".rel", 0))
- elfwritedynentsymsize(s, DT_RELSZ, Linklookup(Ctxt, ".rel", 0))
- Elfwritedynent(s, DT_RELENT, ELF32RELSIZE)
+ elfwritedynentsym(ctxt, s, DT_REL, Linklookup(ctxt, ".rel", 0))
+ elfwritedynentsymsize(ctxt, s, DT_RELSZ, Linklookup(ctxt, ".rel", 0))
+ Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE)
}
if rpath.val != "" {
- Elfwritedynent(s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
+ Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(ctxt, dynstr, rpath.val)))
}
if SysArch.Family == sys.PPC64 {
- elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".plt", 0))
+ elfwritedynentsym(ctxt, s, DT_PLTGOT, Linklookup(ctxt, ".plt", 0))
} else if SysArch.Family == sys.S390X {
- elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got", 0))
+ elfwritedynentsym(ctxt, s, DT_PLTGOT, Linklookup(ctxt, ".got", 0))
} else {
- elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got.plt", 0))
+ elfwritedynentsym(ctxt, s, DT_PLTGOT, Linklookup(ctxt, ".got.plt", 0))
}
if SysArch.Family == sys.PPC64 {
- Elfwritedynent(s, DT_PPC64_OPT, 0)
+ Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0)
}
// Solaris dynamic linker can't handle an empty .rela.plt if
// DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
// DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
// size of .rel(a).plt section.
- Elfwritedynent(s, DT_DEBUG, 0)
+ Elfwritedynent(ctxt, s, DT_DEBUG, 0)
}
if Buildmode == BuildmodeShared {
// The go.link.abihashbytes symbol will be pointed at the appropriate
// part of the .note.go.abihash section in data.go:func address().
- s := Linklookup(Ctxt, "go.link.abihashbytes", 0)
+ s := Linklookup(ctxt, "go.link.abihashbytes", 0)
s.Attr |= AttrLocal
s.Type = obj.SRODATA
s.Attr |= AttrSpecial
s.Attr |= AttrReachable
s.Size = int64(sha1.Size)
- sort.Sort(byPkg(Ctxt.Library))
+ sort.Sort(byPkg(ctxt.Library))
h := sha1.New()
- for _, l := range Ctxt.Library {
+ for _, l := range ctxt.Library {
h.Write(l.hash)
}
- addgonote(".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
- addgonote(".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
+ addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
+ addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
var deplist []string
- for _, shlib := range Ctxt.Shlibs {
+ for _, shlib := range ctxt.Shlibs {
deplist = append(deplist, filepath.Base(shlib.Path))
}
- addgonote(".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
+ addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
}
if Linkmode == LinkExternal && buildid != "" {
- addgonote(".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(buildid))
+ addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(buildid))
}
}
// Do not write DT_NULL. elfdynhash will finish it.
-func shsym(sh *ElfShdr, s *Symbol) {
- addr := Symaddr(s)
+func shsym(ctxt *Link, sh *ElfShdr, s *Symbol) {
+ addr := Symaddr(ctxt, s)
if sh.flags&SHF_ALLOC != 0 {
sh.addr = uint64(addr)
}
- sh.off = uint64(datoff(addr))
+ sh.off = uint64(datoff(ctxt, addr))
sh.size = uint64(s.Size)
}
ph.align = sh.addralign
}
-func Asmbelfsetup() {
+func Asmbelfsetup(ctxt *Link) {
/* This null SHdr must appear before all others */
- elfshname("")
+ elfshname(ctxt, "")
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
- elfshalloc(sect)
+ elfshalloc(ctxt, sect)
}
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
- elfshalloc(sect)
+ elfshalloc(ctxt, sect)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- elfshalloc(sect)
+ elfshalloc(ctxt, sect)
}
for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
- elfshalloc(sect)
+ elfshalloc(ctxt, sect)
}
}
-func Asmbelf(symo int64) {
+func Asmbelf(ctxt *Link, symo int64) {
eh := getElfEhdr()
switch SysArch.Family {
default:
eh.phentsize = 0
if Buildmode == BuildmodeShared {
- sh := elfshname(".note.go.pkg-list")
+ sh := elfshname(ctxt, ".note.go.pkg-list")
sh.type_ = SHT_NOTE
- sh = elfshname(".note.go.abihash")
+ sh = elfshname(ctxt, ".note.go.abihash")
sh.type_ = SHT_NOTE
sh.flags = SHF_ALLOC
- sh = elfshname(".note.go.deps")
+ sh = elfshname(ctxt, ".note.go.deps")
sh.type_ = SHT_NOTE
}
if buildid != "" {
- sh := elfshname(".note.go.buildid")
+ sh := elfshname(ctxt, ".note.go.buildid")
sh.type_ = SHT_NOTE
sh.flags = SHF_ALLOC
}
}
/* program header info */
- pph = newElfPhdr()
+ pph = newElfPhdr(ctxt)
pph.type_ = PT_PHDR
pph.flags = PF_R
if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
/* interpreter */
- sh := elfshname(".interp")
+ sh := elfshname(ctxt, ".interp")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC
resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
- ph := newElfPhdr()
+ ph := newElfPhdr(ctxt)
ph.type_ = PT_INTERP
ph.flags = PF_R
phsh(ph, sh)
var sh *ElfShdr
switch HEADTYPE {
case obj.Hnetbsd:
- sh = elfshname(".note.netbsd.ident")
+ sh = elfshname(ctxt, ".note.netbsd.ident")
resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
case obj.Hopenbsd:
- sh = elfshname(".note.openbsd.ident")
+ sh = elfshname(ctxt, ".note.openbsd.ident")
resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
}
- pnote = newElfPhdr()
+ pnote = newElfPhdr(ctxt)
pnote.type_ = PT_NOTE
pnote.flags = PF_R
phsh(pnote, sh)
}
if len(buildinfo) > 0 {
- sh := elfshname(".note.gnu.build-id")
+ sh := elfshname(ctxt, ".note.gnu.build-id")
resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
if pnote == nil {
- pnote = newElfPhdr()
+ pnote = newElfPhdr(ctxt)
pnote.type_ = PT_NOTE
pnote.flags = PF_R
}
}
if buildid != "" {
- sh := elfshname(".note.go.buildid")
+ sh := elfshname(ctxt, ".note.go.buildid")
resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
- pnote := newElfPhdr()
+ pnote := newElfPhdr(ctxt)
pnote.type_ = PT_NOTE
pnote.flags = PF_R
phsh(pnote, sh)
// Additions to the reserved area must be above this line.
- elfphload(&Segtext)
+ elfphload(ctxt, &Segtext)
if Segrodata.Sect != nil {
- elfphload(&Segrodata)
+ elfphload(ctxt, &Segrodata)
}
- elfphload(&Segdata)
+ elfphload(ctxt, &Segdata)
/* Dynamic linking sections */
if Debug['d'] == 0 {
- sh := elfshname(".dynsym")
+ sh := elfshname(ctxt, ".dynsym")
sh.type_ = SHT_DYNSYM
sh.flags = SHF_ALLOC
if elf64 {
sh.entsize = ELF32SYMSIZE
}
sh.addralign = uint64(SysArch.RegSize)
- sh.link = uint32(elfshname(".dynstr").shnum)
+ sh.link = uint32(elfshname(ctxt, ".dynstr").shnum)
// sh->info = index of first non-local symbol (number of local symbols)
- shsym(sh, Linklookup(Ctxt, ".dynsym", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".dynsym", 0))
- sh = elfshname(".dynstr")
+ sh = elfshname(ctxt, ".dynstr")
sh.type_ = SHT_STRTAB
sh.flags = SHF_ALLOC
sh.addralign = 1
- shsym(sh, Linklookup(Ctxt, ".dynstr", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".dynstr", 0))
if elfverneed != 0 {
- sh := elfshname(".gnu.version")
+ sh := elfshname(ctxt, ".gnu.version")
sh.type_ = SHT_GNU_VERSYM
sh.flags = SHF_ALLOC
sh.addralign = 2
- sh.link = uint32(elfshname(".dynsym").shnum)
+ sh.link = uint32(elfshname(ctxt, ".dynsym").shnum)
sh.entsize = 2
- shsym(sh, Linklookup(Ctxt, ".gnu.version", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".gnu.version", 0))
- sh = elfshname(".gnu.version_r")
+ sh = elfshname(ctxt, ".gnu.version_r")
sh.type_ = SHT_GNU_VERNEED
sh.flags = SHF_ALLOC
sh.addralign = uint64(SysArch.RegSize)
sh.info = uint32(elfverneed)
- sh.link = uint32(elfshname(".dynstr").shnum)
- shsym(sh, Linklookup(Ctxt, ".gnu.version_r", 0))
+ sh.link = uint32(elfshname(ctxt, ".dynstr").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".gnu.version_r", 0))
}
if elfRelType == ".rela" {
- sh := elfshname(".rela.plt")
+ sh := elfshname(ctxt, ".rela.plt")
sh.type_ = SHT_RELA
sh.flags = SHF_ALLOC
sh.entsize = ELF64RELASIZE
sh.addralign = uint64(SysArch.RegSize)
- sh.link = uint32(elfshname(".dynsym").shnum)
- sh.info = uint32(elfshname(".plt").shnum)
- shsym(sh, Linklookup(Ctxt, ".rela.plt", 0))
+ sh.link = uint32(elfshname(ctxt, ".dynsym").shnum)
+ sh.info = uint32(elfshname(ctxt, ".plt").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".rela.plt", 0))
- sh = elfshname(".rela")
+ sh = elfshname(ctxt, ".rela")
sh.type_ = SHT_RELA
sh.flags = SHF_ALLOC
sh.entsize = ELF64RELASIZE
sh.addralign = 8
- sh.link = uint32(elfshname(".dynsym").shnum)
- shsym(sh, Linklookup(Ctxt, ".rela", 0))
+ sh.link = uint32(elfshname(ctxt, ".dynsym").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".rela", 0))
} else {
- sh := elfshname(".rel.plt")
+ sh := elfshname(ctxt, ".rel.plt")
sh.type_ = SHT_REL
sh.flags = SHF_ALLOC
sh.entsize = ELF32RELSIZE
sh.addralign = 4
- sh.link = uint32(elfshname(".dynsym").shnum)
- shsym(sh, Linklookup(Ctxt, ".rel.plt", 0))
+ sh.link = uint32(elfshname(ctxt, ".dynsym").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".rel.plt", 0))
- sh = elfshname(".rel")
+ sh = elfshname(ctxt, ".rel")
sh.type_ = SHT_REL
sh.flags = SHF_ALLOC
sh.entsize = ELF32RELSIZE
sh.addralign = 4
- sh.link = uint32(elfshname(".dynsym").shnum)
- shsym(sh, Linklookup(Ctxt, ".rel", 0))
+ sh.link = uint32(elfshname(ctxt, ".dynsym").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".rel", 0))
}
if eh.machine == EM_PPC64 {
- sh := elfshname(".glink")
+ sh := elfshname(ctxt, ".glink")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC + SHF_EXECINSTR
sh.addralign = 4
- shsym(sh, Linklookup(Ctxt, ".glink", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".glink", 0))
}
- sh = elfshname(".plt")
+ sh = elfshname(ctxt, ".plt")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC + SHF_EXECINSTR
if eh.machine == EM_X86_64 {
sh.entsize = 4
}
sh.addralign = sh.entsize
- shsym(sh, Linklookup(Ctxt, ".plt", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".plt", 0))
// On ppc64, .got comes from the input files, so don't
// create it here, and .got.plt is not used.
if eh.machine != EM_PPC64 {
- sh := elfshname(".got")
+ sh := elfshname(ctxt, ".got")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC + SHF_WRITE
sh.entsize = uint64(SysArch.RegSize)
sh.addralign = uint64(SysArch.RegSize)
- shsym(sh, Linklookup(Ctxt, ".got", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".got", 0))
- sh = elfshname(".got.plt")
+ sh = elfshname(ctxt, ".got.plt")
sh.type_ = SHT_PROGBITS
sh.flags = SHF_ALLOC + SHF_WRITE
sh.entsize = uint64(SysArch.RegSize)
sh.addralign = uint64(SysArch.RegSize)
- shsym(sh, Linklookup(Ctxt, ".got.plt", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".got.plt", 0))
}
- sh = elfshname(".hash")
+ sh = elfshname(ctxt, ".hash")
sh.type_ = SHT_HASH
sh.flags = SHF_ALLOC
sh.entsize = 4
sh.addralign = uint64(SysArch.RegSize)
- sh.link = uint32(elfshname(".dynsym").shnum)
- shsym(sh, Linklookup(Ctxt, ".hash", 0))
+ sh.link = uint32(elfshname(ctxt, ".dynsym").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".hash", 0))
/* sh and PT_DYNAMIC for .dynamic section */
- sh = elfshname(".dynamic")
+ sh = elfshname(ctxt, ".dynamic")
sh.type_ = SHT_DYNAMIC
sh.flags = SHF_ALLOC + SHF_WRITE
sh.entsize = 2 * uint64(SysArch.RegSize)
sh.addralign = uint64(SysArch.RegSize)
- sh.link = uint32(elfshname(".dynstr").shnum)
- shsym(sh, Linklookup(Ctxt, ".dynamic", 0))
- ph := newElfPhdr()
+ sh.link = uint32(elfshname(ctxt, ".dynstr").shnum)
+ shsym(ctxt, sh, Linklookup(ctxt, ".dynamic", 0))
+ ph := newElfPhdr(ctxt)
ph.type_ = PT_DYNAMIC
ph.flags = PF_R + PF_W
phsh(ph, sh)
}
}
if tlssize != 0 {
- ph := newElfPhdr()
+ ph := newElfPhdr(ctxt)
ph.type_ = PT_TLS
ph.flags = PF_R
ph.memsz = tlssize
}
if HEADTYPE == obj.Hlinux {
- ph := newElfPhdr()
+ ph := newElfPhdr(ctxt)
ph.type_ = PT_GNU_STACK
ph.flags = PF_W + PF_R
ph.align = uint64(SysArch.RegSize)
- ph = newElfPhdr()
+ ph = newElfPhdr(ctxt)
ph.type_ = PT_PAX_FLAGS
ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
ph.align = uint64(SysArch.RegSize)
}
elfobj:
- sh := elfshname(".shstrtab")
+ sh := elfshname(ctxt, ".shstrtab")
sh.type_ = SHT_STRTAB
sh.addralign = 1
- shsym(sh, Linklookup(Ctxt, ".shstrtab", 0))
+ shsym(ctxt, sh, Linklookup(ctxt, ".shstrtab", 0))
eh.shstrndx = uint16(sh.shnum)
// put these sections early in the list
if Debug['s'] == 0 {
- elfshname(".symtab")
- elfshname(".strtab")
+ elfshname(ctxt, ".symtab")
+ elfshname(ctxt, ".strtab")
}
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
- elfshbits(sect)
+ elfshbits(ctxt, sect)
}
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
- elfshbits(sect)
+ elfshbits(ctxt, sect)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- elfshbits(sect)
+ elfshbits(ctxt, sect)
}
for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
- elfshbits(sect)
+ elfshbits(ctxt, sect)
}
if Linkmode == LinkExternal {
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
- elfshreloc(sect)
+ elfshreloc(ctxt, sect)
}
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
- elfshreloc(sect)
+ elfshreloc(ctxt, sect)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- elfshreloc(sect)
+ elfshreloc(ctxt, sect)
}
for s := dwarfp; s != nil; s = s.Next {
if len(s.R) > 0 || s.Type == obj.SDWARFINFO {
- elfshreloc(s.Sect)
+ elfshreloc(ctxt, s.Sect)
}
if s.Type == obj.SDWARFINFO {
break
}
}
// add a .note.GNU-stack section to mark the stack as non-executable
- sh := elfshname(".note.GNU-stack")
+ sh := elfshname(ctxt, ".note.GNU-stack")
sh.type_ = SHT_PROGBITS
sh.addralign = 1
}
if Debug['s'] == 0 {
- sh := elfshname(".symtab")
+ sh := elfshname(ctxt, ".symtab")
sh.type_ = SHT_SYMTAB
sh.off = uint64(symo)
sh.size = uint64(Symsize)
sh.addralign = uint64(SysArch.RegSize)
sh.entsize = 8 + 2*uint64(SysArch.RegSize)
- sh.link = uint32(elfshname(".strtab").shnum)
+ sh.link = uint32(elfshname(ctxt, ".strtab").shnum)
sh.info = uint32(elfglobalsymndx)
- sh = elfshname(".strtab")
+ sh = elfshname(ctxt, ".strtab")
sh.type_ = SHT_STRTAB
sh.off = uint64(symo) + uint64(Symsize)
sh.size = uint64(len(Elfstrdat))
} else {
eh.ident[EI_CLASS] = ELFCLASS32
}
- if Ctxt.Arch.ByteOrder == binary.BigEndian {
+ if ctxt.Arch.ByteOrder == binary.BigEndian {
eh.ident[EI_DATA] = ELFDATA2MSB
} else {
eh.ident[EI_DATA] = ELFDATA2LSB
}
if Linkmode != LinkExternal {
- eh.entry = uint64(Entryvalue())
+ eh.entry = uint64(Entryvalue(ctxt))
}
eh.version = EV_CURRENT
a += int64(elfwritephdrs())
a += int64(elfwriteshdrs())
if Debug['d'] == 0 {
- a += int64(elfwriteinterp())
+ a += int64(elfwriteinterp(ctxt))
}
if Linkmode != LinkExternal {
if HEADTYPE == obj.Hnetbsd {
- a += int64(elfwritenetbsdsig())
+ a += int64(elfwritenetbsdsig(ctxt))
}
if HEADTYPE == obj.Hopenbsd {
- a += int64(elfwriteopenbsdsig())
+ a += int64(elfwriteopenbsdsig(ctxt))
}
if len(buildinfo) > 0 {
- a += int64(elfwritebuildinfo())
+ a += int64(elfwritebuildinfo(ctxt))
}
if buildid != "" {
- a += int64(elfwritegobuildid())
+ a += int64(elfwritegobuildid(ctxt))
}
}
if a > elfreserve {
- Diag("ELFRESERVE too small: %d > %d", a, elfreserve)
+ ctxt.Diag("ELFRESERVE too small: %d > %d", a, elfreserve)
}
}
d := Linklookup(ctxt, ".dynsym", 0)
name := s.Extname
- Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name)))
+ Adduint32(ctxt, d, uint32(Addstring(ctxt, Linklookup(ctxt, ".dynstr", 0), name)))
/* type */
t := STB_GLOBAL << 4
Adduint64(ctxt, d, uint64(s.Size))
if SysArch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
- Elfwritedynent(Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
+ Elfwritedynent(ctxt, Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt, Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
}
} else {
s.Dynid = int32(Nelfsym)
/* name */
name := s.Extname
- Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name)))
+ Adduint32(ctxt, d, uint32(Addstring(ctxt, Linklookup(ctxt, ".dynstr", 0), name)))
/* value */
if s.Type == obj.SDYNIMPORT {
// once the dust settles, try to move some code to
// libmach, so that other linkers and ar can share.
-func ldpkg(f *bio.Reader, pkg string, length int64, filename string, whence int) {
+func ldpkg(ctxt *Link, f *bio.Reader, pkg string, length int64, filename string, whence int) {
var p0, p1 int
if Debug['g'] != 0 {
}
p1 += p0
- loadcgo(filename, pkg, data[p0:p1])
+ loadcgo(ctxt, filename, pkg, data[p0:p1])
}
}
-func loadcgo(file string, pkg string, p string) {
+func loadcgo(ctxt *Link, file string, pkg string, p string) {
var next string
var q string
var f []string
if i := strings.Index(remote, "#"); i >= 0 {
remote, q = remote[:i], remote[i+1:]
}
- s = Linklookup(Ctxt, local, 0)
+ s = Linklookup(ctxt, local, 0)
if local != f[1] {
}
if s.Type == 0 || s.Type == obj.SXREF || s.Type == obj.SHOSTOBJ {
goto err
}
local = f[1]
- s = Linklookup(Ctxt, local, 0)
+ s = Linklookup(ctxt, local, 0)
s.Type = obj.SHOSTOBJ
s.Size = 0
continue
remote = local
}
local = expandpkg(local, pkg)
- s = Linklookup(Ctxt, local, 0)
+ s = Linklookup(ctxt, local, 0)
switch Buildmode {
case BuildmodeCShared, BuildmodeCArchive:
- if s == Linklookup(Ctxt, "main", 0) {
+ if s == Linklookup(ctxt, "main", 0) {
continue
}
}
var seenlib = make(map[string]bool)
-func adddynlib(lib string) {
+func adddynlib(ctxt *Link, lib string) {
if seenlib[lib] || Linkmode == LinkExternal {
return
}
seenlib[lib] = true
if Iself {
- s := Linklookup(Ctxt, ".dynstr", 0)
+ s := Linklookup(ctxt, ".dynstr", 0)
if s.Size == 0 {
- Addstring(s, "")
+ Addstring(ctxt, s, "")
}
- Elfwritedynent(Linklookup(Ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(s, lib)))
+ Elfwritedynent(ctxt, Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt, s, lib)))
} else {
- Diag("adddynlib: unsupported binary format")
+ ctxt.Diag("adddynlib: unsupported binary format")
}
}
if Iself {
Elfadddynsym(ctxt, s)
} else if HEADTYPE == obj.Hdarwin {
- Diag("adddynsym: missed symbol %s (%s)", s.Name, s.Extname)
+ ctxt.Diag("adddynsym: missed symbol %s (%s)", s.Name, s.Extname)
} else if HEADTYPE == obj.Hwindows {
// already taken care of
} else {
- Diag("adddynsym: unsupported binary format")
+ ctxt.Diag("adddynsym: unsupported binary format")
}
}
if !s.Attr.Reachable() {
return
}
- addstrdata(tracksym, buf.String())
+ addstrdata(ctxt, tracksym, buf.String())
}
-func addexport() {
+func (ctxt *Link) addexport() {
if HEADTYPE == obj.Hdarwin {
return
}
for _, exp := range dynexp {
- Adddynsym(Ctxt, exp)
+ Adddynsym(ctxt, exp)
}
for _, lib := range dynlib {
- adddynlib(lib)
+ adddynlib(ctxt, lib)
}
}
if shlibnamefile != "" {
shlibbytes, err := ioutil.ReadFile(shlibnamefile)
if err != nil {
- Diag("cannot read %s: %v", shlibnamefile, err)
+ ctxt.Diag("cannot read %s: %v", shlibnamefile, err)
}
l.Shlib = strings.TrimSpace(string(shlibbytes))
}
}
}
-func ldelf(f *bio.Reader, pkg string, length int64, pn string) {
+func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "%5.2f ldelf %s\n", obj.Cputime(), pn)
}
- Ctxt.IncVersion()
+ ctxt.IncVersion()
base := f.Offset()
var add uint64
}
if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
- Diag("%s: elf but not elf relocatable object", pn)
+ ctxt.Diag("%s: elf but not elf relocatable object", pn)
return
}
switch SysArch.Family {
default:
- Diag("%s: elf %s unimplemented", pn, SysArch.Name)
+ ctxt.Diag("%s: elf %s unimplemented", pn, SysArch.Name)
return
case sys.MIPS64:
if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
- Diag("%s: elf object but not mips64", pn)
+ ctxt.Diag("%s: elf object but not mips64", pn)
return
}
case sys.ARM:
if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
- Diag("%s: elf object but not arm", pn)
+ ctxt.Diag("%s: elf object but not arm", pn)
return
}
case sys.AMD64:
if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
- Diag("%s: elf object but not amd64", pn)
+ ctxt.Diag("%s: elf object but not amd64", pn)
return
}
case sys.ARM64:
if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
- Diag("%s: elf object but not arm64", pn)
+ ctxt.Diag("%s: elf object but not arm64", pn)
return
}
case sys.I386:
if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
- Diag("%s: elf object but not 386", pn)
+ ctxt.Diag("%s: elf object but not 386", pn)
return
}
case sys.PPC64:
if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
- Diag("%s: elf object but not ppc64", pn)
+ ctxt.Diag("%s: elf object but not ppc64", pn)
return
}
case sys.S390X:
if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
- Diag("%s: elf object but not s390x", pn)
+ ctxt.Diag("%s: elf object but not s390x", pn)
return
}
}
}
if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
- Diag("%s: elf object has symbol table with invalid string table link", pn)
+ ctxt.Diag("%s: elf object has symbol table with invalid string table link", pn)
return
}
}
name = fmt.Sprintf("%s(%s)", pkg, sect.name)
- s = Linklookup(Ctxt, name, Ctxt.Version)
+ s = Linklookup(ctxt, name, ctxt.Version)
switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
default:
symbols = make([]*Symbol, elfobj.nsymtab)
for i := 1; i < elfobj.nsymtab; i++ {
- if err = readelfsym(elfobj, i, &sym, 1); err != nil {
+ if err = readelfsym(ctxt, elfobj, i, &sym, 1); err != nil {
goto bad
}
symbols[i] = sym.sym
if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this
continue
}
- Diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type_)
+ ctxt.Diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type_)
continue
}
s.Outer = sect.sym
if sect.sym.Type == obj.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
- Diag("%s: duplicate definition of %s", pn, s.Name)
+ ctxt.Diag("%s: duplicate definition of %s", pn, s.Name)
}
s.Attr |= AttrExternal
}
if 2 <= flag && flag <= 6 {
s.Localentry = 1 << uint(flag-2)
} else if flag == 7 {
- Diag("%s: invalid sym.other 0x%x for %s", pn, sym.other, s.Name)
+ ctxt.Diag("%s: invalid sym.other 0x%x for %s", pn, sym.other, s.Name)
}
}
}
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
- Ctxt.Textp = append(Ctxt.Textp, s)
+ ctxt.Textp = append(ctxt.Textp, s)
for s = s.Sub; s != nil; s = s.Sub {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
- Ctxt.Textp = append(Ctxt.Textp, s)
+ ctxt.Textp = append(ctxt.Textp, s)
}
}
}
if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
rp.Sym = nil
} else {
- if err = readelfsym(elfobj, int(info>>32), &sym, 0); err != nil {
+ if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0); err != nil {
goto bad
}
sym.sym = symbols[info>>32]
}
rp.Type = 256 + int32(info)
- rp.Siz = relSize(pn, uint32(info))
+ rp.Siz = relSize(ctxt, pn, uint32(info))
if rela != 0 {
rp.Add = int64(add)
} else {
} else if rp.Siz == 8 {
rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
} else {
- Diag("invalid rela size %d", rp.Siz)
+ ctxt.Diag("invalid rela size %d", rp.Siz)
}
}
return
bad:
- Diag("%s: malformed elf file: %v", pn, err)
+ ctxt.Diag("%s: malformed elf file: %v", pn, err)
}
func section(elfobj *ElfObj, name string) *ElfSect {
return nil
}
-func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
+func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
if i >= elfobj.nsymtab || i < 0 {
err = fmt.Errorf("invalid elf symbol index")
return err
}
if i == 0 {
- Diag("readym: read null symbol!")
+ ctxt.Diag("readym: read null symbol!")
}
if elfobj.is64 != 0 {
switch sym.bind {
case ElfSymBindGlobal:
if needSym != 0 {
- s = Linklookup(Ctxt, sym.name, 0)
+ s = Linklookup(ctxt, sym.name, 0)
// for global scoped hidden symbols we should insert it into
// symbol hash table, but mark them as hidden.
// We need to be able to look this up,
// so put it in the hash table.
if needSym != 0 {
- s = Linklookup(Ctxt, sym.name, Ctxt.Version)
+ s = Linklookup(ctxt, sym.name, ctxt.Version)
s.Type |= obj.SHIDDEN
}
// local names and hidden global names are unique
// and should only be referenced by their index, not name, so we
// don't bother to add them into the hash table
- s = linknewsym(Ctxt, sym.name, Ctxt.Version)
+ s = linknewsym(ctxt, sym.name, ctxt.Version)
s.Type |= obj.SHIDDEN
}
case ElfSymBindWeak:
if needSym != 0 {
- s = Linklookup(Ctxt, sym.name, 0)
+ s = Linklookup(ctxt, sym.name, 0)
if sym.other == 2 {
s.Type |= obj.SHIDDEN
}
return false
}
-func relSize(pn string, elftype uint32) uint8 {
+func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
// TODO(mdempsky): Replace this with a struct-valued switch statement
// once golang.org/issue/15164 is fixed or found to not impair cmd/link
// performance.
switch uint32(SysArch.Family) | elftype<<24 {
default:
- Diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
+ ctxt.Diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
fallthrough
case S390X | R_390_8<<24:
return 0
}
-func ldmacho(f *bio.Reader, pkg string, length int64, pn string) {
+func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
var err error
var j int
var is64 bool
var rp *Reloc
var name string
- Ctxt.IncVersion()
+ ctxt.IncVersion()
base := f.Offset()
if _, err := io.ReadFull(f, hdr[:]); err != nil {
goto bad
switch SysArch.Family {
default:
- Diag("%s: mach-o %s unimplemented", pn, SysArch.Name)
+ ctxt.Diag("%s: mach-o %s unimplemented", pn, SysArch.Name)
return
case sys.AMD64:
if e != binary.LittleEndian || m.cputype != LdMachoCpuAmd64 {
- Diag("%s: mach-o object but not amd64", pn)
+ ctxt.Diag("%s: mach-o object but not amd64", pn)
return
}
case sys.I386:
if e != binary.LittleEndian || m.cputype != LdMachoCpu386 {
- Diag("%s: mach-o object but not 386", pn)
+ ctxt.Diag("%s: mach-o object but not 386", pn)
return
}
}
continue
}
name = fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
- s = Linklookup(Ctxt, name, Ctxt.Version)
+ s = Linklookup(ctxt, name, ctxt.Version)
if s.Type != 0 {
err = fmt.Errorf("duplicate %s/%s", sect.segname, sect.name)
goto bad
}
v := 0
if sym.type_&N_EXT == 0 {
- v = Ctxt.Version
+ v = ctxt.Version
}
- s = Linklookup(Ctxt, name, v)
+ s = Linklookup(ctxt, name, v)
if sym.type_&N_EXT == 0 {
s.Attr |= AttrDuplicateOK
}
}
if outer.Type == obj.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
- Diag("%s: duplicate definition of %s", pn, s.Name)
+ ctxt.Diag("%s: duplicate definition of %s", pn, s.Name)
}
s.Attr |= AttrExternal
}
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
- Ctxt.Textp = append(Ctxt.Textp, s)
+ ctxt.Textp = append(ctxt.Textp, s)
for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
if s1.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s1.Name)
}
s1.Attr |= AttrOnList
- Ctxt.Textp = append(Ctxt.Textp, s1)
+ ctxt.Textp = append(ctxt.Textp, s1)
}
}
}
if rel.scattered != 0 {
if SysArch.Family != sys.I386 {
// mach-o only uses scattered relocation on 32-bit platforms
- Diag("unexpected scattered relocation")
+ ctxt.Diag("unexpected scattered relocation")
continue
}
return
bad:
- Diag("%s: malformed mach-o file: %v", pn, err)
+ ctxt.Diag("%s: malformed mach-o file: %v", pn, err)
}
snames []byte
}
-func ldpe(f *bio.Reader, pkg string, length int64, pn string) {
+func ldpe(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "%5.2f ldpe %s\n", obj.Cputime(), pn)
}
var sect *PeSect
- Ctxt.IncVersion()
+ ctxt.IncVersion()
base := f.Offset()
peobj := new(PeObj)
}
name = fmt.Sprintf("%s(%s)", pkg, sect.name)
- s = Linklookup(Ctxt, name, Ctxt.Version)
+ s = Linklookup(ctxt, name, ctxt.Version)
switch sect.sh.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
s.Size = int64(sect.size)
sect.sym = s
if sect.name == ".rsrc" {
- setpersrc(sect.sym)
+ setpersrc(ctxt, sect.sym)
}
}
rva := Le32(symbuf[0:])
symindex := Le32(symbuf[4:])
type_ := Le16(symbuf[8:])
- if err = readpesym(peobj, int(symindex), &sym); err != nil {
+ if err = readpesym(ctxt, peobj, int(symindex), &sym); err != nil {
goto bad
}
if sym.sym == nil {
rp.Off = int32(rva)
switch type_ {
default:
- Diag("%s: unknown relocation type %d;", pn, type_)
+ ctxt.Diag("%s: unknown relocation type %d;", pn, type_)
fallthrough
case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
}
}
- if err = readpesym(peobj, i, &sym); err != nil {
+ if err = readpesym(ctxt, peobj, i, &sym); err != nil {
goto bad
}
} else if sym.sectnum > 0 && uint(sym.sectnum) <= peobj.nsect {
sect = &peobj.sect[sym.sectnum-1]
if sect.sym == nil {
- Diag("%s: %s sym == 0!", pn, s.Name)
+ ctxt.Diag("%s: %s sym == 0!", pn, s.Name)
}
} else {
- Diag("%s: %s sectnum < 0!", pn, s.Name)
+ ctxt.Diag("%s: %s sectnum < 0!", pn, s.Name)
}
if sect == nil {
s.Outer = sect.sym
if sect.sym.Type == obj.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
- Diag("%s: duplicate definition of %s", pn, s.Name)
+ ctxt.Diag("%s: duplicate definition of %s", pn, s.Name)
}
s.Attr |= AttrExternal
}
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
- Ctxt.Textp = append(Ctxt.Textp, s)
+ ctxt.Textp = append(ctxt.Textp, s)
for s = s.Sub; s != nil; s = s.Sub {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
- Ctxt.Textp = append(Ctxt.Textp, s)
+ ctxt.Textp = append(ctxt.Textp, s)
}
}
}
return
bad:
- Diag("%s: malformed pe file: %v", pn, err)
+ ctxt.Diag("%s: malformed pe file: %v", pn, err)
}
func pemap(peobj *PeObj, sect *PeSect) int {
return s.sclass == IMAGE_SYM_CLASS_STATIC && s.type_ == 0 && s.name[0] == '.'
}
-func readpesym(peobj *PeObj, i int, y **PeSym) (err error) {
+func readpesym(ctxt *Link, peobj *PeObj, i int, y **PeSym) (err error) {
if uint(i) >= peobj.npesym || i < 0 {
err = fmt.Errorf("invalid pe symbol index")
return err
case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
switch sym.sclass {
case IMAGE_SYM_CLASS_EXTERNAL: //global
- s = Linklookup(Ctxt, name, 0)
+ s = Linklookup(ctxt, name, 0)
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
- s = Linklookup(Ctxt, name, Ctxt.Version)
+ s = Linklookup(ctxt, name, ctxt.Version)
s.Attr |= AttrDuplicateOK
default:
Archinit func()
Archreloc func(*Reloc, *Symbol, *int64) int
Archrelocvariant func(*Reloc, *Symbol, int64) int64
- Asmb func()
+ Asmb func(*Link)
Elfreloc1 func(*Reloc, int64) int
Elfsetupplt func()
Gentext func()
extldflags string
extar string
libgccfile string
- debug_s int // backup old value of debug['s']
- Ctxt *Link
+ debug_s int // backup old value of debug['s']
+ Ctxt *Link // Global pointer to ctxt used by arch-specific packages
HEADR int32
HEADTYPE int32
INITRND int32
theline string
)
-func Lflag(arg string) {
- Ctxt.Libdir = append(Ctxt.Libdir, arg)
+func Lflag(ctxt *Link, arg string) {
+ ctxt.Libdir = append(ctxt.Libdir, arg)
}
// A BuildMode indicates the sort of object we are building:
os.Remove(outfile)
}
-func libinit() {
+func libinit(ctxt *Link) {
Funcalign = Thearch.Funcalign
mywhatsys() // get goroot, goarch, goos
suffix = "msan"
}
- Lflag(filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s%s%s", goos, goarch, suffixsep, suffix)))
+ Lflag(ctxt, filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s%s%s", goos, goarch, suffixsep, suffix)))
mayberemoveoutfile()
f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
case BuildmodeShared:
// No INITENTRY for -buildmode=shared
default:
- Diag("unknown INITENTRY for buildmode %v", Buildmode)
+ ctxt.Diag("unknown INITENTRY for buildmode %v", Buildmode)
}
}
if !DynlinkingGo() {
- Linklookup(Ctxt, INITENTRY, 0).Type = obj.SXREF
+ Linklookup(ctxt, INITENTRY, 0).Type = obj.SXREF
}
}
Exit(0)
}
-func loadinternal(name string) {
+func loadinternal(ctxt *Link, name string) {
found := 0
- for i := 0; i < len(Ctxt.Libdir); i++ {
+ for i := 0; i < len(ctxt.Libdir); i++ {
if Linkshared {
- shlibname := filepath.Join(Ctxt.Libdir[i], name+".shlibname")
+ shlibname := filepath.Join(ctxt.Libdir[i], name+".shlibname")
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "searching for %s.a in %s\n", name, shlibname)
}
if _, err := os.Stat(shlibname); err == nil {
- addlibpath(Ctxt, "internal", "internal", "", name, shlibname)
+ addlibpath(ctxt, "internal", "internal", "", name, shlibname)
found = 1
break
}
}
- pname := filepath.Join(Ctxt.Libdir[i], name+".a")
+ pname := filepath.Join(ctxt.Libdir[i], name+".a")
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "searching for %s.a in %s\n", name, pname)
}
if _, err := os.Stat(pname); err == nil {
- addlibpath(Ctxt, "internal", "internal", pname, name, "")
+ addlibpath(ctxt, "internal", "internal", pname, name, "")
found = 1
break
}
}
}
-func loadlib() {
+func (ctxt *Link) loadlib() {
switch Buildmode {
case BuildmodeCShared:
- s := Linklookup(Ctxt, "runtime.islibrary", 0)
+ s := Linklookup(ctxt, "runtime.islibrary", 0)
s.Attr |= AttrDuplicateOK
- Adduint8(Ctxt, s, 1)
+ Adduint8(ctxt, s, 1)
case BuildmodeCArchive:
- s := Linklookup(Ctxt, "runtime.isarchive", 0)
+ s := Linklookup(ctxt, "runtime.isarchive", 0)
s.Attr |= AttrDuplicateOK
- Adduint8(Ctxt, s, 1)
+ Adduint8(ctxt, s, 1)
}
- loadinternal("runtime")
+ loadinternal(ctxt, "runtime")
if SysArch.Family == sys.ARM {
- loadinternal("math")
+ loadinternal(ctxt, "math")
}
if flag_race != 0 {
- loadinternal("runtime/race")
+ loadinternal(ctxt, "runtime/race")
}
if flag_msan != 0 {
- loadinternal("runtime/msan")
+ loadinternal(ctxt, "runtime/msan")
}
var i int
- for i = 0; i < len(Ctxt.Library); i++ {
- iscgo = iscgo || Ctxt.Library[i].Pkg == "runtime/cgo"
- if Ctxt.Library[i].Shlib == "" {
+ for i = 0; i < len(ctxt.Library); i++ {
+ iscgo = iscgo || ctxt.Library[i].Pkg == "runtime/cgo"
+ if ctxt.Library[i].Shlib == "" {
if Debug['v'] > 1 {
- fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
+ fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), ctxt.Library[i].File, ctxt.Library[i].Objref)
}
- objfile(Ctxt.Library[i])
+ objfile(ctxt, ctxt.Library[i])
}
}
- for i = 0; i < len(Ctxt.Library); i++ {
- if Ctxt.Library[i].Shlib != "" {
+ for i = 0; i < len(ctxt.Library); i++ {
+ if ctxt.Library[i].Shlib != "" {
if Debug['v'] > 1 {
- fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].Shlib, Ctxt.Library[i].Objref)
+ fmt.Fprintf(Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), ctxt.Library[i].Shlib, ctxt.Library[i].Objref)
}
- ldshlibsyms(Ctxt.Library[i].Shlib)
+ ldshlibsyms(ctxt, ctxt.Library[i].Shlib)
}
}
// The startup code uses an import of runtime/cgo to decide
// whether to initialize the TLS. So give it one. This could
// be handled differently but it's an unusual case.
- loadinternal("runtime/cgo")
+ loadinternal(ctxt, "runtime/cgo")
- if i < len(Ctxt.Library) {
- if Ctxt.Library[i].Shlib != "" {
- ldshlibsyms(Ctxt.Library[i].Shlib)
+ if i < len(ctxt.Library) {
+ if ctxt.Library[i].Shlib != "" {
+ ldshlibsyms(ctxt, ctxt.Library[i].Shlib)
} else {
if DynlinkingGo() {
Exitf("cannot implicitly include runtime/cgo in a shared library")
}
- objfile(Ctxt.Library[i])
+ objfile(ctxt, ctxt.Library[i])
}
}
}
if Linkmode == LinkInternal {
// Drop all the cgo_import_static declarations.
// Turns out we won't be needing them.
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
if s.Type == obj.SHOSTOBJ {
// If a symbol was marked both
// cgo_import_static and cgo_import_dynamic,
}
}
- tlsg := Linklookup(Ctxt, "runtime.tlsg", 0)
+ tlsg := Linklookup(ctxt, "runtime.tlsg", 0)
// runtime.tlsg is used for external linking on platforms that do not define
// a variable to hold g in assembly (currently only intel).
tlsg.Type = obj.STLSBSS
tlsg.Size = int64(SysArch.PtrSize)
} else if tlsg.Type != obj.SDYNIMPORT {
- Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
+ ctxt.Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
}
tlsg.Attr |= AttrReachable
- Ctxt.Tlsg = tlsg
+ ctxt.Tlsg = tlsg
- moduledata := Linklookup(Ctxt, "runtime.firstmoduledata", 0)
+ moduledata := Linklookup(ctxt, "runtime.firstmoduledata", 0)
if moduledata.Type != 0 && moduledata.Type != obj.SDYNIMPORT {
// If the module (toolchain-speak for "executable or shared
// library") we are linking contains the runtime package, it
// In addition, on ARM, the runtime depends on the linker
// recording the value of GOARM.
if SysArch.Family == sys.ARM {
- s := Linklookup(Ctxt, "runtime.goarm", 0)
+ s := Linklookup(ctxt, "runtime.goarm", 0)
s.Type = obj.SRODATA
s.Size = 0
- Adduint8(Ctxt, s, uint8(Ctxt.Goarm))
+ Adduint8(ctxt, s, uint8(ctxt.Goarm))
}
if obj.Framepointer_enabled(obj.Getgoos(), obj.Getgoarch()) {
- s := Linklookup(Ctxt, "runtime.framepointer_enabled", 0)
+ s := Linklookup(ctxt, "runtime.framepointer_enabled", 0)
s.Type = obj.SRODATA
s.Size = 0
- Adduint8(Ctxt, s, 1)
+ Adduint8(ctxt, s, 1)
}
} else {
// If OTOH the module does not contain the runtime package,
// create a local symbol for the moduledata.
- moduledata = Linklookup(Ctxt, "local.moduledata", 0)
+ moduledata = Linklookup(ctxt, "local.moduledata", 0)
moduledata.Attr |= AttrLocal
}
// In all cases way we mark the moduledata as noptrdata to hide it from
// the GC.
moduledata.Type = obj.SNOPTRDATA
moduledata.Attr |= AttrReachable
- Ctxt.Moduledata = moduledata
+ ctxt.Moduledata = moduledata
// Now that we know the link mode, trim the dynexp list.
x := AttrCgoExportDynamic
// In internal link mode, read the host object files.
if Linkmode == LinkInternal {
- hostobjs()
+ hostobjs(ctxt)
// If we have any undefined symbols in external
// objects, try to read them from the libgcc file.
any := false
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
for _, r := range s.R {
if r.Sym != nil && r.Sym.Type&obj.SMASK == obj.SXREF && r.Sym.Name != ".got" {
any = true
}
if libgccfile != "none" {
- hostArchive(libgccfile)
+ hostArchive(ctxt, libgccfile)
}
}
} else {
return arsize + SAR_HDR
}
-func objfile(lib *Library) {
+func objfile(ctxt *Link, lib *Library) {
pkg := pathtoprefix(lib.Pkg)
if Debug['v'] > 1 {
l := f.Seek(0, 2)
f.Seek(0, 0)
- ldobj(f, pkg, l, lib.File, lib.File, FileObj)
+ ldobj(ctxt, f, pkg, l, lib.File, lib.File, FileObj)
f.Close()
return
l := nextar(f, off, &arhdr)
var pname string
if l <= 0 {
- Diag("%s: short read on archive file symbol header", lib.File)
+ ctxt.Diag("%s: short read on archive file symbol header", lib.File)
goto out
}
if !strings.HasPrefix(arhdr.name, pkgname) {
- Diag("%s: cannot find package header", lib.File)
+ ctxt.Diag("%s: cannot find package header", lib.File)
goto out
}
before := f.Offset()
pkgdefBytes := make([]byte, atolwhex(arhdr.size))
if _, err := io.ReadFull(f, pkgdefBytes); err != nil {
- Diag("%s: short read on archive file symbol header: %v", lib.File, err)
+ ctxt.Diag("%s: short read on archive file symbol header: %v", lib.File, err)
}
hash := sha1.Sum(pkgdefBytes)
lib.hash = hash[:]
off += l
- ldpkg(f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
+ ldpkg(ctxt, f, pkg, atolwhex(arhdr.size), lib.File, Pkgdef)
/*
* load all the object files from the archive now.
pname = fmt.Sprintf("%s(%s)", lib.File, arhdr.name)
l = atolwhex(arhdr.size)
- ldobj(f, pkg, l, pname, lib.File, ArchiveObj)
+ ldobj(ctxt, f, pkg, l, pname, lib.File, ArchiveObj)
}
out:
}
type Hostobj struct {
- ld func(*bio.Reader, string, int64, string)
+ ld func(*Link, *bio.Reader, string, int64, string)
pkg string
pn string
file string
"runtime/msan",
}
-func ldhostobj(ld func(*bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
+func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), f *bio.Reader, pkg string, length int64, pn string, file string) *Hostobj {
isinternal := false
for i := 0; i < len(internalpkg); i++ {
if pkg == internalpkg[i] {
return h
}
-func hostobjs() {
+func hostobjs(ctxt *Link) {
var h *Hostobj
for i := 0; i < len(hostobj); i++ {
}
f.Seek(h.off, 0)
- h.ld(f, h.pkg, h.length, h.pn)
+ h.ld(ctxt, f, h.pkg, h.length, h.pn)
f.Close()
}
}
}
}
-func hostlink() {
+func (l *Link) hostlink() {
if Linkmode != LinkExternal || nerrors > 0 {
return
}
seenLibs[base] = true
}
}
- for _, shlib := range Ctxt.Shlibs {
+ for _, shlib := range l.Shlibs {
addshlib(shlib.Path)
for _, dep := range shlib.Deps {
if dep == "" {
continue
}
- libpath := findshlib(dep)
+ libpath := findshlib(l, dep)
if libpath != "" {
addshlib(libpath)
}
// new and we test for its support first.
src := filepath.Join(tmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
- Ctxt.Diag("WriteFile trivial.c failed: %v", err)
+ l.Diag("WriteFile trivial.c failed: %v", err)
}
cmd := exec.Command(argv[0], "-c", "-no-pie", "trivial.c")
cmd.Dir = tmpdir
if !SysArch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(tmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil {
- Ctxt.Cursym = nil
+ l.Cursym = nil
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
}
// Skip combining if `dsymutil` didn't generate a file. See #11994.
// For os.Rename to work reliably, must be in same directory as outfile.
combinedOutput := outfile + "~"
if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil {
- Ctxt.Cursym = nil
+ l.Cursym = nil
Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
}
os.Remove(outfile)
if err := os.Rename(combinedOutput, outfile); err != nil {
- Ctxt.Cursym = nil
+ l.Cursym = nil
Exitf("%s: %v", os.Args[0], err)
}
}
// ldobj loads an input object. If it is a host object (an object
// compiled by a non-Go compiler) it returns the Hostobj pointer. If
// it is a Go object, it returns nil.
-func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, whence int) *Hostobj {
+func ldobj(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string, file string, whence int) *Hostobj {
eof := f.Offset() + length
start := f.Offset()
/* check the header */
line, err := f.ReadString('\n')
if err != nil {
- Diag("truncated object file: %s: %v", pn, err)
+ ctxt.Diag("truncated object file: %s: %v", pn, err)
return nil
}
if line == SysArch.Name {
// old header format: just $GOOS
- Diag("%s: stale object file", pn)
+ ctxt.Diag("%s: stale object file", pn)
return nil
}
- Diag("%s: not an object file", pn)
+ ctxt.Diag("%s: not an object file", pn)
return nil
}
line = strings.TrimRight(line, "\n")
if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 {
- Diag("%s: object is [%s] expected [%s]", pn, line[10:], t)
+ ctxt.Diag("%s: object is [%s] expected [%s]", pn, line[10:], t)
return nil
}
if theline == "" {
theline = line[10:]
} else if theline != line[10:] {
- Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline)
+ ctxt.Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline)
return nil
}
}
c2 = c3
c3 = bgetc(f)
if c3 == -1 {
- Diag("truncated object file: %s", pn)
+ ctxt.Diag("truncated object file: %s", pn)
return nil
}
}
import1 := f.Offset()
f.Seek(import0, 0)
- ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n
+ ldpkg(ctxt, f, pkg, import1-import0-2, pn, whence) // -2 for !\n
f.Seek(import1, 0)
- LoadObjFile(Ctxt, f, pkg, eof-f.Offset(), pn)
+ LoadObjFile(ctxt, f, pkg, eof-f.Offset(), pn)
return nil
}
-func readelfsymboldata(f *elf.File, sym *elf.Symbol) []byte {
+func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
data := make([]byte, sym.Size)
sect := f.Sections[sym.Section]
if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
- Diag("reading %s from non-data section", sym.Name)
+ ctxt.Diag("reading %s from non-data section", sym.Name)
}
n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
if uint64(n) != sym.Size {
- Diag("reading contents of %s: %v", sym.Name, err)
+ ctxt.Diag("reading contents of %s: %v", sym.Name, err)
}
return data
}
return nil, nil
}
-func findshlib(shlib string) string {
- for _, libdir := range Ctxt.Libdir {
+func findshlib(ctxt *Link, shlib string) string {
+ for _, libdir := range ctxt.Libdir {
libpath := filepath.Join(libdir, shlib)
if _, err := os.Stat(libpath); err == nil {
return libpath
}
}
- Diag("cannot find shared library: %s", shlib)
+ ctxt.Diag("cannot find shared library: %s", shlib)
return ""
}
-func ldshlibsyms(shlib string) {
- libpath := findshlib(shlib)
+func ldshlibsyms(ctxt *Link, shlib string) {
+ libpath := findshlib(ctxt, shlib)
if libpath == "" {
return
}
- for _, processedlib := range Ctxt.Shlibs {
+ for _, processedlib := range ctxt.Shlibs {
if processedlib.Path == libpath {
return
}
}
- if Ctxt.Debugvlog > 1 && Ctxt.Bso != nil {
- fmt.Fprintf(Ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath)
- Ctxt.Bso.Flush()
+ if ctxt.Debugvlog > 1 && ctxt.Bso != nil {
+ fmt.Fprintf(ctxt.Bso, "%5.2f ldshlibsyms: found library with name %s at %s\n", obj.Cputime(), shlib, libpath)
+ ctxt.Bso.Flush()
}
f, err := elf.Open(libpath)
if err != nil {
- Diag("cannot open shared library: %s", libpath)
+ ctxt.Diag("cannot open shared library: %s", libpath)
return
}
hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
if err != nil {
- Diag("cannot read ABI hash from shared library %s: %v", libpath, err)
+ ctxt.Diag("cannot read ABI hash from shared library %s: %v", libpath, err)
return
}
depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
if err != nil {
- Diag("cannot read dep list from shared library %s: %v", libpath, err)
+ ctxt.Diag("cannot read dep list from shared library %s: %v", libpath, err)
return
}
deps := strings.Split(string(depsbytes), "\n")
syms, err := f.DynamicSymbols()
if err != nil {
- Diag("cannot read symbols from shared library: %s", libpath)
+ ctxt.Diag("cannot read symbols from shared library: %s", libpath)
return
}
gcdata_locations := make(map[uint64]*Symbol)
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
continue
}
- lsym := Linklookup(Ctxt, elfsym.Name, 0)
+ lsym := Linklookup(ctxt, elfsym.Name, 0)
// Because loadlib above loads all .a files before loading any shared
// libraries, any non-dynimport symbols we find that duplicate symbols
// already loaded should be ignored (the symbols from the .a files
// The decodetype_* functions in decodetype.go need access to
// the type data.
if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
- lsym.P = readelfsymboldata(f, &elfsym)
+ lsym.P = readelfsymboldata(ctxt, f, &elfsym)
gcdata_locations[elfsym.Value+2*uint64(SysArch.PtrSize)+8+1*uint64(SysArch.PtrSize)] = lsym
}
}
if err == io.EOF {
break
} else if err != nil {
- Diag("reading relocation failed %v", err)
+ ctxt.Diag("reading relocation failed %v", err)
return
}
t := elf.R_AARCH64(rela.Info & 0xffff)
// We might have overwritten some functions above (this tends to happen for the
// autogenerated type equality/hashing functions) and we don't want to generated
// pcln table entries for these any more so remove them from Textp.
- textp := make([]*Symbol, 0, len(Ctxt.Textp))
- for _, s := range Ctxt.Textp {
+ textp := make([]*Symbol, 0, len(ctxt.Textp))
+ for _, s := range ctxt.Textp {
if s.Type != obj.SDYNIMPORT {
textp = append(textp, s)
}
}
- Ctxt.Textp = textp
+ ctxt.Textp = textp
- Ctxt.Shlibs = append(Ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdata_addresses: gcdata_addresses})
+ ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f, gcdata_addresses: gcdata_addresses})
}
func mywhatsys() {
// TODO: Record enough information in new object files to
// allow stack checks here.
-func haslinkregister() bool {
- return Ctxt.FixedFrameSize() != 0
+func haslinkregister(ctxt *Link) bool {
+ return ctxt.FixedFrameSize() != 0
}
-func callsize() int {
- if haslinkregister() {
+func callsize(ctxt *Link) int {
+ if haslinkregister(ctxt) {
return 0
}
return SysArch.RegSize
}
-func dostkcheck() {
+func (ctxt *Link) dostkcheck() {
var ch Chain
- morestack = Linklookup(Ctxt, "runtime.morestack", 0)
+ morestack = Linklookup(ctxt, "runtime.morestack", 0)
// Every splitting function ensures that there are at least StackLimit
// bytes available below SP when the splitting prologue finishes.
// of non-splitting functions.
ch.up = nil
- ch.limit = obj.StackLimit - callsize()
+ ch.limit = obj.StackLimit - callsize(ctxt)
// Check every function, but do the nosplit functions in a first pass,
// to make the printed failure chains as short as possible.
- for _, s := range Ctxt.Textp {
+ for _, s := range ctxt.Textp {
// runtime.racesymbolizethunk is called from gcc-compiled C
// code running on the operating system thread stack.
// It uses more than the usual amount of stack but that's okay.
}
if s.Attr.NoSplit() {
- Ctxt.Cursym = s
+ ctxt.Cursym = s
ch.sym = s
- stkcheck(&ch, 0)
+ stkcheck(ctxt, &ch, 0)
}
}
- for _, s := range Ctxt.Textp {
+ for _, s := range ctxt.Textp {
if !s.Attr.NoSplit() {
- Ctxt.Cursym = s
+ ctxt.Cursym = s
ch.sym = s
- stkcheck(&ch, 0)
+ stkcheck(ctxt, &ch, 0)
}
}
}
-func stkcheck(up *Chain, depth int) int {
+func stkcheck(ctxt *Link, up *Chain, depth int) int {
limit := up.limit
s := up.sym
// Don't duplicate work: only need to consider each
// function at top of safe zone once.
- top := limit == obj.StackLimit-callsize()
+ top := limit == obj.StackLimit-callsize(ctxt)
if top {
if s.Attr.StackCheck() {
return 0
}
if depth > 100 {
- Diag("nosplit stack check too deep")
- stkbroke(up, 0)
+ ctxt.Diag("nosplit stack check too deep")
+ stkbroke(ctxt, up, 0)
return -1
}
if s.Attr.External() || s.FuncInfo == nil {
// external function.
// should never be called directly.
- // only diagnose the direct caller.
+ // onlyctxt.Diagnose the direct caller.
// TODO(mwhudson): actually think about this.
if depth == 1 && s.Type != obj.SXREF && !DynlinkingGo() &&
Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared {
- Diag("call to external function %s", s.Name)
+ ctxt.Diag("call to external function %s", s.Name)
}
return -1
}
if limit < 0 {
- stkbroke(up, limit)
+ stkbroke(ctxt, up, limit)
return -1
}
if !s.Attr.NoSplit() {
// Ensure we have enough stack to call morestack.
- ch.limit = limit - callsize()
+ ch.limit = limit - callsize(ctxt)
ch.sym = morestack
- if stkcheck(&ch, depth+1) < 0 {
+ if stkcheck(ctxt, &ch, depth+1) < 0 {
return -1
}
if !top {
if s.FuncInfo != nil {
locals = s.FuncInfo.Locals
}
- limit = int(obj.StackLimit+locals) + int(Ctxt.FixedFrameSize())
+ limit = int(obj.StackLimit+locals) + int(ctxt.FixedFrameSize())
}
// Walk through sp adjustments in function, consuming relocs.
var ch1 Chain
var pcsp Pciter
var r *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).
// Check stack size in effect for this span.
if int32(limit)-pcsp.value < 0 {
- stkbroke(up, int(int32(limit)-pcsp.value))
+ stkbroke(ctxt, up, int(int32(limit)-pcsp.value))
return -1
}
switch r.Type {
// Direct call.
case obj.R_CALL, obj.R_CALLARM, obj.R_CALLARM64, obj.R_CALLPOWER, obj.R_CALLMIPS:
- ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
+ ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
ch.sym = r.Sym
- if stkcheck(&ch, depth+1) < 0 {
+ if stkcheck(ctxt, &ch, depth+1) < 0 {
return -1
}
// Arrange the data structures to report both calls, so that
// if there is an error, stkprint shows all the steps involved.
case obj.R_CALLIND:
- ch.limit = int(int32(limit) - pcsp.value - int32(callsize()))
+ ch.limit = int(int32(limit) - pcsp.value - int32(callsize(ctxt)))
ch.sym = nil
- ch1.limit = ch.limit - callsize() // for morestack in called prologue
+ ch1.limit = ch.limit - callsize(ctxt) // for morestack in called prologue
ch1.up = &ch
ch1.sym = morestack
- if stkcheck(&ch1, depth+2) < 0 {
+ if stkcheck(ctxt, &ch1, depth+2) < 0 {
return -1
}
}
return 0
}
-func stkbroke(ch *Chain, limit int) {
- Diag("nosplit stack overflow")
- stkprint(ch, limit)
+func stkbroke(ctxt *Link, ch *Chain, limit int) {
+ ctxt.Diag("nosplit stack overflow")
+ stkprint(ctxt, ch, limit)
}
-func stkprint(ch *Chain, limit int) {
+func stkprint(ctxt *Link, ch *Chain, limit int) {
var name string
if ch.sym != nil {
fmt.Printf("\t%d\tguaranteed after split check in %s\n", ch.limit, name)
}
} else {
- stkprint(ch.up, ch.limit+callsize())
- if !haslinkregister() {
+ stkprint(ctxt, ch.up, ch.limit+callsize(ctxt))
+ if !haslinkregister(ctxt) {
fmt.Printf("\t%d\ton entry to %s\n", ch.limit, name)
}
}
Exitf("version %s", obj.Getgoversion())
}
-func genasmsym(put func(*Symbol, string, int, int64, int64, int, *Symbol)) {
+func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, int, int64, int64, int, *Symbol)) {
// These symbols won't show up in the first loop below because we
// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
- s := Linklookup(Ctxt, "runtime.text", 0)
+ s := Linklookup(ctxt, "runtime.text", 0)
if s.Type == obj.STEXT {
- put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
+ put(ctxt, s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
}
- s = Linklookup(Ctxt, "runtime.etext", 0)
+ s = Linklookup(ctxt, "runtime.etext", 0)
if s.Type == obj.STEXT {
- put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
+ put(ctxt, s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
}
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
if s.Attr.Hidden() {
continue
}
if !s.Attr.Reachable() {
continue
}
- put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype)
+ put(ctxt, s, s.Name, 'D', Symaddr(ctxt, s), s.Size, int(s.Version), s.Gotype)
case obj.SBSS, obj.SNOPTRBSS:
if !s.Attr.Reachable() {
continue
}
if len(s.P) > 0 {
- Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, len(s.P), s.Type, s.Attr.Special())
+ ctxt.Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, len(s.P), s.Type, s.Attr.Special())
}
- put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype)
+ put(ctxt, s, s.Name, 'B', Symaddr(ctxt, s), s.Size, int(s.Version), s.Gotype)
case obj.SFILE:
- put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil)
+ put(ctxt, nil, s.Name, 'f', s.Value, 0, int(s.Version), nil)
case obj.SHOSTOBJ:
if HEADTYPE == obj.Hwindows || Iself {
- put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil)
+ put(ctxt, s, s.Name, 'U', s.Value, 0, int(s.Version), nil)
}
case obj.SDYNIMPORT:
if !s.Attr.Reachable() {
continue
}
- put(s, s.Extname, 'U', 0, 0, int(s.Version), nil)
+ put(ctxt, s, s.Extname, 'U', 0, 0, int(s.Version), nil)
case obj.STLSBSS:
if Linkmode == LinkExternal && HEADTYPE != obj.Hopenbsd {
- put(s, s.Name, 't', Symaddr(s), s.Size, int(s.Version), s.Gotype)
+ put(ctxt, s, s.Name, 't', Symaddr(ctxt, s), s.Size, int(s.Version), s.Gotype)
}
}
}
var off int32
- for _, s := range Ctxt.Textp {
- put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
+ for _, s := range ctxt.Textp {
+ put(ctxt, s, s.Name, 'T', s.Value, s.Size, int(s.Version), s.Gotype)
locals := int32(0)
if s.FuncInfo != nil {
locals = s.FuncInfo.Locals
}
// NOTE(ality): acid can't produce a stack trace without .frame symbols
- put(nil, ".frame", 'm', int64(locals)+int64(SysArch.PtrSize), 0, 0, nil)
+ put(ctxt, nil, ".frame", 'm', int64(locals)+int64(SysArch.PtrSize), 0, 0, nil)
if s.FuncInfo == nil {
continue
// FP
if off >= 0 {
- put(nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype)
+ put(ctxt, nil, a.Asym.Name, 'p', int64(off), 0, 0, a.Gotype)
continue
}
// SP
if off <= int32(-SysArch.PtrSize) {
- put(nil, a.Asym.Name, 'a', -(int64(off) + int64(SysArch.PtrSize)), 0, 0, a.Gotype)
+ put(ctxt, nil, a.Asym.Name, 'a', -(int64(off) + int64(SysArch.PtrSize)), 0, 0, a.Gotype)
continue
}
}
Bso.Flush()
}
-func Symaddr(s *Symbol) int64 {
+func Symaddr(ctxt *Link, s *Symbol) int64 {
if !s.Attr.Reachable() {
- Diag("unreachable symbol in symaddr - %s", s.Name)
+ ctxt.Diag("unreachable symbol in symaddr - %s", s.Name)
}
return s.Value
}
-func xdefine(p string, t int, v int64) {
- s := Linklookup(Ctxt, p, 0)
+func (ctxt *Link) xdefine(p string, t int, v int64) {
+ s := Linklookup(ctxt, p, 0)
s.Type = int16(t)
s.Value = v
s.Attr |= AttrReachable
s.Attr |= AttrLocal
}
-func datoff(addr int64) int64 {
+func datoff(ctxt *Link, addr int64) int64 {
if uint64(addr) >= Segdata.Vaddr {
return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
}
if uint64(addr) >= Segtext.Vaddr {
return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
}
- Diag("datoff %#x", addr)
+ ctxt.Diag("datoff %#x", addr)
return 0
}
-func Entryvalue() int64 {
+func Entryvalue(ctxt *Link) int64 {
a := INITENTRY
if a[0] >= '0' && a[0] <= '9' {
return atolwhex(a)
}
- s := Linklookup(Ctxt, a, 0)
+ s := Linklookup(ctxt, a, 0)
if s.Type == 0 {
return INITTEXT
}
if s.Type != obj.STEXT {
- Diag("entry not text: %s", s.Name)
+ ctxt.Diag("entry not text: %s", s.Name)
}
return s.Value
}
-func undefsym(s *Symbol) {
+func undefsym(ctxt *Link, s *Symbol) {
var r *Reloc
- Ctxt.Cursym = s
+ ctxt.Cursym = s
for i := 0; i < len(s.R); i++ {
r = &s.R[i]
if r.Sym == nil { // happens for some external ARM relocs
continue
}
if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF {
- Diag("undefined: %s", r.Sym.Name)
+ ctxt.Diag("undefined: %s", r.Sym.Name)
}
if !r.Sym.Attr.Reachable() {
- Diag("use of unreachable symbol: %s", r.Sym.Name)
+ ctxt.Diag("use of unreachable symbol: %s", r.Sym.Name)
}
}
}
-func undef() {
- for _, s := range Ctxt.Textp {
- undefsym(s)
+func (ctxt *Link) undef() {
+ for _, s := range ctxt.Textp {
+ undefsym(ctxt, s)
}
for _, s := range datap {
- undefsym(s)
+ undefsym(ctxt, s)
}
if nerrors > 0 {
errorexit()
}
}
-func callgraph() {
+func (ctxt *Link) callgraph() {
if Debug['c'] == 0 {
return
}
var i int
var r *Reloc
- for _, s := range Ctxt.Textp {
+ for _, s := range ctxt.Textp {
for i = 0; i < len(s.R); i++ {
r = &s.R[i]
if r.Sym == nil {
}
}
-func Diag(format string, args ...interface{}) {
+func (ctxt *Link) Diag(format string, args ...interface{}) {
tn := ""
sep := ""
- if Ctxt.Cursym != nil {
- tn = Ctxt.Cursym.Name
+ if ctxt.Cursym != nil {
+ tn = ctxt.Cursym.Name
sep = ": "
}
fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...))
// Symbol lookup based on name and indexed by version.
Hash []map[string]*Symbol
- Allsym []*Symbol
- Tlsg *Symbol
- Libdir []string
- Library []*Library
- Shlibs []Shlib
- Tlsoffset int
- Diag func(string, ...interface{})
+ Allsym []*Symbol
+ Tlsg *Symbol
+ Libdir []string
+ Library []*Library
+ Shlibs []Shlib
+ Tlsoffset int
+
Cursym *Symbol
Version int
Textp []*Symbol
return int(Cpos() - o1)
}
-func domacho() {
+func (ctxt *Link) domacho() {
if Debug['d'] != 0 {
return
}
// empirically, string table must begin with " \x00".
- s := Linklookup(Ctxt, ".machosymstr", 0)
+ s := Linklookup(ctxt, ".machosymstr", 0)
s.Type = obj.SMACHOSYMSTR
s.Attr |= AttrReachable
- Adduint8(Ctxt, s, ' ')
- Adduint8(Ctxt, s, '\x00')
+ Adduint8(ctxt, s, ' ')
+ Adduint8(ctxt, s, '\x00')
- s = Linklookup(Ctxt, ".machosymtab", 0)
+ s = Linklookup(ctxt, ".machosymtab", 0)
s.Type = obj.SMACHOSYMTAB
s.Attr |= AttrReachable
if Linkmode != LinkExternal {
- s := Linklookup(Ctxt, ".plt", 0) // will be __symbol_stub
+ s := Linklookup(ctxt, ".plt", 0) // will be __symbol_stub
s.Type = obj.SMACHOPLT
s.Attr |= AttrReachable
- s = Linklookup(Ctxt, ".got", 0) // will be __nl_symbol_ptr
+ s = Linklookup(ctxt, ".got", 0) // will be __nl_symbol_ptr
s.Type = obj.SMACHOGOT
s.Attr |= AttrReachable
s.Align = 4
- s = Linklookup(Ctxt, ".linkedit.plt", 0) // indirect table for .plt
+ s = Linklookup(ctxt, ".linkedit.plt", 0) // indirect table for .plt
s.Type = obj.SMACHOINDIRECTPLT
s.Attr |= AttrReachable
- s = Linklookup(Ctxt, ".linkedit.got", 0) // indirect table for .got
+ s = Linklookup(ctxt, ".linkedit.got", 0) // indirect table for .got
s.Type = obj.SMACHOINDIRECTGOT
s.Attr |= AttrReachable
}
dylib = append(dylib, lib)
}
-func machoshbits(mseg *MachoSeg, sect *Section, segname string) {
+func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
var msect *MachoSect
if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
// data in file
if sect.Length > sect.Seg.Vaddr+sect.Seg.Filelen-sect.Vaddr {
- Diag("macho cannot represent section %s crossing data and bss", sect.Name)
+ ctxt.Diag("macho cannot represent section %s crossing data and bss", sect.Name)
}
msect.off = uint32(sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr)
} else {
if sect.Name == ".got" {
msect.name = "__nl_symbol_ptr"
msect.flag = 6 /* section with nonlazy symbol pointers */
- msect.res1 = uint32(Linklookup(Ctxt, ".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
+ msect.res1 = uint32(Linklookup(ctxt, ".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
}
if sect.Name == ".init_array" {
}
}
-func Asmbmacho() {
+func Asmbmacho(ctxt *Link) {
/* apple MACH */
va := INITTEXT - int64(HEADR)
}
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
- machoshbits(ms, sect, "__TEXT")
+ machoshbits(ctxt, ms, sect, "__TEXT")
}
/* data */
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- machoshbits(ms, sect, "__DATA")
+ machoshbits(ctxt, ms, sect, "__DATA")
}
/* dwarf */
ms.filesize = Segdwarf.Filelen
}
for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
- machoshbits(ms, sect, "__DWARF")
+ machoshbits(ctxt, ms, sect, "__DWARF")
}
}
Exitf("unknown macho architecture: %v", SysArch.Family)
case sys.ARM:
- ml := newMachoLoad(5, 17+2) /* unix thread */
- ml.data[0] = 1 /* thread type */
- ml.data[1] = 17 /* word count */
- ml.data[2+15] = uint32(Entryvalue()) /* start pc */
+ ml := newMachoLoad(5, 17+2) /* unix thread */
+ ml.data[0] = 1 /* thread type */
+ ml.data[1] = 17 /* word count */
+ ml.data[2+15] = uint32(Entryvalue(ctxt)) /* start pc */
case sys.AMD64:
- ml := newMachoLoad(5, 42+2) /* unix thread */
- ml.data[0] = 4 /* thread type */
- ml.data[1] = 42 /* word count */
- ml.data[2+32] = uint32(Entryvalue()) /* start pc */
- ml.data[2+32+1] = uint32(Entryvalue() >> 32)
+ ml := newMachoLoad(5, 42+2) /* unix thread */
+ ml.data[0] = 4 /* thread type */
+ ml.data[1] = 42 /* word count */
+ ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */
+ ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32)
case sys.ARM64:
- ml := newMachoLoad(5, 68+2) /* unix thread */
- ml.data[0] = 6 /* thread type */
- ml.data[1] = 68 /* word count */
- ml.data[2+64] = uint32(Entryvalue()) /* start pc */
- ml.data[2+64+1] = uint32(Entryvalue() >> 32)
+ ml := newMachoLoad(5, 68+2) /* unix thread */
+ ml.data[0] = 6 /* thread type */
+ ml.data[1] = 68 /* word count */
+ ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */
+ ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32)
case sys.I386:
- ml := newMachoLoad(5, 16+2) /* unix thread */
- ml.data[0] = 1 /* thread type */
- ml.data[1] = 16 /* word count */
- ml.data[2+10] = uint32(Entryvalue()) /* start pc */
+ ml := newMachoLoad(5, 16+2) /* unix thread */
+ ml.data[0] = 1 /* thread type */
+ ml.data[1] = 16 /* word count */
+ ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */
}
}
if Debug['d'] == 0 {
// must match domacholink below
- s1 := Linklookup(Ctxt, ".machosymtab", 0)
- s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
- s3 := Linklookup(Ctxt, ".linkedit.got", 0)
- s4 := Linklookup(Ctxt, ".machosymstr", 0)
+ s1 := Linklookup(ctxt, ".machosymtab", 0)
+ s2 := Linklookup(ctxt, ".linkedit.plt", 0)
+ s3 := Linklookup(ctxt, ".linkedit.got", 0)
+ s4 := Linklookup(ctxt, ".machosymstr", 0)
if Linkmode != LinkExternal {
ms := newMachoSeg("__LINKEDIT", 0)
ml.data[2] = uint32(linkoff + s1.Size + s2.Size + s3.Size) /* stroff */
ml.data[3] = uint32(s4.Size) /* strsize */
- machodysymtab()
+ machodysymtab(ctxt)
if Linkmode != LinkExternal {
ml := newMachoLoad(14, 6) /* LC_LOAD_DYLINKER */
return SymKindLocal
}
-func addsym(s *Symbol, name string, type_ int, addr int64, size int64, ver int, gotype *Symbol) {
+func addsym(ctxt *Link, s *Symbol, name string, type_ int, addr int64, size int64, ver int, gotype *Symbol) {
if s == nil {
return
}
return s1.Extname < s2.Extname
}
-func machogenasmsym(put func(*Symbol, string, int, int64, int64, int, *Symbol)) {
- genasmsym(put)
- for _, s := range Ctxt.Allsym {
+func machogenasmsym(ctxt *Link, put func(*Link, *Symbol, string, int, int64, int64, int, *Symbol)) {
+ genasmsym(ctxt, put)
+ for _, s := range ctxt.Allsym {
if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
if s.Attr.Reachable() {
- put(s, "", 'D', 0, 0, 0, nil)
+ put(ctxt, s, "", 'D', 0, 0, 0, nil)
}
}
}
}
-func machosymorder() {
+func machosymorder(ctxt *Link) {
// On Mac OS X Mountain Lion, we must sort exported symbols
// So we sort them here and pre-allocate dynid for them
// See https://golang.org/issue/4029
for i := 0; i < len(dynexp); i++ {
dynexp[i].Attr |= AttrReachable
}
- machogenasmsym(addsym)
+ machogenasmsym(ctxt, addsym)
sortsym = make([]*Symbol, nsortsym)
nsortsym = 0
- machogenasmsym(addsym)
+ machogenasmsym(ctxt, addsym)
sort.Sort(machoscmp(sortsym[:nsortsym]))
for i := 0; i < nsortsym; i++ {
sortsym[i].Dynid = int32(i)
}
}
-func machosymtab() {
- symtab := Linklookup(Ctxt, ".machosymtab", 0)
- symstr := Linklookup(Ctxt, ".machosymstr", 0)
+func machosymtab(ctxt *Link) {
+ symtab := Linklookup(ctxt, ".machosymtab", 0)
+ symstr := Linklookup(ctxt, ".machosymstr", 0)
for i := 0; i < nsortsym; i++ {
s := sortsym[i]
- Adduint32(Ctxt, symtab, uint32(symstr.Size))
+ Adduint32(ctxt, symtab, uint32(symstr.Size))
// Only add _ to C symbols. Go symbols have dot in the name.
if !strings.Contains(s.Extname, ".") {
- Adduint8(Ctxt, symstr, '_')
+ Adduint8(ctxt, symstr, '_')
}
// replace "·" as ".", because DTrace cannot handle it.
- Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
+ Addstring(ctxt, symstr, strings.Replace(s.Extname, "·", ".", -1))
if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
- Adduint8(Ctxt, symtab, 0x01) // type N_EXT, external symbol
- Adduint8(Ctxt, symtab, 0) // no section
- Adduint16(Ctxt, symtab, 0) // desc
- adduintxx(Ctxt, symtab, 0, SysArch.PtrSize) // no value
+ Adduint8(ctxt, symtab, 0x01) // type N_EXT, external symbol
+ Adduint8(ctxt, symtab, 0) // no section
+ Adduint16(ctxt, symtab, 0) // desc
+ adduintxx(ctxt, symtab, 0, SysArch.PtrSize) // no value
} else {
if s.Attr.CgoExport() {
- Adduint8(Ctxt, symtab, 0x0f)
+ Adduint8(ctxt, symtab, 0x0f)
} else {
- Adduint8(Ctxt, symtab, 0x0e)
+ Adduint8(ctxt, symtab, 0x0e)
}
o := s
for o.Outer != nil {
o = o.Outer
}
if o.Sect == nil {
- Diag("missing section for %s", s.Name)
- Adduint8(Ctxt, symtab, 0)
+ ctxt.Diag("missing section for %s", s.Name)
+ Adduint8(ctxt, symtab, 0)
} else {
- Adduint8(Ctxt, symtab, uint8(o.Sect.Extnum))
+ Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
}
- Adduint16(Ctxt, symtab, 0) // desc
- adduintxx(Ctxt, symtab, uint64(Symaddr(s)), SysArch.PtrSize)
+ Adduint16(ctxt, symtab, 0) // desc
+ adduintxx(ctxt, symtab, uint64(Symaddr(ctxt, s)), SysArch.PtrSize)
}
}
}
-func machodysymtab() {
+func machodysymtab(ctxt *Link) {
ml := newMachoLoad(11, 18) /* LC_DYSYMTAB */
n := 0
ml.data[11] = 0 /* nextrefsyms */
// must match domacholink below
- s1 := Linklookup(Ctxt, ".machosymtab", 0)
+ s1 := Linklookup(ctxt, ".machosymtab", 0)
- s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
- s3 := Linklookup(Ctxt, ".linkedit.got", 0)
+ s2 := Linklookup(ctxt, ".linkedit.plt", 0)
+ s3 := Linklookup(ctxt, ".linkedit.got", 0)
ml.data[12] = uint32(linkoff + s1.Size) /* indirectsymoff */
ml.data[13] = uint32((s2.Size + s3.Size) / 4) /* nindirectsyms */
ml.data[17] = 0 /* nlocrel */
}
-func Domacholink() int64 {
- machosymtab()
+func Domacholink(ctxt *Link) int64 {
+ machosymtab(ctxt)
// write data that will be linkedit section
- s1 := Linklookup(Ctxt, ".machosymtab", 0)
+ s1 := Linklookup(ctxt, ".machosymtab", 0)
- s2 := Linklookup(Ctxt, ".linkedit.plt", 0)
- s3 := Linklookup(Ctxt, ".linkedit.got", 0)
- s4 := Linklookup(Ctxt, ".machosymstr", 0)
+ s2 := Linklookup(ctxt, ".linkedit.plt", 0)
+ s3 := Linklookup(ctxt, ".linkedit.got", 0)
+ s4 := Linklookup(ctxt, ".machosymstr", 0)
// Force the linkedit section to end on a 16-byte
// boundary. This allows pure (non-cgo) Go binaries
// any alignment padding itself, working around the
// issue.
for s4.Size%16 != 0 {
- Adduint8(Ctxt, s4, 0)
+ Adduint8(ctxt, s4, 0)
}
size := int(s1.Size + s2.Size + s3.Size + s4.Size)
return Rnd(int64(size), int64(INITRND))
}
-func machorelocsect(sect *Section, syms []*Symbol) {
+func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
// If main section has no bits, nothing to relocate.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
return
if sym.Value >= int64(eaddr) {
break
}
- Ctxt.Cursym = sym
+ ctxt.Cursym = sym
for ri := 0; ri < len(sym.R); ri++ {
r := &sym.R[ri]
continue
}
if Thearch.Machoreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
- Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
+ ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
}
}
}
sect.Rellen = uint64(Cpos()) - sect.Reloff
}
-func Machoemitreloc() {
+func Machoemitreloc(ctxt *Link) {
for Cpos()&7 != 0 {
Cput(0)
}
- machorelocsect(Segtext.Sect, Ctxt.Textp)
+ machorelocsect(ctxt, Segtext.Sect, ctxt.Textp)
for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
- machorelocsect(sect, datap)
+ machorelocsect(ctxt, sect, datap)
}
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- machorelocsect(sect, datap)
+ machorelocsect(ctxt, sect, datap)
}
for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
- machorelocsect(sect, list2slice(dwarfp))
+ machorelocsect(ctxt, sect, list2slice(dwarfp))
}
}
p[0] = byte(v)
}
-func addpctab(ftab *Symbol, off int32, d *Pcdata) int32 {
+func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 {
var start int32
if len(d.P) > 0 {
start = int32(len(ftab.P))
- Addbytes(Ctxt, ftab, d.P)
+ Addbytes(ctxt, ftab, d.P)
}
- return int32(setuint32(Ctxt, ftab, int64(off), uint32(start)))
+ return int32(setuint32(ctxt, ftab, int64(off), uint32(start)))
}
-func ftabaddstring(ftab *Symbol, s string) int32 {
+func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 {
n := int32(len(s)) + 1
start := int32(len(ftab.P))
- Symgrow(Ctxt, ftab, int64(start)+int64(n)+1)
+ Symgrow(ctxt, ftab, int64(start)+int64(n)+1)
copy(ftab.P[start:], s)
return start
}
var pclntabFirstFunc *Symbol
var pclntabLastFunc *Symbol
-func pclntab() {
+func (ctxt *Link) pclntab() {
funcdata_bytes := int64(0)
- ftab := Linklookup(Ctxt, "runtime.pclntab", 0)
+ ftab := Linklookup(ctxt, "runtime.pclntab", 0)
ftab.Type = obj.SPCLNTAB
ftab.Attr |= AttrReachable
nfunc := int32(0)
// Find container symbols, mark them with SCONTAINER
- for _, s := range Ctxt.Textp {
+ for _, s := range ctxt.Textp {
if s.Outer != nil {
s.Outer.Type |= obj.SCONTAINER
}
}
- for _, s := range Ctxt.Textp {
+ for _, s := range ctxt.Textp {
if container(s) == 0 {
nfunc++
}
}
pclntabNfunc = nfunc
- Symgrow(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize)+4)
- setuint32(Ctxt, ftab, 0, 0xfffffffb)
- setuint8(Ctxt, ftab, 6, uint8(SysArch.MinLC))
- setuint8(Ctxt, ftab, 7, uint8(SysArch.PtrSize))
- setuintxx(Ctxt, ftab, 8, uint64(nfunc), int64(SysArch.PtrSize))
+ Symgrow(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize)+4)
+ setuint32(ctxt, ftab, 0, 0xfffffffb)
+ setuint8(ctxt, ftab, 6, uint8(SysArch.MinLC))
+ setuint8(ctxt, ftab, 7, uint8(SysArch.PtrSize))
+ setuintxx(ctxt, ftab, 8, uint64(nfunc), int64(SysArch.PtrSize))
pclntabPclntabOffset = int32(8 + SysArch.PtrSize)
nfunc = 0
var last *Symbol
- for _, Ctxt.Cursym = range Ctxt.Textp {
- last = Ctxt.Cursym
- if container(Ctxt.Cursym) != 0 {
+ for _, ctxt.Cursym = range ctxt.Textp {
+ last = ctxt.Cursym
+ if container(ctxt.Cursym) != 0 {
continue
}
- pcln := Ctxt.Cursym.FuncInfo
+ pcln := ctxt.Cursym.FuncInfo
if pcln == nil {
pcln = &pclntab_zpcln
}
if pclntabFirstFunc == nil {
- pclntabFirstFunc = Ctxt.Cursym
+ pclntabFirstFunc = ctxt.Cursym
}
funcstart := int32(len(ftab.P))
funcstart += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
- setaddr(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), Ctxt.Cursym)
- setuintxx(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint64(funcstart), int64(SysArch.PtrSize))
+ setaddr(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), ctxt.Cursym)
+ setuintxx(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint64(funcstart), int64(SysArch.PtrSize))
// fixed size of struct, checked below
off := funcstart
if len(pcln.Funcdata) > 0 && (end&int32(SysArch.PtrSize-1) != 0) {
end += 4
}
- Symgrow(Ctxt, ftab, int64(end))
+ Symgrow(ctxt, ftab, int64(end))
// entry uintptr
- off = int32(setaddr(Ctxt, ftab, int64(off), Ctxt.Cursym))
+ off = int32(setaddr(ctxt, ftab, int64(off), ctxt.Cursym))
// name int32
- off = int32(setuint32(Ctxt, ftab, int64(off), uint32(ftabaddstring(ftab, Ctxt.Cursym.Name))))
+ off = int32(setuint32(ctxt, ftab, int64(off), uint32(ftabaddstring(ctxt, ftab, ctxt.Cursym.Name))))
// args int32
// TODO: Move into funcinfo.
args := uint32(0)
- if Ctxt.Cursym.FuncInfo != nil {
- args = uint32(Ctxt.Cursym.FuncInfo.Args)
+ if ctxt.Cursym.FuncInfo != nil {
+ args = uint32(ctxt.Cursym.FuncInfo.Args)
}
- off = int32(setuint32(Ctxt, ftab, int64(off), args))
+ off = int32(setuint32(ctxt, ftab, int64(off), args))
// frame int32
// This has been removed (it was never set quite correctly anyway).
// Nothing should use it.
// Leave an obviously incorrect value.
// TODO: Remove entirely.
- off = int32(setuint32(Ctxt, ftab, int64(off), 0x1234567))
+ off = int32(setuint32(ctxt, ftab, int64(off), 0x1234567))
if pcln != &pclntab_zpcln {
- renumberfiles(Ctxt, pcln.File, &pcln.Pcfile)
+ renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
if false {
// Sanity check the new numbering
var it Pciter
- for pciterinit(Ctxt, &it, &pcln.Pcfile); it.done == 0; pciternext(&it) {
- if it.value < 1 || it.value > int32(len(Ctxt.Filesyms)) {
- Diag("bad file number in pcfile: %d not in range [1, %d]\n", it.value, len(Ctxt.Filesyms))
+ for pciterinit(ctxt, &it, &pcln.Pcfile); it.done == 0; pciternext(&it) {
+ if it.value < 1 || it.value > int32(len(ctxt.Filesyms)) {
+ ctxt.Diag("bad file number in pcfile: %d not in range [1, %d]\n", it.value, len(ctxt.Filesyms))
errorexit()
}
}
}
// pcdata
- off = addpctab(ftab, off, &pcln.Pcsp)
+ off = addpctab(ctxt, ftab, off, &pcln.Pcsp)
- off = addpctab(ftab, off, &pcln.Pcfile)
- off = addpctab(ftab, off, &pcln.Pcline)
- off = int32(setuint32(Ctxt, ftab, int64(off), uint32(len(pcln.Pcdata))))
- off = int32(setuint32(Ctxt, ftab, int64(off), uint32(len(pcln.Funcdata))))
+ off = addpctab(ctxt, ftab, off, &pcln.Pcfile)
+ off = addpctab(ctxt, ftab, off, &pcln.Pcline)
+ off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Pcdata))))
+ off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Funcdata))))
for i := 0; i < len(pcln.Pcdata); i++ {
- off = addpctab(ftab, off, &pcln.Pcdata[i])
+ off = addpctab(ctxt, ftab, off, &pcln.Pcdata[i])
}
// funcdata, must be pointer-aligned and we're only int32-aligned.
}
for i := 0; i < len(pcln.Funcdata); i++ {
if pcln.Funcdata[i] == nil {
- setuintxx(Ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]), int64(SysArch.PtrSize))
+ setuintxx(ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]), int64(SysArch.PtrSize))
} else {
// TODO: Dedup.
funcdata_bytes += pcln.Funcdata[i].Size
- setaddrplus(Ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
+ setaddrplus(ctxt, ftab, int64(off)+int64(SysArch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
}
}
}
if off != end {
- Diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), SysArch.PtrSize)
+ ctxt.Diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, len(pcln.Pcdata), len(pcln.Funcdata), SysArch.PtrSize)
errorexit()
}
pclntabLastFunc = last
// Final entry of table is just end pc.
- setaddrplus(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), last, last.Size)
+ setaddrplus(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize), last, last.Size)
// Start file table.
start := int32(len(ftab.P))
start += int32(-len(ftab.P)) & (int32(SysArch.PtrSize) - 1)
pclntabFiletabOffset = start
- setuint32(Ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint32(start))
+ setuint32(ctxt, ftab, 8+int64(SysArch.PtrSize)+int64(nfunc)*2*int64(SysArch.PtrSize)+int64(SysArch.PtrSize), uint32(start))
- Symgrow(Ctxt, ftab, int64(start)+(int64(len(Ctxt.Filesyms))+1)*4)
- setuint32(Ctxt, ftab, int64(start), uint32(len(Ctxt.Filesyms)))
- for i := len(Ctxt.Filesyms) - 1; i >= 0; i-- {
- s := Ctxt.Filesyms[i]
- setuint32(Ctxt, ftab, int64(start)+s.Value*4, uint32(ftabaddstring(ftab, s.Name)))
+ Symgrow(ctxt, ftab, int64(start)+(int64(len(ctxt.Filesyms))+1)*4)
+ setuint32(ctxt, ftab, int64(start), uint32(len(ctxt.Filesyms)))
+ for i := len(ctxt.Filesyms) - 1; i >= 0; i-- {
+ s := ctxt.Filesyms[i]
+ setuint32(ctxt, ftab, int64(start)+s.Value*4, uint32(ftabaddstring(ctxt, ftab, s.Name)))
}
ftab.Size = int64(len(ftab.P))
// findfunctab generates a lookup table to quickly find the containing
// function for a pc. See src/runtime/symtab.go:findfunc for details.
-func findfunctab() {
- t := Linklookup(Ctxt, "runtime.findfunctab", 0)
+func (ctxt *Link) findfunctab() {
+ t := Linklookup(ctxt, "runtime.findfunctab", 0)
t.Type = obj.SRODATA
t.Attr |= AttrReachable
t.Attr |= AttrLocal
// find min and max address
- min := Ctxt.Textp[0].Value
+ min := ctxt.Textp[0].Value
max := int64(0)
- for _, s := range Ctxt.Textp {
+ for _, s := range ctxt.Textp {
max = s.Value + s.Size
}
indexes[i] = NOIDX
}
idx := int32(0)
- for i, s := range Ctxt.Textp {
+ for i, s := range ctxt.Textp {
if container(s) != 0 {
continue
}
p := s.Value
var e *Symbol
i++
- if i < len(Ctxt.Textp) {
- e = Ctxt.Textp[i]
+ if i < len(ctxt.Textp) {
+ e = ctxt.Textp[i]
}
- for container(e) != 0 && i < len(Ctxt.Textp) {
- e = Ctxt.Textp[i]
+ for container(e) != 0 && i < len(ctxt.Textp) {
+ e = ctxt.Textp[i]
i++
}
q := max
// allocate table
nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
- Symgrow(Ctxt, t, 4*int64(nbuckets)+int64(n))
+ Symgrow(ctxt, t, 4*int64(nbuckets)+int64(n))
// fill in table
for i := int32(0); i < nbuckets; i++ {
base := indexes[i*SUBBUCKETS]
if base == NOIDX {
- Diag("hole in findfunctab")
+ ctxt.Diag("hole in findfunctab")
}
- setuint32(Ctxt, t, int64(i)*(4+SUBBUCKETS), uint32(base))
+ setuint32(ctxt, t, int64(i)*(4+SUBBUCKETS), uint32(base))
for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ {
idx = indexes[i*SUBBUCKETS+j]
if idx == NOIDX {
- Diag("hole in findfunctab")
+ ctxt.Diag("hole in findfunctab")
}
if idx-base >= 256 {
- Diag("too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base)
+ ctxt.Diag("too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base)
}
- setuint8(Ctxt, t, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
+ setuint8(ctxt, t, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
}
}
}
var nexport int
-func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
+func addpesection(ctxt *Link, name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
if pensect == 16 {
- Diag("too many sections")
+ ctxt.Diag("too many sections")
errorexit()
}
return h
}
-func chksectoff(h *IMAGE_SECTION_HEADER, off int64) {
+func chksectoff(ctxt *Link, h *IMAGE_SECTION_HEADER, off int64) {
if off != int64(h.PointerToRawData) {
- Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(off))
+ ctxt.Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(off))
errorexit()
}
}
-func chksectseg(h *IMAGE_SECTION_HEADER, s *Segment) {
+func chksectseg(ctxt *Link, h *IMAGE_SECTION_HEADER, s *Segment) {
if s.Vaddr-PEBASE != uint64(h.VirtualAddress) {
- Diag("%s.VirtualAddress = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE)))
+ ctxt.Diag("%s.VirtualAddress = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE)))
errorexit()
}
if s.Fileoff != uint64(h.PointerToRawData) {
- Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff)))
+ ctxt.Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff)))
errorexit()
}
}
-func Peinit() {
+func Peinit(ctxt *Link) {
var l int
switch SysArch.Family {
nextfileoff = int(PEFILEHEADR)
// some mingw libs depend on this symbol, for example, FindPESectionByName
- xdefine("__image_base__", obj.SDATA, PEBASE)
+ ctxt.xdefine("__image_base__", obj.SDATA, PEBASE)
- xdefine("_image_base__", obj.SDATA, PEBASE)
+ ctxt.xdefine("_image_base__", obj.SDATA, PEBASE)
}
func pewrite() {
}
}
-func initdynimport() *Dll {
+func initdynimport(ctxt *Link) *Dll {
var d *Dll
dr = nil
var m *Imp
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
if !s.Attr.Reachable() || s.Type != obj.SDYNIMPORT {
continue
}
var err error
m.argsize, err = strconv.Atoi(s.Extname[i+1:])
if err != nil {
- Diag("failed to parse stdcall decoration: %v", err)
+ ctxt.Diag("failed to parse stdcall decoration: %v", err)
}
m.argsize *= SysArch.PtrSize
s.Extname = s.Extname[:i]
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
m.s.Type = obj.SDATA
- Symgrow(Ctxt, m.s, int64(SysArch.PtrSize))
+ Symgrow(ctxt, m.s, int64(SysArch.PtrSize))
dynName := m.s.Extname
// only windows/386 requires stdcall decoration
if SysArch.Family == sys.I386 && m.argsize >= 0 {
dynName += fmt.Sprintf("@%d", m.argsize)
}
- dynSym := Linklookup(Ctxt, dynName, 0)
+ dynSym := Linklookup(ctxt, dynName, 0)
dynSym.Attr |= AttrReachable
dynSym.Type = obj.SHOSTOBJ
r := Addrel(m.s)
}
}
} else {
- dynamic := Linklookup(Ctxt, ".windynamic", 0)
+ dynamic := Linklookup(ctxt, ".windynamic", 0)
dynamic.Attr |= AttrReachable
dynamic.Type = obj.SWINDOWS
for d := dr; d != nil; d = d.next {
return dlls
}
-func addimports(datsect *IMAGE_SECTION_HEADER) {
+func addimports(ctxt *Link, datsect *IMAGE_SECTION_HEADER) {
startoff := Cpos()
- dynamic := Linklookup(Ctxt, ".windynamic", 0)
+ dynamic := Linklookup(ctxt, ".windynamic", 0)
// skip import descriptor table (will write it later)
n := uint64(0)
// add pe section and pad it at the end
n = uint64(Cpos()) - uint64(startoff)
- isect := addpesection(".idata", int(n), int(n))
+ isect := addpesection(ctxt, ".idata", int(n), int(n))
isect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
- chksectoff(isect, startoff)
+ chksectoff(ctxt, isect, startoff)
strnput("", int(uint64(isect.SizeOfRawData)-n))
endoff := Cpos()
func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s byExtname) Less(i, j int) bool { return s[i].Extname < s[j].Extname }
-func initdynexport() {
+func initdynexport(ctxt *Link) {
nexport = 0
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
if !s.Attr.Reachable() || !s.Attr.CgoExportDynamic() {
continue
}
if nexport+1 > len(dexport) {
- Diag("pe dynexport table is full")
+ ctxt.Diag("pe dynexport table is full")
errorexit()
}
sort.Sort(byExtname(dexport[:nexport]))
}
-func addexports() {
+func addexports(ctxt *Link) {
var e IMAGE_EXPORT_DIRECTORY
size := binary.Size(&e) + 10*nexport + len(outfile) + 1
return
}
- sect := addpesection(".edata", size, size)
+ sect := addpesection(ctxt, ".edata", size, size)
sect.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
- chksectoff(sect, Cpos())
+ chksectoff(ctxt, sect, Cpos())
va := int(sect.VirtualAddress)
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.VirtualSize
// perelocsect relocates symbols from first in section sect, and returns
// the total number of relocations emitted.
-func perelocsect(sect *Section, syms []*Symbol) int {
+func perelocsect(ctxt *Link, sect *Section, syms []*Symbol) int {
// If main section has no bits, nothing to relocate.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
return 0
if sym.Value >= int64(eaddr) {
break
}
- Ctxt.Cursym = sym
+ ctxt.Cursym = sym
for ri := 0; ri < len(sym.R); ri++ {
r := &sym.R[ri]
continue
}
if r.Xsym == nil {
- Diag("missing xsym in relocation")
+ ctxt.Diag("missing xsym in relocation")
continue
}
if r.Xsym.Dynid < 0 {
- Diag("reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
+ ctxt.Diag("reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
}
if !Thearch.PEreloc1(r, int64(uint64(sym.Value+int64(r.Off))-PEBASE)) {
- Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
+ ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
}
relocs++
}
// peemitreloc emits relocation entries for go.o in external linking.
-func peemitreloc(text, data, ctors *IMAGE_SECTION_HEADER) {
+func peemitreloc(ctxt *Link, text, data, ctors *IMAGE_SECTION_HEADER) {
for Cpos()&7 != 0 {
Cput(0)
}
Lputl(0)
Wputl(0)
- n := perelocsect(Segtext.Sect, Ctxt.Textp) + 1
+ n := perelocsect(ctxt, Segtext.Sect, ctxt.Textp) + 1
for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
- n += perelocsect(sect, datap)
+ n += perelocsect(ctxt, sect, datap)
}
cpos := Cpos()
n = 1
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
- n += perelocsect(sect, datap)
+ n += perelocsect(ctxt, sect, datap)
}
cpos = Cpos()
}
data.NumberOfRelocations = uint16(n - 1)
- dottext := Linklookup(Ctxt, ".text", 0)
+ dottext := Linklookup(ctxt, ".text", 0)
ctors.NumberOfRelocations = 1
ctors.PointerToRelocations = uint32(Cpos())
sectoff := ctors.VirtualAddress
}
}
-func dope() {
+func (ctxt *Link) dope() {
/* relocation table */
- rel := Linklookup(Ctxt, ".rel", 0)
+ rel := Linklookup(ctxt, ".rel", 0)
rel.Attr |= AttrReachable
rel.Type = obj.SELFROSECT
- initdynimport()
- initdynexport()
+ initdynimport(ctxt)
+ initdynexport(ctxt)
}
func strtbladd(name string) int {
* reference: pecoff_v8.docx Page 24.
* <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
*/
-func newPEDWARFSection(name string, size int64) *IMAGE_SECTION_HEADER {
+func newPEDWARFSection(ctxt *Link, name string, size int64) *IMAGE_SECTION_HEADER {
if size == 0 {
return nil
}
off := strtbladd(name)
s := fmt.Sprintf("/%d", off)
- h := addpesection(s, int(size), int(size))
+ h := addpesection(ctxt, s, int(size), int(size))
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
return h
// writePESymTableRecords writes all COFF symbol table records.
// It returns number of records written.
-func writePESymTableRecords() int {
+func writePESymTableRecords(ctxt *Link) int {
var symcnt int
- put := func(s *Symbol, name string, type_ int, addr int64, size int64, ver int, gotype *Symbol) {
+ put := func(ctxt *Link, s *Symbol, name string, type_ int, addr int64, size int64, ver int, gotype *Symbol) {
if s == nil {
return
}
} else if type_ == 'U' {
typ = IMAGE_SYM_DTYPE_FUNCTION
} else {
- Diag("addpesym %#x", addr)
+ ctxt.Diag("addpesym %#x", addr)
}
// write COFF symbol table record
for d := dr; d != nil; d = d.next {
for m := d.ms; m != nil; m = m.next {
s := m.s.R[0].Xsym
- put(s, s.Name, 'U', 0, int64(SysArch.PtrSize), 0, nil)
+ put(ctxt, s, s.Name, 'U', 0, int64(SysArch.PtrSize), 0, nil)
}
}
- s := Linklookup(Ctxt, ".text", 0)
+ s := Linklookup(ctxt, ".text", 0)
if s.Type == obj.STEXT {
- put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
+ put(ctxt, s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
}
}
- genasmsym(put)
+ genasmsym(ctxt, put)
return symcnt
}
-func addpesymtable() {
+func addpesymtable(ctxt *Link) {
symtabStartPos := Cpos()
// write COFF symbol table
var symcnt int
if Debug['s'] == 0 || Linkmode == LinkExternal {
- symcnt = writePESymTableRecords()
+ symcnt = writePESymTableRecords(ctxt)
}
// update COFF file header and section table
if Linkmode != LinkExternal {
// We do not really need .symtab for go.o, and if we have one, ld
// will also include it in the exe, and that will confuse windows.
- h = addpesection(".symtab", size, size)
+ h = addpesection(ctxt, ".symtab", size, size)
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
- chksectoff(h, symtabStartPos)
+ chksectoff(ctxt, h, symtabStartPos)
}
fh.PointerToSymbolTable = uint32(symtabStartPos)
fh.NumberOfSymbols = uint32(symcnt)
}
}
-func setpersrc(sym *Symbol) {
+func setpersrc(ctxt *Link, sym *Symbol) {
if rsrcsym != nil {
- Diag("too many .rsrc sections")
+ ctxt.Diag("too many .rsrc sections")
}
rsrcsym = sym
}
-func addpersrc() {
+func addpersrc(ctxt *Link) {
if rsrcsym == nil {
return
}
- h := addpesection(".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
+ h := addpesection(ctxt, ".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
- chksectoff(h, Cpos())
+ chksectoff(ctxt, h, Cpos())
// relocation
var p []byte
dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = h.VirtualSize
}
-func addinitarray() (c *IMAGE_SECTION_HEADER) {
+func addinitarray(ctxt *Link) (c *IMAGE_SECTION_HEADER) {
// The size below was determined by the specification for array relocations,
// and by observing what GCC writes here. If the initarray section grows to
// contain more than one constructor entry, the size will need to be 8 * constructor_count.
size = 8
}
- c = addpesection(".ctors", size, size)
+ c = addpesection(ctxt, ".ctors", size, size)
c.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
c.SizeOfRawData = uint32(size)
Cseek(int64(c.PointerToRawData))
- chksectoff(c, Cpos())
- init_entry := Linklookup(Ctxt, INITENTRY, 0)
+ chksectoff(ctxt, c, Cpos())
+ init_entry := Linklookup(ctxt, INITENTRY, 0)
addr := uint64(init_entry.Value) - init_entry.Sect.Vaddr
switch obj.Getgoarch() {
return c
}
-func Asmbpe() {
+func Asmbpe(ctxt *Link) {
switch SysArch.Family {
default:
Exitf("unknown PE architecture: %v", SysArch.Family)
fh.Machine = IMAGE_FILE_MACHINE_I386
}
- t := addpesection(".text", int(Segtext.Length), int(Segtext.Length))
+ t := addpesection(ctxt, ".text", int(Segtext.Length), int(Segtext.Length))
t.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
if Linkmode == LinkExternal {
// some data symbols (e.g. masks) end up in the .text section, and they normally
// expect larger alignment requirement than the default text section alignment.
t.Characteristics |= IMAGE_SCN_ALIGN_32BYTES
}
- chksectseg(t, &Segtext)
+ chksectseg(ctxt, t, &Segtext)
textsect = pensect
var d *IMAGE_SECTION_HEADER
var c *IMAGE_SECTION_HEADER
if Linkmode != LinkExternal {
- d = addpesection(".data", int(Segdata.Length), int(Segdata.Filelen))
+ d = addpesection(ctxt, ".data", int(Segdata.Length), int(Segdata.Filelen))
d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
- chksectseg(d, &Segdata)
+ chksectseg(ctxt, d, &Segdata)
datasect = pensect
} else {
- d = addpesection(".data", int(Segdata.Filelen), int(Segdata.Filelen))
+ d = addpesection(ctxt, ".data", int(Segdata.Filelen), int(Segdata.Filelen))
d.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
- chksectseg(d, &Segdata)
+ chksectseg(ctxt, d, &Segdata)
datasect = pensect
- b := addpesection(".bss", int(Segdata.Length-Segdata.Filelen), 0)
+ b := addpesection(ctxt, ".bss", int(Segdata.Length-Segdata.Filelen), 0)
b.Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_ALIGN_32BYTES
b.PointerToRawData = 0
bsssect = pensect
- c = addinitarray()
+ c = addinitarray(ctxt)
}
if Debug['s'] == 0 {
- dwarfaddpeheaders()
+ dwarfaddpeheaders(ctxt)
}
Cseek(int64(nextfileoff))
if Linkmode != LinkExternal {
- addimports(d)
- addexports()
+ addimports(ctxt, d)
+ addexports(ctxt)
}
- addpesymtable()
- addpersrc()
+ addpesymtable(ctxt)
+ addpersrc(ctxt)
if Linkmode == LinkExternal {
- peemitreloc(t, d, c)
+ peemitreloc(ctxt, t, d, c)
}
fh.NumberOfSections = uint16(pensect)
oh64.SizeOfUninitializedData = 0
oh.SizeOfUninitializedData = 0
if Linkmode != LinkExternal {
- oh64.AddressOfEntryPoint = uint32(Entryvalue() - PEBASE)
- oh.AddressOfEntryPoint = uint32(Entryvalue() - PEBASE)
+ oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
+ oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
}
oh64.BaseOfCode = t.VirtualAddress
oh.BaseOfCode = t.VirtualAddress
func Ldmain() {
Bso = bufio.NewWriter(os.Stdout)
- Ctxt = linknew(SysArch)
- Ctxt.Diag = Diag
- Ctxt.Bso = Bso
+ ctxt := linknew(SysArch)
+ Ctxt = ctxt // Export Ctxt because it's currently used by the arch-specific packages
+ ctxt.Bso = Bso
Debug = [128]int{}
nerrors = 0
obj.Flagint64("D", "set data segment `address`", &INITDAT)
obj.Flagstr("E", "set `entry` symbol name", &INITENTRY)
obj.Flagfn1("I", "use `linker` as ELF dynamic linker", setinterp)
- obj.Flagfn1("L", "add specified `directory` to library path", Lflag)
+ obj.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) })
obj.Flagfn1("H", "set header `type`", setheadtype)
obj.Flagint32("R", "set address rounding `quantum`", &INITRND)
obj.Flagint64("T", "set text segment `address`", &INITTEXT)
obj.Flagfn0("V", "print version and exit", doversion)
- obj.Flagfn1("X", "add string value `definition` of the form importpath.name=value", addstrdata1)
+ obj.Flagfn1("X", "add string value `definition` of the form importpath.name=value", func(s string) { addstrdata1(ctxt, s) })
obj.Flagcount("a", "disassemble output", &Debug['a'])
obj.Flagstr("buildid", "record `id` as Go toolchain build id", &buildid)
flag.Var(&Buildmode, "buildmode", "set build `mode`")
obj.Flagparse(usage)
startProfile()
- Ctxt.Bso = Bso
- Ctxt.Debugvlog = int32(Debug['v'])
+ ctxt.Bso = Bso
+ ctxt.Debugvlog = int32(Debug['v'])
if flagShared != 0 {
if Buildmode == BuildmodeUnset {
Buildmode = BuildmodeCShared
}
}
- libinit() // creates outfile
+ libinit(ctxt) // creates outfile
if HEADTYPE == -1 {
HEADTYPE = int32(headtype(goos))
}
- Ctxt.Headtype = int(HEADTYPE)
+ ctxt.Headtype = int(HEADTYPE)
if headstring == "" {
headstring = Headstr(int(HEADTYPE))
}
}
pkglistfornote = append(pkglistfornote, pkgpath...)
pkglistfornote = append(pkglistfornote, '\n')
- addlibpath(Ctxt, "command line", "command line", file, pkgpath, "")
+ addlibpath(ctxt, "command line", "command line", file, pkgpath, "")
}
} else {
- addlibpath(Ctxt, "command line", "command line", flag.Arg(0), "main", "")
+ addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "")
}
- loadlib()
+ ctxt.loadlib()
- checkstrdata()
- deadcode(Ctxt)
- fieldtrack(Ctxt)
- callgraph()
+ ctxt.checkstrdata()
+ deadcode(ctxt)
+ fieldtrack(ctxt)
+ ctxt.callgraph()
- doelf()
+ ctxt.doelf()
if HEADTYPE == obj.Hdarwin {
- domacho()
+ ctxt.domacho()
}
- dostkcheck()
+ ctxt.dostkcheck()
if HEADTYPE == obj.Hwindows {
- dope()
+ ctxt.dope()
}
- addexport()
+ ctxt.addexport()
Thearch.Gentext() // trampolines, call stubs, etc.
- textbuildid()
- textaddress()
- pclntab()
- findfunctab()
- symtab()
- dodata()
- address()
- reloc()
- Thearch.Asmb()
- undef()
- hostlink()
+ ctxt.textbuildid()
+ ctxt.textaddress()
+ ctxt.pclntab()
+ ctxt.findfunctab()
+ ctxt.symtab()
+ ctxt.dodata()
+ ctxt.address()
+ ctxt.reloc()
+ Thearch.Asmb(ctxt)
+ ctxt.undef()
+ ctxt.hostlink()
archive()
if Debug['v'] != 0 {
fmt.Fprintf(Bso, "%5.2f cpu time\n", obj.Cputime())
- fmt.Fprintf(Bso, "%d symbols\n", len(Ctxt.Allsym))
+ fmt.Fprintf(Bso, "%d symbols\n", len(ctxt.Allsym))
fmt.Fprintf(Bso, "%d liveness data\n", liveness)
}
var elfbind int
-func putelfsym(x *Symbol, s string, t int, addr int64, size int64, ver int, go_ *Symbol) {
+func putelfsym(ctxt *Link, x *Symbol, s string, t int, addr int64, size int64, ver int, go_ *Symbol) {
var type_ int
switch t {
elfshnum = SHN_UNDEF
} else {
if xo.Sect == nil {
- Ctxt.Cursym = x
- Diag("missing section in putelfsym")
+ ctxt.Cursym = x
+ ctxt.Diag("missing section in putelfsym")
return
}
if xo.Sect.Elfsect == nil {
- Ctxt.Cursym = x
- Diag("missing ELF section in putelfsym")
+ ctxt.Cursym = x
+ ctxt.Diag("missing ELF section in putelfsym")
return
}
elfshnum = xo.Sect.Elfsect.shnum
numelfsym++
}
-func Asmelfsym() {
+func Asmelfsym(ctxt *Link) {
// the first symbol entry is reserved
putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
- dwarfaddelfsectionsyms()
+ dwarfaddelfsectionsyms(ctxt)
// Some linkers will add a FILE sym if one is not present.
// Avoid having the working directory inserted into the symbol table.
numelfsym++
elfbind = STB_LOCAL
- genasmsym(putelfsym)
+ genasmsym(ctxt, putelfsym)
elfbind = STB_GLOBAL
elfglobalsymndx = numelfsym
- genasmsym(putelfsym)
+ genasmsym(ctxt, putelfsym)
}
-func putplan9sym(x *Symbol, s string, t int, addr int64, size int64, ver int, go_ *Symbol) {
+func putplan9sym(ctxt *Link, x *Symbol, s string, t int, addr int64, size int64, ver int, go_ *Symbol) {
switch t {
case 'T', 'L', 'D', 'B':
if ver != 0 {
}
}
-func Asmplan9sym() {
- genasmsym(putplan9sym)
+func Asmplan9sym(ctxt *Link) {
+ genasmsym(ctxt, putplan9sym)
}
var symt *Symbol
libs[a], libs[b] = libs[b], libs[a]
}
-func symtab() {
- dosymtype()
+func (ctxt *Link) symtab() {
+ dosymtype(ctxt)
// Define these so that they'll get put into the symbol table.
// data.c:/^address will provide the actual values.
- xdefine("runtime.text", obj.STEXT, 0)
-
- xdefine("runtime.etext", obj.STEXT, 0)
- xdefine("runtime.typelink", obj.SRODATA, 0)
- xdefine("runtime.etypelink", obj.SRODATA, 0)
- xdefine("runtime.itablink", obj.SRODATA, 0)
- xdefine("runtime.eitablink", obj.SRODATA, 0)
- xdefine("runtime.rodata", obj.SRODATA, 0)
- xdefine("runtime.erodata", obj.SRODATA, 0)
- xdefine("runtime.types", obj.SRODATA, 0)
- xdefine("runtime.etypes", obj.SRODATA, 0)
- xdefine("runtime.noptrdata", obj.SNOPTRDATA, 0)
- xdefine("runtime.enoptrdata", obj.SNOPTRDATA, 0)
- xdefine("runtime.data", obj.SDATA, 0)
- xdefine("runtime.edata", obj.SDATA, 0)
- xdefine("runtime.bss", obj.SBSS, 0)
- xdefine("runtime.ebss", obj.SBSS, 0)
- xdefine("runtime.noptrbss", obj.SNOPTRBSS, 0)
- xdefine("runtime.enoptrbss", obj.SNOPTRBSS, 0)
- xdefine("runtime.end", obj.SBSS, 0)
- xdefine("runtime.epclntab", obj.SRODATA, 0)
- xdefine("runtime.esymtab", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.text", obj.STEXT, 0)
+
+ ctxt.xdefine("runtime.etext", obj.STEXT, 0)
+ ctxt.xdefine("runtime.typelink", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.etypelink", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.itablink", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.eitablink", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.rodata", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.erodata", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.types", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.etypes", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.noptrdata", obj.SNOPTRDATA, 0)
+ ctxt.xdefine("runtime.enoptrdata", obj.SNOPTRDATA, 0)
+ ctxt.xdefine("runtime.data", obj.SDATA, 0)
+ ctxt.xdefine("runtime.edata", obj.SDATA, 0)
+ ctxt.xdefine("runtime.bss", obj.SBSS, 0)
+ ctxt.xdefine("runtime.ebss", obj.SBSS, 0)
+ ctxt.xdefine("runtime.noptrbss", obj.SNOPTRBSS, 0)
+ ctxt.xdefine("runtime.enoptrbss", obj.SNOPTRBSS, 0)
+ ctxt.xdefine("runtime.end", obj.SBSS, 0)
+ ctxt.xdefine("runtime.epclntab", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.esymtab", obj.SRODATA, 0)
// garbage collection symbols
- s := Linklookup(Ctxt, "runtime.gcdata", 0)
+ s := Linklookup(ctxt, "runtime.gcdata", 0)
s.Type = obj.SRODATA
s.Size = 0
s.Attr |= AttrReachable
- xdefine("runtime.egcdata", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.egcdata", obj.SRODATA, 0)
- s = Linklookup(Ctxt, "runtime.gcbss", 0)
+ s = Linklookup(ctxt, "runtime.gcbss", 0)
s.Type = obj.SRODATA
s.Size = 0
s.Attr |= AttrReachable
- xdefine("runtime.egcbss", obj.SRODATA, 0)
+ ctxt.xdefine("runtime.egcbss", obj.SRODATA, 0)
// pseudo-symbols to mark locations of type, string, and go string data.
var symtype *Symbol
var symtyperel *Symbol
if UseRelro() && (Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) {
- s = Linklookup(Ctxt, "type.*", 0)
+ s = Linklookup(ctxt, "type.*", 0)
s.Type = obj.STYPE
s.Size = 0
s.Attr |= AttrReachable
symtype = s
- s = Linklookup(Ctxt, "typerel.*", 0)
+ s = Linklookup(ctxt, "typerel.*", 0)
s.Type = obj.STYPERELRO
s.Size = 0
s.Attr |= AttrReachable
symtyperel = s
} else if !DynlinkingGo() {
- s = Linklookup(Ctxt, "type.*", 0)
+ s = Linklookup(ctxt, "type.*", 0)
s.Type = obj.STYPE
s.Size = 0
}
groupSym := func(name string, t int16) *Symbol {
- s := Linklookup(Ctxt, name, 0)
+ s := Linklookup(ctxt, name, 0)
s.Type = t
s.Size = 0
s.Attr |= AttrLocal | AttrReachable
symgcbits = groupSym("runtime.gcbits.*", obj.SGCBITS)
)
- symtypelink := Linklookup(Ctxt, "runtime.typelink", 0)
+ symtypelink := Linklookup(ctxt, "runtime.typelink", 0)
symtypelink.Type = obj.STYPELINK
- symitablink := Linklookup(Ctxt, "runtime.itablink", 0)
+ symitablink := Linklookup(ctxt, "runtime.itablink", 0)
symitablink.Type = obj.SITABLINK
- symt = Linklookup(Ctxt, "runtime.symtab", 0)
+ symt = Linklookup(ctxt, "runtime.symtab", 0)
symt.Attr |= AttrLocal
symt.Type = obj.SSYMTAB
symt.Size = 0
// within a type they sort by size, so the .* symbols
// just defined above will be first.
// hide the specific symbols.
- for _, s := range Ctxt.Allsym {
+ for _, s := range ctxt.Allsym {
if !s.Attr.Reachable() || s.Attr.Special() || s.Type != obj.SRODATA {
continue
}
}
if Buildmode == BuildmodeShared {
- abihashgostr := Linklookup(Ctxt, "go.link.abihash."+filepath.Base(outfile), 0)
+ abihashgostr := Linklookup(ctxt, "go.link.abihash."+filepath.Base(outfile), 0)
abihashgostr.Attr |= AttrReachable
abihashgostr.Type = obj.SRODATA
- hashsym := Linklookup(Ctxt, "go.link.abihashbytes", 0)
- Addaddr(Ctxt, abihashgostr, hashsym)
- adduint(Ctxt, abihashgostr, uint64(hashsym.Size))
+ hashsym := Linklookup(ctxt, "go.link.abihashbytes", 0)
+ Addaddr(ctxt, abihashgostr, hashsym)
+ adduint(ctxt, abihashgostr, uint64(hashsym.Size))
}
// Information about the layout of the executable image for the
// runtime to use. Any changes here must be matched by changes to
// the definition of moduledata in runtime/symtab.go.
// This code uses several global variables that are set by pcln.go:pclntab.
- moduledata := Ctxt.Moduledata
+ moduledata := ctxt.Moduledata
// The pclntab slice
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0))
- adduint(Ctxt, moduledata, uint64(Linklookup(Ctxt, "runtime.pclntab", 0).Size))
- adduint(Ctxt, moduledata, uint64(Linklookup(Ctxt, "runtime.pclntab", 0).Size))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.pclntab", 0))
+ adduint(ctxt, moduledata, uint64(Linklookup(ctxt, "runtime.pclntab", 0).Size))
+ adduint(ctxt, moduledata, uint64(Linklookup(ctxt, "runtime.pclntab", 0).Size))
// The ftab slice
- Addaddrplus(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0), int64(pclntabPclntabOffset))
- adduint(Ctxt, moduledata, uint64(pclntabNfunc+1))
- adduint(Ctxt, moduledata, uint64(pclntabNfunc+1))
+ Addaddrplus(ctxt, moduledata, Linklookup(ctxt, "runtime.pclntab", 0), int64(pclntabPclntabOffset))
+ adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
+ adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
// The filetab slice
- Addaddrplus(Ctxt, moduledata, Linklookup(Ctxt, "runtime.pclntab", 0), int64(pclntabFiletabOffset))
- adduint(Ctxt, moduledata, uint64(len(Ctxt.Filesyms))+1)
- adduint(Ctxt, moduledata, uint64(len(Ctxt.Filesyms))+1)
+ Addaddrplus(ctxt, moduledata, Linklookup(ctxt, "runtime.pclntab", 0), int64(pclntabFiletabOffset))
+ adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
+ adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
// findfunctab
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.findfunctab", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.findfunctab", 0))
// minpc, maxpc
- Addaddr(Ctxt, moduledata, pclntabFirstFunc)
- Addaddrplus(Ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
+ Addaddr(ctxt, moduledata, pclntabFirstFunc)
+ Addaddrplus(ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
// pointers to specific parts of the module
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.text", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etext", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrdata", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.enoptrdata", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.data", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.edata", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.bss", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.ebss", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.noptrbss", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.enoptrbss", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.end", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcdata", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcbss", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.types", 0))
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etypes", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.text", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.etext", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.noptrdata", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.enoptrdata", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.data", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.edata", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.bss", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.ebss", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.noptrbss", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.enoptrbss", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.end", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.gcdata", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.gcbss", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.types", 0))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.etypes", 0))
// The typelinks slice
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0))
- adduint(Ctxt, moduledata, uint64(ntypelinks))
- adduint(Ctxt, moduledata, uint64(ntypelinks))
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.typelink", 0))
+ adduint(ctxt, moduledata, uint64(ntypelinks))
+ adduint(ctxt, moduledata, uint64(ntypelinks))
// The itablinks slice
- Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.itablink", 0))
- adduint(Ctxt, moduledata, uint64(nitablinks))
- adduint(Ctxt, moduledata, uint64(nitablinks))
- if len(Ctxt.Shlibs) > 0 {
+ Addaddr(ctxt, moduledata, Linklookup(ctxt, "runtime.itablink", 0))
+ adduint(ctxt, moduledata, uint64(nitablinks))
+ adduint(ctxt, moduledata, uint64(nitablinks))
+ if len(ctxt.Shlibs) > 0 {
thismodulename := filepath.Base(outfile)
switch Buildmode {
case BuildmodeExe, BuildmodePIE:
// it something slightly more comprehensible.
thismodulename = "the executable"
}
- addgostring(moduledata, "go.link.thismodulename", thismodulename)
+ addgostring(ctxt, moduledata, "go.link.thismodulename", thismodulename)
- modulehashes := Linklookup(Ctxt, "go.link.abihashes", 0)
+ modulehashes := Linklookup(ctxt, "go.link.abihashes", 0)
modulehashes.Attr |= AttrReachable
modulehashes.Attr |= AttrLocal
modulehashes.Type = obj.SRODATA
- for i, shlib := range Ctxt.Shlibs {
+ for i, shlib := range ctxt.Shlibs {
// modulehashes[i].modulename
modulename := filepath.Base(shlib.Path)
- addgostring(modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
+ addgostring(ctxt, modulehashes, fmt.Sprintf("go.link.libname.%d", i), modulename)
// modulehashes[i].linktimehash
- addgostring(modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
+ addgostring(ctxt, modulehashes, fmt.Sprintf("go.link.linkhash.%d", i), string(shlib.Hash))
// modulehashes[i].runtimehash
- abihash := Linklookup(Ctxt, "go.link.abihash."+modulename, 0)
+ abihash := Linklookup(ctxt, "go.link.abihash."+modulename, 0)
abihash.Attr |= AttrReachable
- Addaddr(Ctxt, modulehashes, abihash)
+ Addaddr(ctxt, modulehashes, abihash)
}
- Addaddr(Ctxt, moduledata, modulehashes)
- adduint(Ctxt, moduledata, uint64(len(Ctxt.Shlibs)))
- adduint(Ctxt, moduledata, uint64(len(Ctxt.Shlibs)))
+ Addaddr(ctxt, moduledata, modulehashes)
+ adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
+ adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
}
// The rest of moduledata is zero initialized.
// When linking an object that does not contain the runtime we are
// creating the moduledata from scratch and it does not have a
// compiler-provided size, so read it from the type data.
- moduledatatype := Linkrlookup(Ctxt, "type.runtime.moduledata", 0)
- moduledata.Size = decodetype_size(moduledatatype)
- Symgrow(Ctxt, moduledata, moduledata.Size)
+ moduledatatype := Linkrlookup(ctxt, "type.runtime.moduledata", 0)
+ moduledata.Size = decodetype_size(ctxt.Arch, moduledatatype)
+ Symgrow(ctxt, moduledata, moduledata.Size)
- lastmoduledatap := Linklookup(Ctxt, "runtime.lastmoduledatap", 0)
+ lastmoduledatap := Linklookup(ctxt, "runtime.lastmoduledatap", 0)
if lastmoduledatap.Type != obj.SDYNIMPORT {
lastmoduledatap.Type = obj.SNOPTRDATA
lastmoduledatap.Size = 0 // overwrite existing value
- Addaddr(Ctxt, lastmoduledatap, moduledata)
+ Addaddr(ctxt, lastmoduledatap, moduledata)
}
}
}
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
+ ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
rs := r.Sym
r.Xadd = r.Add
for rs.Outer != nil {
- r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
+ r.Xadd += ld.Symaddr(ctxt, rs) - ld.Symaddr(ctxt, rs.Outer)
rs = rs.Outer
}
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
- ld.Diag("missing section for %s", rs.Name)
+ ld.Ctxt.Diag("missing section for %s", rs.Name)
}
r.Xsym = rs
return 0
case obj.R_GOTOFF:
- *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
+ *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
case obj.R_ADDRMIPS,
obj.R_ADDRMIPSU:
- t := ld.Symaddr(r.Sym) + r.Add
+ t := ld.Symaddr(ctxt, r.Sym) + r.Add
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
if r.Type == obj.R_ADDRMIPS {
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
case obj.R_ADDRMIPSTLS:
// thread pointer is at 0x7000 offset from the start of TLS data area
- t := ld.Symaddr(r.Sym) + r.Add - 0x7000
+ t := ld.Symaddr(ctxt, r.Sym) + r.Add - 0x7000
if t < -32768 || t >= 32678 {
- ld.Diag("TLS offset out of range %d", t)
+ ld.Ctxt.Diag("TLS offset out of range %d", t)
}
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xffff0000 | uint32(t)&0xffff)
case obj.R_CALLMIPS,
obj.R_JMPMIPS:
// Low 26 bits = (S + A) >> 2
- t := ld.Symaddr(r.Sym) + r.Add
+ t := ld.Symaddr(ctxt, r.Sym) + r.Add
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xfc000000 | uint32(t>>2)&^0xfc000000)
return 0
return -1
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
/* output symbol table */
ld.Symsize = 0
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
case obj.Hplan9:
- ld.Asmplan9sym()
+ ld.Asmplan9sym(ctxt)
ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
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(uint32(ld.Symsize)) /* nsyms */
+ ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
ld.Thearch.Lput(0)
ld.Thearch.Lput(uint32(ld.Lcsize))
obj.Hnetbsd,
obj.Hopenbsd,
obj.Hnacl:
- ld.Asmbelf(int64(symo))
+ ld.Asmbelf(ctxt, int64(symo))
}
ld.Cflush()
}
case obj.Hlinux: /* mips64 elf */
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR)
}
case obj.Hnacl:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = 0x10000
ld.Funcalign = 16
if ld.INITTEXT == -1 {
switch r.Type {
default:
if r.Type >= 256 {
- ld.Diag("unexpected relocation type %d", r.Type)
+ ld.Ctxt.Diag("unexpected relocation type %d", r.Type)
return
}
if targ.Type == obj.SDYNIMPORT {
// Should have been handled in elfsetupplt
- ld.Diag("unexpected R_PPC64_REL24 for dyn import")
+ ld.Ctxt.Diag("unexpected R_PPC64_REL24 for dyn import")
}
return
r.Add += 4
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_PPC_REL32 for dyn import")
+ ld.Ctxt.Diag("unexpected R_PPC_REL32 for dyn import")
}
return
// TODO(austin): Translate our relocations to ELF
- ld.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
+ ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
}
func elfreloc1(r *ld.Reloc, sectoff int64) int {
}
if toc == nil {
- ld.Diag("TOC-relative relocation in object without .TOC.")
+ ld.Ctxt.Diag("TOC-relative relocation in object without .TOC.")
return 0
}
}
func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int {
+ ctxt := ld.Ctxt
var o1, o2 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(*val >> 32)
// instruction (it is an error in this case if the low 2 bits of the address
// are non-zero).
- t := ld.Symaddr(r.Sym) + r.Add
+ t := ld.Symaddr(ctxt, r.Sym) + r.Add
if t < 0 || t >= 1<<31 {
- ld.Ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(r.Sym))
+ ld.Ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(ctxt, r.Sym))
}
if t&0x8000 != 0 {
t += 0x10000
case obj.R_ADDRPOWER_DS:
o1 |= (uint32(t) >> 16) & 0xffff
if t&3 != 0 {
- ld.Ctxt.Diag("bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
+ ld.Ctxt.Diag("bad DS reloc for %s: %d", s.Name, ld.Symaddr(ctxt, r.Sym))
}
o2 |= uint32(t) & 0xfffc
}
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
+ ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
rs := r.Sym
r.Xadd = r.Add
for rs.Outer != nil {
- r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
+ r.Xadd += ld.Symaddr(ctxt, rs) - ld.Symaddr(ctxt, rs.Outer)
rs = rs.Outer
}
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
- ld.Diag("missing section for %s", rs.Name)
+ ld.Ctxt.Diag("missing section for %s", rs.Name)
}
r.Xsym = rs
return 0
case obj.R_GOTOFF:
- *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
+ *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
case obj.R_ADDRPOWER, obj.R_ADDRPOWER_DS:
case obj.R_CALLPOWER:
// Bits 6 through 29 = (S + A - P) >> 2
- t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
+ t := ld.Symaddr(ctxt, r.Sym) + r.Add - (s.Value + int64(r.Off))
if t&3 != 0 {
ld.Ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
}
return 0
case obj.R_POWER_TOC: // S + A - .TOC.
- *val = ld.Symaddr(r.Sym) + r.Add - symtoc(s)
+ *val = ld.Symaddr(ctxt, r.Sym) + r.Add - symtoc(s)
return 0
// Specification".
v := r.Sym.Value - 0x7000
if int64(int16(v)) != v {
- ld.Diag("TLS offset out of range %d", v)
+ ld.Ctxt.Diag("TLS offset out of range %d", v)
}
*val = (*val &^ 0xffff) | (v & 0xffff)
return 0
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
switch r.Variant & ld.RV_TYPE_MASK {
default:
- ld.Diag("unexpected relocation variant %d", r.Variant)
+ ld.Ctxt.Diag("unexpected relocation variant %d", r.Variant)
fallthrough
case ld.RV_NONE:
o1 = uint32(ld.Le16(s.P[r.Off:]))
}
if t&3 != 0 {
- ld.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
+ ld.Ctxt.Diag("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 {
goto overflow
}
overflow:
- ld.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
+ ld.Ctxt.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
return t
}
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")
+ ld.Ctxt.Diag("addpltsym: unsupported binary format")
}
}
// before the first symbol resolver stub.
s := ld.Linklookup(ld.Ctxt, ".dynamic", 0)
- ld.Elfwritedynentsymplus(s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
+ ld.Elfwritedynentsymplus(ld.Ctxt, s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
return glink
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
/* output symbol table */
ld.Symsize = 0
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
case obj.Hplan9:
- ld.Asmplan9sym()
+ ld.Asmplan9sym(ctxt)
ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
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(uint32(ld.Symsize)) /* nsyms */
+ ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
ld.Thearch.Lput(0)
ld.Thearch.Lput(uint32(ld.Lcsize))
obj.Hnetbsd,
obj.Hopenbsd,
obj.Hnacl:
- ld.Asmbelf(int64(symo))
+ ld.Asmbelf(ctxt, int64(symo))
}
ld.Cflush()
if ld.SysArch == sys.ArchPPC64 {
ld.Debug['d'] = 1 // TODO(austin): ELF ABI v1 not supported yet
}
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR)
}
case obj.Hnacl:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = 0x10000
ld.Funcalign = 16
if ld.INITTEXT == -1 {
switch r.Type {
default:
if r.Type >= 256 {
- ld.Diag("unexpected relocation type %d", r.Type)
+ ld.Ctxt.Diag("unexpected relocation type %d", r.Type)
return
}
// Handle relocations found in ELF object files.
case 256 + ld.R_390_12,
256 + ld.R_390_GOT12:
- ld.Diag("s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256)
+ ld.Ctxt.Diag("s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256)
return
case 256 + ld.R_390_8,
256 + ld.R_390_32,
256 + ld.R_390_64:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
}
r.Type = obj.R_ADDR
return
256 + ld.R_390_PC32,
256 + ld.R_390_PC64:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
}
if targ.Type == 0 || targ.Type == obj.SXREF {
- ld.Diag("unknown symbol %s in pcrel", targ.Name)
+ ld.Ctxt.Diag("unknown symbol %s in pcrel", targ.Name)
}
r.Type = obj.R_PCREL
r.Add += int64(r.Siz)
case 256 + ld.R_390_GOT16,
256 + ld.R_390_GOT32,
256 + ld.R_390_GOT64:
- ld.Diag("unimplemented S390x relocation: %v", r.Type-256)
+ ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
return
case 256 + ld.R_390_PLT16DBL,
return
case 256 + ld.R_390_COPY:
- ld.Diag("unimplemented S390x relocation: %v", r.Type-256)
+ ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_GLOB_DAT:
- ld.Diag("unimplemented S390x relocation: %v", r.Type-256)
+ ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_JMP_SLOT:
- ld.Diag("unimplemented S390x relocation: %v", r.Type-256)
+ ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_RELATIVE:
- ld.Diag("unimplemented S390x relocation: %v", r.Type-256)
+ ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_GOTOFF:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
}
r.Type = obj.R_GOTOFF
return
r.Variant = ld.RV_390_DBL
r.Add += int64(r.Siz)
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
}
return
return
}
- ld.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
+ ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
}
func elfreloc1(r *ld.Reloc, sectoff int64) int {
}
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
+ ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal {
return -1
}
return 0
case obj.R_GOTOFF:
- *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
+ *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
}
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
switch r.Variant & ld.RV_TYPE_MASK {
default:
- ld.Diag("unexpected relocation variant %d", r.Variant)
+ ld.Ctxt.Diag("unexpected relocation variant %d", r.Variant)
return t
case ld.RV_NONE:
case ld.RV_390_DBL:
if (t & 1) != 0 {
- ld.Diag("%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
+ ld.Ctxt.Diag("%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
}
return t >> 1
}
s.Plt = int32(plt.Size - 32)
} else {
- ld.Diag("addpltsym: unsupported binary format")
+ ld.Ctxt.Diag("addpltsym: unsupported binary format")
}
}
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT))
ld.Adduint64(ld.Ctxt, rela, 0)
} else {
- ld.Diag("addgotsym: unsupported binary format")
+ ld.Ctxt.Diag("addgotsym: unsupported binary format")
}
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
/* output symbol table */
ld.Symsize = 0
symo := uint32(0)
if ld.Debug['s'] == 0 {
if !ld.Iself {
- ld.Diag("unsupported executable format")
+ ld.Ctxt.Diag("unsupported executable format")
}
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f sym\n", obj.Cputime())
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
}
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
ld.Cseek(0)
switch ld.HEADTYPE {
default:
- ld.Diag("unsupported operating system")
+ ld.Ctxt.Diag("unsupported operating system")
case obj.Hlinux:
- ld.Asmbelf(int64(symo))
+ ld.Asmbelf(ctxt, int64(symo))
}
ld.Cflush()
ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
case obj.Hlinux: // s390x ELF
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR)
switch r.Type {
default:
if r.Type >= 256 {
- ld.Diag("unexpected relocation type %d", r.Type)
+ ld.Ctxt.Diag("unexpected relocation type %d", r.Type)
return
}
// Handle relocations found in ELF object files.
case 256 + ld.R_386_PC32:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
}
if targ.Type == 0 || targ.Type == obj.SXREF {
- ld.Diag("unknown symbol %s in pcrel", targ.Name)
+ ld.Ctxt.Diag("unknown symbol %s in pcrel", targ.Name)
}
r.Type = obj.R_PCREL
r.Add += 4
return
}
- ld.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
return
}
case 256 + ld.R_386_32:
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
}
r.Type = obj.R_ADDR
return
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
r.Type = obj.R_ADDR
if targ.Type == obj.SDYNIMPORT {
- ld.Diag("unexpected reloc for dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected reloc for dynamic symbol %s", targ.Name)
}
return
// have symbol
// turn MOVL of GOT entry into LEAL of symbol itself
if r.Off < 2 || s.P[r.Off-2] != 0x8b {
- ld.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
+ ld.Ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
return
}
}
ld.Ctxt.Cursym = s
- ld.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
+ ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
}
func elfreloc1(r *ld.Reloc, sectoff int64) int {
if rs.Type == obj.SHOSTOBJ {
if rs.Dynid < 0 {
- ld.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1
}
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
- ld.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1
}
}
rs := r.Xsym
if rs.Dynid < 0 {
- ld.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
+ ld.Ctxt.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
return false
}
return 0
case obj.R_GOTOFF:
- *val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ld.Linklookup(ld.Ctxt, ".got", 0))
+ *val = ld.Symaddr(ld.Ctxt, r.Sym) + r.Add - ld.Symaddr(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".got", 0))
return 0
}
ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, ld.Linklookup(ctxt, ".got", 0), int64(s.Got))
} else {
- ld.Diag("addpltsym: unsupported binary format")
+ ld.Ctxt.Diag("addpltsym: unsupported binary format")
}
}
} else if ld.HEADTYPE == obj.Hdarwin {
ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(s.Dynid))
} else {
- ld.Diag("addgotsym: unsupported binary format")
+ ld.Ctxt.Diag("addgotsym: unsupported binary format")
}
}
-func asmb() {
+func asmb(ctxt *ld.Link) {
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f asmb\n", obj.Cputime())
}
ld.Bso.Flush()
if ld.Iself {
- ld.Asmbelfsetup()
+ ld.Asmbelfsetup(ctxt)
}
sect := ld.Segtext.Sect
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// 0xCC is INT $3 - breakpoint instruction
- ld.CodeblkPad(int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
+ ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
for sect = sect.Next; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
if ld.Segrodata.Filelen > 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segrodata.Fileoff))
- ld.Datblk(int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Debug['v'] != 0 {
ld.Bso.Flush()
ld.Cseek(int64(ld.Segdata.Fileoff))
- ld.Datblk(int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
+ ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
- ld.Dwarfblk(int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
+ ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
machlink := uint32(0)
if ld.HEADTYPE == obj.Hdarwin {
- machlink = uint32(ld.Domacholink())
+ machlink = uint32(ld.Domacholink(ctxt))
}
ld.Symsize = 0
if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f elfsym\n", obj.Cputime())
}
- ld.Asmelfsym()
+ ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal {
- ld.Elfemitreloc()
+ ld.Elfemitreloc(ctxt)
}
}
case obj.Hplan9:
- ld.Asmplan9sym()
+ ld.Asmplan9sym(ctxt)
ld.Cflush()
- sym := ld.Linklookup(ld.Ctxt, "pclntab", 0)
+ sym := ld.Linklookup(ctxt, "pclntab", 0)
if sym != nil {
ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ {
case obj.Hdarwin:
if ld.Linkmode == ld.LinkExternal {
- ld.Machoemitreloc()
+ ld.Machoemitreloc(ctxt)
}
}
}
ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
ld.Lputb(uint32(ld.Segdata.Filelen))
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
- ld.Lputb(uint32(ld.Symsize)) /* nsyms */
- ld.Lputb(uint32(ld.Entryvalue())) /* va of entry */
- ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
- ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
+ ld.Lputb(uint32(ld.Symsize)) /* nsyms */
+ ld.Lputb(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+ ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
+ ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
case obj.Hdarwin:
- ld.Asmbmacho()
+ ld.Asmbmacho(ctxt)
case obj.Hlinux,
obj.Hfreebsd,
obj.Hnetbsd,
obj.Hopenbsd,
obj.Hnacl:
- ld.Asmbelf(int64(symo))
+ ld.Asmbelf(ctxt, int64(symo))
case obj.Hwindows:
- ld.Asmbpe()
+ ld.Asmbpe(ctxt)
}
ld.Cflush()
obj.Hfreebsd,
obj.Hnetbsd,
obj.Hopenbsd:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 {
}
case obj.Hnacl:
- ld.Elfinit()
+ ld.Elfinit(ld.Ctxt)
ld.HEADR = 0x10000
ld.Funcalign = 32
if ld.INITTEXT == -1 {
}
case obj.Hwindows: /* PE executable */
- ld.Peinit()
+ ld.Peinit(ld.Ctxt)
ld.HEADR = ld.PEFILEHEADR
if ld.INITTEXT == -1 {