[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