summaryrefslogtreecommitdiffstats
path: root/lld/lib
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2012-02-22 21:56:59 +0000
committerNick Kledzik <kledzik@apple.com>2012-02-22 21:56:59 +0000
commit6bc04c6904971cbbf61cc5d01a258cdab5ba5421 (patch)
tree4099b3078ee4e30d3a39e39b519bc0abd45f13bd /lld/lib
parent1a3c3d45374a74b753373747b9a326a3360c3ac4 (diff)
downloadbcm5719-llvm-6bc04c6904971cbbf61cc5d01a258cdab5ba5421.tar.gz
bcm5719-llvm-6bc04c6904971cbbf61cc5d01a258cdab5ba5421.zip
Add support for SharedLibraryAtoms (proxy atoms for exported symbols from a
shared library) and AbsoluteAtoms (proxy atoms for absolute address (e.g. ROM)). Redesign weak importing as can-be-null-at-runtime and can-be-null-at-build-time. Add lots of test cases for all the above. llvm-svn: 151204
Diffstat (limited to 'lld/lib')
-rw-r--r--lld/lib/Core/NativeFileFormat.h35
-rw-r--r--lld/lib/Core/NativeReader.cpp207
-rw-r--r--lld/lib/Core/NativeWriter.cpp185
-rw-r--r--lld/lib/Core/Resolver.cpp18
-rw-r--r--lld/lib/Core/SymbolTable.cpp56
-rw-r--r--lld/lib/Core/YamlKeyValues.cpp39
-rw-r--r--lld/lib/Core/YamlKeyValues.h11
-rw-r--r--lld/lib/Core/YamlReader.cpp183
-rw-r--r--lld/lib/Core/YamlWriter.cpp129
9 files changed, 736 insertions, 127 deletions
diff --git a/lld/lib/Core/NativeFileFormat.h b/lld/lib/Core/NativeFileFormat.h
index 91996983c6e..9066f471674 100644
--- a/lld/lib/Core/NativeFileFormat.h
+++ b/lld/lib/Core/NativeFileFormat.h
@@ -90,12 +90,14 @@ enum NativeChunkSignatures {
NCS_DefinedAtomsV1 = 1,
NCS_AttributesArrayV1 = 2,
NCS_UndefinedAtomsV1 = 3,
- NCS_Strings = 4,
- NCS_ReferencesArrayV1 = 5,
- NCS_ReferencesArrayV2 = 6,
- NCS_TargetsTable = 7,
- NCS_AddendsTable = 8,
- NCS_Content = 9,
+ NCS_SharedLibraryAtomsV1 = 4,
+ NCS_AbsoluteAtomsV1 = 5,
+ NCS_Strings = 6,
+ NCS_ReferencesArrayV1 = 7,
+ NCS_ReferencesArrayV2 = 8,
+ NCS_TargetsTable = 9,
+ NCS_AddendsTable = 10,
+ NCS_Content = 11,
};
//
@@ -165,6 +167,27 @@ struct NativeUndefinedAtomIvarsV1 {
+//
+// The NCS_SharedLibraryAtomsV1 chunk contains an array of these structs
+//
+struct NativeSharedLibraryAtomIvarsV1 {
+ uint32_t nameOffset;
+ uint32_t loadNameOffset;
+ uint32_t flags;
+};
+
+
+
+//
+// The NCS_AbsoluteAtomsV1 chunk contains an array of these structs
+//
+struct NativeAbsoluteAtomIvarsV1 {
+ uint32_t nameOffset;
+ uint32_t reserved;
+ uint64_t value;
+};
+
+
//
// The NCS_ReferencesArrayV1 chunk contains an array of these structs
diff --git a/lld/lib/Core/NativeReader.cpp b/lld/lib/Core/NativeReader.cpp
index bc86d19c13b..e85d2ff825b 100644
--- a/lld/lib/Core/NativeReader.cpp
+++ b/lld/lib/Core/NativeReader.cpp
@@ -77,7 +77,7 @@ public:
virtual DefinedAtom::DeadStripKind deadStrip() const {
return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
- }
+ }
virtual DefinedAtom::ContentPermissions permissions() const {
return (DefinedAtom::ContentPermissions)(attributes().permissions);
@@ -117,16 +117,64 @@ public:
virtual const File& file() const;
virtual llvm::StringRef name() const;
- virtual bool weakImport() const {
- return (_ivarData->flags & 0x1);
+ virtual CanBeNull canBeNull() const {
+ return (CanBeNull)(_ivarData->flags & 0x3);
}
+
private:
const NativeFile* _file;
const NativeUndefinedAtomIvarsV1* _ivarData;
};
+//
+// An object of this class is instantied for each NativeUndefinedAtomIvarsV1
+// struct in the NCS_SharedLibraryAtomsV1 chunk.
+//
+class NativeSharedLibraryAtomV1 : public SharedLibraryAtom {
+public:
+ NativeSharedLibraryAtomV1(const NativeFile& f,
+ const NativeSharedLibraryAtomIvarsV1* ivarData)
+ : _file(&f), _ivarData(ivarData) { }
+
+ virtual const File& file() const;
+ virtual llvm::StringRef name() const;
+ virtual llvm::StringRef loadName() const;
+
+ virtual bool canBeNullAtRuntime() const {
+ return (_ivarData->flags & 0x1);
+ }
+
+private:
+ const NativeFile* _file;
+ const NativeSharedLibraryAtomIvarsV1* _ivarData;
+};
+
+
+//
+// An object of this class is instantied for each NativeAbsoluteAtomIvarsV1
+// struct in the NCS_AbsoluteAtomsV1 chunk.
+//
+class NativeAbsoluteAtomV1 : public AbsoluteAtom {
+public:
+ NativeAbsoluteAtomV1(const NativeFile& f,
+ const NativeAbsoluteAtomIvarsV1* ivarData)
+ : _file(&f), _ivarData(ivarData) { }
+
+ virtual const File& file() const;
+ virtual llvm::StringRef name() const;
+
+ virtual uint64_t value() const {
+ return _ivarData->value;
+ }
+
+private:
+ const NativeFile* _file;
+ const NativeAbsoluteAtomIvarsV1* _ivarData;
+};
+
+
//
// An object of this class is instantied for each NativeReferenceIvarsV1
@@ -206,6 +254,12 @@ public:
case NCS_UndefinedAtomsV1:
ec = file->processUndefinedAtomsV1(base, chunk);
break;
+ case NCS_SharedLibraryAtomsV1:
+ ec = file->processSharedLibraryAtomsV1(base, chunk);
+ break;
+ case NCS_AbsoluteAtomsV1:
+ ec = file->processAbsoluteAtomsV1(base, chunk);
+ break;
case NCS_ReferencesArrayV1:
ec = file->processReferencesV1(base, chunk);
break;
@@ -247,23 +301,45 @@ public:
// to just delete the memory.
delete _definedAtoms.arrayStart;
delete _undefinedAtoms.arrayStart;
+ delete _sharedLibraryAtoms.arrayStart;
+ delete _absoluteAtoms.arrayStart;
delete _references.arrayStart;
delete _targetsTable;
}
// visits each atom in the file
virtual bool forEachAtom(AtomHandler& handler) const {
+ bool didSomething = false;
for(const uint8_t* p=_definedAtoms.arrayStart; p != _definedAtoms.arrayEnd;
p += _definedAtoms.elementSize) {
const DefinedAtom* atom = reinterpret_cast<const DefinedAtom*>(p);
handler.doDefinedAtom(*atom);
+ didSomething = true;
}
- for(const uint8_t* p=_undefinedAtoms.arrayStart; p != _undefinedAtoms.arrayEnd;
- p += _undefinedAtoms.elementSize) {
+ for(const uint8_t* p=_undefinedAtoms.arrayStart;
+ p != _undefinedAtoms.arrayEnd;
+ p += _undefinedAtoms.elementSize) {
const UndefinedAtom* atom = reinterpret_cast<const UndefinedAtom*>(p);
handler.doUndefinedAtom(*atom);
+ didSomething = true;
+ }
+ for(const uint8_t* p=_sharedLibraryAtoms.arrayStart;
+ p != _sharedLibraryAtoms.arrayEnd;
+ p += _sharedLibraryAtoms.elementSize) {
+ const SharedLibraryAtom* atom
+ = reinterpret_cast<const SharedLibraryAtom*>(p);
+ handler.doSharedLibraryAtom(*atom);
+ didSomething = true;
+ }
+ for(const uint8_t* p=_absoluteAtoms.arrayStart;
+ p != _absoluteAtoms.arrayEnd;
+ p += _absoluteAtoms.elementSize) {
+ const AbsoluteAtom* atom
+ = reinterpret_cast<const AbsoluteAtom*>(p);
+ handler.doAbsoluteAtom(*atom);
+ didSomething = true;
}
- return (_definedAtoms.arrayStart != _definedAtoms.arrayEnd);
+ return didSomething;
}
// not used
@@ -275,6 +351,8 @@ public:
private:
friend class NativeDefinedAtomV1;
friend class NativeUndefinedAtomV1;
+ friend class NativeSharedLibraryAtomV1;
+ friend class NativeAbsoluteAtomV1;
friend class NativeReferenceV1;
// instantiate array of DefinedAtoms from v1 ivar data in file
@@ -308,12 +386,14 @@ private:
}
// set up pointers to attributes array
- llvm::error_code processAttributesV1(const uint8_t* base, const NativeChunk* chunk) {
+ llvm::error_code processAttributesV1(const uint8_t* base,
+ const NativeChunk* chunk) {
this->_attributes = base + chunk->fileOffset;
this->_attributesMaxOffset = chunk->fileSize;
return make_error_code(native_reader_error::success);
}
+ // instantiate array of UndefinedAtoms from v1 ivar data in file
llvm::error_code processUndefinedAtomsV1(const uint8_t* base,
const NativeChunk* chunk) {
const size_t atomSize = sizeof(NativeUndefinedAtomV1);
@@ -344,6 +424,70 @@ private:
}
+ // instantiate array of ShareLibraryAtoms from v1 ivar data in file
+ llvm::error_code processSharedLibraryAtomsV1(const uint8_t* base,
+ const NativeChunk* chunk) {
+ const size_t atomSize = sizeof(NativeSharedLibraryAtomV1);
+ 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(NativeSharedLibraryAtomIvarsV1) )
+ return make_error_code(native_reader_error::file_malformed);
+ uint8_t* atomsEnd = atomsStart + atomsArraySize;
+ const NativeSharedLibraryAtomIvarsV1* ivarData =
+ reinterpret_cast<const NativeSharedLibraryAtomIvarsV1*>
+ (base + chunk->fileOffset);
+ for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
+ NativeSharedLibraryAtomV1* atomAllocSpace =
+ reinterpret_cast<NativeSharedLibraryAtomV1*>(s);
+ new (atomAllocSpace) NativeSharedLibraryAtomV1(*this, ivarData);
+ ++ivarData;
+ }
+ this->_sharedLibraryAtoms.arrayStart = atomsStart;
+ this->_sharedLibraryAtoms.arrayEnd = atomsEnd;
+ this->_sharedLibraryAtoms.elementSize = atomSize;
+ this->_sharedLibraryAtoms.elementCount = chunk->elementCount;
+ return make_error_code(native_reader_error::success);
+ }
+
+
+ // instantiate array of AbsoluteAtoms from v1 ivar data in file
+ llvm::error_code processAbsoluteAtomsV1(const uint8_t* base,
+ const NativeChunk* chunk) {
+ const size_t atomSize = sizeof(NativeAbsoluteAtomV1);
+ 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(NativeAbsoluteAtomIvarsV1) )
+ return make_error_code(native_reader_error::file_malformed);
+ uint8_t* atomsEnd = atomsStart + atomsArraySize;
+ const NativeAbsoluteAtomIvarsV1* ivarData =
+ reinterpret_cast<const NativeAbsoluteAtomIvarsV1*>
+ (base + chunk->fileOffset);
+ for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
+ NativeAbsoluteAtomV1* atomAllocSpace =
+ reinterpret_cast<NativeAbsoluteAtomV1*>(s);
+ new (atomAllocSpace) NativeAbsoluteAtomV1(*this, ivarData);
+ ++ivarData;
+ }
+ this->_absoluteAtoms.arrayStart = atomsStart;
+ this->_absoluteAtoms.arrayEnd = atomsEnd;
+ this->_absoluteAtoms.elementSize = atomSize;
+ this->_absoluteAtoms.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) {
@@ -398,7 +542,24 @@ private:
this->_targetsTable[i] = reinterpret_cast<const UndefinedAtom*>(p);
continue;
}
- return make_error_code(native_reader_error::file_malformed);
+ const uint32_t slIndex = index - _definedAtoms.elementCount
+ - _undefinedAtoms.elementCount;
+ if ( slIndex < _sharedLibraryAtoms.elementCount ) {
+ const uint8_t* p = _sharedLibraryAtoms.arrayStart
+ + slIndex * _sharedLibraryAtoms.elementSize;
+ this->_targetsTable[i] = reinterpret_cast<const SharedLibraryAtom*>(p);
+ continue;
+ }
+ const uint32_t abIndex = index - _definedAtoms.elementCount
+ - _undefinedAtoms.elementCount
+ - _sharedLibraryAtoms.elementCount;
+ if ( abIndex < _absoluteAtoms.elementCount ) {
+ const uint8_t* p = _absoluteAtoms.arrayStart
+ + slIndex * _absoluteAtoms.elementSize;
+ this->_targetsTable[i] = reinterpret_cast<const AbsoluteAtom*>(p);
+ continue;
+ }
+ return make_error_code(native_reader_error::file_malformed);
}
return make_error_code(native_reader_error::success);
}
@@ -491,7 +652,8 @@ private:
_contentStart(NULL),
_contentEnd(NULL)
{
- _header = reinterpret_cast<const NativeFileHeader*>(_buffer->getBufferStart());
+ _header = reinterpret_cast<const NativeFileHeader*>
+ (_buffer->getBufferStart());
}
struct IvarArray {
@@ -507,6 +669,8 @@ private:
const NativeFileHeader* _header;
IvarArray _definedAtoms;
IvarArray _undefinedAtoms;
+ IvarArray _sharedLibraryAtoms;
+ IvarArray _absoluteAtoms;
const uint8_t* _attributes;
uint32_t _attributesMaxOffset;
IvarArray _references;
@@ -567,6 +731,31 @@ inline llvm::StringRef NativeUndefinedAtomV1::name() const {
}
+
+
+inline const class File& NativeSharedLibraryAtomV1::file() const {
+ return *_file;
+}
+
+inline llvm::StringRef NativeSharedLibraryAtomV1::name() const {
+ return _file->string(_ivarData->nameOffset);
+}
+
+inline llvm::StringRef NativeSharedLibraryAtomV1::loadName() const {
+ return _file->string(_ivarData->loadNameOffset);
+}
+
+
+
+inline const class File& NativeAbsoluteAtomV1::file() const {
+ return *_file;
+}
+
+inline llvm::StringRef NativeAbsoluteAtomV1::name() const {
+ return _file->string(_ivarData->nameOffset);
+}
+
+
inline const Atom* NativeReferenceV1::target() const {
return _file->target(_ivarData->targetIndex);
}
diff --git a/lld/lib/Core/NativeWriter.cpp b/lld/lib/Core/NativeWriter.cpp
index da877fd652c..a95a5149808 100644
--- a/lld/lib/Core/NativeWriter.cpp
+++ b/lld/lib/Core/NativeWriter.cpp
@@ -61,7 +61,21 @@ public:
out.write((char*)&_undefinedAtomIvars[0],
_undefinedAtomIvars.size()*sizeof(NativeUndefinedAtomIvarsV1));
}
-
+
+ if ( !_sharedLibraryAtomIvars.empty() ) {
+ assert( out.tell() == findChunk(NCS_SharedLibraryAtomsV1).fileOffset );
+ out.write((char*)&_sharedLibraryAtomIvars[0],
+ _sharedLibraryAtomIvars.size()
+ * sizeof(NativeSharedLibraryAtomIvarsV1));
+ }
+
+ if ( !_absoluteAtomIvars.empty() ) {
+ assert( out.tell() == findChunk(NCS_AbsoluteAtomsV1).fileOffset );
+ out.write((char*)&_absoluteAtomIvars[0],
+ _absoluteAtomIvars.size()
+ * sizeof(NativeAbsoluteAtomIvarsV1));
+ }
+
if (!_stringPool.empty()) {
assert( out.tell() == findChunk(NCS_Strings).fileOffset );
out.write(&_stringPool[0], _stringPool.size());
@@ -110,23 +124,55 @@ private:
_undefinedAtomIndex[&atom] = _undefinedAtomIvars.size();
NativeUndefinedAtomIvarsV1 ivar;
ivar.nameOffset = getNameOffset(atom);
- ivar.flags = (atom.weakImport() ? 1 : 0);
+ ivar.flags = (atom.canBeNull() & 0x03);
_undefinedAtomIvars.push_back(ivar);
}
// visitor routine called by forEachAtom()
+ virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
+ _sharedLibraryAtomIndex[&atom] = _sharedLibraryAtomIvars.size();
+ NativeSharedLibraryAtomIvarsV1 ivar;
+ ivar.nameOffset = getNameOffset(atom);
+ ivar.loadNameOffset = getSharedLibraryNameOffset(atom.loadName());
+ ivar.flags = atom.canBeNullAtRuntime();
+ _sharedLibraryAtomIvars.push_back(ivar);
+ }
+
+ // visitor routine called by forEachAtom()
+ virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
+ _absoluteAtomIndex[&atom] = _absoluteAtomIvars.size();
+ NativeAbsoluteAtomIvarsV1 ivar;
+ ivar.nameOffset = getNameOffset(atom);
+ ivar.reserved = 0;
+ ivar.value = atom.value();
+ _absoluteAtomIvars.push_back(ivar);
+ }
+
+ // visitor routine called by forEachAtom()
virtual void doFile(const File &) {
}
// fill out native file header and chunk directory
void makeHeader() {
+ const bool hasDefines = !_definedAtomIvars.empty();
const bool hasUndefines = !_undefinedAtomIvars.empty();
+ const bool hasSharedLibraries = !_sharedLibraryAtomIvars.empty();
+ const bool hasAbsolutes = !_absoluteAtomIvars.empty();
+ const bool hasReferences = !_references.empty();
const bool hasTargetsTable = !_targetsTableIndex.empty();
const bool hasAddendTable = !_addendsTableIndex.empty();
- int chunkCount = 5;
+ const bool hasContent = !_contentPool.empty();
+
+ int chunkCount = 1; // always have string pool chunk
+ if ( hasDefines ) chunkCount += 2;
if ( hasUndefines ) ++chunkCount;
+ if ( hasSharedLibraries ) ++chunkCount;
+ if ( hasAbsolutes ) ++chunkCount;
+ if ( hasReferences ) ++chunkCount;
if ( hasTargetsTable ) ++chunkCount;
if ( hasAddendTable ) ++chunkCount;
+ if ( hasContent ) ++chunkCount;
+
_headerBufferSize = sizeof(NativeFileHeader)
+ chunkCount*sizeof(NativeChunk);
_headerBuffer = reinterpret_cast<NativeFileHeader*>
@@ -140,23 +186,25 @@ private:
_headerBuffer->fileSize = 0;
_headerBuffer->chunkCount = chunkCount;
-
- // create chunk for atom ivar array
+ // create chunk for defined atom ivar array
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;
+ uint32_t nextFileOffset = _headerBufferSize;
+ if ( hasDefines ) {
+ NativeChunk& chd = chunks[nextIndex++];
+ chd.signature = NCS_DefinedAtomsV1;
+ chd.fileOffset = nextFileOffset;
+ chd.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1);
+ chd.elementCount = _definedAtomIvars.size();
+ 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 ) {
@@ -169,6 +217,28 @@ private:
nextFileOffset = chu.fileOffset + chu.fileSize;
}
+ // create chunk for shared library atom array
+ if ( hasSharedLibraries ) {
+ NativeChunk& chsl = chunks[nextIndex++];
+ chsl.signature = NCS_SharedLibraryAtomsV1;
+ chsl.fileOffset = nextFileOffset;
+ chsl.fileSize = _sharedLibraryAtomIvars.size() *
+ sizeof(NativeSharedLibraryAtomIvarsV1);
+ chsl.elementCount = _sharedLibraryAtomIvars.size();
+ nextFileOffset = chsl.fileOffset + chsl.fileSize;
+ }
+
+ // create chunk for shared library atom array
+ if ( hasAbsolutes ) {
+ NativeChunk& chsl = chunks[nextIndex++];
+ chsl.signature = NCS_AbsoluteAtomsV1;
+ chsl.fileOffset = nextFileOffset;
+ chsl.fileSize = _absoluteAtomIvars.size() *
+ sizeof(NativeAbsoluteAtomIvarsV1);
+ chsl.elementCount = _absoluteAtomIvars.size();
+ nextFileOffset = chsl.fileOffset + chsl.fileSize;
+ }
+
// create chunk for symbol strings
// pad end of string pool to 4-bytes
while ( (_stringPool.size() % 4) != 0 )
@@ -181,13 +251,15 @@ private:
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;
-
+ if ( hasReferences ) {
+ 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++];
@@ -209,13 +281,15 @@ private:
}
// 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;
-
+ if ( hasContent ) {
+ 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;
}
@@ -237,7 +311,23 @@ private:
return this->getNameOffset(atom.name());
}
- // append atom name to string pool and return offset
+ // check if name is already in pool or append and return offset
+ uint32_t getSharedLibraryNameOffset(llvm::StringRef name) {
+ assert( ! name.empty() );
+ // look to see if this library name was used by another atom
+ for(NameToOffsetVector::iterator it = _sharedLibraryNames.begin();
+ it != _sharedLibraryNames.end(); ++it) {
+ if ( name.equals(it->first) )
+ return it->second;
+ }
+ // first use of this library name
+ uint32_t result = this->getNameOffset(name);
+ _sharedLibraryNames.push_back(
+ std::make_pair<llvm::StringRef, uint32_t>(name, result));
+ return result;
+ }
+
+ // append atom name to string pool and return offset
uint32_t getNameOffset(llvm::StringRef name) {
if ( name.empty() )
return 0;
@@ -356,8 +446,26 @@ private:
}
else {
pos = _undefinedAtomIndex.find(atom);
- assert(pos != _undefinedAtomIndex.end());
- atomIndex = pos->second + _definedAtomIvars.size();
+ if ( pos != _undefinedAtomIndex.end() ) {
+ atomIndex = pos->second + _definedAtomIvars.size();
+ }
+ else {
+ pos = _sharedLibraryAtomIndex.find(atom);
+ if ( pos != _sharedLibraryAtomIndex.end() ) {
+ assert(pos != _sharedLibraryAtomIndex.end());
+ atomIndex = pos->second
+ + _definedAtomIvars.size()
+ + _undefinedAtomIndex.size();
+ }
+ else {
+ pos = _absoluteAtomIndex.find(atom);
+ assert(pos != _absoluteAtomIndex.end());
+ atomIndex = pos->second
+ + _definedAtomIvars.size()
+ + _undefinedAtomIndex.size()
+ + _sharedLibraryAtomIndex.size();
+ }
+ }
}
targetIndexes[targetIndex] = atomIndex;
}
@@ -405,12 +513,17 @@ private:
std::vector<NativeDefinedAtomIvarsV1> _definedAtomIvars;
std::vector<NativeAtomAttributesV1> _attributes;
std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;
+ std::vector<NativeSharedLibraryAtomIvarsV1> _sharedLibraryAtomIvars;
+ std::vector<NativeAbsoluteAtomIvarsV1> _absoluteAtomIvars;
std::vector<NativeReferenceIvarsV1> _references;
TargetToIndex _targetsTableIndex;
TargetToIndex _definedAtomIndex;
TargetToIndex _undefinedAtomIndex;
+ TargetToIndex _sharedLibraryAtomIndex;
+ TargetToIndex _absoluteAtomIndex;
AddendToIndex _addendsTableIndex;
NameToOffsetVector _sectionNames;
+ NameToOffsetVector _sharedLibraryNames;
};
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index 68f4ba5b4f8..92c15f0af50 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -134,6 +134,24 @@ void Resolver::doDefinedAtom(const DefinedAtom &atom) {
}
}
+void Resolver::doSharedLibraryAtom(const SharedLibraryAtom& atom) {
+ // add to list of known atoms
+ _atoms.push_back(&atom);
+
+ // tell symbol table
+ _symbolTable.add(atom);
+}
+
+void Resolver::doAbsoluteAtom(const AbsoluteAtom& atom) {
+ // add to list of known atoms
+ _atoms.push_back(&atom);
+
+ // tell symbol table
+ _symbolTable.add(atom);
+}
+
+
+
// utility to add a vector of atoms
void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) {
for (std::vector<const DefinedAtom *>::const_iterator it = newAtoms.begin();
diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp
index cc4c935eb89..4dc86b76250 100644
--- a/lld/lib/Core/SymbolTable.cpp
+++ b/lld/lib/Core/SymbolTable.cpp
@@ -11,10 +11,11 @@
#include "lld/Core/Atom.h"
#include "lld/Core/DefinedAtom.h"
#include "lld/Core/UndefinedAtom.h"
+#include "lld/Core/SharedLibraryAtom.h"
+#include "lld/Core/AbsoluteAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/InputFiles.h"
#include "lld/Core/Resolver.h"
-#include "lld/Core/UndefinedAtom.h"
#include "lld/Platform/Platform.h"
#include "llvm/Support/ErrorHandling.h"
@@ -36,6 +37,14 @@ void SymbolTable::add(const UndefinedAtom &atom) {
this->addByName(atom);
}
+void SymbolTable::add(const SharedLibraryAtom &atom) {
+ this->addByName(atom);
+}
+
+void SymbolTable::add(const AbsoluteAtom &atom) {
+ this->addByName(atom);
+}
+
void SymbolTable::add(const DefinedAtom &atom) {
assert(atom.scope() != DefinedAtom::scopeTranslationUnit);
if ( !atom.name().empty() ) {
@@ -49,7 +58,9 @@ void SymbolTable::add(const DefinedAtom &atom) {
enum NameCollisionResolution {
NCR_First,
NCR_Second,
- NCR_Dup,
+ NCR_DupDef,
+ NCR_DupUndef,
+ NCR_DupShLib,
NCR_Error
};
@@ -57,7 +68,7 @@ static NameCollisionResolution cases[4][4] = {
//regular absolute undef sharedLib
{
// first is regular
- NCR_Dup, NCR_Error, NCR_First, NCR_First
+ NCR_DupDef, NCR_Error, NCR_First, NCR_First
},
{
// first is absolute
@@ -65,11 +76,11 @@ static NameCollisionResolution cases[4][4] = {
},
{
// first is undef
- NCR_Second, NCR_Second, NCR_First, NCR_Second
+ NCR_Second, NCR_Second, NCR_DupUndef, NCR_Second
},
{
// first is sharedLib
- NCR_Second, NCR_Second, NCR_First, NCR_First
+ NCR_Second, NCR_Second, NCR_First, NCR_DupShLib
}
};
@@ -129,7 +140,7 @@ void SymbolTable::addByName(const Atom & newAtom) {
case NCR_Second:
useNew = true;
break;
- case NCR_Dup:
+ case NCR_DupDef:
assert(existing->definition() == Atom::definitionRegular);
assert(newAtom.definition() == Atom::definitionRegular);
switch ( mergeSelect(((DefinedAtom*)existing)->merge(),
@@ -148,6 +159,39 @@ void SymbolTable::addByName(const Atom & newAtom) {
break;
}
break;
+ case NCR_DupUndef: {
+ const UndefinedAtom* existingUndef = existing->undefinedAtom();
+ const UndefinedAtom* newUndef = newAtom.undefinedAtom();
+ assert(existingUndef != NULL);
+ assert(newUndef != NULL);
+ if ( existingUndef->canBeNull() == newUndef->canBeNull() ) {
+ useNew = false;
+ }
+ else {
+ useNew = (newUndef->canBeNull() < existingUndef->canBeNull());
+ // give platform a change to override which to use
+ _platform.undefineCanBeNullMismatch(*existingUndef,
+ *newUndef, useNew);
+ }
+ }
+ break;
+ case NCR_DupShLib: {
+ const SharedLibraryAtom* existingShLib = existing->sharedLibraryAtom();
+ const SharedLibraryAtom* newShLib = newAtom.sharedLibraryAtom();
+ assert(existingShLib != NULL);
+ assert(newShLib != NULL);
+ if ( (existingShLib->canBeNullAtRuntime()
+ == newShLib->canBeNullAtRuntime()) &&
+ existingShLib->loadName().equals(newShLib->loadName()) ) {
+ useNew = false;
+ }
+ else {
+ useNew = false; // use existing shared library by default
+ // give platform a change to override which to use
+ _platform.sharedLibrarylMismatch(*existingShLib, *newShLib, useNew);
+ }
+ }
+ break;
default:
llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause");
}
diff --git a/lld/lib/Core/YamlKeyValues.cpp b/lld/lib/Core/YamlKeyValues.cpp
index bb32aa88489..6e49580ce69 100644
--- a/lld/lib/Core/YamlKeyValues.cpp
+++ b/lld/lib/Core/YamlKeyValues.cpp
@@ -30,10 +30,12 @@ const char* const KeyValues::isThumbKeyword = "is-thumb";
const char* const KeyValues::isAliasKeyword = "is-alias";
const char* const KeyValues::sectionNameKeyword = "section-name";
const char* const KeyValues::contentKeyword = "content";
+const char* const KeyValues::loadNameKeyword = "load-name";
const char* const KeyValues::sizeKeyword = "size";
+const char* const KeyValues::valueKeyword = "value";
const char* const KeyValues::fixupsKeyword = "fixups";
const char* const KeyValues::permissionsKeyword = "permissions";
-const char* const KeyValues::weakImportKeyword = "weak-import";
+const char* const KeyValues::canBeNullKeyword = "can-be-null";
const char* const KeyValues::fixupsKindKeyword = "kind";
const char* const KeyValues::fixupsOffsetKeyword = "offset";
const char* const KeyValues::fixupsTargetKeyword = "target";
@@ -51,7 +53,7 @@ const DefinedAtom::Merge KeyValues::mergeDefault = DefinedAtom::mer
const DefinedAtom::ContentPermissions KeyValues::permissionsDefault = DefinedAtom::permR__;
const bool KeyValues::isThumbDefault = false;
const bool KeyValues::isAliasDefault = false;
-const bool KeyValues::weakImportDefault = false;
+const UndefinedAtom::CanBeNull KeyValues::canBeNullDefault = UndefinedAtom::canBeNullNever;
@@ -389,17 +391,34 @@ const char* KeyValues::isAlias(bool b) {
-bool KeyValues::weakImport(const char* s)
+struct CanBeNullMapping {
+ const char* string;
+ UndefinedAtom::CanBeNull value;
+};
+
+static const CanBeNullMapping cbnMappings[] = {
+ { "never", UndefinedAtom::canBeNullNever },
+ { "at-runtime", UndefinedAtom::canBeNullAtRuntime },
+ { "at-buildtime", UndefinedAtom::canBeNullAtBuildtime },
+ { NULL, UndefinedAtom::canBeNullNever }
+};
+
+
+UndefinedAtom::CanBeNull KeyValues::canBeNull(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");
+ for (const CanBeNullMapping* p = cbnMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad can-be-null value");
}
-const char* KeyValues::weakImport(bool b) {
- return b ? "true" : "false";
+const char* KeyValues::canBeNull(UndefinedAtom::CanBeNull c) {
+ for (const CanBeNullMapping* p = cbnMappings; p->string != NULL; ++p) {
+ if ( p->value == c )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad can-be-null value");
}
diff --git a/lld/lib/Core/YamlKeyValues.h b/lld/lib/Core/YamlKeyValues.h
index 6cd0908c855..c9dac2a6465 100644
--- a/lld/lib/Core/YamlKeyValues.h
+++ b/lld/lib/Core/YamlKeyValues.h
@@ -12,6 +12,7 @@
#include "lld/Core/Atom.h"
#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/UndefinedAtom.h"
namespace lld {
@@ -24,6 +25,8 @@ public:
static const char* const sectionNameKeyword;
static const char* const contentKeyword;
static const char* const sizeKeyword;
+ static const char* const loadNameKeyword;
+ static const char* const valueKeyword;
static const char* const fixupsKeyword;
static const char* const definitionKeyword;
@@ -76,10 +79,10 @@ public:
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);
+ static const char* const canBeNullKeyword;
+ static const UndefinedAtom::CanBeNull canBeNullDefault;
+ static UndefinedAtom::CanBeNull canBeNull(const char*);
+ static const char* canBeNull(UndefinedAtom::CanBeNull);
static const char* const fixupsKindKeyword;
diff --git a/lld/lib/Core/YamlReader.cpp b/lld/lib/Core/YamlReader.cpp
index d5e60eb2131..97642abeadf 100644
--- a/lld/lib/Core/YamlReader.cpp
+++ b/lld/lib/Core/YamlReader.cpp
@@ -13,6 +13,9 @@
#include "lld/Core/YamlReader.h"
#include "lld/Core/Atom.h"
+#include "lld/Core/UndefinedAtom.h"
+#include "lld/Core/SharedLibraryAtom.h"
+#include "lld/Core/AbsoluteAtom.h"
#include "lld/Core/Error.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
@@ -200,9 +203,7 @@ void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
}
break;
case inValue:
- if (isalnum(c) || (c == '-') || (c == '_')) {
- *p++ = c;
- } else if (c == '\n') {
+ if (c == '\n') {
*p = '\0';
entries.push_back(new Entry(key, value, NULL, depth,
nextKeyIsStartOfDocument,
@@ -212,6 +213,9 @@ void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
state = inDocument;
depth = 0;
}
+ else {
+ *p++ = c;
+ }
break;
case inValueSequence:
if (c == ']') {
@@ -300,6 +304,8 @@ public:
void bindTargetReferences();
void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
void addUndefinedAtom(UndefinedAtom* atom);
+ void addSharedLibraryAtom(SharedLibraryAtom* atom);
+ void addAbsoluteAtom(AbsoluteAtom* atom);
Atom* findAtom(const char* name);
struct NameAtomPair {
@@ -310,6 +316,8 @@ public:
std::vector<YAMLDefinedAtom*> _definedAtoms;
std::vector<UndefinedAtom*> _undefinedAtoms;
+ std::vector<SharedLibraryAtom*> _sharedLibraryAtoms;
+ std::vector<AbsoluteAtom*> _absoluteAtoms;
std::vector<YAMLReference> _references;
std::vector<NameAtomPair> _nameToAtomMapping;
unsigned int _lastRefIndex;
@@ -465,8 +473,38 @@ private:
class YAMLUndefinedAtom : public UndefinedAtom {
public:
- YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm, bool wi)
- : _file(f), _name(nm), _ordinal(ord), _weakImport(wi) { }
+ YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm,
+ UndefinedAtom::CanBeNull cbn)
+ : _file(f), _name(nm), _ordinal(ord), _canBeNull(cbn) { }
+
+ virtual const class File& file() const {
+ return _file;
+ }
+
+ virtual llvm::StringRef name() const {
+ return _name;
+ }
+
+ virtual CanBeNull canBeNull() const {
+ return _canBeNull;
+ }
+
+
+private:
+ YAMLFile& _file;
+ const char * _name;
+ uint32_t _ordinal;
+ UndefinedAtom::CanBeNull _canBeNull;
+};
+
+
+
+class YAMLSharedLibraryAtom : public SharedLibraryAtom {
+public:
+ YAMLSharedLibraryAtom(YAMLFile& f, int32_t ord, const char* nm,
+ const char* ldnm, bool cbn)
+ : _file(f), _name(nm), _ordinal(ord),
+ _loadName(ldnm), _canBeNull(cbn) { }
virtual const class File& file() const {
return _file;
@@ -476,18 +514,52 @@ public:
return _name;
}
- virtual bool weakImport() const {
- return _weakImport;
+ virtual llvm::StringRef loadName() const {
+ return _loadName;
+ }
+
+ virtual bool canBeNullAtRuntime() const {
+ return _canBeNull;
}
+
private:
YAMLFile& _file;
const char * _name;
uint32_t _ordinal;
- bool _weakImport;
+ const char * _loadName;
+ bool _canBeNull;
+};
+
+
+
+class YAMLAbsoluteAtom : public AbsoluteAtom {
+public:
+ YAMLAbsoluteAtom(YAMLFile& f, int32_t ord, const char* nm, uint64_t v)
+ : _file(f), _name(nm), _ordinal(ord), _value(v) { }
+
+ virtual const class File& file() const {
+ return _file;
+ }
+
+ virtual llvm::StringRef name() const {
+ return _name;
+ }
+
+ virtual uint64_t value() const {
+ return _value;
+ }
+
+private:
+ YAMLFile& _file;
+ const char * _name;
+ uint32_t _ordinal;
+ uint64_t _value;
};
+
+
bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
handler.doFile(*this);
for (std::vector<YAMLDefinedAtom *>::const_iterator it = _definedAtoms.begin();
@@ -498,6 +570,17 @@ bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
it != _undefinedAtoms.end(); ++it) {
handler.doUndefinedAtom(**it);
}
+ for (std::vector<SharedLibraryAtom *>::const_iterator
+ it = _sharedLibraryAtoms.begin();
+ it != _sharedLibraryAtoms.end(); ++it) {
+ handler.doSharedLibraryAtom(**it);
+ }
+ for (std::vector<AbsoluteAtom *>::const_iterator
+ it = _absoluteAtoms.begin();
+ it != _absoluteAtoms.end(); ++it) {
+ handler.doAbsoluteAtom(**it);
+ }
+
return true;
}
@@ -534,6 +617,16 @@ void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
_nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
}
+void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom* atom) {
+ _sharedLibraryAtoms.push_back(atom);
+ _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
+}
+
+void YAMLFile::addAbsoluteAtom(AbsoluteAtom* atom) {
+ _absoluteAtoms.push_back(atom);
+ _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
+}
+
class YAMLAtomState {
public:
@@ -544,9 +637,7 @@ public:
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&);
@@ -554,7 +645,9 @@ public:
const char * _name;
const char * _refName;
const char * _sectionName;
+ const char* _loadName;
unsigned long long _size;
+ uint64_t _value;
uint32_t _ordinal;
std::vector<uint8_t>* _content;
DefinedAtom::Alignment _alignment;
@@ -568,7 +661,7 @@ public:
DefinedAtom::ContentPermissions _permissions;
bool _isThumb;
bool _isAlias;
- bool _weakImport;
+ UndefinedAtom::CanBeNull _canBeNull;
YAMLReference _ref;
};
@@ -577,7 +670,9 @@ YAMLAtomState::YAMLAtomState()
: _name(NULL)
, _refName(NULL)
, _sectionName(NULL)
+ , _loadName(NULL)
, _size(0)
+ , _value(0)
, _ordinal(0)
, _content(NULL)
, _alignment(0, 0)
@@ -591,7 +686,7 @@ YAMLAtomState::YAMLAtomState()
, _permissions(KeyValues::permissionsDefault)
, _isThumb(KeyValues::isThumbDefault)
, _isAlias(KeyValues::isAliasDefault)
- , _weakImport(false)
+ , _canBeNull(KeyValues::canBeNullDefault)
{
}
@@ -606,16 +701,30 @@ void YAMLAtomState::makeAtom(YAMLFile& f) {
++_ordinal;
}
else if ( _definition == Atom::definitionUndefined ) {
- UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _weakImport);
+ UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _canBeNull);
f.addUndefinedAtom(a);
++_ordinal;
}
-
+ else if ( _definition == Atom::definitionSharedLibrary ) {
+ bool nullable = (_canBeNull == UndefinedAtom::canBeNullAtRuntime);
+ SharedLibraryAtom *a = new YAMLSharedLibraryAtom(f, _ordinal, _name,
+ _loadName, nullable);
+ f.addSharedLibraryAtom(a);
+ ++_ordinal;
+ }
+ else if ( _definition == Atom::definitionAbsolute ) {
+ AbsoluteAtom *a = new YAMLAbsoluteAtom(f, _ordinal, _name, _value);
+ f.addAbsoluteAtom(a);
+ ++_ordinal;
+ }
+
// reset state for next atom
_name = NULL;
_refName = NULL;
_sectionName = NULL;
+ _loadName = NULL;
_size = 0;
+ _value = 0;
_ordinal = 0;
_content = NULL;
_alignment.powerOf2= 0;
@@ -630,7 +739,7 @@ void YAMLAtomState::makeAtom(YAMLFile& f) {
_permissions = KeyValues::permissionsDefault;
_isThumb = KeyValues::isThumbDefault;
_isAlias = KeyValues::isAliasDefault;
- _weakImport = KeyValues::weakImportDefault;
+ _canBeNull = KeyValues::canBeNullDefault;
_ref._target = NULL;
_ref._targetName = NULL;
_ref._addend = 0;
@@ -666,24 +775,10 @@ void YAMLAtomState::setFixupKind(const char *s) {
}
}
-void YAMLAtomState::setFixupOffset(const char *s) {
- if ((s[0] == '0') && (s[1] == 'x'))
- llvm::StringRef(s).getAsInteger(16, _ref._offsetInAtom);
- else
- 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);
@@ -805,8 +900,12 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
atomState._isAlias = KeyValues::isAlias(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, KeyValues::weakImportKeyword) == 0) {
- atomState._weakImport = KeyValues::weakImport(entry->value);
+ else if (strcmp(entry->key, KeyValues::canBeNullKeyword) == 0) {
+ atomState._canBeNull = KeyValues::canBeNull(entry->value);
+ if ( atomState._definition == Atom::definitionSharedLibrary ) {
+ if ( atomState._canBeNull == UndefinedAtom::canBeNullAtBuildtime )
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
@@ -829,7 +928,14 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
}
else if (strcmp(entry->key, KeyValues::fixupsKeyword) == 0) {
inFixups = true;
-
+ }
+ else if (strcmp(entry->key, KeyValues::loadNameKeyword) == 0) {
+ atomState._loadName = entry->value;
+ haveAtom = true;
+ }
+ else if (strcmp(entry->key, KeyValues::valueKeyword) == 0) {
+ llvm::StringRef(entry->value).getAsInteger(0, atomState._value);
+ haveAtom = true;
}
else {
return make_error_code(yaml_reader_error::unknown_keyword);
@@ -847,7 +953,8 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
haveFixup = true;
}
else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0) {
- atomState.setFixupOffset(entry->value);
+ llvm::StringRef(entry->value).getAsInteger(0,
+ atomState._ref._offsetInAtom);
haveFixup = true;
}
else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0) {
@@ -855,7 +962,8 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
haveFixup = true;
}
else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0) {
- atomState.setFixupAddend(entry->value);
+ llvm::StringRef(entry->value).getAsInteger(0,
+ atomState._ref._addend);
haveFixup = true;
}
}
@@ -865,9 +973,10 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
if (haveAtom) {
atomState.makeAtom(*file);
}
-
- file->bindTargetReferences();
- result.push_back(file);
+ if ( file != NULL ) {
+ file->bindTargetReferences();
+ result.push_back(file);
+ }
return make_error_code(yaml_reader_error::success);
}
diff --git a/lld/lib/Core/YamlWriter.cpp b/lld/lib/Core/YamlWriter.cpp
index c38e735b464..c3a7f235454 100644
--- a/lld/lib/Core/YamlWriter.cpp
+++ b/lld/lib/Core/YamlWriter.cpp
@@ -71,6 +71,14 @@ public:
buildDuplicateNameMap(atom);
}
+ virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
+ buildDuplicateNameMap(atom);
+ }
+
+ virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
+ buildDuplicateNameMap(atom);
+ }
+
void buildDuplicateNameMap(const Atom& atom) {
assert(!atom.name().empty());
NameToAtom::iterator pos = _nameMap.find(atom.name());
@@ -132,10 +140,14 @@ public:
virtual void doFile(const class File &) { _firstAtom = true; }
virtual void doDefinedAtom(const class DefinedAtom &atom) {
- // add blank line between atoms for readability
- if ( !_firstAtom )
+ if ( _firstAtom ) {
+ _out << "atoms:\n";
+ _firstAtom = false;
+ }
+ else {
+ // add blank line between atoms for readability
_out << "\n";
- _firstAtom = false;
+ }
bool hasDash = false;
if ( !atom.name().empty() ) {
@@ -313,35 +325,115 @@ public:
virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
- // add blank line between atoms for readability
- if ( !_firstAtom )
- _out << "\n";
+ if ( _firstAtom ) {
+ _out << "atoms:\n";
_firstAtom = false;
+ }
+ else {
+ // add blank line between atoms for readability
+ _out << "\n";
+ }
- _out << " - "
- << KeyValues::nameKeyword
+ _out << " - "
+ << KeyValues::nameKeyword
+ << ":"
+ << spacePadding(KeyValues::nameKeyword)
+ << atom.name()
+ << "\n";
+
+ _out << " "
+ << KeyValues::definitionKeyword
+ << ":"
+ << spacePadding(KeyValues::definitionKeyword)
+ << KeyValues::definition(atom.definition())
+ << "\n";
+
+ if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
+ _out << " "
+ << KeyValues::canBeNullKeyword
<< ":"
- << spacePadding(KeyValues::nameKeyword)
- << atom.name()
+ << spacePadding(KeyValues::canBeNullKeyword)
+ << KeyValues::canBeNull(atom.canBeNull())
<< "\n";
+ }
+ }
+
+ virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
+ if ( _firstAtom ) {
+ _out << "atoms:\n";
+ _firstAtom = false;
+ }
+ else {
+ // add blank line between atoms for readability
+ _out << "\n";
+ }
+
+ _out << " - "
+ << KeyValues::nameKeyword
+ << ":"
+ << spacePadding(KeyValues::nameKeyword)
+ << atom.name()
+ << "\n";
+
+ _out << " "
+ << KeyValues::definitionKeyword
+ << ":"
+ << spacePadding(KeyValues::definitionKeyword)
+ << KeyValues::definition(atom.definition())
+ << "\n";
+ if ( !atom.loadName().empty() ) {
_out << " "
- << KeyValues::definitionKeyword
+ << KeyValues::loadNameKeyword
<< ":"
- << spacePadding(KeyValues::definitionKeyword)
- << KeyValues::definition(atom.definition())
+ << spacePadding(KeyValues::loadNameKeyword)
+ << atom.loadName()
<< "\n";
+ }
- if ( atom.weakImport() != KeyValues::weakImportDefault ) {
+ if ( atom.canBeNullAtRuntime() ) {
_out << " "
- << KeyValues::weakImportKeyword
+ << KeyValues::canBeNullKeyword
<< ":"
- << spacePadding(KeyValues::weakImportKeyword)
- << KeyValues::weakImport(atom.weakImport())
+ << spacePadding(KeyValues::canBeNullKeyword)
+ << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
<< "\n";
}
- }
+ }
+
+ virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
+ if ( _firstAtom ) {
+ _out << "atoms:\n";
+ _firstAtom = false;
+ }
+ else {
+ // add blank line between atoms for readability
+ _out << "\n";
+ }
+
+ _out << " - "
+ << KeyValues::nameKeyword
+ << ":"
+ << spacePadding(KeyValues::nameKeyword)
+ << atom.name()
+ << "\n";
+ _out << " "
+ << KeyValues::definitionKeyword
+ << ":"
+ << spacePadding(KeyValues::definitionKeyword)
+ << KeyValues::definition(atom.definition())
+ << "\n";
+
+ _out << " "
+ << KeyValues::valueKeyword
+ << ":"
+ << spacePadding(KeyValues::valueKeyword)
+ << "0x";
+ _out.write_hex(atom.value());
+ _out << "\n";
+ }
+
private:
// return a string of the correct number of spaces to align value
@@ -380,7 +472,6 @@ void writeObjectText(const File &file, llvm::raw_ostream &out) {
// Write out all atoms
AtomWriter h(rnb, out);
out << "---\n";
- out << "atoms:\n";
file.forEachAtom(h);
out << "...\n";
}
OpenPOWER on IntegriCloud