summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/YAML/ReaderYAML.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/YAML/ReaderYAML.cpp')
-rw-r--r--lld/lib/ReaderWriter/YAML/ReaderYAML.cpp1264
1 files changed, 0 insertions, 1264 deletions
diff --git a/lld/lib/ReaderWriter/YAML/ReaderYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderYAML.cpp
deleted file mode 100644
index bb0a2726f89..00000000000
--- a/lld/lib/ReaderWriter/YAML/ReaderYAML.cpp
+++ /dev/null
@@ -1,1264 +0,0 @@
-//===- lib/ReaderWriter/YAML/ReaderYAML.cpp - Reads YAML object files -----===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/ReaderYAML.h"
-
-#include "lld/Core/AbsoluteAtom.h"
-#include "lld/Core/ArchiveLibraryFile.h"
-#include "lld/Core/Atom.h"
-#include "lld/Core/Error.h"
-#include "lld/Core/File.h"
-#include "lld/Core/LLVM.h"
-#include "lld/Core/Reference.h"
-#include "lld/Core/SharedLibraryAtom.h"
-#include "lld/Core/UndefinedAtom.h"
-
-#include "llvm/ADT/APInt.h"
-#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/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/system_error.h"
-#include "llvm/Support/YAMLParser.h"
-
-#include <cstring>
-#include <vector>
-
-#include "YamlKeyValues.h"
-
-
-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)
- {}
-
- virtual uint64_t offsetInAtom() const {
- return _offsetInAtom;
- }
-
- virtual Kind kind() const {
- return _kind;
- }
-
- virtual void setKind(Kind k) {
- _kind = k;
- }
-
- virtual const Atom *target() const {
- return _target;
- }
-
- virtual Addend addend() const {
- return _addend;
- }
-
- virtual void setAddend(Addend a) {
- _addend = a;
- }
-
- virtual void setTarget(const Atom *newAtom) {
- _target = newAtom;
- }
-
- typedef llvm::yaml::ScalarNode ScalarNode;
-
- const Atom *_target;
- ScalarNode * _targetNameNode;
- uint64_t _offsetInAtom;
- Addend _addend;
- Kind _kind;
-};
-
-
-///
-/// Concrete instance of lld::File created parsing YAML object files.
-///
-class YAMLFile : public ArchiveLibraryFile {
-public:
- YAMLFile()
- : ArchiveLibraryFile("<anonymous>")
- , _lastRefIndex(0)
- , _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;
- }
-
- virtual const atom_collection<DefinedAtom> &defined() const {
- return _definedAtoms;
- }
- virtual const atom_collection<UndefinedAtom> &undefined() const {
- return _undefinedAtoms;
- }
- virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
- return _sharedLibraryAtoms;
- }
- virtual const atom_collection<AbsoluteAtom> &absolute() const {
- return _absoluteAtoms;
- }
-
- virtual void addAtom(const Atom&) {
- assert(0 && "cannot add atoms to YAML files");
- }
-
- // Standard way that archives are searched.
- virtual const File *find(StringRef name, bool dataSymbolOnly) const;
-
- 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);
- Atom *findAtom(StringRef name);
- void addMember(StringRef);
- void setName(StringRef);
-
- StringRef copyString(StringRef);
-
- struct NameAtomPair {
- 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<std::unique_ptr<YAMLFile>> _memberFiles;
- std::vector<char*> _stringCopies;
- unsigned int _lastRefIndex;
- File::Kind _kind;
-};
-
-
-
-///
-/// Concrete instance of lld::DefinedAtom created parsing YAML object files.
-///
-class YAMLDefinedAtom : public DefinedAtom {
-public:
- YAMLDefinedAtom( uint32_t ord
- , YAMLFile &file
- , DefinedAtom::Scope scope
- , DefinedAtom::ContentType type
- , DefinedAtom::SectionChoice sectionChoice
- , DefinedAtom::Interposable interpose
- , DefinedAtom::Merge merge
- , DefinedAtom::DeadStripKind deadStrip
- , DefinedAtom::ContentPermissions perms
- , bool isThumb
- , bool isAlias
- , DefinedAtom::Alignment alignment
- , StringRef name
- , StringRef sectionName
- , uint64_t size
- , std::vector<uint8_t>& content)
- : _file(file)
- , _name(name)
- , _sectionName(sectionName)
- , _size(size)
- , _ord(ord)
- , _content(content)
- , _alignment(alignment)
- , _scope(scope)
- , _type(type)
- , _sectionChoice(sectionChoice)
- , _interpose(interpose)
- , _merge(merge)
- , _deadStrip(deadStrip)
- , _permissions(perms)
- , _isThumb(isThumb)
- , _isAlias(isAlias)
- , _refStartIndex(file._lastRefIndex)
- , _refEndIndex(file._references.size()) {
- file._lastRefIndex = _refEndIndex;
- }
-
- virtual const class File &file() const {
- return _file;
- }
-
- virtual StringRef name() const {
- return _name;
- }
-
- virtual uint64_t size() const {
- return _content.empty() ? _size : _content.size();
- }
-
- virtual DefinedAtom::Scope scope() const {
- return _scope;
- }
-
- virtual DefinedAtom::Interposable interposable() const {
- return _interpose;
- }
-
- virtual DefinedAtom::Merge merge() const {
- return _merge;
- }
-
- virtual DefinedAtom::ContentType contentType() const {
- return _type;
- }
-
- virtual DefinedAtom::Alignment alignment() const {
- return _alignment;
- }
-
- virtual DefinedAtom::SectionChoice sectionChoice() const {
- return _sectionChoice;
- }
-
- virtual StringRef customSectionName() const {
- return _sectionName;
- }
-
- virtual DefinedAtom::DeadStripKind deadStrip() const {
- return _deadStrip;
- }
-
- virtual DefinedAtom::ContentPermissions permissions() const {
- return _permissions;
- }
-
- virtual bool isThumb() const {
- return _isThumb;
- }
-
- virtual bool isAlias() const {
- return _isAlias;
- }
-
- ArrayRef<uint8_t> rawContent() const {
- return ArrayRef<uint8_t>(_content);
- }
-
- virtual uint64_t ordinal() const {
- return _ord;
- }
-
- DefinedAtom::reference_iterator begin() const {
- uintptr_t index = _refStartIndex;
- const void* it = reinterpret_cast<const void*>(index);
- return reference_iterator(*this, it);
- }
-
- DefinedAtom::reference_iterator end() const {
- uintptr_t index = _refEndIndex;
- const void* it = reinterpret_cast<const void*>(index);
- return reference_iterator(*this, it);
- }
-
- const Reference* derefIterator(const void* it) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(it);
- assert(index >= _refStartIndex);
- assert(index < _refEndIndex);
- assert(index < _file._references.size());
- return &_file._references[index];
- }
-
- void incrementIterator(const void*& it) const {
- uintptr_t index = reinterpret_cast<uintptr_t>(it);
- ++index;
- it = reinterpret_cast<const void*>(index);
- }
-
- // 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) {
- 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:
- YAMLFile &_file;
- StringRef _name;
- StringRef _sectionName;
- unsigned long _size;
- uint32_t _ord;
- std::vector<uint8_t> _content;
- DefinedAtom::Alignment _alignment;
- DefinedAtom::Scope _scope;
- DefinedAtom::ContentType _type;
- DefinedAtom::SectionChoice _sectionChoice;
- DefinedAtom::Interposable _interpose;
- DefinedAtom::Merge _merge;
- DefinedAtom::DeadStripKind _deadStrip;
- DefinedAtom::ContentPermissions _permissions;
- bool _isThumb;
- bool _isAlias;
- unsigned int _refStartIndex;
- unsigned int _refEndIndex;
-};
-
-
-
-///
-/// Concrete instance of lld::UndefinedAtom created parsing YAML object files.
-///
-class YAMLUndefinedAtom : public UndefinedAtom {
-public:
- YAMLUndefinedAtom( YAMLFile &f
- , int32_t
- , StringRef name
- , UndefinedAtom::CanBeNull cbn)
- : _file(f)
- , _name(name)
- , _canBeNull(cbn) {
- }
-
- virtual const class File &file() const {
- return _file;
- }
-
- virtual StringRef name() const {
- return _name;
- }
-
- virtual CanBeNull canBeNull() const {
- return _canBeNull;
- }
-
-private:
- YAMLFile &_file;
- StringRef _name;
- UndefinedAtom::CanBeNull _canBeNull;
-};
-
-
-
-///
-/// Concrete instance of lld::SharedLibraryAtom created parsing YAML files.
-///
-class YAMLSharedLibraryAtom : public SharedLibraryAtom {
-public:
- YAMLSharedLibraryAtom( YAMLFile &f
- , int32_t
- , StringRef name
- , StringRef loadName
- , bool cbn)
- : _file(f)
- , _name(name)
- , _loadName(loadName)
- , _canBeNull(cbn) {
- }
-
- virtual const class File &file() const {
- return _file;
- }
-
- virtual StringRef name() const {
- return _name;
- }
-
- virtual StringRef loadName() const {
- return _loadName;
- }
-
- virtual bool canBeNullAtRuntime() const {
- return _canBeNull;
- }
-
-private:
- YAMLFile &_file;
- StringRef _name;
- StringRef _loadName;
- bool _canBeNull;
-};
-
-
-
-///
-/// Concrete instance of lld::AbsoluteAtom created parsing YAML object files.
-///
-class YAMLAbsoluteAtom : public AbsoluteAtom {
-public:
- YAMLAbsoluteAtom(YAMLFile &f, int32_t, StringRef name, uint64_t v, Atom::Scope scope)
- : _file(f)
- , _name(name)
- , _value(v)
- , _scope(scope){
- }
-
- virtual const class File &file() const {
- return _file;
- }
-
- virtual Scope scope() const {
- return _scope;
- }
-
- virtual StringRef name() const {
- return _name;
- }
-
- virtual uint64_t value() const {
- return _value;
- }
-
-private:
- YAMLFile &_file;
- StringRef _name;
- uint64_t _value;
- Atom::Scope _scope;
-};
-
-
-
-
-//===----------------------------------------------------------------------===//
-// 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);
- ec = atom->bindTargetReferences(stream);
- if ( ec )
- return ec;
- }
- return ec;
-}
-
-Atom *YAMLFile::findAtom(StringRef name) {
- for (auto &ci : _nameToAtomMapping) {
- if (ci.name == name)
- return ci.atom;
- }
- return nullptr;
-}
-
-void YAMLFile::addDefinedAtom(YAMLDefinedAtom *atom, StringRef refName) {
- _definedAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(refName, atom));
-}
-
-void YAMLFile::addUndefinedAtom(UndefinedAtom *atom) {
- _undefinedAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
-}
-
-void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom *atom) {
- _sharedLibraryAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
-}
-
-void YAMLFile::addAbsoluteAtom(AbsoluteAtom *atom) {
- _absoluteAtoms._atoms.push_back(atom);
- _nameToAtomMapping.push_back(NameAtomPair(atom->name(), atom));
-}
-
-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() ) {
- if (name == atom->name())
- return file.get();
- }
- }
- return nullptr;
-}
-
-
-
-///
-/// 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:
- YAMLState(const ReaderOptionsYAML &opts, llvm::yaml::Stream *s, YAMLFile *f);
-
- 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 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 moveToState(State s);
- void returnToState(State s, Node *node);
-
- static const Transistion _s_transistions[];
-
- const ReaderOptionsYAML &_options;
- 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;
- std::vector<uint8_t> _content;
- DefinedAtom::Alignment _alignment;
- Atom::Definition _definition;
- DefinedAtom::Scope _scope;
- DefinedAtom::ContentType _type;
- DefinedAtom::SectionChoice _sectionChoice;
- DefinedAtom::Interposable _interpose;
- DefinedAtom::Merge _merge;
- DefinedAtom::DeadStripKind _deadStrip;
- DefinedAtom::ContentPermissions _permissions;
- bool _isThumb;
- 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 },
-};
-
-
-
-YAMLState::YAMLState(const ReaderOptionsYAML &opts, Stream *stream,
- YAMLFile *file)
- : _options(opts)
- , _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,
- _scope);
- _file->addAbsoluteAtom(a);
-}
-
-
-
-void YAMLState::resetState() {
- _name = StringRef();
- _refName = StringRef();
- _sectionName = StringRef();
- _loadName = StringRef();
- _memberName = 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._targetNameNode= nullptr;
- _ref._addend = 0;
- _ref._offsetInAtom = 0;
- _ref._kind = 0;
-
- _hasDefinedAtomAttributes = false;
- _hasUndefinedAtomAttributes = false;
- _hasSharedLibraryAtomAttributes = false;
- _hasAbsoluteAtomAttributes = false;
-}
-
-
-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 YAMLState::setAlign2(StringRef s) {
- if (StringRef(s).getAsInteger(10, _alignment.powerOf2))
- _alignment.powerOf2 = 1;
-}
-
-
-// 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_WITH_TYPE("objtxt", 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_WITH_TYPE("objtxt", 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 YAMLState::parseMemberName(ScalarNode *node) {
- _memberName = extractString(node);
-}
-
-void YAMLState::parseAtomName(ScalarNode *node) {
- _name = extractString(node);
-}
-
-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);
- }
-}
-
-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);
- }
-}
-
-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;
-}
-
-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);
- }
- _hasDefinedAtomAttributes = true;
-}
-
-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;
-}
-
-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);
- }
- _hasDefinedAtomAttributes = true;
-}
-
-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;
-}
-
-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 = _options.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_WITH_TYPE("objtxt", 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);
- }
- }
- 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);
- }
- else {
- for (Node &seqEntry : *seq ) {
- this->parse(&seqEntry, StringRef("<any-seq-item>"));
- if ( _error )
- break;
- }
- }
- }
- 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;
- }
- }
- }
- else {
- _stream->printError(node, "unexpected node type");
- _error = make_error_code(yaml_reader_error::illegal_value);
- }
- this->returnToState(savedState, node);
- return;
- }
- 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);
-}
-
-
-/// parseFile - Parse the specified YAML formatted MemoryBuffer
-/// into lld::File object(s) and append each to the specified vector<File*>.
-static error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
- const ReaderOptionsYAML &options,
- std::vector<std::unique_ptr<File>> &result) {
- llvm::SourceMgr srcMgr;
- llvm::yaml::Stream stream(mb->getBuffer(), srcMgr);
-
- for (llvm::yaml::Document &d : stream) {
- std::unique_ptr<yaml::YAMLFile> curFile(new yaml::YAMLFile);
- if (llvm::isa<llvm::yaml::NullNode>(d.getRoot()))
- continue; // Empty files are allowed.
- yaml::YAMLState yamlState(options, &stream, curFile.get());
- yamlState.parse(d.getRoot(), StringRef("<root>"));
-
- if ( stream.failed() )
- return make_error_code(yaml_reader_error::illegal_value);
- 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);
-}
-
-
-
-} // namespace yaml
-
-
-
-class ReaderYAML: public Reader {
-public:
- ReaderYAML(const ReaderOptionsYAML &options) : _options(options) {
- }
-
- error_code parseFile(std::unique_ptr<MemoryBuffer> mb,
- std::vector<std::unique_ptr<File>> &result) {
- return lld::yaml::parseFile(mb, _options, result);
- }
-
-private:
- const ReaderOptionsYAML &_options;
-};
-
-
-
-Reader* createReaderYAML(const ReaderOptionsYAML &options) {
- return new ReaderYAML(options);
-}
-
-ReaderOptionsYAML::ReaderOptionsYAML() {
-}
-
-ReaderOptionsYAML::~ReaderOptionsYAML() {
-}
-
-
-
-
-} // namespace lld
OpenPOWER on IntegriCloud