]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link/internal: thread *ld.Link through calls
authorMichael Matloob <matloob@golang.org>
Sat, 20 Aug 2016 02:40:38 +0000 (22:40 -0400)
committerMichael Matloob <matloob@golang.org>
Sun, 21 Aug 2016 15:56:43 +0000 (15:56 +0000)
Ctxt is a global defined in cmd/link/internal/ld of type *ld.Link.
Start threading a *ld.Link through function calls instead of
relying on the global variable.

Ctxt is still used as a global by the architecture-specific packages,
but I plan to fix that in a subsequent CL.

Change-Id: I77a3a58bd396fafd959fa1d8b1c83008a9f5a7fb
Reviewed-on: https://go-review.googlesource.com/27408
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
32 files changed:
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/amd64/obj.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/arm/obj.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/arm64/obj.go
src/cmd/link/internal/ld/ar.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/ld/decodesym.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/go.go
src/cmd/link/internal/ld/ld.go
src/cmd/link/internal/ld/ldelf.go
src/cmd/link/internal/ld/ldmacho.go
src/cmd/link/internal/ld/ldpe.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/macho.go
src/cmd/link/internal/ld/pcln.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/ld/pobj.go
src/cmd/link/internal/ld/symtab.go
src/cmd/link/internal/mips64/asm.go
src/cmd/link/internal/mips64/obj.go
src/cmd/link/internal/ppc64/asm.go
src/cmd/link/internal/ppc64/obj.go
src/cmd/link/internal/s390x/asm.go
src/cmd/link/internal/s390x/obj.go
src/cmd/link/internal/x86/asm.go
src/cmd/link/internal/x86/obj.go

index ec430db51c10c67bff9ce0edca8d50aa66761423..39ce45780428fd45164f7f927052df6e682fed86 100644 (file)
@@ -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()
index f62f237b57bed49e09484b2b5a31053d303c9ef2..c41d2bec9c448baeb11c82d88885958d0e11e12b 100644 (file)
@@ -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 {
index 5cd02eba6a01148a8b2c53848bbb1080e5667015..7e58f81d4f0844b3feb09e9e7ba49896d2bff279 100644 (file)
@@ -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()
index 9ea9771ca4e3b151360dcb9728a78698268e52dc..3213231b9e260eccffe694c850c74e8ef6e41aa7 100644 (file)
@@ -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 {
index 544ed1e4330ac7c58ef201d4323fcf5d54d26268..aff1c54c2b84594a0321f480a515d8c1402958a3 100644 (file)
@@ -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()
index 86f9ff79b0257e953477489cdcc91a439c836e14..136d1d4c7a2c7c9ebc24e5917e5abef192af1a3f 100644 (file)
@@ -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 {
index 80c33ceebad2fd07b8cb485beb3e09453af32a22..1eac15ec19d4f5cd07faf090742a23a5baf8a140 100644 (file)
@@ -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
index 9cbb8121e4602fa0f15cda10d89a87f0cd252fea..848ba619342c1690ecb045ee57721fcf92b971eb 100644 (file)
@@ -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))
 }
index 8b59da34b6e3309dedd8a2f27d22cc3c9ef9b167..6278b5d580532dc0e9df68d3dc1156a220862e96 100644 (file)
@@ -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)))
                        }
index d757cc9ff9126440c0f73d60d90de694f3f0efd8..7ec6ad665428900dfd34210faca0e44bbd611a56 100644 (file)
@@ -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)
 }
index 62f6da1d3c6e244882122dfe50224ef9ff565f62..0edeedca1bc6c53b0fc34894ff5a3417eeab7218 100644 (file)
@@ -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("<unspecified>")
+               return mustFind(ctxt, "<unspecified>")
        }
 
        if !strings.HasPrefix(gotype.Name, "type.") {
-               Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name)
-               return mustFind("<unspecified>")
+               ctxt.Diag("dwarf: type name doesn't start with \"type.\": %s", gotype.Name)
+               return mustFind(ctxt, "<unspecified>")
        }
 
        name := gotype.Name[5:] // could also decode from Type.string
 
