diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Object/RelocationResolver.cpp | 64 | 
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()) {  | 
