[JIT] Fix more missing endian conversions (opcodes for AArch64, ARM, and Mips stub...
authorDaniel Sanders <daniel.sanders@imgtec.com>
Thu, 6 Nov 2014 09:53:05 +0000 (09:53 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Thu, 6 Nov 2014 09:53:05 +0000 (09:53 +0000)
Summary:
Fixed all of the missing endian conversions that Lang Hames and I identified in
RuntimeDyldMachOARM.h.

Fixed the opcode emission in RuntimeDyldImpl::createStubFunction() for AArch64,
ARM, Mips when the host endian doesn't match the target endian.
PowerPC will need changing if it's opcodes are affected by endianness but I've
left this for now since I'm unsure if this is the case and it's the only path
that specifies the target endian.

This patch fixes MachO_ARM_PIC_relocations.s on a big-endian Mips host. This
is the last of the known issues on this host.

Reviewers: lhames

Reviewed By: lhames

Subscribers: aemerson, llvm-commits

Differential Revision: http://reviews.llvm.org/D6130

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221446 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h

index 488130112decfb757395d79d6420a1bb558d7132..83c098ded0c8444ad8f56cdb2182a73f8c54b4fd 100644 (file)
@@ -585,28 +585,20 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr,
     // 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.
@@ -614,13 +606,10 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr,
     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
index 9f5b573920d10c367fc3961ed2e617fad01c14b2..9766751c43dcf6e084389ce8ddfd155ada7c9a97 100644 (file)
@@ -39,8 +39,7 @@ public:
       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);
@@ -112,7 +111,6 @@ public:
     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;
@@ -123,7 +121,9 @@ public:
       // 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: {
@@ -136,10 +136,9 @@ public:
         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;
     }
 
@@ -222,8 +221,7 @@ private:
     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;