-       sdie := find(name)
+       sdie := find(ctxt, name)
 
        if sdie != nil {
                return sdie
        }
 
-       return newtype(gotype).Sym.(*Symbol)
+       return newtype(ctxt, gotype).Sym.(*Symbol)
 }
 
-func newtype(gotype *Symbol) *dwarf.DWDie {
+func newtype(ctxt *Link, gotype *Symbol) *dwarf.DWDie {
        name := gotype.Name[5:] // could also decode from Type.string
        kind := decodetype_kind(gotype)
-       bytesize := decodetype_size(gotype)
+       bytesize := decodetype_size(ctxt.Arch, gotype)
 
        var die *dwarf.DWDie
        switch kind {
        case obj.KindBool:
-               die = newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
+               die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, name, 0)
                newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_boolean, 0)
                newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
 
@@ -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("<unspecified>"))
+               ctxt.Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
+               die = newdie(ctxt, &dwtypes, dwarf.DW_ABRV_TYPEDECL, name, 0)
+               newrefattr(die, dwarf.DW_AT_type, mustFind(ctxt, "<unspecified>"))
        }
 
        newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, int64(kind), 0)
@@ -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<K,V>
-               dwhbs := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) {
+               dwhbs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "bucket", keyname, valname, func(dwhb *dwarf.DWDie) {
                        // Copy over all fields except the field "data" from the generic
                        // bucket. "data" will be replaced with keys/values below.
-                       copychildrenexcept(dwhb, bucket, findchild(bucket, "data"))
+                       copychildrenexcept(ctxt, dwhb, bucket, findchild(bucket, "data"))
 
-                       fld := newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys", 0)
+                       fld := newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "keys", 0)
                        newrefattr(fld, dwarf.DW_AT_type, dwhks)
                        newmemberoffsetattr(fld, BucketSize)
-                       fld = newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values", 0)
+                       fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "values", 0)
                        newrefattr(fld, dwarf.DW_AT_type, dwhvs)
                        newmemberoffsetattr(fld, BucketSize+BucketSize*int32(keysize))
-                       fld = newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0)
-                       newrefattr(fld, dwarf.DW_AT_type, defptrto(dtolsym(dwhb.Sym)))
+                       fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "overflow", 0)
+                       newrefattr(fld, dwarf.DW_AT_type, defptrto(ctxt, dtolsym(dwhb.Sym)))
                        newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
                        if SysArch.RegSize > SysArch.PtrSize {
-                               fld = newdie(dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0)
-                               newrefattr(fld, dwarf.DW_AT_type, mustFind("uintptr"))
+                               fld = newdie(ctxt, dwhb, dwarf.DW_ABRV_STRUCTFIELD, "pad", 0)
+                               newrefattr(fld, dwarf.DW_AT_type, mustFind(ctxt, "uintptr"))
                                newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(SysArch.PtrSize))
                        }
 
@@ -747,22 +749,22 @@ func synthesizemaptypes(die *dwarf.DWDie) {
                })
 
                // Construct hash<K,V>
-               dwhs := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) {
-                       copychildren(dwh, hash)
-                       substitutetype(dwh, "buckets", defptrto(dwhbs))
-                       substitutetype(dwh, "oldbuckets", defptrto(dwhbs))
+               dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hash", keyname, valname, func(dwh *dwarf.DWDie) {
+                       copychildren(ctxt, dwh, hash)
+                       substitutetype(dwh, "buckets", defptrto(ctxt, dwhbs))
+                       substitutetype(dwh, "oldbuckets", defptrto(ctxt, dwhbs))
                        newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hash, dwarf.DW_AT_byte_size).Value, nil)
                })
 
                // make map type a pointer to hash<K,V>
-               newrefattr(die, dwarf.DW_AT_type, defptrto(dwhs))
+               newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs))
        }
 }
 
