llvm.org GIT mirror llvm / 10f28ec
[JIT] Fix more missing endian conversions (opcodes for AArch64, ARM, and Mips stub functions, and ARM target in general) 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 Daniel Sanders 5 years ago
2 changed file(s) with 18 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
584584 // This stub has to be able to access the full address space,
585585 // since symbol lookup won't necessarily find a handy, in-range,
586586 // PLT stub for functions which could be anywhere.
587 uint32_t *StubAddr = (uint32_t *)Addr;
588
589587 // Stub can use ip0 (== x16) to calculate address
590 *StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:
591 StubAddr++;
592 *StubAddr = 0xf2c00010; // movk ip0, #:abs_g2_nc:
593 StubAddr++;
594 *StubAddr = 0xf2a00010; // movk ip0, #:abs_g1_nc:
595 StubAddr++;
596 *StubAddr = 0xf2800010; // movk ip0, #:abs_g0_nc:
597 StubAddr++;
598 *StubAddr = 0xd61f0200; // br ip0
588 writeBytesUnaligned(0xd2e00010, Addr, 4); // movz ip0, #:abs_g3:
589 writeBytesUnaligned(0xf2c00010, Addr+4, 4); // movk ip0, #:abs_g2_nc:
590 writeBytesUnaligned(0xf2a00010, Addr+8, 4); // movk ip0, #:abs_g1_nc:
591 writeBytesUnaligned(0xf2800010, Addr+12, 4); // movk ip0, #:abs_g0_nc:
592 writeBytesUnaligned(0xd61f0200, Addr+16, 4); // br ip0
599593
600594 return Addr;
601595 } else if (Arch == Triple::arm || Arch == Triple::armeb) {
602596 // TODO: There is only ARM far stub now. We should add the Thumb stub,
603597 // and stubs for branches Thumb - ARM and ARM - Thumb.
604 uint32_t *StubAddr = (uint32_t *)Addr;
605 *StubAddr = 0xe51ff004; // ldr pc,
606 return (uint8_t *)++StubAddr;
598 writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,
599 return Addr + 4;
607600 } else if (Arch == Triple::mipsel || Arch == Triple::mips) {
608 uint32_t *StubAddr = (uint32_t *)Addr;
609601 // 0: 3c190000 lui t9,%hi(addr).
610602 // 4: 27390000 addiu t9,t9,%lo(addr).
611603 // 8: 03200008 jr t9.
613605 const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000;
614606 const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0;
615607
616 *StubAddr = LuiT9Instr;
617 StubAddr++;
618 *StubAddr = AdduiT9Instr;
619 StubAddr++;
620 *StubAddr = JrT9Instr;
621 StubAddr++;
622 *StubAddr = NopInstr;
608 writeBytesUnaligned(LuiT9Instr, Addr, 4);
609 writeBytesUnaligned(AdduiT9Instr, Addr+4, 4);
610 writeBytesUnaligned(JrT9Instr, Addr+8, 4);
611 writeBytesUnaligned(NopInstr, Addr+12, 4);
623612 return Addr;
624613 } else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
625614 // Depending on which version of the ELF ABI is in use, we need to
3838 default:
3939 return memcpyAddend(RE);
4040 case MachO::ARM_RELOC_BR24: {
41 uint32_t Temp;
42 memcpy(&Temp, LocalAddress, 4);
41 uint32_t Temp = readBytesUnaligned(LocalAddress, 4);
4342 Temp &= 0x00ffffff; // Mask out the opcode.
4443 // Now we've got the shifted immediate, shift by 2, sign extend and ret.
4544 return SignExtend32<26>(Temp << 2);
111110 case MachO::ARM_RELOC_BR24: {
112111 // Mask the value into the target address. We know instructions are
113112 // 32-bit aligned, so we can do it all at once.
114 uint32_t *p = (uint32_t *)LocalAddress;
115113 Value += RE.Addend;
116114 // The low two bits of the value are not encoded.
117115 Value >>= 2;
122120 // instruction instead.
123121
124122 // Insert the value into the instruction.
125 *p = (*p & ~0xffffff) | FinalValue;
123 uint32_t Temp = readBytesUnaligned(LocalAddress, 4);
124 writeBytesUnaligned((Temp & ~0xffffff) | FinalValue, LocalAddress, 4);
125
126126 break;
127127 }
128128 case MachO::ARM_RELOC_HALF_SECTDIFF: {
135135 Value = (Value >> 16);
136136 Value &= 0xffff;
137137
138 uint32_t Insn;
139 memcpy(&Insn, LocalAddress, 4);
138 uint32_t Insn = readBytesUnaligned(LocalAddress, 4);
140139 Insn = (Insn & 0xfff0f000) | ((Value & 0xf000) << 4) | (Value & 0x0fff);
141 memcpy(LocalAddress, &Insn, 4);
140 writeBytesUnaligned(Insn, LocalAddress, 4);
142141 break;
143142 }
144143
221220 uint64_t Offset;
222221 RelI->getOffset(Offset);
223222 uint8_t *LocalAddress = Section.Address + Offset;
224 int64_t Immediate = 0;
225 memcpy(&Immediate, LocalAddress, 4); // Copy the whole instruction out.
223 int64_t Immediate = readBytesUnaligned(LocalAddress, 4); // Copy the whole instruction out.
226224 Immediate = ((Immediate >> 4) & 0xf000) | (Immediate & 0xfff);
227225
228226 ++RelI;