From b6e8ce82509e9ba93238a6eb90fed2007db1bc76 Mon Sep 17 00:00:00 2001 From: Nick Kledzik Date: Thu, 3 Jul 2014 02:01:21 +0000 Subject: [PATCH] [mach-o] add x86 test case to build hello world. Fix bugs it uncovered. llvm-svn: 212247 --- .../MachO/MachONormalizedFileFromAtoms.cpp | 6 +- lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp | 31 +++++--- lld/lib/ReaderWriter/MachO/ReferenceKinds.h | 19 ++--- lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp | 22 +++--- lld/test/mach-o/hello-world-x86.yaml | 83 ++++++++++++++++++++++ 5 files changed, 126 insertions(+), 35 deletions(-) create mode 100644 lld/test/mach-o/hello-world-x86.yaml diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 9f348a3..3befd6a 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -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); } } } diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp index 28cacf3..1d06bed 100644 --- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp +++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.cpp @@ -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(location); + int16_t *loc16 = reinterpret_cast(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: - *loc32 = targetAddress + addend; + case branch16: + *loc16 = (targetAddress - (fixupAddress+4)) + addend; break; - case LLD_X86_RELOC_FUNC_REL32: + case pointer32: + case abs32: *loc32 = targetAddress + addend; break; - case LLD_X86_RELOC_LAZY_TARGET: - case LLD_X86_RELOC_LAZY_IMMEDIATE: + case funcRel32: + *loc32 = targetAddress - inAtomAddress + addend; // FIXME + break; + 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); diff --git a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h index 46bf585..c2d265f 100644 --- a/lld/lib/ReaderWriter/MachO/ReferenceKinds.h +++ b/lld/lib/ReaderWriter/MachO/ReferenceKinds.h @@ -25,14 +25,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 LLD_ARM_RELOC_THUMB_REL_LO16 = 102, // thumb movw of (target - pc) @@ -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 diff --git a/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp b/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp index ff7296b..0d49454 100644 --- a/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp +++ b/lld/lib/ReaderWriter/MachO/StubAtoms_x86.hpp @@ -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); } diff --git a/lld/test/mach-o/hello-world-x86.yaml b/lld/test/mach-o/hello-world-x86.yaml new file mode 100644 index 0000000..8bb3909 --- /dev/null +++ b/lld/test/mach-o/hello-world-x86.yaml @@ -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 -- 2.7.4