[llvm-commits] [lld] r150539 - in /lld/trunk: include/lld/Core/ lib/Core/ test/ tools/lld-core/
Chandler Carruth
chandlerc at google.com
Tue Feb 14 16:51:06 PST 2012
I know this is early stage stuff, but others are interested, so commit log
messages would be good. ;)
On Feb 14, 2012 2:45 PM, "Nick Kledzik" <kledzik at apple.com> wrote:
> Author: kledzik
> Date: Tue Feb 14 18:38:09 2012
> New Revision: 150539
>
> URL: http://llvm.org/viewvc/llvm-project?rev=150539&view=rev
> Log:
>
>
> Added:
> lld/trunk/test/fixups-addend.objtxt
> lld/trunk/test/fixups-dup-named.objtxt
> lld/trunk/test/fixups-named.objtxt
> lld/trunk/test/fixups-unnamed.objtxt
> Removed:
> lld/trunk/test/internal-name-attributes.objtxt
> Modified:
> lld/trunk/include/lld/Core/DefinedAtom.h
> lld/trunk/include/lld/Core/Reference.h
> lld/trunk/include/lld/Core/Resolver.h
> lld/trunk/lib/Core/NativeFileFormat.h
> lld/trunk/lib/Core/NativeReader.cpp
> lld/trunk/lib/Core/NativeWriter.cpp
> lld/trunk/lib/Core/Resolver.cpp
> lld/trunk/lib/Core/SymbolTable.cpp
> lld/trunk/lib/Core/YamlKeyValues.cpp
> lld/trunk/lib/Core/YamlKeyValues.h
> lld/trunk/lib/Core/YamlReader.cpp
> lld/trunk/lib/Core/YamlWriter.cpp
> lld/trunk/test/cstring-coalesce.objtxt
> lld/trunk/tools/lld-core/lld-core.cpp
>
> Modified: lld/trunk/include/lld/Core/DefinedAtom.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/DefinedAtom.h (original)
> +++ lld/trunk/include/lld/Core/DefinedAtom.h Tue Feb 14 18:38:09 2012
> @@ -34,7 +34,7 @@
> /// Here are some example attribute sets for common atoms. If a particular
> /// attribute is not listed, the default values are: definition=regular,
> /// sectionChoice=basedOnContent, scope=translationUnit, merge=no,
> -/// internalName=false, deadStrip=normal, interposable=no
> +/// deadStrip=normal, interposable=no
> ///
> /// C function: void foo() {} <br>
> /// name=foo, type=code, perm=r_x, scope=global
> @@ -71,16 +71,16 @@
> /// mergeDupes=asAddressedWeak
> ///
> /// literal c-string: "hello" <br>
> -/// name=L0, internalName=true, type=cstring, perm=r__,
> scope=linkageUnit
> +/// name="" type=cstring, perm=r__, scope=linkageUnit
> ///
> /// literal double: 1.234 <br>
> -/// name=L0, internalName=true, type=literal8, perm=r__,
> scope=linkageUnit
> +/// name="" type=literal8, perm=r__, scope=linkageUnit
> ///
> /// constant: { 1,2,3 } <br>
> -/// name=L0, internalName=true, type=constant, perm=r__,
> scope=linkageUnit
> +/// name="" type=constant, perm=r__, scope=linkageUnit
> ///
> /// Pointer to initializer function: <br>
> -/// name=_init, internalName=true, type=initializer, perm=rw_l,
> +/// name="" type=initializer, perm=rw_l,
> /// sectionChoice=customRequired
> ///
> /// C function place in custom section:
> __attribute__((section("__foo")))
> @@ -195,15 +195,18 @@
> uint16_t modulus;
> };
>
> + /// for use iterating over this Atom's References
> + class ReferenceHandler {
> + public:
> + virtual ~ReferenceHandler() {}
> + virtual void doReference(const Reference &) = 0;
> + };
> +
> /// ordinal - returns a value for the order of this Atom within its file.
> /// This is used by the linker to order the layout of Atoms so that
> /// the resulting image is stable and reproducible.
> virtual uint64_t ordinal() const = 0;
> -
> - /// internalName - If the name is just a temporary label that should
> - /// not show up in the final linked image.
> - virtual bool internalName() const = 0;
> -
> +
> /// size - the number of bytes of space this atom's content will occupy
> /// in the final linked image. For a function atom, it is the number
> /// of bytes of code in the function.
> @@ -264,12 +267,9 @@
> /// this Atom's content.
> virtual llvm::ArrayRef<uint8_t> rawContent() const = 0;
>
> - /// referencesBegin - used to start iterating this Atom's References
> - virtual Reference::iterator referencesBegin() const = 0;
> -
> - /// referencesEnd - used to end iterating this Atom's References
> - virtual Reference::iterator referencesEnd() const = 0;
> -
> + /// iterator over this Atom's References
> + virtual void forEachReference(ReferenceHandler&) const = 0;
> +
> protected:
> /// DefinedAtom is an abstract base class.
> /// Only subclasses can access constructor.
>
> Modified: lld/trunk/include/lld/Core/Reference.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Reference.h?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/Reference.h (original)
> +++ lld/trunk/include/lld/Core/Reference.h Tue Feb 14 18:38:09 2012
> @@ -12,22 +12,60 @@
>
> #include <stdint.h>
>
> -
> namespace lld {
>
> -class Atom;
> -
> +///
> +/// The linker has a Graph Theory model of linking. An object file is seen
> +/// as a set of Atoms with References to other Atoms. Each Atom is a node
> +/// and each Reference is an edge.
> +///
> +/// For example if a function contains a call site to "malloc" 40 bytes
> into
> +/// the Atom, then the function Atom will have a Reference of:
> offsetInAtom=40,
> +/// kind=callsite, target=malloc, addend=0.
> +///
> +/// Besides supporting traditional "relocations", References are also used
> +/// grouping atoms (group comdat), forcing layout (one atom must follow
> +/// another), marking data-in-code (jump tables or ARM constants), etc.
> +///
> class Reference {
> public:
> - typedef Reference *iterator;
> -
> - const Atom *target;
> - uint64_t addend;
> - uint32_t offsetInAtom;
> - uint16_t kind;
> - uint16_t flags;
> + /// The meaning of positive kind values is architecture specific.
> + /// Negative kind values are architecture independent.
> + typedef int32_t Kind;
> +
> + // A value to be added to the value of a target
> + typedef int64_t Addend;
> +
> + /// What sort of reference this is.
> + virtual Kind kind() const = 0;
> +
> + /// If the reference is a fixup in the Atom, then this returns the
> + /// byte offset into the Atom's content to do the fix up.
> + virtual uint64_t offsetInAtom() const = 0;
> +
> + /// If the reference is an edge to another Atom, then this returns the
> + /// other Atom. Otherwise, it returns NULL.
> + virtual const class Atom * target() const = 0;
> +
> + /// During linking, the linker may merge graphs which coalesces some
> nodes
> + /// (i.e. Atoms). To switch the target of a reference, this method is
> called.
> + virtual void setTarget(const class Atom *) = 0;
> +
> + /// Some relocations require a symbol and a value (e.g. foo + 4).
> + virtual Addend addend() const = 0;
> +
> +protected:
> + /// Atom is an abstract base class. Only subclasses can access
> constructor.
> + Reference() {}
> +
> + /// The memory for Reference objects is always managed by the owning
> File
> + /// object. Therefore, no one but the owning File object should call
> + /// delete on an Reference. In fact, some File objects may bulk
> allocate
> + /// an array of References, so they cannot be individually deleted by
> anyone.
> + virtual ~Reference() {}
> };
>
> +
> } // namespace lld
>
> #endif // LLD_CORE_REFERENCES_H_
>
> Modified: lld/trunk/include/lld/Core/Resolver.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/include/lld/Core/Resolver.h (original)
> +++ lld/trunk/include/lld/Core/Resolver.h Tue Feb 14 18:38:09 2012
> @@ -70,6 +70,22 @@
> void markLive(const Atom &atom, WhyLiveBackChain *previous);
> void addAtoms(const std::vector<const DefinedAtom *>&);
>
> +
> + // helper to update targets for use with forEachReference()
> + class MarkLiveReferences : public DefinedAtom::ReferenceHandler {
> + public:
> + MarkLiveReferences(Resolver& resolver, WhyLiveBackChain*
> chain)
> + : _resolver(resolver), _chain(chain) { }
> +
> + virtual void doReference(const Reference& ref) {
> + _resolver.markLive(*ref.target(), _chain);
> + }
> +
> + private:
> + Resolver& _resolver;
> + WhyLiveBackChain* _chain;
> + };
> +
> Platform &_platform;
> const InputFiles &_inputFiles;
> SymbolTable _symbolTable;
>
> Modified: lld/trunk/lib/Core/NativeFileFormat.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeFileFormat.h?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/NativeFileFormat.h (original)
> +++ lld/trunk/lib/Core/NativeFileFormat.h Tue Feb 14 18:38:09 2012
> @@ -80,6 +80,7 @@
> uint32_t architecture;
> uint32_t fileSize;
> uint32_t chunkCount;
> + // NativeChunk chunks[]
> };
>
> //
> @@ -90,8 +91,11 @@
> NCS_AttributesArrayV1 = 2,
> NCS_UndefinedAtomsV1 = 3,
> NCS_Strings = 4,
> - NCS_Content = 5,
> - NCS_ReferencesArray = 6,
> + NCS_ReferencesArrayV1 = 5,
> + NCS_ReferencesArrayV2 = 6,
> + NCS_TargetsTable = 7,
> + NCS_AddendsTable = 8,
> + NCS_Content = 9,
> };
>
> //
> @@ -125,6 +129,8 @@
> struct NativeDefinedAtomIvarsV1 {
> uint32_t nameOffset;
> uint32_t attributesOffset;
> + uint32_t referencesStartIndex;
> + uint32_t referencesCount;
> uint32_t contentOffset;
> uint32_t contentSize;
> };
> @@ -137,7 +143,6 @@
> uint32_t sectionNameOffset;
> uint16_t align2;
> uint16_t alignModulus;
> - uint8_t internalName;
> uint8_t scope;
> uint8_t interposable;
> uint8_t merge;
> @@ -145,10 +150,7 @@
> uint8_t sectionChoice;
> uint8_t deadStrip;
> uint8_t permissions;
> - uint8_t thumb;
> uint8_t alias;
> - uint8_t pad1;
> - uint8_t pad2;
> };
>
>
> @@ -164,6 +166,51 @@
>
>
>
> +//
> +// The NCS_ReferencesArrayV1 chunk contains an array of these structs
> +//
> +struct NativeReferenceIvarsV1 {
> + uint16_t offsetInAtom;
> + int16_t kind;
> + uint16_t targetIndex;
> + uint16_t addendIndex;
> +};
> +
> +
> +
> +//
> +// The NCS_ReferencesArrayV2 chunk contains an array of these structs
> +//
> +struct NativeReferenceIvarsV2 {
> + uint64_t offsetInAtom;
> + int64_t addend;
> + int32_t kind;
> + uint32_t targetIndex;
> +};
> +
> +
> +//
> +// The NCS_TargetsTable chunk contains an array of uint32_t entries.
> +// The C++ class Reference has a target() method that returns a
> +// pointer to another Atom. We can't have pointers in object files,
> +// so instead NativeReferenceIvarsV1 contains an index to the target.
> +// The index is into this NCS_TargetsTable of uint32_t entries.
> +// The values in this table are the index of the (target) atom in this
> file.
> +// For DefinedAtoms the value is from 0 to
> NCS_DefinedAtomsV1.elementCount.
> +// For UndefinedAtoms the value is from NCS_DefinedAtomsV1.elementCount to
> +// NCS_DefinedAtomsV1.elementCount+NCS_UndefinedAtomsV1.elementCount.
> +//
> +
> +
> +//
> +// The NCS_AddendsTable chunk contains an array of int64_t entries.
> +// If we allocated space for addends directly in NativeReferenceIvarsV1
> +// it would double the size of that struct. But since addends are rare,
> +// we instead just keep a pool of addends and have NativeReferenceIvarsV1
> +// (if it needs an addend) just store the index (into the pool) of the
> +// addend it needs.
> +//
> +
>
>
> } // namespace lld
>
> Modified: lld/trunk/lib/Core/NativeReader.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/NativeReader.cpp (original)
> +++ lld/trunk/lib/Core/NativeReader.cpp Tue Feb 14 18:38:09 2012
> @@ -44,10 +44,6 @@
>
> virtual llvm::StringRef name() const;
>
> - virtual bool internalName() const {
> - return attributes().internalName;
> - }
> -
> virtual uint64_t size() const {
> return _ivarData->contentSize;
> }
> @@ -88,23 +84,17 @@
> }
>
> virtual bool isThumb() const {
> - return (attributes().thumb != 0);
> + return false; //(attributes().thumb != 0);
> }
>
> virtual bool isAlias() const {
> return (attributes().alias != 0);
> }
>
> - llvm::ArrayRef<uint8_t> rawContent() const;
> + virtual llvm::ArrayRef<uint8_t> rawContent() const;
>
> - virtual Reference::iterator referencesBegin() const {
> - return 0;
> - }
> -
> - virtual Reference::iterator referencesEnd() const {
> - return 0;
> - }
> -
> + virtual void forEachReference(ReferenceHandler&) const;
> +
> private:
> const NativeAtomAttributesV1& attributes() const;
>
> @@ -139,6 +129,35 @@
>
>
> //
> +// An object of this class is instantied for each NativeReferenceIvarsV1
> +// struct in the NCS_ReferencesArrayV1 chunk.
> +//
> +class NativeReferenceV1 : public Reference {
> +public:
> + NativeReferenceV1(const NativeFile& f,
> + const NativeReferenceIvarsV1* ivarData)
> + : _file(&f), _ivarData(ivarData) { }
> +
> + virtual uint64_t offsetInAtom() const {
> + return _ivarData->offsetInAtom;
> + }
> +
> + virtual Kind kind() const {
> + return _ivarData->kind;
> + }
> +
> + virtual const Atom* target() const;
> + virtual Addend addend() const;
> + virtual void setTarget(const Atom* newAtom);
> +
> +private:
> + const NativeFile* _file;
> + const NativeReferenceIvarsV1* _ivarData;
> +};
> +
> +
> +
> +//
> // lld::File object for native llvm object file
> //
> class NativeFile : public File {
> @@ -187,6 +206,15 @@
> case NCS_UndefinedAtomsV1:
> ec = file->processUndefinedAtomsV1(base, chunk);
> break;
> + case NCS_ReferencesArrayV1:
> + ec = file->processReferencesV1(base, chunk);
> + break;
> + case NCS_TargetsTable:
> + ec = file->processTargetsTable(base, chunk);
> + break;
> + case NCS_AddendsTable:
> + ec = file->processAddendsTable(base, chunk);
> + break;
> case NCS_Content:
> ec = file->processContent(base, chunk);
> break;
> @@ -219,6 +247,8 @@
> // to just delete the memory.
> delete _definedAtoms.arrayStart;
> delete _undefinedAtoms.arrayStart;
> + delete _references.arrayStart;
> + delete _targetsTable;
> }
>
> // visits each atom in the file
> @@ -245,6 +275,7 @@
> private:
> friend class NativeDefinedAtomV1;
> friend class NativeUndefinedAtomV1;
> + friend class NativeReferenceV1;
>
> // instantiate array of DefinedAtoms from v1 ivar data in file
> llvm::error_code processDefinedAtomsV1(const uint8_t* base,
> @@ -272,6 +303,7 @@
> this->_definedAtoms.arrayStart = atomsStart;
> this->_definedAtoms.arrayEnd = atomsEnd;
> this->_definedAtoms.elementSize = atomSize;
> + this->_definedAtoms.elementCount = chunk->elementCount;
> return make_error_code(native_reader_error::success);
> }
>
> @@ -307,6 +339,77 @@
> this->_undefinedAtoms.arrayStart = atomsStart;
> this->_undefinedAtoms.arrayEnd = atomsEnd;
> this->_undefinedAtoms.elementSize = atomSize;
> + this->_undefinedAtoms.elementCount = chunk->elementCount;
> + return make_error_code(native_reader_error::success);
> + }
> +
> +
> + // instantiate array of Referemces from v1 ivar data in file
> + llvm::error_code processReferencesV1(const uint8_t* base,
> + const NativeChunk* chunk)
> {
> + if ( chunk->elementCount == 0 )
> + return make_error_code(native_reader_error::success);
> + const size_t refSize = sizeof(NativeReferenceV1);
> + size_t refsArraySize = chunk->elementCount * refSize;
> + uint8_t* refsStart = reinterpret_cast<uint8_t*>
> + (operator new(refsArraySize,
> std::nothrow));
> + if (refsStart == NULL )
> + return make_error_code(native_reader_error::memory_error);
> + const size_t ivarElementSize = chunk->fileSize
> + / chunk->elementCount;
> + if ( ivarElementSize != sizeof(NativeReferenceIvarsV1) )
> + return make_error_code(native_reader_error::file_malformed);
> + uint8_t* refsEnd = refsStart + refsArraySize;
> + const NativeReferenceIvarsV1* ivarData =
> + reinterpret_cast<const
> NativeReferenceIvarsV1*>
> + (base +
> chunk->fileOffset);
> + for(uint8_t* s = refsStart; s != refsEnd; s += refSize) {
> + NativeReferenceV1* atomAllocSpace =
> + reinterpret_cast<NativeReferenceV1*>(s);
> + new (atomAllocSpace) NativeReferenceV1(*this, ivarData);
> + ++ivarData;
> + }
> + this->_references.arrayStart = refsStart;
> + this->_references.arrayEnd = refsEnd;
> + this->_references.elementSize = refSize;
> + this->_references.elementCount = chunk->elementCount;
> + return make_error_code(native_reader_error::success);
> + }
> +
> + // set up pointers to target table
> + llvm::error_code processTargetsTable(const uint8_t* base,
> + const NativeChunk* chunk)
> {
> + const uint32_t* targetIndexes = reinterpret_cast<const uint32_t*>
> + (base +
> chunk->fileOffset);
> + this->_targetsTableCount = chunk->elementCount;
> + this->_targetsTable = new const Atom*[chunk->elementCount];
> + for (uint32_t i=0; i < chunk->elementCount; ++i) {
> + const uint32_t index = targetIndexes[i];
> + if ( index < _definedAtoms.elementCount ) {
> + const uint8_t* p = _definedAtoms.arrayStart
> + + index * _definedAtoms.elementSize;
> + this->_targetsTable[i] = reinterpret_cast<const DefinedAtom*>(p);
> + continue;
> + }
> + const uint32_t undefIndex = index - _definedAtoms.elementCount;
> + if ( undefIndex < _undefinedAtoms.elementCount ) {
> + const uint8_t* p = _undefinedAtoms.arrayStart
> + + undefIndex *
> _undefinedAtoms.elementSize;
> + this->_targetsTable[i] = reinterpret_cast<const
> UndefinedAtom*>(p);
> + continue;
> + }
> + return make_error_code(native_reader_error::file_malformed);
> + }
> + return make_error_code(native_reader_error::success);
> + }
> +
> +
> + // set up pointers to addend pool in file
> + llvm::error_code processAddendsTable(const uint8_t* base,
> + const NativeChunk* chunk)
> {
> + this->_addends = reinterpret_cast<const Reference::Addend*>
> + (base +
> chunk->fileOffset);
> + this->_addendsMaxIndex = chunk->elementCount;
> return make_error_code(native_reader_error::success);
> }
>
> @@ -331,9 +434,16 @@
> return llvm::StringRef(&_strings[offset]);
> }
>
> - const NativeAtomAttributesV1& attribute(uint32_t offset) const {
> - assert(offset < _attributesMaxOffset);
> - return *reinterpret_cast<const NativeAtomAttributesV1*>(_attributes +
> offset);
> + Reference::Addend addend(uint32_t index) const {
> + if ( index == 0 )
> + return 0; // addend index zero is used to mean "no addend"
> + assert(index <= _addendsMaxIndex);
> + return _addends[index-1]; // one-based indexing
> + }
> +
> + const NativeAtomAttributesV1& attribute(uint32_t off) const {
> + assert(off < _attributesMaxOffset);
> + return *reinterpret_cast<const NativeAtomAttributesV1*>(_attributes +
> off);
> }
>
> const uint8_t* content(uint32_t offset, uint32_t size) const {
> @@ -342,44 +452,75 @@
> return result;
> }
>
> -
> + void forEachReference(DefinedAtom::ReferenceHandler& handler,
> + uint32_t start, uint32_t count)
> const {
> + assert(start < _references.elementCount);
> + assert(start+count <= _references.elementCount);
> + const uint8_t* arrStart = _references.arrayStart
> + + start * _references.elementSize;
> + const uint8_t* arrEnd = arrStart + count * _references.elementSize;
> + for(const uint8_t* p=arrStart; p != arrEnd; p +=
> _references.elementSize) {
> + const NativeReferenceV1* ref
> + = reinterpret_cast<const
> NativeReferenceV1*>(p);
> + handler.doReference(*ref);
> + }
> + }
> +
> + const Atom* target(uint32_t index) const {
> + assert(index < _targetsTableCount);
> + return _targetsTable[index];
> + }
> +
> + void setTarget(uint32_t index, const Atom* newAtom) const {
> + assert(index > _targetsTableCount);
> + _targetsTable[index] = newAtom;
> + }
> +
> +
> // private constructor, only called by make()
> NativeFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb, llvm::StringRef
> path) :
> lld::File(path),
> _buffer(mb.take()), // NativeFile now takes ownership of buffer
> _header(NULL),
> + _targetsTable(NULL),
> + _targetsTableCount(0),
> _strings(NULL),
> _stringsMaxOffset(0),
> + _addends(NULL),
> + _addendsMaxIndex(0),
> _contentStart(NULL),
> _contentEnd(NULL)
> {
> _header = reinterpret_cast<const
> NativeFileHeader*>(_buffer->getBufferStart());
> - _definedAtoms.arrayStart = NULL;
> - _undefinedAtoms.arrayStart = NULL;
> }
>
> - struct AtomArray {
> - AtomArray() : arrayStart(NULL), arrayEnd(NULL),
> - elementSize(0) { }
> + struct IvarArray {
> + IvarArray() : arrayStart(NULL), arrayEnd(NULL),
> + elementSize(0), elementCount(0) { }
> const uint8_t* arrayStart;
> const uint8_t* arrayEnd;
> uint32_t elementSize;
> - };
> + uint32_t elementCount;
> + };
>
> llvm::OwningPtr<llvm::MemoryBuffer> _buffer;
> const NativeFileHeader* _header;
> - AtomArray _definedAtoms;
> - AtomArray _undefinedAtoms;
> + IvarArray _definedAtoms;
> + IvarArray _undefinedAtoms;
> const uint8_t* _attributes;
> uint32_t _attributesMaxOffset;
> + IvarArray _references;
> + const Atom** _targetsTable;
> + uint32_t _targetsTableCount;
> const char* _strings;
> uint32_t _stringsMaxOffset;
> + const Reference::Addend* _addends;
> + uint32_t _addendsMaxIndex;
> const uint8_t* _contentStart;
> const uint8_t* _contentEnd;
> };
>
> -
> -
> +
> inline const class File& NativeDefinedAtomV1::file() const {
> return *_file;
> }
> @@ -410,8 +551,12 @@
> return _file->string(offset);
> }
>
> -
> -
> +inline void NativeDefinedAtomV1::forEachReference(ReferenceHandler& hnd)
> const {
> + if ( _ivarData->referencesCount == 0 )
> + return;
> + _file->forEachReference(hnd, _ivarData->referencesStartIndex,
> + _ivarData->referencesCount);
> +}
>
> inline const class File& NativeUndefinedAtomV1::file() const {
> return *_file;
> @@ -422,6 +567,17 @@
> }
>
>
> +inline const Atom* NativeReferenceV1::target() const {
> + return _file->target(_ivarData->targetIndex);
> +}
> +
> +inline Reference::Addend NativeReferenceV1::addend() const {
> + return _file->addend(_ivarData->addendIndex);
> +}
> +
> +inline void NativeReferenceV1::setTarget(const Atom* newAtom) {
> + return _file->setTarget(_ivarData->targetIndex, newAtom);
> +}
>
>
> //
>
> Modified: lld/trunk/lib/Core/NativeWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/NativeWriter.cpp (original)
> +++ lld/trunk/lib/Core/NativeWriter.cpp Tue Feb 14 18:38:09 2012
> @@ -12,6 +12,7 @@
>
> #include "llvm/ADT/StringRef.h"
> #include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/DenseMap.h"
>
> #include "lld/Core/File.h"
> #include "lld/Core/NativeWriter.h"
> @@ -25,10 +26,13 @@
> ///
> /// Class for writing native object files.
> ///
> -class NativeWriter : public File::AtomHandler {
> +class NativeWriter : public File::AtomHandler,
> + public DefinedAtom::ReferenceHandler {
> public:
> /// construct writer for an lld::File object
> NativeWriter(const lld::File& file) : _file(file) {
> + // reserve first byte for unnamed atoms
> + _stringPool.push_back('\0');
> // visit all atoms
> _file.forEachAtom(*this);
> // construct file header based on atom information accumulated
> @@ -37,36 +41,73 @@
>
> // write the lld::File in native format to the specified stream
> void write(llvm::raw_ostream& out) {
> + assert( out.tell() == 0 );
> out.write((char*)_headerBuffer, _headerBufferSize);
> - if (!_definedAtomIvars.empty())
> +
> + if (!_definedAtomIvars.empty()) {
> + assert( out.tell() == findChunk(NCS_DefinedAtomsV1).fileOffset );
> out.write((char*)&_definedAtomIvars[0],
> _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1));
> - if (!_attributes.empty())
> + }
> +
> + if (!_attributes.empty()) {
> + assert( out.tell() == findChunk(NCS_AttributesArrayV1).fileOffset );
> out.write((char*)&_attributes[0],
> _attributes.size()*sizeof(NativeAtomAttributesV1));
> - if ( !_undefinedAtomIvars.empty() )
> + }
> +
> + if ( !_undefinedAtomIvars.empty() ) {
> + assert( out.tell() == findChunk(NCS_UndefinedAtomsV1).fileOffset );
> out.write((char*)&_undefinedAtomIvars[0],
>
> _undefinedAtomIvars.size()*sizeof(NativeUndefinedAtomIvarsV1));
> - if (!_stringPool.empty())
> + }
> +
> + if (!_stringPool.empty()) {
> + assert( out.tell() == findChunk(NCS_Strings).fileOffset );
> out.write(&_stringPool[0], _stringPool.size());
> - if (!_contentPool.empty())
> + }
> +
> + if ( !_references.empty() ) {
> + assert( out.tell() == findChunk(NCS_ReferencesArrayV1).fileOffset );
> + out.write((char*)&_references[0],
> + _references.size()*sizeof(NativeReferenceIvarsV1));
> + }
> +
> + if ( !_targetsTableIndex.empty() ) {
> + assert( out.tell() == findChunk(NCS_TargetsTable).fileOffset );
> + writeTargetTable(out);
> + }
> +
> + if ( !_addendsTableIndex.empty() ) {
> + assert( out.tell() == findChunk(NCS_AddendsTable).fileOffset );
> + writeAddendTable(out);
> + }
> +
> + if (!_contentPool.empty()) {
> + assert( out.tell() == findChunk(NCS_Content).fileOffset );
> out.write((char*)&_contentPool[0], _contentPool.size());
> + }
> }
>
> private:
>
> // visitor routine called by forEachAtom()
> - virtual void doDefinedAtom(const class DefinedAtom& atom) {
> + virtual void doDefinedAtom(const DefinedAtom& atom) {
> + _definedAtomIndex[&atom] = _definedAtomIvars.size();
> NativeDefinedAtomIvarsV1 ivar;
> + unsigned refsCount;
> ivar.nameOffset = getNameOffset(atom);
> ivar.attributesOffset = getAttributeOffset(atom);
> + ivar.referencesStartIndex = getReferencesIndex(atom, refsCount);
> + ivar.referencesCount = refsCount;
> ivar.contentOffset = getContentOffset(atom);
> ivar.contentSize = atom.size();
> _definedAtomIvars.push_back(ivar);
> }
>
> // visitor routine called by forEachAtom()
> - virtual void doUndefinedAtom(const class UndefinedAtom& atom) {
> + virtual void doUndefinedAtom(const UndefinedAtom& atom) {
> + _undefinedAtomIndex[&atom] = _undefinedAtomIvars.size();
> NativeUndefinedAtomIvarsV1 ivar;
> ivar.nameOffset = getNameOffset(atom);
> ivar.flags = (atom.weakImport() ? 1 : 0);
> @@ -74,13 +115,18 @@
> }
>
> // visitor routine called by forEachAtom()
> - virtual void doFile(const class File &) {
> + virtual void doFile(const File &) {
> }
>
> // fill out native file header and chunk directory
> void makeHeader() {
> const bool hasUndefines = !_undefinedAtomIvars.empty();
> - const int chunkCount = hasUndefines ? 5 : 4;
> + const bool hasTargetsTable = !_targetsTableIndex.empty();
> + const bool hasAddendTable = !_addendsTableIndex.empty();
> + int chunkCount = 5;
> + if ( hasUndefines ) ++chunkCount;
> + if ( hasTargetsTable ) ++chunkCount;
> + if ( hasAddendTable ) ++chunkCount;
> _headerBufferSize = sizeof(NativeFileHeader)
> + chunkCount*sizeof(NativeChunk);
> _headerBuffer = reinterpret_cast<NativeFileHeader*>
> @@ -124,6 +170,9 @@
> }
>
> // create chunk for symbol strings
> + // pad end of string pool to 4-bytes
> + while ( (_stringPool.size() % 4) != 0 )
> + _stringPool.push_back('\0');
> NativeChunk& chs = chunks[nextIndex++];
> chs.signature = NCS_Strings;
> chs.fileOffset = nextFileOffset;
> @@ -131,6 +180,34 @@
> chs.elementCount = _stringPool.size();
> nextFileOffset = chs.fileOffset + chs.fileSize;
>
> + // create chunk for references
> + NativeChunk& chr = chunks[nextIndex++];
> + chr.signature = NCS_ReferencesArrayV1;
> + chr.fileOffset = nextFileOffset;
> + chr.fileSize = _references.size() * sizeof(NativeReferenceIvarsV1);
> + chr.elementCount = _references.size();
> + nextFileOffset = chr.fileOffset + chr.fileSize;
> +
> + // create chunk for target table
> + if ( hasTargetsTable ) {
> + NativeChunk& cht = chunks[nextIndex++];
> + cht.signature = NCS_TargetsTable;
> + cht.fileOffset = nextFileOffset;
> + cht.fileSize = _targetsTableIndex.size() * sizeof(uint32_t);
> + cht.elementCount = _targetsTableIndex.size();
> + nextFileOffset = cht.fileOffset + cht.fileSize;
> + }
> +
> + // create chunk for addend table
> + if ( hasAddendTable ) {
> + NativeChunk& chad = chunks[nextIndex++];
> + chad.signature = NCS_AddendsTable;
> + chad.fileOffset = nextFileOffset;
> + chad.fileSize = _addendsTableIndex.size() *
> sizeof(Reference::Addend);
> + chad.elementCount = _addendsTableIndex.size();
> + nextFileOffset = chad.fileOffset + chad.fileSize;
> + }
> +
> // create chunk for content
> NativeChunk& chc = chunks[nextIndex++];
> chc.signature = NCS_Content;
> @@ -142,6 +219,18 @@
> _headerBuffer->fileSize = nextFileOffset;
> }
>
> + // scan header to find particular chunk
> + NativeChunk& findChunk(uint32_t signature) {
> + const uint32_t chunkCount = _headerBuffer->chunkCount;
> + NativeChunk* chunks =
> +
> reinterpret_cast<NativeChunk*>(reinterpret_cast<char*>(_headerBuffer)
> + + sizeof(NativeFileHeader));
> + for (uint32_t i=0; i < chunkCount; ++i) {
> + if ( chunks[i].signature == signature )
> + return chunks[i];
> + }
> + assert(0 && "findChunk() signature not found");
> + }
>
> // append atom name to string pool and return offset
> uint32_t getNameOffset(const Atom& atom) {
> @@ -150,6 +239,8 @@
>
> // append atom name to string pool and return offset
> uint32_t getNameOffset(llvm::StringRef name) {
> + if ( name.empty() )
> + return 0;
> uint32_t result = _stringPool.size();
> _stringPool.insert(_stringPool.end(), name.size()+1, 0);
> strcpy(&_stringPool[result], name.data());
> @@ -206,7 +297,6 @@
> attrs.sectionNameOffset = sectionNameOffset(atom);
> attrs.align2 = atom.alignment().powerOf2;
> attrs.alignModulus = atom.alignment().modulus;
> - attrs.internalName = atom.internalName();
> attrs.scope = atom.scope();
> attrs.interposable = atom.interposable();
> attrs.merge = atom.merge();
> @@ -214,12 +304,99 @@
> attrs.sectionChoice = atom.sectionChoice();
> attrs.deadStrip = atom.deadStrip();
> attrs.permissions = atom.permissions();
> - attrs.thumb = atom.isThumb();
> + //attrs.thumb = atom.isThumb();
> attrs.alias = atom.isAlias();
> }
>
> + // add references for this atom in a contiguous block in
> NCS_ReferencesArrayV1
> + uint32_t getReferencesIndex(const DefinedAtom& atom, unsigned& count) {
> + count = 0;
> + size_t startRefSize = _references.size();
> + uint32_t result = startRefSize;
> + atom.forEachReference(*this);
> + count = _references.size() - startRefSize;
> + if ( count == 0 )
> + return 0;
> + else
> + return result;
> + }
> +
> + void doReference(const Reference& ref) {
> + NativeReferenceIvarsV1 nref;
> + nref.offsetInAtom = ref.offsetInAtom();
> + nref.kind = ref.kind();
> + nref.targetIndex = this->getTargetIndex(ref.target());
> + nref.addendIndex = this->getAddendIndex(ref.addend());
> + _references.push_back(nref);
> + }
> +
> + uint32_t getTargetIndex(const Atom* target) {
> + TargetToIndex::const_iterator pos = _targetsTableIndex.find(target);
> + if ( pos != _targetsTableIndex.end() ) {
> + return pos->second;
> + }
> + uint32_t result = _targetsTableIndex.size();
> + _targetsTableIndex[target] = result;
> + return result;
> + }
> +
> + void writeTargetTable(llvm::raw_ostream& out) {
> + // Build table of target indexes
> + uint32_t maxTargetIndex = _targetsTableIndex.size();
> + uint32_t targetIndexes[maxTargetIndex];
> + for (TargetToIndex::iterator it = _targetsTableIndex.begin();
> + it != _targetsTableIndex.end(); ++it) {
> + const Atom* atom = it->first;
> + uint32_t targetIndex = it->second;
> + assert(targetIndex < maxTargetIndex);
> + uint32_t atomIndex = 0;
> + TargetToIndex::iterator pos = _definedAtomIndex.find(atom);
> + if ( pos != _definedAtomIndex.end() ) {
> + atomIndex = pos->second;
> + }
> + else {
> + pos = _undefinedAtomIndex.find(atom);
> + assert(pos != _undefinedAtomIndex.end());
> + atomIndex = pos->second + _definedAtomIvars.size();
> + }
> + targetIndexes[targetIndex] = atomIndex;
> + }
> + // write table
> + out.write((char*)&targetIndexes[0], maxTargetIndex*sizeof(uint32_t));
> + }
> +
> + uint32_t getAddendIndex(Reference::Addend addend) {
> + if ( addend == 0 )
> + return 0; // addend index zero is used to mean "no addend"
> + AddendToIndex::const_iterator pos = _addendsTableIndex.find(addend);
> + if ( pos != _addendsTableIndex.end() ) {
> + return pos->second;
> + }
> + uint32_t result = _addendsTableIndex.size() + 1; // one-based index
> + _addendsTableIndex[addend] = result;
> + return result;
> + }
> +
> + void writeAddendTable(llvm::raw_ostream& out) {
> + // Build table of addends
> + uint32_t maxAddendIndex = _addendsTableIndex.size();
> + Reference::Addend addends[maxAddendIndex];
> + for (AddendToIndex::iterator it = _addendsTableIndex.begin();
> + it != _addendsTableIndex.end(); ++it) {
> + Reference::Addend addend = it->first;
> + uint32_t index = it->second;
> + assert(index <= maxAddendIndex);
> + addends[index-1] = addend;
> + }
> + // write table
> + out.write((char*)&addends[0],
> maxAddendIndex*sizeof(Reference::Addend));
> + }
> +
> typedef std::vector<std::pair<llvm::StringRef, uint32_t> >
> NameToOffsetVector;
>
> + typedef llvm::DenseMap<const Atom*, uint32_t> TargetToIndex;
> + typedef llvm::DenseMap<Reference::Addend, uint32_t> AddendToIndex;
> +
> const lld::File& _file;
> NativeFileHeader* _headerBuffer;
> size_t _headerBufferSize;
> @@ -228,6 +405,11 @@
> std::vector<NativeDefinedAtomIvarsV1> _definedAtomIvars;
> std::vector<NativeAtomAttributesV1> _attributes;
> std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;
> + std::vector<NativeReferenceIvarsV1> _references;
> + TargetToIndex _targetsTableIndex;
> + TargetToIndex _definedAtomIndex;
> + TargetToIndex _undefinedAtomIndex;
> + AddendToIndex _addendsTableIndex;
> NameToOffsetVector _sectionNames;
> };
>
>
> Modified: lld/trunk/lib/Core/Resolver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/Resolver.cpp (original)
> +++ lld/trunk/lib/Core/Resolver.cpp Tue Feb 14 18:38:09 2012
> @@ -199,20 +199,34 @@
> }
> }
>
> +// helper to update targets for use with forEachReference()
> +class ReferenceUpdater : public DefinedAtom::ReferenceHandler {
> +public:
> + ReferenceUpdater(SymbolTable& sym) :
> _symbolTable(sym) { }
> +
> + virtual void doReference(const Reference& ref) {
> + const Atom* newTarget = _symbolTable.replacement(ref.target());
> + (const_cast<Reference*>(&ref))->setTarget(newTarget);
> + }
> +
> +private:
> + SymbolTable& _symbolTable;
> +};
> +
> +
> // switch all references to undefined or coalesced away atoms
> // to the new defined atom
> void Resolver::updateReferences() {
> + ReferenceUpdater updater(_symbolTable);
> for (std::vector<const Atom *>::iterator it = _atoms.begin();
> it != _atoms.end(); ++it) {
> if ( const DefinedAtom* defAtom = (*it)->definedAtom() ) {
> - for (Reference::iterator rit = defAtom->referencesBegin(),
> - end = defAtom->referencesEnd(); rit != end; ++rit) {
> - rit->target = _symbolTable.replacement(rit->target);
> - }
> + defAtom->forEachReference(updater);
> }
> }
> }
>
> +
> // for dead code stripping, recursively mark atom "live"
> void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) {
> // if -why_live cares about this symbol, then dump chain
> @@ -240,10 +254,8 @@
> thisChain.previous = previous;
> thisChain.referer = &atom;
> if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
> - for (Reference::iterator rit = defAtom->referencesBegin(),
> - end = defAtom->referencesEnd(); rit != end; ++rit) {
> - this->markLive(*(rit->target), &thisChain);
> - }
> + MarkLiveReferences markRefs(*this, &thisChain);
> + defAtom->forEachReference(markRefs);
> }
> }
>
>
> Modified: lld/trunk/lib/Core/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/SymbolTable.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/SymbolTable.cpp (original)
> +++ lld/trunk/lib/Core/SymbolTable.cpp Tue Feb 14 18:38:09 2012
> @@ -38,7 +38,7 @@
>
> void SymbolTable::add(const DefinedAtom &atom) {
> assert(atom.scope() != DefinedAtom::scopeTranslationUnit);
> - if ( !atom.internalName() ) {
> + if ( !atom.name().empty() ) {
> this->addByName(atom);
> }
> else {
>
> Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
> +++ lld/trunk/lib/Core/YamlKeyValues.cpp Tue Feb 14 18:38:09 2012
> @@ -18,12 +18,12 @@
>
>
> const char* const KeyValues::nameKeyword = "name";
> +const char* const KeyValues::refNameKeyword = "ref-name";
> const char* const KeyValues::definitionKeyword = "definition";
> const char* const KeyValues::scopeKeyword = "scope";
> const char* const KeyValues::contentTypeKeyword = "type";
> const char* const KeyValues::deadStripKindKeyword = "dead-strip";
> const char* const KeyValues::sectionChoiceKeyword = "section-choice";
> -const char* const KeyValues::internalNameKeyword = "internal-name";
> const char* const KeyValues::interposableKeyword = "interposable";
> const char* const KeyValues::mergeKeyword = "merge";
> const char* const KeyValues::isThumbKeyword = "is-thumb";
> @@ -31,8 +31,14 @@
> const char* const KeyValues::sectionNameKeyword = "section-name";
> const char* const KeyValues::contentKeyword = "content";
> const char* const KeyValues::sizeKeyword = "size";
> +const char* const KeyValues::fixupsKeyword = "fixups";
> const char* const KeyValues::permissionsKeyword = "permissions";
> const char* const KeyValues::weakImportKeyword = "weak-import";
> +const char* const KeyValues::fixupsKindKeyword = "kind";
> +const char* const KeyValues::fixupsOffsetKeyword = "offset";
> +const char* const KeyValues::fixupsTargetKeyword = "target";
> +const char* const KeyValues::fixupsAddendKeyword = "addend";
> +
>
>
> const DefinedAtom::Definition KeyValues::definitionDefault =
> Atom::definitionRegular;
> @@ -43,7 +49,6 @@
> const DefinedAtom::Interposable KeyValues::interposableDefault =
> DefinedAtom::interposeNo;
> const DefinedAtom::Merge KeyValues::mergeDefault =
> DefinedAtom::mergeNo;
> const DefinedAtom::ContentPermissions KeyValues::permissionsDefault =
> DefinedAtom::permR__;
> -const bool KeyValues::internalNameDefault =
> false;
> const bool KeyValues::isThumbDefault = false;
> const bool KeyValues::isAliasDefault = false;
> const bool KeyValues::weakImportDefault =
> false;
> @@ -352,22 +357,6 @@
>
>
>
> -bool KeyValues::internalName(const char* s)
> -{
> - if ( strcmp(s, "true") == 0 )
> - return true;
> - else if ( strcmp(s, "false") == 0 )
> - return false;
> - llvm::report_fatal_error("bad internal-name value");
> -}
> -
> -const char* KeyValues::internalName(bool b) {
> - return b ? "true" : "false";
> -}
> -
> -
> -
> -
> bool KeyValues::isThumb(const char* s)
> {
> if ( strcmp(s, "true") == 0 )
>
> Modified: lld/trunk/lib/Core/YamlKeyValues.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/YamlKeyValues.h (original)
> +++ lld/trunk/lib/Core/YamlKeyValues.h Tue Feb 14 18:38:09 2012
> @@ -20,10 +20,12 @@
> class KeyValues {
> public:
> static const char* const nameKeyword;
> + static const char* const refNameKeyword;
> static const char* const sectionNameKeyword;
> static const char* const contentKeyword;
> static const char* const sizeKeyword;
> -
> + static const char* const fixupsKeyword;
> +
> static const char* const definitionKeyword;
> static const Atom::Definition definitionDefault;
> static Atom::Definition definition(const char*);
> @@ -64,11 +66,6 @@
> static DefinedAtom::ContentPermissions permissions(const char*);
> static const char*
> permissions(DefinedAtom::ContentPermissions);
>
> - static const char* const internalNameKeyword;
> - static const bool internalNameDefault;
> - static bool internalName(const char*);
> - static const char* internalName(bool);
> -
> static const char* const isThumbKeyword;
> static const bool isThumbDefault;
> static bool isThumb(const char*);
> @@ -84,6 +81,12 @@
> static bool weakImport(const char*);
> static const char* weakImport(bool);
>
> +
> + static const char* const fixupsKindKeyword;
> + static const char* const fixupsOffsetKeyword;
> + static const char* const fixupsTargetKeyword;
> + static const char* const fixupsAddendKeyword;
> +
> };
>
> } // namespace yaml
>
> Modified: lld/trunk/lib/Core/YamlReader.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/YamlReader.cpp (original)
> +++ lld/trunk/lib/Core/YamlReader.cpp Tue Feb 14 18:38:09 2012
> @@ -7,6 +7,8 @@
> //
>
> //===----------------------------------------------------------------------===//
>
> +#include <string.h>
> +
> #include "YamlKeyValues.h"
>
> #include "lld/Core/YamlReader.h"
> @@ -30,6 +32,8 @@
> namespace lld {
> namespace yaml {
>
> +namespace {
> +
> class YAML {
> public:
> struct Entry {
> @@ -214,7 +218,7 @@
> sequenceBytes->push_back(contentByte);
> state = inValueSequenceEnd;
> }
> - else if (c == ' ') {
> + else if ( (c == ' ') || (c == '\n') ) {
> // eat white space
> }
> else if (c == ',') {
> @@ -245,6 +249,44 @@
> }
> }
>
> +
> +
> +class YAMLReference : public Reference {
> +public:
> + YAMLReference() : _target(NULL), _targetName(NULL),
> + _offsetInAtom(0), _addend(0), _kind(0)
> { }
> +
> + virtual uint64_t offsetInAtom() const {
> + return _offsetInAtom;
> + }
> +
> + virtual Kind kind() const {
> + return _kind;
> + }
> +
> + virtual const Atom* target() const {
> + return _target;
> + }
> +
> + virtual Addend addend() const {
> + return _addend;
> + }
> +
> + virtual void setTarget(const Atom* newAtom) {
> + _target = newAtom;
> + }
> +
> + const Atom* _target;
> + const char* _targetName;
> + uint64_t _offsetInAtom;
> + Addend _addend;
> + Kind _kind;
> +};
> +
> +
> +
> +class YAMLDefinedAtom;
> +
> class YAMLFile : public File {
> public:
> YAMLFile()
> @@ -255,29 +297,24 @@
> virtual bool justInTimeforEachAtom(llvm::StringRef name,
> File::AtomHandler &) const;
>
> - std::vector<DefinedAtom*> _definedAtoms;
> - std::vector<UndefinedAtom*> _undefinedAtoms;
> - std::vector<Reference> _references;
> - unsigned int _lastRefIndex;
> -};
> + void bindTargetReferences();
> + void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
> + void addUndefinedAtom(UndefinedAtom* atom);
> + Atom* findAtom(const char* name);
> +
> + struct NameAtomPair {
> + NameAtomPair(const char* n, Atom* a) : name(n), atom(a)
> {}
> + const char* name;
> + Atom* atom;
> + };
>
> -bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
> - handler.doFile(*this);
> - for (std::vector<DefinedAtom *>::const_iterator it =
> _definedAtoms.begin();
> - it != _definedAtoms.end(); ++it) {
> - handler.doDefinedAtom(**it);
> - }
> - for (std::vector<UndefinedAtom *>::const_iterator it =
> _undefinedAtoms.begin();
> - it != _undefinedAtoms.end(); ++it) {
> - handler.doUndefinedAtom(**it);
> - }
> - return true;
> -}
> + std::vector<YAMLDefinedAtom*> _definedAtoms;
> + std::vector<UndefinedAtom*> _undefinedAtoms;
> + std::vector<YAMLReference> _references;
> + std::vector<NameAtomPair> _nameToAtomMapping;
> + unsigned int _lastRefIndex;
> +};
>
> -bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
> - File::AtomHandler &handler) const {
> - return false;
> -}
>
>
> class YAMLDefinedAtom : public DefinedAtom {
> @@ -291,7 +328,6 @@
> , DefinedAtom::Merge merge
> , DefinedAtom::DeadStripKind deadStrip
> , DefinedAtom::ContentPermissions perms
> - , bool internalName
> , bool isThumb
> , bool isAlias
> , DefinedAtom::Alignment alignment
> @@ -313,7 +349,6 @@
> , _merge(merge)
> , _deadStrip(deadStrip)
> , _permissions(perms)
> - , _internalName(internalName)
> , _isThumb(isThumb)
> , _isAlias(isAlias)
> , _refStartIndex(file._lastRefIndex)
> @@ -326,13 +361,12 @@
> }
>
> virtual llvm::StringRef name() const {
> - return _name;
> + if ( _name == NULL )
> + return llvm::StringRef();
> + else
> + return _name;
> }
>
> - virtual bool internalName() const {
> - return _internalName;
> - }
> -
> virtual uint64_t size() const {
> return (_content ? _content->size() : _size);
> }
> @@ -393,16 +427,18 @@
> }
>
>
> - virtual Reference::iterator referencesBegin() const {
> - if (_file._references.size() < _refStartIndex)
> - return (Reference::iterator)&_file._references[_refStartIndex];
> - return 0;
> + virtual void forEachReference(ReferenceHandler& handler) const {
> + for (uint32_t i=_refStartIndex; i < _refEndIndex; ++i) {
> + handler.doReference(_file._references[i]);
> + }
> }
> -
> - virtual Reference::iterator referencesEnd() const {
> - if (_file._references.size() < _refEndIndex)
> - return (Reference::iterator)&_file._references[_refEndIndex];
> - return 0;
> +
> + void bindTargetReferences() {
> + for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
> + const char* targetName = _file._references[i]._targetName;
> + Atom* targetAtom = _file.findAtom(targetName);
> + _file._references[i]._target = targetAtom;
> + }
> }
>
> private:
> @@ -420,7 +456,6 @@
> DefinedAtom::Merge _merge;
> DefinedAtom::DeadStripKind _deadStrip;
> DefinedAtom::ContentPermissions _permissions;
> - bool _internalName;
> bool _isThumb;
> bool _isAlias;
> unsigned int _refStartIndex;
> @@ -453,22 +488,71 @@
> };
>
>
> +bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
> + handler.doFile(*this);
> + for (std::vector<YAMLDefinedAtom *>::const_iterator it =
> _definedAtoms.begin();
> + it != _definedAtoms.end(); ++it) {
> + handler.doDefinedAtom(**it);
> + }
> + for (std::vector<UndefinedAtom *>::const_iterator it =
> _undefinedAtoms.begin();
> + it != _undefinedAtoms.end(); ++it) {
> + handler.doUndefinedAtom(**it);
> + }
> + return true;
> +}
> +
> +bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
> + File::AtomHandler &handler) const {
> + return false;
> +}
> +
> +void YAMLFile::bindTargetReferences() {
> + for (std::vector<YAMLDefinedAtom *>::const_iterator
> + it = _definedAtoms.begin(); it != _definedAtoms.end(); ++it) {
> + YAMLDefinedAtom* atom = *it;
> + atom->bindTargetReferences();
> + }
> +}
> +
> +Atom* YAMLFile::findAtom(const char* name) {
> + for (std::vector<NameAtomPair>::const_iterator it =
> _nameToAtomMapping.begin();
> + it != _nameToAtomMapping.end(); ++it)
> {
> + if ( strcmp(name, it->name) == 0 )
> + return it->atom;
> + }
> + llvm::report_fatal_error("reference to atom that does not exist");
> +}
> +
> +void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName)
> {
> + _definedAtoms.push_back(atom);
> + assert(refName != NULL);
> + _nameToAtomMapping.push_back(NameAtomPair(refName, atom));
> +}
> +
> +void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
> + _undefinedAtoms.push_back(atom);
> + _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
> +}
> +
>
> class YAMLAtomState {
> public:
> YAMLAtomState();
>
> void setName(const char *n);
> + void setRefName(const char *n);
> void setAlign2(const char *n);
>
> void setFixupKind(const char *n);
> void setFixupOffset(const char *n);
> void setFixupTarget(const char *n);
> + void setFixupAddend(const char *n);
> void addFixup(YAMLFile *f);
>
> void makeAtom(YAMLFile&);
>
> const char * _name;
> + const char * _refName;
> const char * _sectionName;
> unsigned long long _size;
> uint32_t _ordinal;
> @@ -482,16 +566,16 @@
> DefinedAtom::Merge _merge;
> DefinedAtom::DeadStripKind _deadStrip;
> DefinedAtom::ContentPermissions _permissions;
> - bool _internalName;
> bool _isThumb;
> bool _isAlias;
> bool _weakImport;
> - Reference _ref;
> + YAMLReference _ref;
> };
>
>
> YAMLAtomState::YAMLAtomState()
> : _name(NULL)
> + , _refName(NULL)
> , _sectionName(NULL)
> , _size(0)
> , _ordinal(0)
> @@ -505,38 +589,31 @@
> , _merge(KeyValues::mergeDefault)
> , _deadStrip(KeyValues::deadStripKindDefault)
> , _permissions(KeyValues::permissionsDefault)
> - , _internalName(KeyValues::internalNameDefault)
> , _isThumb(KeyValues::isThumbDefault)
> , _isAlias(KeyValues::isAliasDefault)
> , _weakImport(false)
> {
> - _ref.target = NULL;
> - _ref.addend = 0;
> - _ref.offsetInAtom = 0;
> - _ref.kind = 0;
> - _ref.flags = 0;
> -}
> + }
>
>
> void YAMLAtomState::makeAtom(YAMLFile& f) {
> if ( _definition == Atom::definitionRegular ) {
> - DefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
> + YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
> _sectionChoice, _interpose, _merge, _deadStrip,
> - _permissions, _internalName, _isThumb,
> _isAlias,
> + _permissions, _isThumb, _isAlias,
> _alignment, _name, _sectionName, _size,
> _content);
> -
> - f._definedAtoms.push_back(a);
> + f.addDefinedAtom(a, _refName ? _refName : _name);
> ++_ordinal;
> }
> else if ( _definition == Atom::definitionUndefined ) {
> UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name,
> _weakImport);
> -
> - f._undefinedAtoms.push_back(a);
> + f.addUndefinedAtom(a);
> ++_ordinal;
> }
>
> // reset state for next atom
> _name = NULL;
> + _refName = NULL;
> _sectionName = NULL;
> _size = 0;
> _ordinal = 0;
> @@ -554,17 +631,20 @@
> _isThumb = KeyValues::isThumbDefault;
> _isAlias = KeyValues::isAliasDefault;
> _weakImport = KeyValues::weakImportDefault;
> - _ref.target = NULL;
> - _ref.addend = 0;
> - _ref.offsetInAtom = 0;
> - _ref.kind = 0;
> - _ref.flags = 0;
> + _ref._target = NULL;
> + _ref._targetName = NULL;
> + _ref._addend = 0;
> + _ref._offsetInAtom = 0;
> + _ref._kind = 0;
> }
>
> void YAMLAtomState::setName(const char *n) {
> _name = n;
> }
>
> +void YAMLAtomState::setRefName(const char *n) {
> + _refName = n;
> +}
>
> void YAMLAtomState::setAlign2(const char *s) {
> llvm::StringRef str(s);
> @@ -576,33 +656,54 @@
>
> void YAMLAtomState::setFixupKind(const char *s) {
> if (strcmp(s, "pcrel32") == 0)
> - _ref.kind = 1;
> + _ref._kind = 1;
> else if (strcmp(s, "call32") == 0)
> - _ref.kind = 2;
> - else
> - llvm::report_fatal_error("bad fixup kind value");
> + _ref._kind = 2;
> + else {
> + int k;
> + llvm::StringRef(s).getAsInteger(10, k);
> + _ref._kind = k;
> + }
> }
>
> void YAMLAtomState::setFixupOffset(const char *s) {
> if ((s[0] == '0') && (s[1] == 'x'))
> - llvm::StringRef(s).getAsInteger(16, _ref.offsetInAtom);
> + llvm::StringRef(s).getAsInteger(16, _ref._offsetInAtom);
> else
> - llvm::StringRef(s).getAsInteger(10, _ref.offsetInAtom);
> + llvm::StringRef(s).getAsInteger(10, _ref._offsetInAtom);
> }
>
> void YAMLAtomState::setFixupTarget(const char *s) {
> + _ref._targetName = s;
> }
>
> +void YAMLAtomState::setFixupAddend(const char *s) {
> + if ((s[0] == '0') && (s[1] == 'x'))
> + llvm::StringRef(s).getAsInteger(16, _ref._addend);
> + else
> + llvm::StringRef(s).getAsInteger(10, _ref._addend);
> +}
> +
> +
> void YAMLAtomState::addFixup(YAMLFile *f) {
> f->_references.push_back(_ref);
> // clear for next ref
> - _ref.target = NULL;
> - _ref.addend = 0;
> - _ref.offsetInAtom = 0;
> - _ref.kind = 0;
> - _ref.flags = 0;
> + _ref._target = NULL;
> + _ref._targetName = NULL;
> + _ref._addend = 0;
> + _ref._offsetInAtom = 0;
> + _ref._kind = 0;
> }
>
> +
> +} // anonymous namespace
> +
> +
> +
> +
> +
> +/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
> +/// into lld::File object(s) and append each to the specified
> vector<File*>.
> llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
> , std::vector<File *> &result) {
> std::vector<const YAML::Entry *> entries;
> @@ -628,6 +729,7 @@
> atomState.makeAtom(*file);
> haveAtom = false;
> }
> + file->bindTargetReferences();
> result.push_back(file);
> }
> file = new YAMLFile();
> @@ -663,10 +765,10 @@
> atomState.setName(entry->value);
> haveAtom = true;
> }
> - else if (strcmp(entry->key, KeyValues::internalNameKeyword) == 0)
> {
> - atomState._internalName = KeyValues::internalName(entry->value);
> + else if (strcmp(entry->key, KeyValues::refNameKeyword) == 0) {
> + atomState.setRefName(entry->value);
> haveAtom = true;
> - }
> + }
> else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
> atomState._definition = KeyValues::definition(entry->value);
> haveAtom = true;
> @@ -725,8 +827,9 @@
> atomState.setAlign2(entry->value);
> haveAtom = true;
> }
> - else if (strcmp(entry->key, "fixups") == 0) {
> + else if (strcmp(entry->key, KeyValues::fixupsKeyword) == 0) {
> inFixups = true;
> +
> }
> else {
> return make_error_code(yaml_reader_error::unknown_keyword);
> @@ -739,16 +842,22 @@
> haveFixup = false;
> }
> }
> - if (strcmp(entry->key, "kind") == 0) {
> + if (strcmp(entry->key, KeyValues::fixupsKindKeyword) == 0) {
> atomState.setFixupKind(entry->value);
> haveFixup = true;
> - } else if (strcmp(entry->key, "offset") == 0) {
> + }
> + else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0)
> {
> atomState.setFixupOffset(entry->value);
> haveFixup = true;
> - } else if (strcmp(entry->key, "target") == 0) {
> + }
> + else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0)
> {
> atomState.setFixupTarget(entry->value);
> haveFixup = true;
> }
> + else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0)
> {
> + atomState.setFixupAddend(entry->value);
> + haveFixup = true;
> + }
> }
> }
> lastDepth = entry->depth;
> @@ -757,10 +866,12 @@
> atomState.makeAtom(*file);
> }
>
> + file->bindTargetReferences();
> result.push_back(file);
> return make_error_code(yaml_reader_error::success);
> }
>
> +
> //
> // Fill in vector<File*> from path to input text file.
> //
>
> Modified: lld/trunk/lib/Core/YamlWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/Core/YamlWriter.cpp (original)
> +++ lld/trunk/lib/Core/YamlWriter.cpp Tue Feb 14 18:38:09 2012
> @@ -15,6 +15,8 @@
> #include "lld/Core/Reference.h"
>
> #include "llvm/ADT/OwningPtr.h"
> +#include "llvm/ADT/DenseMap.h"
> +#include "llvm/ADT/StringExtras.h"
> #include "llvm/ADT/ArrayRef.h"
> #include "llvm/ADT/StringExtras.h"
> #include "llvm/Support/DataTypes.h"
> @@ -26,50 +28,154 @@
> namespace lld {
> namespace yaml {
>
> -class Handler : public File::AtomHandler {
> +namespace {
> +///
> +/// In most cases, atoms names are unambiguous, so references can just
> +/// use the atom name as the target (e.g. target: foo). But in a few
> +/// cases that does not work, so ref-names are added. These are labels
> +/// used only in yaml. The labels do not exist in the Atom model.
> +///
> +/// One need for ref-names are when atoms have no user supplied name
> +/// (e.g. c-string literal). Another case is when two object files with
> +/// identically named static functions are merged (ld -r) into one object
> file.
> +/// In that case referencing the function by name is ambiguous, so a
> unique
> +/// ref-name is added.
> +///
> +class RefNameBuilder : public File::AtomHandler,
> + public DefinedAtom::ReferenceHandler {
> public:
> - Handler(llvm::raw_ostream &out) : _out(out), _firstAtom(true) { }
> + RefNameBuilder() { }
> +
> + virtual void doReference(const Reference& ref) {
> + // create refname for any unnamed reference target
> + if ( ref.target()->name().empty() ) {
> + char* buffer;
> + asprintf(&buffer, "L%03d", _unnamedCounter++);
> + _refNames[ref.target()] = buffer;
> + }
> + }
> +
> + virtual void doFile(const File &) { }
> +
> + virtual void doDefinedAtom(const DefinedAtom& atom) {
> + // Build map of atoms names to detect duplicates
> + if ( ! atom.name().empty() )
> + buildDuplicateNameMap(atom);
> +
> + // Find references to unnamed atoms and create ref-names for them.
> + _unnamedCounter = 0;
> + atom.forEachReference(*this);
> + }
> +
> + virtual void doUndefinedAtom(const UndefinedAtom& atom) {
> + buildDuplicateNameMap(atom);
> + }
> +
> + void buildDuplicateNameMap(const Atom& atom) {
> + assert(!atom.name().empty());
> + NameToAtom::iterator pos = _nameMap.find(atom.name());
> + if ( pos != _nameMap.end() ) {
> + // Found name collision, give each a unique ref-name.
> + char* buffer;
> + asprintf(&buffer, "%s.%03d", atom.name().data(),
> ++_collisionCount);
> + _refNames[&atom] = buffer;
> + const Atom* prevAtom = pos->second;
> + AtomToRefName::iterator pos2 = _refNames.find(prevAtom);
> + if ( pos2 == _refNames.end() ) {
> + // only create ref-name for previous if none already created
> + asprintf(&buffer, "%s.%03d", prevAtom->name().data(),
> ++_collisionCount);
> + _refNames[prevAtom] = buffer;
> + }
> + }
> + else {
> + // First time we've seen this name, just add it to map.
> + _nameMap[atom.name()] = &atom;
> + }
> + }
> +
> + bool hasRefName(const Atom* atom) {
> + return _refNames.count(atom);
> + }
> +
> + const char* refName(const Atom* atom) {
> + return _refNames.find(atom)->second;
> + }
> +
> +private:
> + struct MyMappingInfo {
> + static llvm::StringRef getEmptyKey() { return llvm::StringRef(); }
> + static llvm::StringRef getTombstoneKey() { return llvm::StringRef("
> ", 0); }
> + static unsigned getHashValue(llvm::StringRef const val) {
> + return
> llvm::HashString(val); }
> + static bool isEqual(llvm::StringRef const lhs,
> + llvm::StringRef const rhs) { return
> lhs.equals(rhs); }
> + };
> + typedef llvm::DenseMap<llvm::StringRef, const Atom*, MyMappingInfo>
> NameToAtom;
> + typedef llvm::DenseMap<const Atom*, const char*> AtomToRefName;
> +
> + unsigned int _collisionCount;
> + unsigned int _unnamedCounter;
> + NameToAtom _nameMap;
> + AtomToRefName _refNames;
> +};
> +
> +
> +///
> +/// Helper class for writeObjectText() to write out atoms in yaml format.
> +///
> +class AtomWriter : public File::AtomHandler,
> + public DefinedAtom::ReferenceHandler {
> +public:
> + AtomWriter(RefNameBuilder& rnb, llvm::raw_ostream &out)
> + : _out(out), _rnb(rnb), _firstAtom(true) { }
>
> virtual void doFile(const class File &) { _firstAtom = true; }
>
> virtual void doDefinedAtom(const class DefinedAtom &atom) {
> - // add blank line between atoms for readability
> - if ( !_firstAtom )
> - _out << "\n";
> - _firstAtom = false;
> -
> + // add blank line between atoms for readability
> + if ( !_firstAtom )
> + _out << "\n";
> + _firstAtom = false;
> +
> + bool hasDash = false;
> + if ( !atom.name().empty() ) {
> _out << " - "
> << KeyValues::nameKeyword
> << ":"
> << spacePadding(KeyValues::nameKeyword)
> << atom.name()
> << "\n";
> -
> - if ( atom.internalName() != KeyValues::internalNameDefault ) {
> - _out << " "
> - << KeyValues::internalNameKeyword
> + hasDash = true;
> + }
> +
> + if ( _rnb.hasRefName(&atom) ) {
> + _out << (hasDash ? " " : " - ")
> + << KeyValues::refNameKeyword
> << ":"
> - << spacePadding(KeyValues::internalNameKeyword)
> - << KeyValues::internalName(atom.internalName())
> + << spacePadding(KeyValues::refNameKeyword)
> + << _rnb.refName(&atom)
> << "\n";
> + hasDash = true;
> }
>
> if ( atom.definition() != KeyValues::definitionDefault ) {
> - _out << " "
> + _out << (hasDash ? " " : " - ")
> << KeyValues::definitionKeyword
> << ":"
> << spacePadding(KeyValues::definitionKeyword)
> << KeyValues::definition(atom.definition())
> << "\n";
> + hasDash = true;
> }
>
> if ( atom.scope() != KeyValues::scopeDefault ) {
> - _out << " "
> + _out << (hasDash ? " " : " - ")
> << KeyValues::scopeKeyword
> << ":"
> << spacePadding(KeyValues::scopeKeyword)
> << KeyValues::scope(atom.scope())
> << "\n";
> + hasDash = true;
> }
>
> if ( atom.interposable() != KeyValues::interposableDefault ) {
> @@ -161,17 +267,51 @@
> _out << " ]\n";
> }
>
> - if (atom.referencesBegin() != atom.referencesEnd()) {
> + _wroteFirstFixup = false;
> + atom.forEachReference(*this);
> + }
> +
> + virtual void doReference(const Reference& ref) {
> + if ( !_wroteFirstFixup ) {
> _out << " fixups:\n";
> - for (Reference::iterator it = atom.referencesBegin(),
> - end = atom.referencesEnd(); it != end; ++it) {
> - _out << " - kind: " << it->kind << "\n";
> - _out << " offset: " << it->offsetInAtom << "\n";
> - }
> + _wroteFirstFixup = true;
> + }
> + _out << " - "
> + << KeyValues::fixupsOffsetKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsOffsetKeyword)
> + << ref.offsetInAtom()
> + << "\n";
> + _out << " "
> + << KeyValues::fixupsKindKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsKindKeyword)
> + << ref.kind()
> + << "\n";
> + const Atom* target = ref.target();
> + if ( target != NULL ) {
> + llvm::StringRef refName = target->name();
> + if ( _rnb.hasRefName(target) )
> + refName = _rnb.refName(target);
> + assert(!refName.empty());
> + _out << " "
> + << KeyValues::fixupsTargetKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsTargetKeyword)
> + << refName
> + << "\n";
> + }
> + if ( ref.addend() != 0 ) {
> + _out << " "
> + << KeyValues::fixupsAddendKeyword
> + << ":"
> + << spacePadding(KeyValues::fixupsAddendKeyword)
> + << ref.addend()
> + << "\n";
> }
> -
> }
>
> +
> virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
> // add blank line between atoms for readability
> if ( !_firstAtom )
> @@ -219,11 +359,26 @@
> }
>
> llvm::raw_ostream& _out;
> + RefNameBuilder _rnb;
> bool _firstAtom;
> + bool _wroteFirstFixup;
> };
>
> +} // anonymous namespace
> +
> +
> +
> +///
> +/// writeObjectText - writes the lld::File object as in YAML
> +/// format to the specified stream.
> +///
> void writeObjectText(const File &file, llvm::raw_ostream &out) {
> - Handler h(out);
> + // Figure what ref-name labels are needed
> + RefNameBuilder rnb;
> + file.forEachAtom(rnb);
> +
> + // Write out all atoms
> + AtomWriter h(rnb, out);
> out << "---\n";
> out << "atoms:\n";
> file.forEachAtom(h);
>
> Modified: lld/trunk/test/cstring-coalesce.objtxt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/cstring-coalesce.objtxt?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/test/cstring-coalesce.objtxt (original)
> +++ lld/trunk/test/cstring-coalesce.objtxt Tue Feb 14 18:38:09 2012
> @@ -6,28 +6,24 @@
>
> ---
> atoms:
> - - name: L0
> - internal-name: true
> + - ref-name: L0
> scope: hidden
> type: c-string
> content: [ 68, 65, 6c, 6c, 6f, 00 ]
>
> - - name: L1
> - internal-name: true
> + - ref-name: L1
> scope: hidden
> type: c-string
> content: [ 74, 68, 65, 72, 65, 00 ]
> ---
> atoms:
> - - name: L2
> - internal-name: true
> + - ref-name: L2
> scope: hidden
> type: c-string
> content: [ 68, 65, 6c, 6c, 6f, 00 ]
> ---
> atoms:
> - - name: L2
> - internal-name: true
> + - ref-name: L2
> scope: hidden
> type: c-string
> content: [ 74, 68, 65, 72, 65, 00 ]
>
> Added: lld/trunk/test/fixups-addend.objtxt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-addend.objtxt?rev=150539&view=auto
>
> ==============================================================================
> --- lld/trunk/test/fixups-addend.objtxt (added)
> +++ lld/trunk/test/fixups-addend.objtxt Tue Feb 14 18:38:09 2012
> @@ -0,0 +1,50 @@
> +# RUN: lld-core %s | FileCheck %s
> +
> +#
> +# Test addends in fixups
> +#
> +
> +---
> +atoms:
> + - name: foo
> + type: code
> + content: [ 48, 8D, 3D, 00, 00, 00, 00,
> + 48, 8D, 3D, 00, 00, 00, 00 ]
> + fixups:
> + - offset: 3
> + kind: 3
> + target: bar
> + addend: 100
> + - offset: 10
> + kind: 3
> + target: bar
> + addend: -50
> +
> + - name: func
> + type: code
> + content: [ 48, 8D, 3D, 00, 00, 00, 00,
> + 48, 8D, 3D, 00, 00, 00, 00 ]
> + fixups:
> + - offset: 3
> + kind: 3
> + target: bar
> + addend: 8000000000
> + - offset: 10
> + kind: 3
> + target: bar
> + addend: -50
> +
> + - name: bar
> + definition: undefined
> +
> +
> +...
> +
> +# CHECK: name: foo
> +# CHECK: fixups:
> +# CHECK: addend: 100
> +# CHECK: addend: -50
> +# CHECK: name: func
> +# CHECK: fixups:
> +# CHECK: addend: 8000000000
> +# CHECK: addend: -50
>
> Added: lld/trunk/test/fixups-dup-named.objtxt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-dup-named.objtxt?rev=150539&view=auto
>
> ==============================================================================
> --- lld/trunk/test/fixups-dup-named.objtxt (added)
> +++ lld/trunk/test/fixups-dup-named.objtxt Tue Feb 14 18:38:09 2012
> @@ -0,0 +1,31 @@
> +# RUN: lld-core %s | FileCheck %s
> +
> +#
> +# Test fixups referencing multiple atoms that have the same name
> +#
> +
> +---
> +atoms:
> + - name: foo
> + type: code
> + content: [ E8, 00, 00, 00, 00, E8, 00, 00, 00, 00 ]
> + fixups:
> + - offset: 1
> + kind: 3
> + target: bar_1
> + - offset: 6
> + kind: 3
> + target: bar_2
> +
> + - name: bar
> + ref-name: bar_1
> + scope: static
> +
> + - name: bar
> + ref-name: bar_2
> + scope: static
> +
> +
> +...
> +
> +# CHECK: ...
>
> Added: lld/trunk/test/fixups-named.objtxt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-named.objtxt?rev=150539&view=auto
>
> ==============================================================================
> --- lld/trunk/test/fixups-named.objtxt (added)
> +++ lld/trunk/test/fixups-named.objtxt Tue Feb 14 18:38:09 2012
> @@ -0,0 +1,35 @@
> +# RUN: lld-core %s | FileCheck %s
> +
> +#
> +# Test fixups to simple named atoms
> +#
> +
> +---
> +atoms:
> + - name: foo
> + type: code
> + content: [ E8, 00, 00, 00, 00, E8, 00, 00, 00, 00 ]
> + fixups:
> + - offset: 1
> + kind: 3
> + target: bar
> + - offset: 6
> + kind: 3
> + target: baz
> +
> + - name: baz
> + scope: static
> + type: code
> +
> + - name: bar
> + definition: undefined
> +
> +
> +...
> +
> +# CHECK: name: foo
> +# CHECK: fixups:
> +# CHECK: target: bar
> +# CHECK: target: baz
> +# CHECK: ...
> +
>
> Added: lld/trunk/test/fixups-unnamed.objtxt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/fixups-unnamed.objtxt?rev=150539&view=auto
>
> ==============================================================================
> --- lld/trunk/test/fixups-unnamed.objtxt (added)
> +++ lld/trunk/test/fixups-unnamed.objtxt Tue Feb 14 18:38:09 2012
> @@ -0,0 +1,40 @@
> +# RUN: lld-core %s | FileCheck %s
> +
> +#
> +# Test fixups to unnamed atoms
> +#
> +
> +---
> +atoms:
> + - name: foo
> + type: code
> + content: [ 48, 8D, 3D, 00, 00, 00, 00,
> + 48, 8D, 3D, 00, 00, 00, 00 ]
> + fixups:
> + - offset: 3
> + kind: 3
> + target: LC1
> + - offset: 10
> + kind: 3
> + target: LC2
> +
> +
> + - ref-name: LC1
> + scope: hidden
> + type: c-string
> + content: [ 68, 65, 6c, 6c, 6f, 00 ]
> +
> + - ref-name: LC2
> + scope: hidden
> + type: c-string
> + content: [ 74, 68, 65, 72, 65, 00 ]
> +
> +
> +...
> +
> +# CHECK: name: foo
> +# CHECK: fixups:
> +# CHECK: offset: 3
> +# CHECK: offset: 10
> +# CHECK: ref-name:
> +# CHECK: ref-name:
>
> Removed: lld/trunk/test/internal-name-attributes.objtxt
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/internal-name-attributes.objtxt?rev=150538&view=auto
>
> ==============================================================================
> --- lld/trunk/test/internal-name-attributes.objtxt (original)
> +++ lld/trunk/test/internal-name-attributes.objtxt (removed)
> @@ -1,27 +0,0 @@
> -# RUN: lld-core %s | FileCheck %s
> -
> -#
> -# Test that internal-name attributes are preserved
> -#
> -
> ----
> -atoms:
> - - name: foo
> - internal-name: false
> - - name: L0
> - internal-name: true
> - - name: L1
> - internal-name: true
> - - name: bar
> -...
> -
> -
> -# CHECK: name: foo
> -# CHECK-NOT: internal-name: false
> -# CHECK: name: L0
> -# CHECK: internal-name: true
> -# CHECK: name: L1
> -# CHECK: internal-name: true
> -# CHECK: name: bar
> -# CHECK-NOT: internal-name: false
> -# CHECK: ...
>
> Modified: lld/trunk/tools/lld-core/lld-core.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=150539&r1=150538&r2=150539&view=diff
>
> ==============================================================================
> --- lld/trunk/tools/lld-core/lld-core.cpp (original)
> +++ lld/trunk/tools/lld-core/lld-core.cpp Tue Feb 14 18:38:09 2012
> @@ -234,8 +234,9 @@
>
> // read native file
> llvm::OwningPtr<lld::File> natFile;
> - parseNativeObjectFileOrSTDIN(tempPath, natFile);
> -
> + if ( error(parseNativeObjectFileOrSTDIN(tempPath, natFile)) )
> + return 1;
> +
> // write new atom graph out as YAML doc
> yaml::writeObjectText(*natFile, out);
>
>
>
> _______________________________________________
> 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/20120214/c5d0d581/attachment.html>
More information about the llvm-commits
mailing list