git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214205
91177308-0d34-0410-b5e6-
96231b3b80d8
#define LLVM_RUNTIMEDYLDMACHOAARCH64_H
#include "../RuntimeDyldMachO.h"
#define LLVM_RUNTIMEDYLDMACHOAARCH64_H
#include "../RuntimeDyldMachO.h"
+#include "llvm/Support/Endian.h"
#define DEBUG_TYPE "dyld"
#define DEBUG_TYPE "dyld"
default:
llvm_unreachable("Unsupported relocation type!");
case MachO::ARM64_RELOC_UNSIGNED:
default:
llvm_unreachable("Unsupported relocation type!");
case MachO::ARM64_RELOC_UNSIGNED:
- assert((NumBytes >= 4 && NumBytes <= 8) && "Invalid relocation size.");
+ assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
break;
case MachO::ARM64_RELOC_BRANCH26:
case MachO::ARM64_RELOC_PAGE21:
break;
case MachO::ARM64_RELOC_BRANCH26:
case MachO::ARM64_RELOC_PAGE21:
default:
llvm_unreachable("Unsupported relocation type!");
case MachO::ARM64_RELOC_UNSIGNED:
default:
llvm_unreachable("Unsupported relocation type!");
case MachO::ARM64_RELOC_UNSIGNED:
- // This could be an unaligned memory location - use memcpy.
- memcpy(&Addend, LocalAddress, NumBytes);
+ // This could be an unaligned memory location.
+ if (NumBytes == 4)
+ Addend = *reinterpret_cast<support::ulittle32_t *>(LocalAddress);
+ else
+ Addend = *reinterpret_cast<support::ulittle64_t *>(LocalAddress);
break;
case MachO::ARM64_RELOC_BRANCH26: {
// Verify that the relocation points to the expected branch instruction.
break;
case MachO::ARM64_RELOC_BRANCH26: {
// Verify that the relocation points to the expected branch instruction.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
// Get the 26 bit addend encoded in the branch instruction and sign-extend
assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
// Get the 26 bit addend encoded in the branch instruction and sign-extend
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_PAGE21: {
// Verify that the relocation points to the expected adrp instruction.
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_PAGE21: {
// Verify that the relocation points to the expected adrp instruction.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
// Get the 21 bit addend encoded in the adrp instruction and sign-extend
assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
// Get the 21 bit addend encoded in the adrp instruction and sign-extend
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// instructions.
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// instructions.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
(void)p;
assert((*p & 0x3B000000) == 0x39000000 &&
"Only expected load / store instructions.");
(void)p;
assert((*p & 0x3B000000) == 0x39000000 &&
"Only expected load / store instructions.");
case MachO::ARM64_RELOC_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// or add / sub instructions.
case MachO::ARM64_RELOC_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// or add / sub instructions.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
assert((((*p & 0x3B000000) == 0x39000000) ||
((*p & 0x11C00000) == 0x11000000) ) &&
"Expected load / store or add/sub instruction.");
assert((((*p & 0x3B000000) == 0x39000000) ||
((*p & 0x11C00000) == 0x11000000) ) &&
"Expected load / store or add/sub instruction.");
}
/// Extract the addend encoded in the instruction.
}
/// Extract the addend encoded in the instruction.
- void encodeAddend(uint8_t *LocalAddress, MachO::RelocationInfoType RelType,
- int64_t Addend) const {
+ void encodeAddend(uint8_t *LocalAddress, unsigned NumBytes,
+ MachO::RelocationInfoType RelType, int64_t Addend) const {
// Verify that the relocation has the correct alignment.
switch (RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
case MachO::ARM64_RELOC_UNSIGNED:
// Verify that the relocation has the correct alignment.
switch (RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
case MachO::ARM64_RELOC_UNSIGNED:
- llvm_unreachable("Invalid relocation type for instruction.");
+ assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
+ break;
case MachO::ARM64_RELOC_BRANCH26:
case MachO::ARM64_RELOC_PAGE21:
case MachO::ARM64_RELOC_PAGEOFF12:
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
case MachO::ARM64_RELOC_BRANCH26:
case MachO::ARM64_RELOC_PAGE21:
case MachO::ARM64_RELOC_PAGEOFF12:
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
+ assert(NumBytes == 4 && "Invalid relocation size.");
assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
"Instruction address is not aligned to 4 bytes.");
break;
assert((((uintptr_t)LocalAddress & 0x3) == 0) &&
"Instruction address is not aligned to 4 bytes.");
break;
switch (RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
switch (RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
+ case MachO::ARM64_RELOC_UNSIGNED:
+ // This could be an unaligned memory location.
+ if (NumBytes == 4)
+ *reinterpret_cast<support::ulittle32_t *>(LocalAddress) = Addend;
+ else
+ *reinterpret_cast<support::ulittle64_t *>(LocalAddress) = Addend;
+ break;
case MachO::ARM64_RELOC_BRANCH26: {
case MachO::ARM64_RELOC_BRANCH26: {
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
// Verify that the relocation points to the expected branch instruction.
// Verify that the relocation points to the expected branch instruction.
- uint32_t *p = (uint32_t *)LocalAddress;
assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
// Verify addend value.
assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
// Verify addend value.
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_PAGE21: {
// Verify that the relocation points to the expected adrp instruction.
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
case MachO::ARM64_RELOC_PAGE21: {
// Verify that the relocation points to the expected adrp instruction.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
// Check that the addend fits into 21 bits (+ 12 lower bits).
assert((*p & 0x9F000000) == 0x90000000 && "Expected adrp instruction.");
// Check that the addend fits into 21 bits (+ 12 lower bits).
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// instructions.
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// instructions.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
assert((*p & 0x3B000000) == 0x39000000 &&
"Only expected load / store instructions.");
(void)p;
assert((*p & 0x3B000000) == 0x39000000 &&
"Only expected load / store instructions.");
(void)p;
case MachO::ARM64_RELOC_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// or add / sub instructions.
case MachO::ARM64_RELOC_PAGEOFF12: {
// Verify that the relocation points to one of the expected load / store
// or add / sub instructions.
- uint32_t *p = (uint32_t *)LocalAddress;
+ auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
assert((((*p & 0x3B000000) == 0x39000000) ||
((*p & 0x11C00000) == 0x11000000) ) &&
"Expected load / store or add/sub instruction.");
assert((((*p & 0x3B000000) == 0x39000000) ||
((*p & 0x11C00000) == 0x11000000) ) &&
"Expected load / store or add/sub instruction.");
if (RE.Size < 2)
llvm_unreachable("Invalid size for ARM64_RELOC_UNSIGNED");
if (RE.Size < 2)
llvm_unreachable("Invalid size for ARM64_RELOC_UNSIGNED");
- writeBytesUnaligned(LocalAddress, Value + RE.Addend, 1 << RE.Size);
+ encodeAddend(LocalAddress, 1 << RE.Size, RelType, Value + RE.Addend);
break;
}
case MachO::ARM64_RELOC_BRANCH26: {
break;
}
case MachO::ARM64_RELOC_BRANCH26: {
// Check if branch is in range.
uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
int64_t PCRelVal = Value - FinalAddress + RE.Addend;
// Check if branch is in range.
uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
int64_t PCRelVal = Value - FinalAddress + RE.Addend;
- encodeAddend(LocalAddress, RelType, PCRelVal);
+ encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal);
break;
}
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
break;
}
case MachO::ARM64_RELOC_GOT_LOAD_PAGE21:
uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
int64_t PCRelVal =
((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096));
uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
int64_t PCRelVal =
((Value + RE.Addend) & (-4096)) - (FinalAddress & (-4096));
- encodeAddend(LocalAddress, RelType, PCRelVal);
+ encodeAddend(LocalAddress, /*Size=*/4, RelType, PCRelVal);
break;
}
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
break;
}
case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12:
Value += RE.Addend;
// Mask out the page address and only use the lower 12 bits.
Value &= 0xFFF;
Value += RE.Addend;
// Mask out the page address and only use the lower 12 bits.
Value &= 0xFFF;
- encodeAddend(LocalAddress, RelType, Value);
+ encodeAddend(LocalAddress, /*Size=*/4, RelType, Value);
break;
}
case MachO::ARM64_RELOC_SUBTRACTOR:
break;
}
case MachO::ARM64_RELOC_SUBTRACTOR:
# RUN: llvm-mc -triple=arm64-apple-ios7.0.0 -code-model=small -relocation-model=pic -filetype=obj -o %T/foo.o %s
# RUN: sed "s,<filename>,%/T/foo.o,g" %s > %T/foo.s
# RUN: llvm-rtdyld -triple=arm64-apple-ios7.0.0 -verify -check=%T/foo.s %/T/foo.o
# RUN: llvm-mc -triple=arm64-apple-ios7.0.0 -code-model=small -relocation-model=pic -filetype=obj -o %T/foo.o %s
# RUN: sed "s,<filename>,%/T/foo.o,g" %s > %T/foo.s
# RUN: llvm-rtdyld -triple=arm64-apple-ios7.0.0 -verify -check=%T/foo.s %/T/foo.o
.section __TEXT,__text,regular,pure_instructions
.ios_version_min 7, 0
.section __TEXT,__text,regular,pure_instructions
.ios_version_min 7, 0