mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
ARM non-scattered MachO relocations for movw/movt.
Needed when building -mdynamic-no-pic code. rdar://10459256 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153097 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1fc999ec47
commit
07cdd80ccc
@ -34,7 +34,7 @@ class ARMMachObjectWriter : public MCMachObjectTargetWriter {
|
|||||||
MCValue Target,
|
MCValue Target,
|
||||||
unsigned Log2Size,
|
unsigned Log2Size,
|
||||||
uint64_t &FixedValue);
|
uint64_t &FixedValue);
|
||||||
void RecordARMMovwMovtRelocation(MachObjectWriter *Writer,
|
void RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,
|
||||||
const MCAssembler &Asm,
|
const MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout,
|
const MCAsmLayout &Layout,
|
||||||
const MCFragment *Fragment,
|
const MCFragment *Fragment,
|
||||||
@ -102,28 +102,41 @@ static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
|
|||||||
Log2Size = llvm::Log2_32(4);
|
Log2Size = llvm::Log2_32(4);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// For movw/movt r_type relocations they always have a pair following them and
|
||||||
|
// the r_length bits are used differently. The encoding of the r_length is as
|
||||||
|
// follows:
|
||||||
|
// low bit of r_length:
|
||||||
|
// 0 - :lower16: for movw instructions
|
||||||
|
// 1 - :upper16: for movt instructions
|
||||||
|
// high bit of r_length:
|
||||||
|
// 0 - arm instructions
|
||||||
|
// 1 - thumb instructions
|
||||||
case ARM::fixup_arm_movt_hi16:
|
case ARM::fixup_arm_movt_hi16:
|
||||||
case ARM::fixup_arm_movt_hi16_pcrel:
|
case ARM::fixup_arm_movt_hi16_pcrel:
|
||||||
|
RelocType = unsigned(macho::RIT_ARM_Half);
|
||||||
|
Log2Size = 1;
|
||||||
|
return true;
|
||||||
case ARM::fixup_t2_movt_hi16:
|
case ARM::fixup_t2_movt_hi16:
|
||||||
case ARM::fixup_t2_movt_hi16_pcrel:
|
case ARM::fixup_t2_movt_hi16_pcrel:
|
||||||
RelocType = unsigned(macho::RIT_ARM_HalfDifference);
|
RelocType = unsigned(macho::RIT_ARM_Half);
|
||||||
// Report as 'long', even though that is not quite accurate.
|
Log2Size = 3;
|
||||||
Log2Size = llvm::Log2_32(4);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ARM::fixup_arm_movw_lo16:
|
case ARM::fixup_arm_movw_lo16:
|
||||||
case ARM::fixup_arm_movw_lo16_pcrel:
|
case ARM::fixup_arm_movw_lo16_pcrel:
|
||||||
|
RelocType = unsigned(macho::RIT_ARM_Half);
|
||||||
|
Log2Size = 0;
|
||||||
|
return true;
|
||||||
case ARM::fixup_t2_movw_lo16:
|
case ARM::fixup_t2_movw_lo16:
|
||||||
case ARM::fixup_t2_movw_lo16_pcrel:
|
case ARM::fixup_t2_movw_lo16_pcrel:
|
||||||
RelocType = unsigned(macho::RIT_ARM_Half);
|
RelocType = unsigned(macho::RIT_ARM_Half);
|
||||||
// Report as 'long', even though that is not quite accurate.
|
Log2Size = 2;
|
||||||
Log2Size = llvm::Log2_32(4);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMMachObjectWriter::
|
void ARMMachObjectWriter::
|
||||||
RecordARMMovwMovtRelocation(MachObjectWriter *Writer,
|
RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,
|
||||||
const MCAssembler &Asm,
|
const MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout,
|
const MCAsmLayout &Layout,
|
||||||
const MCFragment *Fragment,
|
const MCFragment *Fragment,
|
||||||
@ -313,10 +326,9 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,
|
|||||||
// scattered relocation entry. Differences always require scattered
|
// scattered relocation entry. Differences always require scattered
|
||||||
// relocations.
|
// relocations.
|
||||||
if (Target.getSymB()) {
|
if (Target.getSymB()) {
|
||||||
if (RelocType == macho::RIT_ARM_Half ||
|
if (RelocType == macho::RIT_ARM_Half)
|
||||||
RelocType == macho::RIT_ARM_HalfDifference)
|
return RecordARMScatteredHalfRelocation(Writer, Asm, Layout, Fragment,
|
||||||
return RecordARMMovwMovtRelocation(Writer, Asm, Layout, Fragment, Fixup,
|
Fixup, Target, FixedValue);
|
||||||
Target, FixedValue);
|
|
||||||
return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
|
return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
|
||||||
Target, Log2Size, FixedValue);
|
Target, Log2Size, FixedValue);
|
||||||
}
|
}
|
||||||
@ -391,6 +403,30 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,
|
|||||||
(Log2Size << 25) |
|
(Log2Size << 25) |
|
||||||
(IsExtern << 27) |
|
(IsExtern << 27) |
|
||||||
(Type << 28));
|
(Type << 28));
|
||||||
|
|
||||||
|
// Even when it's not a scattered relocation, movw/movt always uses
|
||||||
|
// a PAIR relocation.
|
||||||
|
if (Type == macho::RIT_ARM_Half) {
|
||||||
|
// The other-half value only gets populated for the movt relocation.
|
||||||
|
uint32_t Value = 0;;
|
||||||
|
switch ((unsigned)Fixup.getKind()) {
|
||||||
|
default: break;
|
||||||
|
case ARM::fixup_arm_movt_hi16:
|
||||||
|
case ARM::fixup_arm_movt_hi16_pcrel:
|
||||||
|
case ARM::fixup_t2_movt_hi16:
|
||||||
|
case ARM::fixup_t2_movt_hi16_pcrel:
|
||||||
|
Value = FixedValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
macho::RelocationEntry MREPair;
|
||||||
|
MREPair.Word0 = Value;
|
||||||
|
MREPair.Word1 = ((0xffffff) |
|
||||||
|
(Log2Size << 25) |
|
||||||
|
(macho::RIT_Pair << 28));
|
||||||
|
|
||||||
|
Writer->addRelocation(Fragment->getParent(), MREPair);
|
||||||
|
}
|
||||||
|
|
||||||
Writer->addRelocation(Fragment->getParent(), MRE);
|
Writer->addRelocation(Fragment->getParent(), MRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
test/MC/MachO/ARM/static-movt-relocs.s
Normal file
23
test/MC/MachO/ARM/static-movt-relocs.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumbv7-apple-darwin10 -filetype=obj -o - < %s | macho-dump | FileCheck %s
|
||||||
|
.thumb
|
||||||
|
.thumb_func foo
|
||||||
|
foo:
|
||||||
|
movw r0, :lower16:(bar + 16)
|
||||||
|
movt r0, :upper16:(bar + 16)
|
||||||
|
bx r0
|
||||||
|
|
||||||
|
|
||||||
|
@ CHECK: ('_relocations', [
|
||||||
|
@ CHECK: # Relocation 0
|
||||||
|
@ CHECK: (('word-0', 0x4),
|
||||||
|
@ CHECK: ('word-1', 0x8e000001)),
|
||||||
|
@ CHECK: # Relocation 1
|
||||||
|
@ CHECK: (('word-0', 0x10),
|
||||||
|
@ CHECK: ('word-1', 0x16ffffff)),
|
||||||
|
@ CHECK: # Relocation 2
|
||||||
|
@ CHECK: (('word-0', 0x0),
|
||||||
|
@ CHECK: ('word-1', 0x8c000001)),
|
||||||
|
@ CHECK: # Relocation 3
|
||||||
|
@ CHECK: (('word-0', 0x0),
|
||||||
|
@ CHECK: ('word-1', 0x14ffffff)),
|
||||||
|
@ CHECK: ])
|
Loading…
x
Reference in New Issue
Block a user