[mach-o] add x86 test case to build hello world. Fix bugs it uncovered.

llvm-svn: 212247
This commit is contained in:
Nick Kledzik 2014-07-03 02:01:21 +00:00
parent 1d0089fa5c
commit b6e8ce8250
5 changed files with 126 additions and 35 deletions

View File

@ -536,14 +536,16 @@ void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
uint64_t targetAddress = 0;
if ( ref->target() != nullptr )
targetAddress = _atomToAddress[ref->target()];
uint64_t fixupAddress = _atomToAddress[ai.atom] + offset;
uint64_t atomAddress = _atomToAddress[ai.atom];
uint64_t fixupAddress = atomAddress + offset;
if ( rMode ) {
// FIXME: Need a handler method to update content for .o file
// output and any needed section relocations.
} else {
_context.kindHandler().applyFixup(
ref->kindNamespace(), ref->kindArch(), ref->kindValue(),
ref->addend(), &atomContent[offset], fixupAddress, targetAddress);
ref->addend(), &atomContent[offset], fixupAddress, targetAddress,
atomAddress);
}
}
}

View File

@ -351,7 +351,8 @@ void KindHandler_x86_64::applyFixup(Reference::KindNamespace ns,
Reference::KindValue kindValue,
uint64_t addend, uint8_t *location,
uint64_t fixupAddress,
uint64_t targetAddress) {
uint64_t targetAddress,
uint64_t inAtomAddress) {
if (ns != Reference::KindNamespace::mach_o)
return;
assert(arch == Reference::KindArch::x86_64);
@ -577,24 +578,33 @@ void KindHandler_x86::applyFixup(Reference::KindNamespace ns,
Reference::KindValue kindValue,
uint64_t addend, uint8_t *location,
uint64_t fixupAddress,
uint64_t targetAddress) {
uint64_t targetAddress,
uint64_t inAtomAddress) {
if (ns != Reference::KindNamespace::mach_o)
return;
assert(arch == Reference::KindArch::x86);
int32_t *loc32 = reinterpret_cast<int32_t*>(location);
int16_t *loc16 = reinterpret_cast<int16_t*>(location);
// FIXME: these writes may need a swap.
switch (kindValue) {
case LLD_X86_RELOC_BRANCH32:
case branch32:
*loc32 = (targetAddress - (fixupAddress+4)) + addend;
break;
case LLD_X86_RELOC_POINTER32:
case LLD_X86_RELOC_ABS32:
case branch16:
*loc16 = (targetAddress - (fixupAddress+4)) + addend;
break;
case pointer32:
case abs32:
*loc32 = targetAddress + addend;
break;
case LLD_X86_RELOC_FUNC_REL32:
*loc32 = targetAddress + addend;
case funcRel32:
*loc32 = targetAddress - inAtomAddress + addend; // FIXME
break;
case LLD_X86_RELOC_LAZY_TARGET:
case LLD_X86_RELOC_LAZY_IMMEDIATE:
case delta32:
*loc32 = targetAddress - fixupAddress + addend;
break;
case lazyPointer:
case lazyImmediateLocation:
// do nothing
break;
default:
@ -647,7 +657,8 @@ void KindHandler_arm::applyFixup(Reference::KindNamespace ns,
Reference::KindValue kindValue,
uint64_t addend, uint8_t *location,
uint64_t fixupAddress,
uint64_t targetAddress) {
uint64_t targetAddress,
uint64_t inAtomAddress) {
if (ns != Reference::KindNamespace::mach_o)
return;
assert(arch == Reference::KindArch::ARM);

View File

@ -24,14 +24,6 @@ namespace mach_o {
// Additional Reference Kind values used internally.
enum {
LLD_X86_RELOC_BRANCH32 = 100, // CALL or JMP 32-bit pc-rel
LLD_X86_RELOC_ABS32 = 101, // 32-bit absolute addr in instruction
LLD_X86_RELOC_FUNC_REL32 = 102, // 32-bit target from start of func
LLD_X86_RELOC_POINTER32 = 103, // 32-bit data pointer
LLD_X86_RELOC_LAZY_TARGET = 104,
LLD_X86_RELOC_LAZY_IMMEDIATE = 105
};
enum {
LLD_ARM_RELOC_THUMB_ABS_LO16 = 100, // thumb movw of absolute address
LLD_ARM_RELOC_THUMB_ABS_HI16 = 101, // thumb movt of absolute address
@ -108,7 +100,7 @@ public:
virtual void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue kindValue, uint64_t addend,
uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress) = 0;
uint64_t targetAddress, uint64_t inAtomAddress) = 0;
protected:
KindHandler();
@ -168,7 +160,8 @@ public:
virtual void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue kindValue, uint64_t addend,
uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress) override;
uint64_t targetAddress, uint64_t inAtomAddress)
override;
private:
friend class X86_64LazyPointerAtom;
@ -245,7 +238,8 @@ public:
void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue kindValue, uint64_t addend,
uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress) override;
uint64_t targetAddress, uint64_t inAtomAddress)
override;
private:
friend class X86LazyPointerAtom;
@ -287,7 +281,8 @@ public:
void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
Reference::KindValue kindValue, uint64_t addend,
uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress) override;
uint64_t targetAddress, uint64_t inAtomAddress)
override;
};
} // namespace mach_o

