mirror of
https://github.com/golang/go
synced 2024-11-23 23:00:03 -07:00
[dev.link] cmd/link: support new dodata for PPC64
Add linux/{ppc64,ppc64le} and aix/ppc64 arch support for the new dodata() phase. This completes the picture in terms of architecture support for the new dodata(), but to be safe this patch leaves the command line flag in place there are problems on the builders (especially given that we have a dead aix-ppc64 builder). Change-Id: I78da615c3b540d8925ed7b3226e199280eb7451d Reviewed-on: https://go-review.googlesource.com/c/go/+/229983 Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
a742d0ed5f
commit
8bd7c01417
@ -200,24 +200,6 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
bench.Start("Archinit")
|
||||
thearch.Archinit(ctxt)
|
||||
|
||||
if *flagnewDoData {
|
||||
// New dodata() is currently only implemented for selected targets.
|
||||
switch {
|
||||
case ctxt.IsElf():
|
||||
switch {
|
||||
case ctxt.Is386(), ctxt.IsAMD64(), ctxt.IsARM(), ctxt.IsARM64(),
|
||||
ctxt.IsMIPS(), ctxt.IsMIPS64(), ctxt.IsRISCV64(), ctxt.IsS390X():
|
||||
// supported
|
||||
default:
|
||||
*flagnewDoData = false
|
||||
}
|
||||
case ctxt.IsDarwin(), ctxt.IsPlan9(), ctxt.IsWasm():
|
||||
// supported
|
||||
default:
|
||||
*flagnewDoData = false
|
||||
}
|
||||
}
|
||||
|
||||
if ctxt.linkShared && !ctxt.IsELF {
|
||||
Exitf("-linkshared can only be used on elf systems")
|
||||
}
|
||||
|
@ -360,7 +360,8 @@ type XcoffLdRel64 struct {
|
||||
// xcoffLoaderReloc holds information about a relocation made by the loader.
|
||||
type xcoffLoaderReloc struct {
|
||||
sym *sym.Symbol
|
||||
rel *sym.Reloc
|
||||
sym2 loader.Sym
|
||||
roff int32
|
||||
rtype uint16
|
||||
symndx int32
|
||||
}
|
||||
@ -1108,51 +1109,55 @@ func (f *xcoffFile) adddynimpsym(ctxt *Link, s loader.Sym) {
|
||||
|
||||
// Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
|
||||
// This relocation will be made by the loader.
|
||||
func Xcoffadddynrel(target *Target, ldr *loader.Loader, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
func Xcoffadddynrel2(target *Target, ldr *loader.Loader, syms *ArchSyms, s loader.Sym, r *loader.Reloc2, rIdx int) bool {
|
||||
if target.IsExternal() {
|
||||
return true
|
||||
}
|
||||
if s.Type <= sym.SPCLNTAB {
|
||||
Errorf(s, "cannot have a relocation to %s in a text section symbol", r.Sym.Name)
|
||||
if ldr.SymType(s) <= sym.SPCLNTAB {
|
||||
ldr.Errorf(s, "cannot have a relocation to %s in a text section symbol", ldr.SymName(r.Sym()))
|
||||
return false
|
||||
}
|
||||
|
||||
xldr := &xcoffLoaderReloc{
|
||||
sym: s,
|
||||
rel: r,
|
||||
sym2: s,
|
||||
roff: r.Off(),
|
||||
}
|
||||
targ := r.Sym()
|
||||
var targType sym.SymKind
|
||||
if targ != 0 {
|
||||
targType = ldr.SymType(targ)
|
||||
}
|
||||
|
||||
switch r.Type {
|
||||
switch r.Type() {
|
||||
default:
|
||||
Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", r.Sym.Name, r.Type.String())
|
||||
ldr.Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", ldr.SymName(targ), r.Type().String())
|
||||
return false
|
||||
case objabi.R_ADDR:
|
||||
if s.Type == sym.SXCOFFTOC && r.Sym.Type == sym.SDYNIMPORT {
|
||||
if ldr.SymType(s) == sym.SXCOFFTOC && targType == sym.SDYNIMPORT {
|
||||
// Imported symbol relocation
|
||||
for i, dynsym := range xfile.loaderSymbols {
|
||||
if ldr.Syms[dynsym.sym].Name == r.Sym.Name {
|
||||
if ldr.SymName(dynsym.sym) == ldr.SymName(targ) {
|
||||
xldr.symndx = int32(i + 3) // +3 because of 3 section symbols
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if s.Type == sym.SDATA {
|
||||
switch r.Sym.Sect.Seg {
|
||||
} else if ldr.SymType(s) == sym.SDATA {
|
||||
switch ldr.SymSect(targ).Seg {
|
||||
default:
|
||||
Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name)
|
||||
ldr.Errorf(s, "unknown segment for .loader relocation with symbol %s", ldr.SymName(targ))
|
||||
case &Segtext:
|
||||
case &Segrodata:
|
||||
xldr.symndx = 0 // .text
|
||||
case &Segdata:
|
||||
if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS {
|
||||
if targType == sym.SBSS || targType == sym.SNOPTRBSS {
|
||||
xldr.symndx = 2 // .bss
|
||||
} else {
|
||||
xldr.symndx = 1 // .data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
Errorf(s, "unexpected type for .loader relocation R_ADDR for symbol %s: %s to %s", r.Sym.Name, s.Type, r.Sym.Type)
|
||||
ldr.Errorf(s, "unexpected type for .loader relocation R_ADDR for symbol %s: %s to %s", ldr.SymName(targ), ldr.SymType(s), ldr.SymType(targ))
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1303,14 +1308,18 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
|
||||
|
||||
off += uint64(16 * len(f.loaderReloc))
|
||||
for _, r := range f.loaderReloc {
|
||||
symp := r.sym
|
||||
if symp == nil {
|
||||
symp = ctxt.loader.Syms[r.sym2]
|
||||
}
|
||||
xldr = &XcoffLdRel64{
|
||||
Lvaddr: uint64(r.sym.Value + int64(r.rel.Off)),
|
||||
Lvaddr: uint64(symp.Value + int64(r.roff)),
|
||||
Lrtype: r.rtype,
|
||||
Lsymndx: r.symndx,
|
||||
}
|
||||
|
||||
if r.sym.Sect != nil {
|
||||
xldr.Lrsecnm = f.getXCOFFscnum(r.sym.Sect)
|
||||
if symp.Sect != nil {
|
||||
xldr.Lrsecnm = f.getXCOFFscnum(symp.Sect)
|
||||
}
|
||||
|
||||
reloctab = append(reloctab, xldr)
|
||||
|
@ -4,7 +4,11 @@
|
||||
|
||||
package ld
|
||||
|
||||
import "cmd/link/internal/sym"
|
||||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
)
|
||||
|
||||
// Temporary dumping around for sym.Symbol version of helper
|
||||
// functions in xcoff.go, still being used for some archs/oses.
|
||||
@ -50,3 +54,60 @@ func xcoffUpdateOuterSize(ctxt *Link, size int64, stype sym.SymKind) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
|
||||
// This relocation will be made by the loader.
|
||||
func Xcoffadddynrel(target *Target, ldr *loader.Loader, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
if target.IsExternal() {
|
||||
return true
|
||||
}
|
||||
if s.Type <= sym.SPCLNTAB {
|
||||
Errorf(s, "cannot have a relocation to %s in a text section symbol", r.Sym.Name)
|
||||
return false
|
||||
}
|
||||
|
||||
xldr := &xcoffLoaderReloc{
|
||||
sym: s,
|
||||
roff: r.Off,
|
||||
}
|
||||
|
||||
switch r.Type {
|
||||
default:
|
||||
Errorf(s, "unexpected .loader relocation to symbol: %s (type: %s)", r.Sym.Name, r.Type.String())
|
||||
return false
|
||||
case objabi.R_ADDR:
|
||||
if s.Type == sym.SXCOFFTOC && r.Sym.Type == sym.SDYNIMPORT {
|
||||
// Imported symbol relocation
|
||||
for i, dynsym := range xfile.loaderSymbols {
|
||||
if ldr.Syms[dynsym.sym].Name == r.Sym.Name {
|
||||
xldr.symndx = int32(i + 3) // +3 because of 3 section symbols
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if s.Type == sym.SDATA {
|
||||
switch r.Sym.Sect.Seg {
|
||||
default:
|
||||
Errorf(s, "unknown segment for .loader relocation with symbol %s", r.Sym.Name)
|
||||
case &Segtext:
|
||||
case &Segrodata:
|
||||
xldr.symndx = 0 // .text
|
||||
case &Segdata:
|
||||
if r.Sym.Type == sym.SBSS || r.Sym.Type == sym.SNOPTRBSS {
|
||||
xldr.symndx = 2 // .bss
|
||||
} else {
|
||||
xldr.symndx = 1 // .data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
Errorf(s, "unexpected type for .loader relocation R_ADDR for symbol %s: %s to %s", r.Sym.Name, s.Type, r.Sym.Type)
|
||||
return false
|
||||
}
|
||||
|
||||
xldr.rtype = 0x3F<<8 + XCOFF_R_POS
|
||||
}
|
||||
|
||||
xfile.loaderReloc = append(xfile.loaderReloc, xldr)
|
||||
return true
|
||||
}
|
||||
|
@ -267,120 +267,134 @@ func gencallstub2(ctxt *ld.Link, ldr *loader.Loader, abicase int, stub *loader.S
|
||||
stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
|
||||
}
|
||||
|
||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
func adddynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r *loader.Reloc2, rIdx int) bool {
|
||||
if target.IsElf() {
|
||||
return addelfdynrel(target, syms, s, r)
|
||||
return addelfdynrel2(target, ldr, syms, s, r, rIdx)
|
||||
} else if target.IsAIX() {
|
||||
return ld.Xcoffadddynrel(target, ldr, s, r)
|
||||
return ld.Xcoffadddynrel2(target, ldr, syms, s, r, rIdx)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func addelfdynrel(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
targ := r.Sym
|
||||
r.InitExt()
|
||||
func addelfdynrel2(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r *loader.Reloc2, rIdx int) bool {
|
||||
targ := r.Sym()
|
||||
var targType sym.SymKind
|
||||
if targ != 0 {
|
||||
targType = ldr.SymType(targ)
|
||||
}
|
||||
|
||||
switch r.Type {
|
||||
switch r.Type() {
|
||||
default:
|
||||
if r.Type >= objabi.ElfRelocOffset {
|
||||
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
|
||||
if r.Type() >= objabi.ElfRelocOffset {
|
||||
ldr.Errorf(s, "unexpected relocation type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type()))
|
||||
return false
|
||||
}
|
||||
|
||||
// Handle relocations found in ELF object files.
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
|
||||
r.Type = objabi.R_CALLPOWER
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_CALLPOWER)
|
||||
|
||||
// This is a local call, so the caller isn't setting
|
||||
// up r12 and r2 is the same for the caller and
|
||||
// callee. Hence, we need to go to the local entry
|
||||
// point. (If we don't do this, the callee will try
|
||||
// to use r12 to compute r2.)
|
||||
r.Add += int64(r.Sym.Localentry()) * 4
|
||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymLocalentry(targ))*4)
|
||||
|
||||
if targ.Type == sym.SDYNIMPORT {
|
||||
if targType == sym.SDYNIMPORT {
|
||||
// Should have been handled in elfsetupplt
|
||||
ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
|
||||
ldr.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC_REL32):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Add += 4
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||
su.SetRelocAdd(rIdx, r.Add()+4)
|
||||
|
||||
if targ.Type == sym.SDYNIMPORT {
|
||||
ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
|
||||
if targType == sym.SDYNIMPORT {
|
||||
ldr.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_ADDR64):
|
||||
r.Type = objabi.R_ADDR
|
||||
if targ.Type == sym.SDYNIMPORT {
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_ADDR)
|
||||
if targType == sym.SDYNIMPORT {
|
||||
// These happen in .toc sections
|
||||
ld.Adddynsym(target, syms, targ)
|
||||
ld.Adddynsym2(ldr, target, syms, targ)
|
||||
|
||||
rela := syms.Rela
|
||||
rela.AddAddrPlus(target.Arch, s, int64(r.Off))
|
||||
rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
|
||||
rela.AddUint64(target.Arch, uint64(r.Add))
|
||||
r.Type = objabi.ElfRelocOffset // ignore during relocsym
|
||||
rela := ldr.MakeSymbolUpdater(syms.Rela2)
|
||||
rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
|
||||
rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_PPC64_ADDR64)))
|
||||
rela.AddUint64(target.Arch, uint64(r.Add()))
|
||||
su.SetRelocType(rIdx, objabi.ElfRelocOffset) // ignore during relocsym
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_POWER_TOC)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_LO|sym.RV_CHECK_OVERFLOW)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_LO
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_POWER_TOC)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_LO)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HA):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_POWER_TOC)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HI):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_POWER_TOC)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HI|sym.RV_CHECK_OVERFLOW)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_DS):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_POWER_TOC)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_DS|sym.RV_CHECK_OVERFLOW)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_DS
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_POWER_TOC)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_DS)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_LO):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_POWER_LO
|
||||
r.Add += 2 // Compensate for relocation size of 2
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_LO)
|
||||
su.SetRelocAdd(rIdx, r.Add()+2) // Compensate for relocation size of 2
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HI):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
|
||||
r.Add += 2
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HI|sym.RV_CHECK_OVERFLOW)
|
||||
su.SetRelocAdd(rIdx, r.Add()+2)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HA):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
|
||||
r.Add += 2
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_PCREL)
|
||||
ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
|
||||
su.SetRelocAdd(rIdx, r.Add()+2)
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle references to ELF symbols from our own object files.
|
||||
if targ.Type != sym.SDYNIMPORT {
|
||||
if targType != sym.SDYNIMPORT {
|
||||
return true
|
||||
}
|
||||
|
||||
|
140
src/cmd/link/internal/ppc64/asm2.go
Normal file
140
src/cmd/link/internal/ppc64/asm2.go
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright 2020 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 ppc64
|
||||
|
||||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
)
|
||||
|
||||
// Temporary dumping ground for sym.Symbol version of helper
|
||||
// functions in asm.go, still being used for some oses.
|
||||
// FIXME: get rid of this file when dodata() is completely
|
||||
// converted.
|
||||
|
||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
if target.IsElf() {
|
||||
return addelfdynrel(target, syms, s, r)
|
||||
} else if target.IsAIX() {
|
||||
return ld.Xcoffadddynrel(target, ldr, s, r)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func addelfdynrel(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
targ := r.Sym
|
||||
r.InitExt()
|
||||
|
||||
switch r.Type {
|
||||
default:
|
||||
if r.Type >= objabi.ElfRelocOffset {
|
||||
ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
|
||||
return false
|
||||
}
|
||||
|
||||
// Handle relocations found in ELF object files.
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
|
||||
r.Type = objabi.R_CALLPOWER
|
||||
|
||||
// This is a local call, so the caller isn't setting
|
||||
// up r12 and r2 is the same for the caller and
|
||||
// callee. Hence, we need to go to the local entry
|
||||
// point. (If we don't do this, the callee will try
|
||||
// to use r12 to compute r2.)
|
||||
r.Add += int64(r.Sym.Localentry()) * 4
|
||||
|
||||
if targ.Type == sym.SDYNIMPORT {
|
||||
// Should have been handled in elfsetupplt
|
||||
ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC_REL32):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Add += 4
|
||||
|
||||
if targ.Type == sym.SDYNIMPORT {
|
||||
ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_ADDR64):
|
||||
r.Type = objabi.R_ADDR
|
||||
if targ.Type == sym.SDYNIMPORT {
|
||||
// These happen in .toc sections
|
||||
ld.Adddynsym(target, syms, targ)
|
||||
|
||||
rela := syms.Rela
|
||||
rela.AddAddrPlus(target.Arch, s, int64(r.Off))
|
||||
rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
|
||||
rela.AddUint64(target.Arch, uint64(r.Add))
|
||||
r.Type = objabi.ElfRelocOffset // ignore during relocsym
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_LO | sym.RV_CHECK_OVERFLOW
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_LO
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HA):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HI):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_DS):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_DS | sym.RV_CHECK_OVERFLOW
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
|
||||
r.Type = objabi.R_POWER_TOC
|
||||
r.Variant = sym.RV_POWER_DS
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_LO):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_POWER_LO
|
||||
r.Add += 2 // Compensate for relocation size of 2
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HI):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_POWER_HI | sym.RV_CHECK_OVERFLOW
|
||||
r.Add += 2
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HA):
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Variant = sym.RV_POWER_HA | sym.RV_CHECK_OVERFLOW
|
||||
r.Add += 2
|
||||
return true
|
||||
}
|
||||
|
||||
// Handle references to ELF symbols from our own object files.
|
||||
if targ.Type != sym.SDYNIMPORT {
|
||||
return true
|
||||
}
|
||||
|
||||
// TODO(austin): Translate our relocations to ELF
|
||||
|
||||
return false
|
||||
}
|
@ -50,6 +50,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Dwarfreglr: dwarfRegLR,
|
||||
|
||||
Adddynrel: adddynrel,
|
||||
Adddynrel2: adddynrel2,
|
||||
Archinit: archinit,
|
||||
Archreloc: archreloc,
|
||||
Archrelocvariant: archrelocvariant,
|
||||
|
Loading…
Reference in New Issue
Block a user