[llvm-commits] [lld] r156136 - in /lld/trunk: lib/Core/InputFiles.cpp lib/Core/YamlKeyValues.cpp lib/Core/YamlKeyValues.h lib/Core/YamlReader.cpp lib/Core/YamlWriter.cpp test/archive-tentdef-search.objtxt test/error-atom-attribute.objtxt test/error-atom-content-byte-value.objtxt test/error-atom-content-bytes.objtxt test/error-atom-type.objtxt test/error-atom-undefined-wrong-attribue.objtxt test/error-file-attribute.objtxt test/error-fixup-attribute.objtxt test/error-fixup-target.objtxt
Nick Kledzik
kledzik at apple.com
Thu May 3 16:55:35 PDT 2012
Author: kledzik
Date: Thu May 3 18:55:34 2012
New Revision: 156136
URL: http://llvm.org/viewvc/llvm-project?rev=156136&view=rev
Log:
Rework how YAMLReader is layered on top of YAMLParser. Turn hand written
recursive descent functions into one table driven parser. Add proper
error recovery and reporting. Add lots of test cases with semantics errors
and verify error messages.
Added:
lld/trunk/test/error-atom-attribute.objtxt
lld/trunk/test/error-atom-content-byte-value.objtxt
lld/trunk/test/error-atom-content-bytes.objtxt
lld/trunk/test/error-atom-type.objtxt
lld/trunk/test/error-atom-undefined-wrong-attribue.objtxt
lld/trunk/test/error-file-attribute.objtxt
lld/trunk/test/error-fixup-attribute.objtxt
lld/trunk/test/error-fixup-target.objtxt
Modified:
lld/trunk/lib/Core/InputFiles.cpp
lld/trunk/lib/Core/YamlKeyValues.cpp
lld/trunk/lib/Core/YamlKeyValues.h
lld/trunk/lib/Core/YamlReader.cpp
lld/trunk/lib/Core/YamlWriter.cpp
lld/trunk/test/archive-tentdef-search.objtxt
Modified: lld/trunk/lib/Core/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputFiles.cpp?rev=156136&r1=156135&r2=156136&view=diff
==============================================================================
--- lld/trunk/lib/Core/InputFiles.cpp (original)
+++ lld/trunk/lib/Core/InputFiles.cpp Thu May 3 18:55:34 2012
@@ -1,4 +1,4 @@
-//===- Core/InputFiles.cpp - Manages list of Files -----------------------===//
+//===- Core/InputFiles.cpp - Manages list of Files ------------------------===//
//
// The LLVM Linker
//
Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=156136&r1=156135&r2=156136&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
+++ lld/trunk/lib/Core/YamlKeyValues.cpp Thu May 3 18:55:34 2012
@@ -18,35 +18,6 @@
namespace yaml {
-const char* const KeyValues::nameKeyword = "name";
-const char* const KeyValues::refNameKeyword = "ref-name";
-const char* const KeyValues::definitionKeyword = "definition";
-const char* const KeyValues::scopeKeyword = "scope";
-const char* const KeyValues::contentTypeKeyword = "type";
-const char* const KeyValues::deadStripKindKeyword = "dead-strip";
-const char* const KeyValues::sectionChoiceKeyword = "section-choice";
-const char* const KeyValues::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::loadNameKeyword = "load-name";
-const char* const KeyValues::sizeKeyword = "size";
-const char* const KeyValues::valueKeyword = "value";
-const char* const KeyValues::fixupsKeyword = "fixups";
-const char* const KeyValues::permissionsKeyword = "permissions";
-const char* const KeyValues::canBeNullKeyword = "can-be-null";
-const char* const KeyValues::fixupsKindKeyword = "kind";
-const char* const KeyValues::fixupsOffsetKeyword = "offset";
-const char* const KeyValues::fixupsTargetKeyword = "target";
-const char* const KeyValues::fixupsAddendKeyword = "addend";
-const char* const KeyValues::fileAtomsKeyword = "atoms";
-const char* const KeyValues::fileKindKeyword = "kind";
-const char* const KeyValues::fileMembersKeyword = "members";
-
-
-
const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
const DefinedAtom::Scope KeyValues::scopeDefault = DefinedAtom::scopeTranslationUnit;
const DefinedAtom::ContentType KeyValues::contentTypeDefault = DefinedAtom::typeData;
@@ -58,36 +29,8 @@
const bool KeyValues::isThumbDefault = false;
const bool KeyValues::isAliasDefault = false;
const UndefinedAtom::CanBeNull KeyValues::canBeNullDefault = UndefinedAtom::canBeNullNever;
-const File::Kind KeyValues::fileKindDefault = File::kindObject;
-struct FileKindMapping {
- const char* string;
- File::Kind value;
-};
-
-static const FileKindMapping fileKindMappings[] = {
- { "object", File::kindObject },
- { "archive", File::kindArchiveLibrary },
- { "shared-library", File::kindSharedLibrary },
- { nullptr, File::kindObject }
-};
-
- File::Kind KeyValues::fileKind(StringRef str) {
- for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
- if (str == p->string)
- return p->value;
- }
- llvm::report_fatal_error("bad file kind value");
-}
-
-const char* KeyValues::fileKind(File::Kind k) {
- for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
- if ( p->value == k )
- return p->string;
- }
- llvm::report_fatal_error("bad file kind value");
-}
struct DefinitionMapping {
@@ -103,13 +46,15 @@
{ nullptr, Atom::definitionRegular }
};
-Atom::Definition KeyValues::definition(StringRef s)
+bool KeyValues::definition(StringRef s, Atom::Definition &out)
{
for (const DefinitionMapping* p = defMappings; p->string != nullptr; ++p) {
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad definition value");
+ return true;
}
const char* KeyValues::definition(Atom::Definition s) {
@@ -136,13 +81,15 @@
{ nullptr, DefinedAtom::scopeGlobal }
};
-DefinedAtom::Scope KeyValues::scope(StringRef s)
+bool KeyValues::scope(StringRef s, DefinedAtom::Scope &out)
{
for (const ScopeMapping* p = scopeMappings; p->string != nullptr; ++p) {
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad scope value");
+ return true;
}
const char* KeyValues::scope(DefinedAtom::Scope s) {
@@ -197,13 +144,15 @@
{ nullptr, DefinedAtom::typeUnknown }
};
-DefinedAtom::ContentType KeyValues::contentType(StringRef s)
+bool KeyValues::contentType(StringRef s, DefinedAtom::ContentType &out)
{
for (const ContentTypeMapping* p = typeMappings; p->string != nullptr; ++p) {
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad content type value");
+ return true;
}
const char* KeyValues::contentType(DefinedAtom::ContentType s) {
@@ -225,26 +174,26 @@
DefinedAtom::DeadStripKind value;
};
-static const DeadStripMapping deadStripMappings[] = {
+static const DeadStripMapping dsMappings[] = {
{ "normal", DefinedAtom::deadStripNormal },
{ "never", DefinedAtom::deadStripNever },
{ "always", DefinedAtom::deadStripAlways },
{ nullptr, DefinedAtom::deadStripNormal }
};
-DefinedAtom::DeadStripKind KeyValues::deadStripKind(StringRef s)
+bool KeyValues::deadStripKind(StringRef s, DefinedAtom::DeadStripKind &out)
{
- for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p)
- {
- if (s == p->string)
- return p->value;
+ for (const DeadStripMapping* p = dsMappings; p->string != nullptr; ++p) {
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad dead strip value");
+ return true;
}
const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) {
- for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p)
- {
+ for (const DeadStripMapping* p = dsMappings; p->string != nullptr; ++p) {
if ( p->value == dsk )
return p->string;
}
@@ -267,13 +216,15 @@
{ nullptr, DefinedAtom::interposeNo }
};
-DefinedAtom::Interposable KeyValues::interposable(StringRef s)
+bool KeyValues::interposable(StringRef s, DefinedAtom::Interposable &out)
{
for (const InterposableMapping* p = interMappings; p->string != nullptr; ++p){
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad interposable value");
+ return true;
}
const char* KeyValues::interposable(DefinedAtom::Interposable in) {
@@ -302,13 +253,15 @@
{ nullptr, DefinedAtom::mergeNo }
};
-DefinedAtom::Merge KeyValues::merge(StringRef s)
+bool KeyValues::merge(StringRef s, DefinedAtom::Merge& out)
{
for (const MergeMapping* p = mergeMappings; p->string != nullptr; ++p) {
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad merge value");
+ return true;
}
const char* KeyValues::merge(DefinedAtom::Merge in) {
@@ -336,13 +289,15 @@
{ nullptr, DefinedAtom::sectionBasedOnContent }
};
-DefinedAtom::SectionChoice KeyValues::sectionChoice(StringRef s)
+bool KeyValues::sectionChoice(StringRef s, DefinedAtom::SectionChoice &out)
{
for (const SectionChoiceMapping* p = sectMappings; p->string != nullptr; ++p){
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad dead strip value");
+ return true;
}
const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) {
@@ -365,21 +320,23 @@
};
static const PermissionsMapping permMappings[] = {
- { "content", DefinedAtom::perm___ },
- { "custom", DefinedAtom::permR__ },
- { "custom-required", DefinedAtom::permR_X },
- { "custom-required", DefinedAtom::permRW_ },
- { "custom-required", DefinedAtom::permRW_L },
- { nullptr, DefinedAtom::perm___ }
+ { "---", DefinedAtom::perm___ },
+ { "r--", DefinedAtom::permR__ },
+ { "r-x", DefinedAtom::permR_X },
+ { "rw-", DefinedAtom::permRW_ },
+ { "rw-l", DefinedAtom::permRW_L },
+ { nullptr, DefinedAtom::perm___ }
};
-DefinedAtom::ContentPermissions KeyValues::permissions(StringRef s)
+bool KeyValues::permissions(StringRef s, DefinedAtom::ContentPermissions &out)
{
for (const PermissionsMapping* p = permMappings; p->string != nullptr; ++p) {
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad permissions value");
+ return true;
}
const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
@@ -390,10 +347,42 @@
llvm::report_fatal_error("bad permissions value");
}
+
+bool KeyValues::isThumb(StringRef s, bool &out)
+{
+ if ( s.equals("true") ) {
+ out = true;
+ return false;
+ }
+
+ if ( s.equals("false") ) {
+ out = false;
+ return false;
+ }
+
+ return true;
+}
+
const char* KeyValues::isThumb(bool b) {
return b ? "true" : "false";
}
+
+bool KeyValues::isAlias(StringRef s, bool &out)
+{
+ if ( s.equals("true") ) {
+ out = true;
+ return false;
+ }
+
+ if ( s.equals("false") ) {
+ out = false;
+ return false;
+ }
+
+ return true;
+}
+
const char* KeyValues::isAlias(bool b) {
return b ? "true" : "false";
}
@@ -414,13 +403,15 @@
};
-UndefinedAtom::CanBeNull KeyValues::canBeNull(StringRef s)
+bool KeyValues::canBeNull(StringRef s, UndefinedAtom::CanBeNull &out)
{
for (const CanBeNullMapping* p = cbnMappings; p->string != nullptr; ++p) {
- if (s == p->string)
- return p->value;
+ if (s == p->string) {
+ out = p->value;
+ return false;
+ }
}
- llvm::report_fatal_error("bad can-be-null value");
+ return true;
}
const char* KeyValues::canBeNull(UndefinedAtom::CanBeNull c) {
Modified: lld/trunk/lib/Core/YamlKeyValues.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=156136&r1=156135&r2=156136&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.h (original)
+++ lld/trunk/lib/Core/YamlKeyValues.h Thu May 3 18:55:34 2012
@@ -20,81 +20,62 @@
class KeyValues {
public:
- static const char* const nameKeyword;
- static const char* const refNameKeyword;
- static const char* const sectionNameKeyword;
- static const char* const contentKeyword;
- static const char* const sizeKeyword;
- static const char* const loadNameKeyword;
- static const char* const valueKeyword;
- static const char* const fixupsKeyword;
- static const char* const fileAtomsKeyword;
- static const char* const fileMembersKeyword;
-
- static const char* const fileKindKeyword;
- static const File::Kind fileKindDefault;
- 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(StringRef);
+ static bool definition(StringRef, Atom::Definition&);
static const char* definition(Atom::Definition);
static const char* const scopeKeyword;
static const DefinedAtom::Scope scopeDefault;
- static DefinedAtom::Scope scope(StringRef);
+ static bool scope(StringRef, DefinedAtom::Scope&);
static const char* scope(DefinedAtom::Scope);
static const char* const contentTypeKeyword;
static const DefinedAtom::ContentType contentTypeDefault;
- static DefinedAtom::ContentType contentType(StringRef);
+ static bool contentType(StringRef, DefinedAtom::ContentType&);
static const char* contentType(DefinedAtom::ContentType);
static const char* const deadStripKindKeyword;
static const DefinedAtom::DeadStripKind deadStripKindDefault;
- static DefinedAtom::DeadStripKind deadStripKind(StringRef);
+ static bool deadStripKind(StringRef, DefinedAtom::DeadStripKind&);
static const char* deadStripKind(DefinedAtom::DeadStripKind);
static const char* const sectionChoiceKeyword;
static const DefinedAtom::SectionChoice sectionChoiceDefault;
- static DefinedAtom::SectionChoice sectionChoice(StringRef);
+ static bool sectionChoice(StringRef, DefinedAtom::SectionChoice&);
static const char* sectionChoice(DefinedAtom::SectionChoice);
static const char* const interposableKeyword;
static const DefinedAtom::Interposable interposableDefault;
- static DefinedAtom::Interposable interposable(StringRef);
+ static bool interposable(StringRef, DefinedAtom::Interposable&);
static const char* interposable(DefinedAtom::Interposable);
static const char* const mergeKeyword;
static const DefinedAtom::Merge mergeDefault;
- static DefinedAtom::Merge merge(StringRef);
+ static bool merge(StringRef, DefinedAtom::Merge&);
static const char* merge(DefinedAtom::Merge);
static const char* const permissionsKeyword;
static const DefinedAtom::ContentPermissions permissionsDefault;
- static DefinedAtom::ContentPermissions permissions(StringRef);
+ static bool permissions(StringRef, DefinedAtom::ContentPermissions&);
static const char* permissions(DefinedAtom::ContentPermissions);
static const char* const isThumbKeyword;
static const bool isThumbDefault;
+ static bool isThumb(StringRef, bool&);
static const char* isThumb(bool);
static const char* const isAliasKeyword;
static const bool isAliasDefault;
+ static bool isAlias(StringRef, bool&);
static const char* isAlias(bool);
static const char* const canBeNullKeyword;
static const UndefinedAtom::CanBeNull canBeNullDefault;
- static UndefinedAtom::CanBeNull canBeNull(StringRef);
+ static bool canBeNull(StringRef, UndefinedAtom::CanBeNull&);
static const char* canBeNull(UndefinedAtom::CanBeNull);
-
- static const char* const fixupsKindKeyword;
- static const char* const fixupsOffsetKeyword;
- static const char* const fixupsTargetKeyword;
- static const char* const fixupsAddendKeyword;
-
};
} // namespace yaml
Modified: lld/trunk/lib/Core/YamlReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=156136&r1=156135&r2=156136&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlReader.cpp (original)
+++ lld/trunk/lib/Core/YamlReader.cpp Thu May 3 18:55:34 2012
@@ -1,4 +1,4 @@
-//===- Core/YamlReader.cpp - Reads YAML -----------------------------------===//
+//===- Core/YamlReader.cpp - Reads YAML encode object files ---------------===//
//
// The LLVM Linker
//
@@ -31,43 +31,25 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
#include <cstring>
-#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 {
+
+///
+/// Concrete instance of lld::Reference created parsing YAML object files
+///
class YAMLReference : public Reference {
public:
YAMLReference()
: _target(nullptr)
+ , _targetNameNode(nullptr)
, _offsetInAtom(0)
, _addend(0)
, _kind(0)
@@ -101,24 +83,31 @@
_target = newAtom;
}
+ typedef llvm::yaml::ScalarNode ScalarNode;
+
const Atom *_target;
- StringRef _targetName;
+ ScalarNode * _targetNameNode;
uint64_t _offsetInAtom;
Addend _addend;
Kind _kind;
};
-class YAMLDefinedAtom;
+///
+/// Concrete instance of lld::File created parsing YAML object files.
+///
class YAMLFile : public ArchiveLibraryFile {
public:
YAMLFile()
: ArchiveLibraryFile("<anonymous>")
, _lastRefIndex(0)
- , _kind(File::kindObject)
- , _inArchive(false) {
+ , _kind(File::kindObject) {
}
+ ~YAMLFile();
+
+ // Depending on the YAML description, this file can be either an
+ // lld::ArchiveLibraryFile or lld::File.
virtual File::Kind kind() const {
return _kind;
}
@@ -140,10 +129,12 @@
assert(0 && "cannot add atoms to YAML files");
}
+ // Standard way that archives are searched.
virtual const File *find(StringRef name, bool dataSymbolOnly) const;
- void bindTargetReferences();
- void addDefinedAtom(YAMLDefinedAtom *atom, StringRef refName);
+ error_code bindTargetReferences(llvm::yaml::Stream &stream);
+
+ void addDefinedAtom(class YAMLDefinedAtom *atom, StringRef refName);
void addUndefinedAtom(UndefinedAtom *atom);
void addSharedLibraryAtom(SharedLibraryAtom *atom);
void addAbsoluteAtom(AbsoluteAtom *atom);
@@ -151,6 +142,8 @@
void addMember(StringRef);
void setName(StringRef);
+ StringRef copyString(StringRef);
+
struct NameAtomPair {
NameAtomPair(StringRef n, Atom *a) : name(n), atom(a) {}
StringRef name;
@@ -163,13 +156,17 @@
atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
std::vector<YAMLReference> _references;
std::vector<NameAtomPair> _nameToAtomMapping;
- std::vector<StringRef> _memberNames;
std::vector<std::unique_ptr<YAMLFile>> _memberFiles;
+ std::vector<char*> _stringCopies;
unsigned int _lastRefIndex;
File::Kind _kind;
- bool _inArchive;
};
+
+
+///
+/// Concrete instance of lld::DefinedAtom created parsing YAML object files.
+///
class YAMLDefinedAtom : public DefinedAtom {
public:
YAMLDefinedAtom( uint32_t ord
@@ -187,13 +184,13 @@
, 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(std::move(content))
+ , _content(content)
, _alignment(alignment)
, _scope(scope)
, _type(type)
@@ -299,12 +296,23 @@
it = reinterpret_cast<const void*>(index);
}
- void bindTargetReferences() const {
+ // Convert each target name to a pointer to an atom object
+ error_code bindTargetReferences(llvm::yaml::Stream &stream) const {
for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
- StringRef targetName = _file._references[i]._targetName;
- Atom *targetAtom = _file.findAtom(targetName);
- _file._references[i]._target = targetAtom;
+ llvm::SmallString<32> storage;
+ llvm::yaml::ScalarNode *node = _file._references[i]._targetNameNode;
+ StringRef name = node->getValue(storage);
+ Atom *targetAtom = _file.findAtom(name);
+ if ( targetAtom ) {
+ _file._references[i]._target = targetAtom;
+ }
+ else {
+ stream.printError(node, "Fixup has target '" + name
+ + "' which does not exist");
+ return make_error_code(yaml_reader_error::illegal_value);
+ }
}
+ return make_error_code(yaml_reader_error::success);
}
private:
@@ -328,6 +336,11 @@
unsigned int _refEndIndex;
};
+
+
+///
+/// Concrete instance of lld::UndefinedAtom created parsing YAML object files.
+///
class YAMLUndefinedAtom : public UndefinedAtom {
public:
YAMLUndefinedAtom( YAMLFile &f
@@ -359,6 +372,11 @@
UndefinedAtom::CanBeNull _canBeNull;
};
+
+
+///
+/// Concrete instance of lld::SharedLibraryAtom created parsing YAML files.
+///
class YAMLSharedLibraryAtom : public SharedLibraryAtom {
public:
YAMLSharedLibraryAtom( YAMLFile &f
@@ -397,6 +415,11 @@
bool _canBeNull;
};
+
+
+///
+/// Concrete instance of lld::AbsoluteAtom created parsing YAML object files.
+///
class YAMLAbsoluteAtom : public AbsoluteAtom {
public:
YAMLAbsoluteAtom(YAMLFile &f, int32_t ord, StringRef name, uint64_t v)
@@ -425,12 +448,30 @@
uint64_t _value;
};
-void YAMLFile::bindTargetReferences() {
+
+
+
+//===----------------------------------------------------------------------===//
+// YAMLFile methods
+//===----------------------------------------------------------------------===//
+
+YAMLFile::~YAMLFile() {
+ for (char *s : _stringCopies) {
+ delete [] s;
+ }
+}
+
+
+error_code YAMLFile::bindTargetReferences(llvm::yaml::Stream &stream) {
+ error_code ec;
for (const DefinedAtom *defAtom : _definedAtoms) {
const YAMLDefinedAtom *atom =
reinterpret_cast<const YAMLDefinedAtom*>(defAtom);
- atom->bindTargetReferences();
+ ec = atom->bindTargetReferences(stream);
+ if ( ec )
+ return ec;
}
+ return ec;
}
Atom *YAMLFile::findAtom(StringRef name) {
@@ -438,7 +479,7 @@
if (ci.name == name)
return ci.atom;
}
- llvm::report_fatal_error("reference to atom that does not exist");
+ return nullptr;
}
void YAMLFile::addDefinedAtom(YAMLDefinedAtom *atom, StringRef refName) {
@@ -461,14 +502,20 @@
_nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
}
-void YAMLFile::addMember(StringRef name) {
- _memberNames.push_back(name);
-}
-
void YAMLFile::setName(StringRef name) {
_path = StringRef(name);
}
+
+// Allocate a new copy of this string and keep track of allocations
+// in _stringCopies, so they can be freed when YAMLFile is destroyed.
+StringRef YAMLFile::copyString(StringRef str) {
+ char* s = new char[str.size()];
+ memcpy(s, str.data(), str.size());
+ _stringCopies.push_back(s);
+ return StringRef(s, str.size());
+}
+
const File *YAMLFile::find(StringRef name, bool dataSymbolOnly) const {
for (auto &file : _memberFiles) {
for (const DefinedAtom *atom : file->defined() ) {
@@ -479,25 +526,96 @@
return nullptr;
}
-class YAMLAtomState {
+
+
+///
+/// The state machine that drives the YAMLParser stream and instantiates
+/// Files and Atoms. This class also buffers all the attribures for the
+/// current atom and current fixup. Once all attributes are accumulated,
+/// a new atom or fixup instance is instantiated.
+///
+class YAMLState {
public:
- YAMLAtomState(Platform &platform);
+ YAMLState(Platform &platform, llvm::yaml::Stream *s, YAMLFile *f);
- void setName(StringRef n);
- void setRefName(StringRef n);
+ void parse(llvm::yaml::Node *node, StringRef keyword,
+ llvm::yaml::Node *keywordNode=nullptr);
+ error_code error() { return _error; }
+
+private:
+ typedef llvm::yaml::Node Node;
+ typedef llvm::yaml::ScalarNode ScalarNode;
+ typedef llvm::yaml::SequenceNode SequenceNode;
+ typedef llvm::yaml::MappingNode MappingNode;
+ typedef llvm::yaml::Stream Stream;
+
+ void resetState();
void setAlign2(StringRef n);
- void setFixupKind(StringRef n);
- void setFixupTarget(StringRef n);
- void addFixup(YAMLFile *f);
+ void makeReference();
+ void makeAtom(Node *node);
+ void makeDefinedAtom(Node *node);
+ void makeUndefinedAtom(Node *node);
+ void makeSharedLibraryAtom(Node *node);
+ void makeAbsoluteAtom(Node *node);
+
+ void parseMemberName(ScalarNode *node);
+ void parseAtomName(ScalarNode *node);
+ void parseAtomRefName(ScalarNode *node);
+ void parseAtomType(ScalarNode *node);
+ void parseAtomScope(ScalarNode *node);
+ void parseAtomDefinition(ScalarNode *node);
+ void parseAtomDeadStrip(ScalarNode *node);
+ void parseAtomSectionChoice(ScalarNode *node);
+ void parseAtomInterposable(ScalarNode *node);
+ void parseAtomMerge(ScalarNode *node);
+ void parseAtomIsThumb(ScalarNode *node);
+ void parseAtomIsAlias(ScalarNode *node);
+ void parseAtomSectionName(ScalarNode *node);
+ void parseAtomSize(ScalarNode *node);
+ void parseAtomPermissions(ScalarNode *node);
+ void parseAtomCanBeNull(ScalarNode *node);
+ void parseFixUpOffset(ScalarNode *node);
+ void parseFixUpKind(ScalarNode *node);
+ void parseFixUpTarget(ScalarNode *node);
+ void parseFixUpAddend(ScalarNode *node);
+ void parseAtomContentByte(ScalarNode *node);
+ void parseAtomLoadName(ScalarNode *node);
+ void parseAtomValue(ScalarNode *node);
+
+ StringRef extractString(ScalarNode *node);
+
+ typedef void (YAMLState:: *ParseScalar)(ScalarNode *node);
+ typedef void (YAMLState:: *ParseSeq)(SequenceNode *node);
+ typedef void (YAMLState:: *ParseMap)(MappingNode *node);
+
+ enum State { inError, inTop, inDoc, inArch, inMemb,
+ inAtoms, inAtom, inFixUps, inFixUp, inBytes };
+ struct Transistion {
+ State state;
+ const char* keyword;
+ State newState;
+ ParseScalar customAction;
+ };
+
+ static const char* stateName(State);
- void makeAtom(YAMLFile&);
+ void moveToState(State s);
+ void returnToState(State s, Node *node);
+
+ static const Transistion _s_transistions[];
Platform &_platform;
+ error_code _error;
+ llvm::yaml::Stream *_stream;
+ YAMLFile *_file;
+ YAMLFile *_archiveFile;
+ State _state;
StringRef _name;
StringRef _refName;
StringRef _sectionName;
StringRef _loadName;
+ StringRef _memberName;
unsigned long long _size;
uint64_t _value;
uint32_t _ordinal;
@@ -515,71 +633,164 @@
bool _isAlias;
UndefinedAtom::CanBeNull _canBeNull;
YAMLReference _ref;
+ bool _hasDefinedAtomAttributes;
+ bool _hasUndefinedAtomAttributes;
+ bool _hasSharedLibraryAtomAttributes;
+ bool _hasAbsoluteAtomAttributes;
+};
+
+
+//
+// This transition table is the heart of the state machine.
+// The table is read left-to-right columns A,B,C,D as:
+// If the state is A and key B is seen switch to state C then
+// if D is not nullptr call that method with the key's value,
+// if D is nullptr, recursively parse in the new state.
+//
+const YAMLState::Transistion YAMLState::_s_transistions[] = {
+ { inTop, "<root>", inDoc, nullptr },
+ { inDoc, "archive", inArch, nullptr },
+ { inArch, "<any-seq-item>", inMemb, nullptr },
+ { inMemb, "atoms", inAtoms, nullptr },
+ { inMemb, "name", inMemb, &YAMLState::parseMemberName },
+ { inDoc, "atoms", inAtoms, nullptr },
+ { inAtoms, "<any-seq-item>", inAtom, nullptr },
+ { inAtom, "name", inAtom, &YAMLState::parseAtomName },
+ { inAtom, "ref-name", inAtom, &YAMLState::parseAtomRefName },
+ { inAtom, "type", inAtom, &YAMLState::parseAtomType },
+ { inAtom, "scope", inAtom, &YAMLState::parseAtomScope },
+ { inAtom, "definition", inAtom, &YAMLState::parseAtomDefinition },
+ { inAtom, "dead-strip", inAtom, &YAMLState::parseAtomDeadStrip },
+ { inAtom, "section-choice", inAtom, &YAMLState::parseAtomSectionChoice },
+ { inAtom, "interposable", inAtom, &YAMLState::parseAtomInterposable },
+ { inAtom, "merge", inAtom, &YAMLState::parseAtomMerge },
+ { inAtom, "is-thumb", inAtom, &YAMLState::parseAtomIsThumb },
+ { inAtom, "is-alias", inAtom, &YAMLState::parseAtomIsAlias },
+ { inAtom, "section-name", inAtom, &YAMLState::parseAtomSectionName },
+ { inAtom, "size", inAtom, &YAMLState::parseAtomSize },
+ { inAtom, "permissions", inAtom, &YAMLState::parseAtomPermissions },
+ { inAtom, "can-be-null", inAtom, &YAMLState::parseAtomCanBeNull },
+ { inAtom, "content", inBytes, nullptr },
+ { inAtom, "fixups", inFixUps,nullptr },
+ { inBytes, "<any-seq-item>", inBytes, &YAMLState::parseAtomContentByte },
+ { inFixUps,"<any-seq-item>", inFixUp, nullptr },
+ { inFixUp, "offset", inFixUp, &YAMLState::parseFixUpOffset },
+ { inFixUp, "kind", inFixUp, &YAMLState::parseFixUpKind },
+ { inFixUp, "target", inFixUp, &YAMLState::parseFixUpTarget },
+ { inFixUp, "addend", inFixUp, &YAMLState::parseFixUpAddend },
+ { inAtom, "load-name", inAtom, &YAMLState::parseAtomLoadName },
+ { inAtom, "value", inAtom, &YAMLState::parseAtomValue },
+ { inError, nullptr, inAtom, nullptr },
};
-YAMLAtomState::YAMLAtomState(Platform &platform)
+
+YAMLState::YAMLState(Platform &platform, Stream *stream, YAMLFile *file)
: _platform(platform)
- , _size(0)
- , _value(0)
- , _ordinal(0)
- , _alignment(0, 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) {
-}
-
-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) {
- UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _canBeNull);
- f.addUndefinedAtom(a);
- ++_ordinal;
- } else if (_definition == Atom::definitionSharedLibrary) {
- bool nullable = (_canBeNull == UndefinedAtom::canBeNullAtRuntime);
- SharedLibraryAtom *a = new YAMLSharedLibraryAtom(f, _ordinal, _name,
- _loadName, nullable);
- f.addSharedLibraryAtom(a);
- ++_ordinal;
- } else if (_definition == Atom::definitionAbsolute) {
- AbsoluteAtom *a = new YAMLAbsoluteAtom(f, _ordinal, _name, _value);
- f.addAbsoluteAtom(a);
- ++_ordinal;
+ , _error(make_error_code(yaml_reader_error::success))
+ , _stream(stream)
+ , _file(file)
+ , _archiveFile(nullptr)
+ , _state(inTop)
+ , _alignment(0, 0) {
+ this->resetState();
+}
+
+void YAMLState::makeAtom(Node *node) {
+ switch (_definition ) {
+ case Atom::definitionRegular:
+ this->makeDefinedAtom(node);
+ break;
+ case Atom::definitionUndefined:
+ this->makeUndefinedAtom(node);
+ break;
+ case Atom::definitionSharedLibrary:
+ this->makeSharedLibraryAtom(node);
+ break;
+ case Atom::definitionAbsolute:
+ this->makeAbsoluteAtom(node);
+ break;
}
-
+ ++_ordinal;
+
// reset state for next atom
+ this->resetState();
+}
+
+void YAMLState::makeDefinedAtom(Node *node) {
+ if ( _hasAbsoluteAtomAttributes ) {
+ _stream->printError(node, "Defined atom '" + _name
+ + "' has attributes only allowed on absolute atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ if ( _hasSharedLibraryAtomAttributes ) {
+ _stream->printError(node, "Defined atom '" + _name
+ + "' has attributes only allowed on shared library atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+
+ YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, *_file, _scope, _type
+ , _sectionChoice, _interpose, _merge, _deadStrip
+ , _permissions, _isThumb, _isAlias, _alignment
+ , _name, _sectionName, _size, _content);
+ _file->addDefinedAtom(a, !_refName.empty() ? _refName : _name);
+}
+
+void YAMLState::makeUndefinedAtom(Node *node) {
+ if ( _hasDefinedAtomAttributes ) {
+ _stream->printError(node, "Undefined atom '" + _name
+ + "' has attributes only allowed on defined atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ if ( _hasAbsoluteAtomAttributes ) {
+ _stream->printError(node, "Defined atom '" + _name
+ + "' has attributes only allowed on absolute atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ UndefinedAtom *a = new YAMLUndefinedAtom(*_file, _ordinal, _name, _canBeNull);
+ _file->addUndefinedAtom(a);
+}
+
+void YAMLState::makeSharedLibraryAtom(Node *node) {
+ if ( _hasDefinedAtomAttributes ) {
+ _stream->printError(node, "SharedLibrary atom '" + _name
+ + "' has attributes only allowed on defined atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ if ( _hasAbsoluteAtomAttributes ) {
+ _stream->printError(node, "Defined atom '" + _name
+ + "' has attributes only allowed on absolute atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ bool nullable = (_canBeNull == UndefinedAtom::canBeNullAtRuntime);
+ SharedLibraryAtom *a = new YAMLSharedLibraryAtom(*_file, _ordinal, _name,
+ _loadName, nullable);
+ _file->addSharedLibraryAtom(a);
+}
+
+void YAMLState::makeAbsoluteAtom(Node *node) {
+ if ( _hasDefinedAtomAttributes ) {
+ _stream->printError(node, "Absolute atom '" + _name
+ + "' has attributes only allowed on defined atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ if ( _hasSharedLibraryAtomAttributes ) {
+ _stream->printError(node, "Absolute atom '" + _name
+ + "' has attributes only allowed on shared library atoms");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ AbsoluteAtom *a = new YAMLAbsoluteAtom(*_file, _ordinal, _name, _value);
+ _file->addAbsoluteAtom(a);
+}
+
+
+
+void YAMLState::resetState() {
_name = StringRef();
_refName = StringRef();
_sectionName = StringRef();
_loadName = StringRef();
+ _memberName = StringRef();
_size = 0;
_value = 0;
_ordinal = 0;
@@ -598,346 +809,429 @@
_isAlias = KeyValues::isAliasDefault;
_canBeNull = KeyValues::canBeNullDefault;
_ref._target = nullptr;
- _ref._targetName = StringRef();
+ _ref._targetNameNode= nullptr;
_ref._addend = 0;
_ref._offsetInAtom = 0;
_ref._kind = 0;
+
+ _hasDefinedAtomAttributes = false;
+ _hasUndefinedAtomAttributes = false;
+ _hasSharedLibraryAtomAttributes = false;
+ _hasAbsoluteAtomAttributes = false;
}
-void YAMLAtomState::setName(StringRef n) {
- _name = n;
-}
-void YAMLAtomState::setRefName(StringRef n) {
- _refName = n;
+void YAMLState::makeReference() {
+ _file->_references.push_back(_ref);
+ // clear for next ref
+ _ref._target = nullptr;
+ _ref._targetNameNode= nullptr;
+ _ref._addend = 0;
+ _ref._offsetInAtom = 0;
+ _ref._kind = 0;
}
-void YAMLAtomState::setAlign2(StringRef s) {
+
+
+void YAMLState::setAlign2(StringRef s) {
if (StringRef(s).getAsInteger(10, _alignment.powerOf2))
_alignment.powerOf2 = 1;
}
-void YAMLAtomState::setFixupKind(StringRef s) {
- _ref._kind = _platform.kindFromString(StringRef(s));
+
+// For debug logging
+const char* YAMLState::stateName(State s) {
+ switch ( s ) {
+ case inError:
+ return "inError";
+ case inTop:
+ return "inTop";
+ case inDoc:
+ return "inDoc";
+ case inArch:
+ return "inArch";
+ case inMemb:
+ return "inMemb";
+ case inAtoms:
+ return "inAtoms";
+ case inAtom:
+ return "inAtom";
+ case inFixUps:
+ return "inFixUps";
+ case inFixUp:
+ return "inFixUp";
+ case inBytes:
+ return "inBytes";
+ }
+ return "unknown case";
+}
+
+// Called by parse() when recursing and switching to a new state.
+void YAMLState::moveToState(State newState) {
+ if ( newState == _state )
+ return;
+ DEBUG(llvm::dbgs() << "moveToState(" << stateName(newState)
+ << "), _state=" << stateName(_state) << "\n");
+
+ if ( newState == inArch ) {
+ // Seen "archive:", repurpose existing YAMLFile to be archive file
+ _file->_kind = File::kindArchiveLibrary;
+ _archiveFile = _file;
+ _file = nullptr;
+ }
+
+ if ( newState == inMemb ) {
+ assert(_state == inArch);
+ // Make new YAMLFile for this member
+ std::unique_ptr<YAMLFile> memberFile(new YAMLFile);
+ _file = memberFile.get();
+ assert(_archiveFile != nullptr);
+ _archiveFile->_memberFiles.emplace_back(memberFile.release());
+ }
+
+ _state = newState;
+}
+
+// Called by parse() when returning from recursion and restoring the old state.
+void YAMLState::returnToState(State prevState, Node *node) {
+ if ( prevState == _state )
+ return;
+ DEBUG(llvm::dbgs() << "returnToState(" << stateName(prevState)
+ << "), _state=" << stateName(_state) << "\n");
+ // If done with an atom, instantiate an object for it.
+ if ( (_state == inAtom) && (prevState == inAtoms) )
+ this->makeAtom(node);
+ // If done wit a fixup, instantiate an object for it.
+ if ( (_state == inFixUp) && (prevState == inFixUps) )
+ this->makeReference();
+ _state = prevState;
+}
+
+// If a string in the yaml document is quoted in a way that there is no
+// contiguous range of bytes that a StringRef can point to, then we make
+// a copy of the string and have the StringRef point to that.
+StringRef YAMLState::extractString(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ StringRef str = node->getValue(storage);
+ if ( str.data() == storage.begin() ) {
+ str = _file->copyString(str);
+ }
+ return str;
}
-void YAMLAtomState::setFixupTarget(StringRef s) {
- _ref._targetName = s;
+
+void YAMLState::parseMemberName(ScalarNode *node) {
+ _memberName = extractString(node);
}
-void YAMLAtomState::addFixup(YAMLFile *f) {
- f->_references.push_back(_ref);
- // clear for next ref
- _ref._target = nullptr;
- _ref._targetName = StringRef();
- _ref._addend = 0;
- _ref._offsetInAtom = 0;
- _ref._kind = 0;
+void YAMLState::parseAtomName(ScalarNode *node) {
+ _name = extractString(node);
}
-llvm::error_code parseFixup( llvm::yaml::MappingNode *mn
- , llvm::yaml::Stream &s
- , Platform &p
- , YAMLFile &f
- , YAMLAtomState &yas) {
- using namespace llvm::yaml;
+void YAMLState::parseAtomRefName(ScalarNode *node) {
+ _refName = extractString(node);
+}
+
+void YAMLState::parseAtomScope(ScalarNode *node) {
llvm::SmallString<32> storage;
+ if ( KeyValues::scope(node->getValue(storage), _scope) ) {
+ _stream->printError(node, "Invalid value for 'scope:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
- 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);
- }
- 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);
- }
+void YAMLState::parseAtomDefinition(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::definition(node->getValue(storage), _definition) ) {
+ _stream->printError(node, "Invalid value for 'definition:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
}
- yas.addFixup(&f);
- return make_error_code(yaml_reader_error::success);
}
-llvm::error_code parseAtom( llvm::yaml::MappingNode *mn
- , llvm::yaml::Stream &s
- , Platform &p
- , YAMLFile &f) {
- using namespace llvm::yaml;
- YAMLAtomState yas(p);
+void YAMLState::parseAtomType(ScalarNode *node) {
llvm::SmallString<32> storage;
+ if ( KeyValues::contentType(node->getValue(storage), _type) ) {
+ _stream->printError(node, "Invalid value for 'type:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
- 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);
- }
- 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);
- }
- 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);
- }
- 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 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 {
- // 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);
- }
- } 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 (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 (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 (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);
- }
- }
+void YAMLState::parseAtomDeadStrip(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::deadStripKind(node->getValue(storage), _deadStrip) ) {
+ _stream->printError(node, "Invalid value for 'dead-strip:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
}
- yas.makeAtom(f);
- return make_error_code(yaml_reader_error::success);
+ _hasDefinedAtomAttributes = true;
}
-llvm::error_code parseAtoms( llvm::yaml::SequenceNode *atoms
- , llvm::yaml::Stream &s
- , Platform &p
- , YAMLFile &f) {
- using namespace llvm::yaml;
+void YAMLState::parseAtomSectionChoice(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::sectionChoice(node->getValue(storage), _sectionChoice) ) {
+ _stream->printError(node, "Invalid value for 'section-choice:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
- 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);
- }
+void YAMLState::parseAtomInterposable(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::interposable(node->getValue(storage), _interpose) ) {
+ _stream->printError(node, "Invalid value for 'interposable:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
}
- return make_error_code(yaml_reader_error::success);
+ _hasDefinedAtomAttributes = true;
}
-llvm::error_code parseArchive( llvm::yaml::SequenceNode *archive
- , llvm::yaml::Stream &s
- , Platform &p
- , YAMLFile &f) {
- using namespace llvm::yaml;
+void YAMLState::parseAtomMerge(ScalarNode *node) {
llvm::SmallString<32> storage;
+ if ( KeyValues::merge(node->getValue(storage), _merge) ) {
+ _stream->printError(node, "Invalid value for 'merge:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
- 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);
+void YAMLState::parseAtomIsThumb(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::isThumb(node->getValue(storage), _isThumb) ) {
+ _stream->printError(node, "Invalid value for 'thumb:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomIsAlias(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::isAlias(node->getValue(storage), _isAlias) ) {
+ _stream->printError(node, "Invalid value for 'is-alias:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomSectionName(ScalarNode *node) {
+ _sectionName = extractString(node);
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomSize(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ StringRef offsetStr = node->getValue(storage);
+ if ( offsetStr.getAsInteger(0, _size) ) {
+ _stream->printError(node, "Invalid value for atom 'size:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomPermissions(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::permissions(node->getValue(storage), _permissions) ) {
+ _stream->printError(node, "Invalid value for 'permissions:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomCanBeNull(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ if ( KeyValues::canBeNull(node->getValue(storage), _canBeNull) ) {
+ _stream->printError(node, "Invalid value for 'can-be-null:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+}
+
+void YAMLState::parseFixUpOffset(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ StringRef offsetStr = node->getValue(storage);
+ if ( offsetStr.getAsInteger(0, _ref._offsetInAtom) ) {
+ _stream->printError(node, "Invalid value for fixup 'offset:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseFixUpKind(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ _ref._kind = _platform.kindFromString(node->getValue(storage));
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseFixUpTarget(ScalarNode *node) {
+ _ref._targetNameNode = node;
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseFixUpAddend(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ StringRef offsetStr = node->getValue(storage);
+ if ( offsetStr.getAsInteger(0, _ref._addend) ) {
+ _stream->printError(node, "Invalid value for fixup 'addend:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomContentByte(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ StringRef str = node->getValue(storage);
+ unsigned int contentByte;
+ if ( str.getAsInteger(16, contentByte) ) {
+ _stream->printError(node, "Invalid content hex byte '0x" + str + "'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ return;
+ }
+ if (contentByte > 0xFF) {
+ _stream->printError(node, "Content hex byte out of range (0x"
+ + str + " > 0xFF)");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ return;
+ }
+ _content.push_back(contentByte & 0xFF);
+ _hasDefinedAtomAttributes = true;
+}
+
+void YAMLState::parseAtomLoadName(ScalarNode *node) {
+ _loadName = extractString(node);
+ _hasSharedLibraryAtomAttributes = true;
+}
+
+
+void YAMLState::parseAtomValue(ScalarNode *node) {
+ llvm::SmallString<32> storage;
+ StringRef offsetStr = node->getValue(storage);
+ if ( offsetStr.getAsInteger(0, _value) ) {
+ _stream->printError(node, "Invalid value for fixup 'addend:'");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ _hasAbsoluteAtomAttributes = true;
+}
+
+//
+// This is the parsing engine that walks the nodes in the yaml document
+// stream. It is table driven. See _s_transistions.
+//
+void YAMLState::parse(Node *node, StringRef keyword, Node *keywordNode) {
+ using namespace llvm::yaml;
+ DEBUG(llvm::dbgs() << "parse(" << keyword << "), _state="
+ << stateName(_state) << "\n");
+ if ( _error )
+ return;
+ State savedState = _state;
+ for(const Transistion* t=_s_transistions; t->state != inError; ++t) {
+ if ( t->state != _state )
+ continue;
+ if ( ! keyword.equals(t->keyword) )
+ continue;
+ ParseScalar action = t->customAction;
+ this->moveToState(t->newState);
+ if ( ScalarNode *sc = llvm::dyn_cast<ScalarNode>(node) ) {
+ if ( action ) {
+ (*this.*action)(sc);
+ }
+ else {
+ _stream->printError(node, "unexpected scalar");
+ _error = 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);
+ else if ( SequenceNode *seq = llvm::dyn_cast<SequenceNode>(node) ) {
+ if ( action ) {
+ _stream->printError(node, "unexpected sequence");
+ _error = 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);
+ else {
+ for (Node &seqEntry : *seq ) {
+ this->parse(&seqEntry, StringRef("<any-seq-item>"));
+ if ( _error )
+ break;
}
- // 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);
+ }
+ }
+ else if ( MappingNode *map = llvm::dyn_cast<MappingNode>(node) ) {
+ if ( action ) {
+ _stream->printError(node, "unexpected map");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ else {
+ llvm::SmallString<32> storage;
+ for (auto &keyVal : *map) {
+ ScalarNode *keyScalar = llvm::dyn_cast<ScalarNode>(keyVal.getKey());
+ llvm::StringRef keyStr = keyScalar->getValue(storage);
+ this->parse(keyVal.getValue(), keyStr, keyScalar);
+ if ( _error )
+ break;
}
- 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));
+ else {
+ _stream->printError(node, "unexpected node type");
+ _error = make_error_code(yaml_reader_error::illegal_value);
+ }
+ this->returnToState(savedState, node);
+ return;
}
- return make_error_code(yaml_reader_error::success);
+ switch (_state) {
+ case inAtom:
+ _stream->printError(keywordNode, "Unknown atom attribute '"
+ + keyword + ":'");
+ break;
+ case inFixUp:
+ _stream->printError(keywordNode, "Unknown fixup attribute '"
+ + keyword + ":'");
+ break;
+ case inDoc:
+ _stream->printError(keywordNode, "Unknown file attribute '"
+ + keyword + ":'");
+ break;
+ default:
+ _stream->printError(keywordNode, "Unknown keyword '"
+ + keyword + ":'");
+ }
+ _error = make_error_code(yaml_reader_error::illegal_value);
}
+
/// 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()))
+ , Platform& platform
+ , std::vector<std::unique_ptr<const File>> &result) {
+ llvm::SourceMgr srcMgr;
+ llvm::yaml::Stream stream(mb->getBuffer(), srcMgr);
+
+ for (llvm::yaml::Document &d : stream) {
+ std::unique_ptr<YAMLFile> curFile(new YAMLFile);
+ if (llvm::isa<llvm::yaml::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())
+ YAMLState yamlState(platform, &stream, curFile.get());
+ yamlState.parse(d.getRoot(), StringRef("<root>"));
+
+ if ( stream.failed() )
return make_error_code(yaml_reader_error::illegal_value);
- CurFile->bindTargetReferences();
- result.emplace_back(CurFile.release());
+ if ( yamlState.error() )
+ return yamlState.error();
+
+ error_code ec = curFile->bindTargetReferences(stream);
+ if ( ec )
+ return ec;
+ 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<
- std::unique_ptr<const File>>& result) {
+error_code
+parseObjectTextFileOrSTDIN( StringRef path
+ , Platform& platform
+ , std::vector<std::unique_ptr<const File>>& result) {
OwningPtr<llvm::MemoryBuffer> mb;
if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb))
return ec;
Modified: lld/trunk/lib/Core/YamlWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=156136&r1=156135&r2=156136&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlWriter.cpp (original)
+++ lld/trunk/lib/Core/YamlWriter.cpp Thu May 3 18:55:34 2012
@@ -164,9 +164,8 @@
bool hasDash = false;
if ( !atom.name().empty() ) {
out << " - "
- << KeyValues::nameKeyword
- << ":"
- << spacePadding(KeyValues::nameKeyword)
+ << "name:"
+ << spacePadding(strlen("name"))
<< atom.name()
<< "\n";
hasDash = true;
@@ -174,9 +173,8 @@
if ( _rnb.hasRefName(&atom) ) {
out << (hasDash ? " " : " - ")
- << KeyValues::refNameKeyword
- << ":"
- << spacePadding(KeyValues::refNameKeyword)
+ << "ref-name:"
+ << spacePadding(strlen("ref-name"))
<< _rnb.refName(&atom)
<< "\n";
hasDash = true;
@@ -184,9 +182,8 @@
if ( atom.definition() != KeyValues::definitionDefault ) {
out << (hasDash ? " " : " - ")
- << KeyValues::definitionKeyword
- << ":"
- << spacePadding(KeyValues::definitionKeyword)
+ << "definition:"
+ << spacePadding(strlen("definition"))
<< KeyValues::definition(atom.definition())
<< "\n";
hasDash = true;
@@ -194,9 +191,8 @@
if ( atom.scope() != KeyValues::scopeDefault ) {
out << (hasDash ? " " : " - ")
- << KeyValues::scopeKeyword
- << ":"
- << spacePadding(KeyValues::scopeKeyword)
+ << "scope:"
+ << spacePadding(strlen("scope"))
<< KeyValues::scope(atom.scope())
<< "\n";
hasDash = true;
@@ -204,70 +200,62 @@
if ( atom.interposable() != KeyValues::interposableDefault ) {
out << " "
- << KeyValues::interposableKeyword
- << ":"
- << spacePadding(KeyValues::interposableKeyword)
+ << "interposable:"
+ << spacePadding(strlen("interposable"))
<< KeyValues::interposable(atom.interposable())
<< "\n";
}
if ( atom.merge() != KeyValues::mergeDefault ) {
out << " "
- << KeyValues::mergeKeyword
- << ":"
- << spacePadding(KeyValues::mergeKeyword)
+ << "merge:"
+ << spacePadding(strlen("merge"))
<< KeyValues::merge(atom.merge())
<< "\n";
}
if ( atom.contentType() != KeyValues::contentTypeDefault ) {
out << " "
- << KeyValues::contentTypeKeyword
- << ":"
- << spacePadding(KeyValues::contentTypeKeyword)
+ << "type:"
+ << spacePadding(strlen("type"))
<< KeyValues::contentType(atom.contentType())
<< "\n";
}
if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
out << " "
- << KeyValues::deadStripKindKeyword
- << ":"
- << spacePadding(KeyValues::deadStripKindKeyword)
+ << "dead-strip:"
+ << spacePadding(strlen("dead-strip"))
<< KeyValues::deadStripKind(atom.deadStrip())
<< "\n";
}
if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
out << " "
- << KeyValues::sectionChoiceKeyword
- << ":"
- << spacePadding(KeyValues::sectionChoiceKeyword)
+ << "section-choice:"
+ << spacePadding(strlen("section-choice"))
<< KeyValues::sectionChoice(atom.sectionChoice())
<< "\n";
assert( ! atom.customSectionName().empty() );
out << " "
- << KeyValues::sectionNameKeyword
- << ":"
- << spacePadding(KeyValues::sectionNameKeyword)
+ << "section-name:"
+ << spacePadding(strlen("section-name"))
<< atom.customSectionName()
<< "\n";
}
if ( atom.isThumb() != KeyValues::isThumbDefault ) {
out << " "
- << KeyValues::isThumbKeyword
- << ":"
- << spacePadding(KeyValues::isThumbKeyword)
+ << "is-thumb:"
+ << spacePadding(strlen("is-thumb"))
<< KeyValues::isThumb(atom.isThumb())
<< "\n";
}
if ( atom.isAlias() != KeyValues::isAliasDefault ) {
out << " "
- << KeyValues::isAliasKeyword
- << ":"
- << spacePadding(KeyValues::isAliasKeyword)
+ << "is-alias:"
+ << spacePadding(strlen("is-alias"))
<< KeyValues::isAlias(atom.isAlias())
<< "\n";
}
@@ -275,9 +263,8 @@
if ( (atom.contentType() != DefinedAtom::typeZeroFill)
&& (atom.size() != 0) ) {
out << " "
- << KeyValues::contentKeyword
- << ":"
- << spacePadding(KeyValues::contentKeyword)
+ << "content:"
+ << spacePadding(strlen("content"))
<< "[ ";
ArrayRef<uint8_t> arr = atom.rawContent();
bool needComma = false;
@@ -301,15 +288,13 @@
wroteFirstFixup = true;
}
out << " - "
- << KeyValues::fixupsOffsetKeyword
- << ":"
- << spacePadding(KeyValues::fixupsOffsetKeyword)
+ << "offset:"
+ << spacePadding(strlen("offset"))
<< ref->offsetInAtom()
<< "\n";
out << " "
- << KeyValues::fixupsKindKeyword
- << ":"
- << spacePadding(KeyValues::fixupsKindKeyword)
+ << "kind:"
+ << spacePadding(strlen("kind"))
<< _platform.kindToString(ref->kind())
<< "\n";
const Atom* target = ref->target();
@@ -319,17 +304,15 @@
refName = _rnb.refName(target);
assert(!refName.empty());
out << " "
- << KeyValues::fixupsTargetKeyword
- << ":"
- << spacePadding(KeyValues::fixupsTargetKeyword)
+ << "target:"
+ << spacePadding(strlen("target"))
<< refName
<< "\n";
}
if ( ref->addend() != 0 ) {
out << " "
- << KeyValues::fixupsAddendKeyword
- << ":"
- << spacePadding(KeyValues::fixupsAddendKeyword)
+ << "addend:"
+ << spacePadding(strlen("addend"))
<< ref->addend()
<< "\n";
}
@@ -348,24 +331,21 @@
}
out << " - "
- << KeyValues::nameKeyword
- << ":"
- << spacePadding(KeyValues::nameKeyword)
+ << "name:"
+ << spacePadding(strlen("name"))
<< atom.name()
<< "\n";
out << " "
- << KeyValues::definitionKeyword
- << ":"
- << spacePadding(KeyValues::definitionKeyword)
+ << "definition:"
+ << spacePadding(strlen("definition"))
<< KeyValues::definition(atom.definition())
<< "\n";
if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
out << " "
- << KeyValues::canBeNullKeyword
- << ":"
- << spacePadding(KeyValues::canBeNullKeyword)
+ << "can-be-null:"
+ << spacePadding(strlen("can-be-null"))
<< KeyValues::canBeNull(atom.canBeNull())
<< "\n";
}
@@ -382,33 +362,29 @@
}
out << " - "
- << KeyValues::nameKeyword
- << ":"
- << spacePadding(KeyValues::nameKeyword)
+ << "name:"
+ << spacePadding(strlen("name"))
<< atom.name()
<< "\n";
out << " "
- << KeyValues::definitionKeyword
- << ":"
- << spacePadding(KeyValues::definitionKeyword)
+ << "definition:"
+ << spacePadding(strlen("definition"))
<< KeyValues::definition(atom.definition())
<< "\n";
if ( !atom.loadName().empty() ) {
out << " "
- << KeyValues::loadNameKeyword
- << ":"
- << spacePadding(KeyValues::loadNameKeyword)
+ << "load-name:"
+ << spacePadding(strlen("load-name"))
<< atom.loadName()
<< "\n";
}
if ( atom.canBeNullAtRuntime() ) {
out << " "
- << KeyValues::canBeNullKeyword
- << ":"
- << spacePadding(KeyValues::canBeNullKeyword)
+ << "can-be-null:"
+ << spacePadding(strlen("can-be-null"))
<< KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
<< "\n";
}
@@ -425,23 +401,20 @@
}
out << " - "
- << KeyValues::nameKeyword
- << ":"
- << spacePadding(KeyValues::nameKeyword)
+ << "name:"
+ << spacePadding(strlen("name"))
<< atom.name()
<< "\n";
out << " "
- << KeyValues::definitionKeyword
- << ":"
- << spacePadding(KeyValues::definitionKeyword)
+ << "definition:"
+ << spacePadding(strlen("definition"))
<< KeyValues::definition(atom.definition())
<< "\n";
out << " "
- << KeyValues::valueKeyword
- << ":"
- << spacePadding(KeyValues::valueKeyword)
+ << "value:"
+ << spacePadding(strlen("value"))
<< "0x";
out.write_hex(atom.value());
out << "\n";
@@ -450,10 +423,10 @@
private:
// return a string of the correct number of spaces to align value
- const char* spacePadding(const char* key) {
+ const char* spacePadding(int keyLen) {
const char* spaces = " ";
- assert(strlen(spaces) > strlen(key));
- return &spaces[strlen(key)];
+ assert(strlen(spaces) > keyLen);
+ return &spaces[keyLen];
}
char hexdigit(uint8_t nibble) {
Modified: lld/trunk/test/archive-tentdef-search.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/archive-tentdef-search.objtxt?rev=156136&r1=156135&r2=156136&view=diff
==============================================================================
--- lld/trunk/test/archive-tentdef-search.objtxt (original)
+++ lld/trunk/test/archive-tentdef-search.objtxt Thu May 3 18:55:34 2012
@@ -14,7 +14,7 @@
- name: bar
scope: global
- content: zero-fill
+ type: zero-fill
merge: asTentative
---
Added: lld/trunk/test/error-atom-attribute.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-atom-attribute.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-atom-attribute.objtxt (added)
+++ lld/trunk/test/error-atom-attribute.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,19 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that unknown atom attribute produces a readable error.
+#
+
+---
+atoms:
+ - name: entry
+ scope: hidden
+ foobar: true
+ dead-strip: never
+
+...
+
+
+# CHECK: error: Unknown atom attribute
+# CHECK: foobar
Added: lld/trunk/test/error-atom-content-byte-value.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-atom-content-byte-value.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-atom-content-byte-value.objtxt (added)
+++ lld/trunk/test/error-atom-content-byte-value.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,18 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that an invalid hex byte produces a readable error.
+#
+
+---
+atoms:
+ - name: entry
+ scope: hidden
+ content: [ A5, 00, 4G, 1F ]
+
+...
+
+
+# CHECK: error: Invalid content hex byte
+# CHECK: 4G
Added: lld/trunk/test/error-atom-content-bytes.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-atom-content-bytes.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-atom-content-bytes.objtxt (added)
+++ lld/trunk/test/error-atom-content-bytes.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,19 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that an out of range byte value produces a readable error.
+#
+
+---
+atoms:
+ - name: entry
+ scope: hidden
+ content: [ A5, 1234, 00, 4F ]
+
+...
+
+
+# CHECK: error: Content hex byte out of range
+# CHECK: 1234
+
Added: lld/trunk/test/error-atom-type.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-atom-type.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-atom-type.objtxt (added)
+++ lld/trunk/test/error-atom-type.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,19 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that an unknown content type produces a readable error.
+#
+
+---
+atoms:
+ - name: entry
+ scope: hidden
+ type: superluminal
+ dead-strip: never
+
+...
+
+
+# CHECK: error: Invalid value for 'type:'
+# CHECK: superluminal
Added: lld/trunk/test/error-atom-undefined-wrong-attribue.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-atom-undefined-wrong-attribue.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-atom-undefined-wrong-attribue.objtxt (added)
+++ lld/trunk/test/error-atom-undefined-wrong-attribue.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,18 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that a defined attribute on an undefined atom produces a readable error.
+#
+
+---
+atoms:
+ - name: foo
+ type: code
+ definition: undefined
+
+...
+
+
+# CHECK: error: Undefined atom 'foo' has attributes only allowed on defined atoms
+
Added: lld/trunk/test/error-file-attribute.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-file-attribute.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-file-attribute.objtxt (added)
+++ lld/trunk/test/error-file-attribute.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,18 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that unknown file attribute produces a readable error.
+#
+
+---
+aardvark: true
+atoms:
+ - name: entry
+ scope: hidden
+
+...
+
+
+# CHECK: error: Unknown file attribute
+# CHECK: aardvark
Added: lld/trunk/test/error-fixup-attribute.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-fixup-attribute.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-fixup-attribute.objtxt (added)
+++ lld/trunk/test/error-fixup-attribute.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,22 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that unknown fixup attribute produces a readable error.
+#
+
+---
+atoms:
+ - name: entry
+ scope: hidden
+ fixups:
+ - offset: 3
+ kind: 3
+ weasel: bar
+ addend: 100
+
+...
+
+
+# CHECK: error: Unknown fixup attribute
+# CHECK: weasel
Added: lld/trunk/test/error-fixup-target.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/error-fixup-target.objtxt?rev=156136&view=auto
==============================================================================
--- lld/trunk/test/error-fixup-target.objtxt (added)
+++ lld/trunk/test/error-fixup-target.objtxt Thu May 3 18:55:34 2012
@@ -0,0 +1,27 @@
+# RUN: not lld-core %s 2> %t.err
+# RUN: FileCheck < %t.err %s
+
+#
+# Test that unbindable target name produces a readable error.
+#
+
+---
+atoms:
+ - name: entry
+ scope: hidden
+ fixups:
+ - offset: 3
+ kind: 3
+ target: bar
+ - offset: 5
+ kind: 3
+ target: baz
+
+ - name: bar
+ definition: undefined
+
+...
+
+
+# CHECK: error: Fixup has target 'baz' which does not exist
+# CHECK: baz
More information about the llvm-commits
mailing list