Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 1 | //===- Core/YamlWriter.cpp - Writes YAML ----------------------------------===// |
| 2 | // |
| 3 | // The LLVM Linker |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "lld/Core/YamlWriter.h" |
Michael J. Spencer | cfd029f | 2012-03-28 19:04:02 +0000 | [diff] [blame] | 11 | #include "YamlKeyValues.h" |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 12 | #include "lld/Core/Atom.h" |
| 13 | #include "lld/Core/File.h" |
Michael J. Spencer | cfd029f | 2012-03-28 19:04:02 +0000 | [diff] [blame] | 14 | #include "lld/Core/Platform.h" |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 15 | #include "lld/Core/Reference.h" |
| 16 | |
Michael J. Spencer | cfd029f | 2012-03-28 19:04:02 +0000 | [diff] [blame] | 17 | #include "llvm/ADT/ArrayRef.h" |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 18 | #include "llvm/ADT/DenseMap.h" |
Michael J. Spencer | cfd029f | 2012-03-28 19:04:02 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/OwningPtr.h" |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/StringExtras.h" |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/StringMap.h" |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 22 | #include "llvm/Support/DataTypes.h" |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 23 | #include "llvm/Support/Format.h" |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 24 | #include "llvm/Support/MemoryBuffer.h" |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 25 | #include "llvm/Support/raw_ostream.h" |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 26 | #include "llvm/Support/system_error.h" |
| 27 | |
| 28 | #include <vector> |
| 29 | |
| 30 | namespace lld { |
| 31 | namespace yaml { |
| 32 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 33 | namespace { |
| 34 | /// |
| 35 | /// In most cases, atoms names are unambiguous, so references can just |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 36 | /// use the atom name as the target (e.g. target: foo). But in a few |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 37 | /// cases that does not work, so ref-names are added. These are labels |
| 38 | /// used only in yaml. The labels do not exist in the Atom model. |
| 39 | /// |
| 40 | /// One need for ref-names are when atoms have no user supplied name |
| 41 | /// (e.g. c-string literal). Another case is when two object files with |
| 42 | /// identically named static functions are merged (ld -r) into one object file. |
| 43 | /// In that case referencing the function by name is ambiguous, so a unique |
| 44 | /// ref-name is added. |
| 45 | /// |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 46 | class RefNameBuilder { |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 47 | public: |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 48 | RefNameBuilder(const File& file) |
| 49 | : _collisionCount(0), _unnamedCounter(0) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 50 | // visit all atoms |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 51 | for(File::defined_iterator it=file.definedAtomsBegin(), |
| 52 | end=file.definedAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 53 | it != end; ++it) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 54 | const DefinedAtom* atom = *it; |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 55 | // Build map of atoms names to detect duplicates |
| 56 | if ( ! atom->name().empty() ) |
| 57 | buildDuplicateNameMap(*atom); |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 58 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 59 | // Find references to unnamed atoms and create ref-names for them. |
Nick Kledzik | 062a98c | 2012-04-08 23:52:13 +0000 | [diff] [blame^] | 60 | for (const Reference *ref : *atom) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 61 | // create refname for any unnamed reference target |
| 62 | if ( ref->target()->name().empty() ) { |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 63 | std::string Storage; |
| 64 | llvm::raw_string_ostream Buffer(Storage); |
| 65 | Buffer << llvm::format("L%03d", _unnamedCounter++); |
| 66 | _refNames[ref->target()] = Buffer.str(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 67 | } |
| 68 | } |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 69 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 70 | for(File::undefined_iterator it=file.undefinedAtomsBegin(), |
| 71 | end=file.undefinedAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 72 | it != end; ++it) { |
| 73 | buildDuplicateNameMap(**it); |
| 74 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 75 | for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(), |
| 76 | end=file.sharedLibraryAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 77 | it != end; ++it) { |
| 78 | buildDuplicateNameMap(**it); |
| 79 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 80 | for(File::absolute_iterator it=file.absoluteAtomsBegin(), |
| 81 | end=file.absoluteAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 82 | it != end; ++it) { |
| 83 | buildDuplicateNameMap(**it); |
| 84 | } |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 85 | |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 86 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 87 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 88 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 89 | void buildDuplicateNameMap(const Atom& atom) { |
| 90 | assert(!atom.name().empty()); |
| 91 | NameToAtom::iterator pos = _nameMap.find(atom.name()); |
| 92 | if ( pos != _nameMap.end() ) { |
| 93 | // Found name collision, give each a unique ref-name. |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 94 | std::string Storage; |
| 95 | llvm::raw_string_ostream Buffer(Storage); |
| 96 | Buffer << atom.name() << llvm::format(".%03d", ++_collisionCount); |
| 97 | _refNames[&atom] = Buffer.str(); |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 98 | const Atom* prevAtom = pos->second; |
| 99 | AtomToRefName::iterator pos2 = _refNames.find(prevAtom); |
| 100 | if ( pos2 == _refNames.end() ) { |
| 101 | // only create ref-name for previous if none already created |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 102 | Buffer << prevAtom->name() << llvm::format(".%03d", ++_collisionCount); |
| 103 | _refNames[prevAtom] = Buffer.str(); |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 104 | } |
| 105 | } |
| 106 | else { |
| 107 | // First time we've seen this name, just add it to map. |
| 108 | _nameMap[atom.name()] = &atom; |
| 109 | } |
| 110 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 111 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 112 | bool hasRefName(const Atom* atom) { |
| 113 | return _refNames.count(atom); |
| 114 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 115 | |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 116 | StringRef refName(const Atom *atom) { |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 117 | return _refNames.find(atom)->second; |
| 118 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 119 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 120 | private: |
Michael J. Spencer | e753cbc | 2012-03-09 05:27:43 +0000 | [diff] [blame] | 121 | typedef llvm::StringMap<const Atom*> NameToAtom; |
| 122 | typedef llvm::DenseMap<const Atom*, std::string> AtomToRefName; |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 123 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 124 | unsigned int _collisionCount; |
| 125 | unsigned int _unnamedCounter; |
| 126 | NameToAtom _nameMap; |
| 127 | AtomToRefName _refNames; |
| 128 | }; |
| 129 | |
| 130 | |
| 131 | /// |
| 132 | /// Helper class for writeObjectText() to write out atoms in yaml format. |
| 133 | /// |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 134 | class AtomWriter { |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 135 | public: |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 136 | AtomWriter(const File& file, Platform& platform, RefNameBuilder& rnb) |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 137 | : _file(file), _platform(platform), _rnb(rnb), _firstAtom(true) { } |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 138 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 139 | |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 140 | void write(raw_ostream &out) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 141 | // write header |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 142 | out << "---\n"; |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 143 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 144 | // visit all atoms |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 145 | for(File::defined_iterator it=_file.definedAtomsBegin(), |
| 146 | end=_file.definedAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 147 | it != end; ++it) { |
| 148 | writeDefinedAtom(**it, out); |
| 149 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 150 | for(File::undefined_iterator it=_file.undefinedAtomsBegin(), |
| 151 | end=_file.undefinedAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 152 | it != end; ++it) { |
| 153 | writeUndefinedAtom(**it, out); |
| 154 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 155 | for(File::shared_library_iterator it=_file.sharedLibraryAtomsBegin(), |
| 156 | end=_file.sharedLibraryAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 157 | it != end; ++it) { |
| 158 | writeSharedLibraryAtom(**it, out); |
| 159 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 160 | for(File::absolute_iterator it=_file.absoluteAtomsBegin(), |
| 161 | end=_file.absoluteAtomsEnd(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 162 | it != end; ++it) { |
| 163 | writeAbsoluteAtom(**it, out); |
| 164 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 165 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 166 | out << "...\n"; |
| 167 | } |
| 168 | |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 169 | |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 170 | void writeDefinedAtom(const DefinedAtom &atom, raw_ostream &out) { |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 171 | if ( _firstAtom ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 172 | out << "atoms:\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 173 | _firstAtom = false; |
| 174 | } |
| 175 | else { |
| 176 | // add blank line between atoms for readability |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 177 | out << "\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 178 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 179 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 180 | bool hasDash = false; |
| 181 | if ( !atom.name().empty() ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 182 | out << " - " |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 183 | << KeyValues::nameKeyword |
| 184 | << ":" |
| 185 | << spacePadding(KeyValues::nameKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 186 | << atom.name() |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 187 | << "\n"; |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 188 | hasDash = true; |
| 189 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 190 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 191 | if ( _rnb.hasRefName(&atom) ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 192 | out << (hasDash ? " " : " - ") |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 193 | << KeyValues::refNameKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 194 | << ":" |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 195 | << spacePadding(KeyValues::refNameKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 196 | << _rnb.refName(&atom) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 197 | << "\n"; |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 198 | hasDash = true; |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 199 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 200 | |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 201 | if ( atom.definition() != KeyValues::definitionDefault ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 202 | out << (hasDash ? " " : " - ") |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 203 | << KeyValues::definitionKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 204 | << ":" |
| 205 | << spacePadding(KeyValues::definitionKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 206 | << KeyValues::definition(atom.definition()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 207 | << "\n"; |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 208 | hasDash = true; |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 209 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 210 | |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 211 | if ( atom.scope() != KeyValues::scopeDefault ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 212 | out << (hasDash ? " " : " - ") |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 213 | << KeyValues::scopeKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 214 | << ":" |
| 215 | << spacePadding(KeyValues::scopeKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 216 | << KeyValues::scope(atom.scope()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 217 | << "\n"; |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 218 | hasDash = true; |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 219 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 220 | |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 221 | if ( atom.interposable() != KeyValues::interposableDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 222 | out << " " |
| 223 | << KeyValues::interposableKeyword |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 224 | << ":" |
| 225 | << spacePadding(KeyValues::interposableKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 226 | << KeyValues::interposable(atom.interposable()) |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 227 | << "\n"; |
| 228 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 229 | |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 230 | if ( atom.merge() != KeyValues::mergeDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 231 | out << " " |
| 232 | << KeyValues::mergeKeyword |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 233 | << ":" |
| 234 | << spacePadding(KeyValues::mergeKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 235 | << KeyValues::merge(atom.merge()) |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 236 | << "\n"; |
| 237 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 238 | |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 239 | if ( atom.contentType() != KeyValues::contentTypeDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 240 | out << " " |
| 241 | << KeyValues::contentTypeKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 242 | << ":" |
| 243 | << spacePadding(KeyValues::contentTypeKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 244 | << KeyValues::contentType(atom.contentType()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 245 | << "\n"; |
| 246 | } |
| 247 | |
| 248 | if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 249 | out << " " |
| 250 | << KeyValues::deadStripKindKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 251 | << ":" |
| 252 | << spacePadding(KeyValues::deadStripKindKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 253 | << KeyValues::deadStripKind(atom.deadStrip()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 254 | << "\n"; |
| 255 | } |
| 256 | |
| 257 | if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 258 | out << " " |
| 259 | << KeyValues::sectionChoiceKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 260 | << ":" |
| 261 | << spacePadding(KeyValues::sectionChoiceKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 262 | << KeyValues::sectionChoice(atom.sectionChoice()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 263 | << "\n"; |
| 264 | assert( ! atom.customSectionName().empty() ); |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 265 | out << " " |
| 266 | << KeyValues::sectionNameKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 267 | << ":" |
| 268 | << spacePadding(KeyValues::sectionNameKeyword) |
| 269 | << atom.customSectionName() |
| 270 | << "\n"; |
| 271 | } |
| 272 | |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 273 | if ( atom.isThumb() != KeyValues::isThumbDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 274 | out << " " |
| 275 | << KeyValues::isThumbKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 276 | << ":" |
| 277 | << spacePadding(KeyValues::isThumbKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 278 | << KeyValues::isThumb(atom.isThumb()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 279 | << "\n"; |
| 280 | } |
| 281 | |
| 282 | if ( atom.isAlias() != KeyValues::isAliasDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 283 | out << " " |
| 284 | << KeyValues::isAliasKeyword |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 285 | << ":" |
| 286 | << spacePadding(KeyValues::isAliasKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 287 | << KeyValues::isAlias(atom.isAlias()) |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 288 | << "\n"; |
| 289 | } |
| 290 | |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 291 | if ( (atom.contentType() != DefinedAtom::typeZeroFill) |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 292 | && (atom.size() != 0) ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 293 | out << " " |
| 294 | << KeyValues::contentKeyword |
Nick Kledzik | bfedfc1 | 2012-01-09 20:18:15 +0000 | [diff] [blame] | 295 | << ":" |
| 296 | << spacePadding(KeyValues::contentKeyword) |
| 297 | << "[ "; |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 298 | ArrayRef<uint8_t> arr = atom.rawContent(); |
Nick Kledzik | bfedfc1 | 2012-01-09 20:18:15 +0000 | [diff] [blame] | 299 | bool needComma = false; |
| 300 | for (unsigned int i=0; i < arr.size(); ++i) { |
| 301 | if ( needComma ) |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 302 | out << ", "; |
Nick Kledzik | f4e2c73 | 2012-03-15 23:36:24 +0000 | [diff] [blame] | 303 | if ( ((i % 12) == 0) && (i != 0) ) { |
| 304 | out << "\n "; |
| 305 | } |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 306 | out << hexdigit(arr[i] >> 4); |
| 307 | out << hexdigit(arr[i] & 0x0F); |
Nick Kledzik | bfedfc1 | 2012-01-09 20:18:15 +0000 | [diff] [blame] | 308 | needComma = true; |
| 309 | } |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 310 | out << " ]\n"; |
Nick Kledzik | bfedfc1 | 2012-01-09 20:18:15 +0000 | [diff] [blame] | 311 | } |
| 312 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 313 | bool wroteFirstFixup = false; |
Nick Kledzik | 062a98c | 2012-04-08 23:52:13 +0000 | [diff] [blame^] | 314 | for (const Reference *ref : atom) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 315 | if ( !wroteFirstFixup ) { |
| 316 | out << " fixups:\n"; |
| 317 | wroteFirstFixup = true; |
| 318 | } |
| 319 | out << " - " |
| 320 | << KeyValues::fixupsOffsetKeyword |
| 321 | << ":" |
| 322 | << spacePadding(KeyValues::fixupsOffsetKeyword) |
| 323 | << ref->offsetInAtom() |
| 324 | << "\n"; |
| 325 | out << " " |
| 326 | << KeyValues::fixupsKindKeyword |
| 327 | << ":" |
| 328 | << spacePadding(KeyValues::fixupsKindKeyword) |
| 329 | << _platform.kindToString(ref->kind()) |
| 330 | << "\n"; |
| 331 | const Atom* target = ref->target(); |
Michael J. Spencer | c9d2506 | 2012-03-29 19:39:14 +0000 | [diff] [blame] | 332 | if (target != nullptr) { |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 333 | StringRef refName = target->name(); |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 334 | if ( _rnb.hasRefName(target) ) |
| 335 | refName = _rnb.refName(target); |
| 336 | assert(!refName.empty()); |
| 337 | out << " " |
| 338 | << KeyValues::fixupsTargetKeyword |
| 339 | << ":" |
| 340 | << spacePadding(KeyValues::fixupsTargetKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 341 | << refName |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 342 | << "\n"; |
| 343 | } |
| 344 | if ( ref->addend() != 0 ) { |
| 345 | out << " " |
| 346 | << KeyValues::fixupsAddendKeyword |
| 347 | << ":" |
| 348 | << spacePadding(KeyValues::fixupsAddendKeyword) |
| 349 | << ref->addend() |
| 350 | << "\n"; |
| 351 | } |
| 352 | } |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 353 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 354 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 355 | |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 356 | void writeUndefinedAtom(const UndefinedAtom &atom, raw_ostream &out) { |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 357 | if ( _firstAtom ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 358 | out << "atoms:\n"; |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 359 | _firstAtom = false; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 360 | } |
| 361 | else { |
| 362 | // add blank line between atoms for readability |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 363 | out << "\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 364 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 365 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 366 | out << " - " |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 367 | << KeyValues::nameKeyword |
| 368 | << ":" |
| 369 | << spacePadding(KeyValues::nameKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 370 | << atom.name() |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 371 | << "\n"; |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 372 | |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 373 | out << " " |
| 374 | << KeyValues::definitionKeyword |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 375 | << ":" |
| 376 | << spacePadding(KeyValues::definitionKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 377 | << KeyValues::definition(atom.definition()) |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 378 | << "\n"; |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 379 | |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 380 | if ( atom.canBeNull() != KeyValues::canBeNullDefault ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 381 | out << " " |
| 382 | << KeyValues::canBeNullKeyword |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 383 | << ":" |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 384 | << spacePadding(KeyValues::canBeNullKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 385 | << KeyValues::canBeNull(atom.canBeNull()) |
Nick Kledzik | 23384e8 | 2012-02-07 02:59:54 +0000 | [diff] [blame] | 386 | << "\n"; |
| 387 | } |
| 388 | } |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 389 | |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 390 | void writeSharedLibraryAtom(const SharedLibraryAtom &atom, raw_ostream &out) { |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 391 | if ( _firstAtom ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 392 | out << "atoms:\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 393 | _firstAtom = false; |
| 394 | } |
| 395 | else { |
| 396 | // add blank line between atoms for readability |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 397 | out << "\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 398 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 399 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 400 | out << " - " |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 401 | << KeyValues::nameKeyword |
| 402 | << ":" |
| 403 | << spacePadding(KeyValues::nameKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 404 | << atom.name() |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 405 | << "\n"; |
| 406 | |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 407 | out << " " |
| 408 | << KeyValues::definitionKeyword |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 409 | << ":" |
| 410 | << spacePadding(KeyValues::definitionKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 411 | << KeyValues::definition(atom.definition()) |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 412 | << "\n"; |
| 413 | |
| 414 | if ( !atom.loadName().empty() ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 415 | out << " " |
| 416 | << KeyValues::loadNameKeyword |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 417 | << ":" |
| 418 | << spacePadding(KeyValues::loadNameKeyword) |
| 419 | << atom.loadName() |
| 420 | << "\n"; |
| 421 | } |
| 422 | |
| 423 | if ( atom.canBeNullAtRuntime() ) { |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 424 | out << " " |
| 425 | << KeyValues::canBeNullKeyword |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 426 | << ":" |
| 427 | << spacePadding(KeyValues::canBeNullKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 428 | << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime) |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 429 | << "\n"; |
| 430 | } |
| 431 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 432 | |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 433 | void writeAbsoluteAtom(const AbsoluteAtom &atom, raw_ostream &out) { |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 434 | if ( _firstAtom ) { |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 435 | out << "atoms:\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 436 | _firstAtom = false; |
| 437 | } |
| 438 | else { |
| 439 | // add blank line between atoms for readability |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 440 | out << "\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 441 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 442 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 443 | out << " - " |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 444 | << KeyValues::nameKeyword |
| 445 | << ":" |
| 446 | << spacePadding(KeyValues::nameKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 447 | << atom.name() |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 448 | << "\n"; |
| 449 | |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 450 | out << " " |
| 451 | << KeyValues::definitionKeyword |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 452 | << ":" |
| 453 | << spacePadding(KeyValues::definitionKeyword) |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 454 | << KeyValues::definition(atom.definition()) |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 455 | << "\n"; |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 456 | |
| 457 | out << " " |
| 458 | << KeyValues::valueKeyword |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 459 | << ":" |
| 460 | << spacePadding(KeyValues::valueKeyword) |
| 461 | << "0x"; |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 462 | out.write_hex(atom.value()); |
| 463 | out << "\n"; |
Nick Kledzik | 6bc04c6 | 2012-02-22 21:56:59 +0000 | [diff] [blame] | 464 | } |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 465 | |
Nick Kledzik | f4fb2c5 | 2012-01-11 01:06:19 +0000 | [diff] [blame] | 466 | |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 467 | private: |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 468 | // return a string of the correct number of spaces to align value |
| 469 | const char* spacePadding(const char* key) { |
| 470 | const char* spaces = " "; |
| 471 | assert(strlen(spaces) > strlen(key)); |
| 472 | return &spaces[strlen(key)]; |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 473 | } |
| 474 | |
Nick Kledzik | bfedfc1 | 2012-01-09 20:18:15 +0000 | [diff] [blame] | 475 | char hexdigit(uint8_t nibble) { |
| 476 | if ( nibble < 0x0A ) |
| 477 | return '0' + nibble; |
| 478 | else |
| 479 | return 'A' + nibble - 0x0A; |
| 480 | } |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 481 | |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 482 | const File& _file; |
| 483 | Platform& _platform; |
| 484 | RefNameBuilder& _rnb; |
Nick Kledzik | 7735a7d | 2012-01-04 23:58:17 +0000 | [diff] [blame] | 485 | bool _firstAtom; |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 486 | }; |
| 487 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 488 | } // anonymous namespace |
| 489 | |
| 490 | |
| 491 | |
| 492 | /// |
| 493 | /// writeObjectText - writes the lld::File object as in YAML |
| 494 | /// format to the specified stream. |
| 495 | /// |
Michael J. Spencer | e6203a5 | 2012-04-03 18:39:40 +0000 | [diff] [blame] | 496 | void writeObjectText(const File &file, Platform &platform, raw_ostream &out) { |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 497 | // Figure what ref-name labels are needed |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 498 | RefNameBuilder rnb(file); |
Michael J. Spencer | 765792d | 2012-04-03 18:40:27 +0000 | [diff] [blame] | 499 | |
Nick Kledzik | 49d6cc8 | 2012-02-15 00:38:09 +0000 | [diff] [blame] | 500 | // Write out all atoms |
Nick Kledzik | 1a6615d | 2012-03-08 00:18:30 +0000 | [diff] [blame] | 501 | AtomWriter writer(file, platform, rnb); |
| 502 | writer.write(out); |
Michael J. Spencer | 773a8fb | 2011-12-18 08:27:59 +0000 | [diff] [blame] | 503 | } |
| 504 | |
| 505 | } // namespace yaml |
| 506 | } // namespace lld |