blob: bd253b425064ba03bc7ccdb93bbda3539724a475 [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
Nick Kledzik7735a7d2012-01-04 23:58:17 +000010#include "YamlKeyValues.h"
11
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000012#include "lld/Core/YamlWriter.h"
13#include "lld/Core/Atom.h"
14#include "lld/Core/File.h"
15#include "lld/Core/Reference.h"
16
Nick Kledzik1a6615d2012-03-08 00:18:30 +000017#include "lld/Platform/Platform.h"
18
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000019#include "llvm/ADT/OwningPtr.h"
Nick Kledzik49d6cc82012-02-15 00:38:09 +000020#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/StringExtras.h"
Michael J. Spencere753cbc2012-03-09 05:27:43 +000022#include "llvm/ADT/StringMap.h"
Nick Kledzikbfedfc12012-01-09 20:18:15 +000023#include "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/StringExtras.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000025#include "llvm/Support/DataTypes.h"
Michael J. Spencere753cbc2012-03-09 05:27:43 +000026#include "llvm/Support/Format.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000027#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencere753cbc2012-03-09 05:27:43 +000028#include "llvm/Support/raw_ostream.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000029#include "llvm/Support/system_error.h"
30
31#include <vector>
32
33namespace lld {
34namespace yaml {
35
Nick Kledzik49d6cc82012-02-15 00:38:09 +000036namespace {
37///
38/// In most cases, atoms names are unambiguous, so references can just
39/// use the atom name as the target (e.g. target: foo). But in a few
40/// cases that does not work, so ref-names are added. These are labels
41/// used only in yaml. The labels do not exist in the Atom model.
42///
43/// One need for ref-names are when atoms have no user supplied name
44/// (e.g. c-string literal). Another case is when two object files with
45/// identically named static functions are merged (ld -r) into one object file.
46/// In that case referencing the function by name is ambiguous, so a unique
47/// ref-name is added.
48///
Nick Kledzik1a6615d2012-03-08 00:18:30 +000049class RefNameBuilder {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000050public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +000051 RefNameBuilder(const File& file)
52 : _collisionCount(0), _unnamedCounter(0) {
53 // visit all atoms
54 for(File::defined_iterator it=file.definedAtomsBegin(),
55 end=file.definedAtomsEnd();
56 it != end; ++it) {
57 const DefinedAtom* atom = *it;
58 // Build map of atoms names to detect duplicates
59 if ( ! atom->name().empty() )
60 buildDuplicateNameMap(*atom);
61
62 // Find references to unnamed atoms and create ref-names for them.
63 for (auto rit=atom->referencesBegin(), rend=atom->referencesEnd();
64 rit != rend; ++rit) {
65 const Reference* ref = *rit;
66 // create refname for any unnamed reference target
67 if ( ref->target()->name().empty() ) {
Michael J. Spencere753cbc2012-03-09 05:27:43 +000068 std::string Storage;
69 llvm::raw_string_ostream Buffer(Storage);
70 Buffer << llvm::format("L%03d", _unnamedCounter++);
71 _refNames[ref->target()] = Buffer.str();
Nick Kledzik1a6615d2012-03-08 00:18:30 +000072 }
73 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000074 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +000075 for(File::undefined_iterator it=file.undefinedAtomsBegin(),
76 end=file.undefinedAtomsEnd();
77 it != end; ++it) {
78 buildDuplicateNameMap(**it);
79 }
80 for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(),
81 end=file.sharedLibraryAtomsEnd();
82 it != end; ++it) {
83 buildDuplicateNameMap(**it);
84 }
85 for(File::absolute_iterator it=file.absoluteAtomsBegin(),
86 end=file.absoluteAtomsEnd();
87 it != end; ++it) {
88 buildDuplicateNameMap(**it);
89 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000090
Nick Kledzik49d6cc82012-02-15 00:38:09 +000091
Nick Kledzik49d6cc82012-02-15 00:38:09 +000092 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +000093
Nick Kledzik49d6cc82012-02-15 00:38:09 +000094 void buildDuplicateNameMap(const Atom& atom) {
95 assert(!atom.name().empty());
96 NameToAtom::iterator pos = _nameMap.find(atom.name());
97 if ( pos != _nameMap.end() ) {
98 // Found name collision, give each a unique ref-name.
Michael J. Spencere753cbc2012-03-09 05:27:43 +000099 std::string Storage;
100 llvm::raw_string_ostream Buffer(Storage);
101 Buffer << atom.name() << llvm::format(".%03d", ++_collisionCount);
102 _refNames[&atom] = Buffer.str();
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000103 const Atom* prevAtom = pos->second;
104 AtomToRefName::iterator pos2 = _refNames.find(prevAtom);
105 if ( pos2 == _refNames.end() ) {
106 // only create ref-name for previous if none already created
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000107 Buffer << prevAtom->name() << llvm::format(".%03d", ++_collisionCount);
108 _refNames[prevAtom] = Buffer.str();
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000109 }
110 }
111 else {
112 // First time we've seen this name, just add it to map.
113 _nameMap[atom.name()] = &atom;
114 }
115 }
116
117 bool hasRefName(const Atom* atom) {
118 return _refNames.count(atom);
119 }
120
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000121 llvm::StringRef refName(const Atom* atom) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000122 return _refNames.find(atom)->second;
123 }
124
125private:
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000126 typedef llvm::StringMap<const Atom*> NameToAtom;
127 typedef llvm::DenseMap<const Atom*, std::string> AtomToRefName;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000128
129 unsigned int _collisionCount;
130 unsigned int _unnamedCounter;
131 NameToAtom _nameMap;
132 AtomToRefName _refNames;
133};
134
135
136///
137/// Helper class for writeObjectText() to write out atoms in yaml format.
138///
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000139class AtomWriter {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000140public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000141 AtomWriter(const File& file, Platform& platform, RefNameBuilder& rnb)
142 : _file(file), _platform(platform), _rnb(rnb), _firstAtom(true) { }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000143
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000144
145 void write(llvm::raw_ostream& out) {
146 // write header
147 out << "---\n";
148
149 // visit all atoms
150 for(File::defined_iterator it=_file.definedAtomsBegin(),
151 end=_file.definedAtomsEnd();
152 it != end; ++it) {
153 writeDefinedAtom(**it, out);
154 }
155 for(File::undefined_iterator it=_file.undefinedAtomsBegin(),
156 end=_file.undefinedAtomsEnd();
157 it != end; ++it) {
158 writeUndefinedAtom(**it, out);
159 }
160 for(File::shared_library_iterator it=_file.sharedLibraryAtomsBegin(),
161 end=_file.sharedLibraryAtomsEnd();
162 it != end; ++it) {
163 writeSharedLibraryAtom(**it, out);
164 }
165 for(File::absolute_iterator it=_file.absoluteAtomsBegin(),
166 end=_file.absoluteAtomsEnd();
167 it != end; ++it) {
168 writeAbsoluteAtom(**it, out);
169 }
170
171 out << "...\n";
172 }
173
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000174
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000175 void writeDefinedAtom(const DefinedAtom &atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000176 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000177 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000178 _firstAtom = false;
179 }
180 else {
181 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000182 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000183 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000184
185 bool hasDash = false;
186 if ( !atom.name().empty() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000187 out << " - "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000188 << KeyValues::nameKeyword
189 << ":"
190 << spacePadding(KeyValues::nameKeyword)
191 << atom.name()
192 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000193 hasDash = true;
194 }
195
196 if ( _rnb.hasRefName(&atom) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000197 out << (hasDash ? " " : " - ")
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000198 << KeyValues::refNameKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000199 << ":"
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000200 << spacePadding(KeyValues::refNameKeyword)
201 << _rnb.refName(&atom)
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000202 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000203 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000204 }
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000205
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000206 if ( atom.definition() != KeyValues::definitionDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000207 out << (hasDash ? " " : " - ")
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000208 << KeyValues::definitionKeyword
209 << ":"
210 << spacePadding(KeyValues::definitionKeyword)
211 << KeyValues::definition(atom.definition())
212 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000213 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000214 }
215
216 if ( atom.scope() != KeyValues::scopeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000217 out << (hasDash ? " " : " - ")
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000218 << KeyValues::scopeKeyword
219 << ":"
220 << spacePadding(KeyValues::scopeKeyword)
221 << KeyValues::scope(atom.scope())
222 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000223 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000224 }
225
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000226 if ( atom.interposable() != KeyValues::interposableDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000227 out << " "
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000228 << KeyValues::interposableKeyword
229 << ":"
230 << spacePadding(KeyValues::interposableKeyword)
231 << KeyValues::interposable(atom.interposable())
232 << "\n";
233 }
234
Nick Kledzik23384e82012-02-07 02:59:54 +0000235 if ( atom.merge() != KeyValues::mergeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000236 out << " "
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000237 << KeyValues::mergeKeyword
238 << ":"
239 << spacePadding(KeyValues::mergeKeyword)
240 << KeyValues::merge(atom.merge())
241 << "\n";
242 }
243
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000244 if ( atom.contentType() != KeyValues::contentTypeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000245 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000246 << KeyValues::contentTypeKeyword
247 << ":"
248 << spacePadding(KeyValues::contentTypeKeyword)
249 << KeyValues::contentType(atom.contentType())
250 << "\n";
251 }
252
253 if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000254 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000255 << KeyValues::deadStripKindKeyword
256 << ":"
257 << spacePadding(KeyValues::deadStripKindKeyword)
258 << KeyValues::deadStripKind(atom.deadStrip())
259 << "\n";
260 }
261
262 if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000263 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000264 << KeyValues::sectionChoiceKeyword
265 << ":"
266 << spacePadding(KeyValues::sectionChoiceKeyword)
267 << KeyValues::sectionChoice(atom.sectionChoice())
268 << "\n";
269 assert( ! atom.customSectionName().empty() );
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000270 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000271 << KeyValues::sectionNameKeyword
272 << ":"
273 << spacePadding(KeyValues::sectionNameKeyword)
274 << atom.customSectionName()
275 << "\n";
276 }
277
Nick Kledzik23384e82012-02-07 02:59:54 +0000278 if ( atom.isThumb() != KeyValues::isThumbDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000279 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000280 << KeyValues::isThumbKeyword
281 << ":"
282 << spacePadding(KeyValues::isThumbKeyword)
283 << KeyValues::isThumb(atom.isThumb())
284 << "\n";
285 }
286
287 if ( atom.isAlias() != KeyValues::isAliasDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000288 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000289 << KeyValues::isAliasKeyword
290 << ":"
291 << spacePadding(KeyValues::isAliasKeyword)
292 << KeyValues::isAlias(atom.isAlias())
293 << "\n";
294 }
295
Nick Kledzik23384e82012-02-07 02:59:54 +0000296 if ( (atom.contentType() != DefinedAtom::typeZeroFill)
297 && (atom.size() != 0) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000298 out << " "
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000299 << KeyValues::contentKeyword
300 << ":"
301 << spacePadding(KeyValues::contentKeyword)
302 << "[ ";
303 llvm::ArrayRef<uint8_t> arr = atom.rawContent();
304 bool needComma = false;
305 for (unsigned int i=0; i < arr.size(); ++i) {
306 if ( needComma )
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000307 out << ", ";
Nick Kledzikf4e2c732012-03-15 23:36:24 +0000308 if ( ((i % 12) == 0) && (i != 0) ) {
309 out << "\n ";
310 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000311 out << hexdigit(arr[i] >> 4);
312 out << hexdigit(arr[i] & 0x0F);
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000313 needComma = true;
314 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000315 out << " ]\n";
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000316 }
317
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000318 bool wroteFirstFixup = false;
319 for (auto it=atom.referencesBegin(), end=atom.referencesEnd();
320 it != end; ++it) {
321 const Reference* ref = *it;
322 if ( !wroteFirstFixup ) {
323 out << " fixups:\n";
324 wroteFirstFixup = true;
325 }
326 out << " - "
327 << KeyValues::fixupsOffsetKeyword
328 << ":"
329 << spacePadding(KeyValues::fixupsOffsetKeyword)
330 << ref->offsetInAtom()
331 << "\n";
332 out << " "
333 << KeyValues::fixupsKindKeyword
334 << ":"
335 << spacePadding(KeyValues::fixupsKindKeyword)
336 << _platform.kindToString(ref->kind())
337 << "\n";
338 const Atom* target = ref->target();
339 if ( target != NULL ) {
340 llvm::StringRef refName = target->name();
341 if ( _rnb.hasRefName(target) )
342 refName = _rnb.refName(target);
343 assert(!refName.empty());
344 out << " "
345 << KeyValues::fixupsTargetKeyword
346 << ":"
347 << spacePadding(KeyValues::fixupsTargetKeyword)
348 << refName
349 << "\n";
350 }
351 if ( ref->addend() != 0 ) {
352 out << " "
353 << KeyValues::fixupsAddendKeyword
354 << ":"
355 << spacePadding(KeyValues::fixupsAddendKeyword)
356 << ref->addend()
357 << "\n";
358 }
359 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000360 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000361
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000362
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000363 void writeUndefinedAtom(const UndefinedAtom &atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000364 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000365 out << "atoms:\n";
Nick Kledzik23384e82012-02-07 02:59:54 +0000366 _firstAtom = false;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000367 }
368 else {
369 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000370 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000371 }
Nick Kledzik23384e82012-02-07 02:59:54 +0000372
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000373 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000374 << KeyValues::nameKeyword
375 << ":"
376 << spacePadding(KeyValues::nameKeyword)
377 << atom.name()
378 << "\n";
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000379
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000380 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000381 << KeyValues::definitionKeyword
382 << ":"
383 << spacePadding(KeyValues::definitionKeyword)
384 << KeyValues::definition(atom.definition())
385 << "\n";
Nick Kledzik23384e82012-02-07 02:59:54 +0000386
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000387 if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000388 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000389 << KeyValues::canBeNullKeyword
Nick Kledzik23384e82012-02-07 02:59:54 +0000390 << ":"
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000391 << spacePadding(KeyValues::canBeNullKeyword)
392 << KeyValues::canBeNull(atom.canBeNull())
Nick Kledzik23384e82012-02-07 02:59:54 +0000393 << "\n";
394 }
395 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000396
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000397 void writeSharedLibraryAtom(const SharedLibraryAtom& atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000398 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000399 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000400 _firstAtom = false;
401 }
402 else {
403 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000404 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000405 }
406
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000407 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000408 << KeyValues::nameKeyword
409 << ":"
410 << spacePadding(KeyValues::nameKeyword)
411 << atom.name()
412 << "\n";
413
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000414 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000415 << KeyValues::definitionKeyword
416 << ":"
417 << spacePadding(KeyValues::definitionKeyword)
418 << KeyValues::definition(atom.definition())
419 << "\n";
420
421 if ( !atom.loadName().empty() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000422 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000423 << KeyValues::loadNameKeyword
424 << ":"
425 << spacePadding(KeyValues::loadNameKeyword)
426 << atom.loadName()
427 << "\n";
428 }
429
430 if ( atom.canBeNullAtRuntime() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000431 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000432 << KeyValues::canBeNullKeyword
433 << ":"
434 << spacePadding(KeyValues::canBeNullKeyword)
435 << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
436 << "\n";
437 }
438 }
439
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000440 void writeAbsoluteAtom(const AbsoluteAtom& atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000441 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000442 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000443 _firstAtom = false;
444 }
445 else {
446 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000447 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000448 }
449
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000450 out << " - "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000451 << KeyValues::nameKeyword
452 << ":"
453 << spacePadding(KeyValues::nameKeyword)
454 << atom.name()
455 << "\n";
456
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000457 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000458 << KeyValues::definitionKeyword
459 << ":"
460 << spacePadding(KeyValues::definitionKeyword)
461 << KeyValues::definition(atom.definition())
462 << "\n";
463
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000464 out << " "
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000465 << KeyValues::valueKeyword
466 << ":"
467 << spacePadding(KeyValues::valueKeyword)
468 << "0x";
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000469 out.write_hex(atom.value());
470 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000471 }
472
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000473
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000474private:
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000475 // return a string of the correct number of spaces to align value
476 const char* spacePadding(const char* key) {
477 const char* spaces = " ";
478 assert(strlen(spaces) > strlen(key));
479 return &spaces[strlen(key)];
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000480 }
481
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000482 char hexdigit(uint8_t nibble) {
483 if ( nibble < 0x0A )
484 return '0' + nibble;
485 else
486 return 'A' + nibble - 0x0A;
487 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000488
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000489 const File& _file;
490 Platform& _platform;
491 RefNameBuilder& _rnb;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000492 bool _firstAtom;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000493};
494
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000495} // anonymous namespace
496
497
498
499///
500/// writeObjectText - writes the lld::File object as in YAML
501/// format to the specified stream.
502///
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000503void writeObjectText(const File& file, Platform& platform,
504 llvm::raw_ostream &out) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000505 // Figure what ref-name labels are needed
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000506 RefNameBuilder rnb(file);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000507
508 // Write out all atoms
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000509 AtomWriter writer(file, platform, rnb);
510 writer.write(out);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000511}
512
513} // namespace yaml
514} // namespace lld