Commit ecfa7375 authored by David Crawshaw's avatar David Crawshaw

cmd/link: move ELF reader to its own package

Along the way, switch to using relocation constants from debug/elf.

For #22095

Change-Id: I1a64353619f95dde5aa39060c4b9d001af7dc1e4
Reviewed-on: https://go-review.googlesource.com/69013
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 70576947
...@@ -68,6 +68,7 @@ var bootstrapDirs = []string{ ...@@ -68,6 +68,7 @@ var bootstrapDirs = []string{
"cmd/link/internal/arm64", "cmd/link/internal/arm64",
"cmd/link/internal/ld", "cmd/link/internal/ld",
"cmd/link/internal/loadmacho", "cmd/link/internal/loadmacho",
"cmd/link/internal/loadelf",
"cmd/link/internal/mips", "cmd/link/internal/mips",
"cmd/link/internal/mips64", "cmd/link/internal/mips64",
"cmd/link/internal/objfile", "cmd/link/internal/objfile",
......
...@@ -109,7 +109,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -109,7 +109,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_X86_64_PC32: case 256 + objabi.RelocType(elf.R_X86_64_PC32):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
} }
...@@ -120,7 +120,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -120,7 +120,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += 4 r.Add += 4
return true return true
case 256 + ld.R_X86_64_PC64: case 256 + objabi.RelocType(elf.R_X86_64_PC64):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_X86_64_PC64 relocation for dynamic symbol %s", targ.Name)
} }
...@@ -131,7 +131,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -131,7 +131,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += 8 r.Add += 8
return true return true
case 256 + ld.R_X86_64_PLT32: case 256 + objabi.RelocType(elf.R_X86_64_PLT32):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Add += 4 r.Add += 4
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
...@@ -142,7 +142,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -142,7 +142,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
case 256 + ld.R_X86_64_GOTPCREL, 256 + ld.R_X86_64_GOTPCRELX, 256 + ld.R_X86_64_REX_GOTPCRELX: case 256 + objabi.RelocType(elf.R_X86_64_GOTPCREL), 256 + objabi.RelocType(elf.R_X86_64_GOTPCRELX), 256 + objabi.RelocType(elf.R_X86_64_REX_GOTPCRELX):
if targ.Type != sym.SDYNIMPORT { if targ.Type != sym.SDYNIMPORT {
// have symbol // have symbol
if r.Off >= 2 && s.P[r.Off-2] == 0x8b { if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
...@@ -165,7 +165,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -165,7 +165,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
return true return true
case 256 + ld.R_X86_64_64: case 256 + objabi.RelocType(elf.R_X86_64_64):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
} }
...@@ -322,10 +322,10 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -322,10 +322,10 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
rela := ctxt.Syms.Lookup(".rela", 0) rela := ctxt.Syms.Lookup(".rela", 0)
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
if r.Siz == 8 { if r.Siz == 8 {
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_X86_64_64)))
} else { } else {
// TODO: never happens, remove. // TODO: never happens, remove.
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_32)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_X86_64_32)))
} }
rela.AddUint64(ctxt.Arch, uint64(r.Add)) rela.AddUint64(ctxt.Arch, uint64(r.Add))
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
...@@ -370,21 +370,21 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -370,21 +370,21 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
return false return false
case objabi.R_ADDR: case objabi.R_ADDR:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write64(ld.R_X86_64_32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_32) | uint64(elfsym)<<32)
} else if r.Siz == 8 { } else if r.Siz == 8 {
ctxt.Out.Write64(ld.R_X86_64_64 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_64) | uint64(elfsym)<<32)
} else { } else {
return false return false
} }
case objabi.R_TLS_LE: case objabi.R_TLS_LE:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write64(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_TPOFF32) | uint64(elfsym)<<32)
} else { } else {
return false return false
} }
case objabi.R_TLS_IE: case objabi.R_TLS_IE:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write64(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_GOTTPOFF) | uint64(elfsym)<<32)
} else { } else {
return false return false
} }
...@@ -392,12 +392,12 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -392,12 +392,12 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
if r.Siz == 4 { if r.Siz == 4 {
if r.Xsym.Type == sym.SDYNIMPORT { if r.Xsym.Type == sym.SDYNIMPORT {
if ctxt.DynlinkingGo() { if ctxt.DynlinkingGo() {
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
} else { } else {
ctxt.Out.Write64(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
} }
} else { } else {
ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
} }
} else { } else {
return false return false
...@@ -405,16 +405,16 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -405,16 +405,16 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
case objabi.R_PCREL: case objabi.R_PCREL:
if r.Siz == 4 { if r.Siz == 4 {
if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC { if r.Xsym.Type == sym.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_PLT32) | uint64(elfsym)<<32)
} else { } else {
ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_PC32) | uint64(elfsym)<<32)
} }
} else { } else {
return false return false
} }
case objabi.R_GOTPCREL: case objabi.R_GOTPCREL:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write64(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_X86_64_GOTPCREL) | uint64(elfsym)<<32)
} else { } else {
return false return false
} }
...@@ -597,7 +597,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -597,7 +597,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
// rela // rela
rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT)) 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(ctxt.Arch, 0)
s.Plt = int32(plt.Size - 16) s.Plt = int32(plt.Size - 16)
...@@ -641,7 +641,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -641,7 +641,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if ld.Iself { if ld.Iself {
rela := ctxt.Syms.Lookup(".rela", 0) rela := ctxt.Syms.Lookup(".rela", 0)
rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got)) rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT)))
rela.AddUint64(ctxt.Arch, 0) rela.AddUint64(ctxt.Arch, 0)
} else if ld.Headtype == objabi.Hdarwin { } else if ld.Headtype == objabi.Hdarwin {
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid)) ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"fmt" "fmt"
"log" "log"
) )
...@@ -125,7 +126,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -125,7 +126,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_ARM_PLT32: case 256 + objabi.RelocType(elf.R_ARM_PLT32):
r.Type = objabi.R_CALLARM r.Type = objabi.R_CALLARM
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
...@@ -136,11 +137,11 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -136,11 +137,11 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
case 256 + ld.R_ARM_THM_PC22: // R_ARM_THM_CALL case 256 + objabi.RelocType(elf.R_ARM_THM_PC22): // R_ARM_THM_CALL
ld.Exitf("R_ARM_THM_CALL, are you using -marm?") ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
return false return false
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL case 256 + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
if targ.Type != sym.SDYNIMPORT { if targ.Type != sym.SDYNIMPORT {
addgotsyminternal(ctxt, targ) addgotsyminternal(ctxt, targ)
} else { } else {
...@@ -152,7 +153,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -152,7 +153,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
return true return true
case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil case 256 + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
if targ.Type != sym.SDYNIMPORT { if targ.Type != sym.SDYNIMPORT {
addgotsyminternal(ctxt, targ) addgotsyminternal(ctxt, targ)
} else { } else {
...@@ -164,19 +165,19 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -164,19 +165,19 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += int64(targ.Got) + 4 r.Add += int64(targ.Got) + 4
return true return true
case 256 + ld.R_ARM_GOTOFF: // R_ARM_GOTOFF32 case 256 + objabi.RelocType(elf.R_ARM_GOTOFF): // R_ARM_GOTOFF32
r.Type = objabi.R_GOTOFF r.Type = objabi.R_GOTOFF
return true return true
case 256 + ld.R_ARM_GOTPC: // R_ARM_BASE_PREL case 256 + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0) r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += 4 r.Add += 4
return true return true
case 256 + ld.R_ARM_CALL: case 256 + objabi.RelocType(elf.R_ARM_CALL):
r.Type = objabi.R_CALLARM r.Type = objabi.R_CALLARM
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ) addpltsym(ctxt, targ)
...@@ -186,13 +187,13 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -186,13 +187,13 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
case 256 + ld.R_ARM_REL32: // R_ARM_REL32 case 256 + objabi.RelocType(elf.R_ARM_REL32): // R_ARM_REL32
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Add += 4 r.Add += 4
return true return true
case 256 + ld.R_ARM_ABS32: case 256 + objabi.RelocType(elf.R_ARM_ABS32):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
} }
...@@ -200,7 +201,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -200,7 +201,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
// we can just ignore this, because we are targeting ARM V5+ anyway // we can just ignore this, because we are targeting ARM V5+ anyway
case 256 + ld.R_ARM_V4BX: case 256 + objabi.RelocType(elf.R_ARM_V4BX):
if r.Sym != nil { if r.Sym != nil {
// R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it // R_ARM_V4BX is ABS relocation, so this symbol is a dummy symbol, ignore it
r.Sym.Type = 0 r.Sym.Type = 0
...@@ -209,8 +210,8 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -209,8 +210,8 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Sym = nil r.Sym = nil
return true return true
case 256 + ld.R_ARM_PC24, case 256 + objabi.RelocType(elf.R_ARM_PC24),
256 + ld.R_ARM_JUMP24: 256 + objabi.RelocType(elf.R_ARM_JUMP24):
r.Type = objabi.R_CALLARM r.Type = objabi.R_CALLARM
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ) addpltsym(ctxt, targ)
...@@ -241,7 +242,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -241,7 +242,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
ld.Adddynsym(ctxt, targ) ld.Adddynsym(ctxt, targ)
rel := ctxt.Syms.Lookup(".rel", 0) rel := ctxt.Syms.Lookup(".rel", 0)
rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynamic reloc 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 r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil r.Sym = nil
return true return true
...@@ -260,33 +261,33 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -260,33 +261,33 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
return false return false
case objabi.R_ADDR: case objabi.R_ADDR:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_ARM_ABS32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_ABS32) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
case objabi.R_PCREL: case objabi.R_PCREL:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_ARM_REL32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_REL32) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
case objabi.R_CALLARM: case objabi.R_CALLARM:
if r.Siz == 4 { if r.Siz == 4 {
if r.Add&0xff000000 == 0xeb000000 { // BL if r.Add&0xff000000 == 0xeb000000 { // BL
ctxt.Out.Write32(ld.R_ARM_CALL | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_CALL) | uint32(elfsym)<<8)
} else { } else {
ctxt.Out.Write32(ld.R_ARM_JUMP24 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_JUMP24) | uint32(elfsym)<<8)
} }
} else { } else {
return false return false
} }
case objabi.R_TLS_LE: case objabi.R_TLS_LE:
ctxt.Out.Write32(ld.R_ARM_TLS_LE32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_TLS_LE32) | uint32(elfsym)<<8)
case objabi.R_TLS_IE: case objabi.R_TLS_IE:
ctxt.Out.Write32(ld.R_ARM_TLS_IE32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_TLS_IE32) | uint32(elfsym)<<8)
case objabi.R_GOTPCREL: case objabi.R_GOTPCREL:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_ARM_GOT_PREL | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_ARM_GOT_PREL) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
...@@ -696,7 +697,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -696,7 +697,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
// rel // rel
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got)) rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT)) rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
} else { } else {
ld.Errorf(s, "addpltsym: unsupported binary format") ld.Errorf(s, "addpltsym: unsupported binary format")
} }
...@@ -731,7 +732,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -731,7 +732,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if ld.Iself { if ld.Iself {
rel := ctxt.Syms.Lookup(".rel", 0) rel := ctxt.Syms.Lookup(".rel", 0)
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got)) rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT)) rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
} else { } else {
ld.Errorf(s, "addgotsym: unsupported binary format") ld.Errorf(s, "addgotsym: unsupported binary format")
} }
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"log" "log"
...@@ -103,35 +104,35 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -103,35 +104,35 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
case objabi.R_ADDR: case objabi.R_ADDR:
switch r.Siz { switch r.Siz {
case 4: case 4:
ctxt.Out.Write64(ld.R_AARCH64_ABS32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS32) | uint64(elfsym)<<32)
case 8: case 8:
ctxt.Out.Write64(ld.R_AARCH64_ABS64 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_ABS64) | uint64(elfsym)<<32)
default: default:
return false return false
} }
case objabi.R_ADDRARM64: case objabi.R_ADDRARM64:
// two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC // two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC
ctxt.Out.Write64(ld.R_AARCH64_ADR_PREL_PG_HI21 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_PREL_PG_HI21) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_AARCH64_ADD_ABS_LO12_NC | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_ADD_ABS_LO12_NC) | uint64(elfsym)<<32)
case objabi.R_ARM64_TLS_LE: case objabi.R_ARM64_TLS_LE:
ctxt.Out.Write64(ld.R_AARCH64_TLSLE_MOVW_TPREL_G0 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSLE_MOVW_TPREL_G0) | uint64(elfsym)<<32)
case objabi.R_ARM64_TLS_IE: case objabi.R_ARM64_TLS_IE:
ctxt.Out.Write64(ld.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) | uint64(elfsym)<<32)
case objabi.R_ARM64_GOTPCREL: case objabi.R_ARM64_GOTPCREL:
ctxt.Out.Write64(ld.R_AARCH64_ADR_GOT_PAGE | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_ADR_GOT_PAGE) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_AARCH64_LD64_GOT_LO12_NC | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_LD64_GOT_LO12_NC) | uint64(elfsym)<<32)
case objabi.R_CALLARM64: case objabi.R_CALLARM64:
if r.Siz != 4 { if r.Siz != 4 {
return false return false
} }
ctxt.Out.Write64(ld.R_AARCH64_CALL26 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_AARCH64_CALL26) | uint64(elfsym)<<32)
} }
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
......
...@@ -330,438 +330,6 @@ const ( ...@@ -330,438 +330,6 @@ const (
* Relocation types. * Relocation types.
*/ */
const ( const (
R_X86_64_NONE = 0
R_X86_64_64 = 1
R_X86_64_PC32 = 2
R_X86_64_GOT32 = 3
R_X86_64_PLT32 = 4
R_X86_64_COPY = 5
R_X86_64_GLOB_DAT = 6
R_X86_64_JMP_SLOT = 7
R_X86_64_RELATIVE = 8
R_X86_64_GOTPCREL = 9
R_X86_64_32 = 10
R_X86_64_32S = 11
R_X86_64_16 = 12
R_X86_64_PC16 = 13
R_X86_64_8 = 14
R_X86_64_PC8 = 15
R_X86_64_DTPMOD64 = 16
R_X86_64_DTPOFF64 = 17
R_X86_64_TPOFF64 = 18
R_X86_64_TLSGD = 19
R_X86_64_TLSLD = 20
R_X86_64_DTPOFF32 = 21
R_X86_64_GOTTPOFF = 22
R_X86_64_TPOFF32 = 23
R_X86_64_PC64 = 24
R_X86_64_GOTOFF64 = 25
R_X86_64_GOTPC32 = 26
R_X86_64_GOT64 = 27
R_X86_64_GOTPCREL64 = 28
R_X86_64_GOTPC64 = 29
R_X86_64_GOTPLT64 = 30
R_X86_64_PLTOFF64 = 31
R_X86_64_SIZE32 = 32
R_X86_64_SIZE64 = 33
R_X86_64_GOTPC32_TLSDEC = 34
R_X86_64_TLSDESC_CALL = 35
R_X86_64_TLSDESC = 36
R_X86_64_IRELATIVE = 37
R_X86_64_PC32_BND = 40
R_X86_64_GOTPCRELX = 41
R_X86_64_REX_GOTPCRELX = 42
R_AARCH64_ABS64 = 257
R_AARCH64_ABS32 = 258
R_AARCH64_CALL26 = 283
R_AARCH64_ADR_PREL_PG_HI21 = 275
R_AARCH64_ADD_ABS_LO12_NC = 277
R_AARCH64_LDST8_ABS_LO12_NC = 278
R_AARCH64_LDST16_ABS_LO12_NC = 284
R_AARCH64_LDST32_ABS_LO12_NC = 285
R_AARCH64_LDST64_ABS_LO12_NC = 286
R_AARCH64_ADR_GOT_PAGE = 311
R_AARCH64_LD64_GOT_LO12_NC = 312
R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541
R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
R_ALPHA_NONE = 0
R_ALPHA_REFLONG = 1
R_ALPHA_REFQUAD = 2
R_ALPHA_GPREL32 = 3
R_ALPHA_LITERAL = 4
R_ALPHA_LITUSE = 5
R_ALPHA_GPDISP = 6
R_ALPHA_BRADDR = 7
R_ALPHA_HINT = 8
R_ALPHA_SREL16 = 9
R_ALPHA_SREL32 = 10
R_ALPHA_SREL64 = 11
R_ALPHA_OP_PUSH = 12
R_ALPHA_OP_STORE = 13
R_ALPHA_OP_PSUB = 14
R_ALPHA_OP_PRSHIFT = 15
R_ALPHA_GPVALUE = 16
R_ALPHA_GPRELHIGH = 17
R_ALPHA_GPRELLOW = 18
R_ALPHA_IMMED_GP_16 = 19
R_ALPHA_IMMED_GP_HI32 = 20
R_ALPHA_IMMED_SCN_HI32 = 21
R_ALPHA_IMMED_BR_HI32 = 22
R_ALPHA_IMMED_LO32 = 23
R_ALPHA_COPY = 24
R_ALPHA_GLOB_DAT = 25
R_ALPHA_JMP_SLOT = 26
R_ALPHA_RELATIVE = 27
R_ARM_NONE = 0
R_ARM_PC24 = 1
R_ARM_ABS32 = 2
R_ARM_REL32 = 3
R_ARM_PC13 = 4
R_ARM_ABS16 = 5
R_ARM_ABS12 = 6
R_ARM_THM_ABS5 = 7
R_ARM_ABS8 = 8
R_ARM_SBREL32 = 9
R_ARM_THM_PC22 = 10
R_ARM_THM_PC8 = 11
R_ARM_AMP_VCALL9 = 12
R_ARM_SWI24 = 13
R_ARM_THM_SWI8 = 14
R_ARM_XPC25 = 15
R_ARM_THM_XPC22 = 16
R_ARM_COPY = 20
R_ARM_GLOB_DAT = 21
R_ARM_JUMP_SLOT = 22
R_ARM_RELATIVE = 23
R_ARM_GOTOFF = 24
R_ARM_GOTPC = 25
R_ARM_GOT32 = 26
R_ARM_PLT32 = 27
R_ARM_CALL = 28
R_ARM_JUMP24 = 29
R_ARM_V4BX = 40
R_ARM_GOT_PREL = 96
R_ARM_GNU_VTENTRY = 100
R_ARM_GNU_VTINHERIT = 101
R_ARM_TLS_IE32 = 107
R_ARM_TLS_LE32 = 108
R_ARM_RSBREL32 = 250
R_ARM_THM_RPC22 = 251
R_ARM_RREL32 = 252
R_ARM_RABS32 = 253
R_ARM_RPC24 = 254
R_ARM_RBASE = 255
R_386_NONE = 0
R_386_32 = 1
R_386_PC32 = 2
R_386_GOT32 = 3
R_386_PLT32 = 4
R_386_COPY = 5
R_386_GLOB_DAT = 6
R_386_JMP_SLOT = 7
R_386_RELATIVE = 8
R_386_GOTOFF = 9
R_386_GOTPC = 10
R_386_TLS_TPOFF = 14
R_386_TLS_IE = 15
R_386_TLS_GOTIE = 16
R_386_TLS_LE = 17
R_386_TLS_GD = 18
R_386_TLS_LDM = 19
R_386_TLS_GD_32 = 24
R_386_TLS_GD_PUSH = 25
R_386_TLS_GD_CALL = 26
R_386_TLS_GD_POP = 27
R_386_TLS_LDM_32 = 28
R_386_TLS_LDM_PUSH = 29
R_386_TLS_LDM_CALL = 30
R_386_TLS_LDM_POP = 31
R_386_TLS_LDO_32 = 32
R_386_TLS_IE_32 = 33
R_386_TLS_LE_32 = 34
R_386_TLS_DTPMOD32 = 35
R_386_TLS_DTPOFF32 = 36
R_386_TLS_TPOFF32 = 37
R_386_TLS_GOTDESC = 39
R_386_TLS_DESC_CALL = 40
R_386_TLS_DESC = 41
R_386_IRELATIVE = 42
R_386_GOT32X = 43
R_MIPS_NONE = 0
R_MIPS_16 = 1
R_MIPS_32 = 2
R_MIPS_REL32 = 3
R_MIPS_26 = 4
R_MIPS_HI16 = 5
R_MIPS_LO16 = 6
R_MIPS_GPREL16 = 7
R_MIPS_LITERAL = 8
R_MIPS_GOT16 = 9
R_MIPS_PC16 = 10
R_MIPS_CALL16 = 11
R_MIPS_GPREL32 = 12
R_MIPS_SHIFT5 = 16
R_MIPS_SHIFT6 = 17
R_MIPS_64 = 18
R_MIPS_GOT_DISP = 19
R_MIPS_GOT_PAGE = 20
R_MIPS_GOT_OFST = 21
R_MIPS_GOT_HI16 = 22
R_MIPS_GOT_LO16 = 23
R_MIPS_SUB = 24
R_MIPS_INSERT_A = 25
R_MIPS_INSERT_B = 26
R_MIPS_DELETE = 27
R_MIPS_HIGHER = 28
R_MIPS_HIGHEST = 29
R_MIPS_CALL_HI16 = 30
R_MIPS_CALL_LO16 = 31
R_MIPS_SCN_DISP = 32
R_MIPS_REL16 = 33
R_MIPS_ADD_IMMEDIATE = 34
R_MIPS_PJUMP = 35
R_MIPS_RELGOT = 36
R_MIPS_JALR = 37
R_MIPS_TLS_DTPMOD32 = 38
R_MIPS_TLS_DTPREL32 = 39
R_MIPS_TLS_DTPMOD64 = 40
R_MIPS_TLS_DTPREL64 = 41
R_MIPS_TLS_GD = 42
R_MIPS_TLS_LDM = 43
R_MIPS_TLS_DTPREL_HI16 = 44
R_MIPS_TLS_DTPREL_LO16 = 45
R_MIPS_TLS_GOTTPREL = 46
R_MIPS_TLS_TPREL32 = 47
R_MIPS_TLS_TPREL64 = 48
R_MIPS_TLS_TPREL_HI16 = 49
R_MIPS_TLS_TPREL_LO16 = 50
R_PPC_NONE = 0
R_PPC_ADDR32 = 1
R_PPC_ADDR24 = 2
R_PPC_ADDR16 = 3
R_PPC_ADDR16_LO = 4
R_PPC_ADDR16_HI = 5
R_PPC_ADDR16_HA = 6
R_PPC_ADDR14 = 7
R_PPC_ADDR14_BRTAKEN = 8
R_PPC_ADDR14_BRNTAKEN = 9
R_PPC_REL24 = 10
R_PPC_REL14 = 11
R_PPC_REL14_BRTAKEN = 12
R_PPC_REL14_BRNTAKEN = 13
R_PPC_GOT16 = 14
R_PPC_GOT16_LO = 15
R_PPC_GOT16_HI = 16
R_PPC_GOT16_HA = 17
R_PPC_PLTREL24 = 18
R_PPC_COPY = 19
R_PPC_GLOB_DAT = 20
R_PPC_JMP_SLOT = 21
R_PPC_RELATIVE = 22
R_PPC_LOCAL24PC = 23
R_PPC_UADDR32 = 24
R_PPC_UADDR16 = 25
R_PPC_REL32 = 26
R_PPC_PLT32 = 27
R_PPC_PLTREL32 = 28
R_PPC_PLT16_LO = 29
R_PPC_PLT16_HI = 30
R_PPC_PLT16_HA = 31
R_PPC_SDAREL16 = 32
R_PPC_SECTOFF = 33
R_PPC_SECTOFF_LO = 34
R_PPC_SECTOFF_HI = 35
R_PPC_SECTOFF_HA = 36
R_PPC_TLS = 67
R_PPC_DTPMOD32 = 68
R_PPC_TPREL16 = 69
R_PPC_TPREL16_LO = 70
R_PPC_TPREL16_HI = 71
R_PPC_TPREL16_HA = 72
R_PPC_TPREL32 = 73
R_PPC_DTPREL16 = 74
R_PPC_DTPREL16_LO = 75
R_PPC_DTPREL16_HI = 76
R_PPC_DTPREL16_HA = 77
R_PPC_DTPREL32 = 78
R_PPC_GOT_TLSGD16 = 79
R_PPC_GOT_TLSGD16_LO = 80
R_PPC_GOT_TLSGD16_HI = 81
R_PPC_GOT_TLSGD16_HA = 82
R_PPC_GOT_TLSLD16 = 83
R_PPC_GOT_TLSLD16_LO = 84
R_PPC_GOT_TLSLD16_HI = 85
R_PPC_GOT_TLSLD16_HA = 86
R_PPC_GOT_TPREL16 = 87
R_PPC_GOT_TPREL16_LO = 88
R_PPC_GOT_TPREL16_HI = 89
R_PPC_GOT_TPREL16_HA = 90
R_PPC_EMB_NADDR32 = 101
R_PPC_EMB_NADDR16 = 102
R_PPC_EMB_NADDR16_LO = 103
R_PPC_EMB_NADDR16_HI = 104
R_PPC_EMB_NADDR16_HA = 105
R_PPC_EMB_SDAI16 = 106
R_PPC_EMB_SDA2I16 = 107
R_PPC_EMB_SDA2REL = 108
R_PPC_EMB_SDA21 = 109
R_PPC_EMB_MRKREF = 110
R_PPC_EMB_RELSEC16 = 111
R_PPC_EMB_RELST_LO = 112
R_PPC_EMB_RELST_HI = 113
R_PPC_EMB_RELST_HA = 114
R_PPC_EMB_BIT_FLD = 115
R_PPC_EMB_RELSDA = 116
R_PPC64_ADDR32 = R_PPC_ADDR32
R_PPC64_ADDR16_LO = R_PPC_ADDR16_LO
R_PPC64_ADDR16_HA = R_PPC_ADDR16_HA
R_PPC64_REL24 = R_PPC_REL24
R_PPC64_GOT16_HA = R_PPC_GOT16_HA
R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT
R_PPC64_TPREL16 = R_PPC_TPREL16
R_PPC64_ADDR64 = 38
R_PPC64_TOC16 = 47
R_PPC64_TOC16_LO = 48
R_PPC64_TOC16_HI = 49
R_PPC64_TOC16_HA = 50
R_PPC64_ADDR16_LO_DS = 57
R_PPC64_GOT16_LO_DS = 59
R_PPC64_TOC16_DS = 63
R_PPC64_TOC16_LO_DS = 64
R_PPC64_TLS = 67
R_PPC64_GOT_TPREL16_LO_DS = 88
R_PPC64_GOT_TPREL16_HA = 90
R_PPC64_REL16_LO = 250
R_PPC64_REL16_HI = 251
R_PPC64_REL16_HA = 252
R_SPARC_NONE = 0
R_SPARC_8 = 1
R_SPARC_16 = 2
R_SPARC_32 = 3
R_SPARC_DISP8 = 4
R_SPARC_DISP16 = 5
R_SPARC_DISP32 = 6
R_SPARC_WDISP30 = 7
R_SPARC_WDISP22 = 8
R_SPARC_HI22 = 9
R_SPARC_22 = 10
R_SPARC_13 = 11
R_SPARC_LO10 = 12
R_SPARC_GOT10 = 13
R_SPARC_GOT13 = 14
R_SPARC_GOT22 = 15
R_SPARC_PC10 = 16
R_SPARC_PC22 = 17
R_SPARC_WPLT30 = 18
R_SPARC_COPY = 19
R_SPARC_GLOB_DAT = 20
R_SPARC_JMP_SLOT = 21
R_SPARC_RELATIVE = 22
R_SPARC_UA32 = 23
R_SPARC_PLT32 = 24
R_SPARC_HIPLT22 = 25
R_SPARC_LOPLT10 = 26
R_SPARC_PCPLT32 = 27
R_SPARC_PCPLT22 = 28
R_SPARC_PCPLT10 = 29
R_SPARC_10 = 30
R_SPARC_11 = 31
R_SPARC_64 = 32
R_SPARC_OLO10 = 33
R_SPARC_HH22 = 34
R_SPARC_HM10 = 35
R_SPARC_LM22 = 36
R_SPARC_PC_HH22 = 37
R_SPARC_PC_HM10 = 38
R_SPARC_PC_LM22 = 39
R_SPARC_WDISP16 = 40
R_SPARC_WDISP19 = 41
R_SPARC_GLOB_JMP = 42
R_SPARC_7 = 43
R_SPARC_5 = 44
R_SPARC_6 = 45
R_SPARC_DISP64 = 46
R_SPARC_PLT64 = 47
R_SPARC_HIX22 = 48
R_SPARC_LOX10 = 49
R_SPARC_H44 = 50
R_SPARC_M44 = 51
R_SPARC_L44 = 52
R_SPARC_REGISTER = 53
R_SPARC_UA64 = 54
R_SPARC_UA16 = 55
R_390_NONE = 0
R_390_8 = 1
R_390_12 = 2
R_390_16 = 3
R_390_32 = 4
R_390_PC32 = 5
R_390_GOT12 = 6
R_390_GOT32 = 7
R_390_PLT32 = 8
R_390_COPY = 9
R_390_GLOB_DAT = 10
R_390_JMP_SLOT = 11
R_390_RELATIVE = 12
R_390_GOTOFF = 13
R_390_GOTPC = 14
R_390_GOT16 = 15
R_390_PC16 = 16
R_390_PC16DBL = 17
R_390_PLT16DBL = 18
R_390_PC32DBL = 19
R_390_PLT32DBL = 20
R_390_GOTPCDBL = 21
R_390_64 = 22
R_390_PC64 = 23
R_390_GOT64 = 24
R_390_PLT64 = 25
R_390_GOTENT = 26
R_390_GOTOFF16 = 27
R_390_GOTOFF64 = 28
R_390_GOTPLT12 = 29
R_390_GOTPLT16 = 30
R_390_GOTPLT32 = 31
R_390_GOTPLT64 = 32
R_390_GOTPLTENT = 33
R_390_GOTPLTOFF16 = 34
R_390_GOTPLTOFF32 = 35
R_390_GOTPLTOFF64 = 36
R_390_TLS_LOAD = 37
R_390_TLS_GDCALL = 38
R_390_TLS_LDCALL = 39
R_390_TLS_GD32 = 40
R_390_TLS_GD64 = 41
R_390_TLS_GOTIE12 = 42
R_390_TLS_GOTIE32 = 43
R_390_TLS_GOTIE64 = 44
R_390_TLS_LDM32 = 45
R_390_TLS_LDM64 = 46
R_390_TLS_IE32 = 47
R_390_TLS_IE64 = 48
R_390_TLS_IEENT = 49
R_390_TLS_LE32 = 50
R_390_TLS_LE64 = 51
R_390_TLS_LDO32 = 52
R_390_TLS_LDO64 = 53
R_390_TLS_DTPMOD = 54
R_390_TLS_DTPOFF = 55
R_390_TLS_TPOFF = 56
R_390_20 = 57
R_390_GOT20 = 58
R_390_GOTPLT20 = 59
R_390_TLS_GOTIE20 = 60
ARM_MAGIC_TRAMP_NUMBER = 0x5c000003 ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
) )
......
...@@ -36,6 +36,7 @@ import ( ...@@ -36,6 +36,7 @@ import (
"cmd/internal/bio" "cmd/internal/bio"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/loadelf"
"cmd/link/internal/loadmacho" "cmd/link/internal/loadmacho"
"cmd/link/internal/objfile" "cmd/link/internal/objfile"
"cmd/link/internal/sym" "cmd/link/internal/sym"
...@@ -1384,6 +1385,15 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, ...@@ -1384,6 +1385,15 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4) magic := uint32(c1)<<24 | uint32(c2)<<16 | uint32(c3)<<8 | uint32(c4)
if magic == 0x7f454c46 { // \x7F E L F if magic == 0x7f454c46 { // \x7F E L F
ldelf := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
textp, flags, err := loadelf.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn, ehdr.flags)
if err != nil {
Errorf(nil, "%v", err)
return
}
ehdr.flags = flags
ctxt.Textp = append(ctxt.Textp, textp...)
}
return ldhostobj(ldelf, f, pkg, length, pn, file) return ldhostobj(ldelf, f, pkg, length, pn, file)
} }
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package ld package ld
import ( import (
"bytes"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
...@@ -24,14 +23,6 @@ func Cputime() float64 { ...@@ -24,14 +23,6 @@ func Cputime() float64 {
return time.Since(startTime).Seconds() return time.Since(startTime).Seconds()
} }
func cstring(x []byte) string {
i := bytes.IndexByte(x, '\x00')
if i >= 0 {
x = x[:i]
}
return string(x)
}
func tokenize(s string) []string { func tokenize(s string) []string {
var f []string var f []string
for { for {
......
package ld // Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package loadelf implements an ELF file reader.
package loadelf
import ( import (
"bytes" "bytes"
...@@ -6,6 +11,7 @@ import ( ...@@ -6,6 +11,7 @@ import (
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"io" "io"
...@@ -170,6 +176,14 @@ const ( ...@@ -170,6 +176,14 @@ const (
ElfNotePrXfpreg = 0x46e62b7f ElfNotePrXfpreg = 0x46e62b7f
) )
// TODO(crawshaw): de-duplicate with cmd/link/internal/ld/elf.go.
const (
ELF64SYMSIZE = 24
ELF32SYMSIZE = 16
SHT_ARM_ATTRIBUTES = 0x70000003
)
type ElfHdrBytes struct { type ElfHdrBytes struct {
Ident [16]uint8 Ident [16]uint8
Type [2]uint8 Type [2]uint8
...@@ -391,15 +405,13 @@ func (a *elfAttributeList) done() bool { ...@@ -391,15 +405,13 @@ func (a *elfAttributeList) done() bool {
// find the one we are looking for. This format is slightly documented in "ELF // find the one we are looking for. This format is slightly documented in "ELF
// for the ARM Architecture" but mostly this is derived from reading the source // for the ARM Architecture" but mostly this is derived from reading the source
// to gold and readelf. // to gold and readelf.
func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) { func parseArmAttributes(e binary.ByteOrder, initEhdrFlags uint32, data []byte) (ehdrFlags uint32, err error) {
// We assume the soft-float ABI unless we see a tag indicating otherwise. // We assume the soft-float ABI unless we see a tag indicating otherwise.
if ehdr.flags == 0x5000002 { if initEhdrFlags == 0x5000002 {
ehdr.flags = 0x5000202 ehdrFlags = 0x5000202
} }
if data[0] != 'A' { if data[0] != 'A' {
// TODO(dfc) should this be ctxt.Diag ? return 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
ctxt.Logf(".ARM.attributes has unexpected format %c\n", data[0])
return
} }
data = data[1:] data = data[1:]
for len(data) != 0 { for len(data) != 0 {
...@@ -409,9 +421,7 @@ func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) { ...@@ -409,9 +421,7 @@ func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) {
nulIndex := bytes.IndexByte(sectiondata, 0) nulIndex := bytes.IndexByte(sectiondata, 0)
if nulIndex < 0 { if nulIndex < 0 {
// TODO(dfc) should this be ctxt.Diag ? return 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
ctxt.Logf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
return
} }
name := string(sectiondata[:nulIndex]) name := string(sectiondata[:nulIndex])
sectiondata = sectiondata[nulIndex+1:] sectiondata = sectiondata[nulIndex+1:]
...@@ -432,35 +442,41 @@ func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) { ...@@ -432,35 +442,41 @@ func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) {
for !attrList.done() { for !attrList.done() {
attr := attrList.armAttr() attr := attrList.armAttr()
if attr.tag == TagABIVFPArgs && attr.ival == 1 { if attr.tag == TagABIVFPArgs && attr.ival == 1 {
ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
} }
} }
if attrList.err != nil { if attrList.err != nil {
// TODO(dfc) should this be ctxt.Diag ? return 0, fmt.Errorf("could not parse .ARM.attributes\n")
ctxt.Logf("could not parse .ARM.attributes\n")
} }
} }
} }
return ehdrFlags, nil
} }
func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { // Load loads the ELF file pn from f.
if ctxt.Debugvlog != 0 { // Symbols are written into syms, and a slice of the text symbols is returned.
ctxt.Logf("%5.2f ldelf %s\n", Cputime(), pn) //
// On ARM systems, Load will attempt to determine what ELF header flags to
// emit by scanning the attributes in the ELF file being loaded. The
// parameter initEhdrFlags contains the current header flags for the output
// object, and the returnd ehdrFlags contains what this Load function computes.
// TODO: find a better place for this logic.
func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []*sym.Symbol, ehdrFlags uint32, err error) {
errorf := func(str string, args ...interface{}) ([]*sym.Symbol, uint32, error) {
return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
} }
localSymVersion := ctxt.Syms.IncVersion() localSymVersion := syms.IncVersion()
base := f.Offset() base := f.Offset()
var hdrbuf [64]uint8 var hdrbuf [64]uint8
if _, err := io.ReadFull(f, hdrbuf[:]); err != nil { if _, err := io.ReadFull(f, hdrbuf[:]); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
hdr := new(ElfHdrBytes) hdr := new(ElfHdrBytes)
binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter
if string(hdr.Ident[:4]) != "\x7FELF" { if string(hdr.Ident[:4]) != "\x7FELF" {
Errorf(nil, "%s: malformed elf file", pn) return errorf("malformed elf file, bad header")
return
} }
var e binary.ByteOrder var e binary.ByteOrder
switch hdr.Ident[5] { switch hdr.Ident[5] {
...@@ -471,8 +487,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -471,8 +487,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
e = binary.BigEndian e = binary.BigEndian
default: default:
Errorf(nil, "%s: malformed elf file", pn) return errorf("malformed elf file, unknown header")
return
} }
// read header // read header
...@@ -520,66 +535,55 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -520,66 +535,55 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
elfobj.is64 = is64 elfobj.is64 = is64
if v := uint32(hdr.Ident[6]); v != elfobj.version { if v := uint32(hdr.Ident[6]); v != elfobj.version {
Errorf(nil, "%s: malformed elf version: got %d, want %d", pn, v, elfobj.version) return errorf("malformed elf version: got %d, want %d", v, elfobj.version)
return
} }
if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable { if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable {
Errorf(nil, "%s: elf but not elf relocatable object", pn) return errorf("elf but not elf relocatable object")
return
} }
switch ctxt.Arch.Family { switch arch.Family {
default: default:
Errorf(nil, "%s: elf %s unimplemented", pn, ctxt.Arch.Name) return errorf("elf %s unimplemented", arch.Name)
return
case sys.MIPS: case sys.MIPS:
if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 { if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 {
Errorf(nil, "%s: elf object but not mips", pn) return errorf("elf object but not mips")
return
} }
case sys.MIPS64: case sys.MIPS64:
if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 { if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 {
Errorf(nil, "%s: elf object but not mips64", pn) return errorf("elf object but not mips64")
return
} }
case sys.ARM: case sys.ARM:
if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 { if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 {
Errorf(nil, "%s: elf object but not arm", pn) return errorf("elf object but not arm")
return
} }
case sys.AMD64: case sys.AMD64:
if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 { if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 {
Errorf(nil, "%s: elf object but not amd64", pn) return errorf("elf object but not amd64")
return
} }
case sys.ARM64: case sys.ARM64:
if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 { if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 {
Errorf(nil, "%s: elf object but not arm64", pn) return errorf("elf object but not arm64")
return
} }
case sys.I386: case sys.I386:
if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 { if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 {
Errorf(nil, "%s: elf object but not 386", pn) return errorf("elf object but not 386")
return
} }
case sys.PPC64: case sys.PPC64:
if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 { if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 {
Errorf(nil, "%s: elf object but not ppc64", pn) return errorf("elf object but not ppc64")
return
} }
case sys.S390X: case sys.S390X:
if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 { if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 {
Errorf(nil, "%s: elf object but not s390x", pn) return errorf("elf object but not s390x")
return
} }
} }
...@@ -589,16 +593,14 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -589,16 +593,14 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
elfobj.nsect = uint(elfobj.shnum) elfobj.nsect = uint(elfobj.shnum)
for i := 0; uint(i) < elfobj.nsect; i++ { for i := 0; uint(i) < elfobj.nsect; i++ {
if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 { if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 {
Errorf(nil, "%s: malformed elf file", pn) return errorf("malformed elf file: negative seek")
return
} }
sect := &elfobj.sect[i] sect := &elfobj.sect[i]
if is64 != 0 { if is64 != 0 {
var b ElfSectBytes64 var b ElfSectBytes64
if err := binary.Read(f, e, &b); err != nil { if err := binary.Read(f, e, &b); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
sect.nameoff = e.Uint32(b.Name[:]) sect.nameoff = e.Uint32(b.Name[:])
...@@ -615,8 +617,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -615,8 +617,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
var b ElfSectBytes var b ElfSectBytes
if err := binary.Read(f, e, &b); err != nil { if err := binary.Read(f, e, &b); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
sect.nameoff = e.Uint32(b.Name[:]) sect.nameoff = e.Uint32(b.Name[:])
...@@ -634,14 +635,12 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -634,14 +635,12 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
// read section string table and translate names // read section string table and translate names
if elfobj.shstrndx >= uint32(elfobj.nsect) { if elfobj.shstrndx >= uint32(elfobj.nsect) {
Errorf(nil, "%s: malformed elf file: shstrndx out of range %d >= %d", pn, elfobj.shstrndx, elfobj.nsect) return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect)
return
} }
sect := &elfobj.sect[elfobj.shstrndx] sect := &elfobj.sect[elfobj.shstrndx]
if err := elfmap(elfobj, sect); err != nil { if err := elfmap(elfobj, sect); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
for i := 0; uint(i) < elfobj.nsect; i++ { for i := 0; uint(i) < elfobj.nsect; i++ {
if elfobj.sect[i].nameoff != 0 { if elfobj.sect[i].nameoff != 0 {
...@@ -658,8 +657,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -658,8 +657,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
} }
if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) { if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) {
Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn) return errorf("elf object has symbol table with invalid string table link")
return
} }
elfobj.symstr = &elfobj.sect[elfobj.symtab.link] elfobj.symstr = &elfobj.sect[elfobj.symtab.link]
...@@ -670,12 +668,10 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -670,12 +668,10 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
} }
if err := elfmap(elfobj, elfobj.symtab); err != nil { if err := elfmap(elfobj, elfobj.symtab); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
if err := elfmap(elfobj, elfobj.symstr); err != nil { if err := elfmap(elfobj, elfobj.symstr); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
// load text and data segments into memory. // load text and data segments into memory.
...@@ -688,28 +684,29 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -688,28 +684,29 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
sect = &elfobj.sect[i] sect = &elfobj.sect[i]
if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" { if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" {
if err := elfmap(elfobj, sect); err != nil { if err := elfmap(elfobj, sect); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("%s: malformed elf file: %v", pn, err)
return }
ehdrFlags, err = parseArmAttributes(e, initEhdrFlags, sect.base[:sect.size])
if err != nil {
// TODO(dfc) should this return an error?
log.Printf("%s: %v", pn, err)
} }
parseArmAttributes(ctxt, e, sect.base[:sect.size])
} }
if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 { if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
continue continue
} }
if sect.type_ != ElfSectNobits { if sect.type_ != ElfSectNobits {
if err := elfmap(elfobj, sect); err != nil { if err := elfmap(elfobj, sect); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("%s: malformed elf file: %v", pn, err)
return
} }
} }
name := fmt.Sprintf("%s(%s)", pkg, sect.name) name := fmt.Sprintf("%s(%s)", pkg, sect.name)
s := ctxt.Syms.Lookup(name, localSymVersion) s := syms.Lookup(name, localSymVersion)
switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) { switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
default: default:
Errorf(nil, "%s: unexpected flags for ELF section %s", pn, sect.name) return errorf("%s: unexpected flags for ELF section %s", pn, sect.name)
return
case ElfSectFlagAlloc: case ElfSectFlagAlloc:
s.Type = sym.SRODATA s.Type = sym.SRODATA
...@@ -744,9 +741,8 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -744,9 +741,8 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
for i := 1; i < elfobj.nsymtab; i++ { for i := 1; i < elfobj.nsymtab; i++ {
var elfsym ElfSym var elfsym ElfSym
if err := readelfsym(ctxt, elfobj, i, &elfsym, 1, localSymVersion); err != nil { if err := readelfsym(arch, syms, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("%s: malformed elf file: %v", pn, err)
return
} }
symbols[i] = elfsym.sym symbols[i] = elfsym.sym
if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon { if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon {
...@@ -786,8 +782,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -786,8 +782,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this
continue continue
} }
Errorf(elfsym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, elfsym.shndx, elfsym.type_) return errorf("%v: sym#%d: ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.shndx, elfsym.type_)
continue
} }
s := elfsym.sym s := elfsym.sym
...@@ -795,7 +790,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -795,7 +790,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if s.Attr.DuplicateOK() { if s.Attr.DuplicateOK() {
continue continue
} }
Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
} }
s.Sub = sect.sym.Sub s.Sub = sect.sym.Sub
...@@ -809,7 +804,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -809,7 +804,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
s.Outer = sect.sym s.Outer = sect.sym
if sect.sym.Type == sym.STEXT { if sect.sym.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() { if s.Attr.External() && !s.Attr.DuplicateOK() {
Errorf(s, "%s: duplicate symbol definition", pn) return errorf("%v: duplicate symbol definition", s)
} }
s.Attr |= sym.AttrExternal s.Attr |= sym.AttrExternal
} }
...@@ -819,7 +814,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -819,7 +814,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if 2 <= flag && flag <= 6 { if 2 <= flag && flag <= 6 {
s.Localentry = 1 << uint(flag-2) s.Localentry = 1 << uint(flag-2)
} else if flag == 7 { } else if flag == 7 {
Errorf(s, "%s: invalid sym.other 0x%x", pn, elfsym.other) return errorf("%v: invalid sym.other 0x%x", s, elfsym.other)
} }
} }
} }
...@@ -836,16 +831,16 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -836,16 +831,16 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
} }
if s.Type == sym.STEXT { if s.Type == sym.STEXT {
if s.Attr.OnList() { if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name) return errorf("symbol %s listed multiple times", s.Name)
} }
s.Attr |= sym.AttrOnList s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s) textp = append(textp, s)
for s = s.Sub; s != nil; s = s.Sub { for s = s.Sub; s != nil; s = s.Sub {
if s.Attr.OnList() { if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name) return errorf("symbol %s listed multiple times", s.Name)
} }
s.Attr |= sym.AttrOnList s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s) textp = append(textp, s)
} }
} }
} }
...@@ -861,8 +856,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -861,8 +856,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
} }
sect = &elfobj.sect[rsect.info] sect = &elfobj.sect[rsect.info]
if err := elfmap(elfobj, rsect); err != nil { if err := elfmap(elfobj, rsect); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
rela := 0 rela := 0
if rsect.type_ == ElfSectRela { if rsect.type_ == ElfSectRela {
...@@ -910,21 +904,22 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -910,21 +904,22 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
rp.Sym = nil rp.Sym = nil
} else { } else {
var elfsym ElfSym var elfsym ElfSym
if err := readelfsym(ctxt, elfobj, int(info>>32), &elfsym, 0, 0); err != nil { if err := readelfsym(arch, syms, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
Errorf(nil, "%s: malformed elf file: %v", pn, err) return errorf("malformed elf file: %v", err)
return
} }
elfsym.sym = symbols[info>>32] elfsym.sym = symbols[info>>32]
if elfsym.sym == nil { if elfsym.sym == nil {
Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_) return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), elfsym.name, elfsym.shndx, elfsym.type_)
return
} }
rp.Sym = elfsym.sym rp.Sym = elfsym.sym
} }
rp.Type = 256 + objabi.RelocType(info) rp.Type = 256 + objabi.RelocType(info)
rp.Siz = relSize(ctxt, pn, uint32(info)) rp.Siz, err = relSize(arch, pn, uint32(info))
if err != nil {
return nil, 0, err
}
if rela != 0 { if rela != 0 {
rp.Add = int64(add) rp.Add = int64(add)
} else { } else {
...@@ -934,7 +929,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -934,7 +929,7 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
} else if rp.Siz == 8 { } else if rp.Siz == 8 {
rp.Add = int64(e.Uint64(sect.base[rp.Off:])) rp.Add = int64(e.Uint64(sect.base[rp.Off:]))
} else { } else {
Errorf(nil, "invalid rela size %d", rp.Siz) return errorf("invalid rela size %d", rp.Siz)
} }
} }
...@@ -954,6 +949,8 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { ...@@ -954,6 +949,8 @@ func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
s.R = r s.R = r
s.R = s.R[:n] s.R = s.R[:n]
} }
return textp, ehdrFlags, nil
} }
func section(elfobj *ElfObj, name string) *ElfSect { func section(elfobj *ElfObj, name string) *ElfSect {
...@@ -986,14 +983,14 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { ...@@ -986,14 +983,14 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
return nil return nil
} }
func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) { func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
if i >= elfobj.nsymtab || i < 0 { if i >= elfobj.nsymtab || i < 0 {
err = fmt.Errorf("invalid elf symbol index") err = fmt.Errorf("invalid elf symbol index")
return err return err
} }
if i == 0 { if i == 0 {
Errorf(nil, "readym: read null symbol!") return fmt.Errorf("readym: read null symbol!")
} }
if elfobj.is64 != 0 { if elfobj.is64 != 0 {
...@@ -1036,7 +1033,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, ...@@ -1036,7 +1033,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int,
switch elfsym.bind { switch elfsym.bind {
case ElfSymBindGlobal: case ElfSymBindGlobal:
if needSym != 0 { if needSym != 0 {
s = ctxt.Syms.Lookup(elfsym.name, 0) s = syms.Lookup(elfsym.name, 0)
// for global scoped hidden symbols we should insert it into // for global scoped hidden symbols we should insert it into
// symbol hash table, but mark them as hidden. // symbol hash table, but mark them as hidden.
...@@ -1052,7 +1049,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, ...@@ -1052,7 +1049,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int,
} }
case ElfSymBindLocal: case ElfSymBindLocal:
if ctxt.Arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) { if arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) {
// binutils for arm generate these mapping // binutils for arm generate these mapping
// symbols, ignore these // symbols, ignore these
break break
...@@ -1062,7 +1059,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, ...@@ -1062,7 +1059,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int,
// We need to be able to look this up, // We need to be able to look this up,
// so put it in the hash table. // so put it in the hash table.
if needSym != 0 { if needSym != 0 {
s = ctxt.Syms.Lookup(elfsym.name, localSymVersion) s = syms.Lookup(elfsym.name, localSymVersion)
s.Type |= sym.SHIDDEN s.Type |= sym.SHIDDEN
} }
...@@ -1073,14 +1070,14 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, ...@@ -1073,14 +1070,14 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int,
// local names and hidden global names are unique // local names and hidden global names are unique
// and should only be referenced by their index, not name, so we // and should only be referenced by their index, not name, so we
// don't bother to add them into the hash table // don't bother to add them into the hash table
s = ctxt.Syms.Newsym(elfsym.name, localSymVersion) s = syms.Newsym(elfsym.name, localSymVersion)
s.Type |= sym.SHIDDEN s.Type |= sym.SHIDDEN
} }
case ElfSymBindWeak: case ElfSymBindWeak:
if needSym != 0 { if needSym != 0 {
s = ctxt.Syms.Lookup(elfsym.name, 0) s = syms.Lookup(elfsym.name, 0)
if elfsym.other == 2 { if elfsym.other == 2 {
s.Type |= sym.SHIDDEN s.Type |= sym.SHIDDEN
} }
...@@ -1100,7 +1097,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, ...@@ -1100,7 +1097,7 @@ func readelfsym(ctxt *Link, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int,
return nil return nil
} }
func relSize(ctxt *Link, pn string, elftype uint32) uint8 { func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) {
// TODO(mdempsky): Replace this with a struct-valued switch statement // TODO(mdempsky): Replace this with a struct-valued switch statement
// once golang.org/issue/15164 is fixed or found to not impair cmd/link // once golang.org/issue/15164 is fixed or found to not impair cmd/link
// performance. // performance.
...@@ -1113,77 +1110,84 @@ func relSize(ctxt *Link, pn string, elftype uint32) uint8 { ...@@ -1113,77 +1110,84 @@ func relSize(ctxt *Link, pn string, elftype uint32) uint8 {
S390X = uint32(sys.S390X) S390X = uint32(sys.S390X)
) )
switch uint32(ctxt.Arch.Family) | elftype<<24 { switch uint32(arch.Family) | elftype<<24 {
default: default:
Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype)
fallthrough
case S390X | uint32(elf.R_390_8)<<24:
case S390X | R_390_8<<24: return 1, nil
return 1
case PPC64 | uint32(elf.R_PPC64_TOC16)<<24,
case PPC64 | R_PPC64_TOC16<<24, PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<24,
PPC64 | R_PPC64_TOC16_LO<<24, PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<24,
PPC64 | R_PPC64_TOC16_HI<<24, PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<24,
PPC64 | R_PPC64_TOC16_HA<<24, PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<24,
PPC64 | R_PPC64_TOC16_DS<<24, PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<24,
PPC64 | R_PPC64_TOC16_LO_DS<<24, PPC64 | uint32(elf.R_PPC64_REL16_LO)<<24,
PPC64 | R_PPC64_REL16_LO<<24, PPC64 | uint32(elf.R_PPC64_REL16_HI)<<24,
PPC64 | R_PPC64_REL16_HI<<24, PPC64 | uint32(elf.R_PPC64_REL16_HA)<<24,
PPC64 | R_PPC64_REL16_HA<<24, S390X | uint32(elf.R_390_16)<<24,
S390X | R_390_16<<24, S390X | uint32(elf.R_390_GOT16)<<24,
S390X | R_390_GOT16<<24, S390X | uint32(elf.R_390_PC16)<<24,
S390X | R_390_PC16<<24, S390X | uint32(elf.R_390_PC16DBL)<<24,
S390X | R_390_PC16DBL<<24, S390X | uint32(elf.R_390_PLT16DBL)<<24:
S390X | R_390_PLT16DBL<<24: return 2, nil
return 2
case ARM | uint32(elf.R_ARM_ABS32)<<24,
case ARM | R_ARM_ABS32<<24, ARM | uint32(elf.R_ARM_GOT32)<<24,
ARM | R_ARM_GOT32<<24, ARM | uint32(elf.R_ARM_PLT32)<<24,
ARM | R_ARM_PLT32<<24, ARM | uint32(elf.R_ARM_GOTOFF)<<24,
ARM | R_ARM_GOTOFF<<24, ARM | uint32(elf.R_ARM_GOTPC)<<24,
ARM | R_ARM_GOTPC<<24, ARM | uint32(elf.R_ARM_THM_PC22)<<24,
ARM | R_ARM_THM_PC22<<24, ARM | uint32(elf.R_ARM_REL32)<<24,
ARM | R_ARM_REL32<<24, ARM | uint32(elf.R_ARM_CALL)<<24,
ARM | R_ARM_CALL<<24, ARM | uint32(elf.R_ARM_V4BX)<<24,
ARM | R_ARM_V4BX<<24, ARM | uint32(elf.R_ARM_GOT_PREL)<<24,
ARM | R_ARM_GOT_PREL<<24, ARM | uint32(elf.R_ARM_PC24)<<24,
ARM | R_ARM_PC24<<24, ARM | uint32(elf.R_ARM_JUMP24)<<24,
ARM | R_ARM_JUMP24<<24, AMD64 | uint32(elf.R_X86_64_PC32)<<24,
AMD64 | R_X86_64_PC32<<24, AMD64 | uint32(elf.R_X86_64_PLT32)<<24,
AMD64 | R_X86_64_PLT32<<24, AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<24,
AMD64 | R_X86_64_GOTPCREL<<24, AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<24,
AMD64 | R_X86_64_GOTPCRELX<<24, AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<24,
AMD64 | R_X86_64_REX_GOTPCRELX<<24, I386 | uint32(elf.R_386_32)<<24,
I386 | R_386_32<<24, I386 | uint32(elf.R_386_PC32)<<24,
I386 | R_386_PC32<<24, I386 | uint32(elf.R_386_GOT32)<<24,
I386 | R_386_GOT32<<24, I386 | uint32(elf.R_386_PLT32)<<24,
I386 | R_386_PLT32<<24, I386 | uint32(elf.R_386_GOTOFF)<<24,
I386 | R_386_GOTOFF<<24, I386 | uint32(elf.R_386_GOTPC)<<24,
I386 | R_386_GOTPC<<24, I386 | uint32(elf.R_386_GOT32X)<<24,
I386 | R_386_GOT32X<<24, PPC64 | uint32(elf.R_PPC64_REL24)<<24,
PPC64 | R_PPC64_REL24<<24, PPC64 | uint32(elf.R_PPC_REL32)<<24,
PPC64 | R_PPC_REL32<<24, S390X | uint32(elf.R_390_32)<<24,
S390X | R_390_32<<24, S390X | uint32(elf.R_390_PC32)<<24,
S390X | R_390_PC32<<24, S390X | uint32(elf.R_390_GOT32)<<24,
S390X | R_390_GOT32<<24, S390X | uint32(elf.R_390_PLT32)<<24,
S390X | R_390_PLT32<<24, S390X | uint32(elf.R_390_PC32DBL)<<24,
S390X | R_390_PC32DBL<<24, S390X | uint32(elf.R_390_PLT32DBL)<<24,
S390X | R_390_PLT32DBL<<24, S390X | uint32(elf.R_390_GOTPCDBL)<<24,
S390X | R_390_GOTPCDBL<<24, S390X | uint32(elf.R_390_GOTENT)<<24:
S390X | R_390_GOTENT<<24: return 4, nil
return 4
case AMD64 | uint32(elf.R_X86_64_64)<<24,
case AMD64 | R_X86_64_64<<24, AMD64 | uint32(elf.R_X86_64_PC64)<<24,
AMD64 | R_X86_64_PC64<<24, PPC64 | uint32(elf.R_PPC64_ADDR64)<<24,
PPC64 | R_PPC64_ADDR64<<24, S390X | uint32(elf.R_390_GLOB_DAT)<<24,
S390X | R_390_GLOB_DAT<<24, S390X | uint32(elf.R_390_RELATIVE)<<24,
S390X | R_390_RELATIVE<<24, S390X | uint32(elf.R_390_GOTOFF)<<24,
S390X | R_390_GOTOFF<<24, S390X | uint32(elf.R_390_GOTPC)<<24,
S390X | R_390_GOTPC<<24, S390X | uint32(elf.R_390_64)<<24,
S390X | R_390_64<<24, S390X | uint32(elf.R_390_PC64)<<24,
S390X | R_390_PC64<<24, S390X | uint32(elf.R_390_GOT64)<<24,
S390X | R_390_GOT64<<24, S390X | uint32(elf.R_390_PLT64)<<24:
S390X | R_390_PLT64<<24: return 8, nil
return 8 }
}
func cstring(x []byte) string {
i := bytes.IndexByte(x, '\x00')
if i >= 0 {
x = x[:i]
} }
return string(x)
} }
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"fmt" "fmt"
"log" "log"
) )
...@@ -59,15 +60,15 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -59,15 +60,15 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
if r.Siz != 4 { if r.Siz != 4 {
return false return false
} }
ctxt.Out.Write32(ld.R_MIPS_32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_MIPS_32) | uint32(elfsym)<<8)
case objabi.R_ADDRMIPS: case objabi.R_ADDRMIPS:
ctxt.Out.Write32(ld.R_MIPS_LO16 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_MIPS_LO16) | uint32(elfsym)<<8)
case objabi.R_ADDRMIPSU: case objabi.R_ADDRMIPSU:
ctxt.Out.Write32(ld.R_MIPS_HI16 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_MIPS_HI16) | uint32(elfsym)<<8)
case objabi.R_ADDRMIPSTLS: case objabi.R_ADDRMIPSTLS:
ctxt.Out.Write32(ld.R_MIPS_TLS_TPREL_LO16 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_MIPS_TLS_TPREL_LO16) | uint32(elfsym)<<8)
case objabi.R_CALLMIPS, objabi.R_JMPMIPS: case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
ctxt.Out.Write32(ld.R_MIPS_26 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_MIPS_26) | uint32(elfsym)<<8)
} }
return true return true
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"fmt" "fmt"
"log" "log"
) )
...@@ -69,21 +70,21 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -69,21 +70,21 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
case objabi.R_ADDR: case objabi.R_ADDR:
switch r.Siz { switch r.Siz {
case 4: case 4:
ctxt.Out.Write8(ld.R_MIPS_32) ctxt.Out.Write8(uint8(elf.R_MIPS_32))
case 8: case 8:
ctxt.Out.Write8(ld.R_MIPS_64) ctxt.Out.Write8(uint8(elf.R_MIPS_64))
default: default:
return false return false
} }
case objabi.R_ADDRMIPS: case objabi.R_ADDRMIPS:
ctxt.Out.Write8(ld.R_MIPS_LO16) ctxt.Out.Write8(uint8(elf.R_MIPS_LO16))
case objabi.R_ADDRMIPSU: case objabi.R_ADDRMIPSU:
ctxt.Out.Write8(ld.R_MIPS_HI16) ctxt.Out.Write8(uint8(elf.R_MIPS_HI16))
case objabi.R_ADDRMIPSTLS: case objabi.R_ADDRMIPSTLS:
ctxt.Out.Write8(ld.R_MIPS_TLS_TPREL_LO16) ctxt.Out.Write8(uint8(elf.R_MIPS_TLS_TPREL_LO16))
case objabi.R_CALLMIPS, case objabi.R_CALLMIPS,
objabi.R_JMPMIPS: objabi.R_JMPMIPS:
ctxt.Out.Write8(ld.R_MIPS_26) ctxt.Out.Write8(uint8(elf.R_MIPS_26))
} }
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"log" "log"
...@@ -93,7 +94,7 @@ func genplt(ctxt *ld.Link) { ...@@ -93,7 +94,7 @@ func genplt(ctxt *ld.Link) {
for _, s := range ctxt.Textp { for _, s := range ctxt.Textp {
for i := range s.R { for i := range s.R {
r := &s.R[i] r := &s.R[i]
if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != sym.SDYNIMPORT { if r.Type != 256+objabi.RelocType(elf.R_PPC64_REL24) || r.Sym.Type != sym.SDYNIMPORT {
continue continue
} }
...@@ -269,7 +270,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -269,7 +270,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_PPC64_REL24: case 256 + objabi.RelocType(elf.R_PPC64_REL24):
r.Type = objabi.R_CALLPOWER r.Type = objabi.R_CALLPOWER
// This is a local call, so the caller isn't setting // This is a local call, so the caller isn't setting
...@@ -286,7 +287,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -286,7 +287,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
case 256 + ld.R_PPC_REL32: case 256 + objabi.RelocType(elf.R_PPC_REL32):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Add += 4 r.Add += 4
...@@ -296,7 +297,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -296,7 +297,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
case 256 + ld.R_PPC64_ADDR64: case 256 + objabi.RelocType(elf.R_PPC64_ADDR64):
r.Type = objabi.R_ADDR r.Type = objabi.R_ADDR
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
// These happen in .toc sections // These happen in .toc sections
...@@ -304,56 +305,56 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -304,56 +305,56 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
rela := ctxt.Syms.Lookup(".rela", 0) rela := ctxt.Syms.Lookup(".rela", 0)
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
rela.AddUint64(ctxt.Arch, uint64(r.Add)) rela.AddUint64(ctxt.Arch, uint64(r.Add))
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
} }
return true return true
case 256 + ld.R_PPC64_TOC16: case 256 + objabi.RelocType(elf.R_PPC64_TOC16):
r.Type = objabi.R_POWER_TOC r.Type = objabi.R_POWER_TOC
r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
return true return true
case 256 + ld.R_PPC64_TOC16_LO: case 256 + objabi.RelocType(elf.R_PPC64_TOC16_LO):
r.Type = objabi.R_POWER_TOC r.Type = objabi.R_POWER_TOC
r.Variant = sym.RV_POWER_LO r.Variant = sym.RV_POWER_LO
return true return true
case 256 + ld.R_PPC64_TOC16_HA: case 256 + objabi.RelocType(elf.R_PPC64_TOC16_HA):
r.Type = objabi.R_POWER_TOC r.Type = objabi.R_POWER_TOC
r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
return true return true
case 256 + ld.R_PPC64_TOC16_HI: case 256 + objabi.RelocType(elf.R_PPC64_TOC16_HI):
r.Type = objabi.R_POWER_TOC r.Type = objabi.R_POWER_TOC
r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
return true return true
case 256 + ld.R_PPC64_TOC16_DS: case 256 + objabi.RelocType(elf.R_PPC64_TOC16_DS):
r.Type = objabi.R_POWER_TOC r.Type = objabi.R_POWER_TOC
r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
return true return true
case 256 + ld.R_PPC64_TOC16_LO_DS: case 256 + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
r.Type = objabi.R_POWER_TOC r.Type = objabi.R_POWER_TOC
r.Variant = sym.RV_POWER_DS r.Variant = sym.RV_POWER_DS
return true return true
case 256 + ld.R_PPC64_REL16_LO: case 256 + objabi.RelocType(elf.R_PPC64_REL16_LO):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Variant = sym.RV_POWER_LO r.Variant = sym.RV_POWER_LO
r.Add += 2 // Compensate for relocation size of 2 r.Add += 2 // Compensate for relocation size of 2
return true return true
case 256 + ld.R_PPC64_REL16_HI: case 256 + objabi.RelocType(elf.R_PPC64_REL16_HI):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
r.Add += 2 r.Add += 2
return true return true
case 256 + ld.R_PPC64_REL16_HA: case 256 + objabi.RelocType(elf.R_PPC64_REL16_HA):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
r.Add += 2 r.Add += 2
...@@ -380,57 +381,57 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -380,57 +381,57 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
case objabi.R_ADDR: case objabi.R_ADDR:
switch r.Siz { switch r.Siz {
case 4: case 4:
ctxt.Out.Write64(ld.R_PPC64_ADDR32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
case 8: case 8:
ctxt.Out.Write64(ld.R_PPC64_ADDR64 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR64) | uint64(elfsym)<<32)
default: default:
return false return false
} }
case objabi.R_POWER_TLS: case objabi.R_POWER_TLS:
ctxt.Out.Write64(ld.R_PPC64_TLS | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
case objabi.R_POWER_TLS_LE: case objabi.R_POWER_TLS_LE:
ctxt.Out.Write64(ld.R_PPC64_TPREL16 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_TPREL16) | uint64(elfsym)<<32)
case objabi.R_POWER_TLS_IE: case objabi.R_POWER_TLS_IE:
ctxt.Out.Write64(ld.R_PPC64_GOT_TPREL16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_GOT_TPREL16_LO_DS | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_LO_DS) | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER: case objabi.R_ADDRPOWER:
ctxt.Out.Write64(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_ADDR16_LO | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO) | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_DS: case objabi.R_ADDRPOWER_DS:
ctxt.Out.Write64(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_ADDR16_LO_DS | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_ADDR16_LO_DS) | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_GOT: case objabi.R_ADDRPOWER_GOT:
ctxt.Out.Write64(ld.R_PPC64_GOT16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_GOT16_LO_DS | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_GOT16_LO_DS) | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_PCREL: case objabi.R_ADDRPOWER_PCREL:
ctxt.Out.Write64(ld.R_PPC64_REL16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_REL16_LO | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_REL16_LO) | uint64(elfsym)<<32)
r.Xadd += 4 r.Xadd += 4
case objabi.R_ADDRPOWER_TOCREL: case objabi.R_ADDRPOWER_TOCREL:
ctxt.Out.Write64(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_TOC16_LO | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO) | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_TOCREL_DS: case objabi.R_ADDRPOWER_TOCREL_DS:
ctxt.Out.Write64(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
ctxt.Out.Write64(uint64(sectoff + 4)) ctxt.Out.Write64(uint64(sectoff + 4))
ctxt.Out.Write64(ld.R_PPC64_TOC16_LO_DS | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_TOC16_LO_DS) | uint64(elfsym)<<32)
case objabi.R_CALLPOWER: case objabi.R_CALLPOWER:
if r.Siz != 4 { if r.Siz != 4 {
return false return false
} }
ctxt.Out.Write64(ld.R_PPC64_REL24 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32)
} }
ctxt.Out.Write64(uint64(r.Xadd)) ctxt.Out.Write64(uint64(r.Xadd))
...@@ -834,7 +835,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -834,7 +835,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
plt.Size += 8 plt.Size += 8
rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt)) rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_PPC64_JMP_SLOT)))
rela.AddUint64(ctxt.Arch, 0) rela.AddUint64(ctxt.Arch, 0)
} else { } else {
ld.Errorf(s, "addpltsym: unsupported binary format") ld.Errorf(s, "addpltsym: unsupported binary format")
......
...@@ -113,24 +113,24 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -113,24 +113,24 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_390_12, case 256 + objabi.RelocType(elf.R_390_12),
256 + ld.R_390_GOT12: 256 + objabi.RelocType(elf.R_390_GOT12):
ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256) ld.Errorf(s, "s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256)
return false return false
case 256 + ld.R_390_8, case 256 + objabi.RelocType(elf.R_390_8),
256 + ld.R_390_16, 256 + objabi.RelocType(elf.R_390_16),
256 + ld.R_390_32, 256 + objabi.RelocType(elf.R_390_32),
256 + ld.R_390_64: 256 + objabi.RelocType(elf.R_390_64):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
} }
r.Type = objabi.R_ADDR r.Type = objabi.R_ADDR
return true return true
case 256 + ld.R_390_PC16, case 256 + objabi.RelocType(elf.R_390_PC16),
256 + ld.R_390_PC32, 256 + objabi.RelocType(elf.R_390_PC32),
256 + ld.R_390_PC64: 256 + objabi.RelocType(elf.R_390_PC64):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
} }
...@@ -141,14 +141,14 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -141,14 +141,14 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
return true return true
case 256 + ld.R_390_GOT16, case 256 + objabi.RelocType(elf.R_390_GOT16),
256 + ld.R_390_GOT32, 256 + objabi.RelocType(elf.R_390_GOT32),
256 + ld.R_390_GOT64: 256 + objabi.RelocType(elf.R_390_GOT64):
ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
return true return true
case 256 + ld.R_390_PLT16DBL, case 256 + objabi.RelocType(elf.R_390_PLT16DBL),
256 + ld.R_390_PLT32DBL: 256 + objabi.RelocType(elf.R_390_PLT32DBL):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Variant = sym.RV_390_DBL r.Variant = sym.RV_390_DBL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
...@@ -159,8 +159,8 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -159,8 +159,8 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
return true return true
case 256 + ld.R_390_PLT32, case 256 + objabi.RelocType(elf.R_390_PLT32),
256 + ld.R_390_PLT64: 256 + objabi.RelocType(elf.R_390_PLT64):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
...@@ -170,37 +170,37 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -170,37 +170,37 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
return true return true
case 256 + ld.R_390_COPY: case 256 + objabi.RelocType(elf.R_390_COPY):
ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
return false return false
case 256 + ld.R_390_GLOB_DAT: case 256 + objabi.RelocType(elf.R_390_GLOB_DAT):
ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
return false return false
case 256 + ld.R_390_JMP_SLOT: case 256 + objabi.RelocType(elf.R_390_JMP_SLOT):
ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
return false return false
case 256 + ld.R_390_RELATIVE: case 256 + objabi.RelocType(elf.R_390_RELATIVE):
ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256) ld.Errorf(s, "unimplemented S390x relocation: %v", r.Type-256)
return false return false
case 256 + ld.R_390_GOTOFF: case 256 + objabi.RelocType(elf.R_390_GOTOFF):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
} }
r.Type = objabi.R_GOTOFF r.Type = objabi.R_GOTOFF
return true return true
case 256 + ld.R_390_GOTPC: case 256 + objabi.RelocType(elf.R_390_GOTPC):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0) r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
return true return true
case 256 + ld.R_390_PC16DBL, case 256 + objabi.RelocType(elf.R_390_PC16DBL),
256 + ld.R_390_PC32DBL: 256 + objabi.RelocType(elf.R_390_PC32DBL):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Variant = sym.RV_390_DBL r.Variant = sym.RV_390_DBL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
...@@ -209,14 +209,14 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -209,14 +209,14 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
return true return true
case 256 + ld.R_390_GOTPCDBL: case 256 + objabi.RelocType(elf.R_390_GOTPCDBL):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Variant = sym.RV_390_DBL r.Variant = sym.RV_390_DBL
r.Sym = ctxt.Syms.Lookup(".got", 0) r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
return true return true
case 256 + ld.R_390_GOTENT: case 256 + objabi.RelocType(elf.R_390_GOTENT):
addgotsym(ctxt, targ) addgotsym(ctxt, targ)
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
...@@ -247,35 +247,35 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -247,35 +247,35 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
return false return false
case 4: case 4:
// WARNING - silently ignored by linker in ELF64 // WARNING - silently ignored by linker in ELF64
ctxt.Out.Write64(ld.R_390_TLS_LE32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_390_TLS_LE32) | uint64(elfsym)<<32)
case 8: case 8:
// WARNING - silently ignored by linker in ELF32 // WARNING - silently ignored by linker in ELF32
ctxt.Out.Write64(ld.R_390_TLS_LE64 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_390_TLS_LE64) | uint64(elfsym)<<32)
} }
case objabi.R_TLS_IE: case objabi.R_TLS_IE:
switch r.Siz { switch r.Siz {
default: default:
return false return false
case 4: case 4:
ctxt.Out.Write64(ld.R_390_TLS_IEENT | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_390_TLS_IEENT) | uint64(elfsym)<<32)
} }
case objabi.R_ADDR: case objabi.R_ADDR:
switch r.Siz { switch r.Siz {
default: default:
return false return false
case 4: case 4:
ctxt.Out.Write64(ld.R_390_32 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_390_32) | uint64(elfsym)<<32)
case 8: case 8:
ctxt.Out.Write64(ld.R_390_64 | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_390_64) | uint64(elfsym)<<32)
} }
case objabi.R_GOTPCREL: case objabi.R_GOTPCREL:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write64(ld.R_390_GOTENT | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elf.R_390_GOTENT) | uint64(elfsym)<<32)
} else { } else {
return false return false
} }
case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL: case objabi.R_PCREL, objabi.R_PCRELDBL, objabi.R_CALL:
elfrel := ld.R_390_NONE elfrel := elf.R_390_NONE
isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL isdbl := r.Variant&sym.RV_TYPE_MASK == sym.RV_390_DBL
// TODO(mundaym): all DBL style relocations should be // TODO(mundaym): all DBL style relocations should be
// signalled using the variant - see issue 14218. // signalled using the variant - see issue 14218.
...@@ -287,38 +287,38 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -287,38 +287,38 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
if isdbl { if isdbl {
switch r.Siz { switch r.Siz {
case 2: case 2:
elfrel = ld.R_390_PLT16DBL elfrel = elf.R_390_PLT16DBL
case 4: case 4:
elfrel = ld.R_390_PLT32DBL elfrel = elf.R_390_PLT32DBL
} }
} else { } else {
switch r.Siz { switch r.Siz {
case 4: case 4:
elfrel = ld.R_390_PLT32 elfrel = elf.R_390_PLT32
case 8: case 8:
elfrel = ld.R_390_PLT64 elfrel = elf.R_390_PLT64
} }
} }
} else { } else {
if isdbl { if isdbl {
switch r.Siz { switch r.Siz {
case 2: case 2:
elfrel = ld.R_390_PC16DBL elfrel = elf.R_390_PC16DBL
case 4: case 4:
elfrel = ld.R_390_PC32DBL elfrel = elf.R_390_PC32DBL
} }
} else { } else {
switch r.Siz { switch r.Siz {
case 2: case 2:
elfrel = ld.R_390_PC16 elfrel = elf.R_390_PC16
case 4: case 4:
elfrel = ld.R_390_PC32 elfrel = elf.R_390_PC32
case 8: case 8:
elfrel = ld.R_390_PC64 elfrel = elf.R_390_PC64
} }
} }
} }
if elfrel == ld.R_390_NONE { if elfrel == elf.R_390_NONE {
return false // unsupported size/dbl combination return false // unsupported size/dbl combination
} }
ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32) ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
...@@ -469,7 +469,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -469,7 +469,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
// rela // rela
rela.AddAddrPlus(ctxt.Arch, got, got.Size-8) rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
rela.AddUint64(ctxt.Arch, 0) rela.AddUint64(ctxt.Arch, 0)
s.Plt = int32(plt.Size - 32) s.Plt = int32(plt.Size - 32)
...@@ -492,7 +492,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -492,7 +492,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if ld.Iself { if ld.Iself {
rela := ctxt.Syms.Lookup(".rela", 0) rela := ctxt.Syms.Lookup(".rela", 0)
rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got)) rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT)) rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
rela.AddUint64(ctxt.Arch, 0) rela.AddUint64(ctxt.Arch, 0)
} else { } else {
ld.Errorf(s, "addgotsym: unsupported binary format") ld.Errorf(s, "addgotsym: unsupported binary format")
......
...@@ -35,6 +35,7 @@ import ( ...@@ -35,6 +35,7 @@ import (
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/ld" "cmd/link/internal/ld"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf"
"log" "log"
) )
...@@ -177,7 +178,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -177,7 +178,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_386_PC32: case 256 + objabi.RelocType(elf.R_386_PC32):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
} }
...@@ -188,7 +189,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -188,7 +189,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += 4 r.Add += 4
return true return true
case 256 + ld.R_386_PLT32: case 256 + objabi.RelocType(elf.R_386_PLT32):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Add += 4 r.Add += 4
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
...@@ -199,7 +200,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -199,7 +200,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
return true return true
case 256 + ld.R_386_GOT32, 256 + ld.R_386_GOT32X: case 256 + objabi.RelocType(elf.R_386_GOT32), 256 + objabi.RelocType(elf.R_386_GOT32X):
if targ.Type != sym.SDYNIMPORT { if targ.Type != sym.SDYNIMPORT {
// have symbol // have symbol
if r.Off >= 2 && s.P[r.Off-2] == 0x8b { if r.Off >= 2 && s.P[r.Off-2] == 0x8b {
...@@ -230,17 +231,17 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -230,17 +231,17 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
return true return true
case 256 + ld.R_386_GOTOFF: case 256 + objabi.RelocType(elf.R_386_GOTOFF):
r.Type = objabi.R_GOTOFF r.Type = objabi.R_GOTOFF
return true return true
case 256 + ld.R_386_GOTPC: case 256 + objabi.RelocType(elf.R_386_GOTPC):
r.Type = objabi.R_PCREL r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0) r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += 4 r.Add += 4
return true return true
case 256 + ld.R_386_32: case 256 + objabi.RelocType(elf.R_386_32):
if targ.Type == sym.SDYNIMPORT { if targ.Type == sym.SDYNIMPORT {
ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name) ld.Errorf(s, "unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
} }
...@@ -307,7 +308,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -307,7 +308,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
ld.Adddynsym(ctxt, targ) ld.Adddynsym(ctxt, targ)
rel := ctxt.Syms.Lookup(".rel", 0) rel := ctxt.Syms.Lookup(".rel", 0)
rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off)) rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32)) rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
r.Type = objabi.R_CONST // write r->add during relocsym r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil r.Sym = nil
return true return true
...@@ -351,16 +352,16 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -351,16 +352,16 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
return false return false
case objabi.R_ADDR: case objabi.R_ADDR:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_386_32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_32) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
case objabi.R_GOTPCREL: case objabi.R_GOTPCREL:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_386_GOTPC) ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" { if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
ctxt.Out.Write32(uint32(sectoff)) ctxt.Out.Write32(uint32(sectoff))
ctxt.Out.Write32(ld.R_386_GOT32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_GOT32) | uint32(elfsym)<<8)
} }
} else { } else {
return false return false
...@@ -368,30 +369,30 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool { ...@@ -368,30 +369,30 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
case objabi.R_CALL: case objabi.R_CALL:
if r.Siz == 4 { if r.Siz == 4 {
if r.Xsym.Type == sym.SDYNIMPORT { if r.Xsym.Type == sym.SDYNIMPORT {
ctxt.Out.Write32(ld.R_386_PLT32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_PLT32) | uint32(elfsym)<<8)
} else { } else {
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
} }
} else { } else {
return false return false
} }
case objabi.R_PCREL: case objabi.R_PCREL:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
case objabi.R_TLS_LE: case objabi.R_TLS_LE:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_386_TLS_LE | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_TLS_LE) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
case objabi.R_TLS_IE: case objabi.R_TLS_IE:
if r.Siz == 4 { if r.Siz == 4 {
ctxt.Out.Write32(ld.R_386_GOTPC) ctxt.Out.Write32(uint32(elf.R_386_GOTPC))
ctxt.Out.Write32(uint32(sectoff)) ctxt.Out.Write32(uint32(sectoff))
ctxt.Out.Write32(ld.R_386_TLS_GOTIE | uint32(elfsym)<<8) ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
} else { } else {
return false return false
} }
...@@ -568,7 +569,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -568,7 +569,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
// rel // rel
rel.AddAddrPlus(ctxt.Arch, got, got.Size-4) rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT)) rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
s.Plt = int32(plt.Size - 16) s.Plt = int32(plt.Size - 16)
} else if ld.Headtype == objabi.Hdarwin { } else if ld.Headtype == objabi.Hdarwin {
...@@ -604,7 +605,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) { ...@@ -604,7 +605,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if ld.Iself { if ld.Iself {
rel := ctxt.Syms.Lookup(".rel", 0) rel := ctxt.Syms.Lookup(".rel", 0)
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got)) rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT)) rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
} else if ld.Headtype == objabi.Hdarwin { } else if ld.Headtype == objabi.Hdarwin {
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid)) ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment