[llvm-commits] [lld] r158336 - in /lld/trunk: include/lld/ReaderWriter/WriterMachO.h lib/ReaderWriter/MachO/CMakeLists.txt lib/ReaderWriter/MachO/MachOFormat.hpp lib/ReaderWriter/MachO/ReferenceKinds.cpp lib/ReaderWriter/MachO/ReferenceKinds.h lib/ReaderWriter/MachO/StubAtoms.hpp lib/ReaderWriter/MachO/StubAtoms_x86.hpp lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp lib/ReaderWriter/MachO/StubsPass.hpp lib/ReaderWriter/MachO/WriterMachO.cpp lib/ReaderWriter/MachO/WriterOptionsMachO.cpp lib/ReaderWriter/YAML/WriterYAML.cpp
Nick Kledzik
kledzik at apple.com
Mon Jun 11 15:53:16 PDT 2012
Author: kledzik
Date: Mon Jun 11 17:53:15 2012
New Revision: 158336
URL: http://llvm.org/viewvc/llvm-project?rev=158336&view=rev
Log:
Move implementation of WriterOptionsMachO to its own file. Reduced redundant
ivars in WriterOptionsMachO instead have its methods compute ivar interactions.
Refactor mach-o Reference Kinds and introduce abstract class KindHandler.
Split up StubAtoms.hpp by architecture. Add support for 32-bit x86 stubs.
Added:
lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp
lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp
lld/trunk/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp
Modified:
lld/trunk/include/lld/ReaderWriter/WriterMachO.h
lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
lld/trunk/lib/ReaderWriter/MachO/MachOFormat.hpp
lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp
lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h
lld/trunk/lib/ReaderWriter/MachO/StubAtoms.hpp
lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp
lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp
lld/trunk/lib/ReaderWriter/YAML/WriterYAML.cpp
Modified: lld/trunk/include/lld/ReaderWriter/WriterMachO.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/WriterMachO.h?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/WriterMachO.h (original)
+++ lld/trunk/include/lld/ReaderWriter/WriterMachO.h Mon Jun 11 17:53:15 2012
@@ -51,25 +51,27 @@
enum Architecture {
arch_x86_64,
arch_x86,
- arch_arm,
+ arch_armv6,
+ arch_armv7,
};
- OutputKind outputKind() const { return _outputkind; }
- Architecture architecture() const { return _architecture; }
- StringRef archName() const { return _archName; }
- uint64_t pageZeroSize() const { return _pageZeroSize; }
- uint32_t cpuType() const { return _cpuType; }
- uint32_t cpuSubtype() const { return _cpuSubtype; }
- bool noTextRelocations() const { return _noTextRelocations; }
-
+ OutputKind outputKind() const { return _outputkind; }
+ Architecture architecture() const { return _architecture; }
+ StringRef archName() const;
+ uint32_t cpuType() const;
+ uint32_t cpuSubtype() const;
+ uint64_t pageZeroSize() const;
+ bool noTextRelocations() const { return _noTextRelocations; }
+ bool addEntryPointLoadCommand() const;
+ bool addUnixThreadLoadCommand() const;
+ StringRef entryPointName() const;
+
protected:
OutputKind _outputkind;
- StringRef _archName;
Architecture _architecture;
uint64_t _pageZeroSize;
- uint32_t _cpuType;
- uint32_t _cpuSubtype;
bool _noTextRelocations;
+ StringRef _customEntryPointName;
};
Modified: lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Mon Jun 11 17:53:15 2012
@@ -1,4 +1,5 @@
add_lld_library(lldMachO
WriterMachO.cpp
+ WriterOptionsMachO.cpp
ReferenceKinds.cpp
)
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOFormat.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOFormat.hpp?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOFormat.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOFormat.hpp Mon Jun 11 17:53:15 2012
@@ -131,7 +131,7 @@
};
-void mach_header::recordLoadCommand(const load_command *lc) {
+inline void mach_header::recordLoadCommand(const load_command *lc) {
++ncmds;
sizeofcmds += lc->cmdsize;
}
@@ -140,6 +140,7 @@
enum {
LC_SEGMENT = 0x00000001,
LC_SYMTAB = 0x00000002,
+ LC_UNIXTHREAD = 0x00000005,
LC_LOAD_DYLIB = 0x0000000C,
LC_LOAD_DYLINKER = 0x0000000E,
LC_SEGMENT_64 = 0x00000019,
@@ -375,6 +376,95 @@
};
+//
+// The thread_command load command holds the set of initial register values
+// for a dynamic executable. In reality, only the PC and SP are used.
+//
+class thread_command : public load_command {
+public:
+ uint32_t fields_flavor;
+ uint32_t fields_count;
+private:
+ uint32_t _cpuType;
+ uint8_t *_registerArray;
+
+public:
+ thread_command(uint32_t cpuType, bool is64)
+ : load_command(LC_UNIXTHREAD, 16+registersBufferSize(cpuType), is64),
+ fields_count(registersBufferSize(cpuType)/4), _cpuType(cpuType) {
+ switch ( cpuType ) {
+ case CPU_TYPE_I386:
+ fields_flavor = 1; // i386_THREAD_STATE
+ break;
+ case CPU_TYPE_X86_64:
+ fields_flavor = 4; // x86_THREAD_STATE64;
+ break;
+ case CPU_TYPE_ARM:
+ fields_flavor = 1; // ARM_THREAD_STATE
+ break;
+ default:
+ assert(0 && "unsupported cpu type");
+ }
+ _registerArray = reinterpret_cast<uint8_t*>(
+ ::calloc(registersBufferSize(cpuType), 1));
+ assert(_registerArray);
+ }
+
+ virtual void copyTo(uint8_t *to, bool swap=false) {
+ if ( swap ) {
+ assert(0 && "non-native endianness not supported yet");
+ }
+ else {
+ // in-memory matches on-disk, so copy fixed fields
+ ::memcpy(to, (uint8_t*)&cmd, 16);
+ // that register array
+ ::memcpy(&to[16], _registerArray, registersBufferSize(_cpuType));
+ }
+ }
+
+ void setPC(uint64_t pc) {
+ uint32_t *regs32 = reinterpret_cast<uint32_t*>(_registerArray);
+ uint64_t *regs64 = reinterpret_cast<uint64_t*>(_registerArray);
+ switch ( _cpuType ) {
+ case CPU_TYPE_I386:
+ regs32[10] = pc;
+ break;
+ case CPU_TYPE_X86_64:
+ regs64[16] = pc;
+ break;
+ case CPU_TYPE_ARM:
+ regs32[15] = pc;
+ break;
+ default:
+ assert(0 && "unsupported cpu type");
+ }
+ }
+
+ virtual ~thread_command() {
+ ::free(_registerArray);
+ }
+
+private:
+ uint32_t registersBufferSize(uint32_t cpuType) {
+ switch ( cpuType ) {
+ case CPU_TYPE_I386:
+ return 64; // i386_THREAD_STATE_COUNT * 4
+ case CPU_TYPE_X86_64:
+ return 168; // x86_THREAD_STATE64_COUNT * 4
+ case CPU_TYPE_ARM:
+ return 68; // ARM_THREAD_STATE_COUNT * 4
+ }
+ assert(0 && "unsupported cpu type");
+ return 0;
+ }
+
+
+
+};
+
+
+
+
//
// The dylib_command load command holds the name/path of a dynamic shared
Modified: lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp Mon Jun 11 17:53:15 2012
@@ -16,85 +16,299 @@
namespace lld {
namespace mach_o {
-
-struct Mapping {
- const char* string;
- Reference::Kind value;
- uint32_t flags;
-};
-
-enum {
- flagsNone = 0x0000,
- flagsIsCallSite = 0x0001,
- flagsUsesGOT = 0x0002,
- flagsisGOTLoad = 0x0006,
- flags32RipRel = 0x1000,
-};
-
-
-static const Mapping sKindMappingsx86_64[] = {
- { "none", ReferenceKind::x86_64_none, flagsNone },
- { "call32", ReferenceKind::x86_64_call32, flagsIsCallSite | flags32RipRel },
- { "pcrel32", ReferenceKind::x86_64_pcRel32, flags32RipRel },
- { "gotLoad32", ReferenceKind::x86_64_gotLoad32, flagsisGOTLoad | flags32RipRel },
- { "gotUse32", ReferenceKind::x86_64_gotUse32, flagsUsesGOT | flags32RipRel },
- { "lea32wasGot", ReferenceKind::x86_64_lea32WasGot, flags32RipRel },
- { "lazyTarget", ReferenceKind::x86_64_lazyTarget, flagsNone },
- { "lazyImm", ReferenceKind::x86_64_lazyImm, flagsNone },
- { "gotTarget", ReferenceKind::x86_64_gotTarget, flagsNone },
- { "pointer64", ReferenceKind::x86_64_pointer64, flagsNone },
- { NULL, ReferenceKind::x86_64_none, flagsNone }
-};
-
-
-Reference::Kind ReferenceKind::fromString(StringRef kindName) {
- for (const Mapping* p = sKindMappingsx86_64; p->string != NULL; ++p) {
- if ( kindName.equals(p->string) )
- return p->value;
+//===----------------------------------------------------------------------===//
+// KindHandler
+//===----------------------------------------------------------------------===//
+
+KindHandler::KindHandler() {
+}
+
+KindHandler::~KindHandler() {
+}
+
+KindHandler *KindHandler::makeHandler(WriterOptionsMachO::Architecture arch) {
+ switch( arch ) {
+ case WriterOptionsMachO::arch_x86_64:
+ return new KindHandler_x86_64();
+ break;
+ case WriterOptionsMachO::arch_x86:
+ return new KindHandler_x86();
+ break;
+ case WriterOptionsMachO::arch_armv6:
+ case WriterOptionsMachO::arch_armv7:
+ return new KindHandler_arm();
+ break;
+ default:
+ assert(0 && "arch not supported");
}
- assert(0 && "unknown darwin reference kind");
+}
+
+
+//===----------------------------------------------------------------------===//
+// KindHandler_x86_64
+//===----------------------------------------------------------------------===//
+
+KindHandler_x86_64::~KindHandler_x86_64() {
+}
+
+Reference::Kind KindHandler_x86_64::stringToKind(StringRef str) {
+ if ( str.equals("none") )
+ return KindHandler_x86_64::none;
+ else if ( str.equals("call32") )
+ return KindHandler_x86_64::call32;
+ else if ( str.equals("ripRel32") )
+ return KindHandler_x86_64::ripRel32;
+ else if ( str.equals("gotLoad32") )
+ return KindHandler_x86_64::gotLoad32;
+ else if ( str.equals("gotUse32") )
+ return KindHandler_x86_64::gotUse32;
+ else if ( str.equals("pointer64") )
+ return KindHandler_x86_64::pointer64;
+ else if ( str.equals("lea32WasGot") )
+ return KindHandler_x86_64::lea32WasGot;
+ else if ( str.equals("lazyTarget") )
+ return KindHandler_x86_64::lazyTarget;
+ else if ( str.equals("lazyImm") )
+ return KindHandler_x86_64::lazyImm;
+ else if ( str.equals("gotTarget") )
+ return KindHandler_x86_64::gotTarget;
+
+ assert(0 && "invalid x86_64 Reference kind");
return 0;
}
-StringRef ReferenceKind::toString(Reference::Kind kindValue) {
- for (const Mapping* p = sKindMappingsx86_64; p->string != NULL; ++p) {
- if ( kindValue == p->value)
- return p->string;
- }
- return StringRef("???");
+StringRef KindHandler_x86_64::kindToString(Reference::Kind kind) {
+ switch ( (Kinds)kind ) {
+ case none:
+ return StringRef("none");
+ case call32:
+ return StringRef("call32");
+ case ripRel32:
+ return StringRef("ripRel32");
+ case gotLoad32:
+ return StringRef("gotLoad32");
+ case gotUse32:
+ return StringRef("gotUse32");
+ case pointer64:
+ return StringRef("pointer64");
+ case lea32WasGot:
+ return StringRef("lea32WasGot");
+ case lazyTarget:
+ return StringRef("lazyTarget");
+ case lazyImm:
+ return StringRef("lazyImm");
+ case gotTarget:
+ return StringRef("gotTarget");
+ }
+ assert(0 && "invalid x86_64 Reference kind");
+ return StringRef();
}
-static const Mapping* mappingsForArch(WriterOptionsMachO::Architecture arch) {
- switch ( arch ) {
- case WriterOptionsMachO::arch_x86_64:
- return sKindMappingsx86_64;
- case WriterOptionsMachO::arch_x86:
- case WriterOptionsMachO::arch_arm:
- assert(0 && "references table not yet implemented for arch");
- return nullptr;
+bool KindHandler_x86_64::isCallSite(Kind kind) {
+ return (kind == call32);
+}
+
+bool KindHandler_x86_64::isPointer(Kind kind) {
+ return (kind == pointer64);
+}
+
+
+bool KindHandler_x86_64::isLazyImmediate(Kind kind) {
+ return (kind == lazyImm);
+}
+
+
+bool KindHandler_x86_64::isLazyTarget(Kind kind) {
+ return (kind == lazyTarget);
+}
+
+
+void KindHandler_x86_64::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress) {
+ int32_t *loc32 = reinterpret_cast<int32_t*>(location);
+ uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
+ switch ( (Kinds)kind ) {
+ case call32:
+ case ripRel32:
+ case gotLoad32:
+ case gotUse32:
+ *loc32 = (targetAddress - (fixupAddress+4)) + addend;
+ break;
+ case pointer64:
+ *loc64 = targetAddress + addend;
+ break;
+ case lea32WasGot:
+ break;
+ case none:
+ case lazyTarget:
+ case lazyImm:
+ case gotTarget:
+ // do nothing
+ break;
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// KindHandler_x86
+//===----------------------------------------------------------------------===//
+
+KindHandler_x86::~KindHandler_x86() {
+}
+
+Reference::Kind KindHandler_x86::stringToKind(StringRef str) {
+ if ( str.equals("none") )
+ return KindHandler_x86::none;
+ else if ( str.equals("call32") )
+ return KindHandler_x86::call32;
+ else if ( str.equals("abs32") )
+ return KindHandler_x86::abs32;
+ else if ( str.equals("pointer32") )
+ return KindHandler_x86::pointer32;
+ else if ( str.equals("lazyTarget") )
+ return KindHandler_x86::lazyTarget;
+ else if ( str.equals("lazyImm") )
+ return KindHandler_x86::lazyImm;
+
+ assert(0 && "invalid x86 Reference kind");
+ return 0;
+}
+
+StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
+ switch ( (Kinds)kind ) {
+ case none:
+ return StringRef("none");
+ case call32:
+ return StringRef("call32");
+ case abs32:
+ return StringRef("abs32");
+ case pointer32:
+ return StringRef("pointer32");
+ case lazyTarget:
+ return StringRef("lazyTarget");
+ case lazyImm:
+ return StringRef("lazyImm");
}
+ assert(0 && "invalid x86 Reference kind");
+ return StringRef();
+}
+
+bool KindHandler_x86::isCallSite(Kind kind) {
+ return (kind == call32);
}
-bool ReferenceKind::isCallSite(WriterOptionsMachO::Architecture arch,
- Reference::Kind kindValue) {
- for (const Mapping* p = mappingsForArch(arch); p->string != NULL; ++p) {
- if ( kindValue == p->value )
- return (p->flags & flagsIsCallSite);
+bool KindHandler_x86::isPointer(Kind kind) {
+ return (kind == pointer32);
+}
+
+
+bool KindHandler_x86::isLazyImmediate(Kind kind) {
+ return (kind == lazyImm);
+}
+
+
+bool KindHandler_x86::isLazyTarget(Kind kind) {
+ return (kind == lazyTarget);
+}
+
+
+void KindHandler_x86::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress) {
+ int32_t *loc32 = reinterpret_cast<int32_t*>(location);
+ switch ( (Kinds)kind ) {
+ case call32:
+ *loc32 = (targetAddress - (fixupAddress+4)) + addend;
+ break;
+ case pointer32:
+ case abs32:
+ *loc32 = targetAddress + addend;
+ break;
+ case none:
+ case lazyTarget:
+ case lazyImm:
+ // do nothing
+ break;
}
- return false;
}
-bool ReferenceKind::isRipRel32(Reference::Kind kindValue) {
- for (const Mapping* p = sKindMappingsx86_64; p->string != NULL; ++p) {
- if ( kindValue == p->value )
- return (p->flags & flags32RipRel);
+
+//===----------------------------------------------------------------------===//
+// KindHandler_arm
+//===----------------------------------------------------------------------===//
+
+KindHandler_arm::~KindHandler_arm() {
+}
+
+Reference::Kind KindHandler_arm::stringToKind(StringRef str) {
+ if ( str.equals("none") )
+ return KindHandler_arm::none;
+ else if ( str.equals("br22") )
+ return KindHandler_arm::br22;
+ else if ( str.equals("pointer32") )
+ return KindHandler_arm::pointer32;
+ else if ( str.equals("lazyTarget") )
+ return KindHandler_arm::lazyTarget;
+ else if ( str.equals("lazyImm") )
+ return KindHandler_arm::lazyImm;
+
+ assert(0 && "invalid ARM Reference kind");
+ return 0;
+}
+
+StringRef KindHandler_arm::kindToString(Reference::Kind kind) {
+ switch ( (Kinds)kind ) {
+ case none:
+ return StringRef("none");
+ case br22:
+ return StringRef("br22");
+ case pointer32:
+ return StringRef("pointer32");
+ case lazyTarget:
+ return StringRef("lazyTarget");
+ case lazyImm:
+ return StringRef("lazyImm");
}
- return false;
+ assert(0 && "invalid ARM Reference kind");
+ return StringRef();
}
+bool KindHandler_arm::isCallSite(Kind kind) {
+ return (kind == br22);
+}
+bool KindHandler_arm::isPointer(Kind kind) {
+ return (kind == pointer32);
+}
+
+bool KindHandler_arm::isLazyImmediate(Kind kind) {
+ return (kind == lazyImm);
+}
+
+bool KindHandler_arm::isLazyTarget(Kind kind) {
+ return (kind == lazyTarget);
+}
+
+
+void KindHandler_arm::applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress) {
+ //int32_t *loc32 = reinterpret_cast<int32_t*>(location);
+ switch ( (Kinds)kind ) {
+ case br22:
+ // FIXME
+ break;
+ case pointer32:
+ // FIXME
+ break;
+ case none:
+ case lazyTarget:
+ case lazyImm:
+ // do nothing
+ break;
+ }
+}
+
} // namespace mach_o
} // namespace lld
Modified: lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h Mon Jun 11 17:53:15 2012
@@ -19,51 +19,104 @@
namespace mach_o {
-class ReferenceKind {
+///
+/// The KindHandler class is the abstract interface to Reference::Kind
+/// values for mach-o files. Particular Kind values (e.g. 3) has a different
+/// meaning for each architecture.
+///
+class KindHandler {
public:
- // x86_64 Reference Kinds
- enum {
- x86_64_none = 0,
- x86_64_call32 = 1,
- x86_64_pcRel32 = 2,
- x86_64_gotLoad32 = 3,
- x86_64_gotUse32 = 4,
- x86_64_lea32WasGot = 5,
- x86_64_lazyTarget = 6,
- x86_64_lazyImm = 7,
- x86_64_gotTarget = 8,
- x86_64_pointer64 = 9,
+ typedef Reference::Kind Kind;
+
+ static KindHandler *makeHandler(WriterOptionsMachO::Architecture arch);
+ virtual ~KindHandler();
+ virtual Kind stringToKind(StringRef str) = 0;
+ virtual StringRef kindToString(Kind) = 0;
+ virtual bool isCallSite(Kind) = 0;
+ virtual bool isPointer(Kind) = 0;
+ virtual bool isLazyImmediate(Kind) = 0;
+ virtual bool isLazyTarget(Kind) = 0;
+ virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress) = 0;
+
+protected:
+ KindHandler();
+};
+
+
+
+class KindHandler_x86_64 : public KindHandler {
+public:
+ enum Kinds {
+ none = 0,
+ call32 = 1,
+ ripRel32 = 2,
+ gotLoad32 = 3,
+ gotUse32 = 4,
+ lea32WasGot = 5,
+ lazyTarget = 6,
+ lazyImm = 7,
+ gotTarget = 8,
+ pointer64 = 9
};
- // x86 Reference Kinds
- enum {
- x86_none = 0,
- x86_call32 = 1,
- x86_pointer32 = 2,
- x86_lazyTarget = 3,
- x86_lazyImm = 4,
- // FIXME
+ virtual ~KindHandler_x86_64();
+ virtual Kind stringToKind(StringRef str);
+ virtual StringRef kindToString(Kind);
+ virtual bool isCallSite(Kind);
+ virtual bool isPointer(Kind);
+ virtual bool isLazyImmediate(Kind);
+ virtual bool isLazyTarget(Kind);
+ virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress);
+
+};
+
+
+class KindHandler_x86 : public KindHandler {
+public:
+ enum Kinds {
+ none = 0,
+ call32 = 1,
+ abs32 = 2,
+ pointer32 = 3,
+ lazyTarget = 4,
+ lazyImm = 5
};
- // ARM Reference Kinds
- enum {
- arm_none = 0,
- arm_br22 = 1,
- arm_pointer32 = 2,
- arm_lazyTarget = 3,
- arm_lazyImm = 4,
+ virtual ~KindHandler_x86();
+ virtual Kind stringToKind(StringRef str);
+ virtual StringRef kindToString(Kind);
+ virtual bool isCallSite(Kind);
+ virtual bool isPointer(Kind);
+ virtual bool isLazyImmediate(Kind);
+ virtual bool isLazyTarget(Kind);
+ virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress);
+
+};
+
+class KindHandler_arm : public KindHandler {
+public:
+ enum Kinds {
+ none = 0,
+ br22 = 1,
+ pointer32 = 2,
+ lazyTarget = 3,
+ lazyImm = 4
// FIXME
};
- static bool isCallSite(WriterOptionsMachO::Architecture arch,
- Reference::Kind kindValue);
-
- static bool isRipRel32(Reference::Kind kindValue);
+ virtual ~KindHandler_arm();
+ virtual Kind stringToKind(StringRef str);
+ virtual StringRef kindToString(Kind);
+ virtual bool isCallSite(Kind);
+ virtual bool isPointer(Kind);
+ virtual bool isLazyImmediate(Kind);
+ virtual bool isLazyTarget(Kind);
+ virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
+ uint64_t fixupAddress, uint64_t targetAddress);
-
- static Reference::Kind fromString(StringRef kindName);
- static StringRef toString(Reference::Kind kindValue);
-
};
Modified: lld/trunk/lib/ReaderWriter/MachO/StubAtoms.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubAtoms.hpp?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubAtoms.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/StubAtoms.hpp Mon Jun 11 17:53:15 2012
@@ -19,184 +19,14 @@
#include "ReferenceKinds.h"
#include "SimpleAtoms.hpp"
+#include "StubAtoms_x86_64.hpp"
+#include "StubAtoms_x86.hpp"
namespace lld {
namespace mach_o {
//
-// X86_64 Stub Atom created by the stubs pass.
-//
-class X86_64StubAtom : public SimpleDefinedAtom {
-public:
- X86_64StubAtom(const File &file, const Atom &lazyPointer)
- : SimpleDefinedAtom(file) {
- this->addReference(ReferenceKind::x86_64_pcRel32, 2, &lazyPointer, 0);
- }
-
- virtual ContentType contentType() const {
- return DefinedAtom::typeStub;
- }
-
- virtual uint64_t size() const {
- return 6;
- }
-
- virtual ContentPermissions permissions() const {
- return DefinedAtom::permR_X;
- }
-
- virtual ArrayRef<uint8_t> rawContent() const {
- static const uint8_t instructions[] =
- { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; // jmp *lazyPointer
- assert(sizeof(instructions) == this->size());
- return ArrayRef<uint8_t>(instructions, sizeof(instructions));
- }
-
-};
-
-
-//
-// X86_64 Stub Helper Common Atom created by the stubs pass.
-//
-class X86_64StubHelperCommonAtom : public SimpleDefinedAtom {
-public:
- X86_64StubHelperCommonAtom(const File &file, const Atom &cache,
- const Atom &binder)
- : SimpleDefinedAtom(file) {
- this->addReference(ReferenceKind::x86_64_pcRel32, 3, &cache, 0);
- this->addReference(ReferenceKind::x86_64_pcRel32, 11, &binder, 0);
- }
-
- virtual ContentType contentType() const {
- return DefinedAtom::typeStubHelper;
- }
-
- virtual uint64_t size() const {
- return 16;
- }
-
- virtual ContentPermissions permissions() const {
- return DefinedAtom::permR_X;
- }
-
- virtual ArrayRef<uint8_t> rawContent() const {
- static const uint8_t instructions[] =
- { 0x4C, 0x8D, 0x1D, 0x00, 0x00, 0x00, 0x00, // leaq cache(%rip),%r11
- 0x41, 0x53, // push %r11
- 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *binder(%rip)
- 0x90 }; // nop
- assert(sizeof(instructions) == this->size());
- return ArrayRef<uint8_t>(instructions, sizeof(instructions));
- }
-
-};
-
-
-
-//
-// X86_64 Stub Helper Atom created by the stubs pass.
-//
-class X86_64StubHelperAtom : public SimpleDefinedAtom {
-public:
- X86_64StubHelperAtom(const File &file, const Atom &helperCommon)
- : SimpleDefinedAtom(file) {
- this->addReference(ReferenceKind::x86_64_lazyImm, 1, nullptr, 0);
- this->addReference(ReferenceKind::x86_64_pcRel32, 6, &helperCommon, 0);
- }
-
- virtual ContentType contentType() const {
- return DefinedAtom::typeStubHelper;
- }
-
- virtual uint64_t size() const {
- return 10;
- }
-
- virtual ContentPermissions permissions() const {
- return DefinedAtom::permR_X;
- }
-
- virtual ArrayRef<uint8_t> rawContent() const {
- static const uint8_t instructions[] =
- { 0x68, 0x00, 0x00, 0x00, 0x00, // pushq $lazy-info-offset
- 0xE9, 0x00, 0x00, 0x00, 0x00 }; // jmp helperhelper
- assert(sizeof(instructions) == this->size());
- return ArrayRef<uint8_t>(instructions, sizeof(instructions));
- }
-
-};
-
-
-//
-// X86_64 Lazy Pointer Atom created by the stubs pass.
-//
-class X86_64LazyPointerAtom : public SimpleDefinedAtom {
-public:
- X86_64LazyPointerAtom(const File &file, const Atom &helper,
- const Atom &shlib)
- : SimpleDefinedAtom(file) {
- this->addReference(ReferenceKind::x86_64_pointer64, 0, &helper, 0);
- this->addReference(ReferenceKind::x86_64_lazyTarget, 0, &shlib, 0);
- }
-
- virtual ContentType contentType() const {
- return DefinedAtom::typeLazyPointer;
- }
-
- virtual uint64_t size() const {
- return 8;
- }
-
- virtual ContentPermissions permissions() const {
- return DefinedAtom::permRW_;
- }
-
- virtual ArrayRef<uint8_t> rawContent() const {
- static const uint8_t bytes[] =
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- return ArrayRef<uint8_t>(bytes, 8);
- }
-
-};
-
-
-//
-// X86_64 NonLazy (GOT) Pointer Atom created by the stubs pass.
-//
-class X86_64NonLazyPointerAtom : public SimpleDefinedAtom {
-public:
- X86_64NonLazyPointerAtom(const File &file)
- : SimpleDefinedAtom(file) {
- }
-
- X86_64NonLazyPointerAtom(const File &file, const Atom &shlib)
- : SimpleDefinedAtom(file) {
- this->addReference(ReferenceKind::x86_64_pointer64, 0, &shlib, 0);
- }
-
- virtual ContentType contentType() const {
- return DefinedAtom::typeGOT;
- }
-
- virtual uint64_t size() const {
- return 8;
- }
-
- virtual ContentPermissions permissions() const {
- return DefinedAtom::permRW_;
- }
-
- virtual ArrayRef<uint8_t> rawContent() const {
- static const uint8_t bytes[] =
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- return ArrayRef<uint8_t>(bytes, 8);
- }
-
-};
-
-
-//
// StubBinderAtom created by the stubs pass.
//
class StubBinderAtom : public SharedLibraryAtom {
Added: lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp?rev=158336&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp (added)
+++ lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86.hpp Mon Jun 11 17:53:15 2012
@@ -0,0 +1,201 @@
+//===- lib/ReaderWriter/MachO/StubAtoms_x86.hpp ---------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_MACHO_STUB_ATOM_X86_H_
+#define LLD_READER_WRITER_MACHO_STUB_ATOM_X86_H_
+
+#include "llvm/ADT/ArrayRef.h"
+
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/SharedLibraryAtom.h"
+#include "lld/Core/File.h"
+#include "lld/Core/Reference.h"
+
+#include "ReferenceKinds.h"
+#include "SimpleAtoms.hpp"
+
+namespace lld {
+namespace mach_o {
+
+
+//
+// X86 Stub Atom created by the stubs pass.
+//
+class X86StubAtom : public SimpleDefinedAtom {
+public:
+ X86StubAtom(const File &file, const Atom &lazyPointer)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86::abs32, 2, &lazyPointer, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeStub;
+ }
+
+ virtual uint64_t size() const {
+ return 6;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permR_X;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t instructions[] =
+ { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; // jmp *lazyPointer
+ assert(sizeof(instructions) == this->size());
+ return ArrayRef<uint8_t>(instructions, sizeof(instructions));
+ }
+
+};
+
+
+//
+// X86 Stub Helper Common Atom created by the stubs pass.
+//
+class X86StubHelperCommonAtom : public SimpleDefinedAtom {
+public:
+ X86StubHelperCommonAtom(const File &file, const Atom &cache,
+ const Atom &binder)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86::abs32, 1, &cache, 0);
+ this->addReference(KindHandler_x86::abs32, 7, &binder, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeStubHelper;
+ }
+
+ virtual uint64_t size() const {
+ return 12;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permR_X;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t instructions[] =
+ { 0x68, 0x00, 0x00, 0x00, 0x00, // pushl $dyld_ImageLoaderCache
+ 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *_fast_lazy_bind
+ 0x90 }; // nop
+ assert(sizeof(instructions) == this->size());
+ return ArrayRef<uint8_t>(instructions, sizeof(instructions));
+ }
+
+};
+
+
+
+//
+// X86 Stub Helper Atom created by the stubs pass.
+//
+class X86StubHelperAtom : public SimpleDefinedAtom {
+public:
+ X86StubHelperAtom(const File &file, const Atom &helperCommon)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86::lazyImm, 1, nullptr, 0);
+ this->addReference(KindHandler_x86::call32, 6, &helperCommon, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeStubHelper;
+ }
+
+ virtual uint64_t size() const {
+ return 10;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permR_X;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t instructions[] =
+ { 0x68, 0x00, 0x00, 0x00, 0x00, // pushq $lazy-info-offset
+ 0xE9, 0x00, 0x00, 0x00, 0x00 }; // jmp helperhelper
+ assert(sizeof(instructions) == this->size());
+ return ArrayRef<uint8_t>(instructions, sizeof(instructions));
+ }
+
+};
+
+
+//
+// X86 Lazy Pointer Atom created by the stubs pass.
+//
+class X86LazyPointerAtom : public SimpleDefinedAtom {
+public:
+ X86LazyPointerAtom(const File &file, const Atom &helper,
+ const Atom &shlib)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86::pointer32, 0, &helper, 0);
+ this->addReference(KindHandler_x86::lazyTarget, 0, &shlib, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeLazyPointer;
+ }
+
+ virtual uint64_t size() const {
+ return 4;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permRW_;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t bytes[] = { 0x00, 0x00, 0x00, 0x00 };
+ return ArrayRef<uint8_t>(bytes, 4);
+ }
+
+};
+
+
+//
+// X86 NonLazy (GOT) Pointer Atom created by the stubs pass.
+//
+class X86NonLazyPointerAtom : public SimpleDefinedAtom {
+public:
+ X86NonLazyPointerAtom(const File &file)
+ : SimpleDefinedAtom(file) {
+ }
+
+ X86NonLazyPointerAtom(const File &file, const Atom &shlib)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86::pointer32, 0, &shlib, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeGOT;
+ }
+
+ virtual uint64_t size() const {
+ return 4;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permRW_;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t bytes[] = { 0x00, 0x00, 0x00, 0x0 };
+ return ArrayRef<uint8_t>(bytes, 4);
+ }
+
+};
+
+
+
+} // namespace mach_o
+} // namespace lld
+
+
+#endif // LLD_READER_WRITER_MACHO_STUB_ATOM_X86_H_
Added: lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp?rev=158336&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp (added)
+++ lld/trunk/lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp Mon Jun 11 17:53:15 2012
@@ -0,0 +1,204 @@
+//===- lib/ReaderWriter/MachO/StubAtoms_x86_64.hpp ------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_MACHO_STUB_ATOM_X86_64_H_
+#define LLD_READER_WRITER_MACHO_STUB_ATOM_X86_64_H_
+
+#include "llvm/ADT/ArrayRef.h"
+
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/SharedLibraryAtom.h"
+#include "lld/Core/File.h"
+#include "lld/Core/Reference.h"
+
+#include "ReferenceKinds.h"
+#include "SimpleAtoms.hpp"
+
+namespace lld {
+namespace mach_o {
+
+
+//
+// X86_64 Stub Atom created by the stubs pass.
+//
+class X86_64StubAtom : public SimpleDefinedAtom {
+public:
+ X86_64StubAtom(const File &file, const Atom &lazyPointer)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86_64::ripRel32, 2, &lazyPointer, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeStub;
+ }
+
+ virtual uint64_t size() const {
+ return 6;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permR_X;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t instructions[] =
+ { 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; // jmp *lazyPointer
+ assert(sizeof(instructions) == this->size());
+ return ArrayRef<uint8_t>(instructions, sizeof(instructions));
+ }
+
+};
+
+
+//
+// X86_64 Stub Helper Common Atom created by the stubs pass.
+//
+class X86_64StubHelperCommonAtom : public SimpleDefinedAtom {
+public:
+ X86_64StubHelperCommonAtom(const File &file, const Atom &cache,
+ const Atom &binder)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86_64::ripRel32, 3, &cache, 0);
+ this->addReference(KindHandler_x86_64::ripRel32, 11, &binder, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeStubHelper;
+ }
+
+ virtual uint64_t size() const {
+ return 16;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permR_X;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t instructions[] =
+ { 0x4C, 0x8D, 0x1D, 0x00, 0x00, 0x00, 0x00, // leaq cache(%rip),%r11
+ 0x41, 0x53, // push %r11
+ 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *binder(%rip)
+ 0x90 }; // nop
+ assert(sizeof(instructions) == this->size());
+ return ArrayRef<uint8_t>(instructions, sizeof(instructions));
+ }
+
+};
+
+
+
+//
+// X86_64 Stub Helper Atom created by the stubs pass.
+//
+class X86_64StubHelperAtom : public SimpleDefinedAtom {
+public:
+ X86_64StubHelperAtom(const File &file, const Atom &helperCommon)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86_64::lazyImm, 1, nullptr, 0);
+ this->addReference(KindHandler_x86_64::ripRel32, 6, &helperCommon, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeStubHelper;
+ }
+
+ virtual uint64_t size() const {
+ return 10;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permR_X;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t instructions[] =
+ { 0x68, 0x00, 0x00, 0x00, 0x00, // pushq $lazy-info-offset
+ 0xE9, 0x00, 0x00, 0x00, 0x00 }; // jmp helperhelper
+ assert(sizeof(instructions) == this->size());
+ return ArrayRef<uint8_t>(instructions, sizeof(instructions));
+ }
+
+};
+
+
+//
+// X86_64 Lazy Pointer Atom created by the stubs pass.
+//
+class X86_64LazyPointerAtom : public SimpleDefinedAtom {
+public:
+ X86_64LazyPointerAtom(const File &file, const Atom &helper,
+ const Atom &shlib)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86_64::pointer64, 0, &helper, 0);
+ this->addReference(KindHandler_x86_64::lazyTarget, 0, &shlib, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeLazyPointer;
+ }
+
+ virtual uint64_t size() const {
+ return 8;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permRW_;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t bytes[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ return ArrayRef<uint8_t>(bytes, 8);
+ }
+
+};
+
+
+//
+// X86_64 NonLazy (GOT) Pointer Atom created by the stubs pass.
+//
+class X86_64NonLazyPointerAtom : public SimpleDefinedAtom {
+public:
+ X86_64NonLazyPointerAtom(const File &file)
+ : SimpleDefinedAtom(file) {
+ }
+
+ X86_64NonLazyPointerAtom(const File &file, const Atom &shlib)
+ : SimpleDefinedAtom(file) {
+ this->addReference(KindHandler_x86_64::pointer64, 0, &shlib, 0);
+ }
+
+ virtual ContentType contentType() const {
+ return DefinedAtom::typeGOT;
+ }
+
+ virtual uint64_t size() const {
+ return 8;
+ }
+
+ virtual ContentPermissions permissions() const {
+ return DefinedAtom::permRW_;
+ }
+
+ virtual ArrayRef<uint8_t> rawContent() const {
+ static const uint8_t bytes[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ return ArrayRef<uint8_t>(bytes, 8);
+ }
+
+};
+
+
+
+} // namespace mach_o
+} // namespace lld
+
+
+#endif // LLD_READER_WRITER_MACHO_STUB_ATOM_X86_64_H_
Modified: lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/StubsPass.hpp Mon Jun 11 17:53:15 2012
@@ -28,7 +28,9 @@
class StubsPass : public lld::StubsPass {
public:
- StubsPass(const WriterOptionsMachO &options) : _options(options) {
+ StubsPass(const WriterOptionsMachO &options)
+ : _options(options),
+ _kindHandler(KindHandler::makeHandler(options.architecture())) {
}
virtual bool noTextRelocs() {
@@ -36,7 +38,7 @@
}
virtual bool isCallSite(Reference::Kind kind) {
- return ReferenceKind::isCallSite(_options.architecture(), kind);
+ return _kindHandler->isCallSite(kind);
}
virtual const DefinedAtom* getStub(const Atom& target) {
@@ -60,7 +62,8 @@
case WriterOptionsMachO::arch_x86:
return makeStub_x86(target);
- case WriterOptionsMachO::arch_arm:
+ case WriterOptionsMachO::arch_armv6:
+ case WriterOptionsMachO::arch_armv7:
return makeStub_arm(target);
}
}
@@ -87,8 +90,24 @@
}
const DefinedAtom* makeStub_x86(const Atom& target) {
- assert(0 && "stubs not yet implemented for x86");
- return nullptr;
+ if ( _helperCommonAtom == nullptr ) {
+ // Lazily create common helper code and data.
+ _helperCacheAtom = new X86NonLazyPointerAtom(_file);
+ _binderAtom = new StubBinderAtom(_file);
+ _helperBinderAtom = new X86NonLazyPointerAtom(_file, *_binderAtom);
+ _helperCommonAtom = new X86StubHelperCommonAtom(_file,
+ *_helperCacheAtom, *_helperBinderAtom);
+ }
+ const DefinedAtom* helper = new X86StubHelperAtom(_file,
+ *_helperCommonAtom);
+ _stubHelperAtoms.push_back(helper);
+ const DefinedAtom* lp = new X86LazyPointerAtom(_file, *helper, target);
+ assert(lp->contentType() == DefinedAtom::typeLazyPointer);
+ _lazyPointers.push_back(lp);
+ const DefinedAtom* stub = new X86StubAtom(_file, *lp);
+ assert(stub->contentType() == DefinedAtom::typeStub);
+ _targetToStub[&target] = stub;
+ return stub;
}
const DefinedAtom* makeStub_arm(const Atom& target) {
@@ -127,6 +146,7 @@
};
const WriterOptionsMachO &_options;
+ KindHandler *_kindHandler;
File _file;
llvm::DenseMap<const Atom*, const DefinedAtom*> _targetToStub;
std::vector<const DefinedAtom*> _lazyPointers;
Modified: lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp Mon Jun 11 17:53:15 2012
@@ -129,10 +129,6 @@
const WriterOptionsMachO &options,
class MachOWriter &writer);
- void applyFixup(Reference::Kind kind, uint64_t addend,
- uint8_t* location, uint64_t fixupAddress,
- uint64_t targetAddress);
-
StringRef _segmentName;
StringRef _sectionName;
const WriterOptionsMachO &_options;
@@ -206,6 +202,7 @@
segment_command *_linkEditSegment;
symtab_command *_symbolTableLoadCommand;
entry_point_command *_entryPointLoadCommand;
+ thread_command *_threadLoadCommand;
dyld_info_command *_dyldInfoLoadCommand;
std::vector<load_command*> _loadCmds;
std::vector<ChunkSegInfo> _sectionInfo;
@@ -354,11 +351,14 @@
uint64_t *segStartAddr, uint64_t *segEndAddr);
const std::vector<Chunk*> chunks() { return _chunks; }
+ KindHandler *kindHandler() { return _referenceKindHandler; }
+
bool use64BitMachO() const;
private:
friend class LoadCommandsChunk;
friend class LazyBindingInfoChunk;
+ friend class BindingInfoChunk;
void build(const lld::File &file);
void createChunks(const lld::File &file);
@@ -373,6 +373,7 @@
typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
const WriterOptionsMachO &_options;
+ KindHandler *_referenceKindHandler;
StubsPass _stubsPass;
GOTPass _gotPass;
CRuntimeFile _cRuntimeFile;
@@ -386,7 +387,7 @@
LazyBindingInfoChunk *_lazyBindingInfo;
SymbolTableChunk *_symbolTableChunk;
SymbolStringsChunk *_stringsChunk;
- const DefinedAtom *_mainAtom;
+ const DefinedAtom *_entryAtom;
uint64_t _linkEditStartOffset;
uint64_t _linkEditStartAddress;
};
@@ -582,34 +583,13 @@
if ( ref->target() != nullptr )
targetAddress = _writer.addressOfAtom(ref->target());
uint64_t fixupAddress = _writer.addressOfAtom(atomInfo.atom) + offset;
- this->applyFixup(ref->kind(), ref->addend(), &atomContent[offset],
- fixupAddress, targetAddress);
+ _writer.kindHandler()->applyFixup(ref->kind(), ref->addend(),
+ &atomContent[offset], fixupAddress, targetAddress);
}
}
}
-
-void SectionChunk::applyFixup(Reference::Kind kind, uint64_t addend,
- uint8_t* location, uint64_t fixupAddress,
- uint64_t targetAddress) {
- //fprintf(stderr, "applyFixup(kind=%s, addend=0x%0llX, "
- // "fixupAddress=0x%0llX, targetAddress=0x%0llX\n",
- // kindToString(kind).data(), addend,
- // fixupAddress, targetAddress);
- if ( ReferenceKind::isRipRel32(kind) ) {
- // compute rip relative value and update.
- int32_t* loc32 = reinterpret_cast<int32_t*>(location);
- *loc32 = (targetAddress - (fixupAddress+4)) + addend;
- }
- else if ( kind == ReferenceKind::x86_64_pointer64 ) {
- uint64_t* loc64 = reinterpret_cast<uint64_t*>(location);
- *loc64 = targetAddress + addend;
- }
-}
-
-
-
//===----------------------------------------------------------------------===//
// MachHeaderChunk
//===----------------------------------------------------------------------===//
@@ -687,7 +667,8 @@
MachOWriter& writer)
: _mh(mh), _options(options), _writer(writer),
_linkEditSegment(nullptr), _symbolTableLoadCommand(nullptr),
- _entryPointLoadCommand(nullptr), _dyldInfoLoadCommand(nullptr) {
+ _entryPointLoadCommand(nullptr), _threadLoadCommand(nullptr),
+ _dyldInfoLoadCommand(nullptr) {
}
@@ -815,15 +796,19 @@
this->addLoadCommand(_dyldInfoLoadCommand);
// Add entry point load command to main executables
- if (_options.outputKind() == WriterOptionsMachO::outputDynamicExecutable) {
+ if ( _options.addEntryPointLoadCommand() ) {
_entryPointLoadCommand = new entry_point_command(is64);
this->addLoadCommand(_entryPointLoadCommand);
}
+ else if ( _options.addUnixThreadLoadCommand() ) {
+ _threadLoadCommand = new thread_command(_options.cpuType(), is64);
+ this->addLoadCommand(_threadLoadCommand);
+ }
// Compute total size.
_size = _mh.loadCommandsSize();
}
-
+
void LoadCommandsChunk::updateLoadCommandContent(const lld::File &file) {
// Update segment/section information in segment load commands
@@ -887,11 +872,17 @@
// Update entry point
if ( _entryPointLoadCommand != nullptr ) {
- const Atom *mainAtom = _writer._mainAtom;
+ const Atom *mainAtom = _writer._entryAtom;
assert(mainAtom != nullptr);
uint32_t entryOffset = _writer.addressOfAtom(mainAtom) - _mh.address();
_entryPointLoadCommand->entryoff = entryOffset;
}
+ else if ( _threadLoadCommand != nullptr ) {
+ const Atom *startAtom = _writer._entryAtom;
+ assert(startAtom != nullptr);
+ _threadLoadCommand->setPC(_writer.addressOfAtom(startAtom));
+ }
+
}
@@ -1037,9 +1028,9 @@
const SharedLibraryAtom *shlTarget
= dyn_cast<SharedLibraryAtom>(target);
if ( shlTarget != nullptr ) {
- assert(ref->kind() == ReferenceKind::x86_64_pointer64);
+ assert(_writer.kindHandler()->isPointer(ref->kind()));
targetName = shlTarget->name();
- ordinal = 1;
+ ordinal = 1; // FIXME
}
}
}
@@ -1096,15 +1087,22 @@
return "lazy binding info";
}
+//
+// Called when lazy-binding-info is being laid out in __LINKEDIT. We need
+// to find the helper atom which contains the instruction which loads an
+// immediate value that is the offset into the lazy-binding-info, and set
+// that immediate value to be the offset parameter.
void LazyBindingInfoChunk::updateHelper(const DefinedAtom *lazyPointerAtom,
uint32_t offset) {
for (const Reference *ref : *lazyPointerAtom ) {
- if ( ref->kind() != ReferenceKind::x86_64_pointer64 )
+ if ( ! _writer.kindHandler()->isPointer(ref->kind() ) )
continue;
- const DefinedAtom *helperAtom = dyn_cast<DefinedAtom>(ref->target());
+ const Atom *targ = ref->target();
+ const DefinedAtom *helperAtom = dyn_cast<DefinedAtom>(targ);
assert(helperAtom != nullptr);
+ // Found helper atom. Search it for Reference that is lazy immediate value.
for (const Reference *href : *helperAtom ) {
- if ( href->kind() == ReferenceKind::x86_64_lazyImm ) {
+ if ( _writer.kindHandler()->isLazyImmediate(href->kind()) ) {
(const_cast<Reference*>(href))->setAddend(offset);
return;
}
@@ -1154,7 +1152,7 @@
int flags = 0;
StringRef name;
for (const Reference *ref : *lazyPointerAtom ) {
- if ( ref->kind() == ReferenceKind::x86_64_lazyTarget ) {
+ if ( _writer.kindHandler()->isLazyTarget(ref->kind()) ) {
const Atom *shlib = ref->target();
assert(shlib != nullptr);
name = shlib->name();
@@ -1298,9 +1296,11 @@
//===----------------------------------------------------------------------===//
MachOWriter::MachOWriter(const WriterOptionsMachO &options)
- : _options(options), _stubsPass(options), _cRuntimeFile(options),
+ : _options(options),
+ _referenceKindHandler(KindHandler::makeHandler(_options.architecture())),
+ _stubsPass(options), _cRuntimeFile(options),
_bindingInfo(nullptr), _lazyBindingInfo(nullptr),
- _symbolTableChunk(nullptr), _stringsChunk(nullptr), _mainAtom(nullptr),
+ _symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
_linkEditStartOffset(0), _linkEditStartAddress(0) {
}
@@ -1388,16 +1388,16 @@
void MachOWriter::buildAtomToAddressMap() {
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
<< "assign atom addresses:\n");
- const bool lookForMain =
+ const bool lookForEntry =
(_options.outputKind() == WriterOptionsMachO::outputDynamicExecutable);
for (SectionChunk *chunk : _sectionChunks ) {
for (const SectionChunk::AtomInfo &info : chunk->atoms() ) {
_atomToAddress[info.atom] = chunk->address() + info.offsetInSection;
- if ( lookForMain
+ if ( lookForEntry
&& (info.atom->contentType() == DefinedAtom::typeCode)
&& (info.atom->size() != 0)
- && info.atom->name().equals("_main") ) {
- _mainAtom = info.atom;
+ && info.atom->name().equals(_options.entryPointName()) ) {
+ _entryAtom = info.atom;
}
DEBUG_WITH_TYPE("WriterMachO-layout", llvm::dbgs()
<< " address="
@@ -1544,23 +1544,10 @@
} // namespace mach_o
+
Writer* createWriterMachO(const WriterOptionsMachO &options) {
return new lld::mach_o::MachOWriter(options);
}
-WriterOptionsMachO::WriterOptionsMachO()
- : _outputkind(outputDynamicExecutable),
- _archName("x86_64"),
- _architecture(arch_x86_64),
- _pageZeroSize(0x100000000),
- _cpuType(mach_o::CPU_TYPE_X86_64),
- _cpuSubtype(mach_o::CPU_SUBTYPE_X86_64_ALL),
- _noTextRelocations(true) {
-}
-
-WriterOptionsMachO::~WriterOptionsMachO() {
-}
-
-
} // namespace lld
Added: lld/trunk/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp?rev=158336&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp (added)
+++ lld/trunk/lib/ReaderWriter/MachO/WriterOptionsMachO.cpp Mon Jun 11 17:53:15 2012
@@ -0,0 +1,144 @@
+//===- lib/ReaderWriter/MachO/WriterOptionsMachO.cpp ----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/ReaderWriter/WriterMachO.h"
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/system_error.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+#include "MachOFormat.hpp"
+
+namespace lld {
+
+WriterOptionsMachO::WriterOptionsMachO()
+ : _outputkind(outputDynamicExecutable),
+ _architecture(arch_x86),
+ _pageZeroSize(0x1000),
+ _noTextRelocations(true) {
+}
+
+WriterOptionsMachO::~WriterOptionsMachO() {
+}
+
+StringRef WriterOptionsMachO::archName() const {
+ switch ( _architecture ) {
+ case arch_x86_64:
+ return StringRef("x86_64");
+ case arch_x86:
+ return StringRef("i386");
+ case arch_armv6:
+ return StringRef("armv6");
+ case arch_armv7:
+ return StringRef("armv7");
+ }
+ assert(0 && "unknown arch");
+ return StringRef("???");
+}
+
+uint32_t WriterOptionsMachO::cpuType() const {
+ switch ( _architecture ) {
+ case arch_x86_64:
+ return mach_o::CPU_TYPE_X86_64;
+ case arch_x86:
+ return mach_o::CPU_TYPE_I386;
+ case arch_armv6:
+ case arch_armv7:
+ return mach_o::CPU_TYPE_ARM;
+ }
+ assert(0 && "unknown arch");
+ return 0;
+}
+
+uint32_t WriterOptionsMachO::cpuSubtype() const {
+ switch ( _architecture ) {
+ case arch_x86_64:
+ return mach_o::CPU_SUBTYPE_X86_64_ALL;
+ case arch_x86:
+ return mach_o::CPU_SUBTYPE_X86_ALL;
+ case arch_armv6:
+ return mach_o::CPU_SUBTYPE_ARM_V6;
+ case arch_armv7:
+ return mach_o::CPU_SUBTYPE_ARM_V7;
+ }
+ assert(0 && "unknown arch");
+ return 0;
+}
+
+uint64_t WriterOptionsMachO::pageZeroSize() const {
+ switch ( _outputkind ) {
+ case outputDynamicExecutable:
+ return _pageZeroSize;
+ case outputDylib:
+ case outputBundle:
+ case outputObjectFile:
+ assert(_pageZeroSize == 0);
+ return 0;
+ }
+ assert(0 && "unknown outputkind");
+ return 0;
+}
+
+bool WriterOptionsMachO::addEntryPointLoadCommand() const {
+ switch ( _outputkind ) {
+ case outputDynamicExecutable:
+ // Only main executables have an entry point
+ return false;
+ case outputDylib:
+ case outputBundle:
+ case outputObjectFile:
+ return false;
+ }
+ assert(0 && "unknown outputkind");
+ return false;
+}
+
+bool WriterOptionsMachO::addUnixThreadLoadCommand() const {
+ switch ( _outputkind ) {
+ case outputDynamicExecutable:
+ // Only main executables have an entry point
+ return true;
+ case outputDylib:
+ case outputBundle:
+ case outputObjectFile:
+ return false;
+ }
+ assert(0 && "unknown outputkind");
+ return false;
+}
+
+StringRef WriterOptionsMachO::entryPointName() const {
+ switch ( _outputkind ) {
+ case outputDynamicExecutable:
+ // Only main executables have an entry point
+ if ( ! _customEntryPointName.empty() ) {
+ return _customEntryPointName;
+ }
+ else {
+ if ( true || this->addEntryPointLoadCommand() )
+ return StringRef("_main");
+ else
+ return StringRef("start");
+ }
+ break;
+ case outputDylib:
+ case outputBundle:
+ case outputObjectFile:
+ return StringRef();
+ }
+ assert(0 && "unknown outputkind");
+ return StringRef();
+}
+
+
+} // namespace lld
+
Modified: lld/trunk/lib/ReaderWriter/YAML/WriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/WriterYAML.cpp?rev=158336&r1=158335&r2=158336&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/WriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/WriterYAML.cpp Mon Jun 11 17:53:15 2012
@@ -196,7 +196,6 @@
<< spacePadding(strlen("scope"))
<< KeyValues::scope(atom.scope())
<< "\n";
- hasDash = true;
}
if ( atom.interposable() != KeyValues::interposableDefault ) {
More information about the llvm-commits
mailing list