(no commit message)
llvm-svn: 150539
diff --git a/lld/lib/Core/YamlReader.cpp b/lld/lib/Core/YamlReader.cpp
index 37c6382..d5e60eb 100644
--- a/lld/lib/Core/YamlReader.cpp
+++ b/lld/lib/Core/YamlReader.cpp
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include <string.h>
+
#include "YamlKeyValues.h"
#include "lld/Core/YamlReader.h"
@@ -30,6 +32,8 @@
namespace lld {
namespace yaml {
+namespace {
+
class YAML {
public:
struct Entry {
@@ -214,7 +218,7 @@
sequenceBytes->push_back(contentByte);
state = inValueSequenceEnd;
}
- else if (c == ' ') {
+ else if ( (c == ' ') || (c == '\n') ) {
// eat white space
}
else if (c == ',') {
@@ -245,6 +249,44 @@
}
}
+
+
+class YAMLReference : public Reference {
+public:
+ YAMLReference() : _target(NULL), _targetName(NULL),
+ _offsetInAtom(0), _addend(0), _kind(0) { }
+
+ virtual uint64_t offsetInAtom() const {
+ return _offsetInAtom;
+ }
+
+ virtual Kind kind() const {
+ return _kind;
+ }
+
+ virtual const Atom* target() const {
+ return _target;
+ }
+
+ virtual Addend addend() const {
+ return _addend;
+ }
+
+ virtual void setTarget(const Atom* newAtom) {
+ _target = newAtom;
+ }
+
+ const Atom* _target;
+ const char* _targetName;
+ uint64_t _offsetInAtom;
+ Addend _addend;
+ Kind _kind;
+};
+
+
+
+class YAMLDefinedAtom;
+
class YAMLFile : public File {
public:
YAMLFile()
@@ -255,29 +297,24 @@
virtual bool justInTimeforEachAtom(llvm::StringRef name,
File::AtomHandler &) const;
- std::vector<DefinedAtom*> _definedAtoms;
- std::vector<UndefinedAtom*> _undefinedAtoms;
- std::vector<Reference> _references;
- unsigned int _lastRefIndex;
+ void bindTargetReferences();
+ void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
+ void addUndefinedAtom(UndefinedAtom* atom);
+ Atom* findAtom(const char* name);
+
+ struct NameAtomPair {
+ NameAtomPair(const char* n, Atom* a) : name(n), atom(a) {}
+ const char* name;
+ Atom* atom;
+ };
+
+ std::vector<YAMLDefinedAtom*> _definedAtoms;
+ std::vector<UndefinedAtom*> _undefinedAtoms;
+ std::vector<YAMLReference> _references;
+ std::vector<NameAtomPair> _nameToAtomMapping;
+ unsigned int _lastRefIndex;
};
-bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
- handler.doFile(*this);
- for (std::vector<DefinedAtom *>::const_iterator it = _definedAtoms.begin();
- it != _definedAtoms.end(); ++it) {
- handler.doDefinedAtom(**it);
- }
- for (std::vector<UndefinedAtom *>::const_iterator it = _undefinedAtoms.begin();
- it != _undefinedAtoms.end(); ++it) {
- handler.doUndefinedAtom(**it);
- }
- return true;
-}
-
-bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
- File::AtomHandler &handler) const {
- return false;
-}
class YAMLDefinedAtom : public DefinedAtom {
@@ -291,7 +328,6 @@
, DefinedAtom::Merge merge
, DefinedAtom::DeadStripKind deadStrip
, DefinedAtom::ContentPermissions perms
- , bool internalName
, bool isThumb
, bool isAlias
, DefinedAtom::Alignment alignment
@@ -313,7 +349,6 @@
, _merge(merge)
, _deadStrip(deadStrip)
, _permissions(perms)
- , _internalName(internalName)
, _isThumb(isThumb)
, _isAlias(isAlias)
, _refStartIndex(file._lastRefIndex)
@@ -326,13 +361,12 @@
}
virtual llvm::StringRef name() const {
- return _name;
+ if ( _name == NULL )
+ return llvm::StringRef();
+ else
+ return _name;
}
- virtual bool internalName() const {
- return _internalName;
- }
-
virtual uint64_t size() const {
return (_content ? _content->size() : _size);
}
@@ -393,16 +427,18 @@
}
- virtual Reference::iterator referencesBegin() const {
- if (_file._references.size() < _refStartIndex)
- return (Reference::iterator)&_file._references[_refStartIndex];
- return 0;
+ virtual void forEachReference(ReferenceHandler& handler) const {
+ for (uint32_t i=_refStartIndex; i < _refEndIndex; ++i) {
+ handler.doReference(_file._references[i]);
+ }
}
-
- virtual Reference::iterator referencesEnd() const {
- if (_file._references.size() < _refEndIndex)
- return (Reference::iterator)&_file._references[_refEndIndex];
- return 0;
+
+ void bindTargetReferences() {
+ for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
+ const char* targetName = _file._references[i]._targetName;
+ Atom* targetAtom = _file.findAtom(targetName);
+ _file._references[i]._target = targetAtom;
+ }
}
private:
@@ -420,7 +456,6 @@
DefinedAtom::Merge _merge;
DefinedAtom::DeadStripKind _deadStrip;
DefinedAtom::ContentPermissions _permissions;
- bool _internalName;
bool _isThumb;
bool _isAlias;
unsigned int _refStartIndex;
@@ -453,22 +488,71 @@
};
+bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
+ handler.doFile(*this);
+ for (std::vector<YAMLDefinedAtom *>::const_iterator it = _definedAtoms.begin();
+ it != _definedAtoms.end(); ++it) {
+ handler.doDefinedAtom(**it);
+ }
+ for (std::vector<UndefinedAtom *>::const_iterator it = _undefinedAtoms.begin();
+ it != _undefinedAtoms.end(); ++it) {
+ handler.doUndefinedAtom(**it);
+ }
+ return true;
+}
+
+bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
+ File::AtomHandler &handler) const {
+ return false;
+}
+
+void YAMLFile::bindTargetReferences() {
+ for (std::vector<YAMLDefinedAtom *>::const_iterator
+ it = _definedAtoms.begin(); it != _definedAtoms.end(); ++it) {
+ YAMLDefinedAtom* atom = *it;
+ atom->bindTargetReferences();
+ }
+}
+
+Atom* YAMLFile::findAtom(const char* name) {
+ for (std::vector<NameAtomPair>::const_iterator it = _nameToAtomMapping.begin();
+ it != _nameToAtomMapping.end(); ++it) {
+ if ( strcmp(name, it->name) == 0 )
+ return it->atom;
+ }
+ llvm::report_fatal_error("reference to atom that does not exist");
+}
+
+void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName) {
+ _definedAtoms.push_back(atom);
+ assert(refName != NULL);
+ _nameToAtomMapping.push_back(NameAtomPair(refName, atom));
+}
+
+void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
+ _undefinedAtoms.push_back(atom);
+ _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
+}
+
class YAMLAtomState {
public:
YAMLAtomState();
void setName(const char *n);
+ void setRefName(const char *n);
void setAlign2(const char *n);
void setFixupKind(const char *n);
void setFixupOffset(const char *n);
void setFixupTarget(const char *n);
+ void setFixupAddend(const char *n);
void addFixup(YAMLFile *f);
void makeAtom(YAMLFile&);
const char * _name;
+ const char * _refName;
const char * _sectionName;
unsigned long long _size;
uint32_t _ordinal;
@@ -482,16 +566,16 @@
DefinedAtom::Merge _merge;
DefinedAtom::DeadStripKind _deadStrip;
DefinedAtom::ContentPermissions _permissions;
- bool _internalName;
bool _isThumb;
bool _isAlias;
bool _weakImport;
- Reference _ref;
+ YAMLReference _ref;
};
YAMLAtomState::YAMLAtomState()
: _name(NULL)
+ , _refName(NULL)
, _sectionName(NULL)
, _size(0)
, _ordinal(0)
@@ -505,38 +589,31 @@
, _merge(KeyValues::mergeDefault)
, _deadStrip(KeyValues::deadStripKindDefault)
, _permissions(KeyValues::permissionsDefault)
- , _internalName(KeyValues::internalNameDefault)
, _isThumb(KeyValues::isThumbDefault)
, _isAlias(KeyValues::isAliasDefault)
, _weakImport(false)
{
- _ref.target = NULL;
- _ref.addend = 0;
- _ref.offsetInAtom = 0;
- _ref.kind = 0;
- _ref.flags = 0;
-}
+ }
void YAMLAtomState::makeAtom(YAMLFile& f) {
if ( _definition == Atom::definitionRegular ) {
- DefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
+ YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
_sectionChoice, _interpose, _merge, _deadStrip,
- _permissions, _internalName, _isThumb, _isAlias,
+ _permissions, _isThumb, _isAlias,
_alignment, _name, _sectionName, _size, _content);
-
- f._definedAtoms.push_back(a);
+ f.addDefinedAtom(a, _refName ? _refName : _name);
++_ordinal;
}
else if ( _definition == Atom::definitionUndefined ) {
UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _weakImport);
-
- f._undefinedAtoms.push_back(a);
+ f.addUndefinedAtom(a);
++_ordinal;
}
// reset state for next atom
_name = NULL;
+ _refName = NULL;
_sectionName = NULL;
_size = 0;
_ordinal = 0;
@@ -554,17 +631,20 @@
_isThumb = KeyValues::isThumbDefault;
_isAlias = KeyValues::isAliasDefault;
_weakImport = KeyValues::weakImportDefault;
- _ref.target = NULL;
- _ref.addend = 0;
- _ref.offsetInAtom = 0;
- _ref.kind = 0;
- _ref.flags = 0;
+ _ref._target = NULL;
+ _ref._targetName = NULL;
+ _ref._addend = 0;
+ _ref._offsetInAtom = 0;
+ _ref._kind = 0;
}
void YAMLAtomState::setName(const char *n) {
_name = n;
}
+void YAMLAtomState::setRefName(const char *n) {
+ _refName = n;
+}
void YAMLAtomState::setAlign2(const char *s) {
llvm::StringRef str(s);
@@ -576,33 +656,54 @@
void YAMLAtomState::setFixupKind(const char *s) {
if (strcmp(s, "pcrel32") == 0)
- _ref.kind = 1;
+ _ref._kind = 1;
else if (strcmp(s, "call32") == 0)
- _ref.kind = 2;
- else
- llvm::report_fatal_error("bad fixup kind value");
+ _ref._kind = 2;
+ else {
+ int k;
+ llvm::StringRef(s).getAsInteger(10, k);
+ _ref._kind = k;
+ }
}
void YAMLAtomState::setFixupOffset(const char *s) {
if ((s[0] == '0') && (s[1] == 'x'))
- llvm::StringRef(s).getAsInteger(16, _ref.offsetInAtom);
+ llvm::StringRef(s).getAsInteger(16, _ref._offsetInAtom);
else
- llvm::StringRef(s).getAsInteger(10, _ref.offsetInAtom);
+ llvm::StringRef(s).getAsInteger(10, _ref._offsetInAtom);
}
void YAMLAtomState::setFixupTarget(const char *s) {
+ _ref._targetName = s;
}
+void YAMLAtomState::setFixupAddend(const char *s) {
+ if ((s[0] == '0') && (s[1] == 'x'))
+ llvm::StringRef(s).getAsInteger(16, _ref._addend);
+ else
+ llvm::StringRef(s).getAsInteger(10, _ref._addend);
+}
+
+
void YAMLAtomState::addFixup(YAMLFile *f) {
f->_references.push_back(_ref);
// clear for next ref
- _ref.target = NULL;
- _ref.addend = 0;
- _ref.offsetInAtom = 0;
- _ref.kind = 0;
- _ref.flags = 0;
+ _ref._target = NULL;
+ _ref._targetName = NULL;
+ _ref._addend = 0;
+ _ref._offsetInAtom = 0;
+ _ref._kind = 0;
}
+
+} // anonymous namespace
+
+
+
+
+
+/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
+/// into lld::File object(s) and append each to the specified vector<File*>.
llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
, std::vector<File *> &result) {
std::vector<const YAML::Entry *> entries;
@@ -628,6 +729,7 @@
atomState.makeAtom(*file);
haveAtom = false;
}
+ file->bindTargetReferences();
result.push_back(file);
}
file = new YAMLFile();
@@ -663,10 +765,10 @@
atomState.setName(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, KeyValues::internalNameKeyword) == 0) {
- atomState._internalName = KeyValues::internalName(entry->value);
+ else if (strcmp(entry->key, KeyValues::refNameKeyword) == 0) {
+ atomState.setRefName(entry->value);
haveAtom = true;
- }
+ }
else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
atomState._definition = KeyValues::definition(entry->value);
haveAtom = true;
@@ -725,8 +827,9 @@
atomState.setAlign2(entry->value);
haveAtom = true;
}
- else if (strcmp(entry->key, "fixups") == 0) {
+ else if (strcmp(entry->key, KeyValues::fixupsKeyword) == 0) {
inFixups = true;
+
}
else {
return make_error_code(yaml_reader_error::unknown_keyword);
@@ -739,16 +842,22 @@
haveFixup = false;
}
}
- if (strcmp(entry->key, "kind") == 0) {
+ if (strcmp(entry->key, KeyValues::fixupsKindKeyword) == 0) {
atomState.setFixupKind(entry->value);
haveFixup = true;
- } else if (strcmp(entry->key, "offset") == 0) {
+ }
+ else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0) {
atomState.setFixupOffset(entry->value);
haveFixup = true;
- } else if (strcmp(entry->key, "target") == 0) {
+ }
+ else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0) {
atomState.setFixupTarget(entry->value);
haveFixup = true;
}
+ else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0) {
+ atomState.setFixupAddend(entry->value);
+ haveFixup = true;
+ }
}
}
lastDepth = entry->depth;
@@ -757,10 +866,12 @@
atomState.makeAtom(*file);
}
+ file->bindTargetReferences();
result.push_back(file);
return make_error_code(yaml_reader_error::success);
}
+
//
// Fill in vector<File*> from path to input text file.
//