blob: 2a9e05078ea74d70d0e86957e24d7bc9b069c753 [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 << ", ";
308 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