summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2015-06-03 10:27:28 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2015-06-03 10:27:28 +0000
commit682b194cd6ea55891caa17ae4b8fafe809453d11 (patch)
tree34d8fe9e3bd9d8e1ca3657c1d1218573d1ab2d6b /lib/ExecutionEngine
parentaa17b5dd2d63a28604cac8a03dc639b38ef8e606 (diff)
downloadllvm-682b194cd6ea55891caa17ae4b8fafe809453d11.tar.gz
Re-commit r238838, r238844 with fix for host/target endian mismatch and windows buildbot.
The windows buildbot originally failed because the check expressions are evaluated as 64-bit values, even for 32-bit symbols. Fixed this by comparing bottom 32-bits of the expressions. The host/target endian mismatch issue is that it's invalid to read/write target values using a host pointer without taking care of endian differences between the target and host. Most (if not all) instances of reinterpret_cast<uint32_t*>() in the RuntimeDyld are examples of this bug. This has been fixed for Mips using the endian aware read/write functions. The original commits were: r238838: [mips] Add RuntimeDyld tests for currently supported O32 relocations. Reviewers: petarj, vkalintiris Reviewed By: vkalintiris Subscribers: vkalintiris, llvm-commits Differential Revision: http://reviews.llvm.org/D10126 r238844: [mips][mcjit] Add support for R_MIPS_PC32. Summary: This allows us to resolve relocations for DW_EH_PE_pcrel TType encodings in the exception handling LSDA. Also fixed a nearby typo. Reviewers: petarj, vkalintiris Reviewed By: vkalintiris Subscribers: vkalintiris, llvm-commits Differential Revision: http://reviews.llvm.org/D10127 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238915 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp37
1 files changed, 25 insertions, 12 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 8679368d7736..720b7b22933e 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -477,32 +477,43 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
uint64_t Offset, uint32_t Value,
uint32_t Type, int32_t Addend) {
- uint32_t *TargetPtr = (uint32_t *)(Section.Address + Offset);
+ uint8_t *TargetPtr = Section.Address + Offset;
Value += Addend;
- DEBUG(dbgs() << "resolveMipselocation, LocalAddress: "
+ DEBUG(dbgs() << "resolveMIPSRelocation, LocalAddress: "
<< Section.Address + Offset << " FinalAddress: "
<< format("%p", Section.LoadAddress + Offset) << " Value: "
<< format("%x", Value) << " Type: " << format("%x", Type)
<< " Addend: " << format("%x", Addend) << "\n");
+ uint32_t Insn = readBytesUnaligned(TargetPtr, 4);
+
switch (Type) {
default:
llvm_unreachable("Not implemented relocation type!");
break;
case ELF::R_MIPS_32:
- *TargetPtr = Value;
+ writeBytesUnaligned(Value, TargetPtr, 4);
break;
case ELF::R_MIPS_26:
- *TargetPtr = ((*TargetPtr) & 0xfc000000) | ((Value & 0x0fffffff) >> 2);
+ Insn &= 0xfc000000;
+ Insn |= (Value & 0x0fffffff) >> 2;
+ writeBytesUnaligned(Insn, TargetPtr, 4);
break;
case ELF::R_MIPS_HI16:
// Get the higher 16-bits. Also add 1 if bit 15 is 1.
- *TargetPtr =
- ((*TargetPtr) & 0xffff0000) | (((Value + 0x8000) >> 16) & 0xffff);
+ Insn &= 0xffff0000;
+ Insn |= ((Value + 0x8000) >> 16) & 0xffff;
+ writeBytesUnaligned(Insn, TargetPtr, 4);
break;
case ELF::R_MIPS_LO16:
- *TargetPtr = ((*TargetPtr) & 0xffff0000) | (Value & 0xffff);
+ Insn &= 0xffff0000;
+ Insn |= Value & 0xffff;
+ writeBytesUnaligned(Insn, TargetPtr, 4);
+ break;
+ case ELF::R_MIPS_PC32:
+ uint32_t FinalAddress = (Section.LoadAddress + Offset);
+ writeBytesUnaligned(Value + Addend - FinalAddress, (uint8_t *)TargetPtr, 4);
break;
}
}
@@ -1199,7 +1210,9 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
processSimpleRelocation(SectionID, Offset, RelType, Value);
}
} else if (IsMipsO32ABI) {
- uint32_t *Placeholder = reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
+ uint8_t *Placeholder = reinterpret_cast<uint8_t *>(
+ computePlaceholderAddress(SectionID, Offset));
+ uint32_t Opcode = readBytesUnaligned(Placeholder, 4);
if (RelType == ELF::R_MIPS_26) {
// This is an Mips branch relocation, need to use a stub function.
DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
@@ -1208,7 +1221,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
// Extract the addend from the instruction.
// We shift up by two since the Value will be down shifted again
// when applying the relocation.
- uint32_t Addend = ((*Placeholder) & 0x03ffffff) << 2;
+ uint32_t Addend = (Opcode & 0x03ffffff) << 2;
Value.Addend += Addend;
@@ -1246,11 +1259,11 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
}
} else {
if (RelType == ELF::R_MIPS_HI16)
- Value.Addend += ((*Placeholder) & 0x0000ffff) << 16;
+ Value.Addend += (Opcode & 0x0000ffff) << 16;
else if (RelType == ELF::R_MIPS_LO16)
- Value.Addend += ((*Placeholder) & 0x0000ffff);
+ Value.Addend += (Opcode & 0x0000ffff);
else if (RelType == ELF::R_MIPS_32)
- Value.Addend += *Placeholder;
+ Value.Addend += Opcode;
processSimpleRelocation(SectionID, Offset, RelType, Value);
}
} else if (IsMipsN64ABI) {