summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp64
1 files changed, 60 insertions, 4 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
index 55b315a20d17..31478be7899e 100644
--- a/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
+++ b/contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp
@@ -30,6 +30,7 @@ static bool supportsX86_64(uint64_t Type) {
case ELF::R_X86_64_DTPOFF32:
case ELF::R_X86_64_DTPOFF64:
case ELF::R_X86_64_PC32:
+ case ELF::R_X86_64_PC64:
case ELF::R_X86_64_32:
case ELF::R_X86_64_32S:
return true;
@@ -47,6 +48,7 @@ static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) {
case ELF::R_X86_64_DTPOFF64:
return S + getELFAddend(R);
case ELF::R_X86_64_PC32:
+ case ELF::R_X86_64_PC64:
return S + getELFAddend(R) - R.getOffset();
case ELF::R_X86_64_32:
case ELF::R_X86_64_32S:
@@ -337,6 +339,7 @@ static bool supportsRISCV(uint64_t Type) {
switch (Type) {
case ELF::R_RISCV_NONE:
case ELF::R_RISCV_32:
+ case ELF::R_RISCV_32_PCREL:
case ELF::R_RISCV_64:
case ELF::R_RISCV_SET6:
case ELF::R_RISCV_SUB6:
@@ -361,12 +364,14 @@ static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) {
return A;
case ELF::R_RISCV_32:
return (S + RA) & 0xFFFFFFFF;
+ case ELF::R_RISCV_32_PCREL:
+ return (S + RA - R.getOffset()) & 0xFFFFFFFF;
case ELF::R_RISCV_64:
return S + RA;
case ELF::R_RISCV_SET6:
- return (A + (S + RA)) & 0xFF;
+ return (A & 0xC0) | ((S + RA) & 0x3F);
case ELF::R_RISCV_SUB6:
- return (A - (S + RA)) & 0xFF;
+ return (A & 0xC0) | (((A & 0x3F) - (S + RA)) & 0x3F);
case ELF::R_RISCV_ADD8:
return (A + (S + RA)) & 0xFF;
case ELF::R_RISCV_SUB8:
@@ -429,6 +434,47 @@ static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) {
}
}
+static bool supportsCOFFARM(uint64_t Type) {
+ switch (Type) {
+ case COFF::IMAGE_REL_ARM_SECREL:
+ case COFF::IMAGE_REL_ARM_ADDR32:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint64_t resolveCOFFARM(RelocationRef R, uint64_t S, uint64_t A) {
+ switch (R.getType()) {
+ case COFF::IMAGE_REL_ARM_SECREL:
+ case COFF::IMAGE_REL_ARM_ADDR32:
+ return (S + A) & 0xFFFFFFFF;
+ default:
+ llvm_unreachable("Invalid relocation type");
+ }
+}
+
+static bool supportsCOFFARM64(uint64_t Type) {
+ switch (Type) {
+ case COFF::IMAGE_REL_ARM64_SECREL:
+ case COFF::IMAGE_REL_ARM64_ADDR64:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static uint64_t resolveCOFFARM64(RelocationRef R, uint64_t S, uint64_t A) {
+ switch (R.getType()) {
+ case COFF::IMAGE_REL_ARM64_SECREL:
+ return (S + A) & 0xFFFFFFFF;
+ case COFF::IMAGE_REL_ARM64_ADDR64:
+ return S + A;
+ default:
+ llvm_unreachable("Invalid relocation type");
+ }
+}
+
static bool supportsMachOX86_64(uint64_t Type) {
return Type == MachO::X86_64_RELOC_UNSIGNED;
}
@@ -481,9 +527,19 @@ static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
std::pair<bool (*)(uint64_t), RelocationResolver>
getRelocationResolver(const ObjectFile &Obj) {
if (Obj.isCOFF()) {
- if (Obj.getBytesInAddress() == 8)
+ switch (Obj.getArch()) {
+ case Triple::x86_64:
return {supportsCOFFX86_64, resolveCOFFX86_64};
- return {supportsCOFFX86, resolveCOFFX86};
+ case Triple::x86:
+ return {supportsCOFFX86, resolveCOFFX86};
+ case Triple::arm:
+ case Triple::thumb:
+ return {supportsCOFFARM, resolveCOFFARM};
+ case Triple::aarch64:
+ return {supportsCOFFARM64, resolveCOFFARM64};
+ default:
+ return {nullptr, nullptr};
+ }
} else if (Obj.isELF()) {
if (Obj.getBytesInAddress() == 8) {
switch (Obj.getArch()) {