case 0:
// No local entry. R2 is preserved.
case 1:
- // These require R2 be saved and restored by the caller. This isn't supported today.
- return errorf("%s: unable to handle local entry type 1", sb.Name())
+ // This is kind of a hack, but pass the hint about this symbol's
+ // usage of R2 (R2 is a caller-save register not a TOC pointer, and
+ // this function does not have a distinct local entry) by setting
+ // its SymLocalentry to 1.
+ l.SetSymLocalentry(s, 1)
case 7:
return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other)
default:
+ // Convert the word sized offset into bytes.
l.SetSymLocalentry(s, 4<<uint(flag-2))
}
}
I386 | uint32(elf.R_386_GOTPC)<<16,
I386 | uint32(elf.R_386_GOT32X)<<16,
PPC64 | uint32(elf.R_PPC64_REL24)<<16,
+ PPC64 | uint32(elf.R_PPC64_REL24_NOTOC)<<16,
PPC64 | uint32(elf.R_PPC_REL32)<<16,
S390X | uint32(elf.R_390_32)<<16,
S390X | uint32(elf.R_390_PC32)<<16,
ARM64 | uint32(elf.R_AARCH64_ABS64)<<16,
ARM64 | uint32(elf.R_AARCH64_PREL64)<<16,
PPC64 | uint32(elf.R_PPC64_ADDR64)<<16,
+ PPC64 | uint32(elf.R_PPC64_PCREL34)<<16,
+ PPC64 | uint32(elf.R_PPC64_GOT_PCREL34)<<16,
+ PPC64 | uint32(elf.R_PPC64_PLT_PCREL34_NOTOC)<<16,
S390X | uint32(elf.R_390_GLOB_DAT)<<16,
S390X | uint32(elf.R_390_RELATIVE)<<16,
S390X | uint32(elf.R_390_GOTOFF)<<16,
// Turn this reloc into an R_CALLPOWER, and convert the TOC restore into a nop.
su.SetRelocType(i, objabi.R_CALLPOWER)
- su.SetRelocAdd(i, r.Add()+int64(ldr.SymLocalentry(r.Sym())))
+ localEoffset := int64(ldr.SymLocalentry(r.Sym()))
+ if localEoffset == 1 {
+ ldr.Errorf(s, "Unsupported NOTOC call to %s", ldr.SymName(r.Sym()))
+ }
+ su.SetRelocAdd(i, r.Add()+localEoffset)
r.SetSiz(4)
rewritetonop(&ctxt.Target, ldr, su, int64(r.Off()+4), 0xFFFFFFFF, OP_TOCRESTORE)
}
// 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.)
- su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymLocalentry(targ)))
+ localEoffset := int64(ldr.SymLocalentry(targ))
+ if localEoffset == 1 {
+ ldr.Errorf(s, "Unsupported NOTOC call to %s", targ)
+ }
+ su.SetRelocAdd(rIdx, r.Add()+localEoffset)
if targType == sym.SDYNIMPORT {
// Should have been handled in elfsetupplt