-func synthesizechantypes(die *dwarf.DWDie) {
-       sudog := walktypedef(findprotodie("type.runtime.sudog"))
-       waitq := walktypedef(findprotodie("type.runtime.waitq"))
-       hchan := walktypedef(findprotodie("type.runtime.hchan"))
+func synthesizechantypes(ctxt *Link, die *dwarf.DWDie) {
+       sudog := walktypedef(findprotodie(ctxt, "type.runtime.sudog"))
+       waitq := walktypedef(findprotodie(ctxt, "type.runtime.waitq"))
+       hchan := walktypedef(findprotodie(ctxt, "type.runtime.hchan"))
        if sudog == nil || waitq == nil || hchan == nil {
                return
        }
@@ -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<T>
-               dwss := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
-                       copychildren(dws, sudog)
+               dwss := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "sudog", elemname, "", func(dws *dwarf.DWDie) {
+                       copychildren(ctxt, dws, sudog)
                        substitutetype(dws, "elem", elemtype)
                        if elemsize > 8 {
                                elemsize -= 8
@@ -791,28 +793,28 @@ func synthesizechantypes(die *dwarf.DWDie) {
                })
 
                // waitq<T>
-               dwws := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) {
+               dwws := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "waitq", elemname, "", func(dww *dwarf.DWDie) {
 
-                       copychildren(dww, waitq)
-                       substitutetype(dww, "first", defptrto(dwss))
-                       substitutetype(dww, "last", defptrto(dwss))
+                       copychildren(ctxt, dww, waitq)
+                       substitutetype(dww, "first", defptrto(ctxt, dwss))
+                       substitutetype(dww, "last", defptrto(ctxt, dwss))
                        newattr(dww, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(waitq, dwarf.DW_AT_byte_size).Value, nil)
                })
 
                // hchan<T>
-               dwhs := mkinternaltype(dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) {
-                       copychildren(dwh, hchan)
+               dwhs := mkinternaltype(ctxt, dwarf.DW_ABRV_STRUCTTYPE, "hchan", elemname, "", func(dwh *dwarf.DWDie) {
+                       copychildren(ctxt, dwh, hchan)
                        substitutetype(dwh, "recvq", dwws)
                        substitutetype(dwh, "sendq", dwws)
                        newattr(dwh, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, getattr(hchan, dwarf.DW_AT_byte_size).Value, nil)
                })
 
-               newrefattr(die, dwarf.DW_AT_type, defptrto(dwhs))
+               newrefattr(die, dwarf.DW_AT_type, defptrto(ctxt, dwhs))
        }
 }
 
 // For use with pass.c::genasmsym
-func defdwsymb(sym *Symbol, s string, t int, v int64, size int64, ver int, gotype *Symbol) {
+func defdwsymb(ctxt *Link, sym *Symbol, s string, t int, v int64, size int64, ver int, gotype *Symbol) {
        if strings.HasPrefix(s, "go.string.") {
                return
        }
@@ -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, "<unspecified>", 0)
+       newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "<unspecified>", 0)
 
-       newdie(&dwtypes, dwarf.DW_ABRV_NULLTYPE, "void", 0)
-       newdie(&dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0)
+       newdie(ctxt, &dwtypes, dwarf.DW_ABRV_NULLTYPE, "void", 0)
+       newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer", 0)
 
-       die := newdie(&dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
+       die := newdie(ctxt, &dwtypes, dwarf.DW_ABRV_BASETYPE, "uintptr", 0) // needed for array size
        newattr(die, dwarf.DW_AT_encoding, dwarf.DW_CLS_CONSTANT, dwarf.DW_ATE_unsigned, 0)
        newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, int64(SysArch.PtrSize), 0)
        newattr(die, dwarf.DW_AT_go_kind, dwarf.DW_CLS_CONSTANT, obj.KindUintptr, 0)
@@ -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()
                }
        }
index 98b5a9e4f0d1fb0d7a2a1d8a4406be96d5b2503d..9de1a2f53230f0d1304ab21a9b1529b3555ca6fb 100644 (file)
@@ -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 {
index aec54c1142dd232c8aa8e9af54fe176b0a21876b..bd184c734ac66eb51d84812521d511da586cfab5 100644 (file)
@@ -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)
        }
 }
 
