// This stub has to be able to access the full address space,
// since symbol lookup won't necessarily find a handy, in-range,
// PLT stub for functions which could be anywhere.
- uint32_t *StubAddr = (uint32_t *)Addr;
-
// Stub can use ip0 (== x16) to calculate address
- *StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:<addr>
- StubAddr++;
- *StubAddr = 0xf2c00010; // movk ip0, #:abs_g2_nc:<addr>
- StubAddr++;
- *StubAddr = 0xf2a00010; // movk ip0, #:abs_g1_nc:<addr>
- StubAddr++;
- *StubAddr = 0xf2800010; // movk ip0, #:abs_g0_nc:<addr>
- StubAddr++;
- *StubAddr = 0xd61f0200; // br ip0
+ writeBytesUnaligned(0xd2e00010, Addr, 4); // movz ip0, #:abs_g3:<addr>
+ writeBytesUnaligned(0xf2c00010, Addr+4, 4); // movk ip0, #:abs_g2_nc:<addr>
+ writeBytesUnaligned(0xf2a00010, Addr+8, 4); // movk ip0, #:abs_g1_nc:<addr>
+ writeBytesUnaligned(0xf2800010, Addr+12, 4); // movk ip0, #:abs_g0_nc:<addr>
+ writeBytesUnaligned(0xd61f0200, Addr+16, 4); // br ip0
return Addr;
} else if (Arch == Triple::arm || Arch == Triple::armeb) {
// TODO: There is only ARM far stub now. We should add the Thumb stub,
// and stubs for branches Thumb - ARM and ARM - Thumb.
- uint32_t *StubAddr = (uint32_t *)Addr;
- *StubAddr = 0xe51ff004; // ldr pc,<label>
- return (uint8_t *)++StubAddr;
+ writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,<label>
+ return Addr + 4;
} else if (Arch == Triple::mipsel || Arch == Triple::mips) {
- uint32_t *StubAddr = (uint32_t *)Addr;
// 0: 3c190000 lui t9,%hi(addr).
// 4: 27390000 addiu t9,t9,%lo(addr).
// 8: 03200008 jr t9.
const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;
const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0;
- *StubAddr = LuiT9Instr;
- StubAddr++;
- *StubAddr = AdduiT9Instr;
- StubAddr++;
- *StubAddr = JrT9Instr;
- StubAddr++;
- *StubAddr = NopInstr;
+ writeBytesUnaligned(LuiT9Instr, Addr, 4);
+ writeBytesUnaligned(AdduiT9Instr, Addr+4, 4);
+ writeBytesUnaligned(JrT9Instr, Addr+8, 4);
+ writeBytesUnaligned(NopInstr, Addr+12, 4);
return Addr;
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
// Depending on which version of the ELF ABI is in use, we need to
default:
return memcpyAddend(RE);
case MachO::ARM_RELOC_BR24: {
- uint32_t Temp;
- memcpy(&Temp, LocalAddress, 4);
+ uint32_t Temp = readBytesUnaligned(LocalAddress, 4);
Temp &= 0x00ffffff; // Mask out the opcode.
// Now we've got the shifted immediate, shift by 2, sign extend and ret.
return SignExtend32<26>(Temp << 2);
case MachO::ARM_RELOC_BR24: {
// Mask the value into the target address. We know instructions are
// 32-bit aligned, so we can do it all at once.
- uint32_t *p = (uint32_t *)LocalAddress;
Value += RE.Addend;
// The low two bits of the value are not encoded.
Value >>= 2;
// instruction instead.
// Insert the value into the instruction.
- *p = (*p & ~0xffffff) | FinalValue;
+ uint32_t Temp = readBytesUnaligned(LocalAddress, 4);
+ writeBytesUnaligned((Temp & ~0xffffff) | FinalValue, LocalAddress, 4);
+
break;
}
case MachO::ARM_RELOC_HALF_SECTDIFF: {
Value = (Value >> 16);
Value &= 0xffff;
- uint32_t Insn;
- memcpy(&Insn, LocalAddress, 4);
+ uint32_t Insn = readBytesUnaligned(LocalAddress, 4);
Insn = (Insn & 0xfff0f000) | ((Value & 0xf000) << 4) | (Value & 0x0fff);
- memcpy(LocalAddress, &Insn, 4);
+ writeBytesUnaligned(Insn, LocalAddress, 4);
break;
}
uint64_t Offset;
RelI->getOffset(Offset);
uint8_t *LocalAddress = Section.Address + Offset;
- int64_t Immediate = 0;
- memcpy(&Immediate, LocalAddress, 4); // Copy the whole instruction out.
+ int64_t Immediate = readBytesUnaligned(LocalAddress, 4); // Copy the whole instruction out.
Immediate = ((Immediate >> 4) & 0xf000) | (Immediate & 0xfff);
++RelI;