[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:
Nick Kledzik 2014-09-03 21:09:24 +00:00
parent 89854ebe8e
commit 0e3e6155fe
2 changed files with 98 additions and 65 deletions

View File

@ -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");
}

View File

@ -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: