[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