summaryrefslogtreecommitdiffstats
path: root/lld/lib/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/Core')
-rw-r--r--lld/lib/Core/Atom.cpp44
-rw-r--r--lld/lib/Core/CMakeLists.txt1
-rw-r--r--lld/lib/Core/Resolver.cpp115
-rw-r--r--lld/lib/Core/SymbolTable.cpp128
-rw-r--r--lld/lib/Core/YamlKeyValues.cpp304
-rw-r--r--lld/lib/Core/YamlKeyValues.h111
-rw-r--r--lld/lib/Core/YamlReader.cpp307
-rw-r--r--lld/lib/Core/YamlWriter.cpp48
8 files changed, 617 insertions, 441 deletions
diff --git a/lld/lib/Core/Atom.cpp b/lld/lib/Core/Atom.cpp
deleted file mode 100644
index 29aa1c805fa..00000000000
--- a/lld/lib/Core/Atom.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===- Core/Atom.cpp - The Fundimental Unit of Linking --------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Core/Atom.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace lld {
-
- Atom::~Atom() {}
-
- llvm::StringRef Atom::name() const {
- return llvm::StringRef();
- }
-
- llvm::StringRef Atom::customSectionName() const {
- return llvm::StringRef();
- }
-
- llvm::ArrayRef<uint8_t> Atom::rawContent() const {
- return llvm::ArrayRef<uint8_t>();
- }
-
- Atom::ContentPermissions Atom::permissions() const {
- return perm___;
- }
-
- Reference::iterator Atom::referencesBegin() const {
- return 0;
- }
-
- Reference::iterator Atom::referencesEnd() const{
- return 0;
- }
-
-
-} // namespace lld
diff --git a/lld/lib/Core/CMakeLists.txt b/lld/lib/Core/CMakeLists.txt
index aa08637db0f..eca024cf231 100644
--- a/lld/lib/Core/CMakeLists.txt
+++ b/lld/lib/Core/CMakeLists.txt
@@ -1,5 +1,4 @@
add_lld_library(lldCore
- Atom.cpp
File.cpp
Resolver.cpp
SymbolTable.cpp
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index c3b83756e1b..51f6a481a65 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -19,17 +19,35 @@
#include <algorithm>
#include <cassert>
+
#include <vector>
namespace lld {
+/// This is used as a filter function to std::remove_if to dead strip atoms.
class NotLive {
public:
+ NotLive(const llvm::DenseSet<const Atom*>& la) : _liveAtoms(la) { }
+
bool operator()(const Atom *atom) const {
- return !(atom->live() || !atom->deadStrip());
+ // don't remove if live
+ if ( _liveAtoms.count(atom) )
+ return false;
+ // don't remove if marked never-dead-strip
+ if ( const DefinedAtom* defAtom = atom->definedAtom() ) {
+ if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
+ return false;
+ }
+ // do remove this atom
+ return true;
}
+
+private:
+ const llvm::DenseSet<const Atom*> _liveAtoms;
};
+
+/// This is used as a filter function to std::remove_if to coalesced atoms.
class AtomCoalescedAway {
public:
AtomCoalescedAway(SymbolTable &sym) : _symbolTable(sym) {}
@@ -43,6 +61,9 @@ private:
SymbolTable &_symbolTable;
};
+
+
+
void Resolver::initializeState() {
_platform.initialize();
}
@@ -68,24 +89,34 @@ void Resolver::doFile(const File &file) {
_platform.fileAdded(file);
}
+
+void Resolver::doUndefinedAtom(const class UndefinedAtom& atom) {
+ // add to list of known atoms
+ _atoms.push_back(&atom);
+
+ // tell symbol table
+ _symbolTable.add(atom);
+}
+
+
// called on each atom when a file is added
-void Resolver::doAtom(const Atom &atom) {
+void Resolver::doDefinedAtom(const DefinedAtom &atom) {
// notify platform
_platform.atomAdded(atom);
// add to list of known atoms
_atoms.push_back(&atom);
-
+
// adjust scope (e.g. force some globals to be hidden)
_platform.adjustScope(atom);
// non-static atoms need extra handling
- if (atom.scope() != Atom::scopeTranslationUnit) {
+ if (atom.scope() != DefinedAtom::scopeTranslationUnit) {
// tell symbol table about non-static atoms
_symbolTable.add(atom);
// platform can add aliases for any symbol
- std::vector<const Atom *> aliases;
+ std::vector<const DefinedAtom *> aliases;
if (_platform.getAliasAtoms(atom, aliases))
this->addAtoms(aliases);
}
@@ -104,10 +135,10 @@ void Resolver::doAtom(const Atom &atom) {
}
// utility to add a vector of atoms
-void Resolver::addAtoms(const std::vector<const Atom *> &newAtoms) {
- for (std::vector<const Atom *>::const_iterator it = newAtoms.begin();
+void Resolver::addAtoms(const std::vector<const DefinedAtom*>& newAtoms) {
+ for (std::vector<const DefinedAtom *>::const_iterator it = newAtoms.begin();
it != newAtoms.end(); ++it) {
- this->doAtom(**it);
+ this->doDefinedAtom(**it);
}
}
@@ -135,7 +166,7 @@ void Resolver::resolveUndefines() {
// give platform a chance to instantiate platform
// specific atoms (e.g. section boundary)
if (!_symbolTable.isDefined(undefName)) {
- std::vector<const Atom *> platAtoms;
+ std::vector<const DefinedAtom *> platAtoms;
if (_platform.getPlatformAtoms(undefName, platAtoms))
this->addAtoms(platAtoms);
}
@@ -146,9 +177,10 @@ void Resolver::resolveUndefines() {
std::vector<const Atom *> tents;
for (std::vector<const Atom *>::iterator ait = _atoms.begin();
ait != _atoms.end(); ++ait) {
- const Atom *atom = *ait;
- if (atom->definition() == Atom::definitionTentative)
- tents.push_back(atom);
+ if ( const DefinedAtom* defAtom = (*ait)->definedAtom() ) {
+ if ( defAtom->merge() == DefinedAtom::mergeAsTentative )
+ tents.push_back(defAtom);
+ }
}
for (std::vector<const Atom *>::iterator dit = tents.begin();
dit != tents.end(); ++dit) {
@@ -157,9 +189,10 @@ void Resolver::resolveUndefines() {
llvm::StringRef tentName = (*dit)->name();
const Atom *curAtom = _symbolTable.findByName(tentName);
assert(curAtom != NULL);
- if (curAtom->definition() == Atom::definitionTentative) {
- _inputFiles.searchLibraries(tentName, searchDylibs, true, true,
- *this);
+ if ( const DefinedAtom* curDefAtom = curAtom->definedAtom() ) {
+ if (curDefAtom->merge() == DefinedAtom::mergeAsTentative )
+ _inputFiles.searchLibraries(tentName, searchDylibs,
+ true, true, *this);
}
}
}
@@ -171,10 +204,11 @@ void Resolver::resolveUndefines() {
void Resolver::updateReferences() {
for (std::vector<const Atom *>::iterator it = _atoms.begin();
it != _atoms.end(); ++it) {
- const Atom *atom = *it;
- for (Reference::iterator rit = atom->referencesBegin(),
- end = atom->referencesEnd(); rit != end; ++rit) {
- rit->target = _symbolTable.replacement(rit->target);
+ if ( const DefinedAtom* defAtom = (*it)->definedAtom() ) {
+ for (Reference::iterator rit = defAtom->referencesBegin(),
+ end = defAtom->referencesEnd(); rit != end; ++rit) {
+ rit->target = _symbolTable.replacement(rit->target);
+ }
}
}
}
@@ -195,19 +229,21 @@ void Resolver::markLive(const Atom &atom, WhyLiveBackChain *previous) {
}
// if already marked live, then done (stop recursion)
- if (atom.live())
+ if ( _liveAtoms.count(&atom) )
return;
// mark this atom is live
- const_cast<Atom *>(&atom)->setLive(true);
+ _liveAtoms.insert(&atom);
// mark all atoms it references as live
WhyLiveBackChain thisChain;
thisChain.previous = previous;
thisChain.referer = &atom;
- for (Reference::iterator rit = atom.referencesBegin(),
- end = atom.referencesEnd(); rit != end; ++rit) {
- this->markLive(*(rit->target), &thisChain);
+ if ( const DefinedAtom* defAtom = atom.definedAtom() ) {
+ for (Reference::iterator rit = defAtom->referencesBegin(),
+ end = defAtom->referencesEnd(); rit != end; ++rit) {
+ this->markLive(*(rit->target), &thisChain);
+ }
}
}
@@ -218,11 +254,7 @@ void Resolver::deadStripOptimize() {
return;
// clear liveness on all atoms
- for (std::vector<const Atom *>::iterator it = _atoms.begin();
- it != _atoms.end(); ++it) {
- const Atom *atom = *it;
- const_cast<Atom *>(atom)->setLive(0);
- }
+ _liveAtoms.clear();
// add entry point (main) to live roots
const Atom *entry = this->entryPoint();
@@ -239,7 +271,7 @@ void Resolver::deadStripOptimize() {
}
// add platform specific helper atoms
- std::vector<const Atom *> platRootAtoms;
+ std::vector<const DefinedAtom *> platRootAtoms;
if (_platform.getImplicitDeadStripRoots(platRootAtoms))
this->addAtoms(platRootAtoms);
@@ -254,7 +286,7 @@ void Resolver::deadStripOptimize() {
// now remove all non-live atoms from _atoms
_atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
- NotLive()), _atoms.end());
+ NotLive(_liveAtoms)), _atoms.end());
}
// error out if some undefines remain
@@ -270,7 +302,7 @@ void Resolver::checkUndefines(bool final) {
// when dead code stripping we don't care if dead atoms are undefined
undefinedAtoms.erase(std::remove_if(
undefinedAtoms.begin(), undefinedAtoms.end(),
- NotLive()), undefinedAtoms.end());
+ NotLive(_liveAtoms)), undefinedAtoms.end());
}
// let platform make error message about missing symbols
@@ -289,15 +321,16 @@ void Resolver::removeCoalescedAwayAtoms() {
void Resolver::checkDylibSymbolCollisions() {
for (std::vector<const Atom *>::const_iterator it = _atoms.begin();
it != _atoms.end(); ++it) {
- const Atom *atom = *it;
- if (atom->scope() == Atom::scopeGlobal) {
- if (atom->definition() == Atom::definitionTentative) {
- // See if any shared library also has symbol which
- // collides with the tentative definition.
- // SymbolTable will warn if needed.
- _inputFiles.searchLibraries(atom->name(), true, false, false, *this);
- }
- }
+ const DefinedAtom* defAtom = (*it)->definedAtom();
+ if ( defAtom == NULL )
+ continue;
+ if ( defAtom->merge() != DefinedAtom::mergeAsTentative )
+ continue;
+ assert(defAtom->scope() != DefinedAtom::scopeTranslationUnit);
+ // See if any shared library also has symbol which
+ // collides with the tentative definition.
+ // SymbolTable will warn if needed.
+ _inputFiles.searchLibraries(defAtom->name(), true, false, false, *this);
}
}
diff --git a/lld/lib/Core/SymbolTable.cpp b/lld/lib/Core/SymbolTable.cpp
index 740773843cd..f964fd8acf9 100644
--- a/lld/lib/Core/SymbolTable.cpp
+++ b/lld/lib/Core/SymbolTable.cpp
@@ -9,6 +9,8 @@
#include "lld/Core/SymbolTable.h"
#include "lld/Core/Atom.h"
+#include "lld/Core/DefinedAtom.h"
+#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/File.h"
#include "lld/Core/InputFiles.h"
#include "lld/Core/Resolver.h"
@@ -30,12 +32,16 @@ SymbolTable::SymbolTable(Platform& plat)
: _platform(plat) {
}
-void SymbolTable::add(const Atom &atom) {
- assert(atom.scope() != Atom::scopeTranslationUnit);
+void SymbolTable::add(const UndefinedAtom &atom) {
+ this->addByName(atom);
+}
+
+void SymbolTable::add(const DefinedAtom &atom) {
+ assert(atom.scope() != DefinedAtom::scopeTranslationUnit);
if ( !atom.internalName() ) {
this->addByName(atom);
}
- else if ( atom.mergeDuplicates() ) {
+ else {
this->addByContent(atom);
}
}
@@ -43,37 +49,27 @@ void SymbolTable::add(const Atom &atom) {
enum NameCollisionResolution {
NCR_First,
NCR_Second,
- NCR_Weak,
- NCR_Larger,
NCR_Dup,
NCR_Error
};
-static NameCollisionResolution cases[6][6] = {
- //regular weak tentative absolute undef sharedLib
+static NameCollisionResolution cases[4][4] = {
+ //regular absolute undef sharedLib
{
// first is regular
- NCR_Dup, NCR_First, NCR_First, NCR_Error, NCR_First, NCR_First
- },
- {
- // first is weak
- NCR_Second, NCR_Weak, NCR_Larger, NCR_Error, NCR_First, NCR_First
- },
- {
- // first is tentative
- NCR_Second, NCR_Second, NCR_Larger, NCR_Error, NCR_First, NCR_First
+ NCR_Dup, NCR_Error, NCR_First, NCR_First
},
{
// first is absolute
- NCR_Error, NCR_Error, NCR_Error, NCR_Error, NCR_First, NCR_First
+ NCR_Error, NCR_Error, NCR_First, NCR_First
},
{
// first is undef
- NCR_Second, NCR_Second, NCR_Second, NCR_Second, NCR_First, NCR_Second
+ NCR_Second, NCR_Second, NCR_First, NCR_Second
},
{
// first is sharedLib
- NCR_Second, NCR_Second, NCR_Second, NCR_Second, NCR_First, NCR_First
+ NCR_Second, NCR_Second, NCR_First, NCR_First
}
};
@@ -82,6 +78,40 @@ static NameCollisionResolution collide(Atom::Definition first,
return cases[first][second];
}
+
+enum MergeResolution {
+ MCR_First,
+ MCR_Second,
+ MCR_Largest,
+ MCR_Error
+};
+
+static MergeResolution mergeCases[4][4] = {
+ // no tentative weak weakAddressUsed
+ {
+ // first is no
+ MCR_Error, MCR_First, MCR_First, MCR_First
+ },
+ {
+ // first is tentative
+ MCR_Second, MCR_Largest, MCR_Second, MCR_Second
+ },
+ {
+ // first is weak
+ MCR_Second, MCR_First, MCR_First, MCR_Second
+ },
+ {
+ // first is weakAddressUsed
+ MCR_Second, MCR_First, MCR_First, MCR_First
+ }
+};
+
+static MergeResolution mergeSelect(DefinedAtom::Merge first,
+ DefinedAtom::Merge second) {
+ return mergeCases[first][second];
+}
+
+
void SymbolTable::addByName(const Atom & newAtom) {
llvm::StringRef name = newAtom.name();
const Atom *existing = this->findByName(name);
@@ -93,31 +123,33 @@ void SymbolTable::addByName(const Atom & newAtom) {
// Name is already in symbol table and associated with another atom.
bool useNew = true;
switch (collide(existing->definition(), newAtom.definition())) {
- case NCR_First:
- useNew = false;
- break;
- case NCR_Second:
- useNew = true;
- break;
- case NCR_Dup:
- if ( existing->mergeDuplicates() && newAtom.mergeDuplicates() ) {
- // Both mergeable. Use auto-hide bit as tie breaker
- if ( existing->autoHide() != newAtom.autoHide() ) {
- // They have different autoHide values, keep non-autohide one
- useNew = existing->autoHide();
- }
- else {
- // They have same autoHide, so just keep using existing
- useNew = false;
+ case NCR_First:
+ useNew = false;
+ break;
+ case NCR_Second:
+ useNew = true;
+ break;
+ case NCR_Dup:
+ assert(existing->definition() == Atom::definitionRegular);
+ assert(newAtom.definition() == Atom::definitionRegular);
+ switch ( mergeSelect(((DefinedAtom*)existing)->merge(),
+ ((DefinedAtom*)(&newAtom))->merge()) ) {
+ case MCR_First:
+ useNew = false;
+ break;
+ case MCR_Second:
+ useNew = true;
+ break;
+ case MCR_Largest:
+ useNew = true;
+ break;
+ case MCR_Error:
+ llvm::report_fatal_error("duplicate symbol error");
+ break;
}
- }
- else {
- const Atom& use = _platform.handleMultipleDefinitions(*existing, newAtom);
- useNew = ( &use != existing );
- }
- break;
- default:
- llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause");
+ break;
+ default:
+ llvm::report_fatal_error("SymbolTable::addByName(): unhandled switch clause");
}
if ( useNew ) {
// Update name table to use new atom.
@@ -133,9 +165,9 @@ void SymbolTable::addByName(const Atom & newAtom) {
}
-unsigned SymbolTable::MyMappingInfo::getHashValue(const Atom * const atom) {
+unsigned SymbolTable::MyMappingInfo::getHashValue(const DefinedAtom * const atom) {
unsigned hash = atom->size();
- if ( atom->contentType() != Atom::typeZeroFill ) {
+ if ( atom->contentType() != DefinedAtom::typeZeroFill ) {
llvm::ArrayRef<uint8_t> content = atom->rawContent();
for (unsigned int i=0; i < content.size(); ++i) {
hash = hash * 33 + content[i];
@@ -148,8 +180,8 @@ unsigned SymbolTable::MyMappingInfo::getHashValue(const Atom * const atom) {
}
-bool SymbolTable::MyMappingInfo::isEqual(const Atom * const l,
- const Atom * const r) {
+bool SymbolTable::MyMappingInfo::isEqual(const DefinedAtom * const l,
+ const DefinedAtom * const r) {
if ( l == r )
return true;
if ( l == getEmptyKey() )
@@ -171,7 +203,7 @@ bool SymbolTable::MyMappingInfo::isEqual(const Atom * const l,
}
-void SymbolTable::addByContent(const Atom & newAtom) {
+void SymbolTable::addByContent(const DefinedAtom & newAtom) {
AtomContentSet::iterator pos = _contentTable.find(&newAtom);
if ( pos == _contentTable.end() ) {
_contentTable.insert(&newAtom);
diff --git a/lld/lib/Core/YamlKeyValues.cpp b/lld/lib/Core/YamlKeyValues.cpp
index 47729d684d8..4158e6d4e51 100644
--- a/lld/lib/Core/YamlKeyValues.cpp
+++ b/lld/lib/Core/YamlKeyValues.cpp
@@ -18,61 +18,33 @@ namespace yaml {
const char* const KeyValues::nameKeyword = "name";
-const char* const KeyValues::scopeKeyword = "scope";
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::mergeDuplicatesKeyword = "merge-duplicates";
-const char* const KeyValues::autoHideKeyword = "auto-hide";
+const char* const KeyValues::interposableKeyword = "interposable";
+const char* const KeyValues::mergeKeyword = "merge";
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::sizeKeyword = "size";
+const char* const KeyValues::permissionsKeyword = "permissions";
-const Atom::Scope KeyValues::scopeDefault = Atom::scopeTranslationUnit;
-const Atom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
-const Atom::ContentType KeyValues::contentTypeDefault = Atom::typeData;
-const Atom::DeadStripKind KeyValues::deadStripKindDefault = Atom::deadStripNormal;
-const Atom::SectionChoice KeyValues::sectionChoiceDefault = Atom::sectionBasedOnContent;
-const bool KeyValues::internalNameDefault = false;
-const bool KeyValues::mergeDuplicatesDefault = false;
-const bool KeyValues::autoHideDefault = false;
-const bool KeyValues::isThumbDefault = false;
-const bool KeyValues::isAliasDefault = false;
-
-
-struct ScopeMapping {
- const char* string;
- Atom::Scope value;
-};
-
-static const ScopeMapping scopeMappings[] = {
- { "global", Atom::scopeGlobal },
- { "hidden", Atom::scopeLinkageUnit },
- { "static", Atom::scopeTranslationUnit },
- { NULL, Atom::scopeGlobal }
-};
-
-Atom::Scope KeyValues::scope(const char* s)
-{
- for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
- if ( strcmp(p->string, s) == 0 )
- return p->value;
- }
- llvm::report_fatal_error("bad scope value");
-}
-
-const char* KeyValues::scope(Atom::Scope s) {
- for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
- if ( p->value == s )
- return p->string;
- }
- llvm::report_fatal_error("bad scope value");
-}
+const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
+const DefinedAtom::Scope KeyValues::scopeDefault = DefinedAtom::scopeTranslationUnit;
+const DefinedAtom::ContentType KeyValues::contentTypeDefault = DefinedAtom::typeData;
+const DefinedAtom::DeadStripKind KeyValues::deadStripKindDefault = DefinedAtom::deadStripNormal;
+const DefinedAtom::SectionChoice KeyValues::sectionChoiceDefault = DefinedAtom::sectionBasedOnContent;
+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;
@@ -85,8 +57,6 @@ struct DefinitionMapping {
static const DefinitionMapping defMappings[] = {
{ "regular", Atom::definitionRegular },
- { "weak", Atom::definitionWeak },
- { "tentative", Atom::definitionTentative },
{ "absolute", Atom::definitionAbsolute },
{ "undefined", Atom::definitionUndefined },
{ "shared-library", Atom::definitionSharedLibrary },
@@ -114,40 +84,76 @@ const char* KeyValues::definition(Atom::Definition s) {
+struct ScopeMapping {
+ const char* string;
+ DefinedAtom::Scope value;
+};
+
+static const ScopeMapping scopeMappings[] = {
+ { "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) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad scope value");
+}
+
+const char* KeyValues::scope(DefinedAtom::Scope s) {
+ for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+ if ( p->value == s )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad scope value");
+}
+
+
+
+
+
+
+
+
struct ContentTypeMapping {
const char* string;
- Atom::ContentType value;
+ DefinedAtom::ContentType value;
};
static const ContentTypeMapping typeMappings[] = {
- { "unknown", Atom::typeUnknown },
- { "code", Atom::typeCode },
- { "resolver", Atom::typeResolver },
- { "constant", Atom::typeConstant },
- { "c-string", Atom::typeCString },
- { "utf16-string", Atom::typeUTF16String },
- { "CFI", Atom::typeCFI },
- { "LSDA", Atom::typeLSDA },
- { "literal-4", Atom::typeLiteral4 },
- { "literal-8", Atom::typeLiteral8 },
- { "literal-16", Atom::typeLiteral16 },
- { "data", Atom::typeData },
- { "zero-fill", Atom::typeZeroFill },
- { "cf-string", Atom::typeCFString },
- { "initializer-ptr",Atom::typeInitializerPtr },
- { "terminator-ptr", Atom::typeTerminatorPtr },
- { "c-string-ptr", Atom::typeCStringPtr },
- { "objc1-class", Atom::typeObjC1Class },
- { "objc1-class-ptr",Atom::typeObjCClassPtr },
- { "objc2-cat-ptr", Atom::typeObjC2CategoryList },
- { "tlv-thunk", Atom::typeThunkTLV },
- { "tlv-data", Atom::typeTLVInitialData },
- { "tlv-zero-fill", Atom::typeTLVInitialZeroFill },
- { "tlv-init-ptr", Atom::typeTLVInitializerPtr },
- { NULL, Atom::typeUnknown }
+ { "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 }
};
-Atom::ContentType KeyValues::contentType(const char* s)
+DefinedAtom::ContentType KeyValues::contentType(const char* s)
{
for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
@@ -156,7 +162,7 @@ Atom::ContentType KeyValues::contentType(const char* s)
llvm::report_fatal_error("bad content type value");
}
-const char* KeyValues::contentType(Atom::ContentType s) {
+const char* KeyValues::contentType(DefinedAtom::ContentType s) {
for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
if ( p->value == s )
return p->string;
@@ -172,17 +178,17 @@ const char* KeyValues::contentType(Atom::ContentType s) {
struct DeadStripMapping {
const char* string;
- Atom::DeadStripKind value;
+ DefinedAtom::DeadStripKind value;
};
static const DeadStripMapping deadStripMappings[] = {
- { "normal", Atom::deadStripNormal },
- { "never", Atom::deadStripNever },
- { "always", Atom::deadStripAlways },
- { NULL, Atom::deadStripNormal }
+ { "normal", DefinedAtom::deadStripNormal },
+ { "never", DefinedAtom::deadStripNever },
+ { "always", DefinedAtom::deadStripAlways },
+ { NULL, DefinedAtom::deadStripNormal }
};
-Atom::DeadStripKind KeyValues::deadStripKind(const char* s)
+DefinedAtom::DeadStripKind KeyValues::deadStripKind(const char* s)
{
for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
@@ -191,7 +197,7 @@ Atom::DeadStripKind KeyValues::deadStripKind(const char* s)
llvm::report_fatal_error("bad dead strip value");
}
-const char* KeyValues::deadStripKind(Atom::DeadStripKind dsk) {
+const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) {
for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
if ( p->value == dsk )
return p->string;
@@ -203,34 +209,33 @@ const char* KeyValues::deadStripKind(Atom::DeadStripKind dsk) {
-
-struct SectionChoiceMapping {
+struct InterposableMapping {
const char* string;
- Atom::SectionChoice value;
+ DefinedAtom::Interposable value;
};
-static const SectionChoiceMapping sectMappings[] = {
- { "content", Atom::sectionBasedOnContent },
- { "custom", Atom::sectionCustomPreferred },
- { "custom-required", Atom::sectionCustomRequired },
- { NULL, Atom::sectionBasedOnContent }
+static const InterposableMapping interMappings[] = {
+ { "no", DefinedAtom::interposeNo },
+ { "yes", DefinedAtom::interposeYes },
+ { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak },
+ { NULL, DefinedAtom::interposeNo }
};
-Atom::SectionChoice KeyValues::sectionChoice(const char* s)
+DefinedAtom::Interposable KeyValues::interposable(const char* s)
{
- for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
if ( strcmp(p->string, s) == 0 )
return p->value;
}
- llvm::report_fatal_error("bad dead strip value");
+ llvm::report_fatal_error("bad interposable value");
}
-const char* KeyValues::sectionChoice(Atom::SectionChoice s) {
- for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
- if ( p->value == s )
+const char* KeyValues::interposable(DefinedAtom::Interposable in) {
+ for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
+ if ( p->value == in )
return p->string;
}
- llvm::report_fatal_error("bad dead strip value");
+ llvm::report_fatal_error("bad interposable value");
}
@@ -238,18 +243,34 @@ const char* KeyValues::sectionChoice(Atom::SectionChoice s) {
+struct MergeMapping {
+ const char* string;
+ DefinedAtom::Merge value;
+};
-bool KeyValues::internalName(const char* s)
+static const MergeMapping mergeMappings[] = {
+ { "no", DefinedAtom::mergeNo },
+ { "asTentative", DefinedAtom::mergeAsTentative },
+ { "asWeak", DefinedAtom::mergeAsWeak },
+ { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed },
+ { NULL, DefinedAtom::mergeNo }
+};
+
+DefinedAtom::Merge KeyValues::merge(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");
+ for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad merge value");
}
-const char* KeyValues::internalName(bool b) {
- return b ? "true" : "false";
+const char* KeyValues::merge(DefinedAtom::Merge in) {
+ for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+ if ( p->value == in )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad merge value");
}
@@ -257,17 +278,33 @@ const char* KeyValues::internalName(bool b) {
-bool KeyValues::mergeDuplicates(const char* s)
+struct SectionChoiceMapping {
+ const char* string;
+ DefinedAtom::SectionChoice value;
+};
+
+static const SectionChoiceMapping sectMappings[] = {
+ { "content", DefinedAtom::sectionBasedOnContent },
+ { "custom", DefinedAtom::sectionCustomPreferred },
+ { "custom-required", DefinedAtom::sectionCustomRequired },
+ { NULL, DefinedAtom::sectionBasedOnContent }
+};
+
+DefinedAtom::SectionChoice KeyValues::sectionChoice(const char* s)
{
- if ( strcmp(s, "true") == 0 )
- return true;
- else if ( strcmp(s, "false") == 0 )
- return false;
- llvm::report_fatal_error("bad merge-duplicates value");
+ for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad dead strip value");
}
-const char* KeyValues::mergeDuplicates(bool b) {
- return b ? "true" : "false";
+const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) {
+ for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+ if ( p->value == s )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad dead strip value");
}
@@ -275,23 +312,60 @@ const char* KeyValues::mergeDuplicates(bool b) {
-bool KeyValues::autoHide(const char* s)
+
+struct PermissionsMapping {
+ 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 },
+ { NULL, DefinedAtom::perm___ }
+};
+
+DefinedAtom::ContentPermissions KeyValues::permissions(const char* s)
+{
+ for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+ if ( strcmp(p->string, s) == 0 )
+ return p->value;
+ }
+ llvm::report_fatal_error("bad permissions value");
+}
+
+const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
+ for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+ if ( p->value == s )
+ return p->string;
+ }
+ llvm::report_fatal_error("bad permissions value");
+}
+
+
+
+
+
+
+
+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 auto-hide value");
+ llvm::report_fatal_error("bad internal-name value");
}
-const char* KeyValues::autoHide(bool b) {
+const char* KeyValues::internalName(bool b) {
return b ? "true" : "false";
}
-
bool KeyValues::isThumb(const char* s)
{
if ( strcmp(s, "true") == 0 )
diff --git a/lld/lib/Core/YamlKeyValues.h b/lld/lib/Core/YamlKeyValues.h
index c8890bd8f1e..b38a26cfaf3 100644
--- a/lld/lib/Core/YamlKeyValues.h
+++ b/lld/lib/Core/YamlKeyValues.h
@@ -11,6 +11,7 @@
#define LLD_CORE_YAML_KEY_VALUES_H_
#include "lld/Core/Atom.h"
+#include "lld/Core/DefinedAtom.h"
namespace lld {
@@ -18,61 +19,65 @@ namespace yaml {
class KeyValues {
public:
- static const char* const nameKeyword;
- static const char* const sectionNameKeyword;
- static const char* const contentKeyword;
- static const char* const sizeKeyword;
+ static const char* const nameKeyword;
+ static const char* const sectionNameKeyword;
+ static const char* const contentKeyword;
+ static const char* const sizeKeyword;
-
- static const char* const scopeKeyword;
- static const Atom::Scope scopeDefault;
- static Atom::Scope scope(const char*);
- static const char* scope(Atom::Scope);
+ static const char* const definitionKeyword;
+ static const Atom::Definition definitionDefault;
+ static Atom::Definition definition(const char*);
+ static const char* definition(Atom::Definition);
+
+ static const char* const scopeKeyword;
+ static const DefinedAtom::Scope scopeDefault;
+ static DefinedAtom::Scope scope(const char*);
+ static const char* scope(DefinedAtom::Scope);
- static const char* const definitionKeyword;
- static const Atom::Definition definitionDefault;
- static Atom::Definition definition(const char*);
- static const char* definition(Atom::Definition);
-
- static const char* const contentTypeKeyword;
- static const Atom::ContentType contentTypeDefault;
- static Atom::ContentType contentType(const char*);
- static const char* contentType(Atom::ContentType);
-
- static const char* const deadStripKindKeyword;
- static const Atom::DeadStripKind deadStripKindDefault;
- static Atom::DeadStripKind deadStripKind(const char*);
- static const char* deadStripKind(Atom::DeadStripKind);
-
- static const char* const sectionChoiceKeyword;
- static const Atom::SectionChoice sectionChoiceDefault;
- static Atom::SectionChoice sectionChoice(const char*);
- static const char* sectionChoice(Atom::SectionChoice);
-
- static const char* const internalNameKeyword;
- static const bool internalNameDefault;
- static bool internalName(const char*);
- static const char* internalName(bool);
-
- static const char* const mergeDuplicatesKeyword;
- static const bool mergeDuplicatesDefault;
- static bool mergeDuplicates(const char*);
- static const char* mergeDuplicates(bool);
-
- static const char* const autoHideKeyword;
- static const bool autoHideDefault;
- static bool autoHide(const char*);
- static const char* autoHide(bool);
-
- static const char* const isThumbKeyword;
- static const bool isThumbDefault;
- static bool isThumb(const char*);
- static const char* isThumb(bool);
-
- static const char* const isAliasKeyword;
- static const bool isAliasDefault;
- static bool isAlias(const char*);
- static const char* isAlias(bool);
+ static const char* const contentTypeKeyword;
+ static const DefinedAtom::ContentType contentTypeDefault;
+ static DefinedAtom::ContentType contentType(const char*);
+ static const char* contentType(DefinedAtom::ContentType);
+
+ static const char* const deadStripKindKeyword;
+ static const DefinedAtom::DeadStripKind deadStripKindDefault;
+ static DefinedAtom::DeadStripKind deadStripKind(const char*);
+ static const char* deadStripKind(DefinedAtom::DeadStripKind);
+
+ static const char* const sectionChoiceKeyword;
+ static const DefinedAtom::SectionChoice sectionChoiceDefault;
+ static DefinedAtom::SectionChoice sectionChoice(const char*);
+ static const char* sectionChoice(DefinedAtom::SectionChoice);
+
+ static const char* const interposableKeyword;
+ static const DefinedAtom::Interposable interposableDefault;
+ static DefinedAtom::Interposable interposable(const char*);
+ static const char* interposable(DefinedAtom::Interposable);
+
+ static const char* const mergeKeyword;
+ static const DefinedAtom::Merge mergeDefault;
+ static DefinedAtom::Merge merge(const char*);
+ static const char* merge(DefinedAtom::Merge);
+
+ static const char* const permissionsKeyword;
+ static const DefinedAtom::ContentPermissions permissionsDefault;
+ 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*);
+ static const char* isThumb(bool);
+
+ static const char* const isAliasKeyword;
+ static const bool isAliasDefault;
+ static bool isAlias(const char*);
+ static const char* isAlias(bool);
};
diff --git a/lld/lib/Core/YamlReader.cpp b/lld/lib/Core/YamlReader.cpp
index 8fe7d507c6b..5ca8fbc8103 100644
--- a/lld/lib/Core/YamlReader.cpp
+++ b/lld/lib/Core/YamlReader.cpp
@@ -289,16 +289,17 @@ public:
virtual bool justInTimeforEachAtom(llvm::StringRef name,
File::AtomHandler &) const;
- std::vector<Atom *> _atoms;
+ std::vector<DefinedAtom*> _definedAtoms;
+ std::vector<UndefinedAtom*> _undefinedAtoms;
std::vector<Reference> _references;
unsigned int _lastRefIndex;
};
bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
handler.doFile(*this);
- for (std::vector<Atom *>::const_iterator it = _atoms.begin();
- it != _atoms.end(); ++it) {
- handler.doAtom(**it);
+ for (std::vector<DefinedAtom *>::const_iterator it = _definedAtoms.begin();
+ it != _definedAtoms.end(); ++it) {
+ handler.doDefinedAtom(**it);
}
return true;
}
@@ -309,90 +310,153 @@ bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
}
-class YAMLAtom : public Atom {
+class YAMLDefinedAtom : public DefinedAtom {
public:
- YAMLAtom( uint64_t ord
- , Definition d
- , Scope s
- , ContentType ct
- , SectionChoice sc
- , bool intn
- , bool md
- , bool ah
- , DeadStripKind dsk
- , bool tb
- , bool al
- , Alignment a
- , YAMLFile& f
- , const char *n
- , const char* sn
- , uint64_t sz
- , std::vector<uint8_t>* c)
- : Atom(ord, d, s, ct, sc, intn, md, ah, dsk, tb, al, a)
- , _file(f)
- , _name(n)
- , _sectionName(sn)
- , _content(c)
- , _size(sz)
- , _refStartIndex(f._lastRefIndex)
- , _refEndIndex(f._references.size()) {
- f._lastRefIndex = _refEndIndex;
+ YAMLDefinedAtom( uint32_t ord
+ , YAMLFile& file
+ , DefinedAtom::Scope scope
+ , DefinedAtom::ContentType type
+ , DefinedAtom::SectionChoice sectionChoice
+ , DefinedAtom::Interposable interpose
+ , DefinedAtom::Merge merge
+ , DefinedAtom::DeadStripKind deadStrip
+ , DefinedAtom::ContentPermissions perms
+ , bool internalName
+ , bool isThumb
+ , bool isAlias
+ , DefinedAtom::Alignment alignment
+ , const char* name
+ , const char* sectionName
+ , uint64_t size
+ , std::vector<uint8_t>* content)
+ : _file(file)
+ , _name(name)
+ , _sectionName(sectionName)
+ , _size(size)
+ , _ord(ord)
+ , _content(content)
+ , _alignment(alignment)
+ , _scope(scope)
+ , _type(type)
+ , _sectionChoice(sectionChoice)
+ , _interpose(interpose)
+ , _merge(merge)
+ , _deadStrip(deadStrip)
+ , _permissions(perms)
+ , _internalName(internalName)
+ , _isThumb(isThumb)
+ , _isAlias(isAlias)
+ , _refStartIndex(file._lastRefIndex)
+ , _refEndIndex(file._references.size()) {
+ file._lastRefIndex = _refEndIndex;
}
virtual const class File& file() const {
return _file;
}
- virtual bool translationUnitSource(const char* *dir, const char* *name) const{
- return false;
- }
-
virtual llvm::StringRef name() const {
return _name;
}
+
+ virtual bool internalName() const {
+ return _internalName;
+ }
- virtual llvm::StringRef customSectionName() const {
- return (_sectionName ? _sectionName : llvm::StringRef());
+ virtual uint64_t size() const {
+ return (_content ? _content->size() : _size);
}
- virtual uint64_t objectAddress() const {
- return 0;
+ virtual DefinedAtom::Scope scope() const {
+ return _scope;
+ }
+
+ virtual DefinedAtom::Interposable interposable() const {
+ return _interpose;
+ }
+
+ virtual DefinedAtom::Merge merge() const {
+ return _merge;
}
- virtual uint64_t size() const {
- return (_content ? _content->size() : _size);
+ virtual DefinedAtom::ContentType contentType() const {
+ return _type;
+ }
+
+ virtual DefinedAtom::Alignment alignment() const {
+ return _alignment;
+ }
+
+ virtual DefinedAtom::SectionChoice sectionChoice() const {
+ return _sectionChoice;
}
- llvm::ArrayRef<uint8_t> rawContent() const {
+ virtual llvm::StringRef customSectionName() const {
+ return _sectionName;
+ }
+
+ virtual DefinedAtom::DeadStripKind deadStrip() const {
+ return _deadStrip;
+ }
+
+ virtual DefinedAtom::ContentPermissions permissions() const {
+ return _permissions;
+ }
+
+ virtual bool isThumb() const {
+ return _isThumb;
+ }
+
+ virtual bool isAlias() const {
+ return _isAlias;
+ }
+
+ llvm::ArrayRef<uint8_t> rawContent() const {
if ( _content != NULL )
return llvm::ArrayRef<uint8_t>(*_content);
else
return llvm::ArrayRef<uint8_t>();
}
+
+ virtual uint64_t ordinal() const {
+ return _ord;
+ }
+
+
+ virtual Reference::iterator referencesBegin() const {
+ if (_file._references.size() < _refStartIndex)
+ return (Reference::iterator)&_file._references[_refStartIndex];
+ return 0;
+ }
+
+ virtual Reference::iterator referencesEnd() const {
+ if (_file._references.size() < _refEndIndex)
+ return (Reference::iterator)&_file._references[_refEndIndex];
+ return 0;
+ }
- virtual Reference::iterator referencesBegin() const;
- virtual Reference::iterator referencesEnd() const;
private:
- YAMLFile& _file;
- const char * _name;
- const char * _sectionName;
- std::vector<uint8_t>* _content;
- unsigned long _size;
- unsigned int _refStartIndex;
- unsigned int _refEndIndex;
+ YAMLFile& _file;
+ const char * _name;
+ const char * _sectionName;
+ unsigned long _size;
+ uint32_t _ord;
+ std::vector<uint8_t>* _content;
+ DefinedAtom::Alignment _alignment;
+ DefinedAtom::Scope _scope;
+ DefinedAtom::ContentType _type;
+ DefinedAtom::SectionChoice _sectionChoice;
+ DefinedAtom::Interposable _interpose;
+ DefinedAtom::Merge _merge;
+ DefinedAtom::DeadStripKind _deadStrip;
+ DefinedAtom::ContentPermissions _permissions;
+ bool _internalName;
+ bool _isThumb;
+ bool _isAlias;
+ unsigned int _refStartIndex;
+ unsigned int _refEndIndex;
};
-Reference::iterator YAMLAtom::referencesBegin() const {
- if (_file._references.size() < _refStartIndex)
- return (Reference::iterator)&_file._references[_refStartIndex];
- return 0;
-}
-
-Reference::iterator YAMLAtom::referencesEnd() const {
- if (_file._references.size() < _refEndIndex)
- return (Reference::iterator)&_file._references[_refEndIndex];
- return 0;
-}
class YAMLAtomState {
public:
@@ -408,42 +472,46 @@ public:
void makeAtom(YAMLFile&);
- uint64_t _ordinal;
- long long _size;
- const char *_name;
- Atom::Alignment _align;
- Atom::ContentType _type;
- Atom::Scope _scope;
- Atom::Definition _def;
- Atom::SectionChoice _sectionChoice;
- bool _internalName;
- bool _mergeDuplicates;
- Atom::DeadStripKind _deadStrip;
- bool _thumb;
- bool _alias;
- bool _autoHide;
- const char *_sectionName;
- std::vector<uint8_t>* _content;
- Reference _ref;
+ const char * _name;
+ const char * _sectionName;
+ unsigned long long _size;
+ uint32_t _ordinal;
+ std::vector<uint8_t>* _content;
+ DefinedAtom::Alignment _alignment;
+ Atom::Definition _definition;
+ DefinedAtom::Scope _scope;
+ DefinedAtom::ContentType _type;
+ DefinedAtom::SectionChoice _sectionChoice;
+ DefinedAtom::Interposable _interpose;
+ DefinedAtom::Merge _merge;
+ DefinedAtom::DeadStripKind _deadStrip;
+ DefinedAtom::ContentPermissions _permissions;
+ bool _internalName;
+ bool _isThumb;
+ bool _isAlias;
+ Reference _ref;
};
+
YAMLAtomState::YAMLAtomState()
- : _ordinal(0)
+ : _name(NULL)
+ , _sectionName(NULL)
, _size(0)
- , _name(NULL)
- , _align(0, 0)
- , _type(KeyValues::contentTypeDefault)
+ , _ordinal(0)
+ , _content(NULL)
+ , _alignment(0, 0)
+ , _definition(KeyValues::definitionDefault)
, _scope(KeyValues::scopeDefault)
- , _def(KeyValues::definitionDefault)
+ , _type(KeyValues::contentTypeDefault)
, _sectionChoice(KeyValues::sectionChoiceDefault)
- , _internalName(KeyValues::internalNameDefault)
- , _mergeDuplicates(KeyValues::mergeDuplicatesDefault)
+ , _interpose(KeyValues::interposableDefault)
+ , _merge(KeyValues::mergeDefault)
, _deadStrip(KeyValues::deadStripKindDefault)
- , _thumb(KeyValues::isThumbDefault)
- , _alias(KeyValues::isAliasDefault)
- , _autoHide(KeyValues::autoHideDefault)
- , _sectionName(NULL)
- , _content(NULL) {
+ , _permissions(KeyValues::permissionsDefault)
+ , _internalName(KeyValues::internalNameDefault)
+ , _isThumb(KeyValues::isThumbDefault)
+ , _isAlias(KeyValues::isAliasDefault)
+ {
_ref.target = NULL;
_ref.addend = 0;
_ref.offsetInAtom = 0;
@@ -451,31 +519,36 @@ YAMLAtomState::YAMLAtomState()
_ref.flags = 0;
}
-void YAMLAtomState::makeAtom(YAMLFile& f) {
- Atom *a = new YAMLAtom(_ordinal, _def, _scope, _type, _sectionChoice,
- _internalName, _mergeDuplicates, _autoHide,
- _deadStrip, _thumb, _alias, _align, f,
- _name, _sectionName, _size, _content);
- f._atoms.push_back(a);
- ++_ordinal;
+void YAMLAtomState::makeAtom(YAMLFile& f) {
+ if ( _definition == Atom::definitionRegular ) {
+ DefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
+ _sectionChoice, _interpose, _merge, _deadStrip,
+ _permissions, _internalName, _isThumb, _isAlias,
+ _alignment, _name, _sectionName, _size, _content);
+
+ f._definedAtoms.push_back(a);
+ ++_ordinal;
+ }
// reset state for next atom
_name = NULL;
- _align.powerOf2 = 0;
- _align.modulus = 0;
- _type = KeyValues::contentTypeDefault;
+ _sectionName = NULL;
+ _size = 0;
+ _ordinal = 0;
+ _content = NULL;
+ _alignment.powerOf2= 0;
+ _alignment.modulus = 0;
+ _definition = KeyValues::definitionDefault;
_scope = KeyValues::scopeDefault;
- _def = KeyValues::definitionDefault;
+ _type = KeyValues::contentTypeDefault;
_sectionChoice = KeyValues::sectionChoiceDefault;
- _internalName = KeyValues::internalNameDefault;
- _mergeDuplicates = KeyValues::mergeDuplicatesDefault;
+ _interpose = KeyValues::interposableDefault;
+ _merge = KeyValues::mergeDefault;
_deadStrip = KeyValues::deadStripKindDefault;
- _thumb = KeyValues::isThumbDefault;
- _alias = KeyValues::isAliasDefault;
- _autoHide = KeyValues::autoHideDefault;
- _sectionName = NULL;
- _content = NULL;
+ _permissions = KeyValues::permissionsDefault;
+ _isThumb = KeyValues::isThumbDefault;
+ _isAlias = KeyValues::isAliasDefault;
_ref.target = NULL;
_ref.addend = 0;
_ref.offsetInAtom = 0;
@@ -492,7 +565,7 @@ void YAMLAtomState::setAlign2(const char *s) {
llvm::StringRef str(s);
uint32_t res;
str.getAsInteger(10, res);
- _align.powerOf2 = static_cast<uint16_t>(res);
+ _alignment.powerOf2 = static_cast<uint16_t>(res);
}
@@ -590,7 +663,7 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
- atomState._def = KeyValues::definition(entry->value);
+ atomState._definition = KeyValues::definition(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
@@ -609,20 +682,20 @@ llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, KeyValues::mergeDuplicatesKeyword) == 0) {
- atomState._mergeDuplicates = KeyValues::mergeDuplicates(entry->value);
+ else if (strcmp(entry->key, KeyValues::mergeKeyword) == 0) {
+ atomState._merge = KeyValues::merge(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, KeyValues::autoHideKeyword) == 0) {
- atomState._autoHide = KeyValues::autoHide(entry->value);
+ else if (strcmp(entry->key, KeyValues::interposableKeyword) == 0) {
+ atomState._interpose = KeyValues::interposable(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::isThumbKeyword) == 0) {
- atomState._thumb = KeyValues::isThumb(entry->value);
+ atomState._isThumb = KeyValues::isThumb(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
- atomState._alias = KeyValues::isAlias(entry->value);
+ atomState._isAlias = KeyValues::isAlias(entry->value);
haveAtom = true;
}
else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
diff --git a/lld/lib/Core/YamlWriter.cpp b/lld/lib/Core/YamlWriter.cpp
index 5b015825d11..3e30c0a4260 100644
--- a/lld/lib/Core/YamlWriter.cpp
+++ b/lld/lib/Core/YamlWriter.cpp
@@ -32,7 +32,7 @@ public:
virtual void doFile(const class File &) { _firstAtom = true; }
- virtual void doAtom(const class Atom &atom) {
+ virtual void doDefinedAtom(const class DefinedAtom &atom) {
// add blank line between atoms for readability
if ( !_firstAtom )
_out << "\n";
@@ -72,6 +72,24 @@ public:
<< "\n";
}
+ if ( atom.interposable() != KeyValues::interposableDefault ) {
+ _out << " "
+ << KeyValues::interposableKeyword
+ << ":"
+ << spacePadding(KeyValues::interposableKeyword)
+ << KeyValues::interposable(atom.interposable())
+ << "\n";
+ }
+
+ if ( atom.merge() != KeyValues::mergeDefault ) {
+ _out << " "
+ << KeyValues::mergeKeyword
+ << ":"
+ << spacePadding(KeyValues::mergeKeyword)
+ << KeyValues::merge(atom.merge())
+ << "\n";
+ }
+
if ( atom.contentType() != KeyValues::contentTypeDefault ) {
_out << " "
<< KeyValues::contentTypeKeyword
@@ -106,25 +124,7 @@ public:
<< "\n";
}
- if ( atom.mergeDuplicates() != KeyValues::mergeDuplicatesDefault ) {
- _out << " "
- << KeyValues::mergeDuplicatesKeyword
- << ":"
- << spacePadding(KeyValues::mergeDuplicatesKeyword)
- << KeyValues::mergeDuplicates(atom.mergeDuplicates())
- << "\n";
- }
-
- if ( atom.autoHide() != KeyValues::autoHideDefault ) {
- _out << " "
- << KeyValues::autoHideKeyword
- << ":"
- << spacePadding(KeyValues::autoHideKeyword)
- << KeyValues::autoHide(atom.autoHide())
- << "\n";
- }
-
- if ( atom.isThumb() != KeyValues::isThumbDefault ) {
+ if ( atom.isThumb() != KeyValues::isThumbDefault ) {
_out << " "
<< KeyValues::isThumbKeyword
<< ":"
@@ -142,8 +142,7 @@ public:
<< "\n";
}
-
- if ( atom.contentType() != Atom::typeZeroFill ) {
+ if ( atom.contentType() != DefinedAtom::typeZeroFill ) {
_out << " "
<< KeyValues::contentKeyword
<< ":"
@@ -172,6 +171,11 @@ public:
}
+ virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
+
+ }
+
+
private:
// return a string of the correct number of spaces to align value
const char* spacePadding(const char* key) {
OpenPOWER on IntegriCloud