[mach-o] Improve x86_64 reference kind switch statements.
The use of default: was disabling the warning about unused enumerators. Fix that, then fix the one enumerator that was not handled. Add coverage for it in test suite. llvm-svn: 217078
This commit is contained in:
parent
89854ebe8e
commit
0e3e6155fe
|
@ -105,7 +105,7 @@ private:
|
|||
static const Registry::KindStrings _sKindStrings[];
|
||||
static const StubInfo _sStubInfo;
|
||||
|
||||
enum : Reference::KindValue {
|
||||
enum X86_64_Kinds: Reference::KindValue {
|
||||
invalid, /// for error condition
|
||||
|
||||
// Kinds found in mach-o .o files:
|
||||
|
@ -413,48 +413,50 @@ void ArchHandler_x86_64::applyFixupFinal(const Reference &ref,
|
|||
assert(ref.kindArch() == Reference::KindArch::x86_64);
|
||||
int32_t *loc32 = reinterpret_cast<int32_t *>(location);
|
||||
uint64_t *loc64 = reinterpret_cast<uint64_t *>(location);
|
||||
switch (ref.kindValue()) {
|
||||
switch (static_cast<X86_64_Kinds>(ref.kindValue())) {
|
||||
case branch32:
|
||||
case ripRel32:
|
||||
case ripRel32Anon:
|
||||
case ripRel32Got:
|
||||
case ripRel32GotLoad:
|
||||
write32(*loc32, _swap, (targetAddress - (fixupAddress + 4)) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case pointer64:
|
||||
case pointer64Anon:
|
||||
write64(*loc64, _swap, targetAddress + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus1:
|
||||
write32(*loc32, _swap, (targetAddress - (fixupAddress + 5)) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus2:
|
||||
write32(*loc32, _swap, (targetAddress - (fixupAddress + 6)) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus4:
|
||||
write32(*loc32, _swap, (targetAddress - (fixupAddress + 8)) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case delta32:
|
||||
case delta32Anon:
|
||||
write32(*loc32, _swap, (targetAddress - fixupAddress) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case delta64:
|
||||
case delta64Anon:
|
||||
write64(*loc64, _swap, (targetAddress - fixupAddress) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32GotLoadNowLea:
|
||||
// Change MOVQ to LEA
|
||||
assert(location[-2] == 0x8B);
|
||||
location[-2] = 0x8D;
|
||||
write32(*loc32, _swap, (targetAddress - (fixupAddress + 4)) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case lazyPointer:
|
||||
case lazyImmediateLocation:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("invalid x86_64 Reference Kind");
|
||||
return;
|
||||
case invalid:
|
||||
// Fall into llvm_unreachable().
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("invalid x86_64 Reference Kind");
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,51 +467,55 @@ void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
|
|||
uint64_t inAtomAddress) {
|
||||
int32_t *loc32 = reinterpret_cast<int32_t *>(location);
|
||||
uint64_t *loc64 = reinterpret_cast<uint64_t *>(location);
|
||||
switch (ref.kindValue()) {
|
||||
switch (static_cast<X86_64_Kinds>(ref.kindValue())) {
|
||||
case branch32:
|
||||
case ripRel32:
|
||||
case ripRel32Got:
|
||||
case ripRel32GotLoad:
|
||||
write32(*loc32, _swap, ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32Anon:
|
||||
write32(*loc32, _swap, (targetAddress - (fixupAddress + 4)) + ref.addend());
|
||||
return;
|
||||
case pointer64:
|
||||
write64(*loc64, _swap, ref.addend());
|
||||
break;
|
||||
return;
|
||||
case pointer64Anon:
|
||||
write64(*loc64, _swap, targetAddress + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus1:
|
||||
write32(*loc32, _swap, ref.addend() - 1);
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus2:
|
||||
write32(*loc32, _swap, ref.addend() - 2);
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus4:
|
||||
write32(*loc32, _swap, ref.addend() - 4);
|
||||
break;
|
||||
return;
|
||||
case delta32:
|
||||
write32(*loc32, _swap, ref.addend() + inAtomAddress - fixupAddress);
|
||||
break;
|
||||
return;
|
||||
case delta32Anon:
|
||||
write32(*loc32, _swap, (targetAddress - fixupAddress) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case delta64:
|
||||
write64(*loc64, _swap, ref.addend() + inAtomAddress - fixupAddress);
|
||||
break;
|
||||
return;
|
||||
case delta64Anon:
|
||||
write64(*loc64, _swap, (targetAddress - fixupAddress) + ref.addend());
|
||||
break;
|
||||
return;
|
||||
case ripRel32GotLoadNowLea:
|
||||
llvm_unreachable("ripRel32GotLoadNowLea implies GOT pass was run");
|
||||
break;
|
||||
return;
|
||||
case lazyPointer:
|
||||
case lazyImmediateLocation:
|
||||
llvm_unreachable("lazy reference kind implies Stubs pass was run");
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unknown x86_64 Reference Kind");
|
||||
return;
|
||||
case invalid:
|
||||
// Fall into llvm_unreachable().
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("unknown x86_64 Reference Kind");
|
||||
}
|
||||
|
||||
void ArchHandler_x86_64::appendSectionRelocations(
|
||||
|
@ -524,78 +530,83 @@ void ArchHandler_x86_64::appendSectionRelocations(
|
|||
return;
|
||||
assert(ref.kindArch() == Reference::KindArch::x86_64);
|
||||
uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom();
|
||||
switch (ref.kindValue()) {
|
||||
switch (static_cast<X86_64_Kinds>(ref.kindValue())) {
|
||||
case branch32:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_BRANCH | rPcRel | rExtern | rLength4);
|
||||
break;
|
||||
return;
|
||||
case ripRel32:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_SIGNED | rPcRel | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case ripRel32Anon:
|
||||
appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_SIGNED | rPcRel | rLength4 );
|
||||
return;
|
||||
case ripRel32Got:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_GOT | rPcRel | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case ripRel32GotLoad:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_GOT_LOAD | rPcRel | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case pointer64:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_UNSIGNED | rExtern | rLength8);
|
||||
break;
|
||||
return;
|
||||
case pointer64Anon:
|
||||
appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_UNSIGNED | rLength8);
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus1:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_SIGNED_1 | rPcRel | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus2:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_SIGNED_2 | rPcRel | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case ripRel32Minus4:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_SIGNED_4 | rPcRel | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case delta32:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
|
||||
X86_64_RELOC_SUBTRACTOR | rExtern | rLength4 );
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_UNSIGNED | rExtern | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case delta32Anon:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
|
||||
X86_64_RELOC_SUBTRACTOR | rExtern | rLength4 );
|
||||
appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_UNSIGNED | rLength4 );
|
||||
break;
|
||||
return;
|
||||
case delta64:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
|
||||
X86_64_RELOC_SUBTRACTOR | rExtern | rLength8 );
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_UNSIGNED | rExtern | rLength8 );
|
||||
break;
|
||||
return;
|
||||
case delta64Anon:
|
||||
appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
|
||||
X86_64_RELOC_SUBTRACTOR | rExtern | rLength8 );
|
||||
appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
|
||||
X86_64_RELOC_UNSIGNED | rLength8 );
|
||||
break;
|
||||
return;
|
||||
case ripRel32GotLoadNowLea:
|
||||
llvm_unreachable("ripRel32GotLoadNowLea implies GOT pass was run");
|
||||
break;
|
||||
return;
|
||||
case lazyPointer:
|
||||
case lazyImmediateLocation:
|
||||
llvm_unreachable("lazy reference kind implies Stubs pass was run");
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("unknown x86_64 Reference Kind");
|
||||
return;
|
||||
case invalid:
|
||||
// Fall into llvm_unreachable().
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("unknown x86_64 Reference Kind");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -18,29 +18,38 @@
|
|||
# movb $0x12, _foo(%rip)
|
||||
# movw $0x1234, _foo(%rip)
|
||||
# movl $0x12345678, _foo(%rip)
|
||||
# movl L2(%rip), %eax
|
||||
#
|
||||
# .data
|
||||
#L2: .long 0
|
||||
|
||||
|
||||
--- !mach-o
|
||||
arch: x86_64
|
||||
file-type: MH_OBJECT
|
||||
flags: [ ]
|
||||
has-UUID: false
|
||||
OS: unknown
|
||||
sections:
|
||||
sections:
|
||||
- segment: __TEXT
|
||||
section: __text
|
||||
type: S_REGULAR
|
||||
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
|
||||
address: 0x0000000000000000
|
||||
content: [ 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x04, 0x00,
|
||||
0x00, 0x00, 0x48, 0x8B, 0x05, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x35, 0x00, 0x00, 0x00, 0x00, 0x8B,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x05, 0x04,
|
||||
0x00, 0x00, 0x00, 0xC6, 0x05, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x12, 0x66, 0xC7, 0x05, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0x34, 0x12, 0xC7, 0x05, 0xFC, 0xFF, 0xFF,
|
||||
0xFF, 0x78, 0x56, 0x34, 0x12 ]
|
||||
relocations:
|
||||
content: [ 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x04, 0x00,
|
||||
0x00, 0x00, 0x48, 0x8B, 0x05, 0x00, 0x00, 0x00,
|
||||
0x00, 0xFF, 0x35, 0x00, 0x00, 0x00, 0x00, 0x8B,
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x05, 0x04,
|
||||
0x00, 0x00, 0x00, 0xC6, 0x05, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x12, 0x66, 0xC7, 0x05, 0xFE, 0xFF, 0xFF,
|
||||
0xFF, 0x34, 0x12, 0xC7, 0x05, 0xFC, 0xFF, 0xFF,
|
||||
0xFF, 0x78, 0x56, 0x34, 0x12, 0x8B, 0x05, 0x00,
|
||||
0x00, 0x00, 0x00 ]
|
||||
relocations:
|
||||
- offset: 0x0000003F
|
||||
type: X86_64_RELOC_SIGNED
|
||||
length: 2
|
||||
pc-rel: true
|
||||
extern: false
|
||||
symbol: 2
|
||||
- offset: 0x00000035
|
||||
type: X86_64_RELOC_SIGNED_4
|
||||
length: 2
|
||||
|
@ -95,20 +104,30 @@ sections:
|
|||
pc-rel: true
|
||||
extern: true
|
||||
symbol: 1
|
||||
local-symbols:
|
||||
- segment: __DATA
|
||||
section: __data
|
||||
type: S_REGULAR
|
||||
attributes: [ ]
|
||||
address: 0x0000000000000043
|
||||
content: [ 0x00, 0x00, 0x00, 0x00 ]
|
||||
local-symbols:
|
||||
- name: _test
|
||||
type: N_SECT
|
||||
sect: 1
|
||||
value: 0x0000000000000000
|
||||
undefined-symbols:
|
||||
undefined-symbols:
|
||||
- name: _foo
|
||||
type: N_UNDF
|
||||
scope: [ N_EXT ]
|
||||
value: 0x0000000000000000
|
||||
...
|
||||
|
||||
# CHECK: defined-atoms:
|
||||
# CHECK: - ref-name: [[LABEL:L[0-9]+]]
|
||||
# CHECK: type: data
|
||||
# CHECK: content: [ 00, 00, 00, 00 ]
|
||||
# CHECK: - name: _test
|
||||
# CHECK: references:
|
||||
# CHECK: references:
|
||||
# CHECK: - kind: branch32
|
||||
# CHECK: offset: 1
|
||||
# CHECK: target: _foo
|
||||
|
@ -132,13 +151,16 @@ undefined-symbols:
|
|||
# CHECK: - kind: ripRel32Minus1
|
||||
# CHECK: offset: 37
|
||||
# CHECK: target: _foo
|
||||
# CHECK-NOT: addend:
|
||||
# CHECK-NOT: addend:
|
||||
# CHECK: - kind: ripRel32Minus2
|
||||
# CHECK: offset: 45
|
||||
# CHECK: target: _foo
|
||||
# CHECK-NOT: addend:
|
||||
# CHECK-NOT: addend:
|
||||
# CHECK: - kind: ripRel32Minus4
|
||||
# CHECK: offset: 53
|
||||
# CHECK: target: _foo
|
||||
# CHECK-NOT: addend:
|
||||
|
||||
# CHECK-NOT: addend:
|
||||
# CHECK: - kind: ripRel32Anon
|
||||
# CHECK: offset: 63
|
||||
# CHECK: target: [[LABEL]]
|
||||
# CHECK-NOT: addend:
|
||||
|
|
Loading…
Reference in New Issue