mirror of
https://github.com/golang/go.git
synced 2025-05-18 13:54:40 +00:00
[dev.link] cmd/link: convert ppc64 archreloc over to Loader
Change-Id: I68945a8284fb3dd9ceb5a9cd774b5b4b91e63ce0 Reviewed-on: https://go-review.googlesource.com/c/go/+/230917 Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
75ca90e309
commit
fee06a6bda
@ -372,7 +372,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
} else if target.IsWindows() {
|
} else if target.IsWindows() {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
} else if target.IsAIX() {
|
} else if target.IsAIX() {
|
||||||
o = ldr.SymValue(rs) + r.Add()
|
o = ldr.SymValue(rs) + rr.Xadd
|
||||||
} else {
|
} else {
|
||||||
st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
|
st.err.Errorf(s, "unhandled pcrel relocation to %s on %v", ldr.SymName(rs), target.HeadType)
|
||||||
}
|
}
|
||||||
@ -391,8 +391,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
// symbol which isn't in .data. However, as .text has the
|
// symbol which isn't in .data. However, as .text has the
|
||||||
// same address once loaded, this is possible.
|
// same address once loaded, this is possible.
|
||||||
if ldr.SymSect(s).Seg == &Segdata {
|
if ldr.SymSect(s).Seg == &Segdata {
|
||||||
panic("not implemented")
|
Xcoffadddynrel2(target, ldr, syms, s, r, ri)
|
||||||
//Xcoffadddynrel(target, ldr, err, s, &r) // XXX
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,10 +542,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
needExtReloc = true
|
needExtReloc = true
|
||||||
rr.Xsym = rs
|
rr.Xsym = rs
|
||||||
rr.Xadd = r.Add()
|
rr.Xadd = r.Add()
|
||||||
|
goto addExtReloc
|
||||||
// This isn't a real relocation so it must not update
|
|
||||||
// its offset value.
|
|
||||||
continue
|
|
||||||
|
|
||||||
case objabi.R_DWARFFILEREF:
|
case objabi.R_DWARFFILEREF:
|
||||||
// We don't renumber files in dwarf.go:writelines anymore.
|
// We don't renumber files in dwarf.go:writelines anymore.
|
||||||
@ -590,6 +586,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
|
|||||||
target.Arch.ByteOrder.PutUint64(P[off:], uint64(o))
|
target.Arch.ByteOrder.PutUint64(P[off:], uint64(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addExtReloc:
|
||||||
if needExtReloc {
|
if needExtReloc {
|
||||||
extRelocs = append(extRelocs, rr)
|
extRelocs = append(extRelocs, rr)
|
||||||
}
|
}
|
||||||
|
@ -318,7 +318,7 @@ func Main(arch *sys.Arch, theArch Arch) {
|
|||||||
bench.Start("Asmb")
|
bench.Start("Asmb")
|
||||||
ctxt.loader.InitOutData()
|
ctxt.loader.InitOutData()
|
||||||
thearch.Asmb(ctxt, ctxt.loader)
|
thearch.Asmb(ctxt, ctxt.loader)
|
||||||
newreloc := ctxt.Is386() || ctxt.IsAMD64() || ctxt.IsARM() || ctxt.IsARM64() || ctxt.IsMIPS() || ctxt.IsMIPS64() || ctxt.IsRISCV64() || ctxt.IsS390X() || ctxt.IsWasm()
|
newreloc := ctxt.Is386() || ctxt.IsAMD64() || ctxt.IsARM() || ctxt.IsARM64() || ctxt.IsMIPS() || ctxt.IsMIPS64() || ctxt.IsRISCV64() || ctxt.IsS390X() || ctxt.IsWasm() || ctxt.IsPPC64()
|
||||||
newasmb2 := ctxt.IsDarwin()
|
newasmb2 := ctxt.IsDarwin()
|
||||||
if newreloc {
|
if newreloc {
|
||||||
bench.Start("reloc")
|
bench.Start("reloc")
|
||||||
|
@ -1122,7 +1122,7 @@ func Xcoffadddynrel2(target *Target, ldr *loader.Loader, syms *ArchSyms, s loade
|
|||||||
sym2: s,
|
sym2: s,
|
||||||
roff: r.Off(),
|
roff: r.Off(),
|
||||||
}
|
}
|
||||||
targ := r.Sym()
|
targ := ldr.ResolveABIAlias(r.Sym())
|
||||||
var targType sym.SymKind
|
var targType sym.SymKind
|
||||||
if targ != 0 {
|
if targ != 0 {
|
||||||
targType = ldr.SymType(targ)
|
targType = ldr.SymType(targ)
|
||||||
|
@ -416,7 +416,7 @@ func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
|
|||||||
switch r.Type {
|
switch r.Type {
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
case objabi.R_ADDR:
|
case objabi.R_ADDR, objabi.R_DWARFSECREF:
|
||||||
v = ld.XCOFF_R_POS
|
v = ld.XCOFF_R_POS
|
||||||
if r.Siz == 4 {
|
if r.Siz == 4 {
|
||||||
v |= 0x1F << 8
|
v |= 0x1F << 8
|
||||||
@ -437,7 +437,6 @@ func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
|
|||||||
emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
|
emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
|
||||||
case objabi.R_XCOFFREF:
|
case objabi.R_XCOFFREF:
|
||||||
emitReloc(ld.XCOFF_R_REF|0x3F<<8, 0)
|
emitReloc(ld.XCOFF_R_REF|0x3F<<8, 0)
|
||||||
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
||||||
@ -533,19 +532,19 @@ func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return the value of .TOC. for symbol s
|
// Return the value of .TOC. for symbol s
|
||||||
func symtoc(syms *ld.ArchSyms, s *sym.Symbol) int64 {
|
func symtoc(ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) int64 {
|
||||||
v := s.Version
|
v := ldr.SymVersion(s)
|
||||||
if s.Outer != nil {
|
if out := ldr.OuterSym(s); out != 0 {
|
||||||
v = s.Outer.Version
|
v = ldr.SymVersion(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
toc := syms.DotTOC[v]
|
toc := syms.DotTOC2[v]
|
||||||
if toc == nil {
|
if toc == 0 {
|
||||||
ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
|
ldr.Errorf(s, "TOC-relative relocation in object without .TOC.")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return toc.Value
|
return ldr.SymValue(toc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// archreloctoc relocates a TOC relative symbol.
|
// archreloctoc relocates a TOC relative symbol.
|
||||||
@ -553,36 +552,35 @@ func symtoc(syms *ld.ArchSyms, s *sym.Symbol) int64 {
|
|||||||
// default load instruction can be changed to an addi instruction and the
|
// default load instruction can be changed to an addi instruction and the
|
||||||
// symbol address can be used directly.
|
// symbol address can be used directly.
|
||||||
// This code is for AIX only.
|
// This code is for AIX only.
|
||||||
func archreloctoc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
|
func archreloctoc(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc2, s loader.Sym, val int64) int64 {
|
||||||
|
rs := ldr.ResolveABIAlias(r.Sym())
|
||||||
if target.IsLinux() {
|
if target.IsLinux() {
|
||||||
ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
|
ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
|
||||||
}
|
}
|
||||||
var o1, o2 uint32
|
var o1, o2 uint32
|
||||||
|
|
||||||
o1 = uint32(val >> 32)
|
o1 = uint32(val >> 32)
|
||||||
o2 = uint32(val)
|
o2 = uint32(val)
|
||||||
|
|
||||||
|
if !strings.HasPrefix(ldr.SymName(rs), "TOC.") {
|
||||||
|
ldr.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
|
||||||
|
}
|
||||||
var t int64
|
var t int64
|
||||||
useAddi := false
|
useAddi := false
|
||||||
const prefix = "TOC."
|
relocs := ldr.Relocs(rs)
|
||||||
var tarSym *sym.Symbol
|
tarSym := ldr.ResolveABIAlias(relocs.At2(0).Sym())
|
||||||
if strings.HasPrefix(r.Sym.Name, prefix) {
|
|
||||||
tarSym = r.Sym.R[0].Sym
|
|
||||||
} else {
|
|
||||||
ld.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
|
|
||||||
}
|
|
||||||
|
|
||||||
if target.IsInternal() && tarSym != nil && tarSym.Attr.Reachable() && (tarSym.Sect.Seg == &ld.Segdata) {
|
if target.IsInternal() && tarSym != 0 && ldr.AttrReachable(tarSym) && ldr.SymSect(tarSym).Seg == &ld.Segdata {
|
||||||
t = ld.Symaddr(tarSym) + r.Add - syms.TOC.Value
|
t = ldr.SymValue(tarSym) + r.Add() - ldr.SymValue(syms.TOC2)
|
||||||
// change ld to addi in the second instruction
|
// change ld to addi in the second instruction
|
||||||
o2 = (o2 & 0x03FF0000) | 0xE<<26
|
o2 = (o2 & 0x03FF0000) | 0xE<<26
|
||||||
useAddi = true
|
useAddi = true
|
||||||
} else {
|
} else {
|
||||||
t = ld.Symaddr(r.Sym) + r.Add - syms.TOC.Value
|
t = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.TOC2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t != int64(int32(t)) {
|
if t != int64(int32(t)) {
|
||||||
ld.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", s.Name, r.Sym, t)
|
ldr.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", ldr.SymName(s), rs, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t&0x8000 != 0 {
|
if t&0x8000 != 0 {
|
||||||
@ -591,13 +589,13 @@ func archreloctoc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Sym
|
|||||||
|
|
||||||
o1 |= uint32((t >> 16) & 0xFFFF)
|
o1 |= uint32((t >> 16) & 0xFFFF)
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type() {
|
||||||
case objabi.R_ADDRPOWER_TOCREL_DS:
|
case objabi.R_ADDRPOWER_TOCREL_DS:
|
||||||
if useAddi {
|
if useAddi {
|
||||||
o2 |= uint32(t) & 0xFFFF
|
o2 |= uint32(t) & 0xFFFF
|
||||||
} else {
|
} else {
|
||||||
if t&3 != 0 {
|
if t&3 != 0 {
|
||||||
ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
|
ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
|
||||||
}
|
}
|
||||||
o2 |= uint32(t) & 0xFFFC
|
o2 |= uint32(t) & 0xFFFC
|
||||||
}
|
}
|
||||||
@ -610,9 +608,10 @@ func archreloctoc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Sym
|
|||||||
|
|
||||||
// archrelocaddr relocates a symbol address.
|
// archrelocaddr relocates a symbol address.
|
||||||
// This code is for AIX only.
|
// This code is for AIX only.
|
||||||
func archrelocaddr(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) int64 {
|
func archrelocaddr(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc2, s loader.Sym, val int64) int64 {
|
||||||
|
rs := ldr.ResolveABIAlias(r.Sym())
|
||||||
if target.IsAIX() {
|
if target.IsAIX() {
|
||||||
ld.Errorf(s, "archrelocaddr called for %s relocation\n", r.Sym.Name)
|
ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
|
||||||
}
|
}
|
||||||
var o1, o2 uint32
|
var o1, o2 uint32
|
||||||
if target.IsBigEndian() {
|
if target.IsBigEndian() {
|
||||||
@ -630,22 +629,22 @@ func archrelocaddr(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Sy
|
|||||||
// instruction (it is an error in this case if the low 2 bits of the address
|
// instruction (it is an error in this case if the low 2 bits of the address
|
||||||
// are non-zero).
|
// are non-zero).
|
||||||
|
|
||||||
t := ld.Symaddr(r.Sym) + r.Add
|
t := ldr.SymAddr(rs) + r.Add()
|
||||||
if t < 0 || t >= 1<<31 {
|
if t < 0 || t >= 1<<31 {
|
||||||
ld.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", s.Name, ld.Symaddr(r.Sym))
|
ldr.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", ldr.SymName(s), ldr.SymValue(rs))
|
||||||
}
|
}
|
||||||
if t&0x8000 != 0 {
|
if t&0x8000 != 0 {
|
||||||
t += 0x10000
|
t += 0x10000
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type() {
|
||||||
case objabi.R_ADDRPOWER:
|
case objabi.R_ADDRPOWER:
|
||||||
o1 |= (uint32(t) >> 16) & 0xffff
|
o1 |= (uint32(t) >> 16) & 0xffff
|
||||||
o2 |= uint32(t) & 0xffff
|
o2 |= uint32(t) & 0xffff
|
||||||
case objabi.R_ADDRPOWER_DS:
|
case objabi.R_ADDRPOWER_DS:
|
||||||
o1 |= (uint32(t) >> 16) & 0xffff
|
o1 |= (uint32(t) >> 16) & 0xffff
|
||||||
if t&3 != 0 {
|
if t&3 != 0 {
|
||||||
ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
|
ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
|
||||||
}
|
}
|
||||||
o2 |= uint32(t) & 0xfffc
|
o2 |= uint32(t) & 0xfffc
|
||||||
default:
|
default:
|
||||||
@ -795,113 +794,114 @@ func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, ta
|
|||||||
tramp.SetData(P)
|
tramp.SetData(P)
|
||||||
}
|
}
|
||||||
|
|
||||||
func archreloc(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bool) {
|
func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc2, rr *loader.ExtReloc, s loader.Sym, val int64) (relocatedOffset int64, needExtReloc bool, ok bool) {
|
||||||
|
needExternal := false
|
||||||
|
rs := ldr.ResolveABIAlias(r.Sym())
|
||||||
if target.IsExternal() {
|
if target.IsExternal() {
|
||||||
// On AIX, relocations (except TLS ones) must be also done to the
|
// On AIX, relocations (except TLS ones) must be also done to the
|
||||||
// value with the current addresses.
|
// value with the current addresses.
|
||||||
switch r.Type {
|
switch r.Type() {
|
||||||
default:
|
default:
|
||||||
if target.IsAIX() {
|
if target.IsAIX() {
|
||||||
return val, false
|
return val, needExternal, false
|
||||||
}
|
}
|
||||||
case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
|
case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
|
||||||
r.Done = false
|
|
||||||
// check Outer is nil, Type is TLSBSS?
|
// check Outer is nil, Type is TLSBSS?
|
||||||
r.Xadd = r.Add
|
needExternal = true
|
||||||
r.Xsym = r.Sym
|
rr.Xadd = r.Add()
|
||||||
return val, true
|
rr.Xsym = rs
|
||||||
|
return val, needExternal, true
|
||||||
case objabi.R_ADDRPOWER,
|
case objabi.R_ADDRPOWER,
|
||||||
objabi.R_ADDRPOWER_DS,
|
objabi.R_ADDRPOWER_DS,
|
||||||
objabi.R_ADDRPOWER_TOCREL,
|
objabi.R_ADDRPOWER_TOCREL,
|
||||||
objabi.R_ADDRPOWER_TOCREL_DS,
|
objabi.R_ADDRPOWER_TOCREL_DS,
|
||||||
objabi.R_ADDRPOWER_GOT,
|
objabi.R_ADDRPOWER_GOT,
|
||||||
objabi.R_ADDRPOWER_PCREL:
|
objabi.R_ADDRPOWER_PCREL:
|
||||||
r.Done = false
|
needExternal = true
|
||||||
|
|
||||||
// set up addend for eventual relocation via outer symbol.
|
// set up addend for eventual relocation via outer symbol.
|
||||||
rs := ld.ApplyOuterToXAdd(r)
|
rs, off := ld.FoldSubSymbolOffset(ldr, rs)
|
||||||
if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil {
|
rr.Xadd = r.Add() + off
|
||||||
ld.Errorf(s, "missing section for %s", rs.Name)
|
rst := ldr.SymType(rs)
|
||||||
|
if rst != sym.SHOSTOBJ && rst != sym.SDYNIMPORT && rst != sym.SUNDEFEXT && ldr.SymSect(rs) == nil {
|
||||||
|
ldr.Errorf(s, "missing section for %s", ldr.SymName(rs))
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
rr.Xsym = rs
|
||||||
|
|
||||||
if !target.IsAIX() {
|
if !target.IsAIX() {
|
||||||
return val, true
|
return val, needExternal, true
|
||||||
}
|
}
|
||||||
case objabi.R_CALLPOWER:
|
case objabi.R_CALLPOWER:
|
||||||
r.Done = false
|
needExternal = true
|
||||||
r.Xsym = r.Sym
|
rr.Xsym = rs
|
||||||
r.Xadd = r.Add
|
rr.Xadd = r.Add()
|
||||||
if !target.IsAIX() {
|
if !target.IsAIX() {
|
||||||
return val, true
|
return val, needExternal, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r.Type {
|
switch r.Type() {
|
||||||
case objabi.R_CONST:
|
|
||||||
return r.Add, true
|
|
||||||
case objabi.R_GOTOFF:
|
|
||||||
return ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(syms.GOT), true
|
|
||||||
case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
|
case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
|
||||||
return archreloctoc(target, syms, r, s, val), true
|
return archreloctoc(ldr, target, syms, r, s, val), needExternal, true
|
||||||
case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
|
case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
|
||||||
return archrelocaddr(target, syms, r, s, val), true
|
return archrelocaddr(ldr, target, syms, r, s, val), needExternal, true
|
||||||
case objabi.R_CALLPOWER:
|
case objabi.R_CALLPOWER:
|
||||||
// Bits 6 through 29 = (S + A - P) >> 2
|
// Bits 6 through 29 = (S + A - P) >> 2
|
||||||
|
|
||||||
t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
|
t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
|
||||||
|
|
||||||
if t&3 != 0 {
|
if t&3 != 0 {
|
||||||
ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
|
ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
|
||||||
}
|
}
|
||||||
// If branch offset is too far then create a trampoline.
|
// If branch offset is too far then create a trampoline.
|
||||||
|
|
||||||
if int64(int32(t<<6)>>6) != t {
|
if int64(int32(t<<6)>>6) != t {
|
||||||
ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
|
ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
|
||||||
}
|
}
|
||||||
return val | int64(uint32(t)&^0xfc000003), true
|
return val | int64(uint32(t)&^0xfc000003), needExternal, true
|
||||||
case objabi.R_POWER_TOC: // S + A - .TOC.
|
case objabi.R_POWER_TOC: // S + A - .TOC.
|
||||||
return ld.Symaddr(r.Sym) + r.Add - symtoc(syms, s), true
|
return ldr.SymValue(rs) + r.Add() - symtoc(ldr, syms, s), needExternal, true
|
||||||
|
|
||||||
case objabi.R_POWER_TLS_LE:
|
case objabi.R_POWER_TLS_LE:
|
||||||
// The thread pointer points 0x7000 bytes after the start of the
|
// The thread pointer points 0x7000 bytes after the start of the
|
||||||
// thread local storage area as documented in section "3.7.2 TLS
|
// thread local storage area as documented in section "3.7.2 TLS
|
||||||
// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
|
// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
|
||||||
// Specification".
|
// Specification".
|
||||||
v := r.Sym.Value - 0x7000
|
v := ldr.SymValue(rs) - 0x7000
|
||||||
if target.IsAIX() {
|
if target.IsAIX() {
|
||||||
// On AIX, the thread pointer points 0x7800 bytes after
|
// On AIX, the thread pointer points 0x7800 bytes after
|
||||||
// the TLS.
|
// the TLS.
|
||||||
v -= 0x800
|
v -= 0x800
|
||||||
}
|
}
|
||||||
if int64(int16(v)) != v {
|
if int64(int16(v)) != v {
|
||||||
ld.Errorf(s, "TLS offset out of range %d", v)
|
ldr.Errorf(s, "TLS offset out of range %d", v)
|
||||||
}
|
}
|
||||||
return (val &^ 0xffff) | (v & 0xffff), true
|
return (val &^ 0xffff) | (v & 0xffff), needExternal, true
|
||||||
}
|
}
|
||||||
|
|
||||||
return val, false
|
return val, needExternal, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
|
func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc2, rv sym.RelocVariant, s loader.Sym, t int64) (relocatedOffset int64) {
|
||||||
switch r.Variant & sym.RV_TYPE_MASK {
|
rs := ldr.ResolveABIAlias(r.Sym())
|
||||||
|
switch rv & sym.RV_TYPE_MASK {
|
||||||
default:
|
default:
|
||||||
ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
|
ldr.Errorf(s, "unexpected relocation variant %d", rv)
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
case sym.RV_NONE:
|
case sym.RV_NONE:
|
||||||
return t
|
return t
|
||||||
|
|
||||||
case sym.RV_POWER_LO:
|
case sym.RV_POWER_LO:
|
||||||
if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
|
if rv&sym.RV_CHECK_OVERFLOW != 0 {
|
||||||
// Whether to check for signed or unsigned
|
// Whether to check for signed or unsigned
|
||||||
// overflow depends on the instruction
|
// overflow depends on the instruction
|
||||||
var o1 uint32
|
var o1 uint32
|
||||||
if target.IsBigEndian() {
|
if target.IsBigEndian() {
|
||||||
o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
|
o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
|
||||||
} else {
|
} else {
|
||||||
o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
|
o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
|
||||||
}
|
}
|
||||||
switch o1 >> 26 {
|
switch o1 >> 26 {
|
||||||
case 24, // ori
|
case 24, // ori
|
||||||
@ -928,14 +928,14 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
|
|||||||
case sym.RV_POWER_HI:
|
case sym.RV_POWER_HI:
|
||||||
t >>= 16
|
t >>= 16
|
||||||
|
|
||||||
if r.Variant&sym.RV_CHECK_OVERFLOW != 0 {
|
if rv&sym.RV_CHECK_OVERFLOW != 0 {
|
||||||
// Whether to check for signed or unsigned
|
// Whether to check for signed or unsigned
|
||||||
// overflow depends on the instruction
|
// overflow depends on the instruction
|
||||||
var o1 uint32
|
var o1 uint32
|
||||||
if target.IsBigEndian() {
|
if target.IsBigEndian() {
|
||||||
o1 = binary.BigEndian.Uint32(s.P[r.Off-2:])
|
o1 = binary.BigEndian.Uint32(ldr.Data(s)[r.Off()-2:])
|
||||||
} else {
|
} else {
|
||||||
o1 = binary.LittleEndian.Uint32(s.P[r.Off:])
|
o1 = binary.LittleEndian.Uint32(ldr.Data(s)[r.Off():])
|
||||||
}
|
}
|
||||||
switch o1 >> 26 {
|
switch o1 >> 26 {
|
||||||
case 25, // oris
|
case 25, // oris
|
||||||
@ -957,21 +957,21 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
|
|||||||
case sym.RV_POWER_DS:
|
case sym.RV_POWER_DS:
|
||||||
var o1 uint32
|
var o1 uint32
|
||||||
if target.IsBigEndian() {
|
if target.IsBigEndian() {
|
||||||
o1 = uint32(binary.BigEndian.Uint16(s.P[r.Off:]))
|
o1 = uint32(binary.BigEndian.Uint16(ldr.Data(s)[r.Off():]))
|
||||||
} else {
|
} else {
|
||||||
o1 = uint32(binary.LittleEndian.Uint16(s.P[r.Off:]))
|
o1 = uint32(binary.LittleEndian.Uint16(ldr.Data(s)[r.Off():]))
|
||||||
}
|
}
|
||||||
if t&3 != 0 {
|
if t&3 != 0 {
|
||||||
ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
|
ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
|
||||||
}
|
}
|
||||||
if (r.Variant&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
|
if (rv&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
|
||||||
goto overflow
|
goto overflow
|
||||||
}
|
}
|
||||||
return int64(o1)&0x3 | int64(int16(t))
|
return int64(o1)&0x3 | int64(int16(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
overflow:
|
overflow:
|
||||||
ld.Errorf(s, "relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
|
ldr.Errorf(s, "relocation for %s+%d is too big: %d", ldr.SymName(rs), r.Off(), t)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,18 +49,18 @@ func Init() (*sys.Arch, ld.Arch) {
|
|||||||
Dwarfregsp: dwarfRegSP,
|
Dwarfregsp: dwarfRegSP,
|
||||||
Dwarfreglr: dwarfRegLR,
|
Dwarfreglr: dwarfRegLR,
|
||||||
|
|
||||||
Adddynrel2: adddynrel2,
|
Adddynrel2: adddynrel2,
|
||||||
Archinit: archinit,
|
Archinit: archinit,
|
||||||
Archreloc: archreloc,
|
Archreloc2: archreloc,
|
||||||
Archrelocvariant: archrelocvariant,
|
Archrelocvariant2: archrelocvariant,
|
||||||
Asmb: asmb,
|
Asmb: asmb,
|
||||||
Asmb2: asmb2,
|
Asmb2: asmb2,
|
||||||
Elfreloc1: elfreloc1,
|
Elfreloc1: elfreloc1,
|
||||||
Elfsetupplt: elfsetupplt,
|
Elfsetupplt: elfsetupplt,
|
||||||
Gentext2: gentext2,
|
Gentext2: gentext2,
|
||||||
Trampoline: trampoline,
|
Trampoline: trampoline,
|
||||||
Machoreloc1: machoreloc1,
|
Machoreloc1: machoreloc1,
|
||||||
Xcoffreloc1: xcoffreloc1,
|
Xcoffreloc1: xcoffreloc1,
|
||||||
|
|
||||||
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
|
// TODO(austin): ABI v1 uses /usr/lib/ld.so.1,
|
||||||
Linuxdynld: "/lib64/ld64.so.1",
|
Linuxdynld: "/lib64/ld64.so.1",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user