View File

@ -32,7 +32,7 @@ public:
X86StubAtom(const File &file, const Atom &lazyPointer)
: SimpleDefinedAtom(file) {
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_ABS32, 2,
Reference::KindArch::x86, KindHandler_x86::abs32, 2,
&lazyPointer, 0);
}
@ -66,10 +66,10 @@ public:
const Atom &binder)
: SimpleDefinedAtom(file) {
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_ABS32, 1, &cache,
0);
Reference::KindArch::x86, KindHandler_x86::abs32, 1,
&cache, 0);
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_ABS32, 7,
Reference::KindArch::x86, KindHandler_x86::abs32, 7,
&binder, 0);
}
@ -104,10 +104,10 @@ public:
X86StubHelperAtom(const File &file, const Atom &helperCommon)
: SimpleDefinedAtom(file) {
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_LAZY_IMMEDIATE,
1, this, 0);
Reference::KindArch::x86,
KindHandler_x86::lazyImmediateLocation, 1, this, 0);
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_BRANCH32, 6,
Reference::KindArch::x86, KindHandler_x86::branch32, 6,
&helperCommon, 0);
}
@ -141,11 +141,11 @@ public:
X86LazyPointerAtom(const File &file, const Atom &helper, const Atom &shlib)
: SimpleDefinedAtom(file) {
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_POINTER32, 0,
Reference::KindArch::x86, KindHandler_x86::pointer32, 0,
&helper, 0);
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_LAZY_TARGET, 0,
&shlib, 0);
Reference::KindArch::x86, KindHandler_x86::lazyPointer,
0, &shlib, 0);
}
ContentType contentType() const override {
@ -182,7 +182,7 @@ public:
X86NonLazyPointerAtom(const File &file, const Atom &shlib)
: SimpleDefinedAtom(file) {
this->addReference(Reference::KindNamespace::mach_o,
Reference::KindArch::x86, LLD_X86_RELOC_POINTER32, 0,
Reference::KindArch::x86, KindHandler_x86::pointer32, 0,
&shlib, 0);
}

View File

@ -0,0 +1,83 @@
# RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s -o %t && \
# RUN: llvm-nm %t | FileCheck %s
#
# Test that i386 hello-world can be linked into a mach-o executable
#
--- !mach-o
arch: x86
file-type: MH_OBJECT
flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
sections:
- segment: __TEXT
section: __text
type: S_REGULAR
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
address: 0x0000000000000000
content: [ 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8, 0x00,
0x00, 0x00, 0x00, 0x58, 0x8D, 0x80, 0x16, 0x00,
0x00, 0x00, 0x89, 0x04, 0x24, 0xE8, 0xE6, 0xFF,
0xFF, 0xFF, 0x31, 0xC0, 0x83, 0xC4, 0x08, 0x5D,
0xC3 ]
relocations:
- offset: 0x00000016
type: GENERIC_RELOC_VANILLA
length: 2
pc-rel: true
extern: true
symbol: 1
- offset: 0x0000000E
scattered: true
type: GENERIC_RELOC_LOCAL_SECTDIFF
length: 2
pc-rel: false
value: 0x00000021
- offset: 0x00000000
scattered: true
type: GENERIC_RELOC_PAIR
length: 2
pc-rel: false
value: 0x0000000B
- segment: __TEXT
section: __cstring
type: S_CSTRING_LITERALS
attributes: [ ]
address: 0x0000000000000021
content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
global-symbols:
- name: _main
type: N_SECT
scope: [ N_EXT ]
sect: 1
value: 0x0000000000000000
undefined-symbols:
- name: _printf
type: N_UNDF
scope: [ N_EXT ]
value: 0x0000000000000000
--- !mach-o
arch: x86
file-type: MH_DYLIB
flags: [ ]
install-name: /usr/lib/libSystem.B.dylib
sections:
- segment: __TEXT
section: __text
type: S_REGULAR
attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
address: 0x0000000000000000
content: [ 0x55 ]
global-symbols:
- name: _printf
type: N_SECT
scope: [ N_EXT ]
sect: 1
value: 0x0000000000000001
...
# CHECK: {{[0-9a-f]+}} T _main
# CHECK: U _printf
# CHECK: U dyld_stub_binder