blob: 7f9b0c3170e9a16f41c7870710dc1438b6b55e1e [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
36/// use the atom name as the target (e.g. target: foo). But in a few
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 Kledzik1a6615d2012-03-08 00:18:30 +000046class RefNameBuilder {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000047public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +000048 RefNameBuilder(const File& file)
49 : _collisionCount(0), _unnamedCounter(0) {
50 // visit all atoms
51 for(File::defined_iterator it=file.definedAtomsBegin(),
52 end=file.definedAtomsEnd();
53 it != end; ++it) {
54 const DefinedAtom* atom = *it;
55 // Build map of atoms names to detect duplicates
56 if ( ! atom->name().empty() )
57 buildDuplicateNameMap(*atom);
58
59 // Find references to unnamed atoms and create ref-names for them.
60 for (auto rit=atom->referencesBegin(), rend=atom->referencesEnd();
61 rit != rend; ++rit) {
62 const Reference* ref = *rit;
63 // create refname for any unnamed reference target
64 if ( ref->target()->name().empty() ) {
Michael J. Spencere753cbc2012-03-09 05:27:43 +000065 std::string Storage;
66 llvm::raw_string_ostream Buffer(Storage);
67 Buffer << llvm::format("L%03d", _unnamedCounter++);
68 _refNames[ref->target()] = Buffer.str();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000069 }
70 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000071 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +000072 for(File::undefined_iterator it=file.undefinedAtomsBegin(),
73 end=file.undefinedAtomsEnd();
74 it != end; ++it) {
75 buildDuplicateNameMap(**it);
76 }
77 for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(),
78 end=file.sharedLibraryAtomsEnd();
79 it != end; ++it) {
80 buildDuplicateNameMap(**it);
81 }
82 for(File::absolute_iterator it=file.absoluteAtomsBegin(),
83 end=file.absoluteAtomsEnd();
84 it != end; ++it) {
85 buildDuplicateNameMap(**it);
86 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000087
Nick Kledzik49d6cc82012-02-15 00:38:09 +000088
Nick Kledzik49d6cc82012-02-15 00:38:09 +000089 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +000090
Nick Kledzik49d6cc82012-02-15 00:38:09 +000091 void buildDuplicateNameMap(const Atom& atom) {
92 assert(!atom.name().empty());
93 NameToAtom::iterator pos = _nameMap.find(atom.name());
94 if ( pos != _nameMap.end() ) {
95 // Found name collision, give each a unique ref-name.
Michael J. Spencere753cbc2012-03-09 05:27:43 +000096 std::string Storage;
97 llvm::raw_string_ostream Buffer(Storage);
98 Buffer << atom.name() << llvm::format(".%03d", ++_collisionCount);
99 _refNames[&atom] = Buffer.str();
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000100 const Atom* prevAtom = pos->second;
101 AtomToRefName::iterator pos2 = _refNames.find(prevAtom);
102 if ( pos2 == _refNames.end() ) {
103 // only create ref-name for previous if none already created
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000104 Buffer << prevAtom->name() << llvm::format(".%03d", ++_collisionCount);
105 _refNames[prevAtom] = Buffer.str();
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000106 }
107 }
108 else {
109 // First time we've seen this name, just add it to map.
110 _nameMap[atom.name()] = &atom;
111 }
112 }
113
114 bool hasRefName(const Atom* atom) {
115 return _refNames.count(atom);
116 }
117
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000118 llvm::StringRef refName(const Atom* atom) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000119 return _refNames.find(atom)->second;
120 }
121
122private:
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000123 typedef llvm::StringMap<const Atom*> NameToAtom;
124 typedef llvm::DenseMap<const Atom*, std::string> AtomToRefName;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000125
126 unsigned int _collisionCount;
127 unsigned int _unnamedCounter;
128 NameToAtom _nameMap;
129 AtomToRefName _refNames;
130};
131
132
133///
134/// Helper class for writeObjectText() to write out atoms in yaml format.
135///
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000136class AtomWriter {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000137public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000138 AtomWriter(const File& file, Platform& platform, RefNameBuilder& rnb)
139 : _file(file), _platform(platform), _rnb(rnb), _firstAtom(true) { }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000140
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000141
142 void write(llvm::raw_ostream& out) {
143 // write header
144 out << "---\n";
145
146 // visit all atoms
147 for(File::defined_iterator it=_file.definedAtomsBegin(),
148 end=_file.definedAtomsEnd();
149 it != end; ++it) {
150 writeDefinedAtom(**it, out);
151 }
152 for(File::undefined_iterator it=_file.undefinedAtomsBegin(),
153 end=_file.undefinedAtomsEnd();
154 it != end; ++it) {
155 writeUndefinedAtom(**it, out);
156 }
157 for(File::shared_library_iterator it=_file.sharedLibraryAtomsBegin(),
158 end=_file.sharedLibraryAtomsEnd();
159 it != end; ++it) {
160 writeSharedLibraryAtom(**it, out);
161 }
162 for(File::absolute_iterator it=_file.absoluteAtomsBegin(),
163 end=_file.absoluteAtomsEnd();
164 it != end; ++it) {
165 writeAbsoluteAtom(**it, out);
166 }
167
168 out << "...\n";
169 }
170
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000171
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000172 void writeDefinedAtom(const DefinedAtom &atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000173 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000174 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000175 _firstAtom = false;
176 }
177 else {
178 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000179 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000180 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000181
182 bool hasDash = false;
183 if ( !atom.name().empty() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000184 out << " - "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000185 << KeyValues::nameKeyword
186 << ":"
187 << spacePadding(KeyValues::nameKeyword)
188 << atom.name()
189 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000190 hasDash = true;
191 }
192
193 if ( _rnb.hasRefName(&atom) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000194 out << (hasDash ? " " : " - ")
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000195 << KeyValues::refNameKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000196 << ":"
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000197 << spacePadding(KeyValues::refNameKeyword)
198 << _rnb.refName(&atom)
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000199 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000200 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000201 }
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000202
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000203 if ( atom.definition() != KeyValues::definitionDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000204 out << (hasDash ? " " : " - ")
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000205 << KeyValues::definitionKeyword
206 << ":"
207 << spacePadding(KeyValues::definitionKeyword)
208 << KeyValues::definition(atom.definition())
209 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000210 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000211 }
212
213 if ( atom.scope() != KeyValues::scopeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000214 out << (hasDash ? " " : " - ")
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000215 << KeyValues::scopeKeyword
216 << ":"
217 << spacePadding(KeyValues::scopeKeyword)
218 << KeyValues::scope(atom.scope())
219 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000220 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000221 }
222
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000223 if ( atom.interposable() != KeyValues::interposableDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000224 out << " "
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000225 << KeyValues::interposableKeyword
226 << ":"
227 << spacePadding(KeyValues::interposableKeyword)
228 << KeyValues::interposable(atom.interposable())
229 << "\n";
230 }
231
Nick Kledzik23384e82012-02-07 02:59:54 +0000232 if ( atom.merge() != KeyValues::mergeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000233 out << " "
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000234 << KeyValues::mergeKeyword
235 << ":"
236 << spacePadding(KeyValues::mergeKeyword)
237 << KeyValues::merge(atom.merge())
238 << "\n";
239 }
240
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000241 if ( atom.contentType() != KeyValues::contentTypeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000242 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000243 << KeyValues::contentTypeKeyword
244 << ":"
245 << spacePadding(KeyValues::contentTypeKeyword)
246 << KeyValues::contentType(atom.contentType())
247 << "\n";
248 }
249
250 if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000251 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000252 << KeyValues::deadStripKindKeyword
253 << ":"
254 << spacePadding(KeyValues::deadStripKindKeyword)
255 << KeyValues::deadStripKind(atom.deadStrip())
256 << "\n";
257 }
258
259 if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000260 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000261 << KeyValues::sectionChoiceKeyword
262 << ":"
263 << spacePadding(KeyValues::sectionChoiceKeyword)
264 << KeyValues::sectionChoice(atom.sectionChoice())
265 << "\n";
266 assert( ! atom.customSectionName().empty() );
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000267 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000268 << KeyValues::sectionNameKeyword
269 << ":"
270 << spacePadding(KeyValues::sectionNameKeyword)
271 << atom.customSectionName()
272 << "\n";
273 }
274
Nick Kledzik23384e82012-02-07 02:59:54 +0000275 if ( atom.isThumb() != KeyValues::isThumbDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000276 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000277 << KeyValues::isThumbKeyword
278 << ":"
279 << spacePadding(KeyValues::isThumbKeyword)
280 << KeyValues::isThumb(atom.isThumb())
281 << "\n";
282 }
283
284 if ( atom.isAlias() != KeyValues::isAliasDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000285 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000286 << KeyValues::isAliasKeyword
287 << ":"
288 << spacePadding(KeyValues::isAliasKeyword)
289 << KeyValues::isAlias(atom.isAlias())
290 << "\n";
291 }
292
Nick Kledzik23384e82012-02-07 02:59:54 +0000293 if ( (atom.contentType() != DefinedAtom::typeZeroFill)
294 && (atom.size() != 0) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000295 out << " "
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000296 << KeyValues::contentKeyword
297 << ":"
298 << spacePadding(KeyValues::contentKeyword)
299 << "[ ";
300 llvm::ArrayRef<uint8_t> arr = atom.rawContent();
301 bool needComma = false;
302 for (unsigned int i=0; i < arr.size(); ++i) {
303 if ( needComma )
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000304 out << ", ";
Nick Kledzikf4e2c732012-03-15 23:36:24 +0000305 if ( ((i % 12) == 0) && (i != 0) ) {
306 out << "\n ";
307 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000308 out << hexdigit(arr[i] >> 4);
309 out << hexdigit(arr[i] & 0x0F);
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000310 needComma = true;
311 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000312 out << " ]\n";
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000313 }
314
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000315 bool wroteFirstFixup = false;
316 for (auto it=atom.referencesBegin(), end=atom.referencesEnd();
317 it != end; ++it) {
318 const Reference* ref = *it;
319 if ( !wroteFirstFixup ) {
320 out << " fixups:\n";
321 wroteFirstFixup = true;
322 }
323 out << " - "
324 << KeyValues::fixupsOffsetKeyword
325 << ":"
326 << spacePadding(KeyValues::fixupsOffsetKeyword)
327 << ref->offsetInAtom()
328 << "\n";
329 out << " "
330 << KeyValues::fixupsKindKeyword
331 << ":"
332 << spacePadding(KeyValues::fixupsKindKeyword)
333 << _platform.kindToString(ref->kind())
334 << "\n";
335 const Atom* target = ref->target();
336 if ( target != NULL ) {
337 llvm::StringRef refName = target->name();
338 if ( _rnb.hasRefName(target) )
339 refName = _rnb.refName(target);
340 assert(!refName.empty());
341 out << " "
342 << KeyValues::fixupsTargetKeyword
343 << ":"
344 << spacePadding(KeyValues::fixupsTargetKeyword)
345 << refName
346 << "\n";
347 }
348 if ( ref->addend() != 0 ) {
349 out << " "
350 << KeyValues::fixupsAddendKeyword
351 << ":"
352 << spacePadding(KeyValues::fixupsAddendKeyword)
353 << ref->addend()
354 << "\n";
355 }
356 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000357 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000358
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000359
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000360 void writeUndefinedAtom(const UndefinedAtom &atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000361 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000362 out << "atoms:\n";
Nick Kledzik23384e82012-02-07 02:59:54 +0000363 _firstAtom = false;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000364 }
365 else {
366 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000367 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000368 }
Nick Kledzik23384e82012-02-07 02:59:54 +0000369
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000370 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000371 << KeyValues::nameKeyword
372 << ":"
373 << spacePadding(KeyValues::nameKeyword)
374 << atom.name()
375 << "\n";
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000376
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000377 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000378 << KeyValues::definitionKeyword
379 << ":"
380 << spacePadding(KeyValues::definitionKeyword)
381 << KeyValues::definition(atom.definition())
382 << "\n";
Nick Kledzik23384e82012-02-07 02:59:54 +0000383
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000384 if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000385 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000386 << KeyValues::canBeNullKeyword
Nick Kledzik23384e82012-02-07 02:59:54 +0000387 << ":"
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000388 << spacePadding(KeyValues::canBeNullKeyword)
389 << KeyValues::canBeNull(atom.canBeNull())
Nick Kledzik23384e82012-02-07 02:59:54 +0000390 << "\n";
391 }
392 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000393
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000394 void writeSharedLibraryAtom(const SharedLibraryAtom& atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000395 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000396 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000397 _firstAtom = false;
398 }
399 else {
400 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000401 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000402 }
403
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000404 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000405 << KeyValues::nameKeyword
406 << ":"
407 << spacePadding(KeyValues::nameKeyword)
408 << atom.name()
409 << "\n";
410
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000411 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000412 << KeyValues::definitionKeyword
413 << ":"
414 << spacePadding(KeyValues::definitionKeyword)
415 << KeyValues::definition(atom.definition())
416 << "\n";
417
418 if ( !atom.loadName().empty() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000419 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000420 << KeyValues::loadNameKeyword
421 << ":"
422 << spacePadding(KeyValues::loadNameKeyword)
423 << atom.loadName()
424 << "\n";
425 }
426
427 if ( atom.canBeNullAtRuntime() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000428 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000429 << KeyValues::canBeNullKeyword
430 << ":"
431 << spacePadding(KeyValues::canBeNullKeyword)
432 << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
433 << "\n";
434 }
435 }
436
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000437 void writeAbsoluteAtom(const AbsoluteAtom& atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000438 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000439 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000440 _firstAtom = false;
441 }
442 else {
443 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000444 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000445 }
446
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000447 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000448 << KeyValues::nameKeyword
449 << ":"
450 << spacePadding(KeyValues::nameKeyword)
451 << atom.name()
452 << "\n";
453
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000454 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000455 << KeyValues::definitionKeyword
456 << ":"
457 << spacePadding(KeyValues::definitionKeyword)
458 << KeyValues::definition(atom.definition())
459 << "\n";
460
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000461 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000462 << KeyValues::valueKeyword
463 << ":"
464 << spacePadding(KeyValues::valueKeyword)
465 << "0x";
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000466 out.write_hex(atom.value());
467 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000468 }
469
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000470
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000471private:
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000472 // return a string of the correct number of spaces to align value
473 const char* spacePadding(const char* key) {
474 const char* spaces = " ";
475 assert(strlen(spaces) > strlen(key));
476 return &spaces[strlen(key)];
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000477 }
478
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000479 char hexdigit(uint8_t nibble) {
480 if ( nibble < 0x0A )
481 return '0' + nibble;
482 else
483 return 'A' + nibble - 0x0A;
484 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000485
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000486 const File& _file;
487 Platform& _platform;
488 RefNameBuilder& _rnb;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000489 bool _firstAtom;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000490};
491
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000492} // anonymous namespace
493
494
495
496///
497/// writeObjectText - writes the lld::File object as in YAML
498/// format to the specified stream.
499///
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000500void writeObjectText(const File& file, Platform& platform,
501 llvm::raw_ostream &out) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000502 // Figure what ref-name labels are needed
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000503 RefNameBuilder rnb(file);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000504
505 // Write out all atoms
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000506 AtomWriter writer(file, platform, rnb);
507 writer.write(out);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000508}
509
510} // namespace yaml
511} // namespace lld