blob: 5ca8fbc81035d62abdc353832217b77550cde87d [file] [log] [blame]
Michael J. Spencer773a8fb2011-12-18 08:27:59 +00001//===- Core/YamlReader.cpp - Reads 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/YamlReader.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"
18#include "llvm/ADT/StringRef.h"
Nick Kledzikbfedfc12012-01-09 20:18:15 +000019#include "llvm/ADT/ArrayRef.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000020#include "llvm/Support/DataTypes.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/MemoryBuffer.h"
23#include "llvm/Support/system_error.h"
24
25#include <vector>
26
Nick Kledzik7735a7d2012-01-04 23:58:17 +000027
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000028
29namespace lld {
30namespace yaml {
Nick Kledzik7735a7d2012-01-04 23:58:17 +000031
32enum yaml_reader_errors {
33 success = 0,
34 unknown_keyword,
35 illegal_value
36};
37
38class reader_error_category : public llvm::_do_message {
39public:
40 virtual const char* name() const {
41 return "lld.yaml.reader";
42 }
43 virtual std::string message(int ev) const;
44};
45
46const reader_error_category reader_error_category_singleton;
47
48std::string reader_error_category::message(int ev) const {
49 switch (ev) {
50 case success:
51 return "Success";
52 case unknown_keyword:
53 return "Unknown keyword found in yaml file";
54 case illegal_value:
55 return "Bad value found in yaml file";
56 default:
57 llvm_unreachable("An enumerator of yaml_reader_errors does not have a "
58 "message defined.");
59 }
60}
61
62inline llvm::error_code make_error_code(yaml_reader_errors e) {
63 return llvm::error_code(static_cast<int>(e), reader_error_category_singleton);
64}
65
66
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000067class YAML {
68public:
69 struct Entry {
Nick Kledzikbfedfc12012-01-09 20:18:15 +000070 Entry(const char *k, const char *v, std::vector<uint8_t>* vs,
71 int d, bool bd, bool bs)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000072 : key(strdup(k))
Nick Kledzikbfedfc12012-01-09 20:18:15 +000073 , value(v ? strdup(v) : NULL)
74 , valueSequenceBytes(vs)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000075 , depth(d)
76 , beginSequence(bs)
77 , beginDocument(bd) {}
78
Nick Kledzikbfedfc12012-01-09 20:18:15 +000079 const char * key;
80 const char * value;
81 std::vector<uint8_t>* valueSequenceBytes;
82 int depth;
83 bool beginSequence;
84 bool beginDocument;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000085 };
86
87 static void parse(llvm::MemoryBuffer *mb, std::vector<const Entry *>&);
88
89private:
90 enum State {
91 start,
92 inHeaderComment,
93 inTripleDash,
94 inTriplePeriod,
95 inDocument,
96 inKey,
97 inSpaceBeforeValue,
98 inValue,
99 inValueSequence,
100 inValueSequenceEnd
101 };
102};
103
104
105void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
106 State state = start;
107 char key[64];
108 char value[64];
109 char *p = NULL;
110 unsigned int lineNumber = 1;
111 int depth = 0;
112 bool nextKeyIsStartOfDocument = false;
113 bool nextKeyIsStartOfSequence = false;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000114 std::vector<uint8_t>* sequenceBytes = NULL;
115 unsigned contentByte = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000116 for (const char *s = mb->getBufferStart(); s < mb->getBufferEnd(); ++s) {
117 char c = *s;
118 if (c == '\n')
119 ++lineNumber;
120 switch (state) {
121 case start:
122 if (c == '#')
123 state = inHeaderComment;
124 else if (c == '-') {
125 p = &key[0];
126 *p++ = c;
127 state = inTripleDash;
128 }
129 break;
130 case inHeaderComment:
131 if (c == '\n') {
132 state = start;
133 }
134 break;
135 case inTripleDash:
136 if (c == '-') {
137 *p++ = c;
138 } else if (c == '\n') {
139 *p = '\0';
140 if (strcmp(key, "---") != 0)
141 return;
142 depth = 0;
143 state = inDocument;
144 nextKeyIsStartOfDocument = true;
145 } else {
146 return;
147 }
148 break;
149 case inTriplePeriod:
150 if (c == '.') {
151 *p++ = c;
152 } else if (c == '\n') {
153 *p = '\0';
154 if (strcmp(key, "...") != 0)
155 return;
156 depth = 0;
157 state = inHeaderComment;
158 } else {
159 return;
160 }
161 break;
162 case inDocument:
163 if (isalnum(c)) {
164 state = inKey;
165 p = &key[0];
166 *p++ = c;
167 } else if (c == '-') {
168 if (depth == 0) {
169 p = &key[0];
170 *p++ = c;
171 state = inTripleDash;
172 } else {
173 nextKeyIsStartOfSequence = true;
174 ++depth;
175 }
176 } else if (c == ' ') {
177 ++depth;
178 } else if (c == '.') {
179 p = &key[0];
180 *p++ = c;
181 state = inTriplePeriod;
182 } else if (c == '\n') {
183 // ignore empty lines
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000184 depth = 0;
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000185 } else if (c == '\t') {
186 llvm::report_fatal_error("TAB character found in yaml file");
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000187 } else {
188 return;
189 }
190 break;
191 case inKey:
192 if (isalnum(c) || (c == '-')) {
193 *p++ = c;
194 } else if (c == ':') {
195 *p = '\0';
196 state = inSpaceBeforeValue;
197 } else if (c == '\n') {
198 *p = '\0';
199 if (strcmp(key, "---") == 0)
200 state = inDocument;
201 else
202 return;
203 } else {
204 return;
205 }
206 break;
207 case inSpaceBeforeValue:
208 if (isalnum(c) || (c == '-') || (c == '_')) {
209 p = &value[0];
210 *p++ = c;
211 state = inValue;
212 } else if (c == '\n') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000213 entries.push_back(new Entry(key, "", NULL, depth,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000214 nextKeyIsStartOfDocument,
215 nextKeyIsStartOfSequence));
216 nextKeyIsStartOfSequence = false;
217 nextKeyIsStartOfDocument = false;
218 state = inDocument;
219 depth = 0;
220 } else if (c == '[') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000221 contentByte = 0;
222 sequenceBytes = new std::vector<uint8_t>();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000223 state = inValueSequence;
224 } else if (c == ' ') {
225 // eat space
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000226 } else if (c == '\t') {
227 llvm::report_fatal_error("TAB character found in yaml file");
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000228 } else {
229 return;
230 }
231 break;
232 case inValue:
233 if (isalnum(c) || (c == '-') || (c == '_')) {
234 *p++ = c;
235 } else if (c == '\n') {
236 *p = '\0';
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000237 entries.push_back(new Entry(key, value, NULL, depth,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000238 nextKeyIsStartOfDocument,
239 nextKeyIsStartOfSequence));
240 nextKeyIsStartOfSequence = false;
241 nextKeyIsStartOfDocument = false;
242 state = inDocument;
243 depth = 0;
244 }
245 break;
246 case inValueSequence:
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000247 if (c == ']') {
248 sequenceBytes->push_back(contentByte);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000249 state = inValueSequenceEnd;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000250 }
251 else if (c == ' ') {
252 // eat white space
253 }
254 else if (c == ',') {
255 sequenceBytes->push_back(contentByte);
256 }
257 else if ( isdigit(c) ) {
258 contentByte = (contentByte << 4) | (c-'0');
259 }
260 else if ( ('a' <= tolower(c)) && (tolower(c) <= 'f') ) {
261 contentByte = (contentByte << 4) | (tolower(c)-'a'+10);
262 }
263 else {
264 llvm::report_fatal_error("non-hex digit found in content [ ]");
265 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000266 break;
267 case inValueSequenceEnd:
268 if (c == '\n') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000269 entries.push_back(new Entry(key, NULL, sequenceBytes, depth,
270 nextKeyIsStartOfDocument,
271 nextKeyIsStartOfSequence));
272 nextKeyIsStartOfSequence = false;
273 nextKeyIsStartOfDocument = false;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000274 state = inDocument;
275 depth = 0;
276 }
277 break;
278 }
279 }
280}
281
282class YAMLFile : public File {
283public:
284 YAMLFile()
285 : File("path")
286 , _lastRefIndex(0) {}
287
288 virtual bool forEachAtom(File::AtomHandler &) const;
289 virtual bool justInTimeforEachAtom(llvm::StringRef name,
290 File::AtomHandler &) const;
291
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000292 std::vector<DefinedAtom*> _definedAtoms;
293 std::vector<UndefinedAtom*> _undefinedAtoms;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000294 std::vector<Reference> _references;
295 unsigned int _lastRefIndex;
296};
297
298bool YAMLFile::forEachAtom(File::AtomHandler &handler) const {
299 handler.doFile(*this);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000300 for (std::vector<DefinedAtom *>::const_iterator it = _definedAtoms.begin();
301 it != _definedAtoms.end(); ++it) {
302 handler.doDefinedAtom(**it);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000303 }
304 return true;
305}
306
307bool YAMLFile::justInTimeforEachAtom(llvm::StringRef name,
308 File::AtomHandler &handler) const {
309 return false;
310}
311
312
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000313class YAMLDefinedAtom : public DefinedAtom {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000314public:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000315 YAMLDefinedAtom( uint32_t ord
316 , YAMLFile& file
317 , DefinedAtom::Scope scope
318 , DefinedAtom::ContentType type
319 , DefinedAtom::SectionChoice sectionChoice
320 , DefinedAtom::Interposable interpose
321 , DefinedAtom::Merge merge
322 , DefinedAtom::DeadStripKind deadStrip
323 , DefinedAtom::ContentPermissions perms
324 , bool internalName
325 , bool isThumb
326 , bool isAlias
327 , DefinedAtom::Alignment alignment
328 , const char* name
329 , const char* sectionName
330 , uint64_t size
331 , std::vector<uint8_t>* content)
332 : _file(file)
333 , _name(name)
334 , _sectionName(sectionName)
335 , _size(size)
336 , _ord(ord)
337 , _content(content)
338 , _alignment(alignment)
339 , _scope(scope)
340 , _type(type)
341 , _sectionChoice(sectionChoice)
342 , _interpose(interpose)
343 , _merge(merge)
344 , _deadStrip(deadStrip)
345 , _permissions(perms)
346 , _internalName(internalName)
347 , _isThumb(isThumb)
348 , _isAlias(isAlias)
349 , _refStartIndex(file._lastRefIndex)
350 , _refEndIndex(file._references.size()) {
351 file._lastRefIndex = _refEndIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000352 }
353
Nick Kledzikf46669c2011-12-21 23:29:36 +0000354 virtual const class File& file() const {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000355 return _file;
356 }
357
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000358 virtual llvm::StringRef name() const {
359 return _name;
360 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000361
362 virtual bool internalName() const {
363 return _internalName;
364 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000365
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000366 virtual uint64_t size() const {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000367 return (_content ? _content->size() : _size);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000368 }
369
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000370 virtual DefinedAtom::Scope scope() const {
371 return _scope;
372 }
373
374 virtual DefinedAtom::Interposable interposable() const {
375 return _interpose;
376 }
377
378 virtual DefinedAtom::Merge merge() const {
379 return _merge;
380 }
381
382 virtual DefinedAtom::ContentType contentType() const {
383 return _type;
384 }
385
386 virtual DefinedAtom::Alignment alignment() const {
387 return _alignment;
388 }
389
390 virtual DefinedAtom::SectionChoice sectionChoice() const {
391 return _sectionChoice;
392 }
393
394 virtual llvm::StringRef customSectionName() const {
395 return _sectionName;
396 }
397
398 virtual DefinedAtom::DeadStripKind deadStrip() const {
399 return _deadStrip;
400 }
401
402 virtual DefinedAtom::ContentPermissions permissions() const {
403 return _permissions;
404 }
405
406 virtual bool isThumb() const {
407 return _isThumb;
408 }
409
410 virtual bool isAlias() const {
411 return _isAlias;
412 }
413
414 llvm::ArrayRef<uint8_t> rawContent() const {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000415 if ( _content != NULL )
416 return llvm::ArrayRef<uint8_t>(*_content);
417 else
418 return llvm::ArrayRef<uint8_t>();
419 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000420
421 virtual uint64_t ordinal() const {
422 return _ord;
423 }
424
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000425
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000426 virtual Reference::iterator referencesBegin() const {
427 if (_file._references.size() < _refStartIndex)
428 return (Reference::iterator)&_file._references[_refStartIndex];
429 return 0;
430 }
431
432 virtual Reference::iterator referencesEnd() const {
433 if (_file._references.size() < _refEndIndex)
434 return (Reference::iterator)&_file._references[_refEndIndex];
435 return 0;
436 }
437
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000438private:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000439 YAMLFile& _file;
440 const char * _name;
441 const char * _sectionName;
442 unsigned long _size;
443 uint32_t _ord;
444 std::vector<uint8_t>* _content;
445 DefinedAtom::Alignment _alignment;
446 DefinedAtom::Scope _scope;
447 DefinedAtom::ContentType _type;
448 DefinedAtom::SectionChoice _sectionChoice;
449 DefinedAtom::Interposable _interpose;
450 DefinedAtom::Merge _merge;
451 DefinedAtom::DeadStripKind _deadStrip;
452 DefinedAtom::ContentPermissions _permissions;
453 bool _internalName;
454 bool _isThumb;
455 bool _isAlias;
456 unsigned int _refStartIndex;
457 unsigned int _refEndIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000458};
459
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000460
461class YAMLAtomState {
462public:
463 YAMLAtomState();
464
465 void setName(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000466 void setAlign2(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000467
468 void setFixupKind(const char *n);
469 void setFixupOffset(const char *n);
470 void setFixupTarget(const char *n);
471 void addFixup(YAMLFile *f);
472
Nick Kledzikf46669c2011-12-21 23:29:36 +0000473 void makeAtom(YAMLFile&);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000474
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000475 const char * _name;
476 const char * _sectionName;
477 unsigned long long _size;
478 uint32_t _ordinal;
479 std::vector<uint8_t>* _content;
480 DefinedAtom::Alignment _alignment;
481 Atom::Definition _definition;
482 DefinedAtom::Scope _scope;
483 DefinedAtom::ContentType _type;
484 DefinedAtom::SectionChoice _sectionChoice;
485 DefinedAtom::Interposable _interpose;
486 DefinedAtom::Merge _merge;
487 DefinedAtom::DeadStripKind _deadStrip;
488 DefinedAtom::ContentPermissions _permissions;
489 bool _internalName;
490 bool _isThumb;
491 bool _isAlias;
492 Reference _ref;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000493};
494
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000495
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000496YAMLAtomState::YAMLAtomState()
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000497 : _name(NULL)
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000498 , _sectionName(NULL)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000499 , _size(0)
500 , _ordinal(0)
501 , _content(NULL)
502 , _alignment(0, 0)
503 , _definition(KeyValues::definitionDefault)
504 , _scope(KeyValues::scopeDefault)
505 , _type(KeyValues::contentTypeDefault)
506 , _sectionChoice(KeyValues::sectionChoiceDefault)
507 , _interpose(KeyValues::interposableDefault)
508 , _merge(KeyValues::mergeDefault)
509 , _deadStrip(KeyValues::deadStripKindDefault)
510 , _permissions(KeyValues::permissionsDefault)
511 , _internalName(KeyValues::internalNameDefault)
512 , _isThumb(KeyValues::isThumbDefault)
513 , _isAlias(KeyValues::isAliasDefault)
514 {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000515 _ref.target = NULL;
516 _ref.addend = 0;
517 _ref.offsetInAtom = 0;
518 _ref.kind = 0;
519 _ref.flags = 0;
520}
521
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000522
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000523void YAMLAtomState::makeAtom(YAMLFile& f) {
524 if ( _definition == Atom::definitionRegular ) {
525 DefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
526 _sectionChoice, _interpose, _merge, _deadStrip,
527 _permissions, _internalName, _isThumb, _isAlias,
528 _alignment, _name, _sectionName, _size, _content);
529
530 f._definedAtoms.push_back(a);
531 ++_ordinal;
532 }
Nick Kledzikf46669c2011-12-21 23:29:36 +0000533
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000534 // reset state for next atom
535 _name = NULL;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000536 _sectionName = NULL;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000537 _size = 0;
538 _ordinal = 0;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000539 _content = NULL;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000540 _alignment.powerOf2= 0;
541 _alignment.modulus = 0;
542 _definition = KeyValues::definitionDefault;
543 _scope = KeyValues::scopeDefault;
544 _type = KeyValues::contentTypeDefault;
545 _sectionChoice = KeyValues::sectionChoiceDefault;
546 _interpose = KeyValues::interposableDefault;
547 _merge = KeyValues::mergeDefault;
548 _deadStrip = KeyValues::deadStripKindDefault;
549 _permissions = KeyValues::permissionsDefault;
550 _isThumb = KeyValues::isThumbDefault;
551 _isAlias = KeyValues::isAliasDefault;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000552 _ref.target = NULL;
553 _ref.addend = 0;
554 _ref.offsetInAtom = 0;
555 _ref.kind = 0;
556 _ref.flags = 0;
557}
558
559void YAMLAtomState::setName(const char *n) {
560 _name = n;
561}
562
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000563
564void YAMLAtomState::setAlign2(const char *s) {
565 llvm::StringRef str(s);
566 uint32_t res;
567 str.getAsInteger(10, res);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000568 _alignment.powerOf2 = static_cast<uint16_t>(res);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000569}
570
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000571
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000572void YAMLAtomState::setFixupKind(const char *s) {
573 if (strcmp(s, "pcrel32") == 0)
574 _ref.kind = 1;
575 else if (strcmp(s, "call32") == 0)
576 _ref.kind = 2;
577 else
578 llvm::report_fatal_error("bad fixup kind value");
579}
580
581void YAMLAtomState::setFixupOffset(const char *s) {
582 if ((s[0] == '0') && (s[1] == 'x'))
583 llvm::StringRef(s).getAsInteger(16, _ref.offsetInAtom);
584 else
585 llvm::StringRef(s).getAsInteger(10, _ref.offsetInAtom);
586}
587
588void YAMLAtomState::setFixupTarget(const char *s) {
589}
590
591void YAMLAtomState::addFixup(YAMLFile *f) {
592 f->_references.push_back(_ref);
593 // clear for next ref
594 _ref.target = NULL;
595 _ref.addend = 0;
596 _ref.offsetInAtom = 0;
597 _ref.kind = 0;
598 _ref.flags = 0;
599}
600
601llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
602 , std::vector<File *> &result) {
603 std::vector<const YAML::Entry *> entries;
604 YAML::parse(mb, entries);
605
606 YAMLFile *file = NULL;
607 YAMLAtomState atomState;
608 bool inAtoms = false;
609 bool inFixups = false;
610 int depthForAtoms = -1;
611 int depthForFixups = -1;
612 int lastDepth = -1;
613 bool haveAtom = false;
614 bool haveFixup = false;
615
616 for (std::vector<const YAML::Entry *>::iterator it = entries.begin();
617 it != entries.end(); ++it) {
618 const YAML::Entry *entry = *it;
619
620 if (entry->beginDocument) {
621 if (file != NULL) {
622 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000623 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000624 haveAtom = false;
625 }
626 result.push_back(file);
627 }
628 file = new YAMLFile();
629 inAtoms = false;
630 depthForAtoms = -1;
631 }
632 if (lastDepth > entry->depth) {
633 // end of fixup sequence
634 if (haveFixup) {
635 atomState.addFixup(file);
636 haveFixup = false;
637 }
638 }
639
640 if (inAtoms && (depthForAtoms == -1)) {
641 depthForAtoms = entry->depth;
642 }
643 if (inFixups && (depthForFixups == -1)) {
644 depthForFixups = entry->depth;
645 }
646 if (strcmp(entry->key, "atoms") == 0) {
647 inAtoms = true;
648 }
649 if (inAtoms) {
650 if (depthForAtoms == entry->depth) {
651 if (entry->beginSequence) {
652 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000653 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000654 haveAtom = false;
655 }
656 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000657 if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000658 atomState.setName(entry->value);
659 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000660 }
661 else if (strcmp(entry->key, KeyValues::internalNameKeyword) == 0) {
662 atomState._internalName = KeyValues::internalName(entry->value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000663 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000664 }
665 else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000666 atomState._definition = KeyValues::definition(entry->value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000667 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000668 }
669 else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
670 atomState._scope = KeyValues::scope(entry->value);
671 haveAtom = true;
672 }
673 else if (strcmp(entry->key, KeyValues::contentTypeKeyword) == 0) {
674 atomState._type = KeyValues::contentType(entry->value);
675 haveAtom = true;
676 }
677 else if (strcmp(entry->key, KeyValues::deadStripKindKeyword) == 0) {
678 atomState._deadStrip = KeyValues::deadStripKind(entry->value);
679 haveAtom = true;
680 }
681 else if (strcmp(entry->key, KeyValues::sectionChoiceKeyword) == 0) {
682 atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
683 haveAtom = true;
684 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000685 else if (strcmp(entry->key, KeyValues::mergeKeyword) == 0) {
686 atomState._merge = KeyValues::merge(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000687 haveAtom = true;
688 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000689 else if (strcmp(entry->key, KeyValues::interposableKeyword) == 0) {
690 atomState._interpose = KeyValues::interposable(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000691 haveAtom = true;
692 }
693 else if (strcmp(entry->key, KeyValues::isThumbKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000694 atomState._isThumb = KeyValues::isThumb(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000695 haveAtom = true;
696 }
697 else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000698 atomState._isAlias = KeyValues::isAlias(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000699 haveAtom = true;
700 }
701 else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
702 atomState._sectionName = entry->value;
703 haveAtom = true;
704 }
705 else if (strcmp(entry->key, KeyValues::sizeKeyword) == 0) {
706 llvm::StringRef val = entry->value;
707 if ( val.getAsInteger(0, atomState._size) )
708 return make_error_code(illegal_value);
709 haveAtom = true;
710 }
711 else if (strcmp(entry->key, KeyValues::contentKeyword) == 0) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000712 atomState._content = entry->valueSequenceBytes;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000713 haveAtom = true;
714 }
715 else if (strcmp(entry->key, "align2") == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000716 atomState.setAlign2(entry->value);
717 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000718 }
719 else if (strcmp(entry->key, "fixups") == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000720 inFixups = true;
721 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000722 else {
723 return make_error_code(unknown_keyword);
724 }
725 }
726 else if (depthForFixups == entry->depth) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000727 if (entry->beginSequence) {
728 if (haveFixup) {
729 atomState.addFixup(file);
730 haveFixup = false;
731 }
732 }
733 if (strcmp(entry->key, "kind") == 0) {
734 atomState.setFixupKind(entry->value);
735 haveFixup = true;
736 } else if (strcmp(entry->key, "offset") == 0) {
737 atomState.setFixupOffset(entry->value);
738 haveFixup = true;
739 } else if (strcmp(entry->key, "target") == 0) {
740 atomState.setFixupTarget(entry->value);
741 haveFixup = true;
742 }
743 }
744 }
745 lastDepth = entry->depth;
746 }
747 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000748 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000749 }
750
751 result.push_back(file);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000752 return make_error_code(success);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000753}
Nick Kledzik070e1a72011-12-20 00:07:11 +0000754
755//
756// Fill in vector<File*> from path to input text file.
757//
758llvm::error_code parseObjectTextFileOrSTDIN(llvm::StringRef path
759 , std::vector<File*>& result) {
760 llvm::OwningPtr<llvm::MemoryBuffer> mb;
761 llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
762 if ( ec )
763 return ec;
764
765 return parseObjectText(mb.get(), result);
766}
767
768
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000769} // namespace yaml
770} // namespace lld