gnome-shell cores dump on sparc when mesa is build with llvm without this.
|
(to be submitted to upstream).
|
|
------------ lwp# 1 / thread# 1 ---------------
|
00000000e7a01a84 fail (e7a017d8, 21, e7a017b0, 1d, f71a7cee, 0) + 108 (ssp.c:169)
|
00000000e7a01ad8 __stack_chk_fail (ff000000, ff000000, ff000000, 0, f3e29970, f3e33d44) + 28
|
00000000ea6c6328 llvm::RuntimeDyldELF::resolveRelocation(const llvm::SectionEntry&,unsigned long,unsignedlong,unsigned,long,unsigned long,unsigned) (3cd2e10, 3cd2ee8, 20, f30a6000, 6, 0) + 1c0
|
00000000ea6c639c llvm::RuntimeDyldELF::resolveRelocation(const llvm::RelocationEntry&,unsigned long) (3cd2e10, 3ee67d8, f30a6000, 0, 0, e7b04430) + 64
|
00000000ea6ab3e0 llvm::RuntimeDyldImpl::resolveRelocationList(const llvm::SmallVector<llvm::RelocationEntry, (unsigned)64>&,unsigned long) (3cd2e10, 3ee67c0, f30a6000, e7b04430, 0, 38) + e0
|
00000000ea6af60c llvm::RuntimeDyldImpl::resolveRelocations() (3cd2e10, 6, 1, e7b04430, 3cd42d0, 3ee67b0) + 2dc
|
00000000ea6af888 llvm::RuntimeDyld::resolveRelocations() (3e13038, 3d801a0, 3fa49a0, 3fa49b0, e7b04430, e7b04430) + 30
|
|
--- llvm-13.0.0.src/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
|
+++ llvm-13.0.0.src/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
|
@@ -87,3 +87,8 @@
|
ELF_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82)
|
ELF_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83)
|
ELF_RELOC(R_SPARC_GOTDATA_OP, 84)
|
+ELF_RELOC(R_SPARC_H34, 85)
|
+ELF_RELOC(R_SPARC_SIZE32, 86)
|
+ELF_RELOC(R_SPARC_SIZE64, 87)
|
+ELF_RELOC(R_SPARC_WDISP10, 88)
|
+ELF_RELOC(R_SPARC_NUM, 89)
|
--- llvm-13.0.0.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h.~1~ 2021-09-24 19:18:10.000000000 +0000
|
+++ llvm-13.0.0.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h 2022-01-02 14:26:31.003875610 +0000
|
@@ -109,6 +109,11 @@
|
assert(StubOffset <= AllocationSize && "Not enough space allocated!");
|
}
|
|
+ void setStubOffset(unsigned Value) {
|
+ StubOffset = Value;
|
+ assert(StubOffset <= AllocationSize && "Not enough space allocated!");
|
+ }
|
+
|
uintptr_t getObjAddress() const { return ObjAddress; }
|
};
|
|
--- llvm-13.0.0.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h.~1~ 2021-09-24 19:18:10.000000000 +0000
|
+++ llvm-13.0.0.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h 2022-01-02 14:26:31.004157633 +0000
|
@@ -54,6 +54,14 @@
|
void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,
|
uint64_t Value, uint32_t Type, int64_t Addend);
|
|
+ void resolveSPARC3264Relocation(const SectionEntry &Section,
|
+ uint64_t Offset, uint64_t Value,
|
+ uint32_t Type, int32_t Addend);
|
+
|
+ void resolveSPARC64Relocation(const SectionEntry &Section,
|
+ uint64_t Offset, uint64_t Value,
|
+ uint32_t Type, int64_t Addend);
|
+
|
void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
|
uint64_t Value, uint32_t Type, int64_t Addend);
|
|
@@ -71,6 +79,10 @@
|
return 32;
|
else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
|
return 44;
|
+ else if (Arch == Triple::sparc)
|
+ return 16;
|
+ else if (Arch == Triple::sparcv9)
|
+ return 32;
|
else if (Arch == Triple::x86_64)
|
return 6; // 2-byte jmp instruction + 32-bit relative address
|
else if (Arch == Triple::systemz)
|
--- llvm-13.0.0.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp.~1~ 2021-09-24 19:18:10.000000000 +0000
|
+++ llvm-13.0.0.src/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp 2022-01-02 14:26:31.005058486 +0000
|
@@ -887,6 +887,448 @@
|
}
|
}
|
|
+/// SPARC ELF Relocations - common to 32-bit and 64-bit.
|
+/// https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-24/index.html
|
+void RuntimeDyldELF::resolveSPARC3264Relocation(const SectionEntry &Section,
|
+ uint64_t Offset,
|
+ uint64_t Value,
|
+ uint32_t Type,
|
+ int32_t Addend) {
|
+ uint64_t *TargetAddress =
|
+ reinterpret_cast<uint64_t*>(reinterpret_cast<void*>(Section.getAddress()));
|
+ uint64_t *TargetPtr =
|
+ reinterpret_cast<uint64_t*>(Section.getAddressWithOffset(Offset));
|
+ uint32_t Reloc = 0U;
|
+ uint8_t *TargetPtr8 = nullptr;
|
+ uint16_t *TargetPtr16 = nullptr;
|
+ uint32_t *TargetPtr32 = nullptr;
|
+ uint32_t LoadAddress = Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
|
+ uint32_t TargetValue = 0U;
|
+ int32_t RS = 0;
|
+ int32_t RM = 0;
|
+
|
+ switch (Type) {
|
+ default:
|
+ llvm_unreachable("Unimplemented SPARC32 Relocation Type!");
|
+ break;
|
+ case ELF::R_SPARC_NONE:
|
+ break;
|
+ case ELF::R_SPARC_SIZE32:
|
+ *TargetPtr = Section.getSize() + Addend;
|
+ break;
|
+ case ELF::R_SPARC_RELATIVE:
|
+ *TargetPtr = LoadAddress + Addend;
|
+ break;
|
+ case ELF::R_SPARC_COPY:
|
+ Value += Addend;
|
+ (void) std::memcpy(TargetPtr,
|
+ reinterpret_cast<void*>(static_cast<uintptr_t>(Value)),
|
+ Section.getSize());
|
+ break;
|
+ case ELF::R_SPARC_8:
|
+ TargetPtr8 = reinterpret_cast<uint8_t*>(TargetPtr);
|
+ Value += Addend;
|
+ *TargetPtr8 = Value;
|
+ break;
|
+ case ELF::R_SPARC_16:
|
+ TargetPtr16 = reinterpret_cast<uint16_t*>(TargetPtr);
|
+ Value += Addend;
|
+ *TargetPtr16 = Value;
|
+ break;
|
+ case ELF::R_SPARC_32:
|
+ case ELF::R_SPARC_GLOB_DAT:
|
+ Value += Addend;
|
+ *TargetPtr = Value;
|
+ break;
|
+ case ELF::R_SPARC_JMP_SLOT:
|
+ break;
|
+ case ELF::R_SPARC_TLS_DTPOFF32:
|
+ Value += Addend;
|
+ *TargetPtr = Value;
|
+ break;
|
+ case ELF::R_SPARC_TLS_TPOFF32:
|
+ Value += Addend;
|
+ *TargetPtr = Value - Offset;
|
+ break;
|
+ case ELF::R_SPARC_TLS_LE_HIX22:
|
+ Value -= Offset;
|
+ Value += Addend;
|
+ *TargetPtr = (*TargetPtr & 0xFFC00000) | ((~Value) & 0x003FFFFFLL);
|
+ break;
|
+ case ELF::R_SPARC_TLS_LE_LOX10:
|
+ Value -= Offset;
|
+ Value += Addend;
|
+ *TargetPtr = (*TargetPtr & 0xFFFFE000) | (Value & 0x000003FFLL);
|
+ break;
|
+ case ELF::R_SPARC_DISP8:
|
+ Value += Addend;
|
+ TargetPtr8 = reinterpret_cast<uint8_t*>(TargetAddress);
|
+ *TargetPtr8 = (Value - reinterpret_cast<uintptr_t>(TargetPtr8));
|
+ break;
|
+ case ELF::R_SPARC_DISP16:
|
+ Value += Addend;
|
+ TargetPtr16 = reinterpret_cast<uint16_t*>(TargetAddress);
|
+ *TargetPtr16 = (Value - reinterpret_cast<uintptr_t>(TargetPtr16));
|
+ break;
|
+ case ELF::R_SPARC_DISP32:
|
+ Value += Addend;
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetAddress);
|
+ *TargetPtr32 = (Value - reinterpret_cast<uintptr_t>(TargetPtr32));
|
+ break;
|
+ case ELF::R_SPARC_WDISP30:
|
+ case ELF::R_SPARC_WDISP22:
|
+ case ELF::R_SPARC_WDISP19:
|
+ case ELF::R_SPARC_WDISP16:
|
+ case ELF::R_SPARC_WDISP10:
|
+ switch (Type) {
|
+ default:
|
+ llvm_unreachable("Impossible default case!");
|
+ break;
|
+ case ELF::R_SPARC_WDISP30:
|
+ RS = 2;
|
+ RM = 0x3FFFFFFF;
|
+ break;
|
+ case ELF::R_SPARC_WDISP22:
|
+ RS = 2;
|
+ RM = 0x003FFFFF;
|
+ break;
|
+ case ELF::R_SPARC_WDISP19:
|
+ RS = 2;
|
+ RM = 0x0007FFFF;
|
+ break;
|
+ case ELF::R_SPARC_WDISP16:
|
+ RS = 2;
|
+ break;
|
+ case ELF::R_SPARC_WDISP10:
|
+ RS = 2;
|
+ break;
|
+ }
|
+
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ Reloc = (((Value + Addend) - LoadAddress) >> RS);
|
+ TargetValue = *TargetPtr32;
|
+
|
+ switch (Type) {
|
+ default:
|
+ llvm_unreachable("Impossible default case!");
|
+ break;
|
+ case ELF::R_SPARC_WDISP16:
|
+ TargetValue &= ~((0x3 << 20) | 0x3FFF);
|
+ Reloc = (((Reloc & 0xC000) << (7 - 1)) | (Reloc & 0x3FFFF));
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_WDISP10:
|
+ TargetValue &= ~((0x3 << 19) | (0xFF << 5));
|
+ Reloc = (((Reloc & 0x300) << (13 - 2)) | ((Reloc & 0xFF) | (7 - 2)));
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_WDISP30:
|
+ case ELF::R_SPARC_WDISP22:
|
+ case ELF::R_SPARC_WDISP19:
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ }
|
+ break;
|
+ case ELF::R_SPARC_HI22:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 10;
|
+ RM = 0x003FFFFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_10:
|
+ Value += Addend;
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ *TargetPtr32 = Value;
|
+ break;
|
+ case ELF::R_SPARC_11:
|
+ Value += Addend;
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ *TargetPtr32 = Value;
|
+ break;
|
+ case ELF::R_SPARC_13:
|
+ Value += Addend;
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ *TargetPtr32 = Value;
|
+ break;
|
+ case ELF::R_SPARC_22:
|
+ Value += Addend;
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ *TargetPtr32 = Value;
|
+ break;
|
+ case ELF::R_SPARC_LO10:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 0;
|
+ RM = 0x000003FF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_LM22:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 10;
|
+ RM = 0x003FFFFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_HIX22:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 10;
|
+ RM = 0x3FFFFF;
|
+ Reloc = Value + Addend;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc ^= ~0;
|
+ Reloc >>= RS;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_LOX10:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ Reloc = Value + Addend;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~0x1FFF;
|
+ Reloc &= 0x3FF;
|
+ Reloc |= 0x1C00;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_HH22:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 42;
|
+ RM = 0x003FFFFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_HM10:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 32;
|
+ RM = 0x000003FF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_H44:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 22;
|
+ RM = 0x003FFFFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_M44:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 12;
|
+ RM = 0x000003FF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_L44:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 0;
|
+ RM = 0x00000FFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_GOT10:
|
+ assert((Offset != static_cast<uint64_t>(-1)) &&
|
+ "R_SPARC_GOT10: Invalid offset!");
|
+ if ((Offset & 1) != 0)
|
+ Offset &= ~1;
|
+ else
|
+ Offset |= 1;
|
+
|
+ RS = 0;
|
+ RM = 0x000003FF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_GOT13:
|
+ assert((Offset != static_cast<uint64_t>(-1)) &&
|
+ "R_SPARC_GOT13: Invalid offset!");
|
+ if ((Offset & 1) != 0)
|
+ Offset &= ~1;
|
+ else
|
+ Offset |= 1;
|
+
|
+ RS = 0;
|
+ RM = 0x00001FFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_GOT22:
|
+ assert((Offset != static_cast<uint64_t>(-1)) &&
|
+ "R_SPARC_GOT22: Invalid offset!");
|
+ if ((Offset & 1) != 0)
|
+ Offset &= ~1;
|
+ else
|
+ Offset |= 1;
|
+
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 10;
|
+ RM = 0x003FFFFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_PC10:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 0;
|
+ RM =0x000003FF;
|
+ Reloc = ((Value + Addend) - LoadAddress) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_PC22:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 10;
|
+ RM = 0x003FFFFF;
|
+ Reloc = ((Value + Addend) - LoadAddress) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_UA16:
|
+ TargetPtr8 = reinterpret_cast<uint8_t*>(TargetPtr);
|
+ TargetPtr8[0] = Value >> 8U;
|
+ TargetPtr8[1] = Value;
|
+ break;
|
+ case ELF::R_SPARC_UA32:
|
+ TargetPtr8 = reinterpret_cast<uint8_t*>(TargetPtr);
|
+ TargetPtr8[0] = Value >> 24U;
|
+ TargetPtr8[1] = Value >> 16U;
|
+ TargetPtr8[2] = Value >> 8U;
|
+ TargetPtr8[3] = Value;
|
+ break;
|
+ case ELF::R_SPARC_WPLT30:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 2;
|
+ RM = 0x3FFFFFFF;
|
+ Reloc = ((Value + Addend) - LoadAddress) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ TargetValue = *TargetPtr32;
|
+ break;
|
+ }
|
+}
|
+
|
+/// SPARCV9 ELF Relocatinos - valid in 64-bit only.
|
+/// https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-24-1/index.html
|
+void RuntimeDyldELF::resolveSPARC64Relocation(const SectionEntry &Section,
|
+ uint64_t Offset, uint64_t Value,
|
+ uint32_t Type, int64_t Addend) {
|
+ uint64_t *TargetAddress =
|
+ reinterpret_cast<uint64_t*>(reinterpret_cast<void*>(Section.getAddress()));
|
+ uint64_t *TargetPtr =
|
+ reinterpret_cast<uint64_t*>(Section.getAddressWithOffset(Offset));
|
+ uint32_t Reloc;
|
+ uintptr_t TargetPtrVal = reinterpret_cast<uintptr_t>(TargetPtr);
|
+ uint8_t *TargetPtr8 = nullptr;
|
+ uint16_t *TargetPtr16 = nullptr;
|
+ uint32_t *TargetPtr32 = nullptr;
|
+ uint64_t LoadAddress = Section.getLoadAddressWithOffset(Offset);
|
+ uint64_t TargetValue = 0ULL;
|
+ int32_t RS;
|
+ int32_t RM;
|
+
|
+ switch (Type) {
|
+ case ELF::R_SPARC_HI22:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ RS = 10;
|
+ RM = 0x003FFFFF;
|
+ Reloc = (Value + Addend) >> RS;
|
+ TargetValue = *TargetPtr32;
|
+ TargetValue &= ~RM;
|
+ Reloc &= RM;
|
+ *TargetPtr32 = TargetValue | Reloc;
|
+ break;
|
+ case ELF::R_SPARC_64:
|
+ case ELF::R_SPARC_GLOB_DAT:
|
+ Value += Addend;
|
+ *TargetPtr = Value;
|
+ break;
|
+ case ELF::R_SPARC_RELATIVE:
|
+ *TargetPtr = LoadAddress + Addend;
|
+ break;
|
+ case ELF::R_SPARC_OLO10:
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ *TargetPtr32 = (*TargetPtr32 & ~0x1FFF) | (((Value + Addend) & 0x3FF) +
|
+ ((Offset >> 8) & 0x1FFF));
|
+ break;
|
+ case ELF::R_SPARC_DISP64:
|
+ Value += Addend;
|
+ *TargetPtr = (Value - reinterpret_cast<uintptr_t>(TargetPtr));
|
+ break;
|
+ case ELF::R_SPARC_REGISTER:
|
+ Value += Addend;
|
+ *TargetPtr = Value;
|
+ break;
|
+ case ELF::R_SPARC_PLT64:
|
+ llvm::errs() << __PRETTY_FUNCTION__
|
+ << ": Warning: Unimplemented R_SPARC_PLT64 Relocation type.\n" ;
|
+ break;
|
+ case ELF::R_SPARC_UA64:
|
+ Value += Addend;
|
+ if (0 == (TargetPtrVal & 3)) {
|
+ TargetPtr32 = reinterpret_cast<uint32_t*>(TargetPtr);
|
+ TargetPtr32[0] = Value >> 32;
|
+ TargetPtr32[1] = Value;
|
+ } else {
|
+ TargetPtr8 = reinterpret_cast<uint8_t*>(TargetPtr);
|
+ TargetPtr8[0] = Value >> 56;
|
+ TargetPtr8[0] = Value >> 48;
|
+ TargetPtr8[0] = Value >> 40;
|
+ TargetPtr8[0] = Value >> 32;
|
+ TargetPtr8[0] = Value >> 24;
|
+ TargetPtr8[0] = Value >> 16;
|
+ TargetPtr8[0] = Value >> 8;
|
+ TargetPtr8[0] = Value;
|
+ }
|
+ break;
|
+ default:
|
+ resolveSPARC3264Relocation(Section, Offset, Value, Type, Addend);
|
+ break;
|
+ }
|
+}
|
+
|
void RuntimeDyldELF::resolveSystemZRelocation(const SectionEntry &Section,
|
uint64_t Offset, uint64_t Value,
|
uint32_t Type, int64_t Addend) {
|
@@ -1037,6 +1479,12 @@
|
case Triple::bpfeb:
|
resolveBPFRelocation(Section, Offset, Value, Type, Addend);
|
break;
|
+ case Triple::sparc:
|
+ resolveSPARC3264Relocation(Section, Offset, Value, Type, Addend);
|
+ break;
|
+ case Triple::sparcv9:
|
+ resolveSPARC64Relocation(Section, Offset, Value, Type, Addend);
|
+ break;
|
default:
|
llvm_unreachable("Unsupported CPU type!");
|
}
|
@@ -1672,6 +2120,160 @@
|
else
|
addRelocationForSection(RE, Value.SectionID);
|
}
|
+ } else if (Arch == Triple::sparc) {
|
+ LLVM_DEBUG(dbgs() << "This is a SPARC32 relocation.\n");
|
+ SectionEntry &Section = Sections[SectionID];
|
+ uint8_t *Target = Section.getAddressWithOffset(Offset);
|
+ uint32_t *TargetAddress = reinterpret_cast<uint32_t*>(Target);
|
+ uint8_t *SectionAddress = Section.getAddress();
|
+ uintptr_t StubOffset = Section.getStubOffset();
|
+ uintptr_t StubAddress = static_cast<uintptr_t>(-1);
|
+
|
+ if (RelType == ELF::R_SPARC_WDISP30) {
|
+ // Look up for existing stub.
|
+ StubMap::const_iterator i = Stubs.find(Value);
|
+
|
+ if (i != Stubs.end()) {
|
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
|
+ StubAddress =
|
+ reinterpret_cast<uintptr_t>(Section.getAddressWithOffset(i->second));
|
+
|
+ resolveRelocation(Section, Offset, StubAddress, RelType, 0);
|
+ Section.advanceStubOffset(getMaxStubSize());
|
+ } else {
|
+ // Create a new stub function.
|
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
|
+
|
+ uintptr_t BaseAddress =
|
+ reinterpret_cast<uintptr_t>(Section.getAddress());
|
+ uintptr_t StubAlignment = getStubAlignment();
|
+ StubAddress = BaseAddress + StubOffset;
|
+ StubAddress = llvm::alignTo(StubAddress, 4U);
|
+ StubOffset = StubAddress - BaseAddress;
|
+
|
+ Stubs[Value] = StubOffset;
|
+ uint8_t *StubTargetAddr =
|
+ createStubFunction(reinterpret_cast<uint8_t*>(StubAddress));
|
+
|
+ // Creating Hi and Lo relocations for the filled stub instructions.
|
+ RelocationEntry REhi(SectionID,
|
+ StubTargetAddr - SectionAddress,
|
+ ELF::R_SPARC_HI22, Value.Addend);
|
+ RelocationEntry RElo(SectionID,
|
+ StubTargetAddr - SectionAddress + 4,
|
+ ELF::R_SPARC_LO10, Value.Addend);
|
+
|
+ if (Value.SymbolName) {
|
+ addRelocationForSymbol(REhi, Value.SymbolName);
|
+ addRelocationForSymbol(RElo, Value.SymbolName);
|
+ } else {
|
+ addRelocationForSection(REhi, Value.SectionID);
|
+ addRelocationForSection(RElo, Value.SectionID);
|
+ }
|
+
|
+ resolveRelocation(Section, Offset, StubAddress, RelType, 0);
|
+ Section.advanceStubOffset(getMaxStubSize());
|
+ }
|
+ } else {
|
+ uintptr_t BaseAddress =
|
+ reinterpret_cast<uintptr_t>(Section.getAddress());
|
+ uintptr_t StubAlignment = getStubAlignment();
|
+ StubAddress = BaseAddress + StubOffset;
|
+ StubAddress = llvm::alignTo(StubAddress, 4U);
|
+ StubOffset = StubAddress - BaseAddress;
|
+
|
+ RelocationEntry RE(SectionID, Offset, RelType, Addend);
|
+ if (Value.SymbolName)
|
+ addRelocationForSymbol(RE, Value.SymbolName);
|
+ else
|
+ addRelocationForSection(RE, Value.SectionID);
|
+
|
+ resolveRelocation(Section, Offset, StubOffset, RelType, 0);
|
+ Section.advanceStubOffset(getMaxStubSize());
|
+ }
|
+ } else if (Arch == Triple::sparcv9) {
|
+ LLVM_DEBUG(dbgs() << "This is a SPARC64 relocation.\n");
|
+
|
+ SectionEntry &Section = Sections[SectionID];
|
+ uint8_t *Target = Section.getAddressWithOffset(Offset);
|
+ uint32_t *TargetAddress = reinterpret_cast<uint32_t*>(Target);
|
+ uint8_t *SectionAddress = Section.getAddress();
|
+ uintptr_t StubOffset = Section.getStubOffset();
|
+ uintptr_t StubAddress = static_cast<uintptr_t>(-1);
|
+
|
+ if (RelType == ELF::R_SPARC_WDISP30) {
|
+ // Look up for existing stub.
|
+ StubMap::const_iterator i = Stubs.find(Value);
|
+ if (i != Stubs.end()) {
|
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
|
+
|
+ StubAddress =
|
+ reinterpret_cast<uintptr_t>(Section.getAddressWithOffset(i->second));
|
+
|
+ resolveRelocation(Section, Offset, StubAddress, RelType, 0);
|
+ Section.advanceStubOffset(getMaxStubSize());
|
+ } else {
|
+ // Create a new stub function.
|
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
|
+
|
+ uintptr_t BaseAddress =
|
+ reinterpret_cast<uintptr_t>(Section.getAddress());
|
+ uintptr_t StubAlignment = getStubAlignment();
|
+
|
+ StubAddress = BaseAddress + StubOffset;
|
+ StubAddress = llvm::alignTo(StubAddress, 8U);
|
+ StubOffset = StubAddress - BaseAddress;
|
+ Stubs[Value] = StubOffset;
|
+
|
+ uint8_t *StubTargetAddr =
|
+ createStubFunction(reinterpret_cast<uint8_t*>(StubAddress));
|
+
|
+ // Creating Hi and Lo relocations for the filled stub instructions.
|
+ RelocationEntry REhh(SectionID,
|
+ StubTargetAddr - SectionAddress,
|
+ ELF::R_SPARC_HH22, Value.Addend);
|
+ RelocationEntry REhm(SectionID,
|
+ StubTargetAddr - SectionAddress + 8,
|
+ ELF::R_SPARC_HM10, Value.Addend);
|
+ RelocationEntry RElm(SectionID,
|
+ StubTargetAddr - SectionAddress + 16,
|
+ ELF::R_SPARC_LM22, Value.Addend);
|
+ RelocationEntry RElo(SectionID,
|
+ StubTargetAddr - SectionAddress + 24,
|
+ ELF::R_SPARC_LO10, Value.Addend);
|
+
|
+ if (Value.SymbolName) {
|
+ addRelocationForSymbol(REhh, Value.SymbolName);
|
+ addRelocationForSymbol(REhm, Value.SymbolName);
|
+ addRelocationForSymbol(RElm, Value.SymbolName);
|
+ addRelocationForSymbol(RElo, Value.SymbolName);
|
+ } else {
|
+ addRelocationForSection(REhh, Value.SectionID);
|
+ addRelocationForSection(REhm, Value.SectionID);
|
+ addRelocationForSection(RElm, Value.SectionID);
|
+ addRelocationForSection(RElo, Value.SectionID);
|
+ }
|
+
|
+ resolveRelocation(Section, Offset, StubAddress, RelType, 0);
|
+ Section.advanceStubOffset(getMaxStubSize());
|
+ }
|
+ } else {
|
+ uintptr_t BaseAddress =
|
+ reinterpret_cast<uintptr_t>(Section.getAddress());
|
+ uintptr_t StubAlignment = getStubAlignment();
|
+ StubAddress = BaseAddress + StubOffset;
|
+ StubAddress = llvm::alignTo(StubAddress, 8U);
|
+ StubOffset = StubAddress - BaseAddress;
|
+
|
+ RelocationEntry RE(SectionID, Offset, RelType, Addend);
|
+ if (Value.SymbolName)
|
+ addRelocationForSymbol(RE, Value.SymbolName);
|
+ else
|
+ addRelocationForSection(RE, Value.SectionID);
|
+
|
+ resolveRelocation(Section, Offset, StubAddress, RelType, 0);
|
+ Section.advanceStubOffset(getMaxStubSize());
|
+ }
|
} else if (Arch == Triple::systemz &&
|
(RelType == ELF::R_390_PLT32DBL || RelType == ELF::R_390_GOTENT)) {
|
// Create function stubs for both PLT and GOT references, regardless of
|
--- llvm-13.0.0.src/include/llvm/Object/ELFObjectFile.h.~1~ 2021-09-24 19:18:10.000000000 +0000
|
+++ llvm-13.0.0.src/include/llvm/Object/ELFObjectFile.h 2022-01-02 14:26:31.005542785 +0000
|
@@ -1190,8 +1190,9 @@
|
case ELF::EM_CSKY:
|
return "elf32-csky";
|
case ELF::EM_SPARC:
|
- case ELF::EM_SPARC32PLUS:
|
return "elf32-sparc";
|
+ case ELF::EM_SPARC32PLUS:
|
+ return "elf32-sparc32plus";
|
case ELF::EM_AMDGPU:
|
return "elf32-amdgpu";
|
default:
|
@@ -1212,7 +1213,7 @@
|
case ELF::EM_S390:
|
return "elf64-s390";
|
case ELF::EM_SPARCV9:
|
- return "elf64-sparc";
|
+ return "elf64-sparcv9";
|
case ELF::EM_MIPS:
|
return "elf64-mips";
|
case ELF::EM_AMDGPU:
|
@@ -1278,8 +1279,8 @@
|
return Triple::systemz;
|
|
case ELF::EM_SPARC:
|
- case ELF::EM_SPARC32PLUS:
|
return IsLittleEndian ? Triple::sparcel : Triple::sparc;
|
+ case ELF::EM_SPARC32PLUS:
|
case ELF::EM_SPARCV9:
|
return Triple::sparcv9;
|
|