blob: f8440667c9d930e410cdbb77b9653b7f92184a67 [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"
Nick Kledzikbfedfc12012-01-09 20:18:15 +000022#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/StringExtras.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000024#include "llvm/Support/DataTypes.h"
25#include "llvm/Support/MemoryBuffer.h"
26#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() ) {
65 char* buffer;
66 asprintf(&buffer, "L%03d", _unnamedCounter++);
67 _refNames[ref->target()] = buffer;
68 }
69 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000070 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +000071 for(File::undefined_iterator it=file.undefinedAtomsBegin(),
72 end=file.undefinedAtomsEnd();
73 it != end; ++it) {
74 buildDuplicateNameMap(**it);
75 }
76 for(File::shared_library_iterator it=file.sharedLibraryAtomsBegin(),
77 end=file.sharedLibraryAtomsEnd();
78 it != end; ++it) {
79 buildDuplicateNameMap(**it);
80 }
81 for(File::absolute_iterator it=file.absoluteAtomsBegin(),
82 end=file.absoluteAtomsEnd();
83 it != end; ++it) {
84 buildDuplicateNameMap(**it);
85 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +000086
Nick Kledzik49d6cc82012-02-15 00:38:09 +000087
Nick Kledzik49d6cc82012-02-15 00:38:09 +000088 }
Nick Kledzik1a6615d2012-03-08 00:18:30 +000089
Nick Kledzik49d6cc82012-02-15 00:38:09 +000090 void buildDuplicateNameMap(const Atom& atom) {
91 assert(!atom.name().empty());
92 NameToAtom::iterator pos = _nameMap.find(atom.name());
93 if ( pos != _nameMap.end() ) {
94 // Found name collision, give each a unique ref-name.
95 char* buffer;
96 asprintf(&buffer, "%s.%03d", atom.name().data(), ++_collisionCount);
97 _refNames[&atom] = buffer;
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
102 asprintf(&buffer, "%s.%03d", prevAtom->name().data(), ++_collisionCount);
103 _refNames[prevAtom] = buffer;
104 }
105 }
106 else {
107 // First time we've seen this name, just add it to map.
108 _nameMap[atom.name()] = &atom;
109 }
110 }
111
112 bool hasRefName(const Atom* atom) {
113 return _refNames.count(atom);
114 }
115
116 const char* refName(const Atom* atom) {
117 return _refNames.find(atom)->second;
118 }
119
120private:
121 struct MyMappingInfo {
122 static llvm::StringRef getEmptyKey() { return llvm::StringRef(); }
123 static llvm::StringRef getTombstoneKey() { return llvm::StringRef(" ", 0); }
124 static unsigned getHashValue(llvm::StringRef const val) {
125 return llvm::HashString(val); }
126 static bool isEqual(llvm::StringRef const lhs,
127 llvm::StringRef const rhs) { return lhs.equals(rhs); }
128 };
129 typedef llvm::DenseMap<llvm::StringRef, const Atom*, MyMappingInfo> NameToAtom;
130 typedef llvm::DenseMap<const Atom*, const char*> AtomToRefName;
131
132 unsigned int _collisionCount;
133 unsigned int _unnamedCounter;
134 NameToAtom _nameMap;
135 AtomToRefName _refNames;
136};
137
138
139///
140/// Helper class for writeObjectText() to write out atoms in yaml format.
141///
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000142class AtomWriter {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000143public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000144 AtomWriter(const File& file, Platform& platform, RefNameBuilder& rnb)
145 : _file(file), _platform(platform), _rnb(rnb), _firstAtom(true) { }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000146
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000147
148 void write(llvm::raw_ostream& out) {
149 // write header
150 out << "---\n";
151
152 // visit all atoms
153 for(File::defined_iterator it=_file.definedAtomsBegin(),
154 end=_file.definedAtomsEnd();
155 it != end; ++it) {
156 writeDefinedAtom(**it, out);
157 }
158 for(File::undefined_iterator it=_file.undefinedAtomsBegin(),
159 end=_file.undefinedAtomsEnd();
160 it != end; ++it) {
161 writeUndefinedAtom(**it, out);
162 }
163 for(File::shared_library_iterator it=_file.sharedLibraryAtomsBegin(),
164 end=_file.sharedLibraryAtomsEnd();
165 it != end; ++it) {
166 writeSharedLibraryAtom(**it, out);
167 }
168 for(File::absolute_iterator it=_file.absoluteAtomsBegin(),
169 end=_file.absoluteAtomsEnd();
170 it != end; ++it) {
171 writeAbsoluteAtom(**it, out);
172 }
173
174 out << "...\n";
175 }
176
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000177
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000178 void writeDefinedAtom(const DefinedAtom &atom, llvm::raw_ostream& out) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000179 if ( _firstAtom ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000180 out << "atoms:\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000181 _firstAtom = false;
182 }
183 else {
184 // add blank line between atoms for readability
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000185 out << "\n";
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000186 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000187
188 bool hasDash = false;
189 if ( !atom.name().empty() ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000190 out << " - "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000191 << KeyValues::nameKeyword
192 << ":"
193 << spacePadding(KeyValues::nameKeyword)
194 << atom.name()
195 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000196 hasDash = true;
197 }
198
199 if ( _rnb.hasRefName(&atom) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000200 out << (hasDash ? " " : " - ")
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000201 << KeyValues::refNameKeyword
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000202 << ":"
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000203 << spacePadding(KeyValues::refNameKeyword)
204 << _rnb.refName(&atom)
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000205 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000206 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000207 }
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000208
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000209 if ( atom.definition() != KeyValues::definitionDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000210 out << (hasDash ? " " : " - ")
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000211 << KeyValues::definitionKeyword
212 << ":"
213 << spacePadding(KeyValues::definitionKeyword)
214 << KeyValues::definition(atom.definition())
215 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000216 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000217 }
218
219 if ( atom.scope() != KeyValues::scopeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000220 out << (hasDash ? " " : " - ")
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000221 << KeyValues::scopeKeyword
222 << ":"
223 << spacePadding(KeyValues::scopeKeyword)
224 << KeyValues::scope(atom.scope())
225 << "\n";
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000226 hasDash = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000227 }
228
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000229 if ( atom.interposable() != KeyValues::interposableDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000230 out << " "
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000231 << KeyValues::interposableKeyword
232 << ":"
233 << spacePadding(KeyValues::interposableKeyword)
234 << KeyValues::interposable(atom.interposable())
235 << "\n";
236 }
237
Nick Kledzik23384e82012-02-07 02:59:54 +0000238 if ( atom.merge() != KeyValues::mergeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000239 out << " "
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000240 << KeyValues::mergeKeyword
241 << ":"
242 << spacePadding(KeyValues::mergeKeyword)
243 << KeyValues::merge(atom.merge())
244 << "\n";
245 }
246
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000247 if ( atom.contentType() != KeyValues::contentTypeDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000248 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000249 << KeyValues::contentTypeKeyword
250 << ":"
251 << spacePadding(KeyValues::contentTypeKeyword)
252 << KeyValues::contentType(atom.contentType())
253 << "\n";
254 }
255
256 if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000257 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000258 << KeyValues::deadStripKindKeyword
259 << ":"
260 << spacePadding(KeyValues::deadStripKindKeyword)
261 << KeyValues::deadStripKind(atom.deadStrip())
262 << "\n";
263 }
264
265 if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000266 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000267 << KeyValues::sectionChoiceKeyword
268 << ":"
269 << spacePadding(KeyValues::sectionChoiceKeyword)
270 << KeyValues::sectionChoice(atom.sectionChoice())
271 << "\n";
272 assert( ! atom.customSectionName().empty() );
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000273 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000274 << KeyValues::sectionNameKeyword
275 << ":"
276 << spacePadding(KeyValues::sectionNameKeyword)
277 << atom.customSectionName()
278 << "\n";
279 }
280
Nick Kledzik23384e82012-02-07 02:59:54 +0000281 if ( atom.isThumb() != KeyValues::isThumbDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000282 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000283 << KeyValues::isThumbKeyword
284 << ":"
285 << spacePadding(KeyValues::isThumbKeyword)
286 << KeyValues::isThumb(atom.isThumb())
287 << "\n";
288 }
289
290 if ( atom.isAlias() != KeyValues::isAliasDefault ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000291 out << " "
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000292 << KeyValues::isAliasKeyword
293 << ":"
294 << spacePadding(KeyValues::isAliasKeyword)
295 << KeyValues::isAlias(atom.isAlias())
296 << "\n";
297 }
298
Nick Kledzik23384e82012-02-07 02:59:54 +0000299 if ( (atom.contentType() != DefinedAtom::typeZeroFill)
300 && (atom.size() != 0) ) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000301 out << " "
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000302 << KeyValues::contentKeyword
303 << ":"
304 << spacePadding(KeyValues::contentKeyword)
305 << "[ ";
306 llvm::ArrayRef<uint8_t> arr = atom.rawContent();
307 bool needComma = false;
308 for (unsigned int i=0; i < arr.size(); ++i) {
309 if ( needComma )
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000310 out << ", ";
311 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