summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/YAML/WriterYAML.cpp
diff options
context:
space:
mode:
authorNick Kledzik <kledzik@apple.com>2013-01-05 02:22:35 +0000
committerNick Kledzik <kledzik@apple.com>2013-01-05 02:22:35 +0000
commit6b079f5e2f303cbe24a2ef87842a50cdf831b8d7 (patch)
tree8b687e42748f67ce09418dcee4d4b5ce3e1e452f /lld/lib/ReaderWriter/YAML/WriterYAML.cpp
parente974bd1be9b954c33310f401ff704b4c1f1e4869 (diff)
downloadbcm5719-llvm-6b079f5e2f303cbe24a2ef87842a50cdf831b8d7.tar.gz
bcm5719-llvm-6b079f5e2f303cbe24a2ef87842a50cdf831b8d7.zip
Removes files for separate ReaderYAML.cpp and WriterYAML.cpp
and adds a new file ReaderWriterYAML.cpp that uses YAML I/O. Lots of tweaks to test suite for slightly different YAML encoding. llvm-svn: 171592
Diffstat (limited to 'lld/lib/ReaderWriter/YAML/WriterYAML.cpp')
-rw-r--r--lld/lib/ReaderWriter/YAML/WriterYAML.cpp505
1 files changed, 0 insertions, 505 deletions
diff --git a/lld/lib/ReaderWriter/YAML/WriterYAML.cpp b/lld/lib/ReaderWriter/YAML/WriterYAML.cpp
deleted file mode 100644
index 76773b7e88d..00000000000
--- a/lld/lib/ReaderWriter/YAML/WriterYAML.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-//===- lib/ReaderWriter/YAML/WriterYAML.cpp - Writes 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/WriterYAML.h"
-
-#include "lld/Core/Atom.h"
-#include "lld/Core/File.h"
-#include "lld/Core/Reference.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-
-#include "YamlKeyValues.h"
-
-#include <vector>
-
-namespace lld {
-namespace yaml {
-
-///
-/// In most cases, atoms names are unambiguous, so references can just
-/// use the atom name as the target (e.g. target: foo). But in a few
-/// cases that does not work, so ref-names are added. These are labels
-/// used only in yaml. The labels do not exist in the Atom model.
-///
-/// One need for ref-names are when atoms have no user supplied name
-/// (e.g. c-string literal). Another case is when two object files with
-/// identically named static functions are merged (ld -r) into one object file.
-/// In that case referencing the function by name is ambiguous, so a unique
-/// ref-name is added.
-///
-class RefNameBuilder {
-public:
- RefNameBuilder(const File& file)
- : _collisionCount(0), _unnamedCounter(0) {
- // visit all atoms
- for( const DefinedAtom *atom : file.defined() ) {
- // Build map of atoms names to detect duplicates
- if ( ! atom->name().empty() )
- buildDuplicateNameMap(*atom);
-
- // Find references to unnamed atoms and create ref-names for them.
- for (const Reference *ref : *atom) {
- // create refname for any unnamed reference target
- const Atom *target = ref->target();
- if ( (target != nullptr) && target->name().empty() ) {
- std::string Storage;
- llvm::raw_string_ostream Buffer(Storage);
- Buffer << llvm::format("L%03d", _unnamedCounter++);
- _refNames[target] = Buffer.str();
- }
- }
- }
- for( const UndefinedAtom *undefAtom : file.undefined() ) {
- buildDuplicateNameMap(*undefAtom);
- }
- for( const SharedLibraryAtom *shlibAtom : file.sharedLibrary() ) {
- buildDuplicateNameMap(*shlibAtom);
- }
- for( const AbsoluteAtom *absAtom : file.absolute() ) {
- buildDuplicateNameMap(*absAtom);
- }
-
-
- }
-
- void buildDuplicateNameMap(const Atom& atom) {
- assert(!atom.name().empty());
- NameToAtom::iterator pos = _nameMap.find(atom.name());
- if ( pos != _nameMap.end() ) {
- // Found name collision, give each a unique ref-name.
- std::string Storage;
- llvm::raw_string_ostream Buffer(Storage);
- Buffer << atom.name() << llvm::format(".%03d", ++_collisionCount);
- _refNames[&atom] = Buffer.str();
- const Atom* prevAtom = pos->second;
- AtomToRefName::iterator pos2 = _refNames.find(prevAtom);
- if ( pos2 == _refNames.end() ) {
- // only create ref-name for previous if none already created
- Buffer << prevAtom->name() << llvm::format(".%03d", ++_collisionCount);
- _refNames[prevAtom] = Buffer.str();
- }
- }
- else {
- // First time we've seen this name, just add it to map.
- _nameMap[atom.name()] = &atom;
- }
- }
-
- bool hasRefName(const Atom* atom) {
- return _refNames.count(atom);
- }
-
- StringRef refName(const Atom *atom) {
- return _refNames.find(atom)->second;
- }
-
-private:
- typedef llvm::StringMap<const Atom*> NameToAtom;
- typedef llvm::DenseMap<const Atom*, std::string> AtomToRefName;
-
- unsigned int _collisionCount;
- unsigned int _unnamedCounter;
- NameToAtom _nameMap;
- AtomToRefName _refNames;
-};
-
-
-///
-/// Helper class for writeObjectText() to write out atoms in yaml format.
-///
-class AtomWriter {
-public:
- AtomWriter(const File& file, const WriterOptionsYAML &options,
- RefNameBuilder& rnb)
- : _file(file), _options(options), _rnb(rnb), _firstAtom(true) { }
-
-
- void write(raw_ostream &out) {
- // write header
- out << "---\n";
-
- // visit all atoms
- for( const DefinedAtom *atom : _file.defined() ) {
- writeDefinedAtom(*atom, out);
- }
- for( const UndefinedAtom *undefAtom : _file.undefined() ) {
- writeUndefinedAtom(*undefAtom, out);
- }
- for( const SharedLibraryAtom *shlibAtom : _file.sharedLibrary() ) {
- writeSharedLibraryAtom(*shlibAtom, out);
- }
- for( const AbsoluteAtom *absAtom : _file.absolute() ) {
- writeAbsoluteAtom(*absAtom, out);
- }
-
- out << "...\n";
- }
-
-
- void writeDefinedAtom(const DefinedAtom &atom, raw_ostream &out) {
- if ( _firstAtom ) {
- out << "atoms:\n";
- _firstAtom = false;
- }
- else {
- // add blank line between atoms for readability
- out << "\n";
- }
-
- bool hasDash = false;
- if ( !atom.name().empty() ) {
- out << " - "
- << "name:"
- << spacePadding(strlen("name"))
- << atom.name()
- << "\n";
- hasDash = true;
- }
-
- if ( _rnb.hasRefName(&atom) ) {
- out << (hasDash ? " " : " - ")
- << "ref-name:"
- << spacePadding(strlen("ref-name"))
- << _rnb.refName(&atom)
- << "\n";
- hasDash = true;
- }
-
- if ( atom.definition() != KeyValues::definitionDefault ) {
- out << (hasDash ? " " : " - ")
- << "definition:"
- << spacePadding(strlen("definition"))
- << KeyValues::definition(atom.definition())
- << "\n";
- hasDash = true;
- }
-
- if ( atom.scope() != KeyValues::scopeDefault ) {
- out << (hasDash ? " " : " - ")
- << "scope:"
- << spacePadding(strlen("scope"))
- << KeyValues::scope(atom.scope())
- << "\n";
- }
-
- if ( atom.interposable() != KeyValues::interposableDefault ) {
- out << " "
- << "interposable:"
- << spacePadding(strlen("interposable"))
- << KeyValues::interposable(atom.interposable())
- << "\n";
- }
-
- if ( atom.merge() != KeyValues::mergeDefault ) {
- out << " "
- << "merge:"
- << spacePadding(strlen("merge"))
- << KeyValues::merge(atom.merge())
- << "\n";
- }
-
- if ( atom.contentType() != KeyValues::contentTypeDefault ) {
- out << " "
- << "type:"
- << spacePadding(strlen("type"))
- << KeyValues::contentType(atom.contentType())
- << "\n";
- }
-
- if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
- out << " "
- << "dead-strip:"
- << spacePadding(strlen("dead-strip"))
- << KeyValues::deadStripKind(atom.deadStrip())
- << "\n";
- }
-
- if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
- out << " "
- << "section-choice:"
- << spacePadding(strlen("section-choice"))
- << KeyValues::sectionChoice(atom.sectionChoice())
- << "\n";
- assert( ! atom.customSectionName().empty() );
- out << " "
- << "section-name:"
- << spacePadding(strlen("section-name"))
- << atom.customSectionName()
- << "\n";
- }
-
- if ( atom.isThumb() != KeyValues::isThumbDefault ) {
- out << " "
- << "is-thumb:"
- << spacePadding(strlen("is-thumb"))
- << KeyValues::isThumb(atom.isThumb())
- << "\n";
- }
-
- if ( atom.isAlias() != KeyValues::isAliasDefault ) {
- out << " "
- << "is-alias:"
- << spacePadding(strlen("is-alias"))
- << KeyValues::isAlias(atom.isAlias())
- << "\n";
- }
-
- if ( (atom.contentType() != DefinedAtom::typeZeroFill)
- && (atom.size() != 0) ) {
- out << " "
- << "content:"
- << spacePadding(strlen("content"))
- << "[ ";
- ArrayRef<uint8_t> arr = atom.rawContent();
- bool needComma = false;
- for (unsigned int i=0; i < arr.size(); ++i) {
- if ( needComma )
- out << ", ";
- if ( ((i % 12) == 0) && (i != 0) ) {
- out << "\n ";
- }
- out << hexdigit(arr[i] >> 4);
- out << hexdigit(arr[i] & 0x0F);
- needComma = true;
- }
- out << " ]\n";
- }
-
- bool wroteFirstFixup = false;
- for (const Reference *ref : atom) {
- if ( !wroteFirstFixup ) {
- out << " fixups:\n";
- wroteFirstFixup = true;
- }
- out << " - "
- << "offset:"
- << spacePadding(strlen("offset"))
- << ref->offsetInAtom()
- << "\n";
- out << " "
- << "kind:"
- << spacePadding(strlen("kind"))
- << _options.kindToString(ref->kind())
- << "\n";
- const Atom* target = ref->target();
- if (target != nullptr) {
- StringRef refName = target->name();
- if ( _rnb.hasRefName(target) )
- refName = _rnb.refName(target);
- assert(!refName.empty());
- out << " "
- << "target:"
- << spacePadding(strlen("target"))
- << refName
- << "\n";
- }
- if ( ref->addend() != 0 ) {
- out << " "
- << "addend:"
- << spacePadding(strlen("addend"))
- << ref->addend()
- << "\n";
- }
- }
- }
-
-
- void writeUndefinedAtom(const UndefinedAtom &atom, raw_ostream &out) {
- if ( _firstAtom ) {
- out << "atoms:\n";
- _firstAtom = false;
- }
- else {
- // add blank line between atoms for readability
- out << "\n";
- }
-
- out << " - "
- << "name:"
- << spacePadding(strlen("name"))
- << atom.name()
- << "\n";
-
- out << " "
- << "definition:"
- << spacePadding(strlen("definition"))
- << KeyValues::definition(atom.definition())
- << "\n";
-
- if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
- out << " "
- << "can-be-null:"
- << spacePadding(strlen("can-be-null"))
- << KeyValues::canBeNull(atom.canBeNull())
- << "\n";
- }
- }
-
- void writeSharedLibraryAtom(const SharedLibraryAtom &atom, raw_ostream &out) {
- if ( _firstAtom ) {
- out << "atoms:\n";
- _firstAtom = false;
- }
- else {
- // add blank line between atoms for readability
- out << "\n";
- }
-
- out << " - "
- << "name:"
- << spacePadding(strlen("name"))
- << atom.name()
- << "\n";
-
- out << " "
- << "definition:"
- << spacePadding(strlen("definition"))
- << KeyValues::definition(atom.definition())
- << "\n";
-
- if ( !atom.loadName().empty() ) {
- out << " "
- << "load-name:"
- << spacePadding(strlen("load-name"))
- << atom.loadName()
- << "\n";
- }
-
- if ( atom.canBeNullAtRuntime() ) {
- out << " "
- << "can-be-null:"
- << spacePadding(strlen("can-be-null"))
- << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
- << "\n";
- }
- }
-
- void writeAbsoluteAtom(const AbsoluteAtom &atom, raw_ostream &out) {
- if ( _firstAtom ) {
- out << "atoms:\n";
- _firstAtom = false;
- }
- else {
- // add blank line between atoms for readability
- out << "\n";
- }
-
- out << " - "
- << "name:"
- << spacePadding(strlen("name"))
- << atom.name()
- << "\n";
-
- out << " "
- << "definition:"
- << spacePadding(strlen("definition"))
- << KeyValues::definition(atom.definition())
- << "\n";
-
- if ( atom.scope() != KeyValues::scopeDefault ) {
- out << " "
- << "scope:"
- << spacePadding(strlen("scope"))
- << KeyValues::scope(atom.scope())
- << "\n";
- }
-
- out << " "
- << "value:"
- << spacePadding(strlen("value"))
- << "0x";
- out.write_hex(atom.value());
- out << "\n";
- }
-
-
-private:
- // return a string of the correct number of spaces to align value
- const char* spacePadding(size_t keyLen) {
- const char* spaces = " ";
- assert(strlen(spaces) > keyLen);
- return &spaces[keyLen];
- }
-
- char hexdigit(uint8_t nibble) {
- if ( nibble < 0x0A )
- return '0' + nibble;
- else
- return 'A' + nibble - 0x0A;
- }
-
- const File &_file;
- const WriterOptionsYAML &_options;
- RefNameBuilder &_rnb;
- bool _firstAtom;
-};
-
-
-
-
-class Writer : public lld::Writer {
-public:
- Writer(const WriterOptionsYAML &options) : _options(options) {
- }
-
- virtual error_code writeFile(const lld::File &file, StringRef path) {
- // Create stream to path.
- std::string errorInfo;
- llvm::raw_fd_ostream out(path.data(), errorInfo);
- if (!errorInfo.empty())
- return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
-
- // Figure what ref-name labels are needed.
- RefNameBuilder rnb(file);
-
- // Write out all atoms.
- AtomWriter writer(file, _options, rnb);
- writer.write(out);
- return error_code::success();
- }
-
- virtual StubsPass *stubPass() {
- return _options.stubPass();
- }
-
- virtual GOTPass *gotPass() {
- return _options.gotPass();
- }
-
-
-private:
- const WriterOptionsYAML &_options;
-};
-
-
-} // namespace yaml
-
-
-Writer* createWriterYAML(const WriterOptionsYAML &options) {
- return new lld::yaml::Writer(options);
-}
-
-WriterOptionsYAML::WriterOptionsYAML() {
-}
-
-WriterOptionsYAML::~WriterOptionsYAML() {
-}
-
-
-} // namespace lld
OpenPOWER on IntegriCloud