blob: db63b6135529ebbc18d8871d3771f3469c63ec0b [file] [log] [blame]
Michael J. Spencer773a8fb2011-12-18 08:27:59 +00001//===- 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. Spencercfd029f2012-03-28 19:04:02 +000011#include "YamlKeyValues.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000012#include "lld/Core/Atom.h"
13#include "lld/Core/File.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000014#include "lld/Core/Platform.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000015#include "lld/Core/Reference.h"
16
Michael J. Spencercfd029f2012-03-28 19:04:02 +000017#include "llvm/ADT/ArrayRef.h"
Nick Kledzik49d6cc82012-02-15 00:38:09 +000018#include "llvm/ADT/DenseMap.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000019#include "llvm/ADT/OwningPtr.h"
Nick Kledzik49d6cc82012-02-15 00:38:09 +000020#include "llvm/ADT/StringExtras.h"
Michael J. Spencere753cbc2012-03-09 05:27:43 +000021#include "llvm/ADT/StringMap.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000022#include "llvm/Support/DataTypes.h"
Michael J. Spencere753cbc2012-03-09 05:27:43 +000023#include "llvm/Support/Format.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000024#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencere753cbc2012-03-09 05:27:43 +000025#include "llvm/Support/raw_ostream.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000026#include "llvm/Support/system_error.h"
27
28#include <vector>
29
30namespace lld {
31namespace yaml {
32
Nick Kledzik49d6cc82012-02-15 00:38:09 +000033namespace {
34///
35/// In most cases, atoms names are unambiguous, so references can just
Michael J. Spencer765792d2012-04-03 18:40:27 +000036/// use the atom name as the target (e.g. target: foo). But in a few
Nick Kledzik49d6cc82012-02-15 00:38:09 +000037/// 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 Kledzik1a6615d2012-03-08 00:18:30 +000046class RefNameBuilder {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000047public:
Michael J. Spencer765792d2012-04-03 18:40:27 +000048 RefNameBuilder(const File& file)
49 : _collisionCount(0), _unnamedCounter(0) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +000050 // visit all atoms
Michael J. Spencer765792d2012-04-03 18:40:27 +000051 for(File::defined_iterator it=file.definedAtomsBegin(),
52 end=file.definedAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000053 it != end; ++it) {
Michael J. Spencer765792d2012-04-03 18:40:27 +000054 const DefinedAtom* atom = *it;
Nick Kledzik1a6615d2012-03-08 00:18:30 +000055 // Build map of atoms names to detect duplicates
56 if ( ! atom->name().empty() )
57 buildDuplicateNameMap(*atom);
Michael J. Spencer765792d2012-04-03 18:40:27 +000058
Nick Kledzik1a6615d2012-03-08 00:18:30 +000059 // Find references to unnamed atoms and create ref-names for them.
Nick Kledzik062a98c2012-04-08 23:52:13 +000060 for (const Reference *ref : *atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +000061 // create refname for any unnamed reference target
62 if ( ref->target()->name().empty() ) {
Michael J. Spencere753cbc2012-03-09 05:27:43 +000063 std::string Storage;
64 llvm::raw_string_ostream Buffer(Storage);
65 Buffer << llvm::format("L%03d", _unnamedCounter++);
66 _refNames[ref->target()] = Buffer.str();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000067 }
68 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000069 }
Michael J. Spencer765792d2012-04-03 18:40:27 +000070 for(File::undefined_iterator it=file.undefinedAtomsBegin(),
71 end=file.undefinedAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000072 it != end; ++it) {
73 buildDuplicateNameMap(**it);
74 }
Michael J. Spencer765792d2012-04-03 18:40:27 +000075 for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(),
76 end=file.sharedLibraryAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000077 it != end; ++it) {
78 buildDuplicateNameMap(**it);
79 }
Michael J. Spencer765792d2012-04-03 18:40:27 +000080 for(File::absolute_iterator it=file.absoluteAtomsBegin(),
81 end=file.absoluteAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000082 it != end; ++it) {
83 buildDuplicateNameMap(**it);
84 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000085
Michael J. Spencer765792d2012-04-03 18:40:27 +000086
Nick Kledzik49d6cc82012-02-15 00:38:09 +000087 }
Michael J. Spencer765792d2012-04-03 18:40:27 +000088
Nick Kledzik49d6cc82012-02-15 00:38:09 +000089 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. Spencere753cbc2012-03-09 05:27:43 +000094 std::string Storage;
95 llvm::raw_string_ostream Buffer(Storage);
96 Buffer << atom.name() << llvm::format(".%03d", ++_collisionCount);
97 _refNames[&atom] = Buffer.str();
Nick Kledzik49d6cc82012-02-15 00:38:09 +000098 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. Spencere753cbc2012-03-09 05:27:43 +0000102 Buffer << prevAtom->name() << llvm::format(".%03d", ++_collisionCount);
103 _refNames[prevAtom] = Buffer.str();
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000104 }
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. Spencer765792d2012-04-03 18:40:27 +0000111
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000112 bool hasRefName(const Atom* atom) {
113 return _refNames.count(atom);
114 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000115
Michael J. Spencere6203a52012-04-03 18:39:40 +0000116 StringRef refName(const Atom *atom) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000117 return _refNames.find(atom)->second;
118 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000119
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000120private:
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000121 typedef llvm::StringMap<const Atom*> NameToAtom;
122 typedef llvm::DenseMap<const Atom*, std::string> AtomToRefName;
Michael J. Spencer765792d2012-04-03 18:40:27 +0000123
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000124 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 Kledzik1a6615d2012-03-08 00:18:30 +0000134class AtomWriter {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000135public:
Michael J. Spencer765792d2012-04-03 18:40:27 +0000136 AtomWriter(const File& file, Platform& platform, RefNameBuilder& rnb)
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000137 : _file(file), _platform(platform), _rnb(rnb), _firstAtom(true) { }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000138
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000139
Michael J. Spencere6203a52012-04-03 18:39:40 +0000140 void write(raw_ostream &out) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000141 // write header
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000142 out << "---\n";
Michael J. Spencer765792d2012-04-03 18:40:27 +0000143
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000144 // visit all atoms
Michael J. Spencer765792d2012-04-03 18:40:27 +0000145 for(File::defined_iterator it=_file.definedAtomsBegin(),
146 end=_file.definedAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000147 it != end; ++it) {
148 writeDefinedAtom(**it, out);
149 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000150 for(File::undefined_iterator it=_file.undefinedAtomsBegin(),
151 end=_file.undefinedAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000152 it != end; ++it) {
153 writeUndefinedAtom(**it, out);
154 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000155 for(File::shared_library_iterator it=_file.sharedLibraryAtomsBegin(),
156 end=_file.sharedLibraryAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000157 it != end; ++it) {
158 writeSharedLibraryAtom(**it, out);
159 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000160 for(File::absolute_iterator it=_file.absoluteAtomsBegin(),
161 end=_file.absoluteAtomsEnd();
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000162 it != end; ++it) {
163 writeAbsoluteAtom(**it, out);
164 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000165
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000166 out << "...\n";
167 }
168
Michael J. Spencer765792d2012-04-03 18:40:27 +0000169
Michael J. Spencere6203a52012-04-03 18:39:40 +0000170 void writeDefinedAtom(const DefinedAtom &atom, raw_ostream &out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000171 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000172 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000173 _firstAtom = false;
174 }
175 else {
176 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000177 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000178 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000179
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000180 bool hasDash = false;
181 if ( !atom.name().empty() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000182 out << " - "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000183 << KeyValues::nameKeyword
184 << ":"
185 << spacePadding(KeyValues::nameKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000186 << atom.name()
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000187 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000188 hasDash = true;
189 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000190
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000191 if ( _rnb.hasRefName(&atom) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000192 out << (hasDash ? " " : " - ")
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000193 << KeyValues::refNameKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000194 << ":"
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000195 << spacePadding(KeyValues::refNameKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000196 << _rnb.refName(&atom)
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000197 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000198 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000199 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000200
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000201 if ( atom.definition() != KeyValues::definitionDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000202 out << (hasDash ? " " : " - ")
Michael J. Spencer765792d2012-04-03 18:40:27 +0000203 << KeyValues::definitionKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000204 << ":"
205 << spacePadding(KeyValues::definitionKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000206 << KeyValues::definition(atom.definition())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000207 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000208 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000209 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000210
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000211 if ( atom.scope() != KeyValues::scopeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000212 out << (hasDash ? " " : " - ")
Michael J. Spencer765792d2012-04-03 18:40:27 +0000213 << KeyValues::scopeKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000214 << ":"
215 << spacePadding(KeyValues::scopeKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000216 << KeyValues::scope(atom.scope())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000217 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000218 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000219 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000220
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000221 if ( atom.interposable() != KeyValues::interposableDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000222 out << " "
223 << KeyValues::interposableKeyword
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000224 << ":"
225 << spacePadding(KeyValues::interposableKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000226 << KeyValues::interposable(atom.interposable())
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000227 << "\n";
228 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000229
Nick Kledzik23384e82012-02-07 02:59:54 +0000230 if ( atom.merge() != KeyValues::mergeDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000231 out << " "
232 << KeyValues::mergeKeyword
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000233 << ":"
234 << spacePadding(KeyValues::mergeKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000235 << KeyValues::merge(atom.merge())
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000236 << "\n";
237 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000238
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000239 if ( atom.contentType() != KeyValues::contentTypeDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000240 out << " "
241 << KeyValues::contentTypeKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000242 << ":"
243 << spacePadding(KeyValues::contentTypeKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000244 << KeyValues::contentType(atom.contentType())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000245 << "\n";
246 }
247
248 if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000249 out << " "
250 << KeyValues::deadStripKindKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000251 << ":"
252 << spacePadding(KeyValues::deadStripKindKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000253 << KeyValues::deadStripKind(atom.deadStrip())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000254 << "\n";
255 }
256
257 if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000258 out << " "
259 << KeyValues::sectionChoiceKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000260 << ":"
261 << spacePadding(KeyValues::sectionChoiceKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000262 << KeyValues::sectionChoice(atom.sectionChoice())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000263 << "\n";
264 assert( ! atom.customSectionName().empty() );
Michael J. Spencer765792d2012-04-03 18:40:27 +0000265 out << " "
266 << KeyValues::sectionNameKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000267 << ":"
268 << spacePadding(KeyValues::sectionNameKeyword)
269 << atom.customSectionName()
270 << "\n";
271 }
272
Nick Kledzik23384e82012-02-07 02:59:54 +0000273 if ( atom.isThumb() != KeyValues::isThumbDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000274 out << " "
275 << KeyValues::isThumbKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000276 << ":"
277 << spacePadding(KeyValues::isThumbKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000278 << KeyValues::isThumb(atom.isThumb())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000279 << "\n";
280 }
281
282 if ( atom.isAlias() != KeyValues::isAliasDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000283 out << " "
284 << KeyValues::isAliasKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000285 << ":"
286 << spacePadding(KeyValues::isAliasKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000287 << KeyValues::isAlias(atom.isAlias())
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000288 << "\n";
289 }
290
Michael J. Spencer765792d2012-04-03 18:40:27 +0000291 if ( (atom.contentType() != DefinedAtom::typeZeroFill)
Nick Kledzik23384e82012-02-07 02:59:54 +0000292 && (atom.size() != 0) ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000293 out << " "
294 << KeyValues::contentKeyword
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000295 << ":"
296 << spacePadding(KeyValues::contentKeyword)
297 << "[ ";
Michael J. Spencere6203a52012-04-03 18:39:40 +0000298 ArrayRef<uint8_t> arr = atom.rawContent();
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000299 bool needComma = false;
300 for (unsigned int i=0; i < arr.size(); ++i) {
301 if ( needComma )
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000302 out << ", ";
Nick Kledzikf4e2c732012-03-15 23:36:24 +0000303 if ( ((i % 12) == 0) && (i != 0) ) {
304 out << "\n ";
305 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000306 out << hexdigit(arr[i] >> 4);
307 out << hexdigit(arr[i] & 0x0F);
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000308 needComma = true;
309 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000310 out << " ]\n";
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000311 }
312
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000313 bool wroteFirstFixup = false;
Nick Kledzik062a98c2012-04-08 23:52:13 +0000314 for (const Reference *ref : atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000315 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. Spencerc9d25062012-03-29 19:39:14 +0000332 if (target != nullptr) {
Michael J. Spencere6203a52012-04-03 18:39:40 +0000333 StringRef refName = target->name();
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000334 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. Spencer765792d2012-04-03 18:40:27 +0000341 << refName
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000342 << "\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. Spencer773a8fb2011-12-18 08:27:59 +0000353 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000354
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000355
Michael J. Spencere6203a52012-04-03 18:39:40 +0000356 void writeUndefinedAtom(const UndefinedAtom &atom, raw_ostream &out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000357 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000358 out << "atoms:\n";
Nick Kledzik23384e82012-02-07 02:59:54 +0000359 _firstAtom = false;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000360 }
361 else {
362 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000363 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000364 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000365
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000366 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000367 << KeyValues::nameKeyword
368 << ":"
369 << spacePadding(KeyValues::nameKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000370 << atom.name()
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000371 << "\n";
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000372
Michael J. Spencer765792d2012-04-03 18:40:27 +0000373 out << " "
374 << KeyValues::definitionKeyword
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000375 << ":"
376 << spacePadding(KeyValues::definitionKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000377 << KeyValues::definition(atom.definition())
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000378 << "\n";
Nick Kledzik23384e82012-02-07 02:59:54 +0000379
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000380 if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000381 out << " "
382 << KeyValues::canBeNullKeyword
Nick Kledzik23384e82012-02-07 02:59:54 +0000383 << ":"
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000384 << spacePadding(KeyValues::canBeNullKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000385 << KeyValues::canBeNull(atom.canBeNull())
Nick Kledzik23384e82012-02-07 02:59:54 +0000386 << "\n";
387 }
388 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000389
Michael J. Spencere6203a52012-04-03 18:39:40 +0000390 void writeSharedLibraryAtom(const SharedLibraryAtom &atom, raw_ostream &out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000391 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000392 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000393 _firstAtom = false;
394 }
395 else {
396 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000397 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000398 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000399
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000400 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000401 << KeyValues::nameKeyword
402 << ":"
403 << spacePadding(KeyValues::nameKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000404 << atom.name()
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000405 << "\n";
406
Michael J. Spencer765792d2012-04-03 18:40:27 +0000407 out << " "
408 << KeyValues::definitionKeyword
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000409 << ":"
410 << spacePadding(KeyValues::definitionKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000411 << KeyValues::definition(atom.definition())
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000412 << "\n";
413
414 if ( !atom.loadName().empty() ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000415 out << " "
416 << KeyValues::loadNameKeyword
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000417 << ":"
418 << spacePadding(KeyValues::loadNameKeyword)
419 << atom.loadName()
420 << "\n";
421 }
422
423 if ( atom.canBeNullAtRuntime() ) {
Michael J. Spencer765792d2012-04-03 18:40:27 +0000424 out << " "
425 << KeyValues::canBeNullKeyword
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000426 << ":"
427 << spacePadding(KeyValues::canBeNullKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000428 << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000429 << "\n";
430 }
431 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000432
Michael J. Spencere6203a52012-04-03 18:39:40 +0000433 void writeAbsoluteAtom(const AbsoluteAtom &atom, raw_ostream &out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000434 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000435 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000436 _firstAtom = false;
437 }
438 else {
439 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000440 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000441 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000442
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000443 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000444 << KeyValues::nameKeyword
445 << ":"
446 << spacePadding(KeyValues::nameKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000447 << atom.name()
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000448 << "\n";
449
Michael J. Spencer765792d2012-04-03 18:40:27 +0000450 out << " "
451 << KeyValues::definitionKeyword
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000452 << ":"
453 << spacePadding(KeyValues::definitionKeyword)
Michael J. Spencer765792d2012-04-03 18:40:27 +0000454 << KeyValues::definition(atom.definition())
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000455 << "\n";
Michael J. Spencer765792d2012-04-03 18:40:27 +0000456
457 out << " "
458 << KeyValues::valueKeyword
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000459 << ":"
460 << spacePadding(KeyValues::valueKeyword)
461 << "0x";
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000462 out.write_hex(atom.value());
463 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000464 }
Michael J. Spencer765792d2012-04-03 18:40:27 +0000465
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000466
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000467private:
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000468 // 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. Spencer773a8fb2011-12-18 08:27:59 +0000473 }
474
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000475 char hexdigit(uint8_t nibble) {
476 if ( nibble < 0x0A )
477 return '0' + nibble;
478 else
479 return 'A' + nibble - 0x0A;
480 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000481
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000482 const File& _file;
483 Platform& _platform;
484 RefNameBuilder& _rnb;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000485 bool _firstAtom;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000486};
487
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000488} // 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. Spencere6203a52012-04-03 18:39:40 +0000496void writeObjectText(const File &file, Platform &platform, raw_ostream &out) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000497 // Figure what ref-name labels are needed
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000498 RefNameBuilder rnb(file);
Michael J. Spencer765792d2012-04-03 18:40:27 +0000499
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000500 // Write out all atoms
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000501 AtomWriter writer(file, platform, rnb);
502 writer.write(out);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000503}
504
505} // namespace yaml
506} // namespace lld