From: Jeremy Faller Date: Wed, 4 Mar 2020 22:25:01 +0000 (-0500) Subject: [dev.link] cmd/link: eliminate usage of *Link in arch funcs X-Git-Tag: go1.15beta1~679^2~60 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=bf5dc7af0fed15a28fadac8ea07e497cd9c9742d;p=gostls13.git [dev.link] cmd/link: eliminate usage of *Link in arch funcs Change-Id: I10e6b266ff3a1238d1b86a9b39debb13f5a04e55 Reviewed-on: https://go-review.googlesource.com/c/go/+/222159 Run-TryBot: Jeremy Faller TryBot-Result: Gobot Gobot Reviewed-by: Than McIntosh --- diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go index 06c4a362a9..9b87170b06 100644 --- a/src/cmd/link/internal/amd64/asm.go +++ b/src/cmd/link/internal/amd64/asm.go @@ -107,13 +107,13 @@ func makeWritable(s *sym.Symbol) { } } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= objabi.ElfRelocOffset { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type)) return false } @@ -146,8 +146,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo r.Type = objabi.R_PCREL r.Add += 4 if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } @@ -171,10 +171,10 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // fall back to using GOT and hope for the best (CMOV*) // TODO: just needs relocation, no need to put in .dynsym - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += 4 r.Add += int64(targ.Got()) return true @@ -184,7 +184,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_ADDR - if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal { + if target.IsPIE() && target.IsInternal() { // For internal linking PIE, this R_ADDR relocation cannot // be resolved statically. We need to generate a dynamic // relocation. Let the code below handle it. @@ -206,8 +206,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1: if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(targ.Plt()) r.Type = objabi.R_PCREL return true @@ -246,9 +246,9 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo if targ.Type != sym.SDYNIMPORT { ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name) } - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) return true } @@ -260,37 +260,37 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // nothing to do, the relocation will be laid out in reloc return true } - if ctxt.LinkMode == ld.LinkExternal { + if target.IsExternal() { // External linker will do this relocation. return true } // Internal linking, for both ELF and Mach-O. // Build a PLT entry and change the relocation target to that entry. - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(targ.Plt()) return true case objabi.R_ADDR: - if s.Type == sym.STEXT && ctxt.IsELF { - if ctxt.HeadType == objabi.Hsolaris { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + if s.Type == sym.STEXT && target.IsElf() { + if target.IsSolaris() { + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) return true } // The code is asking for the address of an external // function. We provide it with the address of the // correspondent GOT symbol. - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) return true } // Process dynamic relocations for the data sections. - if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal { + if target.IsPIE() && target.IsInternal() { // When internally linking, generate dynamic relocations // for all typical R_ADDR relocations. The exception // are those R_ADDR that are created as part of generating @@ -338,7 +338,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo } } - if ctxt.IsELF { + if target.IsElf() { // Generate R_X86_64_RELATIVE relocations for best // efficiency in the dynamic linker. // @@ -356,14 +356,14 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // AddAddrPlus is used for r_offset and r_addend to // generate new R_ADDR relocations that will update // these fields in the 'reloc' phase. - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) + rela := syms.Rela + rela.AddAddrPlus(target.Arch, s, int64(r.Off)) if r.Siz == 8 { - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE))) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE))) } else { ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name) } - rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add)) + rela.AddAddrPlus(target.Arch, targ, int64(r.Add)) // Not mark r done here. So we still apply it statically, // so in the file content we'll also have the right offset // to the relocation target. So it can be examined statically @@ -371,7 +371,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo return true } - if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 { + if target.IsDarwin() && s.Size == int64(target.Arch.PtrSize) && r.Off == 0 { // Mach-O relocations are a royal pain to lay out. // They use a compact stateful bytecode representation // that is too much bother to deal with. @@ -382,17 +382,17 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // just in case the C code assigns to the variable, // and of course it only works for single pointers, // but we only need to support cgo and that's all it needs. - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ) + ld.Adddynsym(target, syms, targ) - got := ctxt.Syms.Lookup(".got", 0) + got := syms.GOT s.Type = got.Type s.Attr |= sym.AttrSubSymbol s.Outer = got s.Sub = got.Sub got.Sub = s s.Value = got.Size - got.AddUint64(ctxt.Arch, 0) - ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid)) + got.AddUint64(target.Arch, 0) + syms.LinkEditGOT.AddUint32(target.Arch, uint32(targ.Dynid)) r.Type = objabi.ElfRelocOffset // ignore during relocsym return true } @@ -598,17 +598,17 @@ func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.S } } -func addpltsym(ctxt *ld.Link, s *sym.Symbol) { +func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Plt() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) + ld.Adddynsym(target, syms, s) - if ctxt.IsELF { - plt := ctxt.Syms.Lookup(".plt", 0) - got := ctxt.Syms.Lookup(".got.plt", 0) - rela := ctxt.Syms.Lookup(".rela.plt", 0) + if target.IsElf() { + plt := syms.PLT + got := syms.GOTPLT + rela := syms.RelaPLT if plt.Size == 0 { panic("plt is not set up") } @@ -617,29 +617,29 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { plt.AddUint8(0xff) plt.AddUint8(0x25) - plt.AddPCRelPlus(ctxt.Arch, got, got.Size) + plt.AddPCRelPlus(target.Arch, got, got.Size) // add to got: pointer to current pos in plt - got.AddAddrPlus(ctxt.Arch, plt, plt.Size) + got.AddAddrPlus(target.Arch, plt, plt.Size) // pushq $x plt.AddUint8(0x68) - plt.AddUint32(ctxt.Arch, uint32((got.Size-24-8)/8)) + plt.AddUint32(target.Arch, uint32((got.Size-24-8)/8)) // jmpq .plt plt.AddUint8(0xe9) - plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4))) + plt.AddUint32(target.Arch, uint32(-(plt.Size + 4))) // rela - rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) + rela.AddAddrPlus(target.Arch, got, got.Size-8) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT))) - rela.AddUint64(ctxt.Arch, 0) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT))) + rela.AddUint64(target.Arch, 0) s.SetPlt(int32(plt.Size - 16)) - } else if ctxt.HeadType == objabi.Hdarwin { + } else if target.IsDarwin() { // To do lazy symbol lookup right, we're supposed // to tell the dynamic loader which library each // symbol comes from and format the link info @@ -650,39 +650,39 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { // https://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html // has details about what we're avoiding. - addgotsym(ctxt, s) - plt := ctxt.Syms.Lookup(".plt", 0) + addgotsym(target, syms, s) + plt := syms.PLT - ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid)) + syms.LinkEditPLT.AddUint32(target.Arch, uint32(s.Dynid)) // jmpq *got+size(IP) s.SetPlt(int32(plt.Size)) plt.AddUint8(0xff) plt.AddUint8(0x25) - plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got())) + plt.AddPCRelPlus(target.Arch, syms.GOT, int64(s.Got())) } else { ld.Errorf(s, "addpltsym: unsupported binary format") } } -func addgotsym(ctxt *ld.Link, s *sym.Symbol) { +func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) - got := ctxt.Syms.Lookup(".got", 0) + ld.Adddynsym(target, syms, s) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddUint64(ctxt.Arch, 0) - - if ctxt.IsELF { - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT))) - rela.AddUint64(ctxt.Arch, 0) - } else if ctxt.HeadType == objabi.Hdarwin { - ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid)) + got.AddUint64(target.Arch, 0) + + if target.IsElf() { + rela := syms.Rela + rela.AddAddrPlus(target.Arch, got, int64(s.Got())) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT))) + rela.AddUint64(target.Arch, 0) + } else if target.IsDarwin() { + syms.LinkEditGOT.AddUint32(target.Arch, uint32(s.Dynid)) } else { ld.Errorf(s, "addgotsym: unsupported binary format") } diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index e4a52e5589..765882f0e0 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go @@ -116,13 +116,13 @@ func braddoff(a int32, b int32) int32 { return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b)) } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= objabi.ElfRelocOffset { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type)) return false } @@ -131,8 +131,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo r.Type = objabi.R_CALLARM if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4)) } @@ -144,9 +144,9 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL if targ.Type != sym.SDYNIMPORT { - addgotsyminternal(ctxt, targ) + addgotsyminternal(target, syms, targ) } else { - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) } r.Type = objabi.R_CONST // write r->add during relocsym @@ -156,13 +156,13 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil if targ.Type != sym.SDYNIMPORT { - addgotsyminternal(ctxt, targ) + addgotsyminternal(target, syms, targ) } else { - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) } r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) + 4 return true @@ -174,15 +174,15 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += 4 return true case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL): r.Type = objabi.R_CALLARM if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4)) } @@ -215,8 +215,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24): r.Type = objabi.R_CALLARM if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4)) } @@ -230,12 +230,12 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo switch r.Type { case objabi.R_CALLARM: - if ctxt.LinkMode == ld.LinkExternal { + if target.IsExternal() { // External linker will do this relocation. return true } - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(targ.Plt()) return true @@ -243,12 +243,12 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo if s.Type != sym.SDATA { break } - if ctxt.IsELF { - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ) - rel := ctxt.Syms.Lookup(".rel", 0) - rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) - rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc - r.Type = objabi.R_CONST // write r->add during relocsym + if target.IsElf() { + ld.Adddynsym(target, syms, targ) + rel := syms.Rel + rel.AddAddrPlus(target.Arch, s, int64(r.Off)) + rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc + r.Type = objabi.R_CONST // write r->add during relocsym r.Sym = nil return true } @@ -671,7 +671,7 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym return t } -func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) { +func addpltreloc(plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) { r := plt.AddRel() r.Sym = got r.Off = int32(plt.Size) @@ -684,17 +684,17 @@ func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, plt.Grow(plt.Size) } -func addpltsym(ctxt *ld.Link, s *sym.Symbol) { +func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Plt() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) + ld.Adddynsym(target, syms, s) - if ctxt.IsELF { - plt := ctxt.Syms.Lookup(".plt", 0) - got := ctxt.Syms.Lookup(".got.plt", 0) - rel := ctxt.Syms.Lookup(".rel.plt", 0) + if target.IsElf() { + plt := syms.PLT + got := syms.GOTPLT + rel := syms.RelPLT if plt.Size == 0 { panic("plt is not set up") } @@ -705,54 +705,54 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { // In theory, all GOT should point to the first PLT entry, // Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's // dynamic linker won't, so we'd better do it ourselves. - got.AddAddrPlus(ctxt.Arch, plt, 0) + got.AddAddrPlus(target.Arch, plt, 0) // .plt entry, this depends on the .got entry s.SetPlt(int32(plt.Size)) - addpltreloc(ctxt, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000 - addpltreloc(ctxt, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000 - addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]! + addpltreloc(plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000 + addpltreloc(plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000 + addpltreloc(plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]! // rel - rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) + rel.AddAddrPlus(target.Arch, got, int64(s.Got())) - rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT))) + rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT))) } else { ld.Errorf(s, "addpltsym: unsupported binary format") } } -func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) { +func addgotsyminternal(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - got := ctxt.Syms.Lookup(".got", 0) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddAddrPlus(ctxt.Arch, s, 0) + got.AddAddrPlus(target.Arch, s, 0) - if ctxt.IsELF { + if target.IsElf() { } else { ld.Errorf(s, "addgotsyminternal: unsupported binary format") } } -func addgotsym(ctxt *ld.Link, s *sym.Symbol) { +func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) - got := ctxt.Syms.Lookup(".got", 0) + ld.Adddynsym(target, syms, s) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddUint32(ctxt.Arch, 0) + got.AddUint32(target.Arch, 0) - if ctxt.IsELF { - rel := ctxt.Syms.Lookup(".rel", 0) - rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) - rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT))) + if target.IsElf() { + rel := syms.Rel + rel.AddAddrPlus(target.Arch, got, int64(s.Got())) + rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT))) } else { ld.Errorf(s, "addgotsym: unsupported binary format") } diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go index 0b4ecd6c5f..01eb7864d6 100644 --- a/src/cmd/link/internal/arm64/asm.go +++ b/src/cmd/link/internal/arm64/asm.go @@ -92,13 +92,13 @@ func gentext(ctxt *ld.Link) { initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= objabi.ElfRelocOffset { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type)) return false } @@ -130,8 +130,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26), objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26): if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() { @@ -149,10 +149,10 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // fall back to using GOT // TODO: just needs relocation, no need to put in .dynsym - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) r.Type = objabi.R_ARM64_GOT - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) return true @@ -172,7 +172,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo ld.Errorf(s, "unexpected R_AARCH64_ABS64 relocation for dynamic symbol %s", targ.Name) } r.Type = objabi.R_ADDR - if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal { + if target.IsPIE() && target.IsInternal() { // For internal linking PIE, this R_ADDR relocation cannot // be resolved statically. We need to generate a dynamic // relocation. Let the code below handle it. @@ -217,25 +217,25 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // nothing to do, the relocation will be laid out in reloc return true } - if ctxt.LinkMode == ld.LinkExternal { + if target.IsExternal() { // External linker will do this relocation. return true } case objabi.R_ADDR: - if s.Type == sym.STEXT && ctxt.IsELF { + if s.Type == sym.STEXT && target.IsElf() { // The code is asking for the address of an external // function. We provide it with the address of the // correspondent GOT symbol. - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) return true } // Process dynamic relocations for the data sections. - if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal { + if target.IsPIE() && target.IsInternal() { // When internally linking, generate dynamic relocations // for all typical R_ADDR relocations. The exception // are those R_ADDR that are created as part of generating @@ -283,7 +283,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo } } - if ctxt.IsELF { + if target.IsElf() { // Generate R_AARCH64_RELATIVE relocations for best // efficiency in the dynamic linker. // @@ -301,14 +301,14 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // AddAddrPlus is used for r_offset and r_addend to // generate new R_ADDR relocations that will update // these fields in the 'reloc' phase. - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) + rela := syms.Rela + rela.AddAddrPlus(target.Arch, s, int64(r.Off)) if r.Siz == 8 { - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE))) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE))) } else { ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name) } - rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add)) + rela.AddAddrPlus(target.Arch, targ, int64(r.Add)) // Not mark r done here. So we still apply it statically, // so in the file content we'll also have the right offset // to the relocation target. So it can be examined statically @@ -751,47 +751,47 @@ func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loade } } -func addpltsym(ctxt *ld.Link, s *sym.Symbol) { +func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Plt() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) + ld.Adddynsym(target, syms, s) - if ctxt.IsELF { - plt := ctxt.Syms.Lookup(".plt", 0) - gotplt := ctxt.Syms.Lookup(".got.plt", 0) - rela := ctxt.Syms.Lookup(".rela.plt", 0) + if target.IsElf() { + plt := syms.PLT + gotplt := syms.GOTPLT + rela := syms.RelaPLT if plt.Size == 0 { panic("plt is not set up") } // adrp x16, &got.plt[0] plt.AddAddrPlus4(gotplt, gotplt.Size) - plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010) + plt.SetUint32(target.Arch, plt.Size-4, 0x90000010) plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT // is the offset value of &got.plt[n] to &got.plt[0] // ldr x17, [x16, ] plt.AddAddrPlus4(gotplt, gotplt.Size) - plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211) + plt.SetUint32(target.Arch, plt.Size-4, 0xf9400211) plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT // add x16, x16, plt.AddAddrPlus4(gotplt, gotplt.Size) - plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210) + plt.SetUint32(target.Arch, plt.Size-4, 0x91000210) plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL // br x17 - plt.AddUint32(ctxt.Arch, 0xd61f0220) + plt.AddUint32(target.Arch, 0xd61f0220) // add to got.plt: pointer to plt[0] - gotplt.AddAddrPlus(ctxt.Arch, plt, 0) + gotplt.AddAddrPlus(target.Arch, plt, 0) // rela - rela.AddAddrPlus(ctxt.Arch, gotplt, gotplt.Size-8) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_JUMP_SLOT))) - rela.AddUint64(ctxt.Arch, 0) + rela.AddAddrPlus(target.Arch, gotplt, gotplt.Size-8) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_JUMP_SLOT))) + rela.AddUint64(target.Arch, 0) s.SetPlt(int32(plt.Size - 16)) } else { @@ -799,21 +799,21 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *sym.Symbol) { +func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) - got := ctxt.Syms.Lookup(".got", 0) + ld.Adddynsym(target, syms, s) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddUint64(ctxt.Arch, 0) + got.AddUint64(target.Arch, 0) - if ctxt.IsELF { - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_GLOB_DAT))) - rela.AddUint64(ctxt.Arch, 0) + if target.IsElf() { + rela := syms.Rela + rela.AddAddrPlus(target.Arch, got, int64(s.Got())) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_GLOB_DAT))) + rela.AddUint64(target.Arch, 0) } else { ld.Errorf(s, "addgotsym: unsupported binary format") } diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index c7cbbddcba..1b07dc5a91 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -113,6 +113,16 @@ type ArchSyms struct { Dynamic *sym.Symbol DynSym *sym.Symbol DynStr *sym.Symbol + + // Elf specific + Rel *sym.Symbol + Rela *sym.Symbol + RelPLT *sym.Symbol + RelaPLT *sym.Symbol + + // Darwin symbols + LinkEditGOT *sym.Symbol + LinkEditPLT *sym.Symbol } // setArchSyms sets up the ArchSyms structure, and must be called before @@ -136,6 +146,16 @@ func (ctxt *Link) setArchSyms() { ctxt.DotTOC[i] = ctxt.Syms.Lookup(".TOC.", i) } } + if ctxt.IsElf() { + ctxt.Rel = ctxt.Syms.Lookup(".rel", 0) + ctxt.Rela = ctxt.Syms.Lookup(".rela", 0) + ctxt.RelPLT = ctxt.Syms.Lookup(".rel.plt", 0) + ctxt.RelaPLT = ctxt.Syms.Lookup(".rela.plt", 0) + } + if ctxt.IsDarwin() { + ctxt.LinkEditGOT = ctxt.Syms.Lookup(".linkedit.got", 0) + ctxt.LinkEditPLT = ctxt.Syms.Lookup(".linkedit.plt", 0) + } } type Arch struct { @@ -2699,6 +2719,9 @@ func (ctxt *Link) loadlibfull() { ctxt.cgodata = nil addToTextp(ctxt) + + // Set special global symbols. + ctxt.setArchSyms() } func (ctxt *Link) dumpsyms() { diff --git a/src/cmd/link/internal/mips/asm.go b/src/cmd/link/internal/mips/asm.go index c2cabc8291..ab55099084 100644 --- a/src/cmd/link/internal/mips/asm.go +++ b/src/cmd/link/internal/mips/asm.go @@ -45,7 +45,7 @@ func gentext(ctxt *ld.Link) { return } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { log.Fatalf("adddynrel not implemented") return false } diff --git a/src/cmd/link/internal/mips64/asm.go b/src/cmd/link/internal/mips64/asm.go index a6abec15f6..442147c4e2 100644 --- a/src/cmd/link/internal/mips64/asm.go +++ b/src/cmd/link/internal/mips64/asm.go @@ -43,7 +43,7 @@ import ( func gentext(ctxt *ld.Link) {} -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { log.Fatalf("adddynrel not implemented") return false } diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index d3ebafc603..ef477b277c 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -263,22 +263,23 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *sym.Symbol, targ *sym.Symbol) stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { - if ctxt.IsELF { - return addelfdynrel(ctxt, s, r) - } else if ctxt.HeadType == objabi.Haix { - return ld.Xcoffadddynrel(&ctxt.Target, s, r) +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { + if target.IsElf() { + return addelfdynrel(target, syms, s, r) + } else if target.IsAIX() { + return ld.Xcoffadddynrel(target, s, r) } return false } -func addelfdynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { + +func addelfdynrel(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym r.InitExt() switch r.Type { default: if r.Type >= objabi.ElfRelocOffset { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type)) return false } @@ -314,12 +315,12 @@ func addelfdynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { r.Type = objabi.R_ADDR if targ.Type == sym.SDYNIMPORT { // These happen in .toc sections - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ) + ld.Adddynsym(target, syms, targ) - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64))) - rela.AddUint64(ctxt.Arch, uint64(r.Add)) + rela := syms.Rela + rela.AddAddrPlus(target.Arch, s, int64(r.Off)) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64))) + rela.AddUint64(target.Arch, uint64(r.Add)) r.Type = objabi.ElfRelocOffset // ignore during relocsym } diff --git a/src/cmd/link/internal/riscv64/asm.go b/src/cmd/link/internal/riscv64/asm.go index bd8380bfe2..c6b9a48bd4 100644 --- a/src/cmd/link/internal/riscv64/asm.go +++ b/src/cmd/link/internal/riscv64/asm.go @@ -18,11 +18,11 @@ import ( func gentext(ctxt *ld.Link) { } -func adddynrela(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) { +func adddynrela(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) { log.Fatalf("adddynrela not implemented") } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { log.Fatalf("adddynrel not implemented") return false } diff --git a/src/cmd/link/internal/s390x/asm.go b/src/cmd/link/internal/s390x/asm.go index 57437f2f4e..73cf5a0907 100644 --- a/src/cmd/link/internal/s390x/asm.go +++ b/src/cmd/link/internal/s390x/asm.go @@ -105,7 +105,7 @@ func gentext(ctxt *ld.Link) { initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym r.InitExt() @@ -159,8 +159,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo r.Variant = sym.RV_390_DBL r.Add += int64(r.Siz) if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } return true @@ -170,8 +170,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo r.Type = objabi.R_PCREL r.Add += int64(r.Siz) if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } return true @@ -201,7 +201,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC): r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(r.Siz) return true @@ -218,16 +218,16 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL): r.Type = objabi.R_PCREL r.Variant = sym.RV_390_DBL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(r.Siz) return true case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT): - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) r.Type = objabi.R_PCREL r.Variant = sym.RV_390_DBL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += int64(targ.Got()) r.Add += int64(r.Siz) return true @@ -418,17 +418,17 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym } } -func addpltsym(ctxt *ld.Link, s *sym.Symbol) { +func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Plt() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) + ld.Adddynsym(target, syms, s) - if ctxt.IsELF { - plt := ctxt.Syms.Lookup(".plt", 0) - got := ctxt.Syms.Lookup(".got", 0) - rela := ctxt.Syms.Lookup(".rela.plt", 0) + if target.IsElf() { + plt := syms.PLT + got := syms.GOT + rela := syms.RelaPLT if plt.Size == 0 { panic("plt is not set up") } @@ -436,10 +436,10 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { plt.AddUint8(0xc0) plt.AddUint8(0x10) - plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant? + plt.AddPCRelPlus(target.Arch, got, got.Size+6) // need variant? // add to got: pointer to current pos in plt - got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct + got.AddAddrPlus(target.Arch, plt, plt.Size+8) // weird but correct // lg %r1,0(%r1) plt.AddUint8(0xe3) plt.AddUint8(0x10) @@ -464,15 +464,15 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { plt.AddUint8(0xc0) plt.AddUint8(0xf4) - plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation + plt.AddUint32(target.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation //.plt index - plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry + plt.AddUint32(target.Arch, uint32(rela.Size)) // rela size before current entry // rela - rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) + rela.AddAddrPlus(target.Arch, got, got.Size-8) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT))) - rela.AddUint64(ctxt.Arch, 0) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT))) + rela.AddUint64(target.Arch, 0) s.SetPlt(int32(plt.Size - 32)) @@ -481,21 +481,21 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { } } -func addgotsym(ctxt *ld.Link, s *sym.Symbol) { +func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) - got := ctxt.Syms.Lookup(".got", 0) + ld.Adddynsym(target, syms, s) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddUint64(ctxt.Arch, 0) + got.AddUint64(target.Arch, 0) - if ctxt.IsELF { - rela := ctxt.Syms.Lookup(".rela", 0) - rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) - rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT))) - rela.AddUint64(ctxt.Arch, 0) + if target.IsElf() { + rela := syms.Rela + rela.AddAddrPlus(target.Arch, got, int64(s.Got())) + rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT))) + rela.AddUint64(target.Arch, 0) } else { ld.Errorf(s, "addgotsym: unsupported binary format") } diff --git a/src/cmd/link/internal/x86/asm.go b/src/cmd/link/internal/x86/asm.go index 1e407d05c0..0f09e76b4b 100644 --- a/src/cmd/link/internal/x86/asm.go +++ b/src/cmd/link/internal/x86/asm.go @@ -168,13 +168,13 @@ func gentext(ctxt *ld.Link) { initarray_entry.AddAddr(ctxt.Arch, initfunc) } -func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { +func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool { targ := r.Sym switch r.Type { default: if r.Type >= objabi.ElfRelocOffset { - ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type)) + ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type)) return false } @@ -196,8 +196,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo r.Type = objabi.R_PCREL r.Add += 4 if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add += int64(targ.Plt()) } @@ -229,7 +229,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo return false } - addgotsym(ctxt, targ) + addgotsym(target, syms, targ) r.Type = objabi.R_CONST // write r->add during relocsym r.Sym = nil r.Add += int64(targ.Got()) @@ -241,7 +241,7 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTPC): r.Type = objabi.R_PCREL - r.Sym = ctxt.Syms.Lookup(".got", 0) + r.Sym = syms.GOT r.Add += 4 return true @@ -261,8 +261,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1: if targ.Type == sym.SDYNIMPORT { - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(targ.Plt()) r.Type = objabi.R_PCREL return true @@ -285,8 +285,8 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo return true } - addgotsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".got", 0) + addgotsym(target, syms, targ) + r.Sym = syms.GOT r.Add += int64(targ.Got()) r.Type = objabi.R_PCREL return true @@ -299,12 +299,12 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo switch r.Type { case objabi.R_CALL, objabi.R_PCREL: - if ctxt.LinkMode == ld.LinkExternal { + if target.IsExternal() { // External linker will do this relocation. return true } - addpltsym(ctxt, targ) - r.Sym = ctxt.Syms.Lookup(".plt", 0) + addpltsym(target, syms, targ) + r.Sym = syms.PLT r.Add = int64(targ.Plt()) return true @@ -312,17 +312,17 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo if s.Type != sym.SDATA { break } - if ctxt.IsELF { - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ) - rel := ctxt.Syms.Lookup(".rel", 0) - rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) - rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32))) + if target.IsElf() { + ld.Adddynsym(target, syms, targ) + rel := syms.Rel + rel.AddAddrPlus(target.Arch, s, int64(r.Off)) + rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32))) r.Type = objabi.R_CONST // write r->add during relocsym r.Sym = nil return true } - if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 { + if target.IsDarwin() && s.Size == int64(target.Arch.PtrSize) && r.Off == 0 { // Mach-O relocations are a royal pain to lay out. // They use a compact stateful bytecode representation // that is too much bother to deal with. @@ -333,17 +333,17 @@ func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbo // just in case the C code assigns to the variable, // and of course it only works for single pointers, // but we only need to support cgo and that's all it needs. - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ) + ld.Adddynsym(target, syms, targ) - got := ctxt.Syms.Lookup(".got", 0) + got := syms.GOT s.Type = got.Type s.Attr |= sym.AttrSubSymbol s.Outer = got s.Sub = got.Sub got.Sub = s s.Value = got.Size - got.AddUint32(ctxt.Arch, 0) - ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid)) + got.AddUint32(target.Arch, 0) + syms.LinkEditGOT.AddUint32(target.Arch, uint32(targ.Dynid)) r.Type = objabi.ElfRelocOffset // ignore during relocsym return true } @@ -537,17 +537,17 @@ func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.S } } -func addpltsym(ctxt *ld.Link, s *sym.Symbol) { +func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Plt() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) + ld.Adddynsym(target, syms, s) - if ctxt.IsELF { - plt := ctxt.Syms.Lookup(".plt", 0) - got := ctxt.Syms.Lookup(".got.plt", 0) - rel := ctxt.Syms.Lookup(".rel.plt", 0) + if target.IsElf() { + plt := syms.PLT + got := syms.GOTPLT + rel := syms.RelPLT if plt.Size == 0 { panic("plt is not set up") } @@ -556,63 +556,63 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { plt.AddUint8(0xff) plt.AddUint8(0x25) - plt.AddAddrPlus(ctxt.Arch, got, got.Size) + plt.AddAddrPlus(target.Arch, got, got.Size) // add to got: pointer to current pos in plt - got.AddAddrPlus(ctxt.Arch, plt, plt.Size) + got.AddAddrPlus(target.Arch, plt, plt.Size) // pushl $x plt.AddUint8(0x68) - plt.AddUint32(ctxt.Arch, uint32(rel.Size)) + plt.AddUint32(target.Arch, uint32(rel.Size)) // jmp .plt plt.AddUint8(0xe9) - plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4))) + plt.AddUint32(target.Arch, uint32(-(plt.Size + 4))) // rel - rel.AddAddrPlus(ctxt.Arch, got, got.Size-4) + rel.AddAddrPlus(target.Arch, got, got.Size-4) - rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT))) + rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT))) s.SetPlt(int32(plt.Size - 16)) - } else if ctxt.HeadType == objabi.Hdarwin { + } else if target.IsDarwin() { // Same laziness as in 6l. - plt := ctxt.Syms.Lookup(".plt", 0) + plt := syms.PLT - addgotsym(ctxt, s) + addgotsym(target, syms, s) - ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid)) + syms.LinkEditPLT.AddUint32(target.Arch, uint32(s.Dynid)) // jmpq *got+size(IP) s.SetPlt(int32(plt.Size)) plt.AddUint8(0xff) plt.AddUint8(0x25) - plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got())) + plt.AddAddrPlus(target.Arch, syms.GOT, int64(s.Got())) } else { ld.Errorf(s, "addpltsym: unsupported binary format") } } -func addgotsym(ctxt *ld.Link, s *sym.Symbol) { +func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) { if s.Got() >= 0 { return } - ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s) - got := ctxt.Syms.Lookup(".got", 0) + ld.Adddynsym(target, syms, s) + got := syms.GOT s.SetGot(int32(got.Size)) - got.AddUint32(ctxt.Arch, 0) - - if ctxt.IsELF { - rel := ctxt.Syms.Lookup(".rel", 0) - rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got())) - rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT))) - } else if ctxt.HeadType == objabi.Hdarwin { - ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid)) + got.AddUint32(target.Arch, 0) + + if target.IsElf() { + rel := syms.Rel + rel.AddAddrPlus(target.Arch, got, int64(s.Got())) + rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT))) + } else if target.IsDarwin() { + syms.LinkEditGOT.AddUint32(target.Arch, uint32(s.Dynid)) } else { ld.Errorf(s, "addgotsym: unsupported binary format") }