summaryrefslogtreecommitdiffstats
path: root/lld
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2012-04-30 21:20:13 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2012-04-30 21:20:13 +0000
commitd0d5ec4a383f280219b1ee1fbf91275620472cf1 (patch)
tree1f09a70288785bf63c034c15b5c516fd1f87610c /lld
parent63d320064df163022654e4e421efe15aade98df4 (diff)
downloadbcm5719-llvm-d0d5ec4a383f280219b1ee1fbf91275620472cf1.tar.gz
bcm5719-llvm-d0d5ec4a383f280219b1ee1fbf91275620472cf1.zip
Convert the YAMLReader to use LLVM/Support/YAMLParser.
llvm-svn: 155847
Diffstat (limited to 'lld')
-rw-r--r--lld/include/lld/Core/YamlReader.h6
-rw-r--r--lld/lib/Core/YamlKeyValues.cpp67
-rw-r--r--lld/lib/Core/YamlKeyValues.h24
-rw-r--r--lld/lib/Core/YamlReader.cpp1122
-rw-r--r--lld/test/archive-basic.objtxt43
-rw-r--r--lld/test/archive-chain.objtxt90
-rw-r--r--lld/test/archive-tentdef-search.objtxt24
-rw-r--r--lld/tools/lld-core/lld-core.cpp6
8 files changed, 594 insertions, 788 deletions
diff --git a/lld/include/lld/Core/YamlReader.h b/lld/include/lld/Core/YamlReader.h
index 9287df02d18..5a6328c23d5 100644
--- a/lld/include/lld/Core/YamlReader.h
+++ b/lld/include/lld/Core/YamlReader.h
@@ -14,6 +14,7 @@
#include "llvm/Support/system_error.h"
+#include <memory>
#include <vector>
namespace llvm {
@@ -33,14 +34,15 @@ namespace yaml {
/// the specified vector<File*>.
error_code parseObjectTextFileOrSTDIN( StringRef path
, Platform&
- , std::vector<const File *>&);
+ , std::vector<
+ std::unique_ptr<const File>>&);
/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
/// into lld::File object(s) and append each to the specified vector<File*>.
error_code parseObjectText( llvm::MemoryBuffer *mb
, Platform&
- , std::vector<const File *>&);
+ , std::vector<std::unique_ptr<const File>>&);
} // namespace yaml
} // namespace lld
diff --git a/lld/lib/Core/YamlKeyValues.cpp b/lld/lib/Core/YamlKeyValues.cpp
index 19abf4ff12d..e21860ee199 100644
--- a/lld/lib/Core/YamlKeyValues.cpp
+++ b/lld/lib/Core/YamlKeyValues.cpp
@@ -73,9 +73,9 @@ static const FileKindMapping fileKindMappings[] = {
{ nullptr, File::kindObject }
};
- File::Kind KeyValues::fileKind(const char* str) {
+ File::Kind KeyValues::fileKind(StringRef str) {
for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, str) == 0 )
+ if (str == p->string)
return p->value;
}
llvm::report_fatal_error("bad file kind value");
@@ -103,10 +103,10 @@ static const DefinitionMapping defMappings[] = {
{ nullptr, Atom::definitionRegular }
};
-Atom::Definition KeyValues::definition(const char* s)
+Atom::Definition KeyValues::definition(StringRef s)
{
for (const DefinitionMapping* p = defMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad definition value");
@@ -136,10 +136,10 @@ static const ScopeMapping scopeMappings[] = {
{ nullptr, DefinedAtom::scopeGlobal }
};
-DefinedAtom::Scope KeyValues::scope(const char* s)
+DefinedAtom::Scope KeyValues::scope(StringRef s)
{
for (const ScopeMapping* p = scopeMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad scope value");
@@ -197,10 +197,10 @@ static const ContentTypeMapping typeMappings[] = {
{ nullptr, DefinedAtom::typeUnknown }
};
-DefinedAtom::ContentType KeyValues::contentType(const char* s)
+DefinedAtom::ContentType KeyValues::contentType(StringRef s)
{
for (const ContentTypeMapping* p = typeMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad content type value");
@@ -232,11 +232,11 @@ static const DeadStripMapping deadStripMappings[] = {
{ nullptr, DefinedAtom::deadStripNormal }
};
-DefinedAtom::DeadStripKind KeyValues::deadStripKind(const char* s)
+DefinedAtom::DeadStripKind KeyValues::deadStripKind(StringRef s)
{
for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p)
{
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad dead strip value");
@@ -267,10 +267,10 @@ static const InterposableMapping interMappings[] = {
{ nullptr, DefinedAtom::interposeNo }
};
-DefinedAtom::Interposable KeyValues::interposable(const char* s)
+DefinedAtom::Interposable KeyValues::interposable(StringRef s)
{
for (const InterposableMapping* p = interMappings; p->string != nullptr; ++p){
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad interposable value");
@@ -302,10 +302,10 @@ static const MergeMapping mergeMappings[] = {
{ nullptr, DefinedAtom::mergeNo }
};
-DefinedAtom::Merge KeyValues::merge(const char* s)
+DefinedAtom::Merge KeyValues::merge(StringRef s)
{
for (const MergeMapping* p = mergeMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad merge value");
@@ -336,10 +336,10 @@ static const SectionChoiceMapping sectMappings[] = {
{ nullptr, DefinedAtom::sectionBasedOnContent }
};
-DefinedAtom::SectionChoice KeyValues::sectionChoice(const char* s)
+DefinedAtom::SectionChoice KeyValues::sectionChoice(StringRef s)
{
for (const SectionChoiceMapping* p = sectMappings; p->string != nullptr; ++p){
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad dead strip value");
@@ -373,10 +373,10 @@ static const PermissionsMapping permMappings[] = {
{ nullptr, DefinedAtom::perm___ }
};
-DefinedAtom::ContentPermissions KeyValues::permissions(const char* s)
+DefinedAtom::ContentPermissions KeyValues::permissions(StringRef s)
{
for (const PermissionsMapping* p = permMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad permissions value");
@@ -390,37 +390,10 @@ const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
llvm::report_fatal_error("bad permissions value");
}
-
-
-
-
-
-
-bool KeyValues::isThumb(const char* s)
-{
- if ( strcmp(s, "true") == 0 )
- return true;
- else if ( strcmp(s, "false") == 0 )
- return false;
- llvm::report_fatal_error("bad is-thumb value");
-}
-
const char* KeyValues::isThumb(bool b) {
return b ? "true" : "false";
}
-
-
-
-bool KeyValues::isAlias(const char* s)
-{
- if ( strcmp(s, "true") == 0 )
- return true;
- else if ( strcmp(s, "false") == 0 )
- return false;
- llvm::report_fatal_error("bad is-alias value");
-}
-
const char* KeyValues::isAlias(bool b) {
return b ? "true" : "false";
}
@@ -441,10 +414,10 @@ static const CanBeNullMapping cbnMappings[] = {
};
-UndefinedAtom::CanBeNull KeyValues::canBeNull(const char* s)
+UndefinedAtom::CanBeNull KeyValues::canBeNull(StringRef s)
{
for (const CanBeNullMapping* p = cbnMappings; p->string != nullptr; ++p) {
- if ( strcmp(p->string, s) == 0 )
+ if (s == p->string)
return p->value;
}
llvm::report_fatal_error("bad can-be-null value");
diff --git a/lld/lib/Core/YamlKeyValues.h b/lld/lib/Core/YamlKeyValues.h
index 2265c5f5596..18c8e469b5a 100644
--- a/lld/lib/Core/YamlKeyValues.h
+++ b/lld/lib/Core/YamlKeyValues.h
@@ -15,7 +15,6 @@
#include "lld/Core/UndefinedAtom.h"
#include "lld/Core/File.h"
-
namespace lld {
namespace yaml {
@@ -34,62 +33,60 @@ public:
static const char* const fileKindKeyword;
static const File::Kind fileKindDefault;
- static File::Kind fileKind(const char*);
+ static File::Kind fileKind(StringRef);
static const char* fileKind(File::Kind);
static const char* const definitionKeyword;
static const Atom::Definition definitionDefault;
- static Atom::Definition definition(const char*);
+ static Atom::Definition definition(StringRef);
static const char* definition(Atom::Definition);
static const char* const scopeKeyword;
static const DefinedAtom::Scope scopeDefault;
- static DefinedAtom::Scope scope(const char*);
+ static DefinedAtom::Scope scope(StringRef);
static const char* scope(DefinedAtom::Scope);
static const char* const contentTypeKeyword;
static const DefinedAtom::ContentType contentTypeDefault;
- static DefinedAtom::ContentType contentType(const char*);
+ static DefinedAtom::ContentType contentType(StringRef);
static const char* contentType(DefinedAtom::ContentType);
static const char* const deadStripKindKeyword;
static const DefinedAtom::DeadStripKind deadStripKindDefault;
- static DefinedAtom::DeadStripKind deadStripKind(const char*);
+ static DefinedAtom::DeadStripKind deadStripKind(StringRef);
static const char* deadStripKind(DefinedAtom::DeadStripKind);
static const char* const sectionChoiceKeyword;
static const DefinedAtom::SectionChoice sectionChoiceDefault;
- static DefinedAtom::SectionChoice sectionChoice(const char*);
+ static DefinedAtom::SectionChoice sectionChoice(StringRef);
static const char* sectionChoice(DefinedAtom::SectionChoice);
static const char* const interposableKeyword;
static const DefinedAtom::Interposable interposableDefault;
- static DefinedAtom::Interposable interposable(const char*);
+ static DefinedAtom::Interposable interposable(StringRef);
static const char* interposable(DefinedAtom::Interposable);
static const char* const mergeKeyword;
static const DefinedAtom::Merge mergeDefault;
- static DefinedAtom::Merge merge(const char*);
+ static DefinedAtom::Merge merge(StringRef);
static const char* merge(DefinedAtom::Merge);
static const char* const permissionsKeyword;
static const DefinedAtom::ContentPermissions permissionsDefault;
- static DefinedAtom::ContentPermissions permissions(const char*);
+ static DefinedAtom::ContentPermissions permissions(StringRef);
static const char* permissions(DefinedAtom::ContentPermissions);
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 canBeNullKeyword;
static const UndefinedAtom::CanBeNull canBeNullDefault;
- static UndefinedAtom::CanBeNull canBeNull(const char*);
+ static UndefinedAtom::CanBeNull canBeNull(StringRef);
static const char* canBeNull(UndefinedAtom::CanBeNull);
@@ -104,4 +101,3 @@ public:
} // namespace lld
#endif // LLD_CORE_YAML_KEY_VALUES_H_
-
diff --git a/lld/lib/Core/YamlReader.cpp b/lld/lib/Core/YamlReader.cpp
index 5069ef206ce..6641f2f6b20 100644
--- a/lld/lib/Core/YamlReader.cpp
+++ b/lld/lib/Core/YamlReader.cpp
@@ -24,244 +24,54 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/system_error.h"
+#include "llvm/Support/YAMLParser.h"
#include <cstring>
-#include <vector>
#include <set>
+#include <type_traits>
+#include <vector>
+using namespace lld;
+
+static bool getAs(const llvm::yaml::ScalarNode *SN, bool &Result) {
+ SmallString<4> Storage;
+ StringRef Value = SN->getValue(Storage);
+ if (Value == "true")
+ Result = true;
+ else if (Value == "false")
+ Result = false;
+ else
+ return false;
+ return true;
+}
+template<class T>
+typename std::enable_if<std::numeric_limits<T>::is_integer, bool>::type
+getAs(const llvm::yaml::ScalarNode *SN, T &Result) {
+ SmallString<4> Storage;
+ StringRef Value = SN->getValue(Storage);
+ if (Value.getAsInteger(0, Result))
+ return false;
+ return true;
+}
namespace lld {
namespace yaml {
-namespace {
-
-class YAML {
-public:
- struct Entry {
- Entry(const char *k, const char *v, std::vector<uint8_t>* vs,
- int d, bool bd, bool bs)
- : key(strdup(k))
- , value(v ? strdup(v) : nullptr)
- , valueSequenceBytes(vs)
- , depth(d)
- , beginSequence(bs)
- , beginDocument(bd) {}
-
- const char * key;
- const char * value;
- std::vector<uint8_t>* valueSequenceBytes;
- int depth;
- bool beginSequence;
- bool beginDocument;
- };
-
- static void parse(llvm::MemoryBuffer *mb, std::vector<const Entry *>&);
-
-private:
- enum State {
- start,
- inHeaderComment,
- inTripleDash,
- inTriplePeriod,
- inDocument,
- inKey,
- inSpaceBeforeValue,
- inValue,
- inValueSequence,
- inValueSequenceEnd
- };
-};
-
-
-void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
- State state = start;
- char key[64];
- char value[64];
- char *p = nullptr;
- unsigned int lineNumber = 1;
- int depth = 0;
- bool nextKeyIsStartOfDocument = false;
- bool nextKeyIsStartOfSequence = false;
- std::vector<uint8_t>* sequenceBytes = nullptr;
- unsigned contentByte = 0;
- for (const char *s = mb->getBufferStart(); s < mb->getBufferEnd(); ++s) {
- char c = *s;
- if (c == '\n')
- ++lineNumber;
- switch (state) {
- case start:
- if (c == '#')
- state = inHeaderComment;
- else if (c == '-') {
- p = &key[0];
- *p++ = c;
- state = inTripleDash;
- }
- break;
- case inHeaderComment:
- if (c == '\n') {
- state = start;
- }
- break;
- case inTripleDash:
- if (c == '-') {
- *p++ = c;
- } else if (c == '\n') {
- *p = '\0';
- if (strcmp(key, "---") != 0)
- return;
- depth = 0;
- state = inDocument;
- nextKeyIsStartOfDocument = true;
- } else {
- return;
- }
- break;
- case inTriplePeriod:
- if (c == '.') {
- *p++ = c;
- } else if (c == '\n') {
- *p = '\0';
- if (strcmp(key, "...") != 0)
- return;
- depth = 0;
- state = inHeaderComment;
- } else {
- return;
- }
- break;
- case inDocument:
- if (isalnum(c)) {
- state = inKey;
- p = &key[0];
- *p++ = c;
- } else if (c == '-') {
- if (depth == 0) {
- p = &key[0];
- *p++ = c;
- state = inTripleDash;
- } else {
- nextKeyIsStartOfSequence = true;
- ++depth;
- }
- } else if (c == ' ') {
- ++depth;
- } else if (c == '.') {
- p = &key[0];
- *p++ = c;
- state = inTriplePeriod;
- } else if (c == '\n') {
- // ignore empty lines
- depth = 0;
- } else if (c == '\t') {
- llvm::report_fatal_error("TAB character found in yaml file");
- } else {
- return;
- }
- break;
- case inKey:
- if (isalnum(c) || (c == '-')) {
- *p++ = c;
- } else if (c == ':') {
- *p = '\0';
- state = inSpaceBeforeValue;
- } else if (c == '\n') {
- *p = '\0';
- if (strcmp(key, "---") == 0)
- state = inDocument;
- else
- return;
- } else {
- return;
- }
- break;
- case inSpaceBeforeValue:
- if (isalnum(c) || (c == '-') || (c == '_') || (c == '/')) {
- p = &value[0];
- *p++ = c;
- state = inValue;
- } else if (c == '\n') {
- entries.push_back(new Entry(key, "", nullptr, depth,
- nextKeyIsStartOfDocument,
- nextKeyIsStartOfSequence));
- nextKeyIsStartOfSequence = false;
- nextKeyIsStartOfDocument = false;
- state = inDocument;
- depth = 0;
- } else if (c == '[') {
- contentByte = 0;
- sequenceBytes = new std::vector<uint8_t>();
- state = inValueSequence;
- } else if (c == ' ') {
- // eat space
- } else if (c == '\t') {
- llvm::report_fatal_error("TAB character found in yaml file");
- } else {
- return;
- }
- break;
- case inValue:
- if (c == '\n') {
- *p = '\0';
- entries.push_back(new Entry(key, value, nullptr, depth,
- nextKeyIsStartOfDocument,
- nextKeyIsStartOfSequence));
- nextKeyIsStartOfSequence = false;
- nextKeyIsStartOfDocument = false;
- state = inDocument;
- depth = 0;
- }
- else {
- *p++ = c;
- }
- break;
- case inValueSequence:
- if (c == ']') {
- sequenceBytes->push_back(contentByte);
- state = inValueSequenceEnd;
- }
- else if ( (c == ' ') || (c == '\n') ) {
- // eat white space
- }
- else if (c == ',') {
- sequenceBytes->push_back(contentByte);
- }
- else if ( isdigit(c) ) {
- contentByte = (contentByte << 4) | (c-'0');
- }
- else if ( ('a' <= tolower(c)) && (tolower(c) <= 'f') ) {
- contentByte = (contentByte << 4) | (tolower(c)-'a'+10);
- }
- else {
- llvm::report_fatal_error("non-hex digit found in content [ ]");
- }
- break;
- case inValueSequenceEnd:
- if (c == '\n') {
- entries.push_back(new Entry(key, nullptr, sequenceBytes, depth,
- nextKeyIsStartOfDocument,
- nextKeyIsStartOfSequence));
- nextKeyIsStartOfSequence = false;
- nextKeyIsStartOfDocument = false;
- state = inDocument;
- depth = 0;
- }
- break;
- }
- }
-}
-
-
-
class YAMLReference : public Reference {
public:
- YAMLReference() : _target(nullptr), _targetName(nullptr),
- _offsetInAtom(0), _addend(0), _kind(0) { }
+ YAMLReference()
+ : _target(nullptr)
+ , _offsetInAtom(0)
+ , _addend(0)
+ , _kind(0)
+ {}
virtual uint64_t offsetInAtom() const {
return _offsetInAtom;
@@ -275,7 +85,7 @@ public:
_kind = k;
}
- virtual const Atom* target() const {
+ virtual const Atom *target() const {
return _target;
}
@@ -287,19 +97,17 @@ public:
_addend = a;
}
- virtual void setTarget(const Atom* newAtom) {
+ virtual void setTarget(const Atom *newAtom) {
_target = newAtom;
}
- const Atom* _target;
- const char* _targetName;
- uint64_t _offsetInAtom;
- Addend _addend;
- Kind _kind;
+ const Atom *_target;
+ StringRef _targetName;
+ uint64_t _offsetInAtom;
+ Addend _addend;
+ Kind _kind;
};
-
-
class YAMLDefinedAtom;
class YAMLFile : public ArchiveLibraryFile {
@@ -315,16 +123,16 @@ public:
return _kind;
}
- virtual const atom_collection<DefinedAtom>& defined() const {
+ virtual const atom_collection<DefinedAtom> &defined() const {
return _definedAtoms;
}
- virtual const atom_collection<UndefinedAtom>& undefined() const {
+ virtual const atom_collection<UndefinedAtom> &undefined() const {
return _undefinedAtoms;
}
- virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
+ virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
return _sharedLibraryAtoms;
}
- virtual const atom_collection<AbsoluteAtom>& absolute() const {
+ virtual const atom_collection<AbsoluteAtom> &absolute() const {
return _absoluteAtoms;
}
@@ -335,39 +143,37 @@ public:
virtual const File *find(StringRef name, bool dataSymbolOnly) const;
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);
- void addMember(const char*);
- void setName(const char*);
+ void addDefinedAtom(YAMLDefinedAtom *atom, StringRef refName);
+ void addUndefinedAtom(UndefinedAtom *atom);
+ void addSharedLibraryAtom(SharedLibraryAtom *atom);
+ void addAbsoluteAtom(AbsoluteAtom *atom);
+ Atom *findAtom(StringRef name);
+ void addMember(StringRef);
+ void setName(StringRef);
struct NameAtomPair {
- NameAtomPair(const char* n, Atom* a) : name(n), atom(a) {}
- const char* name;
- Atom* atom;
+ NameAtomPair(StringRef n, Atom *a) : name(n), atom(a) {}
+ StringRef name;
+ Atom *atom;
};
- atom_collection_vector<DefinedAtom> _definedAtoms;
- atom_collection_vector<UndefinedAtom> _undefinedAtoms;
- atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
- atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
- std::vector<YAMLReference> _references;
- std::vector<NameAtomPair> _nameToAtomMapping;
- std::vector<const char*> _memberNames;
- std::vector<YAMLFile*> _memberFiles;
- unsigned int _lastRefIndex;
- File::Kind _kind;
- bool _inArchive;
+ atom_collection_vector<DefinedAtom> _definedAtoms;
+ atom_collection_vector<UndefinedAtom> _undefinedAtoms;
+ atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
+ atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
+ std::vector<YAMLReference> _references;
+ std::vector<NameAtomPair> _nameToAtomMapping;
+ std::vector<StringRef> _memberNames;
+ std::vector<std::unique_ptr<YAMLFile>> _memberFiles;
+ unsigned int _lastRefIndex;
+ File::Kind _kind;
+ bool _inArchive;
};
-
-
class YAMLDefinedAtom : public DefinedAtom {
public:
YAMLDefinedAtom( uint32_t ord
- , YAMLFile& file
+ , YAMLFile &file
, DefinedAtom::Scope scope
, DefinedAtom::ContentType type
, DefinedAtom::SectionChoice sectionChoice
@@ -378,16 +184,16 @@ public:
, bool isThumb
, bool isAlias
, DefinedAtom::Alignment alignment
- , const char* name
- , const char* sectionName
+ , StringRef name
+ , StringRef sectionName
, uint64_t size
- , std::vector<uint8_t>* content)
+ , std::vector<uint8_t> content)
: _file(file)
, _name(name)
, _sectionName(sectionName)
, _size(size)
, _ord(ord)
- , _content(content)
+ , _content(std::move(content))
, _alignment(alignment)
, _scope(scope)
, _type(type)
@@ -403,19 +209,16 @@ public:
file._lastRefIndex = _refEndIndex;
}
- virtual const class File& file() const {
+ virtual const class File &file() const {
return _file;
}
virtual StringRef name() const {
- if (_name == nullptr)
- return StringRef();
- else
- return _name;
+ return _name;
}
- virtual uint64_t size() const {
- return (_content ? _content->size() : _size);
+ virtual uint64_t size() const {
+ return _content.empty() ? _size : _content.size();
}
virtual DefinedAtom::Scope scope() const {
@@ -462,11 +265,8 @@ public:
return _isAlias;
}
- ArrayRef<uint8_t> rawContent() const {
- if (_content != nullptr)
- return ArrayRef<uint8_t>(*_content);
- else
- return ArrayRef<uint8_t>();
+ ArrayRef<uint8_t> rawContent() const {
+ return ArrayRef<uint8_t>(_content);
}
virtual uint64_t ordinal() const {
@@ -499,23 +299,21 @@ public:
it = reinterpret_cast<const void*>(index);
}
-
-
void bindTargetReferences() const {
for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
- const char* targetName = _file._references[i]._targetName;
- Atom* targetAtom = _file.findAtom(targetName);
+ StringRef targetName = _file._references[i]._targetName;
+ Atom *targetAtom = _file.findAtom(targetName);
_file._references[i]._target = targetAtom;
}
}
private:
- YAMLFile& _file;
- const char * _name;
- const char * _sectionName;
+ YAMLFile &_file;
+ StringRef _name;
+ StringRef _sectionName;
unsigned long _size;
uint32_t _ord;
- std::vector<uint8_t>* _content;
+ std::vector<uint8_t> _content;
DefinedAtom::Alignment _alignment;
DefinedAtom::Scope _scope;
DefinedAtom::ContentType _type;
@@ -530,14 +328,19 @@ private:
unsigned int _refEndIndex;
};
-
class YAMLUndefinedAtom : public UndefinedAtom {
public:
- YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm,
- UndefinedAtom::CanBeNull cbn)
- : _file(f), _name(nm), _ordinal(ord), _canBeNull(cbn) { }
+ YAMLUndefinedAtom( YAMLFile &f
+ , int32_t ord
+ , StringRef name
+ , UndefinedAtom::CanBeNull cbn)
+ : _file(f)
+ , _name(name)
+ , _ordinal(ord)
+ , _canBeNull(cbn) {
+ }
- virtual const class File& file() const {
+ virtual const class File &file() const {
return _file;
}
@@ -549,24 +352,28 @@ public:
return _canBeNull;
}
-
private:
- YAMLFile& _file;
- const char * _name;
- uint32_t _ordinal;
- UndefinedAtom::CanBeNull _canBeNull;
+ YAMLFile &_file;
+ StringRef _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) { }
+ YAMLSharedLibraryAtom( YAMLFile &f
+ , int32_t ord
+ , StringRef name
+ , StringRef loadName
+ , bool cbn)
+ : _file(f)
+ , _name(name)
+ , _ordinal(ord)
+ , _loadName(loadName)
+ , _canBeNull(cbn) {
+ }
- virtual const class File& file() const {
+ virtual const class File &file() const {
return _file;
}
@@ -575,33 +382,31 @@ public:
}
virtual StringRef loadName() const {
- if ( _loadName == nullptr )
- return StringRef();
- else
- return StringRef(_loadName);
+ return _loadName;
}
virtual bool canBeNullAtRuntime() const {
return _canBeNull;
}
-
private:
- YAMLFile& _file;
- const char * _name;
- uint32_t _ordinal;
- const char * _loadName;
- bool _canBeNull;
+ YAMLFile &_file;
+ StringRef _name;
+ uint32_t _ordinal;
+ StringRef _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) { }
+ YAMLAbsoluteAtom(YAMLFile &f, int32_t ord, StringRef name, uint64_t v)
+ : _file(f)
+ , _name(name)
+ , _ordinal(ord)
+ , _value(v) {
+ }
- virtual const class File& file() const {
+ virtual const class File &file() const {
return _file;
}
@@ -614,95 +419,89 @@ public:
}
private:
- YAMLFile& _file;
- const char * _name;
- uint32_t _ordinal;
- uint64_t _value;
+ YAMLFile &_file;
+ StringRef _name;
+ uint32_t _ordinal;
+ uint64_t _value;
};
-
-
void YAMLFile::bindTargetReferences() {
- for (const DefinedAtom *defAtom : _definedAtoms) {
- const YAMLDefinedAtom* atom =
- reinterpret_cast<const YAMLDefinedAtom*>(defAtom);
- atom->bindTargetReferences();
- }
+ for (const DefinedAtom *defAtom : _definedAtoms) {
+ const YAMLDefinedAtom *atom =
+ reinterpret_cast<const YAMLDefinedAtom*>(defAtom);
+ atom->bindTargetReferences();
+ }
}
-Atom* YAMLFile::findAtom(const char* name) {
- for (std::vector<NameAtomPair>::const_iterator it = _nameToAtomMapping.begin();
- it != _nameToAtomMapping.end(); ++it) {
- if ( strcmp(name, it->name) == 0 )
- return it->atom;
+Atom *YAMLFile::findAtom(StringRef name) {
+ for (auto &ci : _nameToAtomMapping) {
+ if (ci.name == name)
+ return ci.atom;
}
llvm::report_fatal_error("reference to atom that does not exist");
}
-void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName) {
+void YAMLFile::addDefinedAtom(YAMLDefinedAtom *atom, StringRef refName) {
_definedAtoms._atoms.push_back(atom);
- assert(refName != nullptr);
_nameToAtomMapping.push_back(NameAtomPair(refName, atom));
}
-void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
+void YAMLFile::addUndefinedAtom(UndefinedAtom *atom) {
_undefinedAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
+ _nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
}
-void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom* atom) {
+void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom *atom) {
_sharedLibraryAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
+ _nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
}
-void YAMLFile::addAbsoluteAtom(AbsoluteAtom* atom) {
+void YAMLFile::addAbsoluteAtom(AbsoluteAtom *atom) {
_absoluteAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
+ _nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
}
-void YAMLFile::addMember(const char* name) {
+void YAMLFile::addMember(StringRef name) {
_memberNames.push_back(name);
}
-void YAMLFile::setName(const char* name) {
+void YAMLFile::setName(StringRef name) {
_path = StringRef(name);
}
const File *YAMLFile::find(StringRef name, bool dataSymbolOnly) const {
- for (YAMLFile *file : _memberFiles) {
+ for (auto &file : _memberFiles) {
for (const DefinedAtom *atom : file->defined() ) {
- if ( name.equals(atom->name()) )
- return file;
+ if (name == atom->name())
+ return file.get();
}
}
- return NULL;
+ return nullptr;
}
-
-
class YAMLAtomState {
public:
- YAMLAtomState(Platform& platform);
+ YAMLAtomState(Platform &platform);
- void setName(const char *n);
- void setRefName(const char *n);
- void setAlign2(const char *n);
+ void setName(StringRef n);
+ void setRefName(StringRef n);
+ void setAlign2(StringRef n);
- void setFixupKind(const char *n);
- void setFixupTarget(const char *n);
+ void setFixupKind(StringRef n);
+ void setFixupTarget(StringRef n);
void addFixup(YAMLFile *f);
void makeAtom(YAMLFile&);
- Platform& _platform;
- const char * _name;
- const char * _refName;
- const char * _sectionName;
- const char* _loadName;
+ Platform &_platform;
+ StringRef _name;
+ StringRef _refName;
+ StringRef _sectionName;
+ StringRef _loadName;
unsigned long long _size;
uint64_t _value;
uint32_t _ordinal;
- std::vector<uint8_t>* _content;
+ std::vector<uint8_t> _content;
DefinedAtom::Alignment _alignment;
Atom::Definition _definition;
DefinedAtom::Scope _scope;
@@ -719,16 +518,11 @@ public:
};
-YAMLAtomState::YAMLAtomState(Platform& platform)
+YAMLAtomState::YAMLAtomState(Platform &platform)
: _platform(platform)
- , _name(nullptr)
- , _refName(nullptr)
- , _sectionName(nullptr)
- , _loadName(nullptr)
, _size(0)
, _value(0)
, _ordinal(0)
- , _content(nullptr)
, _alignment(0, 0)
, _definition(KeyValues::definitionDefault)
, _scope(KeyValues::scopeDefault)
@@ -740,357 +534,415 @@ YAMLAtomState::YAMLAtomState(Platform& platform)
, _permissions(KeyValues::permissionsDefault)
, _isThumb(KeyValues::isThumbDefault)
, _isAlias(KeyValues::isAliasDefault)
- , _canBeNull(KeyValues::canBeNullDefault)
- {
- }
-
+ , _canBeNull(KeyValues::canBeNullDefault) {
+}
-void YAMLAtomState::makeAtom(YAMLFile& f) {
- if ( _definition == Atom::definitionRegular ) {
- YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
- _sectionChoice, _interpose, _merge, _deadStrip,
- _permissions, _isThumb, _isAlias,
- _alignment, _name, _sectionName, _size, _content);
- f.addDefinedAtom(a, _refName ? _refName : _name);
+void YAMLAtomState::makeAtom(YAMLFile &f) {
+ if (_definition == Atom::definitionRegular) {
+ YAMLDefinedAtom *a =
+ new YAMLDefinedAtom( _ordinal
+ , f
+ , _scope
+ , _type
+ , _sectionChoice
+ , _interpose
+ , _merge
+ , _deadStrip
+ , _permissions
+ , _isThumb
+ , _isAlias
+ , _alignment
+ , _name
+ , _sectionName
+ , _size
+ , _content
+ );
+ f.addDefinedAtom(a, !_refName.empty() ? _refName : _name);
++_ordinal;
- }
- else if ( _definition == Atom::definitionUndefined ) {
+ } else if (_definition == Atom::definitionUndefined) {
UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _canBeNull);
f.addUndefinedAtom(a);
++_ordinal;
- }
- else if ( _definition == Atom::definitionSharedLibrary ) {
+ } 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 ) {
+ } else if (_definition == Atom::definitionAbsolute) {
AbsoluteAtom *a = new YAMLAbsoluteAtom(f, _ordinal, _name, _value);
f.addAbsoluteAtom(a);
++_ordinal;
}
// reset state for next atom
- _name = nullptr;
- _refName = nullptr;
- _sectionName = nullptr;
- _loadName = nullptr;
- _size = 0;
- _value = 0;
- _ordinal = 0;
- _content = nullptr;
- _alignment.powerOf2= 0;
- _alignment.modulus = 0;
- _definition = KeyValues::definitionDefault;
- _scope = KeyValues::scopeDefault;
- _type = KeyValues::contentTypeDefault;
- _sectionChoice = KeyValues::sectionChoiceDefault;
- _interpose = KeyValues::interposableDefault;
- _merge = KeyValues::mergeDefault;
- _deadStrip = KeyValues::deadStripKindDefault;
- _permissions = KeyValues::permissionsDefault;
- _isThumb = KeyValues::isThumbDefault;
- _isAlias = KeyValues::isAliasDefault;
- _canBeNull = KeyValues::canBeNullDefault;
- _ref._target = nullptr;
- _ref._targetName = nullptr;
- _ref._addend = 0;
- _ref._offsetInAtom = 0;
- _ref._kind = 0;
+ _name = StringRef();
+ _refName = StringRef();
+ _sectionName = StringRef();
+ _loadName = StringRef();
+ _size = 0;
+ _value = 0;
+ _ordinal = 0;
+ _content.clear();
+ _alignment.powerOf2 = 0;
+ _alignment.modulus = 0;
+ _definition = KeyValues::definitionDefault;
+ _scope = KeyValues::scopeDefault;
+ _type = KeyValues::contentTypeDefault;
+ _sectionChoice = KeyValues::sectionChoiceDefault;
+ _interpose = KeyValues::interposableDefault;
+ _merge = KeyValues::mergeDefault;
+ _deadStrip = KeyValues::deadStripKindDefault;
+ _permissions = KeyValues::permissionsDefault;
+ _isThumb = KeyValues::isThumbDefault;
+ _isAlias = KeyValues::isAliasDefault;
+ _canBeNull = KeyValues::canBeNullDefault;
+ _ref._target = nullptr;
+ _ref._targetName = StringRef();
+ _ref._addend = 0;
+ _ref._offsetInAtom = 0;
+ _ref._kind = 0;
}
-void YAMLAtomState::setName(const char *n) {
+void YAMLAtomState::setName(StringRef n) {
_name = n;
}
-void YAMLAtomState::setRefName(const char *n) {
+void YAMLAtomState::setRefName(StringRef n) {
_refName = n;
}
-void YAMLAtomState::setAlign2(const char *s) {
+void YAMLAtomState::setAlign2(StringRef s) {
if (StringRef(s).getAsInteger(10, _alignment.powerOf2))
_alignment.powerOf2 = 1;
}
-void YAMLAtomState::setFixupKind(const char *s) {
+void YAMLAtomState::setFixupKind(StringRef s) {
_ref._kind = _platform.kindFromString(StringRef(s));
}
-void YAMLAtomState::setFixupTarget(const char *s) {
+void YAMLAtomState::setFixupTarget(StringRef s) {
_ref._targetName = s;
}
-
void YAMLAtomState::addFixup(YAMLFile *f) {
f->_references.push_back(_ref);
// clear for next ref
_ref._target = nullptr;
- _ref._targetName = nullptr;
+ _ref._targetName = StringRef();
_ref._addend = 0;
_ref._offsetInAtom = 0;
_ref._kind = 0;
}
-
-} // anonymous namespace
-
-
-
-
-
-/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
-/// into lld::File object(s) and append each to the specified vector<File*>.
-error_code parseObjectText( llvm::MemoryBuffer *mb
- , Platform& platform
- , std::vector<const File *> &result) {
- std::vector<const YAML::Entry *> entries;
- std::vector<YAMLFile*> allFiles;
- YAML::parse(mb, entries);
-
- YAMLFile *file = nullptr;
- YAMLAtomState atomState(platform);
- bool inAtoms = false;
- bool inFixups = false;
- bool inMembers = false;
- int depthForAtoms = -1;
- int depthForFixups = -1;
- int depthForMembers= -1;
- int lastDepth = -1;
- bool haveAtom = false;
- bool haveFixup = false;
- bool hasArchives = false;
-
- for (std::vector<const YAML::Entry *>::iterator it = entries.begin();
- it != entries.end(); ++it) {
- const YAML::Entry *entry = *it;
-
- if (entry->beginDocument) {
- if (file != nullptr) {
- if (haveAtom) {
- atomState.makeAtom(*file);
- haveAtom = false;
- }
- file->bindTargetReferences();
- allFiles.push_back(file);
- }
- file = new YAMLFile();
- inAtoms = false;
- depthForAtoms = -1;
+llvm::error_code parseFixup( llvm::yaml::MappingNode *mn
+ , llvm::yaml::Stream &s
+ , Platform &p
+ , YAMLFile &f
+ , YAMLAtomState &yas) {
+ using namespace llvm::yaml;
+ llvm::SmallString<32> storage;
+
+ for (auto &keyval : *mn) {
+ ScalarNode *key = llvm::dyn_cast<ScalarNode>(keyval.getKey());
+ if (!key) {
+ s.printError(key, "Expected a scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
}
- if (lastDepth > entry->depth) {
- // end of fixup sequence
- if (haveFixup) {
- atomState.addFixup(file);
- haveFixup = false;
+ ScalarNode *value = llvm::dyn_cast<ScalarNode>(keyval.getValue());
+ if (!value) {
+ s.printError(value, "Expected a scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ llvm::StringRef keyValue = key->getValue(storage);
+ if (keyValue == KeyValues::fixupsOffsetKeyword) {
+ if (!getAs(value, yas._ref._offsetInAtom)) {
+ s.printError(value, "Invalid value for offset");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ } else if (keyValue == KeyValues::fixupsKindKeyword) {
+ yas._ref._kind = p.kindFromString(value->getValue(storage));
+ } else if (keyValue == KeyValues::fixupsTargetKeyword) {
+ // FIXME: string lifetime.
+ yas._ref._targetName = value->getValue(storage);
+ } else if (keyValue == KeyValues::fixupsAddendKeyword) {
+ if (!getAs(value, yas._ref._addend)) {
+ s.printError(value, "Invalid value for addend");
+ return make_error_code(yaml_reader_error::illegal_value);
}
+ } else {
+ s.printError(key, "Unrecognized key");
+ return make_error_code(yaml_reader_error::unknown_keyword);
}
+ }
+ yas.addFixup(&f);
+ return make_error_code(yaml_reader_error::success);
+}
- if (inAtoms && (depthForAtoms == -1)) {
- depthForAtoms = entry->depth;
- }
- if (inFixups && (depthForFixups == -1)) {
- depthForFixups = entry->depth;
- }
- if (inMembers && (depthForMembers == -1)) {
- depthForMembers = entry->depth;
- }
- if ( !inFixups && (strcmp(entry->key, KeyValues::fileKindKeyword) == 0) ) {
- file->_kind = KeyValues::fileKind(entry->value);
- if ( file->_kind == File::kindArchiveLibrary )
- hasArchives = true;
- }
- else if (strcmp(entry->key, KeyValues::fileMembersKeyword) == 0) {
- inMembers = true;
- }
- else if (strcmp(entry->key, KeyValues::fileAtomsKeyword) == 0) {
- inAtoms = true;
- }
- else if ( !inAtoms && !inMembers
- && (strcmp(entry->key, KeyValues::nameKeyword) == 0) ) {
- file->setName(entry->value);
- }
- if (inAtoms) {
- if (depthForAtoms == entry->depth) {
- if (entry->beginSequence) {
- if (haveAtom) {
- atomState.makeAtom(*file);
- haveAtom = false;
- }
- }
- if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
- atomState.setName(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::refNameKeyword) == 0) {
- atomState.setRefName(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
- atomState._definition = KeyValues::definition(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
- atomState._scope = KeyValues::scope(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::contentTypeKeyword) == 0) {
- atomState._type = KeyValues::contentType(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::deadStripKindKeyword) == 0) {
- atomState._deadStrip = KeyValues::deadStripKind(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::sectionChoiceKeyword) == 0) {
- atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::mergeKeyword) == 0) {
- atomState._merge = KeyValues::merge(entry->value);
- haveAtom = true;
- }
- 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._isThumb = KeyValues::isThumb(entry->value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
- atomState._isAlias = KeyValues::isAlias(entry->value);
- haveAtom = true;
+llvm::error_code parseAtom( llvm::yaml::MappingNode *mn
+ , llvm::yaml::Stream &s
+ , Platform &p
+ , YAMLFile &f) {
+ using namespace llvm::yaml;
+ YAMLAtomState yas(p);
+ llvm::SmallString<32> storage;
+
+ for (MappingNode::iterator i = mn->begin(), e = mn->end(); i != e; ++i) {
+ ScalarNode *Key = llvm::dyn_cast<ScalarNode>(i->getKey());
+ if (!Key)
+ return make_error_code(yaml_reader_error::illegal_value);
+ llvm::StringRef KeyValue = Key->getValue(storage);
+ if (KeyValue == KeyValues::contentKeyword) {
+ ScalarNode *scalarValue = llvm::dyn_cast<ScalarNode>(i->getValue());
+ if (scalarValue) {
+ yas._type = KeyValues::contentType(scalarValue->getValue(storage));
+ } else {
+ SequenceNode *Value = llvm::dyn_cast<SequenceNode>(i->getValue());
+ if (!Value) {
+ s.printError(i->getValue(), "Expected a sequence");
+ return make_error_code(yaml_reader_error::illegal_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);
+ for (SequenceNode::iterator ci = Value->begin(), ce = Value->end();
+ ci != ce; ++ci) {
+ ScalarNode *Entry = llvm::dyn_cast<ScalarNode>(&*ci);
+ if (!Entry) {
+ s.printError(i->getValue(), "Expected a scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
}
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
- atomState._sectionName = entry->value;
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::sizeKeyword) == 0) {
- StringRef val = entry->value;
- if (val.getAsInteger(0, atomState._size))
+ unsigned int ContentByte;
+ if (Entry->getValue(storage).getAsInteger(16, ContentByte)) {
+ s.printError(i->getValue(), "Invalid content byte");
return make_error_code(yaml_reader_error::illegal_value);
- haveAtom = true;
- }
- else if (strcmp(entry->key, KeyValues::contentKeyword) == 0) {
- atomState._content = entry->valueSequenceBytes;
- haveAtom = true;
- }
- else if (strcmp(entry->key, "align2") == 0) {
- atomState.setAlign2(entry->value);
- haveAtom = true;
- }
- 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::APInt Val;
- StringRef(entry->value).getAsInteger(0, Val);
- atomState._value = Val.getZExtValue();
- haveAtom = true;
+ }
+ if (ContentByte > 0xFF) {
+ s.printError(i->getValue(), "Byte out of range (> 0xFF)");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ yas._content.push_back(ContentByte & 0xFF);
}
- else {
- return make_error_code(yaml_reader_error::unknown_keyword);
+ }
+ } else if (KeyValue == KeyValues::fixupsKeyword) {
+ SequenceNode *Value = llvm::dyn_cast<SequenceNode>(i->getValue());
+ if (!Value) {
+ s.printError(i->getValue(), "Expected a sequence");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ for (auto &i : *Value) {
+ MappingNode *Fixup = llvm::dyn_cast<MappingNode>(&i);
+ if (!Fixup) {
+ s.printError(&i, "Expected a map");
+ return make_error_code(yaml_reader_error::illegal_value);
}
+ if (error_code ec = parseFixup(Fixup, s, p, f, yas))
+ return ec;
}
- else if (depthForFixups == entry->depth) {
- if (entry->beginSequence) {
- if (haveFixup) {
- atomState.addFixup(file);
- haveFixup = false;
- }
+ } else {
+ // The rest of theses all require value to be a scalar.
+ ScalarNode *Value = llvm::dyn_cast<ScalarNode>(i->getValue());
+ if (!Value) {
+ s.printError(i->getValue(), "Expected a scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ if (KeyValue == KeyValues::nameKeyword) {
+ // FIXME: String lifetime.
+ yas.setName(Value->getValue(storage));
+ } else if (KeyValue == KeyValues::refNameKeyword) {
+ // FIXME: String lifetime.
+ yas.setRefName(Value->getValue(storage));
+ } else if (KeyValue == KeyValues::valueKeyword) {
+ if (!getAs(Value, yas._value)) {
+ s.printError(Value, "Invalid value for value");
+ return make_error_code(yaml_reader_error::illegal_value);
}
- if (strcmp(entry->key, KeyValues::fixupsKindKeyword) == 0) {
- atomState.setFixupKind(entry->value);
- haveFixup = true;
+ } else if (KeyValue == KeyValues::loadNameKeyword)
+ // FIXME: String lifetime.
+ yas._loadName = Value->getValue(storage);
+ else if (KeyValue == KeyValues::definitionKeyword)
+ yas._definition = KeyValues::definition(Value->getValue(storage));
+ else if (KeyValue == KeyValues::scopeKeyword)
+ yas._scope = KeyValues::scope(Value->getValue(storage));
+ else if (KeyValue == KeyValues::contentTypeKeyword)
+ yas._type = KeyValues::contentType(Value->getValue(storage));
+ else if (KeyValue == KeyValues::deadStripKindKeyword)
+ yas._deadStrip = KeyValues::deadStripKind(Value->getValue(storage));
+ else if (KeyValue == KeyValues::sectionChoiceKeyword)
+ yas._sectionChoice = KeyValues::sectionChoice(Value->getValue(storage));
+ else if (KeyValue == KeyValues::mergeKeyword)
+ yas._merge = KeyValues::merge(Value->getValue(storage));
+ else if (KeyValue == KeyValues::interposableKeyword)
+ yas._interpose = KeyValues::interposable(Value->getValue(storage));
+ else if (KeyValue == KeyValues::isThumbKeyword) {
+ if (!getAs(Value, yas._isThumb)) {
+ s.printError(Value, "Invalid value for isThumb");
+ return make_error_code(yaml_reader_error::illegal_value);
}
- else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0) {
- if (StringRef(entry->value).getAsInteger(0,
- atomState._ref._offsetInAtom))
- return make_error_code(yaml_reader_error::illegal_value);
- haveFixup = true;
+ } else if (KeyValue == KeyValues::isAliasKeyword) {
+ if (!getAs(Value, yas._isAlias)) {
+ s.printError(Value, "Invalid value for isAlias");
+ return make_error_code(yaml_reader_error::illegal_value);
}
- else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0) {
- atomState.setFixupTarget(entry->value);
- haveFixup = true;
+ } else if (KeyValue == KeyValues::canBeNullKeyword) {
+ yas._canBeNull = KeyValues::canBeNull(Value->getValue(storage));
+ if (yas._definition == Atom::definitionSharedLibrary
+ && yas._canBeNull == UndefinedAtom::canBeNullAtBuildtime) {
+ s.printError(Value, "Invalid value for can be null");
+ return make_error_code(yaml_reader_error::illegal_value);
}
- else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0) {
- StringRef Addend(entry->value);
- if (Addend.getAsInteger(0, atomState._ref._addend))
- return make_error_code(yaml_reader_error::illegal_value);
- haveFixup = true;
- }
- }
- }
- else if (inMembers) {
- if (depthForMembers == entry->depth) {
- if (entry->beginSequence) {
- if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
- file->addMember(entry->value);
- }
+ } else if (KeyValue == KeyValues::sectionNameKeyword)
+ // FIXME: String lifetime.
+ yas._sectionName = Value->getValue(storage);
+ else if (KeyValue == KeyValues::sizeKeyword) {
+ if (!getAs(Value, yas._size)) {
+ s.printError(Value, "Invalid value for size");
+ return make_error_code(yaml_reader_error::illegal_value);
}
+ } else if (KeyValue == "align2")
+ yas.setAlign2(Value->getValue(storage));
+ else {
+ s.printError(Key, "Unrecognized key");
+ return make_error_code(yaml_reader_error::unknown_keyword);
}
}
- lastDepth = entry->depth;
}
- if (haveAtom) {
- atomState.makeAtom(*file);
- }
- if (file != nullptr) {
- file->bindTargetReferences();
- allFiles.push_back(file);
+ yas.makeAtom(f);
+ return make_error_code(yaml_reader_error::success);
+}
+
+llvm::error_code parseAtoms( llvm::yaml::SequenceNode *atoms
+ , llvm::yaml::Stream &s
+ , Platform &p
+ , YAMLFile &f) {
+ using namespace llvm::yaml;
+
+ for (auto &atom : *atoms) {
+ if (MappingNode *a = llvm::dyn_cast<MappingNode>(&atom)) {
+ if (llvm::error_code ec = parseAtom(a, s, p, f))
+ return ec;
+ } else {
+ s.printError(&atom, "Expected map");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
}
+ return make_error_code(yaml_reader_error::success);
+}
- // If yaml contained archive files, push members down into archives
- if ( hasArchives ) {
- for (YAMLFile *f : allFiles) {
- if ( f->kind() == File::kindArchiveLibrary ) {
- for (const char *memberName : f->_memberNames ) {
- for (YAMLFile *f2 : allFiles) {
- if ( f2->path().equals(memberName) ) {
- f2->_inArchive = true;
- f->_memberFiles.push_back(f2);
- }
- }
+llvm::error_code parseArchive( llvm::yaml::SequenceNode *archive
+ , llvm::yaml::Stream &s
+ , Platform &p
+ , YAMLFile &f) {
+ using namespace llvm::yaml;
+ llvm::SmallString<32> storage;
+
+ for (auto &member : *archive) {
+ std::unique_ptr<YAMLFile> mf(new YAMLFile);
+ MappingNode *mem = llvm::dyn_cast<MappingNode>(&member);
+ if (!mem) {
+ s.printError(&member, "Expected map");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ for (auto &keyVal : *mem) {
+ ScalarNode *key = llvm::dyn_cast<ScalarNode>(keyVal.getKey());
+ if (!key) {
+ s.printError(keyVal.getKey(), "Expected scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ if (key->getValue(storage) == "name") {
+ ScalarNode *value = llvm::dyn_cast<ScalarNode>(keyVal.getValue());
+ if (!value) {
+ s.printError(keyVal.getValue(), "Expected scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ // FIXME: String lifetime.
+ mf->setName(value->getValue(storage));
+ } else if (key->getValue(storage) == "atoms") {
+ SequenceNode *atoms = llvm::dyn_cast<SequenceNode>(keyVal.getValue());
+ if (!atoms) {
+ s.printError(keyVal.getValue(), "Expected sequence");
+ return make_error_code(yaml_reader_error::illegal_value);
}
+ if (error_code ec = parseAtoms(atoms, s, p, *mf))
+ return ec;
+ } else {
+ s.printError(key, "Unrecognized key");
+ return make_error_code(yaml_reader_error::unknown_keyword);
}
}
+ f._memberFiles.push_back(std::move(mf));
}
- // Copy files that have not been pushed into archives to result.
- for (YAMLFile *f : allFiles) {
- if ( ! f->_inArchive ) {
- result.push_back(f);
+ return make_error_code(yaml_reader_error::success);
+}
+
+/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
+/// into lld::File object(s) and append each to the specified vector<File*>.
+error_code parseObjectText( llvm::MemoryBuffer *mb
+ , Platform& platform
+ , std::vector<std::unique_ptr<const File>> &result) {
+ using namespace llvm::yaml;
+ llvm::SourceMgr sm;
+ Stream stream(mb->getBuffer(), sm);
+
+ llvm::SmallString<32> storage;
+ for (Document &d : stream) {
+ std::unique_ptr<YAMLFile> CurFile(new YAMLFile);
+ if (llvm::isa<NullNode>(d.getRoot()))
+ continue; // Empty files are allowed.
+ MappingNode *n = llvm::dyn_cast<MappingNode>(d.getRoot());
+ if (!n) {
+ stream.printError(d.getRoot(), "Expected map");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ for (MappingNode::iterator mi = n->begin(), me = n->end(); mi != me; ++mi) {
+ ScalarNode *key = llvm::dyn_cast<ScalarNode>(mi->getKey());
+ if (!key) {
+ stream.printError(mi->getValue(), "Expected scalar value");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ if (key->getValue(storage) == "atoms") {
+ SequenceNode *Atoms = llvm::dyn_cast<SequenceNode>(mi->getValue());
+ if (!Atoms) {
+ stream.printError(mi->getValue(), "Expected sequence");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ if (error_code ec = parseAtoms(Atoms, stream, platform, *CurFile))
+ return ec;
+ } else if (key->getValue(storage) == "archive") {
+ CurFile->_kind = YAMLFile::kindArchiveLibrary;
+ SequenceNode *members = llvm::dyn_cast<SequenceNode>(mi->getValue());
+ if (!members) {
+ stream.printError(mi->getValue(), "Expected sequence");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
+ if (error_code ec = parseArchive( members
+ , stream
+ , platform
+ , *CurFile))
+ return ec;
+ } else {
+ stream.printError(key, "Unrecognized key");
+ return make_error_code(yaml_reader_error::unknown_keyword);
+ }
}
+ if (stream.failed())
+ return make_error_code(yaml_reader_error::illegal_value);
+ CurFile->bindTargetReferences();
+ result.emplace_back(CurFile.release());
}
return make_error_code(yaml_reader_error::success);
}
-
//
// Fill in vector<File*> from path to input text file.
//
error_code parseObjectTextFileOrSTDIN( StringRef path
, Platform& platform
- , std::vector<const File*>& result) {
+ , std::vector<
+ std::unique_ptr<const File>>& result) {
OwningPtr<llvm::MemoryBuffer> mb;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb))
return ec;
- return parseObjectText(mb.get(), platform, result);
+ return parseObjectText(mb.take(), platform, result);
}
} // namespace yaml
diff --git a/lld/test/archive-basic.objtxt b/lld/test/archive-basic.objtxt
index 6f13d489d5e..0e4a754ed45 100644
--- a/lld/test/archive-basic.objtxt
+++ b/lld/test/archive-basic.objtxt
@@ -9,34 +9,29 @@
atoms:
- name: foo
type: code
-
+
- name: bar
definition: undefined
---
-name: bar.o
-atoms:
- - name: bar
- scope: global
- type: code
-
- - name: bar2
- type: code
-
----
-name: baz.o
-atoms:
- - name: baz
- scope: global
- type: code
-
- - name: baz2
- type: code
----
-kind: archive
-members:
- - name: bar.o
- - name: baz.o
+archive:
+ - name: bar.o
+ atoms:
+ - name: bar
+ scope: global
+ type: code
+
+ - name: bar2
+ type: code
+
+ - name: baz.o
+ atoms:
+ - name: baz
+ scope: global
+ type: code
+
+ - name: baz2
+ type: code
...
# CHECK: name: foo
diff --git a/lld/test/archive-chain.objtxt b/lld/test/archive-chain.objtxt
index 3a5f292629b..f0d8e6c08ed 100644
--- a/lld/test/archive-chain.objtxt
+++ b/lld/test/archive-chain.objtxt
@@ -8,60 +8,52 @@
atoms:
- name: foo
type: code
-
- - name: bar1
- definition: undefined
----
-name: bar1.o
-atoms:
- name: bar1
- scope: global
- type: code
-
- - name: bar1b
- type: code
-
- - name: baz1
definition: undefined
+
---
-name: bar2.o
-atoms:
- - name: bar2
- scope: global
- type: code
-
- - name: bar2b
- type: code
-
----
-name: baz1.o
-atoms:
- - name: baz1
- scope: global
- type: code
-
- - name: baz1b
- type: code
----
-name: baz2.o
-atoms:
- - name: baz2
- scope: global
- type: code
-
- - name: baz2b
- type: code
----
-kind: archive
-members:
- - name: bar1.o
- - name: bar2.o
+archive:
+ - name: bar1.o
+ - atoms:
+ - name: bar1
+ scope: global
+ type: code
+
+ - name: bar1b
+ type: code
+
+ - name: baz1
+ definition: undefined
+
+ - name: bar2.o
+ - atoms:
+ - name: bar2
+ scope: global
+ type: code
+
+ - name: bar2b
+ type: code
+
---
-kind: archive
-members:
- - name: baz1.o
- - name: baz2.o
+archive:
+ - name: baz1.o
+ - atoms:
+ - name: baz1
+ scope: global
+ type: code
+
+ - name: baz1b
+ type: code
+
+ - name: baz2.o
+ - atoms:
+ - name: baz2
+ scope: global
+ type: code
+
+ - name: baz2b
+ type: code
...
# CHECK: name: foo
diff --git a/lld/test/archive-tentdef-search.objtxt b/lld/test/archive-tentdef-search.objtxt
index ce93018f9a9..48859088895 100644
--- a/lld/test/archive-tentdef-search.objtxt
+++ b/lld/test/archive-tentdef-search.objtxt
@@ -11,26 +11,22 @@
atoms:
- name: foo
type: code
-
+
- name: bar
scope: global
content: zero-fill
merge: asTentative
---
-name: bar.o
-atoms:
- - name: bar
- scope: global
- type: data
-
- - name: bar2
- type: data
-
----
-kind: archive
-members:
- - name: bar.o
+archive:
+ - name: bar.o
+ - atoms:
+ - name: bar
+ scope: global
+ type: data
+
+ - name: bar2
+ type: data
...
# CHK1: name: foo
diff --git a/lld/tools/lld-core/lld-core.cpp b/lld/tools/lld-core/lld-core.cpp
index 794829c5ac5..50e00fc7cbe 100644
--- a/lld/tools/lld-core/lld-core.cpp
+++ b/lld/tools/lld-core/lld-core.cpp
@@ -422,7 +422,7 @@ int main(int argc, char *argv[]) {
llvm::cl::ParseCommandLineOptions(argc, argv);
// create platform for testing
- Platform* platform = NULL;
+ Platform* platform = nullptr;
switch ( platformSelected ) {
case platformTesting:
platform = new TestingPlatform();
@@ -433,7 +433,7 @@ int main(int argc, char *argv[]) {
}
// read input YAML doc into object file(s)
- std::vector<const File *> files;
+ std::vector<std::unique_ptr<const File>> files;
if (error(yaml::parseObjectTextFileOrSTDIN(cmdLineInputFilePath,
*platform, files))) {
return 1;
@@ -444,7 +444,7 @@ int main(int argc, char *argv[]) {
// create object to mange input files
InputFiles inputFiles;
- for (const File *file : files) {
+ for (const auto &file : files) {
inputFiles.appendFile(*file);
}
OpenPOWER on IntegriCloud