[llvm-commits] [lld] r149962 - in /lld/trunk: include/lld/Core/Atom.h include/lld/Core/NativeReader.h include/lld/Core/UndefinedAtom.h lib/Core/NativeFileFormat.h lib/Core/NativeReader.cpp lib/Core/NativeWriter.cpp lib/Core/Resolver.cpp lib/Core/YamlKeyValues.cpp lib/Core/YamlKeyValues.h lib/Core/YamlReader.cpp lib/Core/YamlWriter.cpp test/undef-coalesce.objtxt tools/lld-core/lld-core.cpp
Nick Kledzik
kledzik at apple.com
Mon Feb 6 18:59:54 PST 2012
Author: kledzik
Date: Mon Feb 6 20:59:54 2012
New Revision: 149962
URL: http://llvm.org/viewvc/llvm-project?rev=149962&view=rev
Log:
Add support for UndefinedAtom in yaml and native format. Add test cases with undefined atoms
Added:
lld/trunk/test/undef-coalesce.objtxt
Modified:
lld/trunk/include/lld/Core/Atom.h
lld/trunk/include/lld/Core/NativeReader.h
lld/trunk/include/lld/Core/UndefinedAtom.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/YamlKeyValues.cpp
lld/trunk/lib/Core/YamlKeyValues.h
lld/trunk/lib/Core/YamlReader.cpp
lld/trunk/lib/Core/YamlWriter.cpp
lld/trunk/tools/lld-core/lld-core.cpp
Modified: lld/trunk/include/lld/Core/Atom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Atom.h (original)
+++ lld/trunk/include/lld/Core/Atom.h Mon Feb 6 20:59:54 2012
@@ -20,6 +20,7 @@
class File;
class DefinedAtom;
+class UndefinedAtom;
///
/// The linker has a Graph Theory model of linking. An object file is seen
@@ -53,6 +54,10 @@
/// returns atom cast to DefinedAtom*, else returns nullptr;
virtual const DefinedAtom* definedAtom() const { return 0; }
+ /// undefinedAtom - like dynamic_cast, if atom is definitionUndefined
+ /// returns atom cast to UndefinedAtom*, else returns NULL;
+ virtual const UndefinedAtom* undefinedAtom() const { return NULL; }
+
protected:
/// Atom is an abstract base class. Only subclasses can access constructor.
Atom() {}
Modified: lld/trunk/include/lld/Core/NativeReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/NativeReader.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/NativeReader.h (original)
+++ lld/trunk/include/lld/Core/NativeReader.h Mon Feb 6 20:59:54 2012
@@ -12,6 +12,8 @@
#include "lld/Core/File.h"
+#include "llvm/ADT/OwningPtr.h"
+
#include "llvm/Support/system_error.h"
#include <vector>
@@ -26,13 +28,14 @@
/// parseNativeObjectFileOrSTDIN - Open the specified native object file (use
/// stdin if the path is "-") and instantiate into an lld::File object.
llvm::error_code parseNativeObjectFileOrSTDIN(llvm::StringRef path
- , File*&);
+ , llvm::OwningPtr<File>& result);
/// parseNativeObjectFile - Parse the specified native object file
/// (in a buffer) and instantiate into an lld::File object.
- llvm::error_code parseNativeObjectFile(llvm::MemoryBuffer* mb,
- llvm::StringRef path, File*& result);
+ llvm::error_code parseNativeObjectFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb
+ ,llvm::StringRef path
+ ,llvm::OwningPtr<File>& result);
} // namespace lld
Modified: lld/trunk/include/lld/Core/UndefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/UndefinedAtom.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/UndefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/UndefinedAtom.h Mon Feb 6 20:59:54 2012
@@ -20,31 +20,22 @@
/// It exists as a place holder for a future atom.
class UndefinedAtom : public Atom {
public:
- UndefinedAtom(llvm::StringRef nm, bool weakImport, const File& f)
- : _name(nm), _file(f), _weakImport(weakImport) {}
-
- virtual const File& file() const {
- return _file;
- }
-
- virtual llvm::StringRef name() const {
- return _name;
- }
-
virtual Definition definition() const {
return Atom::definitionUndefined;
}
- virtual bool weakImport() const {
- return _weakImport;
+ /// like dynamic_cast, if atom is definitionUndefined
+ /// returns atom cast to UndefinedAtom*, else returns NULL
+ virtual const UndefinedAtom* undefinedAtom() const {
+ return this;
}
+ /// returns if undefined symbol can be missing at runtime
+ virtual bool weakImport() const = 0;
+
protected:
+ UndefinedAtom() {}
virtual ~UndefinedAtom() {}
-
- llvm::StringRef _name;
- const File& _file;
- bool _weakImport;
};
} // namespace lld
Modified: lld/trunk/lib/Core/NativeFileFormat.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeFileFormat.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/NativeFileFormat.h (original)
+++ lld/trunk/lib/Core/NativeFileFormat.h Mon Feb 6 20:59:54 2012
@@ -88,9 +88,10 @@
enum NativeChunkSignatures {
NCS_DefinedAtomsV1 = 1,
NCS_AttributesArrayV1 = 2,
- NCS_Content = 3,
+ NCS_UndefinedAtomsV1 = 3,
NCS_Strings = 4,
- NCS_ReferencesArray = 5,
+ NCS_Content = 5,
+ NCS_ReferencesArray = 6,
};
//
@@ -152,6 +153,16 @@
+//
+// The NCS_UndefinedAtomsV1 chunk contains an array of these structs
+//
+struct NativeUndefinedAtomIvarsV1 {
+ uint32_t nameOffset;
+ uint32_t flags;
+};
+
+
+
Modified: lld/trunk/lib/Core/NativeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/NativeReader.cpp (original)
+++ lld/trunk/lib/Core/NativeReader.cpp Mon Feb 6 20:59:54 2012
@@ -65,7 +65,8 @@
}
virtual DefinedAtom::ContentType contentType() const {
- return (DefinedAtom::ContentType)(attributes().contentType);
+ const NativeAtomAttributesV1& attr = attributes();
+ return (DefinedAtom::ContentType)(attr.contentType);
}
virtual DefinedAtom::Alignment alignment() const {
@@ -113,6 +114,29 @@
+//
+// An object of this class is instantied for each NativeUndefinedAtomIvarsV1
+// struct in the NCS_UndefinedAtomsV1 chunk.
+//
+class NativeUndefinedAtomV1 : public UndefinedAtom {
+public:
+ NativeUndefinedAtomV1(const NativeFile& f,
+ const NativeUndefinedAtomIvarsV1* ivarData)
+ : _file(&f), _ivarData(ivarData) { }
+
+ virtual const File& file() const;
+ virtual llvm::StringRef name() const;
+
+ virtual bool weakImport() const {
+ return (_ivarData->flags & 0x1);
+ }
+
+private:
+ const NativeFile* _file;
+ const NativeUndefinedAtomIvarsV1* _ivarData;
+};
+
+
//
// lld::File object for native llvm object file
@@ -122,8 +146,9 @@
/// Instantiates a File object from a native object file. Ownership
/// of the MemoryBuffer is transfered to the resulting File object.
- static llvm::error_code make(llvm::MemoryBuffer* mb, llvm::StringRef path,
- File*& result) {
+ static llvm::error_code make(llvm::OwningPtr<llvm::MemoryBuffer>& mb,
+ llvm::StringRef path,
+ llvm::OwningPtr<File>& result) {
const uint8_t* const base =
reinterpret_cast<const uint8_t*>(mb->getBufferStart());
const NativeFileHeader* const header =
@@ -159,6 +184,9 @@
case NCS_AttributesArrayV1:
ec = file->processAttributesV1(base, chunk);
break;
+ case NCS_UndefinedAtomsV1:
+ ec = file->processUndefinedAtomsV1(base, chunk);
+ break;
case NCS_Content:
ec = file->processContent(base, chunk);
break;
@@ -175,7 +203,7 @@
// TO DO: validate enough chunks were used
- result = file;
+ result.reset(file);
}
@@ -183,13 +211,14 @@
}
virtual ~NativeFile() {
- // The NativeFile owns the MemoryBuffer and must not delete it.
- delete _buffer;
+ // _buffer is automatically deleted because of OwningPtr<>
+
// All other ivar pointers are pointers into the MemoryBuffer, except
// the _definedAtoms array which was allocated to contain an array
// of Atom objects. The atoms have empty destructors, so it is ok
// to just delete the memory.
delete _definedAtoms.arrayStart;
+ delete _undefinedAtoms.arrayStart;
}
// visits each atom in the file
@@ -199,6 +228,11 @@
const DefinedAtom* atom = reinterpret_cast<const DefinedAtom*>(p);
handler.doDefinedAtom(*atom);
}
+ for(const uint8_t* p=_undefinedAtoms.arrayStart; p != _undefinedAtoms.arrayEnd;
+ p += _undefinedAtoms.elementSize) {
+ const UndefinedAtom* atom = reinterpret_cast<const UndefinedAtom*>(p);
+ handler.doUndefinedAtom(*atom);
+ }
return (_definedAtoms.arrayStart != _definedAtoms.arrayEnd);
}
@@ -210,6 +244,7 @@
private:
friend class NativeDefinedAtomV1;
+ friend class NativeUndefinedAtomV1;
// instantiate array of DefinedAtoms from v1 ivar data in file
llvm::error_code processDefinedAtomsV1(const uint8_t* base,
@@ -247,6 +282,34 @@
return make_error_code(native_reader_error::success);
}
+ llvm::error_code processUndefinedAtomsV1(const uint8_t* base,
+ const NativeChunk* chunk) {
+ const size_t atomSize = sizeof(NativeUndefinedAtomV1);
+ size_t atomsArraySize = chunk->elementCount * atomSize;
+ uint8_t* atomsStart = reinterpret_cast<uint8_t*>
+ (operator new(atomsArraySize, std::nothrow));
+ if (atomsStart == NULL )
+ return make_error_code(native_reader_error::memory_error);
+ const size_t ivarElementSize = chunk->fileSize
+ / chunk->elementCount;
+ if ( ivarElementSize != sizeof(NativeUndefinedAtomIvarsV1) )
+ return make_error_code(native_reader_error::file_malformed);
+ uint8_t* atomsEnd = atomsStart + atomsArraySize;
+ const NativeUndefinedAtomIvarsV1* ivarData =
+ reinterpret_cast<const NativeUndefinedAtomIvarsV1*>
+ (base + chunk->fileOffset);
+ for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
+ NativeUndefinedAtomV1* atomAllocSpace =
+ reinterpret_cast<NativeUndefinedAtomV1*>(s);
+ new (atomAllocSpace) NativeUndefinedAtomV1(*this, ivarData);
+ ++ivarData;
+ }
+ this->_undefinedAtoms.arrayStart = atomsStart;
+ this->_undefinedAtoms.arrayEnd = atomsEnd;
+ this->_undefinedAtoms.elementSize = atomSize;
+ return make_error_code(native_reader_error::success);
+ }
+
// set up pointers to string pool in file
llvm::error_code processStrings(const uint8_t* base,
const NativeChunk* chunk) {
@@ -281,12 +344,18 @@
// private constructor, only called by make()
- NativeFile(llvm::MemoryBuffer* mb, llvm::StringRef path) :
- lld::File(path), _buffer(mb), _header(NULL),
- _strings(NULL), _stringsMaxOffset(0),
- _contentStart(NULL), _contentEnd(NULL)
+ NativeFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb, llvm::StringRef path) :
+ lld::File(path),
+ _buffer(mb.take()), // NativeFile now takes ownership of buffer
+ _header(NULL),
+ _strings(NULL),
+ _stringsMaxOffset(0),
+ _contentStart(NULL),
+ _contentEnd(NULL)
{
- _header = reinterpret_cast<const NativeFileHeader*>(mb->getBufferStart());
+ _header = reinterpret_cast<const NativeFileHeader*>(_buffer->getBufferStart());
+ _definedAtoms.arrayStart = NULL;
+ _undefinedAtoms.arrayStart = NULL;
}
struct AtomArray {
@@ -297,9 +366,10 @@
uint32_t elementSize;
};
- llvm::MemoryBuffer* _buffer;
+ llvm::OwningPtr<llvm::MemoryBuffer> _buffer;
const NativeFileHeader* _header;
AtomArray _definedAtoms;
+ AtomArray _undefinedAtoms;
const uint8_t* _attributes;
uint32_t _attributesMaxOffset;
const char* _strings;
@@ -342,11 +412,24 @@
+
+inline const class File& NativeUndefinedAtomV1::file() const {
+ return *_file;
+}
+
+inline llvm::StringRef NativeUndefinedAtomV1::name() const {
+ return _file->string(_ivarData->nameOffset);
+}
+
+
+
+
//
// Instantiate an lld::File from the given native object file buffer
//
-llvm::error_code parseNativeObjectFile(llvm::MemoryBuffer* mb,
- llvm::StringRef path, File*& result) {
+llvm::error_code parseNativeObjectFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb,
+ llvm::StringRef path,
+ llvm::OwningPtr<File>& result) {
return NativeFile::make(mb, path, result);
}
@@ -356,13 +439,13 @@
// Instantiate an lld::File from the given native object file path
//
llvm::error_code parseNativeObjectFileOrSTDIN(llvm::StringRef path,
- File*& result) {
+ llvm::OwningPtr<File>& result) {
llvm::OwningPtr<llvm::MemoryBuffer> mb;
llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
if ( ec )
return ec;
- return parseNativeObjectFile(mb.take(), path, result);
+ return parseNativeObjectFile(mb, path, result);
}
Modified: lld/trunk/lib/Core/NativeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/NativeWriter.cpp (original)
+++ lld/trunk/lib/Core/NativeWriter.cpp Mon Feb 6 20:59:54 2012
@@ -44,10 +44,13 @@
if (!_attributes.empty())
out.write((char*)&_attributes[0],
_attributes.size()*sizeof(NativeAtomAttributesV1));
- if (!_contentPool.empty())
- out.write((char*)&_contentPool[0], _contentPool.size());
+ if ( !_undefinedAtomIvars.empty() )
+ out.write((char*)&_undefinedAtomIvars[0],
+ _undefinedAtomIvars.size()*sizeof(NativeUndefinedAtomIvarsV1));
if (!_stringPool.empty())
out.write(&_stringPool[0], _stringPool.size());
+ if (!_contentPool.empty())
+ out.write((char*)&_contentPool[0], _contentPool.size());
}
private:
@@ -64,15 +67,22 @@
// visitor routine called by forEachAtom()
virtual void doUndefinedAtom(const class UndefinedAtom& atom) {
+ NativeUndefinedAtomIvarsV1 ivar;
+ ivar.nameOffset = getNameOffset(atom);
+ ivar.flags = (atom.weakImport() ? 1 : 0);
+ _undefinedAtomIvars.push_back(ivar);
}
// visitor routine called by forEachAtom()
virtual void doFile(const class File &) {
}
-
+
// fill out native file header and chunk directory
void makeHeader() {
- _headerBufferSize = sizeof(NativeFileHeader) + 4*sizeof(NativeChunk);
+ const bool hasUndefines = !_undefinedAtomIvars.empty();
+ const int chunkCount = hasUndefines ? 5 : 4;
+ _headerBufferSize = sizeof(NativeFileHeader)
+ + chunkCount*sizeof(NativeChunk);
_headerBuffer = reinterpret_cast<NativeFileHeader*>
(operator new(_headerBufferSize, std::nothrow));
NativeChunk *chunks =
@@ -82,39 +92,59 @@
_headerBuffer->endian = NFH_LittleEndian;
_headerBuffer->architecture = 0;
_headerBuffer->fileSize = 0;
- _headerBuffer->chunkCount = 4;
+ _headerBuffer->chunkCount = chunkCount;
+
// create chunk for atom ivar array
- NativeChunk& ch0 = chunks[0];
- ch0.signature = NCS_DefinedAtomsV1;
- ch0.fileOffset = _headerBufferSize;
- ch0.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1);
- ch0.elementCount = _definedAtomIvars.size();
- // create chunk for attributes
- NativeChunk& ch1 = chunks[1];
- ch1.signature = NCS_AttributesArrayV1;
- ch1.fileOffset = ch0.fileOffset + ch0.fileSize;
- ch1.fileSize = _attributes.size()*sizeof(NativeAtomAttributesV1);
- ch1.elementCount = _attributes.size();
- // create chunk for content
- NativeChunk& ch2 = chunks[2];
- ch2.signature = NCS_Content;
- ch2.fileOffset = ch1.fileOffset + ch1.fileSize;
- ch2.fileSize = _contentPool.size();
- ch2.elementCount = _contentPool.size();
+ int nextIndex = 0;
+ NativeChunk& chd = chunks[nextIndex++];
+ chd.signature = NCS_DefinedAtomsV1;
+ chd.fileOffset = _headerBufferSize;
+ chd.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1);
+ chd.elementCount = _definedAtomIvars.size();
+ uint32_t nextFileOffset = chd.fileOffset + chd.fileSize;
+
+ // create chunk for attributes
+ NativeChunk& cha = chunks[nextIndex++];
+ cha.signature = NCS_AttributesArrayV1;
+ cha.fileOffset = nextFileOffset;
+ cha.fileSize = _attributes.size()*sizeof(NativeAtomAttributesV1);
+ cha.elementCount = _attributes.size();
+ nextFileOffset = cha.fileOffset + cha.fileSize;
+
+ // create chunk for undefined atom array
+ if ( hasUndefines ) {
+ NativeChunk& chu = chunks[nextIndex++];
+ chu.signature = NCS_UndefinedAtomsV1;
+ chu.fileOffset = nextFileOffset;
+ chu.fileSize = _undefinedAtomIvars.size() *
+ sizeof(NativeUndefinedAtomIvarsV1);
+ chu.elementCount = _undefinedAtomIvars.size();
+ nextFileOffset = chu.fileOffset + chu.fileSize;
+ }
+
// create chunk for symbol strings
- NativeChunk& ch3 = chunks[3];
- ch3.signature = NCS_Strings;
- ch3.fileOffset = ch2.fileOffset + ch2.fileSize;
- ch3.fileSize = _stringPool.size();
- ch3.elementCount = _stringPool.size();
+ NativeChunk& chs = chunks[nextIndex++];
+ chs.signature = NCS_Strings;
+ chs.fileOffset = nextFileOffset;
+ chs.fileSize = _stringPool.size();
+ chs.elementCount = _stringPool.size();
+ nextFileOffset = chs.fileOffset + chs.fileSize;
- _headerBuffer->fileSize = ch3.fileOffset + ch3.fileSize;
+ // create chunk for content
+ NativeChunk& chc = chunks[nextIndex++];
+ chc.signature = NCS_Content;
+ chc.fileOffset = nextFileOffset;
+ chc.fileSize = _contentPool.size();
+ chc.elementCount = _contentPool.size();
+ nextFileOffset = chc.fileOffset + chc.fileSize;
+
+ _headerBuffer->fileSize = nextFileOffset;
}
// append atom name to string pool and return offset
- uint32_t getNameOffset(const class DefinedAtom& atom) {
+ uint32_t getNameOffset(const Atom& atom) {
return this->getNameOffset(atom.name());
}
@@ -190,14 +220,15 @@
typedef std::vector<std::pair<llvm::StringRef, uint32_t> > NameToOffsetVector;
- const lld::File& _file;
- NativeFileHeader* _headerBuffer;
- size_t _headerBufferSize;
- std::vector<char> _stringPool;
- std::vector<uint8_t> _contentPool;
- std::vector<NativeDefinedAtomIvarsV1> _definedAtomIvars;
- std::vector<NativeAtomAttributesV1> _attributes;
- NameToOffsetVector _sectionNames;
+ const lld::File& _file;
+ NativeFileHeader* _headerBuffer;
+ size_t _headerBufferSize;
+ std::vector<char> _stringPool;
+ std::vector<uint8_t> _contentPool;
+ std::vector<NativeDefinedAtomIvarsV1> _definedAtomIvars;
+ std::vector<NativeAtomAttributesV1> _attributes;
+ std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;
+ NameToOffsetVector _sectionNames;
};
Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Mon Feb 6 20:59:54 2012
@@ -33,7 +33,7 @@
// don't remove if live
if ( _liveAtoms.count(atom) )
return false;
- // don't remove if marked never-dead-strip
+ // don't remove if marked never-dead-strip
if ( const DefinedAtom* defAtom = atom->definedAtom() ) {
if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
return false;
Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
+++ lld/trunk/lib/Core/YamlKeyValues.cpp Mon Feb 6 20:59:54 2012
@@ -31,7 +31,8 @@
const char* const KeyValues::sectionNameKeyword = "section-name";
const char* const KeyValues::contentKeyword = "content";
const char* const KeyValues::sizeKeyword = "size";
-const char* const KeyValues::permissionsKeyword = "permissions";
+const char* const KeyValues::permissionsKeyword = "permissions";
+const char* const KeyValues::weakImportKeyword = "weak-import";
const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
@@ -45,27 +46,28 @@
const bool KeyValues::internalNameDefault = false;
const bool KeyValues::isThumbDefault = false;
const bool KeyValues::isAliasDefault = false;
+const bool KeyValues::weakImportDefault = false;
struct DefinitionMapping {
- const char* string;
- Atom::Definition value;
+ const char* string;
+ Atom::Definition value;
};
static const DefinitionMapping defMappings[] = {
- { "regular", Atom::definitionRegular },
- { "absolute", Atom::definitionAbsolute },
- { "undefined", Atom::definitionUndefined },
- { "shared-library", Atom::definitionSharedLibrary },
+ { "regular", Atom::definitionRegular },
+ { "absolute", Atom::definitionAbsolute },
+ { "undefined", Atom::definitionUndefined },
+ { "shared-library", Atom::definitionSharedLibrary },
{ NULL, Atom::definitionRegular }
};
Atom::Definition KeyValues::definition(const char* s)
{
- for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
+ for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -73,7 +75,7 @@
}
const char* KeyValues::definition(Atom::Definition s) {
- for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
+ for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
}
@@ -85,20 +87,20 @@
struct ScopeMapping {
- const char* string;
- DefinedAtom::Scope value;
+ const char* string;
+ DefinedAtom::Scope value;
};
static const ScopeMapping scopeMappings[] = {
- { "global", DefinedAtom::scopeGlobal },
- { "hidden", DefinedAtom::scopeLinkageUnit },
- { "static", DefinedAtom::scopeTranslationUnit },
+ { "global", DefinedAtom::scopeGlobal },
+ { "hidden", DefinedAtom::scopeLinkageUnit },
+ { "static", DefinedAtom::scopeTranslationUnit },
{ NULL, DefinedAtom::scopeGlobal }
};
DefinedAtom::Scope KeyValues::scope(const char* s)
{
- for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+ for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -106,7 +108,7 @@
}
const char* KeyValues::scope(DefinedAtom::Scope s) {
- for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+ for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
}
@@ -121,41 +123,41 @@
struct ContentTypeMapping {
- const char* string;
- DefinedAtom::ContentType value;
+ const char* string;
+ DefinedAtom::ContentType value;
};
static const ContentTypeMapping typeMappings[] = {
- { "unknown", DefinedAtom::typeUnknown },
- { "code", DefinedAtom::typeCode },
- { "resolver", DefinedAtom::typeResolver },
- { "constant", DefinedAtom::typeConstant },
- { "c-string", DefinedAtom::typeCString },
- { "utf16-string", DefinedAtom::typeUTF16String },
- { "CFI", DefinedAtom::typeCFI },
- { "LSDA", DefinedAtom::typeLSDA },
- { "literal-4", DefinedAtom::typeLiteral4 },
- { "literal-8", DefinedAtom::typeLiteral8 },
- { "literal-16", DefinedAtom::typeLiteral16 },
- { "data", DefinedAtom::typeData },
- { "zero-fill", DefinedAtom::typeZeroFill },
- { "cf-string", DefinedAtom::typeCFString },
- { "initializer-ptr",DefinedAtom::typeInitializerPtr },
- { "terminator-ptr", DefinedAtom::typeTerminatorPtr },
- { "c-string-ptr", DefinedAtom::typeCStringPtr },
- { "objc1-class", DefinedAtom::typeObjC1Class },
- { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr },
- { "objc2-cat-ptr", DefinedAtom::typeObjC2CategoryList },
- { "tlv-thunk", DefinedAtom::typeThunkTLV },
- { "tlv-data", DefinedAtom::typeTLVInitialData },
- { "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill },
- { "tlv-init-ptr", DefinedAtom::typeTLVInitializerPtr },
+ { "unknown", DefinedAtom::typeUnknown },
+ { "code", DefinedAtom::typeCode },
+ { "resolver", DefinedAtom::typeResolver },
+ { "constant", DefinedAtom::typeConstant },
+ { "c-string", DefinedAtom::typeCString },
+ { "utf16-string", DefinedAtom::typeUTF16String },
+ { "CFI", DefinedAtom::typeCFI },
+ { "LSDA", DefinedAtom::typeLSDA },
+ { "literal-4", DefinedAtom::typeLiteral4 },
+ { "literal-8", DefinedAtom::typeLiteral8 },
+ { "literal-16", DefinedAtom::typeLiteral16 },
+ { "data", DefinedAtom::typeData },
+ { "zero-fill", DefinedAtom::typeZeroFill },
+ { "cf-string", DefinedAtom::typeCFString },
+ { "initializer-ptr",DefinedAtom::typeInitializerPtr },
+ { "terminator-ptr", DefinedAtom::typeTerminatorPtr },
+ { "c-string-ptr", DefinedAtom::typeCStringPtr },
+ { "objc1-class", DefinedAtom::typeObjC1Class },
+ { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr },
+ { "objc2-cat-ptr", DefinedAtom::typeObjC2CategoryList },
+ { "tlv-thunk", DefinedAtom::typeThunkTLV },
+ { "tlv-data", DefinedAtom::typeTLVInitialData },
+ { "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill },
+ { "tlv-init-ptr", DefinedAtom::typeTLVInitializerPtr },
{ NULL, DefinedAtom::typeUnknown }
};
DefinedAtom::ContentType KeyValues::contentType(const char* s)
{
- for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
+ for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -163,7 +165,7 @@
}
const char* KeyValues::contentType(DefinedAtom::ContentType s) {
- for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
+ for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
}
@@ -177,20 +179,20 @@
struct DeadStripMapping {
- const char* string;
- DefinedAtom::DeadStripKind value;
+ const char* string;
+ DefinedAtom::DeadStripKind value;
};
static const DeadStripMapping deadStripMappings[] = {
- { "normal", DefinedAtom::deadStripNormal },
- { "never", DefinedAtom::deadStripNever },
- { "always", DefinedAtom::deadStripAlways },
+ { "normal", DefinedAtom::deadStripNormal },
+ { "never", DefinedAtom::deadStripNever },
+ { "always", DefinedAtom::deadStripAlways },
{ NULL, DefinedAtom::deadStripNormal }
};
DefinedAtom::DeadStripKind KeyValues::deadStripKind(const char* s)
{
- for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
+ for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -198,7 +200,7 @@
}
const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) {
- for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
+ for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
if ( p->value == dsk )
return p->string;
}
@@ -210,20 +212,20 @@
struct InterposableMapping {
- const char* string;
- DefinedAtom::Interposable value;
+ const char* string;
+ DefinedAtom::Interposable value;
};
static const InterposableMapping interMappings[] = {
- { "no", DefinedAtom::interposeNo },
- { "yes", DefinedAtom::interposeYes },
- { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak },
+ { "no", DefinedAtom::interposeNo },
+ { "yes", DefinedAtom::interposeYes },
+ { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak },
{ NULL, DefinedAtom::interposeNo }
};
DefinedAtom::Interposable KeyValues::interposable(const char* s)
{
- for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
+ for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -231,7 +233,7 @@
}
const char* KeyValues::interposable(DefinedAtom::Interposable in) {
- for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
+ for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
if ( p->value == in )
return p->string;
}
@@ -244,21 +246,21 @@
struct MergeMapping {
- const char* string;
- DefinedAtom::Merge value;
+ const char* string;
+ DefinedAtom::Merge value;
};
static const MergeMapping mergeMappings[] = {
- { "no", DefinedAtom::mergeNo },
- { "asTentative", DefinedAtom::mergeAsTentative },
- { "asWeak", DefinedAtom::mergeAsWeak },
- { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed },
+ { "no", DefinedAtom::mergeNo },
+ { "asTentative", DefinedAtom::mergeAsTentative },
+ { "asWeak", DefinedAtom::mergeAsWeak },
+ { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed },
{ NULL, DefinedAtom::mergeNo }
};
DefinedAtom::Merge KeyValues::merge(const char* s)
{
- for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+ for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -266,7 +268,7 @@
}
const char* KeyValues::merge(DefinedAtom::Merge in) {
- for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+ for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
if ( p->value == in )
return p->string;
}
@@ -279,20 +281,20 @@
struct SectionChoiceMapping {
- const char* string;
- DefinedAtom::SectionChoice value;
+ const char* string;
+ DefinedAtom::SectionChoice value;
};
static const SectionChoiceMapping sectMappings[] = {
- { "content", DefinedAtom::sectionBasedOnContent },
- { "custom", DefinedAtom::sectionCustomPreferred },
- { "custom-required", DefinedAtom::sectionCustomRequired },
+ { "content", DefinedAtom::sectionBasedOnContent },
+ { "custom", DefinedAtom::sectionCustomPreferred },
+ { "custom-required", DefinedAtom::sectionCustomRequired },
{ NULL, DefinedAtom::sectionBasedOnContent }
};
DefinedAtom::SectionChoice KeyValues::sectionChoice(const char* s)
{
- for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -300,7 +302,7 @@
}
const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) {
- for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
}
@@ -314,22 +316,22 @@
struct PermissionsMapping {
- const char* string;
- DefinedAtom::ContentPermissions value;
+ const char* string;
+ DefinedAtom::ContentPermissions value;
};
static const PermissionsMapping permMappings[] = {
- { "content", DefinedAtom::perm___ },
- { "custom", DefinedAtom::permR__ },
- { "custom-required", DefinedAtom::permR_X },
- { "custom-required", DefinedAtom::permRW_ },
- { "custom-required", DefinedAtom::permRW_L },
+ { "content", DefinedAtom::perm___ },
+ { "custom", DefinedAtom::permR__ },
+ { "custom-required", DefinedAtom::permR_X },
+ { "custom-required", DefinedAtom::permRW_ },
+ { "custom-required", DefinedAtom::permRW_L },
{ NULL, DefinedAtom::perm___ }
};
DefinedAtom::ContentPermissions KeyValues::permissions(const char* s)
{
- for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+ for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
@@ -337,7 +339,7 @@
}
const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
- for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+ for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
}
@@ -398,6 +400,23 @@
+bool KeyValues::weakImport(const char* s)
+{
+ if ( strcmp(s, "true") == 0 )
+ return true;
+ else if ( strcmp(s, "false") == 0 )
+ return false;
+ llvm::report_fatal_error("bad weak-import value");
+}
+
+const char* KeyValues::weakImport(bool b) {
+ return b ? "true" : "false";
+}
+
+
+
+
+
} // namespace yaml
Modified: lld/trunk/lib/Core/YamlKeyValues.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.h (original)
+++ lld/trunk/lib/Core/YamlKeyValues.h Mon Feb 6 20:59:54 2012
@@ -79,6 +79,11 @@
static bool isAlias(const char*);
static const char* isAlias(bool);
+ static const char* const weakImportKeyword;
+ static const bool weakImportDefault;
+ static bool weakImport(const char*);
+ static const char* weakImport(bool);
+
};
} // namespace yaml
Modified: lld/trunk/lib/Core/YamlReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlReader.cpp (original)
+++ lld/trunk/lib/Core/YamlReader.cpp Mon Feb 6 20:59:54 2012
@@ -267,6 +267,10 @@
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;
}
@@ -424,6 +428,32 @@
};
+class YAMLUndefinedAtom : public UndefinedAtom {
+public:
+ YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm, bool wi)
+ : _file(f), _name(nm), _ordinal(ord), _weakImport(wi) { }
+
+ virtual const class File& file() const {
+ return _file;
+ }
+
+ virtual llvm::StringRef name() const {
+ return _name;
+ }
+
+ virtual bool weakImport() const {
+ return _weakImport;
+ }
+
+private:
+ YAMLFile& _file;
+ const char * _name;
+ uint32_t _ordinal;
+ bool _weakImport;
+};
+
+
+
class YAMLAtomState {
public:
YAMLAtomState();
@@ -455,6 +485,7 @@
bool _internalName;
bool _isThumb;
bool _isAlias;
+ bool _weakImport;
Reference _ref;
};
@@ -477,6 +508,7 @@
, _internalName(KeyValues::internalNameDefault)
, _isThumb(KeyValues::isThumbDefault)
, _isAlias(KeyValues::isAliasDefault)
+ , _weakImport(false)
{
_ref.target = NULL;
_ref.addend = 0;
@@ -496,6 +528,12 @@
f._definedAtoms.push_back(a);
++_ordinal;
}
+ else if ( _definition == Atom::definitionUndefined ) {
+ UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _weakImport);
+
+ f._undefinedAtoms.push_back(a);
+ ++_ordinal;
+ }
// reset state for next atom
_name = NULL;
@@ -515,6 +553,7 @@
_permissions = KeyValues::permissionsDefault;
_isThumb = KeyValues::isThumbDefault;
_isAlias = KeyValues::isAliasDefault;
+ _weakImport = KeyValues::weakImportDefault;
_ref.target = NULL;
_ref.addend = 0;
_ref.offsetInAtom = 0;
@@ -664,6 +703,10 @@
atomState._isAlias = KeyValues::isAlias(entry->value);
haveAtom = true;
}
+ else if (strcmp(entry->key, KeyValues::weakImportKeyword) == 0) {
+ atomState._weakImport = KeyValues::weakImport(entry->value);
+ haveAtom = true;
+ }
else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
atomState._sectionName = entry->value;
haveAtom = true;
Modified: lld/trunk/lib/Core/YamlWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlWriter.cpp (original)
+++ lld/trunk/lib/Core/YamlWriter.cpp Mon Feb 6 20:59:54 2012
@@ -81,7 +81,7 @@
<< "\n";
}
- if ( atom.merge() != KeyValues::mergeDefault ) {
+ if ( atom.merge() != KeyValues::mergeDefault ) {
_out << " "
<< KeyValues::mergeKeyword
<< ":"
@@ -124,7 +124,7 @@
<< "\n";
}
- if ( atom.isThumb() != KeyValues::isThumbDefault ) {
+ if ( atom.isThumb() != KeyValues::isThumbDefault ) {
_out << " "
<< KeyValues::isThumbKeyword
<< ":"
@@ -142,7 +142,8 @@
<< "\n";
}
- if ( atom.contentType() != DefinedAtom::typeZeroFill ) {
+ if ( (atom.contentType() != DefinedAtom::typeZeroFill)
+ && (atom.size() != 0) ) {
_out << " "
<< KeyValues::contentKeyword
<< ":"
@@ -171,9 +172,35 @@
}
- virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
+ virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
+ // add blank line between atoms for readability
+ if ( !_firstAtom )
+ _out << "\n";
+ _firstAtom = false;
+
+ _out << " - "
+ << KeyValues::nameKeyword
+ << ":"
+ << spacePadding(KeyValues::nameKeyword)
+ << atom.name()
+ << "\n";
+
+ _out << " "
+ << KeyValues::definitionKeyword
+ << ":"
+ << spacePadding(KeyValues::definitionKeyword)
+ << KeyValues::definition(atom.definition())
+ << "\n";
- }
+ if ( atom.weakImport() != KeyValues::weakImportDefault ) {
+ _out << " "
+ << KeyValues::weakImportKeyword
+ << ":"
+ << spacePadding(KeyValues::weakImportKeyword)
+ << KeyValues::weakImport(atom.weakImport())
+ << "\n";
+ }
+ }
private:
Added: lld/trunk/test/undef-coalesce.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/undef-coalesce.objtxt?rev=149962&view=auto
==============================================================================
--- lld/trunk/test/undef-coalesce.objtxt (added)
+++ lld/trunk/test/undef-coalesce.objtxt Mon Feb 6 20:59:54 2012
@@ -0,0 +1,46 @@
+# RUN: lld-core %s | FileCheck %s
+
+#
+# Test that undefined symbols are coalesced with other undefined symbols
+# and definitions override them.
+#
+
+---
+atoms:
+ - name: foo
+ type: code
+
+ - name: malloc
+ definition: undefined
+
+ - name: free
+ definition: undefined
+---
+atoms:
+ - name: bar
+ type: code
+
+ - name: malloc
+ definition: undefined
+
+ - name: myfunc
+ definition: undefined
+---
+atoms:
+ - name: myfunc
+ scope: global
+ type: code
+
+ - name: free
+ definition: undefined
+...
+
+# CHECK: name: foo
+# CHECK: name: bar
+# CHECK: name: myfunc
+# CHECK: scope: global
+# CHECK: name: malloc
+# CHECK: definition: undefined
+# CHECK: name: free
+# CHECK: definition: undefined
+# 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=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/lld-core.cpp (original)
+++ lld/trunk/tools/lld-core/lld-core.cpp Mon Feb 6 20:59:54 2012
@@ -172,20 +172,19 @@
virtual bool forEachAtom(File::AtomHandler &handler) const {
handler.doFile(*this);
+ // visit defined atoms
for (std::vector<const Atom *>::iterator it = _atoms.begin();
it != _atoms.end(); ++it) {
- const Atom* atom = *it;
- switch ( atom->definition() ) {
- case Atom::definitionRegular:
- handler.doDefinedAtom(*(DefinedAtom*)atom);
- break;
- case Atom::definitionUndefined:
- handler.doUndefinedAtom(*(UndefinedAtom*)atom);
- break;
- default:
- // TO DO
- break;
- }
+ const DefinedAtom* atom = (*it)->definedAtom();
+ if ( atom )
+ handler.doDefinedAtom(*atom);
+ }
+ // visit undefined atoms
+ for (std::vector<const Atom *>::iterator it = _atoms.begin();
+ it != _atoms.end(); ++it) {
+ const UndefinedAtom* atom = (*it)->undefinedAtom();
+ if ( atom )
+ handler.doUndefinedAtom(*atom);
}
return true;
}
@@ -198,7 +197,8 @@
private:
std::vector<const Atom *> &_atoms;
};
-}
+} //anonymous namespace
+
int main(int argc, const char *argv[]) {
// Print a stack trace if we signal out.
@@ -220,7 +220,7 @@
// write new atom graph out as YAML doc
std::string errorInfo;
llvm::raw_fd_ostream out("-", errorInfo);
-// yaml::writeObjectText(outFile, out);
+ //yaml::writeObjectText(outFile, out);
// make unique temp .o file to put generated object file
int fd;
@@ -233,7 +233,7 @@
binaryOut.close(); // manually close so that file can be read next
// read native file
- lld::File* natFile;
+ llvm::OwningPtr<lld::File> natFile;
parseNativeObjectFileOrSTDIN(tempPath, natFile);
// write new atom graph out as YAML doc
@@ -242,6 +242,6 @@
// delete temp .o file
bool existed;
llvm::sys::fs::remove(tempPath.str(), existed);
-
+
return 0;
}
More information about the llvm-commits
mailing list