From: Michael Matloob Date: Sat, 20 Aug 2016 02:40:38 +0000 (-0400) Subject: cmd/link/internal: thread *ld.Link through calls X-Git-Tag: go1.8beta1~1755 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2f783c3458744a95a01286eed5f4c0af0978cd46;p=gostls13.git cmd/link/internal: thread *ld.Link through calls 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 TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: Michael Hudson-Doyle --- diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go index ec430db51c..39ce457804 100644 --- a/src/cmd/link/internal/amd64/asm.go +++ b/src/cmd/link/internal/amd64/asm.go @@ -101,17 +101,17 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -153,7 +153,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -166,7 +166,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -189,7 +189,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -198,7 +198,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { // 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 } @@ -211,7 +211,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { // 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 @@ -306,7 +306,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { } 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 { @@ -385,7 +385,7 @@ func machoreloc1(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 } @@ -394,7 +394,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { } 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 } } @@ -444,7 +444,7 @@ func pereloc1(r *ld.Reloc, sectoff int64) bool { 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 } @@ -572,7 +572,7 @@ func addpltsym(s *ld.Symbol) { 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") } } @@ -594,11 +594,11 @@ func addgotsym(s *ld.Symbol) { } 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()) } @@ -610,16 +610,16 @@ func asmb() { 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 { @@ -629,7 +629,7 @@ func asmb() { 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 { @@ -638,19 +638,19 @@ func asmb() { 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: @@ -710,7 +710,7 @@ func asmb() { default: if ld.Iself { ld.Cseek(symo) - ld.Asmelfsym() + ld.Asmelfsym(ctxt) ld.Cflush() ld.Cwrite(ld.Elfstrdat) @@ -719,12 +719,12 @@ func asmb() { } 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) @@ -744,7 +744,7 @@ func asmb() { case obj.Hdarwin: if ld.Linkmode == ld.LinkExternal { - ld.Machoemitreloc() + ld.Machoemitreloc(ctxt) } } } @@ -765,14 +765,14 @@ func asmb() { 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, @@ -781,10 +781,10 @@ func asmb() { obj.Hdragonfly, obj.Hsolaris, obj.Hnacl: - ld.Asmbelf(symo) + ld.Asmbelf(ctxt, symo) case obj.Hwindows: - ld.Asmbpe() + ld.Asmbpe(ctxt) } ld.Cflush() diff --git a/src/cmd/link/internal/amd64/obj.go b/src/cmd/link/internal/amd64/obj.go index f62f237b57..c41d2bec9c 100644 --- a/src/cmd/link/internal/amd64/obj.go +++ b/src/cmd/link/internal/amd64/obj.go @@ -83,6 +83,8 @@ func linkarchinit() { } 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" { @@ -151,7 +153,7 @@ func archinit() { obj.Hopenbsd, /* openbsd */ obj.Hdragonfly, /* dragonfly */ obj.Hsolaris: /* solaris */ - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = ld.ELFRESERVE if ld.INITTEXT == -1 { @@ -165,7 +167,7 @@ func archinit() { } 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 @@ -180,7 +182,7 @@ func archinit() { } case obj.Hwindows: /* PE executable */ - ld.Peinit() + ld.Peinit(ctxt) ld.HEADR = ld.PEFILEHEADR if ld.INITTEXT == -1 { diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 5cd02eba6a..7e58f81d4f 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -116,7 +116,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 } @@ -190,7 +190,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -245,7 +245,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { } 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 { @@ -332,7 +332,7 @@ func machoreloc1(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 { @@ -354,7 +354,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { 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 @@ -362,7 +362,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { 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 } @@ -371,7 +371,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { } 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 } } @@ -411,6 +411,7 @@ func machoreloc1(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 { switch r.Type { case obj.R_CALLARM: @@ -425,12 +426,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { } 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 @@ -440,7 +441,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { // 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)))) @@ -456,30 +457,30 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 } @@ -542,7 +543,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { 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") } } @@ -558,7 +559,7 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) { if ld.Iself { } else { - ld.Diag("addgotsyminternal: unsupported binary format") + ld.Ctxt.Diag("addgotsyminternal: unsupported binary format") } } @@ -577,26 +578,26 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) { 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 { @@ -606,7 +607,7 @@ func asmb() { 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 { @@ -615,14 +616,14 @@ func asmb() { 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 */ @@ -657,17 +658,17 @@ func asmb() { 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) @@ -682,7 +683,7 @@ func asmb() { case obj.Hdarwin: if ld.Linkmode == ld.LinkExternal { - ld.Machoemitreloc() + ld.Machoemitreloc(ctxt) } } } @@ -700,8 +701,8 @@ func asmb() { 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)) @@ -710,10 +711,10 @@ func asmb() { 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() diff --git a/src/cmd/link/internal/arm/obj.go b/src/cmd/link/internal/arm/obj.go index 9ea9771ca4..3213231b9e 100644 --- a/src/cmd/link/internal/arm/obj.go +++ b/src/cmd/link/internal/arm/obj.go @@ -128,7 +128,7 @@ func archinit() { 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) @@ -141,7 +141,7 @@ func archinit() { } case obj.Hnacl: - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = 0x10000 ld.Funcalign = 16 if ld.INITTEXT == -1 { diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 544ed1e433..aff1c54c2b 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -157,7 +157,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { // 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 } @@ -166,7 +166,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { } 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 } } @@ -180,7 +180,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { 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 @@ -227,6 +227,7 @@ func machoreloc1(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 { switch r.Type { default: @@ -270,12 +271,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -329,13 +330,13 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -362,21 +363,21 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -390,22 +391,22 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { 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 { @@ -415,7 +416,7 @@ func asmb() { 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 { @@ -424,14 +425,14 @@ func asmb() { 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 */ @@ -466,17 +467,17 @@ func asmb() { 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) @@ -491,7 +492,7 @@ func asmb() { case obj.Hdarwin: if ld.Linkmode == ld.LinkExternal { - ld.Machoemitreloc() + ld.Machoemitreloc(ctxt) } } } @@ -509,8 +510,8 @@ func asmb() { 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)) @@ -519,10 +520,10 @@ func asmb() { 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() diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go index 86f9ff79b0..136d1d4c7a 100644 --- a/src/cmd/link/internal/arm64/obj.go +++ b/src/cmd/link/internal/arm64/obj.go @@ -125,7 +125,7 @@ func archinit() { } 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) @@ -152,7 +152,7 @@ func archinit() { } case obj.Hnacl: - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = 0x10000 ld.Funcalign = 16 if ld.INITTEXT == -1 { diff --git a/src/cmd/link/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go index 80c33ceeba..1eac15ec19 100644 --- a/src/cmd/link/internal/ld/ar.go +++ b/src/cmd/link/internal/ld/ar.go @@ -63,7 +63,7 @@ type ArHdr struct { // 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) { @@ -99,7 +99,7 @@ func hostArchive(name string) { 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] { @@ -118,9 +118,9 @@ func hostArchive(name string) { 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 diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 9cbb8121e4..848ba61934 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -319,7 +319,7 @@ func listsort(l *Symbol, cmp func(*Symbol, *Symbol) int, nextp func(*Symbol) **S return l } -func relocsym(s *Symbol) { +func relocsym(ctxt *Link, s *Symbol) { var r *Reloc var rs *Symbol var i16 int16 @@ -328,14 +328,14 @@ func relocsym(s *Symbol) { 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 } @@ -351,7 +351,7 @@ func relocsym(s *Symbol) { continue } } else { - Diag("%s: not defined", r.Sym.Name) + ctxt.Diag("%s: not defined", r.Sym.Name) continue } } @@ -367,11 +367,11 @@ func relocsym(s *Symbol) { // 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. @@ -389,18 +389,18 @@ func relocsym(s *Symbol) { 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: @@ -409,7 +409,7 @@ func relocsym(s *Symbol) { 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 @@ -429,12 +429,12 @@ func relocsym(s *Symbol) { // 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: @@ -443,7 +443,7 @@ func relocsym(s *Symbol) { 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 @@ -464,12 +464,12 @@ func relocsym(s *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 } 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 @@ -486,22 +486,22 @@ func relocsym(s *Symbol) { // 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 @@ -509,20 +509,20 @@ func relocsym(s *Symbol) { // 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 { @@ -530,14 +530,14 @@ func relocsym(s *Symbol) { } 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. @@ -545,13 +545,13 @@ func relocsym(s *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 @@ -563,12 +563,12 @@ func relocsym(s *Symbol) { } 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) } @@ -580,7 +580,7 @@ func relocsym(s *Symbol) { // 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 @@ -588,7 +588,7 @@ func relocsym(s *Symbol) { 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 @@ -612,12 +612,12 @@ func relocsym(s *Symbol) { 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. @@ -626,51 +626,51 @@ func relocsym(s *Symbol) { 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 } @@ -681,7 +681,7 @@ func dynrelocsym(s *Symbol) { 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) @@ -690,17 +690,17 @@ func dynrelocsym(s *Symbol) { // 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 @@ -715,14 +715,14 @@ func dynrelocsym(s *Symbol) { 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 { @@ -733,20 +733,20 @@ func dynreloc(data *[obj.SXREF][]*Symbol) { } 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 { @@ -763,9 +763,9 @@ func blk(start *Symbol, addr int64, size int64) { 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() } @@ -780,7 +780,7 @@ func blk(start *Symbol, addr int64, size int64) { 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() } @@ -795,22 +795,22 @@ func blk(start *Symbol, addr int64, size int64) { 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 @@ -867,7 +867,7 @@ func CodeblkPad(addr int64, size int64, pad []byte) { // 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:] @@ -883,9 +883,9 @@ func blkSlice(syms []*Symbol, addr, size int64, pad []byte) { 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 { @@ -899,7 +899,7 @@ func blkSlice(syms []*Symbol, addr, size int64, pad []byte) { 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 { @@ -913,12 +913,12 @@ func blkSlice(syms []*Symbol, addr, size int64, pad []byte) { 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 { @@ -984,12 +984,12 @@ func Datblk(addr int64, size int64) { 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 @@ -1021,27 +1021,27 @@ func strnputPad(s string, n int, pad []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 @@ -1053,24 +1053,24 @@ func addstrdata(name string, value string) { 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) @@ -1080,31 +1080,31 @@ func Addstring(s *Symbol, str string) int64 { // 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 @@ -1118,7 +1118,7 @@ func dosymtype() { switch Buildmode { case BuildmodeCArchive, BuildmodeCShared: if s.Name == INITENTRY { - addinitarrdata(s) + addinitarrdata(ctxt, s) } } } @@ -1151,21 +1151,25 @@ func aligndatsize(datsize int64, s *Symbol) int64 { 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) { @@ -1181,12 +1185,12 @@ func (p *GCProg) AddSym(s *Symbol) { // 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) @@ -1194,7 +1198,7 @@ func (p *GCProg) AddSym(s *Symbol) { 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) @@ -1204,7 +1208,7 @@ func (p *GCProg) AddSym(s *Symbol) { } // Copy program. - prog := decodetype_gcprog(typ) + prog := decodetype_gcprog(p.ctxt, typ) p.w.ZeroUntil(s.Value / ptrsize) p.w.Append(prog[4:], nptr) } @@ -1231,9 +1235,9 @@ func (d bySizeAndName) Less(i, j int) bool { 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) } } @@ -1249,7 +1253,7 @@ func list2slice(s *Symbol) []*Symbol { // 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()) } @@ -1257,7 +1261,7 @@ func dodata() { // 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 } @@ -1274,9 +1278,9 @@ func dodata() { // // 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 @@ -1314,7 +1318,7 @@ func dodata() { // 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) } } @@ -1331,7 +1335,7 @@ func dodata() { 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() }() } @@ -1362,7 +1366,7 @@ func dodata() { datsize += s.Size sect.Length = uint64(datsize) - sect.Vaddr } - checkdatsize(datsize, symn) + checkdatsize(ctxt, datsize, symn) } // .got (and .toc on ppc64) @@ -1379,7 +1383,7 @@ func dodata() { 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 @@ -1391,7 +1395,7 @@ func dodata() { datsize += s.Size } - checkdatsize(datsize, obj.SELFGOT) + checkdatsize(ctxt, datsize, obj.SELFGOT) sect.Length = uint64(datsize) - sect.Vaddr } @@ -1400,8 +1404,8 @@ func dodata() { 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 @@ -1409,7 +1413,7 @@ func dodata() { 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 @@ -1431,7 +1435,7 @@ func dodata() { datsize += s.Size } sect.Length = uint64(datsize) - sect.Vaddr - checkdatsize(datsize, obj.SINITARR) + checkdatsize(ctxt, datsize, obj.SINITARR) } /* data */ @@ -1439,10 +1443,10 @@ func dodata() { 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 @@ -1451,7 +1455,7 @@ func dodata() { 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)) @@ -1460,10 +1464,10 @@ func dodata() { 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) @@ -1471,7 +1475,7 @@ func dodata() { 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)) @@ -1480,8 +1484,8 @@ func dodata() { 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 @@ -1490,8 +1494,8 @@ func dodata() { } 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 @@ -1508,7 +1512,7 @@ func dodata() { s.Value = datsize datsize += s.Size } - checkdatsize(datsize, obj.STLSBSS) + checkdatsize(ctxt, datsize, obj.STLSBSS) if sect != nil { sect.Length = uint64(datsize) @@ -1536,7 +1540,7 @@ func dodata() { /* 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) @@ -1548,18 +1552,18 @@ func dodata() { 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, @@ -1586,7 +1590,7 @@ func dodata() { s.Value = int64(uint64(datsize) - sect.Vaddr) datsize += s.Size } - checkdatsize(datsize, symn) + checkdatsize(ctxt, datsize, symn) } sect.Length = uint64(datsize) - sect.Vaddr @@ -1610,8 +1614,8 @@ func dodata() { 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, @@ -1633,14 +1637,14 @@ func dodata() { 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 @@ -1652,8 +1656,8 @@ func dodata() { 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 @@ -1661,7 +1665,7 @@ func dodata() { 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 */ @@ -1669,8 +1673,8 @@ func dodata() { 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 @@ -1678,7 +1682,7 @@ func dodata() { 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 */ @@ -1686,8 +1690,8 @@ func dodata() { 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 @@ -1695,7 +1699,7 @@ func dodata() { 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 */ @@ -1703,8 +1707,8 @@ func dodata() { 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 @@ -1712,7 +1716,7 @@ func dodata() { 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 */ @@ -1727,7 +1731,7 @@ func dodata() { 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) @@ -1740,18 +1744,18 @@ func dodata() { 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 { @@ -1765,7 +1769,7 @@ func dodata() { 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) @@ -1780,7 +1784,7 @@ func dodata() { datsize += s.Size } sect.Length = uint64(datsize) - sect.Vaddr - checkdatsize(datsize, obj.SDWARFINFO) + checkdatsize(ctxt, datsize, obj.SDWARFINFO) } /* number the sections */ @@ -1804,7 +1808,7 @@ func dodata() { } } -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. @@ -1825,11 +1829,11 @@ func dodataSect(symn int, syms []*Symbol) (result []*Symbol, maxAlign int32) { 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{ @@ -1896,12 +1900,12 @@ func dodataSect(symn int, syms []*Symbol) (result []*Symbol, maxAlign int32) { // 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. @@ -1910,13 +1914,13 @@ func textbuildid() { 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. @@ -1925,14 +1929,14 @@ func textaddress() { 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 @@ -1947,7 +1951,7 @@ func textaddress() { 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 @@ -1960,7 +1964,7 @@ func textaddress() { } // assign addresses -func address() { +func (ctxt *Link) address() { va := uint64(INITTEXT) Segtext.Rwx = 05 Segtext.Vaddr = va @@ -2082,7 +2086,7 @@ func address() { pclntab := symtab.Next for _, s := range datap { - Ctxt.Cursym = s + ctxt.Cursym = s if s.Sect != nil { s.Value += int64(s.Sect.Vaddr) } @@ -2092,7 +2096,7 @@ func address() { } for sym := dwarfp; sym != nil; sym = sym.Next { - Ctxt.Cursym = sym + ctxt.Cursym = sym if sym.Sect != nil { sym.Value += int64(sym.Sect.Vaddr) } @@ -2102,8 +2106,8 @@ func address() { } 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) } @@ -2113,41 +2117,41 @@ func address() { 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)) } diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index 8b59da34b6..6278b5d580 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -277,7 +277,7 @@ func (d *deadcodepass) flood() { 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) } @@ -315,7 +315,7 @@ func (d *deadcodepass) flood() { // 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))) } diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go index d757cc9ff9..7ec6ad6654 100644 --- a/src/cmd/link/internal/ld/decodesym.go +++ b/src/cmd/link/internal/ld/decodesym.go @@ -45,14 +45,14 @@ func decode_reloc_sym(s *Symbol, off int32) *Symbol { 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") @@ -74,13 +74,13 @@ func decodetype_usegcprog(s *Symbol) uint8 { } // 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 @@ -89,8 +89,8 @@ func decodetype_hasUncommon(s *Symbol) bool { } // 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 { @@ -103,16 +103,16 @@ func findShlibSection(path string, addr uint64) *elf.Section { } // 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...) } @@ -122,23 +122,23 @@ func decodetype_gcprog(s *Symbol) []byte { 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)) @@ -156,8 +156,8 @@ func decodetype_arrayelem(s *Symbol) *Symbol { 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 @@ -180,17 +180,17 @@ func decodetype_chanelem(s *Symbol) *Symbol { } // 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 { @@ -204,13 +204,13 @@ 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 { @@ -253,14 +253,14 @@ func decodetype_structfieldtype(s *Symbol, i int) *Symbol { 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 @@ -286,7 +286,7 @@ const ( // 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++ { @@ -294,7 +294,7 @@ func decode_methodsig(s *Symbol, off, size, count int) []methodsig { 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(", ") @@ -302,12 +302,12 @@ func decode_methodsig(s *Symbol, off, size, count int) []methodsig { 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(')') @@ -318,7 +318,7 @@ func decode_methodsig(s *Symbol, off, size, count int) []methodsig { 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)) } @@ -330,12 +330,12 @@ func decodetype_ifacemethods(s *Symbol) []methodsig { 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)) } @@ -361,9 +361,9 @@ func decodetype_methods(s *Symbol) []methodsig { // 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) } diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 62f6da1d3c..0edeedca1b 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -23,43 +23,45 @@ import ( "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 @@ -79,11 +81,11 @@ var gdbscript string 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) } @@ -134,7 +136,7 @@ func getattr(die *dwarf.DWDie, attr uint16) *dwarf.DWAttr { // 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 @@ -144,7 +146,7 @@ func newdie(parent *dwarf.DWDie, abbrev int, name string, version int) *dwarf.DW 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 @@ -170,8 +172,8 @@ func walktypedef(die *dwarf.DWDie) *dwarf.DWDie { 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 @@ -195,10 +197,10 @@ func findchild(die *dwarf.DWDie, name string) *dwarf.DWDie { // Used to avoid string allocation when looking up dwarf symbols var prefixBuf = []byte(dwarf.InfoPrefix) -func find(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 @@ -206,8 +208,8 @@ func find(name string) *Symbol { 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) } @@ -218,7 +220,7 @@ func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 { 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) @@ -237,11 +239,11 @@ func newrefattr(die *dwarf.DWDie, attr uint16, ref *Symbol) *dwarf.DWAttr { 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 } @@ -253,7 +255,7 @@ func dtolsym(s dwarf.Sym) *Symbol { 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] @@ -267,7 +269,7 @@ func putdie(ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDie) []*Symbol { 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 } @@ -309,8 +311,8 @@ func newabslocexprattr(die *dwarf.DWDie, addr int64, sym *Symbol) { } // 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) } @@ -318,7 +320,7 @@ func lookup_or_diag(n string) *Symbol { 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 @@ -333,10 +335,10 @@ func dotypedef(parent *dwarf.DWDie, name string, def *dwarf.DWDie) { 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 @@ -345,42 +347,42 @@ func dotypedef(parent *dwarf.DWDie, name string, def *dwarf.DWDie) { // 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("") + return mustFind(ctxt, "") } if !strings.HasPrefix(gotype.Name, "type.") { - Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name) - return mustFind("") + ctxt.Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name) + return mustFind(ctxt, "") } 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) @@ -389,7 +391,7 @@ func newtype(gotype *Symbol) *dwarf.DWDie { 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) @@ -399,113 +401,113 @@ func newtype(gotype *Symbol) *dwarf.DWDie { 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 @@ -515,18 +517,18 @@ func newtype(gotype *Symbol) *dwarf.DWDie { 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("")) + 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, "")) } newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(kind), 0) @@ -543,11 +545,11 @@ func nameFromDIESym(dwtype *Symbol) string { } // 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) } @@ -558,23 +560,23 @@ func defptrto(dwtype *Symbol) *Symbol { // 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 @@ -595,17 +597,17 @@ func substitutetype(structdie *dwarf.DWDie, field string, dwtype *Symbol) { } } -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 } @@ -614,12 +616,12 @@ func synthesizestringtypes(die *dwarf.DWDie) { 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 } @@ -628,9 +630,9 @@ func synthesizeslicetypes(die *dwarf.DWDie) { 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)) } } @@ -653,21 +655,21 @@ const ( 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 @@ -680,8 +682,8 @@ func synthesizemaptypes(die *dwarf.DWDie) { 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 @@ -696,50 +698,50 @@ func synthesizemaptypes(die *dwarf.DWDie) { // 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 - 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)) } @@ -747,22 +749,22 @@ func synthesizemaptypes(die *dwarf.DWDie) { }) // Construct hash - 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 - 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 } @@ -774,13 +776,13 @@ func synthesizechantypes(die *dwarf.DWDie) { 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 - 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 @@ -791,28 +793,28 @@ func synthesizechantypes(die *dwarf.DWDie) { }) // waitq - 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 - 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 } @@ -821,7 +823,7 @@ func defdwsymb(sym *Symbol, s string, t int, v int64, size int64, ver int, gotyp } if strings.HasPrefix(s, "type.") && s != "type.*" && !strings.HasPrefix(s, "type..") { - defgotype(sym) + defgotype(ctxt, sym) return } @@ -833,7 +835,7 @@ func defdwsymb(sym *Symbol, s string, t int, v int64, size int64, ver int, gotyp 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) @@ -841,7 +843,7 @@ func defdwsymb(sym *Symbol, s string, t int, v int64, size int64, ver int, gotyp fallthrough case 'a', 'p': - dt = defgotype(gotype) + dt = defgotype(ctxt, gotype) } if dv != nil { @@ -886,23 +888,23 @@ const ( 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) } /* @@ -916,10 +918,10 @@ func getCompilationDir() string { 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] @@ -937,9 +939,9 @@ func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) { 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) @@ -950,60 +952,60 @@ func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) { // 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 { @@ -1013,7 +1015,7 @@ func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) { continue } n := nameFromDIESym(r.Sym) - defgotype(Linklookup(Ctxt, "type."+n, 0)) + defgotype(ctxt, Linklookup(ctxt, "type."+n, 0)) } } funcs = append(funcs, dsym) @@ -1024,8 +1026,8 @@ func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) { 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) { @@ -1039,12 +1041,12 @@ func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) { } 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) @@ -1057,14 +1059,14 @@ func writelines(syms []*Symbol) ([]*Symbol, []*Symbol) { } } - 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 } @@ -1097,10 +1099,10 @@ func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte { 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] @@ -1109,32 +1111,32 @@ func writeframes(syms []*Symbol) []*Symbol { // 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)]. } @@ -1146,12 +1148,12 @@ func writeframes(syms []*Symbol) []*Symbol { 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 } @@ -1159,7 +1161,7 @@ func writeframes(syms []*Symbol) []*Symbol { // 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, @@ -1171,7 +1173,7 @@ func writeframes(syms []*Symbol) []*Symbol { } } - 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. @@ -1200,15 +1202,15 @@ func writeframes(syms []*Symbol) []*Symbol { // 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 } @@ -1220,9 +1222,9 @@ const ( 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 @@ -1230,11 +1232,11 @@ func writeinfo(syms []*Symbol, funcs []*Symbol) []*Symbol { 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) @@ -1242,13 +1244,13 @@ func writeinfo(syms []*Symbol, funcs []*Symbol) []*Symbol { // 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) @@ -1258,13 +1260,13 @@ func writeinfo(syms []*Symbol, funcs []*Symbol) []*Symbol { 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...) } @@ -1289,8 +1291,8 @@ func ispubtype(die *dwarf.DWDie) bool { 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) @@ -1299,10 +1301,10 @@ func writepub(sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Sy 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) { @@ -1313,13 +1315,13 @@ func writepub(sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Sy 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 @@ -1329,8 +1331,8 @@ func writepub(sname string, ispub func(*dwarf.DWDie) bool, syms []*Symbol) []*Sy * 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) @@ -1348,22 +1350,22 @@ func writearanges(syms []*Symbol) []*Symbol { // 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) @@ -1371,14 +1373,14 @@ func writearanges(syms []*Symbol) []*Symbol { 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 @@ -1395,7 +1397,7 @@ var prototypedies map[string]*dwarf.DWDie * passes. * */ -func dwarfgeneratedebugsyms() { +func dwarfgeneratedebugsyms(ctxt *Link) { if Debug['w'] != 0 { // disable dwarf return } @@ -1416,16 +1418,16 @@ func dwarfgeneratedebugsyms() { 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, "", 0) + newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "", 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) @@ -1442,21 +1444,21 @@ func dwarfgeneratedebugsyms() { } // 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) @@ -1467,12 +1469,12 @@ func dwarfgeneratedebugsyms() { // 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++ { @@ -1484,60 +1486,60 @@ func dwarfgeneratedebugsyms() { /* * 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() } } diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 98b5a9e4f0..9de1a2f532 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -913,7 +913,7 @@ var buildinfo []byte 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) { @@ -925,7 +925,7 @@ func Elfinit() { 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 */ @@ -1054,9 +1054,9 @@ func elfwriteshdrs() uint32 { 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() } @@ -1079,10 +1079,10 @@ func elfwritephdrs() uint32 { 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++ @@ -1095,12 +1095,12 @@ func newElfPhdr() *ElfPhdr { 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++ @@ -1173,36 +1173,36 @@ func elfhash(name string) uint32 { 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 { @@ -1215,8 +1215,8 @@ 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) @@ -1238,8 +1238,8 @@ func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int 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)) @@ -1266,9 +1266,9 @@ func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int { 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 @@ -1298,9 +1298,9 @@ func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int { 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 @@ -1359,8 +1359,8 @@ func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int { 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 } @@ -1373,8 +1373,8 @@ func elfwritebuildinfo() int { 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 } @@ -1438,13 +1438,13 @@ havelib: 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 @@ -1461,7 +1461,7 @@ func elfdynhash() { buckets := make([]uint32, nbucket) var b int - for _, sy := range Ctxt.Allsym { + for _, sy := range ctxt.Allsym { if sy.Dynid <= 0 { continue } @@ -1480,29 +1480,29 @@ func elfdynhash() { // 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 @@ -1511,18 +1511,18 @@ func elfdynhash() { 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 { @@ -1530,55 +1530,55 @@ func elfdynhash() { 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 @@ -1599,7 +1599,7 @@ func elfphload(seg *Segment) *ElfPhdr { return ph } -func elfshname(name string) *ElfShdr { +func elfshname(ctxt *Link, name string) *ElfShdr { var off int var sh *ElfShdr @@ -1613,24 +1613,24 @@ func elfshname(name string) *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 { @@ -1642,7 +1642,7 @@ func elfshbits(sect *Section) *ElfShdr { // 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 @@ -1685,7 +1685,7 @@ func elfshbits(sect *Section) *ElfShdr { 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 { @@ -1705,13 +1705,13 @@ func elfshreloc(sect *Section) *ElfShdr { 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 @@ -1719,7 +1719,7 @@ func elfshreloc(sect *Section) *ElfShdr { 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 { @@ -1748,7 +1748,7 @@ func elfrelocsect(sect *Section, syms []*Symbol) { if sym.Value >= int64(eaddr) { break } - Ctxt.Cursym = sym + ctxt.Cursym = sym for ri := 0; ri < len(sym.R); ri++ { r := &sym.R[ri] @@ -1756,14 +1756,14 @@ func elfrelocsect(sect *Section, syms []*Symbol) { 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) } } } @@ -1771,36 +1771,36 @@ func elfrelocsect(sect *Section, syms []*Symbol) { 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 { @@ -1814,23 +1814,23 @@ func addgonote(sectionName string, tag uint32, desc []byte) { 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 @@ -1838,56 +1838,56 @@ func doelf() { // 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") } } @@ -1900,38 +1900,38 @@ func doelf() { } 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 @@ -1942,44 +1942,44 @@ func doelf() { } /* 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 { @@ -1992,20 +1992,20 @@ func doelf() { 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 @@ -2013,85 +2013,85 @@ func doelf() { /* * .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) } @@ -2104,25 +2104,25 @@ func phsh(ph *ElfPhdr, sh *ElfShdr) { 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: @@ -2156,17 +2156,17 @@ func Asmbelf(symo int64) { 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 } @@ -2175,7 +2175,7 @@ func Asmbelf(symo int64) { } /* program header info */ - pph = newElfPhdr() + pph = newElfPhdr(ctxt) pph.type_ = PT_PHDR pph.flags = PF_R @@ -2200,7 +2200,7 @@ func Asmbelf(symo int64) { 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 @@ -2229,7 +2229,7 @@ func Asmbelf(symo int64) { 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) @@ -2240,26 +2240,26 @@ func Asmbelf(symo int64) { 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 } @@ -2268,10 +2268,10 @@ func Asmbelf(symo int64) { } 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) @@ -2279,15 +2279,15 @@ func Asmbelf(symo int64) { // 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 { @@ -2296,79 +2296,79 @@ func Asmbelf(symo int64) { 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 { @@ -2386,44 +2386,44 @@ func Asmbelf(symo int64) { 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) @@ -2442,7 +2442,7 @@ func Asmbelf(symo int64) { } } if tlssize != 0 { - ph := newElfPhdr() + ph := newElfPhdr(ctxt) ph.type_ = PT_TLS ph.flags = PF_R ph.memsz = tlssize @@ -2452,63 +2452,63 @@ func Asmbelf(symo int64) { } 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 @@ -2516,16 +2516,16 @@ elfobj: } 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)) @@ -2552,7 +2552,7 @@ elfobj: } 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 @@ -2566,7 +2566,7 @@ elfobj: } if Linkmode != LinkExternal { - eh.entry = uint64(Entryvalue()) + eh.entry = uint64(Entryvalue(ctxt)) } eh.version = EV_CURRENT @@ -2582,25 +2582,25 @@ elfobj: 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) } } @@ -2612,7 +2612,7 @@ func Elfadddynsym(ctxt *Link, s *Symbol) { 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 @@ -2645,7 +2645,7 @@ func Elfadddynsym(ctxt *Link, s *Symbol) { 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) @@ -2656,7 +2656,7 @@ func Elfadddynsym(ctxt *Link, s *Symbol) { /* 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 { diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go index aec54c1142..bd184c734a 100644 --- a/src/cmd/link/internal/ld/go.go +++ b/src/cmd/link/internal/ld/go.go @@ -28,7 +28,7 @@ func expandpkg(t0 string, pkg string) string { // 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 { @@ -121,11 +121,11 @@ func ldpkg(f *bio.Reader, pkg string, length int64, filename string, whence int) } 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 @@ -187,7 +187,7 @@ func loadcgo(file string, pkg string, p 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 { @@ -208,7 +208,7 @@ func loadcgo(file string, pkg string, p string) { goto err } local = f[1] - s = Linklookup(Ctxt, local, 0) + s = Linklookup(ctxt, local, 0) s.Type = obj.SHOSTOBJ s.Size = 0 continue @@ -225,11 +225,11 @@ func loadcgo(file string, pkg string, p string) { 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 } } @@ -298,20 +298,20 @@ err: 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") } } @@ -323,11 +323,11 @@ func Adddynsym(ctxt *Link, s *Symbol) { 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") } } @@ -359,19 +359,19 @@ func fieldtrack(ctxt *Link) { 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) } } diff --git a/src/cmd/link/internal/ld/ld.go b/src/cmd/link/internal/ld/ld.go index bbbfd3e049..cf33a9f42d 100644 --- a/src/cmd/link/internal/ld/ld.go +++ b/src/cmd/link/internal/ld/ld.go @@ -118,7 +118,7 @@ func addlibpath(ctxt *Link, srcref string, objref string, file string, pkg strin 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)) } diff --git a/src/cmd/link/internal/ld/ldelf.go b/src/cmd/link/internal/ld/ldelf.go index 2ee06b2ded..070c16012a 100644 --- a/src/cmd/link/internal/ld/ldelf.go +++ b/src/cmd/link/internal/ld/ldelf.go @@ -447,12 +447,12 @@ func parseArmAttributes(e binary.ByteOrder, data []byte) { } } -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 @@ -544,54 +544,54 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { } 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 } } @@ -667,7 +667,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { } 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 } @@ -709,7 +709,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { } 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: @@ -748,7 +748,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 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 @@ -789,7 +789,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 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 } @@ -812,7 +812,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 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 } @@ -822,7 +822,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 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) } } } @@ -842,13 +842,13 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 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) } } } @@ -910,7 +910,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol rp.Sym = nil } else { - 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] @@ -923,7 +923,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { } 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 { @@ -933,7 +933,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { } 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) } } @@ -957,7 +957,7 @@ func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 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 { @@ -990,14 +990,14 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { 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 { @@ -1040,7 +1040,7 @@ func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) { 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. @@ -1066,7 +1066,7 @@ func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) { // 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 } @@ -1077,14 +1077,14 @@ func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) { // 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 } @@ -1126,7 +1126,7 @@ func (x rbyoff) Less(i, j int) bool { 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. @@ -1141,7 +1141,7 @@ func relSize(pn string, elftype uint32) uint8 { 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: diff --git a/src/cmd/link/internal/ld/ldmacho.go b/src/cmd/link/internal/ld/ldmacho.go index 549516a0c0..66a2c6d13a 100644 --- a/src/cmd/link/internal/ld/ldmacho.go +++ b/src/cmd/link/internal/ld/ldmacho.go @@ -415,7 +415,7 @@ func macholoadsym(m *LdMachoObj, symtab *LdMachoSymtab) int { 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 @@ -444,7 +444,7 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { var rp *Reloc var name string - Ctxt.IncVersion() + ctxt.IncVersion() base := f.Offset() if _, err := io.ReadFull(f, hdr[:]); err != nil { goto bad @@ -487,18 +487,18 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { 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 } } @@ -587,7 +587,7 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { 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 @@ -634,9 +634,9 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { } 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 } @@ -673,7 +673,7 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { } 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 } @@ -707,13 +707,13 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { 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) } } } @@ -738,7 +738,7 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { 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 } @@ -900,5 +900,5 @@ func ldmacho(f *bio.Reader, pkg string, length int64, pn string) { return bad: - Diag("%s: malformed mach-o file: %v", pn, err) + ctxt.Diag("%s: malformed mach-o file: %v", pn, err) } diff --git a/src/cmd/link/internal/ld/ldpe.go b/src/cmd/link/internal/ld/ldpe.go index 7ace279f6f..e7e871e998 100644 --- a/src/cmd/link/internal/ld/ldpe.go +++ b/src/cmd/link/internal/ld/ldpe.go @@ -130,13 +130,13 @@ type PeObj struct { 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) @@ -246,7 +246,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { } 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 @@ -271,7 +271,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { s.Size = int64(sect.size) sect.sym = s if sect.name == ".rsrc" { - setpersrc(sect.sym) + setpersrc(ctxt, sect.sym) } } @@ -300,7 +300,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { 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 { @@ -313,7 +313,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { 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, @@ -371,7 +371,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { } } - if err = readpesym(peobj, i, &sym); err != nil { + if err = readpesym(ctxt, peobj, i, &sym); err != nil { goto bad } @@ -389,10 +389,10 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { } 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 { @@ -414,7 +414,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { 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 } @@ -435,13 +435,13 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { 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) } } } @@ -449,7 +449,7 @@ func ldpe(f *bio.Reader, pkg string, length int64, pn string) { 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 { @@ -475,7 +475,7 @@ func issect(s *PeSym) bool { 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 @@ -511,10 +511,10 @@ func readpesym(peobj *PeObj, i int, y **PeSym) (err error) { 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: diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 74dd001f8e..d43312b989 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -99,7 +99,7 @@ type Arch struct { 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() @@ -209,8 +209,8 @@ var ( 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 @@ -277,8 +277,8 @@ var ( 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: @@ -385,7 +385,7 @@ func mayberemoveoutfile() { os.Remove(outfile) } -func libinit() { +func libinit(ctxt *Link) { Funcalign = Thearch.Funcalign mywhatsys() // get goroot, goarch, goos @@ -404,7 +404,7 @@ func libinit() { 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) @@ -424,12 +424,12 @@ func libinit() { 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 } } @@ -463,26 +463,26 @@ func errorexit() { 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 } @@ -493,46 +493,46 @@ func loadinternal(name string) { } } -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) } } @@ -581,16 +581,16 @@ func loadlib() { // 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]) } } } @@ -598,7 +598,7 @@ func loadlib() { 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, @@ -613,7 +613,7 @@ func loadlib() { } } - 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). @@ -621,12 +621,12 @@ func loadlib() { 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 @@ -638,29 +638,29 @@ func loadlib() { // 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 @@ -679,12 +679,12 @@ func loadlib() { // 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 @@ -715,7 +715,7 @@ func loadlib() { } if libgccfile != "none" { - hostArchive(libgccfile) + hostArchive(ctxt, libgccfile) } } } else { @@ -775,7 +775,7 @@ func nextar(bp *bio.Reader, off int64, a *ArHdr) int64 { return arsize + SAR_HDR } -func objfile(lib *Library) { +func objfile(ctxt *Link, lib *Library) { pkg := pathtoprefix(lib.Pkg) if Debug['v'] > 1 { @@ -796,7 +796,7 @@ func objfile(lib *Library) { 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 @@ -809,12 +809,12 @@ func objfile(lib *Library) { 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 } @@ -822,7 +822,7 @@ func objfile(lib *Library) { 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[:] @@ -831,7 +831,7 @@ func objfile(lib *Library) { 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. @@ -858,7 +858,7 @@ func objfile(lib *Library) { 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: @@ -866,7 +866,7 @@ 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 @@ -887,7 +887,7 @@ var internalpkg = []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] { @@ -923,7 +923,7 @@ func ldhostobj(ld func(*bio.Reader, string, int64, string), f *bio.Reader, pkg s return h } -func hostobjs() { +func hostobjs(ctxt *Link) { var h *Hostobj for i := 0; i < len(hostobj); i++ { @@ -934,7 +934,7 @@ func hostobjs() { } 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() } } @@ -1056,7 +1056,7 @@ func archive() { } } -func hostlink() { +func (l *Link) hostlink() { if Linkmode != LinkExternal || nerrors > 0 { return } @@ -1208,13 +1208,13 @@ func hostlink() { 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) } @@ -1239,7 +1239,7 @@ func hostlink() { // 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 @@ -1293,7 +1293,7 @@ func hostlink() { 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. @@ -1303,12 +1303,12 @@ func hostlink() { // 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) } } @@ -1336,7 +1336,7 @@ func hostlinkArchArgs() []string { // 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() @@ -1362,7 +1362,7 @@ func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, when /* 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 } @@ -1374,11 +1374,11 @@ func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, when 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 } @@ -1387,7 +1387,7 @@ func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, when 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 } @@ -1398,7 +1398,7 @@ func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, when 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 } } @@ -1414,7 +1414,7 @@ func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, when c2 = c3 c3 = bgetc(f) if c3 == -1 { - Diag("truncated object file: %s", pn) + ctxt.Diag("truncated object file: %s", pn) return nil } } @@ -1422,22 +1422,22 @@ func ldobj(f *bio.Reader, pkg string, length int64, pn string, file string, when 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 } @@ -1491,54 +1491,54 @@ func readnote(f *elf.File, name []byte, typ int32) ([]byte, error) { 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) @@ -1546,7 +1546,7 @@ func ldshlibsyms(shlib string) { 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 @@ -1563,7 +1563,7 @@ func ldshlibsyms(shlib string) { // 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 } } @@ -1579,7 +1579,7 @@ func ldshlibsyms(shlib string) { 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) @@ -1597,15 +1597,15 @@ func ldshlibsyms(shlib string) { // 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() { @@ -1688,21 +1688,21 @@ var morestack *Symbol // 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. @@ -1713,11 +1713,11 @@ func dostkcheck() { // 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. @@ -1726,28 +1726,28 @@ func dostkcheck() { } 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 @@ -1756,25 +1756,25 @@ func stkcheck(up *Chain, depth int) int { } 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 } @@ -1789,9 +1789,9 @@ func stkcheck(up *Chain, depth int) int { 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 { @@ -1802,7 +1802,7 @@ func stkcheck(up *Chain, depth int) int { 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. @@ -1812,12 +1812,12 @@ func stkcheck(up *Chain, depth int) int { 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 } @@ -1827,9 +1827,9 @@ func stkcheck(up *Chain, depth int) int { 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 } @@ -1838,13 +1838,13 @@ func stkcheck(up *Chain, depth int) int { // 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 } } @@ -1854,12 +1854,12 @@ func stkcheck(up *Chain, depth int) int { 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 { @@ -1879,8 +1879,8 @@ func stkprint(ch *Chain, limit int) { 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) } } @@ -1949,19 +1949,19 @@ func doversion() { 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 } @@ -1997,48 +1997,48 @@ func genasmsym(put func(*Symbol, string, int, int64, int64, int, *Symbol)) { 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 @@ -2059,13 +2059,13 @@ func genasmsym(put func(*Symbol, string, int, int64, int64, int, *Symbol)) { // 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 } } @@ -2079,15 +2079,15 @@ func genasmsym(put func(*Symbol, string, int, int64, int64, int, *Symbol)) { 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 @@ -2095,70 +2095,70 @@ func xdefine(p string, t int, v int64) { 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 { @@ -2171,11 +2171,11 @@ func callgraph() { } } -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...)) diff --git a/src/cmd/link/internal/ld/link.go b/src/cmd/link/internal/ld/link.go index 4c57bd30eb..e45c2d1338 100644 --- a/src/cmd/link/internal/ld/link.go +++ b/src/cmd/link/internal/ld/link.go @@ -171,13 +171,13 @@ type Link struct { // 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 diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 66db9bc646..af6bca6a07 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -294,38 +294,38 @@ func machowrite() int { 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 } @@ -347,7 +347,7 @@ func Machoadddynlib(lib string) { 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 @@ -376,7 +376,7 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) { 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 { @@ -400,7 +400,7 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) { 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" { @@ -413,7 +413,7 @@ func machoshbits(mseg *MachoSeg, sect *Section, segname string) { } } -func Asmbmacho() { +func Asmbmacho(ctxt *Link) { /* apple MACH */ va := INITTEXT - int64(HEADR) @@ -473,7 +473,7 @@ func Asmbmacho() { } for sect := Segtext.Sect; sect != nil; sect = sect.Next { - machoshbits(ms, sect, "__TEXT") + machoshbits(ctxt, ms, sect, "__TEXT") } /* data */ @@ -489,7 +489,7 @@ func Asmbmacho() { } for sect := Segdata.Sect; sect != nil; sect = sect.Next { - machoshbits(ms, sect, "__DATA") + machoshbits(ctxt, ms, sect, "__DATA") } /* dwarf */ @@ -502,7 +502,7 @@ func Asmbmacho() { ms.filesize = Segdwarf.Filelen } for sect := Segdwarf.Sect; sect != nil; sect = sect.Next { - machoshbits(ms, sect, "__DWARF") + machoshbits(ctxt, ms, sect, "__DWARF") } } @@ -512,39 +512,39 @@ func Asmbmacho() { 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) @@ -562,7 +562,7 @@ func Asmbmacho() { 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 */ @@ -612,7 +612,7 @@ func symkind(s *Symbol) int { 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 } @@ -656,78 +656,78 @@ func (x machoscmp) Less(i, j int) bool { 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 @@ -750,10 +750,10 @@ func machodysymtab() { 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 */ @@ -763,15 +763,15 @@ func machodysymtab() { 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 @@ -791,7 +791,7 @@ func Domacholink() int64 { // 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) @@ -809,7 +809,7 @@ func Domacholink() int64 { 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 @@ -834,7 +834,7 @@ func machorelocsect(sect *Section, syms []*Symbol) { if sym.Value >= int64(eaddr) { break } - Ctxt.Cursym = sym + ctxt.Cursym = sym for ri := 0; ri < len(sym.R); ri++ { r := &sym.R[ri] @@ -842,7 +842,7 @@ func machorelocsect(sect *Section, syms []*Symbol) { 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) } } } @@ -850,19 +850,19 @@ func machorelocsect(sect *Section, syms []*Symbol) { 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)) } } diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index ac28169d1f..8526f276c5 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -123,19 +123,19 @@ func addvarint(d *Pcdata, val uint32) { 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 } @@ -207,9 +207,9 @@ var pclntabPclntabOffset int32 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 @@ -222,47 +222,47 @@ func pclntab() { 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 @@ -271,37 +271,37 @@ func pclntab() { 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() } } @@ -309,14 +309,14 @@ func pclntab() { } // 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. @@ -327,12 +327,12 @@ func pclntab() { } 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]) } } @@ -340,7 +340,7 @@ func pclntab() { } 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() } @@ -349,20 +349,20 @@ func pclntab() { 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)) @@ -393,16 +393,16 @@ const ( // 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 } @@ -415,18 +415,18 @@ func findfunctab() { 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 @@ -452,25 +452,25 @@ func findfunctab() { // 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)) } } } diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 81862d7e33..e4bd3ec65e 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -377,9 +377,9 @@ var dexport [1024]*Symbol 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() } @@ -398,26 +398,26 @@ func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER 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 { @@ -441,9 +441,9 @@ func Peinit() { 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() { @@ -472,12 +472,12 @@ func strput(s string) { } } -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 } @@ -505,7 +505,7 @@ func initdynimport() *Dll { 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] @@ -521,13 +521,13 @@ func initdynimport() *Dll { 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) @@ -538,7 +538,7 @@ func initdynimport() *Dll { } } } 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 { @@ -569,9 +569,9 @@ func peimporteddlls() []string { 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) @@ -621,9 +621,9 @@ func addimports(datsect *IMAGE_SECTION_HEADER) { // 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() @@ -680,14 +680,14 @@ func (s byExtname) Len() int { return len(s) } func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s byExtname) 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() } @@ -698,7 +698,7 @@ func initdynexport() { 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 @@ -710,9 +710,9 @@ func addexports() { 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 @@ -764,7 +764,7 @@ func addexports() { // 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 @@ -791,7 +791,7 @@ func perelocsect(sect *Section, syms []*Symbol) int { if sym.Value >= int64(eaddr) { break } - Ctxt.Cursym = sym + ctxt.Cursym = sym for ri := 0; ri < len(sym.R); ri++ { r := &sym.R[ri] @@ -799,15 +799,15 @@ func perelocsect(sect *Section, syms []*Symbol) int { 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++ @@ -820,7 +820,7 @@ func perelocsect(sect *Section, syms []*Symbol) int { } // 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) } @@ -831,9 +831,9 @@ func peemitreloc(text, data, ctors *IMAGE_SECTION_HEADER) { 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() @@ -856,7 +856,7 @@ func peemitreloc(text, data, ctors *IMAGE_SECTION_HEADER) { n = 1 for sect := Segdata.Sect; sect != nil; sect = sect.Next { - n += perelocsect(sect, datap) + n += perelocsect(ctxt, sect, datap) } cpos = Cpos() @@ -871,7 +871,7 @@ func peemitreloc(text, data, ctors *IMAGE_SECTION_HEADER) { } 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 @@ -888,15 +888,15 @@ func peemitreloc(text, data, ctors *IMAGE_SECTION_HEADER) { } } -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 { @@ -913,14 +913,14 @@ func strtbladd(name string) int { * reference: pecoff_v8.docx Page 24. * */ -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 @@ -928,10 +928,10 @@ func newPEDWARFSection(name string, size int64) *IMAGE_SECTION_HEADER { // 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 } @@ -970,7 +970,7 @@ func writePESymTableRecords() int { } else if type_ == 'U' { typ = IMAGE_SYM_DTYPE_FUNCTION } else { - Diag("addpesym %#x", addr) + ctxt.Diag("addpesym %#x", addr) } // write COFF symbol table record @@ -1001,28 +1001,28 @@ func writePESymTableRecords() int { 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 @@ -1031,9 +1031,9 @@ func addpesymtable() { 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) @@ -1048,22 +1048,22 @@ func addpesymtable() { } } -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 @@ -1091,7 +1091,7 @@ func addpersrc() { 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. @@ -1108,13 +1108,13 @@ func addinitarray() (c *IMAGE_SECTION_HEADER) { 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() { @@ -1127,7 +1127,7 @@ func addinitarray() (c *IMAGE_SECTION_HEADER) { return c } -func Asmbpe() { +func Asmbpe(ctxt *Link) { switch SysArch.Family { default: Exitf("unknown PE architecture: %v", SysArch.Family) @@ -1137,50 +1137,50 @@ func Asmbpe() { 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) @@ -1218,8 +1218,8 @@ func Asmbpe() { 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 diff --git a/src/cmd/link/internal/ld/pobj.go b/src/cmd/link/internal/ld/pobj.go index 7a4555fd23..7ca6ccf8c8 100644 --- a/src/cmd/link/internal/ld/pobj.go +++ b/src/cmd/link/internal/ld/pobj.go @@ -48,9 +48,9 @@ var ( 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 @@ -79,12 +79,12 @@ func Ldmain() { 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`") @@ -124,8 +124,8 @@ func Ldmain() { 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 @@ -148,12 +148,12 @@ func Ldmain() { } } - 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)) } @@ -181,43 +181,43 @@ func Ldmain() { } 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) } diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index 8dd3c9eca4..90888e3ee0 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -84,7 +84,7 @@ var numelfsym int = 1 // 0 is reserved 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 { @@ -119,13 +119,13 @@ func putelfsym(x *Symbol, s string, t int, addr int64, size int64, ver int, go_ 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 @@ -190,11 +190,11 @@ func putelfsectionsym(s *Symbol, shndx int) { 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. @@ -204,14 +204,14 @@ func Asmelfsym() { 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 { @@ -263,8 +263,8 @@ func putplan9sym(x *Symbol, s string, t int, addr int64, size int64, ver int, go } } -func Asmplan9sym() { - genasmsym(putplan9sym) +func Asmplan9sym(ctxt *Link) { + genasmsym(ctxt, putplan9sym) } var symt *Symbol @@ -317,67 +317,67 @@ func (libs byPkg) Swap(a, b int) { 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 @@ -387,7 +387,7 @@ func symtab() { } 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 @@ -400,13 +400,13 @@ func symtab() { 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 @@ -419,7 +419,7 @@ func symtab() { // 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 } @@ -483,61 +483,61 @@ func symtab() { } 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: @@ -545,44 +545,44 @@ func symtab() { // 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) } } diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go index 4bde70dc8e..c1e52ee098 100644 --- a/src/cmd/link/internal/mips64/asm.go +++ b/src/cmd/link/internal/mips64/asm.go @@ -102,6 +102,7 @@ func machoreloc1(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 { switch r.Type { default: @@ -115,12 +116,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -142,12 +143,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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) @@ -158,9 +159,9 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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) @@ -169,7 +170,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -182,22 +183,22 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { 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 { @@ -207,7 +208,7 @@ func asmb() { 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 { @@ -216,10 +217,10 @@ func asmb() { 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 @@ -250,17 +251,17 @@ func asmb() { 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) @@ -292,8 +293,8 @@ func asmb() { 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)) @@ -302,7 +303,7 @@ func asmb() { obj.Hnetbsd, obj.Hopenbsd, obj.Hnacl: - ld.Asmbelf(int64(symo)) + ld.Asmbelf(ctxt, int64(symo)) } ld.Cflush() diff --git a/src/cmd/link/internal/mips64/obj.go b/src/cmd/link/internal/mips64/obj.go index ae9a280083..ab439ef3f8 100644 --- a/src/cmd/link/internal/mips64/obj.go +++ b/src/cmd/link/internal/mips64/obj.go @@ -130,7 +130,7 @@ func archinit() { } 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) @@ -143,7 +143,7 @@ func archinit() { } case obj.Hnacl: - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = 0x10000 ld.Funcalign = 16 if ld.INITTEXT == -1 { diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index 1075ece578..f973bdfe99 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -247,7 +247,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 } @@ -264,7 +264,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -274,7 +274,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -350,7 +350,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { // 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 { @@ -458,7 +458,7 @@ func symtoc(s *ld.Symbol) int64 { } if toc == nil { - ld.Diag("TOC-relative relocation in object without .TOC.") + ld.Ctxt.Diag("TOC-relative relocation in object without .TOC.") return 0 } @@ -466,6 +466,7 @@ func symtoc(s *ld.Symbol) int64 { } 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) @@ -482,9 +483,9 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { // 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 @@ -498,7 +499,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -515,6 +516,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { } func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { + ctxt := ld.Ctxt if ld.Linkmode == ld.LinkExternal { switch r.Type { default: @@ -539,12 +541,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -564,7 +566,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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: @@ -573,7 +575,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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) } @@ -587,7 +589,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 @@ -598,7 +600,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { // 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 @@ -610,7 +612,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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: @@ -685,7 +687,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { 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 @@ -694,7 +696,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { } 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 } @@ -739,7 +741,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { 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") } } @@ -798,27 +800,27 @@ func ensureglinkresolver() *ld.Symbol { // 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 { @@ -828,7 +830,7 @@ func asmb() { 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 { @@ -837,10 +839,10 @@ func asmb() { 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 @@ -871,17 +873,17 @@ func asmb() { 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) @@ -909,8 +911,8 @@ func asmb() { 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)) @@ -919,7 +921,7 @@ func asmb() { obj.Hnetbsd, obj.Hopenbsd, obj.Hnacl: - ld.Asmbelf(int64(symo)) + ld.Asmbelf(ctxt, int64(symo)) } ld.Cflush() diff --git a/src/cmd/link/internal/ppc64/obj.go b/src/cmd/link/internal/ppc64/obj.go index b619eb9f43..608e9f65aa 100644 --- a/src/cmd/link/internal/ppc64/obj.go +++ b/src/cmd/link/internal/ppc64/obj.go @@ -148,7 +148,7 @@ func archinit() { 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) @@ -161,7 +161,7 @@ func archinit() { } case obj.Hnacl: - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = 0x10000 ld.Funcalign = 16 if ld.INITTEXT == -1 { diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index ba892402a1..cd65537e3c 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -105,14 +105,14 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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, @@ -120,7 +120,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -129,10 +129,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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) @@ -141,7 +141,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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, @@ -168,20 +168,20 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -198,7 +198,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -224,7 +224,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 { @@ -381,6 +381,7 @@ func machoreloc1(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 } @@ -391,7 +392,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 } @@ -401,7 +402,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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: @@ -409,7 +410,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { 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 } @@ -474,7 +475,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { s.Plt = int32(plt.Size - 32) } else { - ld.Diag("addpltsym: unsupported binary format") + ld.Ctxt.Diag("addpltsym: unsupported binary format") } } @@ -494,26 +495,26 @@ func addgotsym(s *ld.Symbol) { 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 { @@ -523,7 +524,7 @@ func asmb() { 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 { @@ -532,10 +533,10 @@ func asmb() { 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 @@ -544,7 +545,7 @@ func asmb() { 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()) @@ -557,7 +558,7 @@ func asmb() { 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) @@ -566,7 +567,7 @@ func asmb() { } if ld.Linkmode == ld.LinkExternal { - ld.Elfemitreloc() + ld.Elfemitreloc(ctxt) } } @@ -578,9 +579,9 @@ func asmb() { 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() diff --git a/src/cmd/link/internal/s390x/obj.go b/src/cmd/link/internal/s390x/obj.go index b77f57db72..bf9bdbc5e1 100644 --- a/src/cmd/link/internal/s390x/obj.go +++ b/src/cmd/link/internal/s390x/obj.go @@ -95,7 +95,7 @@ func archinit() { 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) diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index 770907179e..26c1650a0c 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -156,17 +156,17 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -204,7 +204,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 } @@ -226,7 +226,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -234,7 +234,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { 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 @@ -255,7 +255,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { // 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 } @@ -330,7 +330,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { } 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 { @@ -404,7 +404,7 @@ func machoreloc1(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 } @@ -413,7 +413,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { } 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 } } @@ -459,7 +459,7 @@ func pereloc1(r *ld.Reloc, sectoff int64) bool { 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 } @@ -493,7 +493,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { 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 } @@ -588,7 +588,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { 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") } } @@ -609,27 +609,27 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) { } 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 { @@ -639,7 +639,7 @@ func asmb() { 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 { @@ -648,14 +648,14 @@ func asmb() { 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 @@ -693,20 +693,20 @@ func asmb() { 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++ { @@ -723,7 +723,7 @@ func asmb() { case obj.Hdarwin: if ld.Linkmode == ld.LinkExternal { - ld.Machoemitreloc() + ld.Machoemitreloc(ctxt) } } } @@ -742,23 +742,23 @@ func asmb() { 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() diff --git a/src/cmd/link/internal/x86/obj.go b/src/cmd/link/internal/x86/obj.go index a4d8f5070a..dea8c6411f 100644 --- a/src/cmd/link/internal/x86/obj.go +++ b/src/cmd/link/internal/x86/obj.go @@ -145,7 +145,7 @@ func archinit() { obj.Hfreebsd, obj.Hnetbsd, obj.Hopenbsd: - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = ld.ELFRESERVE if ld.INITTEXT == -1 { @@ -159,7 +159,7 @@ func archinit() { } case obj.Hnacl: - ld.Elfinit() + ld.Elfinit(ld.Ctxt) ld.HEADR = 0x10000 ld.Funcalign = 32 if ld.INITTEXT == -1 { @@ -173,7 +173,7 @@ func archinit() { } case obj.Hwindows: /* PE executable */ - ld.Peinit() + ld.Peinit(ld.Ctxt) ld.HEADR = ld.PEFILEHEADR if ld.INITTEXT == -1 {