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: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
David Crawshaw 2017-10-06 16:01:02 -04:00
parent 70576947fd
commit ecfa7375e4
13 changed files with 347 additions and 767 deletions

View file

@ -35,6 +35,7 @@ import (
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"debug/elf"
"log"
)
@ -177,7 +178,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
}
// 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 {
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 {
r.Add += 4
return true
case 256 + ld.R_386_PLT32:
case 256 + objabi.RelocType(elf.R_386_PLT32):
r.Type = objabi.R_PCREL
r.Add += 4
if targ.Type == sym.SDYNIMPORT {
@ -199,7 +200,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
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 {
// have symbol
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 {
r.Add += int64(targ.Got)
return true
case 256 + ld.R_386_GOTOFF:
case 256 + objabi.RelocType(elf.R_386_GOTOFF):
r.Type = objabi.R_GOTOFF
return true
case 256 + ld.R_386_GOTPC:
case 256 + objabi.RelocType(elf.R_386_GOTPC):
r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += 4
return true
case 256 + ld.R_386_32:
case 256 + objabi.RelocType(elf.R_386_32):
if targ.Type == sym.SDYNIMPORT {
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 {
ld.Adddynsym(ctxt, 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), 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.Sym = nil
return true
@ -351,16 +352,16 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
return false
case objabi.R_ADDR:
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 {
return false
}
case objabi.R_GOTPCREL:
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_" {
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 {
return false
@ -368,30 +369,30 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
case objabi.R_CALL:
if r.Siz == 4 {
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 {
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8)
ctxt.Out.Write32(uint32(elf.R_386_PC32) | uint32(elfsym)<<8)
}
} else {
return false
}
case objabi.R_PCREL:
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 {
return false
}
case objabi.R_TLS_LE:
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 {
return false
}
case objabi.R_TLS_IE:
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(ld.R_386_TLS_GOTIE | uint32(elfsym)<<8)
ctxt.Out.Write32(uint32(elf.R_386_TLS_GOTIE) | uint32(elfsym)<<8)
} else {
return false
}
@ -568,7 +569,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
// rel
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)
} else if ld.Headtype == objabi.Hdarwin {
@ -604,7 +605,7 @@ func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
if ld.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), 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 {
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
} else {