[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 li

Sean Silva silvas at purdue.edu
Mon Jun 11 20:09:08 PDT 2012


I would like a "how to add support for a new object file format to lld"
tutorial.

On Mon, Jun 11, 2012 at 5:19 PM, Nick Kledzik <kledzik at apple.com> wrote:

>
> On Jun 11, 2012, at 4:02 PM, Chandler Carruth wrote:
>
> On Mon, Jun 11, 2012 at 3:53 PM, Nick Kledzik <kledzik at apple.com> wrote:
>
>> 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.
>>
>
> This really feels like it should be split across separate commits to make
> code review more tractable Nick...
>
> You have several changes which are no-functionality changed, just moving
> code around. Those should always be separate. They can be reviewed super
> easily, and that allows the commits which actually make changes to be
> reviewed with a precise diff.
>
> You actually have the different steps in your log message: each sentence
> feels like it should have been its own distinct commit.
>
>
> For reference, I mention this because several people have come to me
> expressing interest in getting involved with lld, but have struggled to
> review the existing code and start reviewing commits because the commits
> were very lumped together.
>
>
> I understand simple, modular commits for a mature, large code base with
> lots of developers involved.
>
> But, lld is still very much in its infancy.  These commits are more like
> check-points.   I expect plenty more refactoring churn before lld is stable
> enough to open it up to more contributors.
>
> That said, if there are developers interested in lld, I'd very much like
> to hear what design areas they would like documented better.  Questions
> like: How would X be handled by an in-memory based linker?  or How does the
> Atom model handle a cpu with feature X, etc.   Getting me to document
>  those design points will help everyone come up to speed and see how their
> needs fit into the lld model, and ensure lld can support (eventually)
> everyone's linking needs.
>
> -Nick
>
>
>
>> 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 ) {
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20120611/0340fbfa/attachment.html>


More information about the llvm-commits mailing list