index bbbfd3e0493095683076d179643186a593e00382..cf33a9f42decff62b409ec338f90eaf14066af90 100644 (file)
@@ -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))
        }
index 2ee06b2ded63671bbe5fbbf93fede96c1f9ff0d9..070c16012ac581e3229f5543e448292031199f34 100644 (file)
@@ -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:
index 549516a0c033d4495dcb246277b4889dfaad579a..66a2c6d13aab54ec2993f3e32ea726975ab2f6b0 100644 (file)
@@ -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)
 }
index 7ace279f6f5c6ed35ceb678f0c55f70f068fa1f9..e7e871e99885be787a78e85d5b9e27ca37c9a1b4 100644 (file)
@@ -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:
index 74dd001f8edc1058bc47db1ce53339bc1a7aa737..d43312b989d3e10ead2c6df1ce58407c948f064d 100644 (file)
@@ -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...))
index 4c57bd30eb41ac19fc6f6869900fabebd6820f39..e45c2d1338023288caf20e597756f7691ae78601 100644 (file)
@@ -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
index 66db9bc646bf24e715cd6bfebfa84063b76b9ac0..af6bca6a07660d95f31318c53c9b11ac252ba429 100644 (file)
@@ -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))
        }
 }
index ac28169d1fe7a137c96e26c330d0e113a8ead0ab..8526f276c5302e84a9f07d0781d93a9a5ed12f01 100644 (file)
@@ -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))
                }
        }
 }
index 81862d7e33065193b43ae88a541f2106a34d8077..e4bd3ec65eb2b6df4fef80413a3dc6aa64581b9c 100644 (file)
@@ -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.
  * <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
  */
-func newPEDWARFSection(name string, size int64) *IMAGE_SECTION_HEADER {
+func newPEDWARFSection(ctxt *Link, name string, size int64) *IMAGE_SECTION_HEADER {
        if size == 0 {
                return nil
        }
 
        off := strtbladd(name)
        s := fmt.Sprintf("/%d", off)
-       h := addpesection(s, int(size), int(size))
+       h := addpesection(ctxt, s, int(size), int(size))
        h.Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE
 
        return h
@@ -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
index 7a4555fd23016ee82e0e35c3c30b58f38efa5f6c..7ca6ccf8c818756e6826035945e612bdbf8ee2a4 100644 (file)
@@ -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)
        }
 
index 8dd3c9eca4a5ec98e0c5cb0a9bb539a4dd428150..90888e3ee03c497006487f7fc1689352d7a69df5 100644 (file)
@@ -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)
        }
 }
index 4bde70dc8e2e063a3e668b8617f9762f5ccd0274..c1e52ee0982532e54033c11bd701973d7aac0a70 100644 (file)
@@ -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()
index ae9a280083817e1fc7cd8bfcbb7cd5739af2b752..ab439ef3f809c7187a9a0c437b4cd21ff557fd03 100644 (file)
@@ -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 {
index 1075ece578b727287a40bb720178e4ac84559241..f973bdfe999311c8ff4b118840d75869704446db 100644 (file)
@@ -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()
index b619eb9f4380b75822485d3b47715336450ae42b..608e9f65aaa081dba6a934a73f8eff88e861bf58 100644 (file)
@@ -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 {
index ba892402a1a1344cbcda31b67af41cb1336619b9..cd65537e3cfc1c597b725c83d8b1dee35fdc1a0a 100644 (file)
@@ -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()
index b77f57db72459f1fa0db5d235b60f635c3788eba..bf9bdbc5e1973a4c6f3f84caebf66ea311d74137 100644 (file)
@@ -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)
index 770907179e701d0f10552691f46b0c5567af4108..26c1650a0c059d89973b9cb7097c02cccac50517 100644 (file)
@@ -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()
index a4d8f5070ab0fedd299c775d19aa7a775e9d9a70..dea8c6411f4a06f1913d879db9711745db01ac08 100644 (file)
@@ -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 {