diff options
Diffstat (limited to 'lld/lib/ReaderWriter')
4 files changed, 12 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h index 27f90b0c5e2..ab60daae523 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h @@ -108,6 +108,7 @@ private: const uint8_t *ap = content.data() + ri.r_offset - symbol.st_value; switch (ri.getType(isMips64EL)) { case llvm::ELF::R_MIPS_32: + case llvm::ELF::R_MIPS_PC32: ref->setAddend(*(int32_t *)ap); break; case llvm::ELF::R_MIPS_26: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp index 0cc5630bb6f..7407ad58ed9 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp @@ -34,6 +34,12 @@ static void reloc32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { applyReloc(location, S + A, 0xffffffff); } +/// \brief R_MIPS_PC32 +/// local/external: word32 S + A i- P (truncate) +void relocpc32(uint8_t *location, uint64_t P, uint64_t S, int64_t A) { + applyReloc(location, S + A - P, 0xffffffff); +} + /// \brief R_MIPS_26 /// local : ((A | ((P + 4) & 0x3F000000)) + S) >> 2 static void reloc26loc(uint8_t *location, uint64_t P, uint64_t S, int32_t A) { @@ -154,6 +160,9 @@ error_code MipsTargetRelocationHandler::applyRelocation( case R_MIPS_JUMP_SLOT: // Ignore runtime relocations. break; + case R_MIPS_PC32: + relocpc32(location, relocVAddress, targetVAddress, ref.addend()); + break; case LLD_R_MIPS_GLOBAL_GOT: // Do nothing. break; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index efcd00cb874..5556135898b 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -316,6 +316,7 @@ void RelocationPass<ELFT>::handleReference(Reference &ref) { assert(ref.kindArch() == Reference::KindArch::Mips); switch (ref.kindValue()) { case R_MIPS_32: + case R_MIPS_PC32: case R_MIPS_HI16: case R_MIPS_LO16: // FIXME (simon): Handle dynamic/static linking differently. diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp index e2269ed5a68..0e6c9918e9f 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp @@ -57,6 +57,7 @@ const Registry::KindStrings MipsTargetHandler::kindStrings[] = { LLD_KIND_STRING_ENTRY(R_MIPS_JALR), LLD_KIND_STRING_ENTRY(R_MIPS_COPY), LLD_KIND_STRING_ENTRY(R_MIPS_JUMP_SLOT), + LLD_KIND_STRING_ENTRY(R_MIPS_PC32), LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT), LLD_KIND_STRING_ENTRY(LLD_R_MIPS_32_HI16), LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26), |

