blob: e5f0b1c44c373880fd0b956a80db8e354cf4ce62 [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
17#include "llvm/ADT/OwningPtr.h"
Nick Kledzikbfedfc12012-01-09 20:18:15 +000018#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/StringExtras.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000020#include "llvm/Support/DataTypes.h"
21#include "llvm/Support/MemoryBuffer.h"
22#include "llvm/Support/system_error.h"
23
24#include <vector>
25
26namespace lld {
27namespace yaml {
28
29class Handler : public File::AtomHandler {
30public:
Nick Kledzik7735a7d2012-01-04 23:58:17 +000031 Handler(llvm::raw_ostream &out) : _out(out), _firstAtom(true) { }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000032
Nick Kledzik7735a7d2012-01-04 23:58:17 +000033 virtual void doFile(const class File &) { _firstAtom = true; }
34
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000035 virtual void doDefinedAtom(const class DefinedAtom &atom) {
Nick Kledzik7735a7d2012-01-04 23:58:17 +000036 // add blank line between atoms for readability
37 if ( !_firstAtom )
38 _out << "\n";
39 _firstAtom = false;
40
41 _out << " - "
42 << KeyValues::nameKeyword
43 << ":"
44 << spacePadding(KeyValues::nameKeyword)
45 << atom.name()
46 << "\n";
Nick Kledzik38eec3d2011-12-22 02:38:01 +000047
Nick Kledzik7735a7d2012-01-04 23:58:17 +000048 if ( atom.internalName() != KeyValues::internalNameDefault ) {
49 _out << " "
50 << KeyValues::internalNameKeyword
51 << ":"
52 << spacePadding(KeyValues::internalNameKeyword)
53 << KeyValues::internalName(atom.internalName())
54 << "\n";
55 }
Nick Kledzik38eec3d2011-12-22 02:38:01 +000056
Nick Kledzik7735a7d2012-01-04 23:58:17 +000057 if ( atom.definition() != KeyValues::definitionDefault ) {
58 _out << " "
59 << KeyValues::definitionKeyword
60 << ":"
61 << spacePadding(KeyValues::definitionKeyword)
62 << KeyValues::definition(atom.definition())
63 << "\n";
64 }
65
66 if ( atom.scope() != KeyValues::scopeDefault ) {
67 _out << " "
68 << KeyValues::scopeKeyword
69 << ":"
70 << spacePadding(KeyValues::scopeKeyword)
71 << KeyValues::scope(atom.scope())
72 << "\n";
73 }
74
Nick Kledzikf4fb2c52012-01-11 01:06:19 +000075 if ( atom.interposable() != KeyValues::interposableDefault ) {
76 _out << " "
77 << KeyValues::interposableKeyword
78 << ":"
79 << spacePadding(KeyValues::interposableKeyword)
80 << KeyValues::interposable(atom.interposable())
81 << "\n";
82 }
83
84 if ( atom.merge() != KeyValues::mergeDefault ) {
85 _out << " "
86 << KeyValues::mergeKeyword
87 << ":"
88 << spacePadding(KeyValues::mergeKeyword)
89 << KeyValues::merge(atom.merge())
90 << "\n";
91 }
92
Nick Kledzik7735a7d2012-01-04 23:58:17 +000093 if ( atom.contentType() != KeyValues::contentTypeDefault ) {
94 _out << " "
95 << KeyValues::contentTypeKeyword
96 << ":"
97 << spacePadding(KeyValues::contentTypeKeyword)
98 << KeyValues::contentType(atom.contentType())
99 << "\n";
100 }
101
102 if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
103 _out << " "
104 << KeyValues::deadStripKindKeyword
105 << ":"
106 << spacePadding(KeyValues::deadStripKindKeyword)
107 << KeyValues::deadStripKind(atom.deadStrip())
108 << "\n";
109 }
110
111 if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
112 _out << " "
113 << KeyValues::sectionChoiceKeyword
114 << ":"
115 << spacePadding(KeyValues::sectionChoiceKeyword)
116 << KeyValues::sectionChoice(atom.sectionChoice())
117 << "\n";
118 assert( ! atom.customSectionName().empty() );
119 _out << " "
120 << KeyValues::sectionNameKeyword
121 << ":"
122 << spacePadding(KeyValues::sectionNameKeyword)
123 << atom.customSectionName()
124 << "\n";
125 }
126
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000127 if ( atom.isThumb() != KeyValues::isThumbDefault ) {
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000128 _out << " "
129 << KeyValues::isThumbKeyword
130 << ":"
131 << spacePadding(KeyValues::isThumbKeyword)
132 << KeyValues::isThumb(atom.isThumb())
133 << "\n";
134 }
135
136 if ( atom.isAlias() != KeyValues::isAliasDefault ) {
137 _out << " "
138 << KeyValues::isAliasKeyword
139 << ":"
140 << spacePadding(KeyValues::isAliasKeyword)
141 << KeyValues::isAlias(atom.isAlias())
142 << "\n";
143 }
144
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000145 if ( atom.contentType() != DefinedAtom::typeZeroFill ) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000146 _out << " "
147 << KeyValues::contentKeyword
148 << ":"
149 << spacePadding(KeyValues::contentKeyword)
150 << "[ ";
151 llvm::ArrayRef<uint8_t> arr = atom.rawContent();
152 bool needComma = false;
153 for (unsigned int i=0; i < arr.size(); ++i) {
154 if ( needComma )
155 _out << ", ";
156 _out << hexdigit(arr[i] >> 4);
157 _out << hexdigit(arr[i] & 0x0F);
158 needComma = true;
159 }
160 _out << " ]\n";
161 }
162
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000163 if (atom.referencesBegin() != atom.referencesEnd()) {
164 _out << " fixups:\n";
165 for (Reference::iterator it = atom.referencesBegin(),
166 end = atom.referencesEnd(); it != end; ++it) {
167 _out << " - kind: " << it->kind << "\n";
168 _out << " offset: " << it->offsetInAtom << "\n";
169 }
170 }
171
172 }
173
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000174 virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
175
176 }
177
178
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000179private:
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000180 // return a string of the correct number of spaces to align value
181 const char* spacePadding(const char* key) {
182 const char* spaces = " ";
183 assert(strlen(spaces) > strlen(key));
184 return &spaces[strlen(key)];
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000185 }
186
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000187 char hexdigit(uint8_t nibble) {
188 if ( nibble < 0x0A )
189 return '0' + nibble;
190 else
191 return 'A' + nibble - 0x0A;
192 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000193
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000194 llvm::raw_ostream& _out;
195 bool _firstAtom;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000196};
197
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000198void writeObjectText(const File &file, llvm::raw_ostream &out) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000199 Handler h(out);
200 out << "---\n";
201 out << "atoms:\n";
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000202 file.forEachAtom(h);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000203 out << "...\n";
204}
205
206} // namespace yaml
207} // namespace lld