mirror of
https://github.com/golang/go.git
synced 2025-10-19 19:13:18 +00:00
cmd/link/internal: add support for internal linking on loong64
Change-Id: Ic0d36f27481ac707d04aaf7001f26061e510dd8f Reviewed-on: https://go-review.googlesource.com/c/go/+/533716 Reviewed-by: Qiqi Huang <huangqiqi@loongson.cn> Reviewed-by: sophie zhao <zhaoxiaolin@loongson.cn> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: abner chenc <chenguoqi@loongson.cn> Reviewed-by: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
42f9ee904c
commit
f212b6499a
2 changed files with 375 additions and 5 deletions
|
@ -610,6 +610,11 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
|
|||
// See issue 73591.
|
||||
continue
|
||||
}
|
||||
|
||||
if arch.Family == sys.Loong64 && (strings.HasPrefix(elfsym.name, ".L") || elfsym.name == "L0\001") {
|
||||
// Symbols generated by the relax feature of gcc and binutils on loong64.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(elfsym.name, ".Linfo_string") {
|
||||
|
@ -690,6 +695,12 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
|
|||
l.SetAttrOnList(s, true)
|
||||
textp = append(textp, s)
|
||||
for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) {
|
||||
if arch.Family == sys.Loong64 && (strings.HasPrefix(l.SymName(ss), ".L") || l.SymName(ss) == "L0\001") {
|
||||
// Symbols generated by the relax feature of gcc and binutils on loong64.
|
||||
// We ignore them here because there are too many symbols of this type,
|
||||
// resulting in insufficient space in findfunctable.
|
||||
continue
|
||||
}
|
||||
if l.AttrOnList(ss) {
|
||||
return errorf("symbol %s listed multiple times",
|
||||
l.SymName(ss))
|
||||
|
@ -1026,7 +1037,14 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
|
|||
MIPS64 | uint32(elf.R_MIPS_PC32)<<16:
|
||||
return 4, 4, nil
|
||||
|
||||
// These are informational annotations to assist linker optimizations.
|
||||
case LOONG64 | uint32(elf.R_LARCH_ALIGN)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_RELAX)<<16:
|
||||
return 0, 0, nil
|
||||
|
||||
case LOONG64 | uint32(elf.R_LARCH_ADD8)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_ADD6)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_SUB6)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_SUB8)<<16:
|
||||
return 1, 1, nil
|
||||
|
||||
|
@ -1040,7 +1058,13 @@ func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) {
|
|||
LOONG64 | uint32(elf.R_LARCH_ADD32)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_SUB24)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_SUB32)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_B16)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_B21)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_B26)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_PCALA_HI20)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_PCALA_LO12)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_GOT_PC_HI20)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_GOT_PC_LO12)<<16,
|
||||
LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16:
|
||||
return 4, 4, nil
|
||||
|
||||
|
|
|
@ -58,8 +58,326 @@ func gentext(ctxt *ld.Link, ldr *loader.Loader) {
|
|||
}
|
||||
|
||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
|
||||
log.Fatalf("adddynrel not implemented")
|
||||
targ := r.Sym()
|
||||
var targType sym.SymKind
|
||||
if targ != 0 {
|
||||
targType = ldr.SymType(targ)
|
||||
}
|
||||
|
||||
switch r.Type() {
|
||||
default:
|
||||
if r.Type() >= objabi.ElfRelocOffset {
|
||||
ldr.Errorf(s, "adddynrel: unexpected reloction type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type()))
|
||||
return false
|
||||
}
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_64):
|
||||
if targType == sym.SDYNIMPORT {
|
||||
ldr.Errorf(s, "unexpected R_LARCH_64 relocation for dynamic symbol %s", ldr.SymName(targ))
|
||||
}
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_ADDR)
|
||||
if target.IsPIE() && target.IsInternal() {
|
||||
// For internal linking PIE, this R_ADDR relocation cannot
|
||||
// be resolved statically. We need to generate a dynamic
|
||||
// relocation. Let the code below handle it.
|
||||
break
|
||||
}
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B26):
|
||||
if targType == sym.SDYNIMPORT {
|
||||
addpltsym(target, ldr, syms, targ)
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocSym(rIdx, syms.PLT)
|
||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
|
||||
}
|
||||
if targType == 0 || targType == sym.SXREF {
|
||||
ldr.Errorf(s, "unknown symbol %s in callloong64", ldr.SymName(targ))
|
||||
}
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocType(rIdx, objabi.R_CALLLOONG64)
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_HI20),
|
||||
objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_GOT_PC_LO12):
|
||||
if targType != sym.SDYNIMPORT {
|
||||
// TODO: turn LDR of GOT entry into ADR of symbol itself
|
||||
}
|
||||
|
||||
ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64))
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_GOT_PC_HI20) {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI)
|
||||
} else {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO)
|
||||
}
|
||||
su.SetRelocSym(rIdx, syms.GOT)
|
||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA_HI20),
|
||||
objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_PCALA_LO12):
|
||||
if targType == sym.SDYNIMPORT {
|
||||
ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ))
|
||||
}
|
||||
if targType == 0 || targType == sym.SXREF {
|
||||
ldr.Errorf(s, "unknown symbol %s", ldr.SymName(targ))
|
||||
}
|
||||
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_PCALA_HI20) {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI)
|
||||
} else {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO)
|
||||
}
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_ADD64),
|
||||
objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_SUB64):
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_ADD64) {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADD64)
|
||||
} else {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_SUB64)
|
||||
}
|
||||
return true
|
||||
|
||||
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B16),
|
||||
objabi.ElfRelocOffset + objabi.RelocType(elf.R_LARCH_B21):
|
||||
if targType == sym.SDYNIMPORT {
|
||||
addpltsym(target, ldr, syms, targ)
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocSym(rIdx, syms.PLT)
|
||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymPlt(targ)))
|
||||
}
|
||||
if targType == 0 || targType == sym.SXREF {
|
||||
ldr.Errorf(s, "unknown symbol %s in R_JMPxxLOONG64", ldr.SymName(targ))
|
||||
}
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
if r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_LARCH_B16) {
|
||||
su.SetRelocType(rIdx, objabi.R_JMP16LOONG64)
|
||||
} else {
|
||||
su.SetRelocType(rIdx, objabi.R_JMP21LOONG64)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
relocs := ldr.Relocs(s)
|
||||
r = relocs.At(rIdx)
|
||||
|
||||
switch r.Type() {
|
||||
case objabi.R_CALLLOONG64:
|
||||
if targType != sym.SDYNIMPORT {
|
||||
return true
|
||||
}
|
||||
if target.IsExternal() {
|
||||
return true
|
||||
}
|
||||
|
||||
// Internal linking.
|
||||
if r.Add() != 0 {
|
||||
ldr.Errorf(s, "PLT call with no-zero addend (%v)", r.Add())
|
||||
}
|
||||
|
||||
// Build a PLT entry and change the relocation target to that entry.
|
||||
addpltsym(target, ldr, syms, targ)
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocSym(rIdx, syms.PLT)
|
||||
su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
|
||||
return true
|
||||
|
||||
case objabi.R_ADDR:
|
||||
if ldr.SymType(s) == sym.STEXT && target.IsElf() {
|
||||
// The code is asking for the address of an external
|
||||
// function. We provide it with the address of the
|
||||
// correspondent GOT symbol.
|
||||
ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64))
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
su.SetRelocSym(rIdx, syms.GOT)
|
||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
|
||||
return true
|
||||
}
|
||||
|
||||
// Process dynamic relocations for the data sections.
|
||||
if target.IsPIE() && target.IsInternal() {
|
||||
// When internally linking, generate dynamic relocations
|
||||
// for all typical R_ADDR relocations. The exception
|
||||
// are those R_ADDR that are created as part of generating
|
||||
// the dynamic relocations and must be resolved statically.
|
||||
//
|
||||
// There are three phases relevant to understanding this:
|
||||
//
|
||||
// dodata() // we are here
|
||||
// address() // symbol address assignment
|
||||
// reloc() // resolution of static R_ADDR relocs
|
||||
//
|
||||
// At this point symbol addresses have not been
|
||||
// assigned yet (as the final size of the .rela section
|
||||
// will affect the addresses), and so we cannot write
|
||||
// the Elf64_Rela.r_offset now. Instead we delay it
|
||||
// until after the 'address' phase of the linker is
|
||||
// complete. We do this via Addaddrplus, which creates
|
||||
// a new R_ADDR relocation which will be resolved in
|
||||
// the 'reloc' phase.
|
||||
//
|
||||
// These synthetic static R_ADDR relocs must be skipped
|
||||
// now, or else we will be caught in an infinite loop
|
||||
// of generating synthetic relocs for our synthetic
|
||||
// relocs.
|
||||
//
|
||||
// Furthermore, the rela sections contain dynamic
|
||||
// relocations with R_ADDR relocations on
|
||||
// Elf64_Rela.r_offset. This field should contain the
|
||||
// symbol offset as determined by reloc(), not the
|
||||
// final dynamically linked address as a dynamic
|
||||
// relocation would provide.
|
||||
switch ldr.SymName(s) {
|
||||
case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic":
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// Either internally linking a static executable,
|
||||
// in which case we can resolve these relocations
|
||||
// statically in the 'reloc' phase, or externally
|
||||
// linking, in which case the relocation will be
|
||||
// prepared in the 'reloc' phase and passed to the
|
||||
// external linker in the 'asmb' phase.
|
||||
if ldr.SymType(s) != sym.SDATA && ldr.SymType(s) != sym.SRODATA {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if target.IsElf() {
|
||||
// Generate R_LARCH_RELATIVE relocations for best
|
||||
// efficiency in the dynamic linker.
|
||||
//
|
||||
// As noted above, symbol addresses have not been
|
||||
// assigned yet, so we can't generate the final reloc
|
||||
// entry yet. We ultimately want:
|
||||
//
|
||||
// r_offset = s + r.Off
|
||||
// r_info = R_LARCH_RELATIVE
|
||||
// r_addend = targ + r.Add
|
||||
//
|
||||
// The dynamic linker will set *offset = base address +
|
||||
// addend.
|
||||
//
|
||||
// AddAddrPlus is used for r_offset and r_addend to
|
||||
// generate new R_ADDR relocations that will update
|
||||
// these fields in the 'reloc' phase.
|
||||
rela := ldr.MakeSymbolUpdater(syms.Rela)
|
||||
rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
|
||||
if r.Siz() == 8 {
|
||||
rela.AddUint64(target.Arch, elf.R_INFO(0, uint32(elf.R_LARCH_RELATIVE)))
|
||||
} else {
|
||||
ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ))
|
||||
}
|
||||
rela.AddAddrPlus(target.Arch, targ, int64(r.Add()))
|
||||
return true
|
||||
}
|
||||
|
||||
case objabi.R_LOONG64_GOT_HI,
|
||||
objabi.R_LOONG64_GOT_LO:
|
||||
ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_LARCH_64))
|
||||
su := ldr.MakeSymbolUpdater(s)
|
||||
if r.Type() == objabi.R_LOONG64_GOT_HI {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_HI)
|
||||
} else {
|
||||
su.SetRelocType(rIdx, objabi.R_LOONG64_ADDR_LO)
|
||||
}
|
||||
su.SetRelocSym(rIdx, syms.GOT)
|
||||
su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// pcalau12i $r14, imm
|
||||
plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_LOONG64_ADDR_HI, 4)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x1a00000e)
|
||||
|
||||
// sub.d $r13, $r13, $r15
|
||||
plt.AddUint32(ctxt.Arch, 0x0011bdad)
|
||||
|
||||
// ld.d $r15, $r14, imm
|
||||
plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_LOONG64_ADDR_LO, 4)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x28c001cf)
|
||||
|
||||
// addi.d $r13, $r13, -40
|
||||
plt.AddUint32(ctxt.Arch, 0x02ff61ad)
|
||||
|
||||
// addi.d $r12, $r14, imm
|
||||
plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 0, objabi.R_LOONG64_ADDR_LO, 4)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x2c001cc)
|
||||
|
||||
// srli.d $r13, $r13, 1
|
||||
plt.AddUint32(ctxt.Arch, 0x004505ad)
|
||||
|
||||
// ld.d $r12, $r12, 8
|
||||
plt.AddUint32(ctxt.Arch, 0x28c0218c)
|
||||
|
||||
// jirl $r0, $r15, 0
|
||||
plt.AddUint32(ctxt.Arch, 0x4c0001e0)
|
||||
|
||||
// check gotplt.size == 0
|
||||
if gotplt.Size() != 0 {
|
||||
ctxt.Errorf(gotplt.Sym(), "got.plt is not empty at the very beginning")
|
||||
}
|
||||
|
||||
gotplt.AddUint64(ctxt.Arch, 0)
|
||||
gotplt.AddUint64(ctxt.Arch, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func addpltsym(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) {
|
||||
if ldr.SymPlt(s) >= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
ld.Adddynsym(ldr, target, syms, s)
|
||||
|
||||
if target.IsElf() {
|
||||
plt := ldr.MakeSymbolUpdater(syms.PLT)
|
||||
gotplt := ldr.MakeSymbolUpdater(syms.GOTPLT)
|
||||
rela := ldr.MakeSymbolUpdater(syms.RelaPLT)
|
||||
if plt.Size() == 0 {
|
||||
panic("plt is not set up")
|
||||
}
|
||||
|
||||
// pcalau12i $r15, imm
|
||||
plt.AddAddrPlus4(target.Arch, gotplt.Sym(), gotplt.Size())
|
||||
plt.SetUint32(target.Arch, plt.Size()-4, 0x1a00000f)
|
||||
relocs := plt.Relocs()
|
||||
plt.SetRelocType(relocs.Count()-1, objabi.R_LOONG64_ADDR_HI)
|
||||
|
||||
// ld.d $r15, $r15, imm
|
||||
plt.AddAddrPlus4(target.Arch, gotplt.Sym(), gotplt.Size())
|
||||
plt.SetUint32(target.Arch, plt.Size()-4, 0x28c001ef)
|
||||
relocs = plt.Relocs()
|
||||
plt.SetRelocType(relocs.Count()-1, objabi.R_LOONG64_ADDR_LO)
|
||||
|
||||
// pcaddu12i $r13, 0
|
||||
plt.AddUint32(target.Arch, 0x1c00000d)
|
||||
|
||||
// jirl r0, r15, 0
|
||||
plt.AddUint32(target.Arch, 0x4c0001e0)
|
||||
|
||||
// add to got.plt: pointer to plt[0]
|
||||
gotplt.AddAddrPlus(target.Arch, plt.Sym(), 0)
|
||||
|
||||
// rela
|
||||
rela.AddAddrPlus(target.Arch, gotplt.Sym(), gotplt.Size()-8)
|
||||
sDynid := ldr.SymDynid(s)
|
||||
rela.AddUint64(target.Arch, elf.R_INFO(uint32(sDynid), uint32(elf.R_LARCH_JUMP_SLOT)))
|
||||
rela.AddUint64(target.Arch, 0)
|
||||
|
||||
ldr.SetPlt(s, int32(plt.Size()-16))
|
||||
} else {
|
||||
ldr.Errorf(s, "addpltsym: unsupport binary format")
|
||||
}
|
||||
}
|
||||
|
||||
func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool {
|
||||
|
@ -134,10 +452,6 @@ func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
|
|||
return true
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, ldr *loader.Loader, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
return
|
||||
}
|
||||
|
||||
func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool {
|
||||
return false
|
||||
}
|
||||
|
@ -197,6 +511,38 @@ func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loade
|
|||
pc := ldr.SymValue(s) + int64(r.Off())
|
||||
t := ldr.SymAddr(rs) + r.Add() - pc
|
||||
return int64(val&0xfc000000 | (((t >> 2) & 0xffff) << 10) | (((t >> 2) & 0x3ff0000) >> 16)), noExtReloc, isOk
|
||||
|
||||
case objabi.R_JMP16LOONG64,
|
||||
objabi.R_JMP21LOONG64:
|
||||
pc := ldr.SymValue(s) + int64(r.Off())
|
||||
t := ldr.SymAddr(rs) + r.Add() - pc
|
||||
if r.Type() == objabi.R_JMP16LOONG64 {
|
||||
return int64(val&0xfc0003ff | (((t >> 2) & 0xffff) << 10)), noExtReloc, isOk
|
||||
}
|
||||
return int64(val&0xfc0003e0 | (((t >> 2) & 0xffff) << 10) | (((t >> 2) & 0x1f0000) >> 16)), noExtReloc, isOk
|
||||
|
||||
case objabi.R_LOONG64_TLS_IE_HI,
|
||||
objabi.R_LOONG64_TLS_IE_LO:
|
||||
if target.IsPIE() && target.IsElf() {
|
||||
if !target.IsLinux() {
|
||||
ldr.Errorf(s, "TLS reloc on unsupported OS %v", target.HeadType)
|
||||
}
|
||||
t := ldr.SymAddr(rs) + r.Add()
|
||||
if r.Type() == objabi.R_LOONG64_TLS_IE_HI {
|
||||
// pcalau12i -> lu12i.w
|
||||
return (0x14000000 | (val & 0x1f) | ((t >> 12) << 5)), noExtReloc, isOk
|
||||
}
|
||||
// ld.d -> ori
|
||||
return (0x03800000 | (val & 0x3ff) | ((t & 0xfff) << 10)), noExtReloc, isOk
|
||||
} else {
|
||||
log.Fatalf("cannot handle R_LOONG64_TLS_IE_x (sym %s) when linking internally", ldr.SymName(rs))
|
||||
}
|
||||
|
||||
case objabi.R_LOONG64_ADD64, objabi.R_LOONG64_SUB64:
|
||||
if r.Type() == objabi.R_LOONG64_ADD64 {
|
||||
return int64(val + ldr.SymAddr(rs) + r.Add()), noExtReloc, isOk
|
||||
}
|
||||
return int64(val - (ldr.SymAddr(rs) + r.Add())), noExtReloc, isOk
|
||||
}
|
||||
|
||||
return val, 0, false
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue