blob: c4c826d6f6e3695c5139cc8f7d42d4f8bed7f211 [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
10#include "lld/Core/YamlReader.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000011#include "YamlKeyValues.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000012#include "lld/Core/Atom.h"
Nick Kledzik6bc04c62012-02-22 21:56:59 +000013#include "lld/Core/AbsoluteAtom.h"
Michael J. Spencer7aba8952012-01-31 21:47:13 +000014#include "lld/Core/Error.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000015#include "lld/Core/File.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000016#include "lld/Core/Platform.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000017#include "lld/Core/Reference.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000018#include "lld/Core/SharedLibraryAtom.h"
19#include "lld/Core/UndefinedAtom.h"
Nick Kledzik1a6615d2012-03-08 00:18:30 +000020
Michael J. Spencere753cbc2012-03-09 05:27:43 +000021#include "llvm/ADT/APInt.h"
Michael J. Spencercfd029f2012-03-28 19:04:02 +000022#include "llvm/ADT/ArrayRef.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000023#include "llvm/ADT/OwningPtr.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/Support/DataTypes.h"
26#include "llvm/Support/ErrorHandling.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include "llvm/Support/system_error.h"
29
Michael J. Spencercfd029f2012-03-28 19:04:02 +000030#include <cstring>
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000031#include <vector>
32
Nick Kledzik7735a7d2012-01-04 23:58:17 +000033
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000034
35namespace lld {
36namespace yaml {
Nick Kledzik7735a7d2012-01-04 23:58:17 +000037
Nick Kledzik49d6cc82012-02-15 00:38:09 +000038namespace {
39
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000040class YAML {
41public:
42 struct Entry {
Nick Kledzikbfedfc12012-01-09 20:18:15 +000043 Entry(const char *k, const char *v, std::vector<uint8_t>* vs,
44 int d, bool bd, bool bs)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000045 : key(strdup(k))
Nick Kledzikbfedfc12012-01-09 20:18:15 +000046 , value(v ? strdup(v) : NULL)
47 , valueSequenceBytes(vs)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000048 , depth(d)
49 , beginSequence(bs)
50 , beginDocument(bd) {}
51
Nick Kledzikbfedfc12012-01-09 20:18:15 +000052 const char * key;
53 const char * value;
54 std::vector<uint8_t>* valueSequenceBytes;
55 int depth;
56 bool beginSequence;
57 bool beginDocument;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000058 };
59
60 static void parse(llvm::MemoryBuffer *mb, std::vector<const Entry *>&);
61
62private:
63 enum State {
64 start,
65 inHeaderComment,
66 inTripleDash,
67 inTriplePeriod,
68 inDocument,
69 inKey,
70 inSpaceBeforeValue,
71 inValue,
72 inValueSequence,
73 inValueSequenceEnd
74 };
75};
76
77
78void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
79 State state = start;
80 char key[64];
81 char value[64];
82 char *p = NULL;
83 unsigned int lineNumber = 1;
84 int depth = 0;
85 bool nextKeyIsStartOfDocument = false;
86 bool nextKeyIsStartOfSequence = false;
Nick Kledzikbfedfc12012-01-09 20:18:15 +000087 std::vector<uint8_t>* sequenceBytes = NULL;
88 unsigned contentByte = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000089 for (const char *s = mb->getBufferStart(); s < mb->getBufferEnd(); ++s) {
90 char c = *s;
91 if (c == '\n')
92 ++lineNumber;
93 switch (state) {
94 case start:
95 if (c == '#')
96 state = inHeaderComment;
97 else if (c == '-') {
98 p = &key[0];
99 *p++ = c;
100 state = inTripleDash;
101 }
102 break;
103 case inHeaderComment:
104 if (c == '\n') {
105 state = start;
106 }
107 break;
108 case inTripleDash:
109 if (c == '-') {
110 *p++ = c;
111 } else if (c == '\n') {
112 *p = '\0';
113 if (strcmp(key, "---") != 0)
114 return;
115 depth = 0;
116 state = inDocument;
117 nextKeyIsStartOfDocument = true;
118 } else {
119 return;
120 }
121 break;
122 case inTriplePeriod:
123 if (c == '.') {
124 *p++ = c;
125 } else if (c == '\n') {
126 *p = '\0';
127 if (strcmp(key, "...") != 0)
128 return;
129 depth = 0;
130 state = inHeaderComment;
131 } else {
132 return;
133 }
134 break;
135 case inDocument:
136 if (isalnum(c)) {
137 state = inKey;
138 p = &key[0];
139 *p++ = c;
140 } else if (c == '-') {
141 if (depth == 0) {
142 p = &key[0];
143 *p++ = c;
144 state = inTripleDash;
145 } else {
146 nextKeyIsStartOfSequence = true;
147 ++depth;
148 }
149 } else if (c == ' ') {
150 ++depth;
151 } else if (c == '.') {
152 p = &key[0];
153 *p++ = c;
154 state = inTriplePeriod;
155 } else if (c == '\n') {
156 // ignore empty lines
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000157 depth = 0;
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000158 } else if (c == '\t') {
159 llvm::report_fatal_error("TAB character found in yaml file");
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000160 } else {
161 return;
162 }
163 break;
164 case inKey:
165 if (isalnum(c) || (c == '-')) {
166 *p++ = c;
167 } else if (c == ':') {
168 *p = '\0';
169 state = inSpaceBeforeValue;
170 } else if (c == '\n') {
171 *p = '\0';
172 if (strcmp(key, "---") == 0)
173 state = inDocument;
174 else
175 return;
176 } else {
177 return;
178 }
179 break;
180 case inSpaceBeforeValue:
181 if (isalnum(c) || (c == '-') || (c == '_')) {
182 p = &value[0];
183 *p++ = c;
184 state = inValue;
185 } else if (c == '\n') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000186 entries.push_back(new Entry(key, "", NULL, depth,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000187 nextKeyIsStartOfDocument,
188 nextKeyIsStartOfSequence));
189 nextKeyIsStartOfSequence = false;
190 nextKeyIsStartOfDocument = false;
191 state = inDocument;
192 depth = 0;
193 } else if (c == '[') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000194 contentByte = 0;
195 sequenceBytes = new std::vector<uint8_t>();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000196 state = inValueSequence;
197 } else if (c == ' ') {
198 // eat space
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000199 } else if (c == '\t') {
200 llvm::report_fatal_error("TAB character found in yaml file");
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000201 } else {
202 return;
203 }
204 break;
205 case inValue:
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000206 if (c == '\n') {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000207 *p = '\0';
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000208 entries.push_back(new Entry(key, value, NULL, depth,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000209 nextKeyIsStartOfDocument,
210 nextKeyIsStartOfSequence));
211 nextKeyIsStartOfSequence = false;
212 nextKeyIsStartOfDocument = false;
213 state = inDocument;
214 depth = 0;
215 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000216 else {
217 *p++ = c;
218 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000219 break;
220 case inValueSequence:
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000221 if (c == ']') {
222 sequenceBytes->push_back(contentByte);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000223 state = inValueSequenceEnd;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000224 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000225 else if ( (c == ' ') || (c == '\n') ) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000226 // eat white space
227 }
228 else if (c == ',') {
229 sequenceBytes->push_back(contentByte);
230 }
231 else if ( isdigit(c) ) {
232 contentByte = (contentByte << 4) | (c-'0');
233 }
234 else if ( ('a' <= tolower(c)) && (tolower(c) <= 'f') ) {
235 contentByte = (contentByte << 4) | (tolower(c)-'a'+10);
236 }
237 else {
238 llvm::report_fatal_error("non-hex digit found in content [ ]");
239 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000240 break;
241 case inValueSequenceEnd:
242 if (c == '\n') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000243 entries.push_back(new Entry(key, NULL, sequenceBytes, depth,
244 nextKeyIsStartOfDocument,
245 nextKeyIsStartOfSequence));
246 nextKeyIsStartOfSequence = false;
247 nextKeyIsStartOfDocument = false;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000248 state = inDocument;
249 depth = 0;
250 }
251 break;
252 }
253 }
254}
255
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000256
257
258class YAMLReference : public Reference {
259public:
260 YAMLReference() : _target(NULL), _targetName(NULL),
261 _offsetInAtom(0), _addend(0), _kind(0) { }
262
263 virtual uint64_t offsetInAtom() const {
264 return _offsetInAtom;
265 }
266
267 virtual Kind kind() const {
268 return _kind;
269 }
270
Nick Kledzikf4e2c732012-03-15 23:36:24 +0000271 virtual void setKind(Kind k) {
272 _kind = k;
273 }
274
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000275 virtual const Atom* target() const {
276 return _target;
277 }
278
279 virtual Addend addend() const {
280 return _addend;
281 }
282
283 virtual void setTarget(const Atom* newAtom) {
284 _target = newAtom;
285 }
286
287 const Atom* _target;
288 const char* _targetName;
289 uint64_t _offsetInAtom;
290 Addend _addend;
291 Kind _kind;
292};
293
294
295
296class YAMLDefinedAtom;
297
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000298class YAMLFile : public File {
299public:
300 YAMLFile()
301 : File("path")
302 , _lastRefIndex(0) {}
303
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000304 virtual const atom_collection<DefinedAtom>& defined() const {
305 return _definedAtoms;
306 }
307 virtual const atom_collection<UndefinedAtom>& undefined() const {
308 return _undefinedAtoms;
309 }
310 virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
311 return _sharedLibraryAtoms;
312 }
313 virtual const atom_collection<AbsoluteAtom>& absolute() const {
314 return _absoluteAtoms;
315 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000316
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000317 virtual void addAtom(const Atom&) {
318 assert(0 && "cannot add atoms to YAML files");
319 }
320
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000321 void bindTargetReferences();
322 void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
323 void addUndefinedAtom(UndefinedAtom* atom);
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000324 void addSharedLibraryAtom(SharedLibraryAtom* atom);
325 void addAbsoluteAtom(AbsoluteAtom* atom);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000326 Atom* findAtom(const char* name);
327
328 struct NameAtomPair {
329 NameAtomPair(const char* n, Atom* a) : name(n), atom(a) {}
330 const char* name;
331 Atom* atom;
332 };
333
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000334 atom_collection_vector<DefinedAtom> _definedAtoms;
335 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
336 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
337 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
338 std::vector<YAMLReference> _references;
339 std::vector<NameAtomPair> _nameToAtomMapping;
340 unsigned int _lastRefIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000341};
342
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000343
344
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000345class YAMLDefinedAtom : public DefinedAtom {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000346public:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000347 YAMLDefinedAtom( uint32_t ord
348 , YAMLFile& file
349 , DefinedAtom::Scope scope
350 , DefinedAtom::ContentType type
351 , DefinedAtom::SectionChoice sectionChoice
352 , DefinedAtom::Interposable interpose
353 , DefinedAtom::Merge merge
354 , DefinedAtom::DeadStripKind deadStrip
355 , DefinedAtom::ContentPermissions perms
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000356 , bool isThumb
357 , bool isAlias
358 , DefinedAtom::Alignment alignment
359 , const char* name
360 , const char* sectionName
361 , uint64_t size
362 , std::vector<uint8_t>* content)
363 : _file(file)
364 , _name(name)
365 , _sectionName(sectionName)
366 , _size(size)
367 , _ord(ord)
368 , _content(content)
369 , _alignment(alignment)
370 , _scope(scope)
371 , _type(type)
372 , _sectionChoice(sectionChoice)
373 , _interpose(interpose)
374 , _merge(merge)
375 , _deadStrip(deadStrip)
376 , _permissions(perms)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000377 , _isThumb(isThumb)
378 , _isAlias(isAlias)
379 , _refStartIndex(file._lastRefIndex)
380 , _refEndIndex(file._references.size()) {
381 file._lastRefIndex = _refEndIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000382 }
383
Nick Kledzikf46669c2011-12-21 23:29:36 +0000384 virtual const class File& file() const {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000385 return _file;
386 }
387
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000388 virtual llvm::StringRef name() const {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000389 if ( _name == NULL )
390 return llvm::StringRef();
391 else
392 return _name;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000393 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000394
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000395 virtual uint64_t size() const {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000396 return (_content ? _content->size() : _size);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000397 }
398
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000399 virtual DefinedAtom::Scope scope() const {
400 return _scope;
401 }
402
403 virtual DefinedAtom::Interposable interposable() const {
404 return _interpose;
405 }
406
407 virtual DefinedAtom::Merge merge() const {
408 return _merge;
409 }
410
411 virtual DefinedAtom::ContentType contentType() const {
412 return _type;
413 }
414
415 virtual DefinedAtom::Alignment alignment() const {
416 return _alignment;
417 }
418
419 virtual DefinedAtom::SectionChoice sectionChoice() const {
420 return _sectionChoice;
421 }
422
423 virtual llvm::StringRef customSectionName() const {
424 return _sectionName;
425 }
426
427 virtual DefinedAtom::DeadStripKind deadStrip() const {
428 return _deadStrip;
429 }
430
431 virtual DefinedAtom::ContentPermissions permissions() const {
432 return _permissions;
433 }
434
435 virtual bool isThumb() const {
436 return _isThumb;
437 }
438
439 virtual bool isAlias() const {
440 return _isAlias;
441 }
442
443 llvm::ArrayRef<uint8_t> rawContent() const {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000444 if ( _content != NULL )
445 return llvm::ArrayRef<uint8_t>(*_content);
446 else
447 return llvm::ArrayRef<uint8_t>();
448 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000449
450 virtual uint64_t ordinal() const {
451 return _ord;
452 }
453
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000454 DefinedAtom::reference_iterator referencesBegin() const {
455 uintptr_t index = _refStartIndex;
456 const void* it = reinterpret_cast<const void*>(index);
457 return reference_iterator(*this, it);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000458 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000459
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000460 DefinedAtom::reference_iterator referencesEnd() const {
461 uintptr_t index = _refEndIndex;
462 const void* it = reinterpret_cast<const void*>(index);
463 return reference_iterator(*this, it);
464 }
465
466 const Reference* derefIterator(const void* it) const {
467 uintptr_t index = reinterpret_cast<uintptr_t>(it);
468 assert(index >= _refStartIndex);
469 assert(index < _refEndIndex);
470 assert(index < _file._references.size());
471 return &_file._references[index];
472 }
473
474 void incrementIterator(const void*& it) const {
475 uintptr_t index = reinterpret_cast<uintptr_t>(it);
476 ++index;
477 it = reinterpret_cast<const void*>(index);
478 }
479
480
481
482 void bindTargetReferences() const {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000483 for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
484 const char* targetName = _file._references[i]._targetName;
485 Atom* targetAtom = _file.findAtom(targetName);
486 _file._references[i]._target = targetAtom;
487 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000488 }
489
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000490private:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000491 YAMLFile& _file;
492 const char * _name;
493 const char * _sectionName;
494 unsigned long _size;
495 uint32_t _ord;
496 std::vector<uint8_t>* _content;
497 DefinedAtom::Alignment _alignment;
498 DefinedAtom::Scope _scope;
499 DefinedAtom::ContentType _type;
500 DefinedAtom::SectionChoice _sectionChoice;
501 DefinedAtom::Interposable _interpose;
502 DefinedAtom::Merge _merge;
503 DefinedAtom::DeadStripKind _deadStrip;
504 DefinedAtom::ContentPermissions _permissions;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000505 bool _isThumb;
506 bool _isAlias;
507 unsigned int _refStartIndex;
508 unsigned int _refEndIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000509};
510
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000511
Nick Kledzik23384e82012-02-07 02:59:54 +0000512class YAMLUndefinedAtom : public UndefinedAtom {
513public:
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000514 YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm,
515 UndefinedAtom::CanBeNull cbn)
516 : _file(f), _name(nm), _ordinal(ord), _canBeNull(cbn) { }
Nick Kledzik23384e82012-02-07 02:59:54 +0000517
518 virtual const class File& file() const {
519 return _file;
520 }
521
522 virtual llvm::StringRef name() const {
523 return _name;
524 }
525
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000526 virtual CanBeNull canBeNull() const {
527 return _canBeNull;
Nick Kledzik23384e82012-02-07 02:59:54 +0000528 }
529
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000530
Nick Kledzik23384e82012-02-07 02:59:54 +0000531private:
532 YAMLFile& _file;
533 const char * _name;
534 uint32_t _ordinal;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000535 UndefinedAtom::CanBeNull _canBeNull;
Nick Kledzik23384e82012-02-07 02:59:54 +0000536};
537
538
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000539
540class YAMLSharedLibraryAtom : public SharedLibraryAtom {
541public:
542 YAMLSharedLibraryAtom(YAMLFile& f, int32_t ord, const char* nm,
543 const char* ldnm, bool cbn)
544 : _file(f), _name(nm), _ordinal(ord),
545 _loadName(ldnm), _canBeNull(cbn) { }
546
547 virtual const class File& file() const {
548 return _file;
549 }
550
551 virtual llvm::StringRef name() const {
552 return _name;
553 }
554
555 virtual llvm::StringRef loadName() const {
556 return _loadName;
557 }
558
559 virtual bool canBeNullAtRuntime() const {
560 return _canBeNull;
561 }
562
563
564private:
565 YAMLFile& _file;
566 const char * _name;
567 uint32_t _ordinal;
568 const char * _loadName;
569 bool _canBeNull;
570};
571
572
573
574class YAMLAbsoluteAtom : public AbsoluteAtom {
575public:
576 YAMLAbsoluteAtom(YAMLFile& f, int32_t ord, const char* nm, uint64_t v)
577 : _file(f), _name(nm), _ordinal(ord), _value(v) { }
578
579 virtual const class File& file() const {
580 return _file;
581 }
582
583 virtual llvm::StringRef name() const {
584 return _name;
585 }
586
587 virtual uint64_t value() const {
588 return _value;
589 }
590
591private:
592 YAMLFile& _file;
593 const char * _name;
594 uint32_t _ordinal;
595 uint64_t _value;
596};
597
598
599
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000600void YAMLFile::bindTargetReferences() {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000601 for (defined_iterator it = definedAtomsBegin(); it != definedAtomsEnd(); ++it) {
602 const YAMLDefinedAtom* atom = reinterpret_cast<const YAMLDefinedAtom*>(*it);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000603 atom->bindTargetReferences();
604 }
605}
606
607Atom* YAMLFile::findAtom(const char* name) {
608 for (std::vector<NameAtomPair>::const_iterator it = _nameToAtomMapping.begin();
609 it != _nameToAtomMapping.end(); ++it) {
610 if ( strcmp(name, it->name) == 0 )
611 return it->atom;
612 }
613 llvm::report_fatal_error("reference to atom that does not exist");
614}
615
616void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000617 _definedAtoms._atoms.push_back(atom);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000618 assert(refName != NULL);
619 _nameToAtomMapping.push_back(NameAtomPair(refName, atom));
620}
621
622void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000623 _undefinedAtoms._atoms.push_back(atom);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000624 _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
625}
626
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000627void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom* atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000628 _sharedLibraryAtoms._atoms.push_back(atom);
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000629 _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
630}
631
632void YAMLFile::addAbsoluteAtom(AbsoluteAtom* atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000633 _absoluteAtoms._atoms.push_back(atom);
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000634 _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
635}
636
Nick Kledzik23384e82012-02-07 02:59:54 +0000637
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000638class YAMLAtomState {
639public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000640 YAMLAtomState(Platform& platform);
641
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000642 void setName(const char *n);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000643 void setRefName(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000644 void setAlign2(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000645
646 void setFixupKind(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000647 void setFixupTarget(const char *n);
648 void addFixup(YAMLFile *f);
649
Nick Kledzikf46669c2011-12-21 23:29:36 +0000650 void makeAtom(YAMLFile&);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000651
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000652 Platform& _platform;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000653 const char * _name;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000654 const char * _refName;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000655 const char * _sectionName;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000656 const char* _loadName;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000657 unsigned long long _size;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000658 uint64_t _value;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000659 uint32_t _ordinal;
660 std::vector<uint8_t>* _content;
661 DefinedAtom::Alignment _alignment;
662 Atom::Definition _definition;
663 DefinedAtom::Scope _scope;
664 DefinedAtom::ContentType _type;
665 DefinedAtom::SectionChoice _sectionChoice;
666 DefinedAtom::Interposable _interpose;
667 DefinedAtom::Merge _merge;
668 DefinedAtom::DeadStripKind _deadStrip;
669 DefinedAtom::ContentPermissions _permissions;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000670 bool _isThumb;
671 bool _isAlias;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000672 UndefinedAtom::CanBeNull _canBeNull;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000673 YAMLReference _ref;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000674};
675
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000676
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000677YAMLAtomState::YAMLAtomState(Platform& platform)
678 : _platform(platform)
679 , _name(NULL)
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000680 , _refName(NULL)
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000681 , _sectionName(NULL)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000682 , _loadName(NULL)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000683 , _size(0)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000684 , _value(0)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000685 , _ordinal(0)
686 , _content(NULL)
687 , _alignment(0, 0)
688 , _definition(KeyValues::definitionDefault)
689 , _scope(KeyValues::scopeDefault)
690 , _type(KeyValues::contentTypeDefault)
691 , _sectionChoice(KeyValues::sectionChoiceDefault)
692 , _interpose(KeyValues::interposableDefault)
693 , _merge(KeyValues::mergeDefault)
694 , _deadStrip(KeyValues::deadStripKindDefault)
695 , _permissions(KeyValues::permissionsDefault)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000696 , _isThumb(KeyValues::isThumbDefault)
697 , _isAlias(KeyValues::isAliasDefault)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000698 , _canBeNull(KeyValues::canBeNullDefault)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000699 {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000700 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000701
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000702
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000703void YAMLAtomState::makeAtom(YAMLFile& f) {
704 if ( _definition == Atom::definitionRegular ) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000705 YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000706 _sectionChoice, _interpose, _merge, _deadStrip,
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000707 _permissions, _isThumb, _isAlias,
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000708 _alignment, _name, _sectionName, _size, _content);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000709 f.addDefinedAtom(a, _refName ? _refName : _name);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000710 ++_ordinal;
711 }
Nick Kledzik23384e82012-02-07 02:59:54 +0000712 else if ( _definition == Atom::definitionUndefined ) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000713 UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _canBeNull);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000714 f.addUndefinedAtom(a);
Nick Kledzik23384e82012-02-07 02:59:54 +0000715 ++_ordinal;
716 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000717 else if ( _definition == Atom::definitionSharedLibrary ) {
718 bool nullable = (_canBeNull == UndefinedAtom::canBeNullAtRuntime);
719 SharedLibraryAtom *a = new YAMLSharedLibraryAtom(f, _ordinal, _name,
720 _loadName, nullable);
721 f.addSharedLibraryAtom(a);
722 ++_ordinal;
723 }
724 else if ( _definition == Atom::definitionAbsolute ) {
725 AbsoluteAtom *a = new YAMLAbsoluteAtom(f, _ordinal, _name, _value);
726 f.addAbsoluteAtom(a);
727 ++_ordinal;
728 }
729
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000730 // reset state for next atom
731 _name = NULL;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000732 _refName = NULL;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000733 _sectionName = NULL;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000734 _loadName = NULL;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000735 _size = 0;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000736 _value = 0;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000737 _ordinal = 0;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000738 _content = NULL;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000739 _alignment.powerOf2= 0;
740 _alignment.modulus = 0;
741 _definition = KeyValues::definitionDefault;
742 _scope = KeyValues::scopeDefault;
743 _type = KeyValues::contentTypeDefault;
744 _sectionChoice = KeyValues::sectionChoiceDefault;
745 _interpose = KeyValues::interposableDefault;
746 _merge = KeyValues::mergeDefault;
747 _deadStrip = KeyValues::deadStripKindDefault;
748 _permissions = KeyValues::permissionsDefault;
749 _isThumb = KeyValues::isThumbDefault;
750 _isAlias = KeyValues::isAliasDefault;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000751 _canBeNull = KeyValues::canBeNullDefault;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000752 _ref._target = NULL;
753 _ref._targetName = NULL;
754 _ref._addend = 0;
755 _ref._offsetInAtom = 0;
756 _ref._kind = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000757}
758
759void YAMLAtomState::setName(const char *n) {
760 _name = n;
761}
762
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000763void YAMLAtomState::setRefName(const char *n) {
764 _refName = n;
765}
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000766
767void YAMLAtomState::setAlign2(const char *s) {
Michael J. Spencer166b0902012-03-12 18:13:36 +0000768 if (llvm::StringRef(s).getAsInteger(10, _alignment.powerOf2))
769 _alignment.powerOf2 = 1;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000770}
771
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000772void YAMLAtomState::setFixupKind(const char *s) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000773 _ref._kind = _platform.kindFromString(llvm::StringRef(s));
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000774}
775
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000776void YAMLAtomState::setFixupTarget(const char *s) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000777 _ref._targetName = s;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000778}
779
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000780
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000781void YAMLAtomState::addFixup(YAMLFile *f) {
782 f->_references.push_back(_ref);
783 // clear for next ref
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000784 _ref._target = NULL;
785 _ref._targetName = NULL;
786 _ref._addend = 0;
787 _ref._offsetInAtom = 0;
788 _ref._kind = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000789}
790
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000791
792} // anonymous namespace
793
794
795
796
797
798/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
799/// into lld::File object(s) and append each to the specified vector<File*>.
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000800llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000801 , Platform& platform
802 , std::vector<const File *> &result) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000803 std::vector<const YAML::Entry *> entries;
804 YAML::parse(mb, entries);
805
806 YAMLFile *file = NULL;
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000807 YAMLAtomState atomState(platform);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000808 bool inAtoms = false;
809 bool inFixups = false;
810 int depthForAtoms = -1;
811 int depthForFixups = -1;
812 int lastDepth = -1;
813 bool haveAtom = false;
814 bool haveFixup = false;
815
816 for (std::vector<const YAML::Entry *>::iterator it = entries.begin();
817 it != entries.end(); ++it) {
818 const YAML::Entry *entry = *it;
819
820 if (entry->beginDocument) {
821 if (file != NULL) {
822 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000823 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000824 haveAtom = false;
825 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000826 file->bindTargetReferences();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000827 result.push_back(file);
828 }
829 file = new YAMLFile();
830 inAtoms = false;
831 depthForAtoms = -1;
832 }
833 if (lastDepth > entry->depth) {
834 // end of fixup sequence
835 if (haveFixup) {
836 atomState.addFixup(file);
837 haveFixup = false;
838 }
839 }
840
841 if (inAtoms && (depthForAtoms == -1)) {
842 depthForAtoms = entry->depth;
843 }
844 if (inFixups && (depthForFixups == -1)) {
845 depthForFixups = entry->depth;
846 }
847 if (strcmp(entry->key, "atoms") == 0) {
848 inAtoms = true;
849 }
850 if (inAtoms) {
851 if (depthForAtoms == entry->depth) {
852 if (entry->beginSequence) {
853 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000854 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000855 haveAtom = false;
856 }
857 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000858 if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000859 atomState.setName(entry->value);
860 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000861 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000862 else if (strcmp(entry->key, KeyValues::refNameKeyword) == 0) {
863 atomState.setRefName(entry->value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000864 haveAtom = true;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000865 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000866 else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000867 atomState._definition = KeyValues::definition(entry->value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000868 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000869 }
870 else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
871 atomState._scope = KeyValues::scope(entry->value);
872 haveAtom = true;
873 }
874 else if (strcmp(entry->key, KeyValues::contentTypeKeyword) == 0) {
875 atomState._type = KeyValues::contentType(entry->value);
876 haveAtom = true;
877 }
878 else if (strcmp(entry->key, KeyValues::deadStripKindKeyword) == 0) {
879 atomState._deadStrip = KeyValues::deadStripKind(entry->value);
880 haveAtom = true;
881 }
882 else if (strcmp(entry->key, KeyValues::sectionChoiceKeyword) == 0) {
883 atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
884 haveAtom = true;
885 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000886 else if (strcmp(entry->key, KeyValues::mergeKeyword) == 0) {
887 atomState._merge = KeyValues::merge(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000888 haveAtom = true;
889 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000890 else if (strcmp(entry->key, KeyValues::interposableKeyword) == 0) {
891 atomState._interpose = KeyValues::interposable(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000892 haveAtom = true;
893 }
894 else if (strcmp(entry->key, KeyValues::isThumbKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000895 atomState._isThumb = KeyValues::isThumb(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000896 haveAtom = true;
897 }
898 else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000899 atomState._isAlias = KeyValues::isAlias(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000900 haveAtom = true;
901 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000902 else if (strcmp(entry->key, KeyValues::canBeNullKeyword) == 0) {
903 atomState._canBeNull = KeyValues::canBeNull(entry->value);
904 if ( atomState._definition == Atom::definitionSharedLibrary ) {
905 if ( atomState._canBeNull == UndefinedAtom::canBeNullAtBuildtime )
906 return make_error_code(yaml_reader_error::illegal_value);
907 }
Nick Kledzik23384e82012-02-07 02:59:54 +0000908 haveAtom = true;
909 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000910 else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
911 atomState._sectionName = entry->value;
912 haveAtom = true;
913 }
914 else if (strcmp(entry->key, KeyValues::sizeKeyword) == 0) {
915 llvm::StringRef val = entry->value;
Michael J. Spencer166b0902012-03-12 18:13:36 +0000916 if (val.getAsInteger(0, atomState._size))
Michael J. Spencer7aba8952012-01-31 21:47:13 +0000917 return make_error_code(yaml_reader_error::illegal_value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000918 haveAtom = true;
919 }
920 else if (strcmp(entry->key, KeyValues::contentKeyword) == 0) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000921 atomState._content = entry->valueSequenceBytes;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000922 haveAtom = true;
923 }
924 else if (strcmp(entry->key, "align2") == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000925 atomState.setAlign2(entry->value);
926 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000927 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000928 else if (strcmp(entry->key, KeyValues::fixupsKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000929 inFixups = true;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000930 }
931 else if (strcmp(entry->key, KeyValues::loadNameKeyword) == 0) {
932 atomState._loadName = entry->value;
933 haveAtom = true;
934 }
935 else if (strcmp(entry->key, KeyValues::valueKeyword) == 0) {
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000936 llvm::APInt Val;
937 llvm::StringRef(entry->value).getAsInteger(0, Val);
938 atomState._value = Val.getZExtValue();
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000939 haveAtom = true;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000940 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000941 else {
Michael J. Spencer7aba8952012-01-31 21:47:13 +0000942 return make_error_code(yaml_reader_error::unknown_keyword);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000943 }
944 }
945 else if (depthForFixups == entry->depth) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000946 if (entry->beginSequence) {
947 if (haveFixup) {
948 atomState.addFixup(file);
949 haveFixup = false;
950 }
951 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000952 if (strcmp(entry->key, KeyValues::fixupsKindKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000953 atomState.setFixupKind(entry->value);
954 haveFixup = true;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000955 }
956 else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0) {
Michael J. Spencer166b0902012-03-12 18:13:36 +0000957 if (llvm::StringRef(entry->value).getAsInteger(0,
958 atomState._ref._offsetInAtom))
959 return make_error_code(yaml_reader_error::illegal_value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000960 haveFixup = true;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000961 }
962 else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000963 atomState.setFixupTarget(entry->value);
964 haveFixup = true;
965 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000966 else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0) {
Michael J. Spencere753cbc2012-03-09 05:27:43 +0000967 llvm::StringRef Addend(entry->value);
Michael J. Spencer166b0902012-03-12 18:13:36 +0000968 if (Addend.getAsInteger(0, atomState._ref._addend))
969 return make_error_code(yaml_reader_error::illegal_value);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000970 haveFixup = true;
971 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000972 }
973 }
974 lastDepth = entry->depth;
975 }
976 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000977 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000978 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000979 if ( file != NULL ) {
980 file->bindTargetReferences();
981 result.push_back(file);
982 }
Michael J. Spencer7aba8952012-01-31 21:47:13 +0000983 return make_error_code(yaml_reader_error::success);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000984}
Nick Kledzik070e1a72011-12-20 00:07:11 +0000985
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000986
Nick Kledzik070e1a72011-12-20 00:07:11 +0000987//
988// Fill in vector<File*> from path to input text file.
989//
990llvm::error_code parseObjectTextFileOrSTDIN(llvm::StringRef path
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000991 , Platform& platform
992 , std::vector<const File*>& result) {
Nick Kledzik070e1a72011-12-20 00:07:11 +0000993 llvm::OwningPtr<llvm::MemoryBuffer> mb;
994 llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
995 if ( ec )
996 return ec;
997
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000998 return parseObjectText(mb.get(), platform, result);
Nick Kledzik070e1a72011-12-20 00:07:11 +0000999}
1000
1001
Michael J. Spencer773a8fb2011-12-18 08:27:59 +00001002} // namespace yaml
1003} // namespace lld