blob: 31f999e3d241220318f229167f0399b5ad080286 [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 Kledzik49d6cc82012-02-15 00:38:09 +000010#include <string.h>
11
Nick Kledzik7735a7d2012-01-04 23:58:17 +000012#include "YamlKeyValues.h"
13
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000014#include "lld/Core/YamlReader.h"
15#include "lld/Core/Atom.h"
Nick Kledzik6bc04c62012-02-22 21:56:59 +000016#include "lld/Core/UndefinedAtom.h"
17#include "lld/Core/SharedLibraryAtom.h"
18#include "lld/Core/AbsoluteAtom.h"
Michael J. Spencer7aba8952012-01-31 21:47:13 +000019#include "lld/Core/Error.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000020#include "lld/Core/File.h"
21#include "lld/Core/Reference.h"
22
Nick Kledzik1a6615d2012-03-08 00:18:30 +000023#include "lld/Platform/Platform.h"
24
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000025#include "llvm/ADT/OwningPtr.h"
26#include "llvm/ADT/StringRef.h"
Nick Kledzikbfedfc12012-01-09 20:18:15 +000027#include "llvm/ADT/ArrayRef.h"
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000028#include "llvm/Support/DataTypes.h"
29#include "llvm/Support/ErrorHandling.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/system_error.h"
32
33#include <vector>
34
Nick Kledzik7735a7d2012-01-04 23:58:17 +000035
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000036
37namespace lld {
38namespace yaml {
Nick Kledzik7735a7d2012-01-04 23:58:17 +000039
Nick Kledzik49d6cc82012-02-15 00:38:09 +000040namespace {
41
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000042class YAML {
43public:
44 struct Entry {
Nick Kledzikbfedfc12012-01-09 20:18:15 +000045 Entry(const char *k, const char *v, std::vector<uint8_t>* vs,
46 int d, bool bd, bool bs)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000047 : key(strdup(k))
Nick Kledzikbfedfc12012-01-09 20:18:15 +000048 , value(v ? strdup(v) : NULL)
49 , valueSequenceBytes(vs)
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000050 , depth(d)
51 , beginSequence(bs)
52 , beginDocument(bd) {}
53
Nick Kledzikbfedfc12012-01-09 20:18:15 +000054 const char * key;
55 const char * value;
56 std::vector<uint8_t>* valueSequenceBytes;
57 int depth;
58 bool beginSequence;
59 bool beginDocument;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000060 };
61
62 static void parse(llvm::MemoryBuffer *mb, std::vector<const Entry *>&);
63
64private:
65 enum State {
66 start,
67 inHeaderComment,
68 inTripleDash,
69 inTriplePeriod,
70 inDocument,
71 inKey,
72 inSpaceBeforeValue,
73 inValue,
74 inValueSequence,
75 inValueSequenceEnd
76 };
77};
78
79
80void YAML::parse(llvm::MemoryBuffer *mb, std::vector<const Entry *> &entries) {
81 State state = start;
82 char key[64];
83 char value[64];
84 char *p = NULL;
85 unsigned int lineNumber = 1;
86 int depth = 0;
87 bool nextKeyIsStartOfDocument = false;
88 bool nextKeyIsStartOfSequence = false;
Nick Kledzikbfedfc12012-01-09 20:18:15 +000089 std::vector<uint8_t>* sequenceBytes = NULL;
90 unsigned contentByte = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +000091 for (const char *s = mb->getBufferStart(); s < mb->getBufferEnd(); ++s) {
92 char c = *s;
93 if (c == '\n')
94 ++lineNumber;
95 switch (state) {
96 case start:
97 if (c == '#')
98 state = inHeaderComment;
99 else if (c == '-') {
100 p = &key[0];
101 *p++ = c;
102 state = inTripleDash;
103 }
104 break;
105 case inHeaderComment:
106 if (c == '\n') {
107 state = start;
108 }
109 break;
110 case inTripleDash:
111 if (c == '-') {
112 *p++ = c;
113 } else if (c == '\n') {
114 *p = '\0';
115 if (strcmp(key, "---") != 0)
116 return;
117 depth = 0;
118 state = inDocument;
119 nextKeyIsStartOfDocument = true;
120 } else {
121 return;
122 }
123 break;
124 case inTriplePeriod:
125 if (c == '.') {
126 *p++ = c;
127 } else if (c == '\n') {
128 *p = '\0';
129 if (strcmp(key, "...") != 0)
130 return;
131 depth = 0;
132 state = inHeaderComment;
133 } else {
134 return;
135 }
136 break;
137 case inDocument:
138 if (isalnum(c)) {
139 state = inKey;
140 p = &key[0];
141 *p++ = c;
142 } else if (c == '-') {
143 if (depth == 0) {
144 p = &key[0];
145 *p++ = c;
146 state = inTripleDash;
147 } else {
148 nextKeyIsStartOfSequence = true;
149 ++depth;
150 }
151 } else if (c == ' ') {
152 ++depth;
153 } else if (c == '.') {
154 p = &key[0];
155 *p++ = c;
156 state = inTriplePeriod;
157 } else if (c == '\n') {
158 // ignore empty lines
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000159 depth = 0;
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000160 } else if (c == '\t') {
161 llvm::report_fatal_error("TAB character found in yaml file");
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000162 } else {
163 return;
164 }
165 break;
166 case inKey:
167 if (isalnum(c) || (c == '-')) {
168 *p++ = c;
169 } else if (c == ':') {
170 *p = '\0';
171 state = inSpaceBeforeValue;
172 } else if (c == '\n') {
173 *p = '\0';
174 if (strcmp(key, "---") == 0)
175 state = inDocument;
176 else
177 return;
178 } else {
179 return;
180 }
181 break;
182 case inSpaceBeforeValue:
183 if (isalnum(c) || (c == '-') || (c == '_')) {
184 p = &value[0];
185 *p++ = c;
186 state = inValue;
187 } else if (c == '\n') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000188 entries.push_back(new Entry(key, "", NULL, depth,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000189 nextKeyIsStartOfDocument,
190 nextKeyIsStartOfSequence));
191 nextKeyIsStartOfSequence = false;
192 nextKeyIsStartOfDocument = false;
193 state = inDocument;
194 depth = 0;
195 } else if (c == '[') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000196 contentByte = 0;
197 sequenceBytes = new std::vector<uint8_t>();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000198 state = inValueSequence;
199 } else if (c == ' ') {
200 // eat space
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000201 } else if (c == '\t') {
202 llvm::report_fatal_error("TAB character found in yaml file");
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000203 } else {
204 return;
205 }
206 break;
207 case inValue:
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000208 if (c == '\n') {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000209 *p = '\0';
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000210 entries.push_back(new Entry(key, value, NULL, depth,
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000211 nextKeyIsStartOfDocument,
212 nextKeyIsStartOfSequence));
213 nextKeyIsStartOfSequence = false;
214 nextKeyIsStartOfDocument = false;
215 state = inDocument;
216 depth = 0;
217 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000218 else {
219 *p++ = c;
220 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000221 break;
222 case inValueSequence:
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000223 if (c == ']') {
224 sequenceBytes->push_back(contentByte);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000225 state = inValueSequenceEnd;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000226 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000227 else if ( (c == ' ') || (c == '\n') ) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000228 // eat white space
229 }
230 else if (c == ',') {
231 sequenceBytes->push_back(contentByte);
232 }
233 else if ( isdigit(c) ) {
234 contentByte = (contentByte << 4) | (c-'0');
235 }
236 else if ( ('a' <= tolower(c)) && (tolower(c) <= 'f') ) {
237 contentByte = (contentByte << 4) | (tolower(c)-'a'+10);
238 }
239 else {
240 llvm::report_fatal_error("non-hex digit found in content [ ]");
241 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000242 break;
243 case inValueSequenceEnd:
244 if (c == '\n') {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000245 entries.push_back(new Entry(key, NULL, sequenceBytes, depth,
246 nextKeyIsStartOfDocument,
247 nextKeyIsStartOfSequence));
248 nextKeyIsStartOfSequence = false;
249 nextKeyIsStartOfDocument = false;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000250 state = inDocument;
251 depth = 0;
252 }
253 break;
254 }
255 }
256}
257
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000258
259
260class YAMLReference : public Reference {
261public:
262 YAMLReference() : _target(NULL), _targetName(NULL),
263 _offsetInAtom(0), _addend(0), _kind(0) { }
264
265 virtual uint64_t offsetInAtom() const {
266 return _offsetInAtom;
267 }
268
269 virtual Kind kind() const {
270 return _kind;
271 }
272
273 virtual const Atom* target() const {
274 return _target;
275 }
276
277 virtual Addend addend() const {
278 return _addend;
279 }
280
281 virtual void setTarget(const Atom* newAtom) {
282 _target = newAtom;
283 }
284
285 const Atom* _target;
286 const char* _targetName;
287 uint64_t _offsetInAtom;
288 Addend _addend;
289 Kind _kind;
290};
291
292
293
294class YAMLDefinedAtom;
295
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000296class YAMLFile : public File {
297public:
298 YAMLFile()
299 : File("path")
300 , _lastRefIndex(0) {}
301
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000302 virtual const atom_collection<DefinedAtom>& defined() const {
303 return _definedAtoms;
304 }
305 virtual const atom_collection<UndefinedAtom>& undefined() const {
306 return _undefinedAtoms;
307 }
308 virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
309 return _sharedLibraryAtoms;
310 }
311 virtual const atom_collection<AbsoluteAtom>& absolute() const {
312 return _absoluteAtoms;
313 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000314
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000315 virtual void addAtom(const Atom&) {
316 assert(0 && "cannot add atoms to YAML files");
317 }
318
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000319 void bindTargetReferences();
320 void addDefinedAtom(YAMLDefinedAtom* atom, const char* refName);
321 void addUndefinedAtom(UndefinedAtom* atom);
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000322 void addSharedLibraryAtom(SharedLibraryAtom* atom);
323 void addAbsoluteAtom(AbsoluteAtom* atom);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000324 Atom* findAtom(const char* name);
325
326 struct NameAtomPair {
327 NameAtomPair(const char* n, Atom* a) : name(n), atom(a) {}
328 const char* name;
329 Atom* atom;
330 };
331
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000332 atom_collection_vector<DefinedAtom> _definedAtoms;
333 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
334 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
335 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
336 std::vector<YAMLReference> _references;
337 std::vector<NameAtomPair> _nameToAtomMapping;
338 unsigned int _lastRefIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000339};
340
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000341
342
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000343class YAMLDefinedAtom : public DefinedAtom {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000344public:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000345 YAMLDefinedAtom( uint32_t ord
346 , YAMLFile& file
347 , DefinedAtom::Scope scope
348 , DefinedAtom::ContentType type
349 , DefinedAtom::SectionChoice sectionChoice
350 , DefinedAtom::Interposable interpose
351 , DefinedAtom::Merge merge
352 , DefinedAtom::DeadStripKind deadStrip
353 , DefinedAtom::ContentPermissions perms
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000354 , bool isThumb
355 , bool isAlias
356 , DefinedAtom::Alignment alignment
357 , const char* name
358 , const char* sectionName
359 , uint64_t size
360 , std::vector<uint8_t>* content)
361 : _file(file)
362 , _name(name)
363 , _sectionName(sectionName)
364 , _size(size)
365 , _ord(ord)
366 , _content(content)
367 , _alignment(alignment)
368 , _scope(scope)
369 , _type(type)
370 , _sectionChoice(sectionChoice)
371 , _interpose(interpose)
372 , _merge(merge)
373 , _deadStrip(deadStrip)
374 , _permissions(perms)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000375 , _isThumb(isThumb)
376 , _isAlias(isAlias)
377 , _refStartIndex(file._lastRefIndex)
378 , _refEndIndex(file._references.size()) {
379 file._lastRefIndex = _refEndIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000380 }
381
Nick Kledzikf46669c2011-12-21 23:29:36 +0000382 virtual const class File& file() const {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000383 return _file;
384 }
385
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000386 virtual llvm::StringRef name() const {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000387 if ( _name == NULL )
388 return llvm::StringRef();
389 else
390 return _name;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000391 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000392
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000393 virtual uint64_t size() const {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000394 return (_content ? _content->size() : _size);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000395 }
396
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000397 virtual DefinedAtom::Scope scope() const {
398 return _scope;
399 }
400
401 virtual DefinedAtom::Interposable interposable() const {
402 return _interpose;
403 }
404
405 virtual DefinedAtom::Merge merge() const {
406 return _merge;
407 }
408
409 virtual DefinedAtom::ContentType contentType() const {
410 return _type;
411 }
412
413 virtual DefinedAtom::Alignment alignment() const {
414 return _alignment;
415 }
416
417 virtual DefinedAtom::SectionChoice sectionChoice() const {
418 return _sectionChoice;
419 }
420
421 virtual llvm::StringRef customSectionName() const {
422 return _sectionName;
423 }
424
425 virtual DefinedAtom::DeadStripKind deadStrip() const {
426 return _deadStrip;
427 }
428
429 virtual DefinedAtom::ContentPermissions permissions() const {
430 return _permissions;
431 }
432
433 virtual bool isThumb() const {
434 return _isThumb;
435 }
436
437 virtual bool isAlias() const {
438 return _isAlias;
439 }
440
441 llvm::ArrayRef<uint8_t> rawContent() const {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000442 if ( _content != NULL )
443 return llvm::ArrayRef<uint8_t>(*_content);
444 else
445 return llvm::ArrayRef<uint8_t>();
446 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000447
448 virtual uint64_t ordinal() const {
449 return _ord;
450 }
451
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000452 DefinedAtom::reference_iterator referencesBegin() const {
453 uintptr_t index = _refStartIndex;
454 const void* it = reinterpret_cast<const void*>(index);
455 return reference_iterator(*this, it);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000456 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000457
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000458 DefinedAtom::reference_iterator referencesEnd() const {
459 uintptr_t index = _refEndIndex;
460 const void* it = reinterpret_cast<const void*>(index);
461 return reference_iterator(*this, it);
462 }
463
464 const Reference* derefIterator(const void* it) const {
465 uintptr_t index = reinterpret_cast<uintptr_t>(it);
466 assert(index >= _refStartIndex);
467 assert(index < _refEndIndex);
468 assert(index < _file._references.size());
469 return &_file._references[index];
470 }
471
472 void incrementIterator(const void*& it) const {
473 uintptr_t index = reinterpret_cast<uintptr_t>(it);
474 ++index;
475 it = reinterpret_cast<const void*>(index);
476 }
477
478
479
480 void bindTargetReferences() const {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000481 for (unsigned int i=_refStartIndex; i < _refEndIndex; ++i) {
482 const char* targetName = _file._references[i]._targetName;
483 Atom* targetAtom = _file.findAtom(targetName);
484 _file._references[i]._target = targetAtom;
485 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000486 }
487
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000488private:
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000489 YAMLFile& _file;
490 const char * _name;
491 const char * _sectionName;
492 unsigned long _size;
493 uint32_t _ord;
494 std::vector<uint8_t>* _content;
495 DefinedAtom::Alignment _alignment;
496 DefinedAtom::Scope _scope;
497 DefinedAtom::ContentType _type;
498 DefinedAtom::SectionChoice _sectionChoice;
499 DefinedAtom::Interposable _interpose;
500 DefinedAtom::Merge _merge;
501 DefinedAtom::DeadStripKind _deadStrip;
502 DefinedAtom::ContentPermissions _permissions;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000503 bool _isThumb;
504 bool _isAlias;
505 unsigned int _refStartIndex;
506 unsigned int _refEndIndex;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000507};
508
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000509
Nick Kledzik23384e82012-02-07 02:59:54 +0000510class YAMLUndefinedAtom : public UndefinedAtom {
511public:
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000512 YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm,
513 UndefinedAtom::CanBeNull cbn)
514 : _file(f), _name(nm), _ordinal(ord), _canBeNull(cbn) { }
Nick Kledzik23384e82012-02-07 02:59:54 +0000515
516 virtual const class File& file() const {
517 return _file;
518 }
519
520 virtual llvm::StringRef name() const {
521 return _name;
522 }
523
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000524 virtual CanBeNull canBeNull() const {
525 return _canBeNull;
Nick Kledzik23384e82012-02-07 02:59:54 +0000526 }
527
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000528
Nick Kledzik23384e82012-02-07 02:59:54 +0000529private:
530 YAMLFile& _file;
531 const char * _name;
532 uint32_t _ordinal;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000533 UndefinedAtom::CanBeNull _canBeNull;
Nick Kledzik23384e82012-02-07 02:59:54 +0000534};
535
536
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000537
538class YAMLSharedLibraryAtom : public SharedLibraryAtom {
539public:
540 YAMLSharedLibraryAtom(YAMLFile& f, int32_t ord, const char* nm,
541 const char* ldnm, bool cbn)
542 : _file(f), _name(nm), _ordinal(ord),
543 _loadName(ldnm), _canBeNull(cbn) { }
544
545 virtual const class File& file() const {
546 return _file;
547 }
548
549 virtual llvm::StringRef name() const {
550 return _name;
551 }
552
553 virtual llvm::StringRef loadName() const {
554 return _loadName;
555 }
556
557 virtual bool canBeNullAtRuntime() const {
558 return _canBeNull;
559 }
560
561
562private:
563 YAMLFile& _file;
564 const char * _name;
565 uint32_t _ordinal;
566 const char * _loadName;
567 bool _canBeNull;
568};
569
570
571
572class YAMLAbsoluteAtom : public AbsoluteAtom {
573public:
574 YAMLAbsoluteAtom(YAMLFile& f, int32_t ord, const char* nm, uint64_t v)
575 : _file(f), _name(nm), _ordinal(ord), _value(v) { }
576
577 virtual const class File& file() const {
578 return _file;
579 }
580
581 virtual llvm::StringRef name() const {
582 return _name;
583 }
584
585 virtual uint64_t value() const {
586 return _value;
587 }
588
589private:
590 YAMLFile& _file;
591 const char * _name;
592 uint32_t _ordinal;
593 uint64_t _value;
594};
595
596
597
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000598void YAMLFile::bindTargetReferences() {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000599 for (defined_iterator it = definedAtomsBegin(); it != definedAtomsEnd(); ++it) {
600 const YAMLDefinedAtom* atom = reinterpret_cast<const YAMLDefinedAtom*>(*it);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000601 atom->bindTargetReferences();
602 }
603}
604
605Atom* YAMLFile::findAtom(const char* name) {
606 for (std::vector<NameAtomPair>::const_iterator it = _nameToAtomMapping.begin();
607 it != _nameToAtomMapping.end(); ++it) {
608 if ( strcmp(name, it->name) == 0 )
609 return it->atom;
610 }
611 llvm::report_fatal_error("reference to atom that does not exist");
612}
613
614void YAMLFile::addDefinedAtom(YAMLDefinedAtom* atom, const char* refName) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000615 _definedAtoms._atoms.push_back(atom);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000616 assert(refName != NULL);
617 _nameToAtomMapping.push_back(NameAtomPair(refName, atom));
618}
619
620void YAMLFile::addUndefinedAtom(UndefinedAtom* atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000621 _undefinedAtoms._atoms.push_back(atom);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000622 _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
623}
624
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000625void YAMLFile::addSharedLibraryAtom(SharedLibraryAtom* atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000626 _sharedLibraryAtoms._atoms.push_back(atom);
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000627 _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
628}
629
630void YAMLFile::addAbsoluteAtom(AbsoluteAtom* atom) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000631 _absoluteAtoms._atoms.push_back(atom);
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000632 _nameToAtomMapping.push_back(NameAtomPair(atom->name().data(), atom));
633}
634
Nick Kledzik23384e82012-02-07 02:59:54 +0000635
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000636class YAMLAtomState {
637public:
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000638 YAMLAtomState(Platform& platform);
639
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000640 void setName(const char *n);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000641 void setRefName(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000642 void setAlign2(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000643
644 void setFixupKind(const char *n);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000645 void setFixupTarget(const char *n);
646 void addFixup(YAMLFile *f);
647
Nick Kledzikf46669c2011-12-21 23:29:36 +0000648 void makeAtom(YAMLFile&);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000649
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000650 Platform& _platform;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000651 const char * _name;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000652 const char * _refName;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000653 const char * _sectionName;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000654 const char* _loadName;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000655 unsigned long long _size;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000656 uint64_t _value;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000657 uint32_t _ordinal;
658 std::vector<uint8_t>* _content;
659 DefinedAtom::Alignment _alignment;
660 Atom::Definition _definition;
661 DefinedAtom::Scope _scope;
662 DefinedAtom::ContentType _type;
663 DefinedAtom::SectionChoice _sectionChoice;
664 DefinedAtom::Interposable _interpose;
665 DefinedAtom::Merge _merge;
666 DefinedAtom::DeadStripKind _deadStrip;
667 DefinedAtom::ContentPermissions _permissions;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000668 bool _isThumb;
669 bool _isAlias;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000670 UndefinedAtom::CanBeNull _canBeNull;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000671 YAMLReference _ref;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000672};
673
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000674
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000675YAMLAtomState::YAMLAtomState(Platform& platform)
676 : _platform(platform)
677 , _name(NULL)
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000678 , _refName(NULL)
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000679 , _sectionName(NULL)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000680 , _loadName(NULL)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000681 , _size(0)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000682 , _value(0)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000683 , _ordinal(0)
684 , _content(NULL)
685 , _alignment(0, 0)
686 , _definition(KeyValues::definitionDefault)
687 , _scope(KeyValues::scopeDefault)
688 , _type(KeyValues::contentTypeDefault)
689 , _sectionChoice(KeyValues::sectionChoiceDefault)
690 , _interpose(KeyValues::interposableDefault)
691 , _merge(KeyValues::mergeDefault)
692 , _deadStrip(KeyValues::deadStripKindDefault)
693 , _permissions(KeyValues::permissionsDefault)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000694 , _isThumb(KeyValues::isThumbDefault)
695 , _isAlias(KeyValues::isAliasDefault)
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000696 , _canBeNull(KeyValues::canBeNullDefault)
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000697 {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000698 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000699
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000700
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000701void YAMLAtomState::makeAtom(YAMLFile& f) {
702 if ( _definition == Atom::definitionRegular ) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000703 YAMLDefinedAtom *a = new YAMLDefinedAtom(_ordinal, f, _scope, _type,
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000704 _sectionChoice, _interpose, _merge, _deadStrip,
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000705 _permissions, _isThumb, _isAlias,
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000706 _alignment, _name, _sectionName, _size, _content);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000707 f.addDefinedAtom(a, _refName ? _refName : _name);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000708 ++_ordinal;
709 }
Nick Kledzik23384e82012-02-07 02:59:54 +0000710 else if ( _definition == Atom::definitionUndefined ) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000711 UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _canBeNull);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000712 f.addUndefinedAtom(a);
Nick Kledzik23384e82012-02-07 02:59:54 +0000713 ++_ordinal;
714 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000715 else if ( _definition == Atom::definitionSharedLibrary ) {
716 bool nullable = (_canBeNull == UndefinedAtom::canBeNullAtRuntime);
717 SharedLibraryAtom *a = new YAMLSharedLibraryAtom(f, _ordinal, _name,
718 _loadName, nullable);
719 f.addSharedLibraryAtom(a);
720 ++_ordinal;
721 }
722 else if ( _definition == Atom::definitionAbsolute ) {
723 AbsoluteAtom *a = new YAMLAbsoluteAtom(f, _ordinal, _name, _value);
724 f.addAbsoluteAtom(a);
725 ++_ordinal;
726 }
727
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000728 // reset state for next atom
729 _name = NULL;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000730 _refName = NULL;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000731 _sectionName = NULL;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000732 _loadName = NULL;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000733 _size = 0;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000734 _value = 0;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000735 _ordinal = 0;
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000736 _content = NULL;
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000737 _alignment.powerOf2= 0;
738 _alignment.modulus = 0;
739 _definition = KeyValues::definitionDefault;
740 _scope = KeyValues::scopeDefault;
741 _type = KeyValues::contentTypeDefault;
742 _sectionChoice = KeyValues::sectionChoiceDefault;
743 _interpose = KeyValues::interposableDefault;
744 _merge = KeyValues::mergeDefault;
745 _deadStrip = KeyValues::deadStripKindDefault;
746 _permissions = KeyValues::permissionsDefault;
747 _isThumb = KeyValues::isThumbDefault;
748 _isAlias = KeyValues::isAliasDefault;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000749 _canBeNull = KeyValues::canBeNullDefault;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000750 _ref._target = NULL;
751 _ref._targetName = NULL;
752 _ref._addend = 0;
753 _ref._offsetInAtom = 0;
754 _ref._kind = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000755}
756
757void YAMLAtomState::setName(const char *n) {
758 _name = n;
759}
760
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000761void YAMLAtomState::setRefName(const char *n) {
762 _refName = n;
763}
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000764
765void YAMLAtomState::setAlign2(const char *s) {
766 llvm::StringRef str(s);
767 uint32_t res;
768 str.getAsInteger(10, res);
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000769 _alignment.powerOf2 = static_cast<uint16_t>(res);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000770}
771
Nick Kledzik38eec3d2011-12-22 02:38:01 +0000772
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000773void YAMLAtomState::setFixupKind(const char *s) {
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000774 _ref._kind = _platform.kindFromString(llvm::StringRef(s));
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000775}
776
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000777void YAMLAtomState::setFixupTarget(const char *s) {
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000778 _ref._targetName = s;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000779}
780
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000781
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000782void YAMLAtomState::addFixup(YAMLFile *f) {
783 f->_references.push_back(_ref);
784 // clear for next ref
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000785 _ref._target = NULL;
786 _ref._targetName = NULL;
787 _ref._addend = 0;
788 _ref._offsetInAtom = 0;
789 _ref._kind = 0;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000790}
791
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000792
793} // anonymous namespace
794
795
796
797
798
799/// parseObjectText - Parse the specified YAML formatted MemoryBuffer
800/// into lld::File object(s) and append each to the specified vector<File*>.
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000801llvm::error_code parseObjectText( llvm::MemoryBuffer *mb
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000802 , Platform& platform
803 , std::vector<const File *> &result) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000804 std::vector<const YAML::Entry *> entries;
805 YAML::parse(mb, entries);
806
807 YAMLFile *file = NULL;
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000808 YAMLAtomState atomState(platform);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000809 bool inAtoms = false;
810 bool inFixups = false;
811 int depthForAtoms = -1;
812 int depthForFixups = -1;
813 int lastDepth = -1;
814 bool haveAtom = false;
815 bool haveFixup = false;
816
817 for (std::vector<const YAML::Entry *>::iterator it = entries.begin();
818 it != entries.end(); ++it) {
819 const YAML::Entry *entry = *it;
820
821 if (entry->beginDocument) {
822 if (file != NULL) {
823 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000824 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000825 haveAtom = false;
826 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000827 file->bindTargetReferences();
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000828 result.push_back(file);
829 }
830 file = new YAMLFile();
831 inAtoms = false;
832 depthForAtoms = -1;
833 }
834 if (lastDepth > entry->depth) {
835 // end of fixup sequence
836 if (haveFixup) {
837 atomState.addFixup(file);
838 haveFixup = false;
839 }
840 }
841
842 if (inAtoms && (depthForAtoms == -1)) {
843 depthForAtoms = entry->depth;
844 }
845 if (inFixups && (depthForFixups == -1)) {
846 depthForFixups = entry->depth;
847 }
848 if (strcmp(entry->key, "atoms") == 0) {
849 inAtoms = true;
850 }
851 if (inAtoms) {
852 if (depthForAtoms == entry->depth) {
853 if (entry->beginSequence) {
854 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000855 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000856 haveAtom = false;
857 }
858 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000859 if (strcmp(entry->key, KeyValues::nameKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000860 atomState.setName(entry->value);
861 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000862 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000863 else if (strcmp(entry->key, KeyValues::refNameKeyword) == 0) {
864 atomState.setRefName(entry->value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000865 haveAtom = true;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000866 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000867 else if (strcmp(entry->key, KeyValues::definitionKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000868 atomState._definition = KeyValues::definition(entry->value);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000869 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000870 }
871 else if (strcmp(entry->key, KeyValues::scopeKeyword) == 0) {
872 atomState._scope = KeyValues::scope(entry->value);
873 haveAtom = true;
874 }
875 else if (strcmp(entry->key, KeyValues::contentTypeKeyword) == 0) {
876 atomState._type = KeyValues::contentType(entry->value);
877 haveAtom = true;
878 }
879 else if (strcmp(entry->key, KeyValues::deadStripKindKeyword) == 0) {
880 atomState._deadStrip = KeyValues::deadStripKind(entry->value);
881 haveAtom = true;
882 }
883 else if (strcmp(entry->key, KeyValues::sectionChoiceKeyword) == 0) {
884 atomState._sectionChoice = KeyValues::sectionChoice(entry->value);
885 haveAtom = true;
886 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000887 else if (strcmp(entry->key, KeyValues::mergeKeyword) == 0) {
888 atomState._merge = KeyValues::merge(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000889 haveAtom = true;
890 }
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000891 else if (strcmp(entry->key, KeyValues::interposableKeyword) == 0) {
892 atomState._interpose = KeyValues::interposable(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000893 haveAtom = true;
894 }
895 else if (strcmp(entry->key, KeyValues::isThumbKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000896 atomState._isThumb = KeyValues::isThumb(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000897 haveAtom = true;
898 }
899 else if (strcmp(entry->key, KeyValues::isAliasKeyword) == 0) {
Nick Kledzikf4fb2c52012-01-11 01:06:19 +0000900 atomState._isAlias = KeyValues::isAlias(entry->value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000901 haveAtom = true;
902 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000903 else if (strcmp(entry->key, KeyValues::canBeNullKeyword) == 0) {
904 atomState._canBeNull = KeyValues::canBeNull(entry->value);
905 if ( atomState._definition == Atom::definitionSharedLibrary ) {
906 if ( atomState._canBeNull == UndefinedAtom::canBeNullAtBuildtime )
907 return make_error_code(yaml_reader_error::illegal_value);
908 }
Nick Kledzik23384e82012-02-07 02:59:54 +0000909 haveAtom = true;
910 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000911 else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
912 atomState._sectionName = entry->value;
913 haveAtom = true;
914 }
915 else if (strcmp(entry->key, KeyValues::sizeKeyword) == 0) {
916 llvm::StringRef val = entry->value;
Michael J. Spencer7aba8952012-01-31 21:47:13 +0000917 if ( val.getAsInteger(0, atomState._size) )
918 return make_error_code(yaml_reader_error::illegal_value);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000919 haveAtom = true;
920 }
921 else if (strcmp(entry->key, KeyValues::contentKeyword) == 0) {
Nick Kledzikbfedfc12012-01-09 20:18:15 +0000922 atomState._content = entry->valueSequenceBytes;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000923 haveAtom = true;
924 }
925 else if (strcmp(entry->key, "align2") == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000926 atomState.setAlign2(entry->value);
927 haveAtom = true;
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000928 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000929 else if (strcmp(entry->key, KeyValues::fixupsKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000930 inFixups = true;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000931 }
932 else if (strcmp(entry->key, KeyValues::loadNameKeyword) == 0) {
933 atomState._loadName = entry->value;
934 haveAtom = true;
935 }
936 else if (strcmp(entry->key, KeyValues::valueKeyword) == 0) {
937 llvm::StringRef(entry->value).getAsInteger(0, atomState._value);
938 haveAtom = true;
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000939 }
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000940 else {
Michael J. Spencer7aba8952012-01-31 21:47:13 +0000941 return make_error_code(yaml_reader_error::unknown_keyword);
Nick Kledzik7735a7d2012-01-04 23:58:17 +0000942 }
943 }
944 else if (depthForFixups == entry->depth) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000945 if (entry->beginSequence) {
946 if (haveFixup) {
947 atomState.addFixup(file);
948 haveFixup = false;
949 }
950 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000951 if (strcmp(entry->key, KeyValues::fixupsKindKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000952 atomState.setFixupKind(entry->value);
953 haveFixup = true;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000954 }
955 else if (strcmp(entry->key, KeyValues::fixupsOffsetKeyword) == 0) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000956 llvm::StringRef(entry->value).getAsInteger(0,
957 atomState._ref._offsetInAtom);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000958 haveFixup = true;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000959 }
960 else if (strcmp(entry->key, KeyValues::fixupsTargetKeyword) == 0) {
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000961 atomState.setFixupTarget(entry->value);
962 haveFixup = true;
963 }
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000964 else if (strcmp(entry->key, KeyValues::fixupsAddendKeyword) == 0) {
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000965 llvm::StringRef(entry->value).getAsInteger(0,
966 atomState._ref._addend);
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000967 haveFixup = true;
968 }
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000969 }
970 }
971 lastDepth = entry->depth;
972 }
973 if (haveAtom) {
Nick Kledzikf46669c2011-12-21 23:29:36 +0000974 atomState.makeAtom(*file);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000975 }
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000976 if ( file != NULL ) {
977 file->bindTargetReferences();
978 result.push_back(file);
979 }
Michael J. Spencer7aba8952012-01-31 21:47:13 +0000980 return make_error_code(yaml_reader_error::success);
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000981}
Nick Kledzik070e1a72011-12-20 00:07:11 +0000982
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000983
Nick Kledzik070e1a72011-12-20 00:07:11 +0000984//
985// Fill in vector<File*> from path to input text file.
986//
987llvm::error_code parseObjectTextFileOrSTDIN(llvm::StringRef path
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000988 , Platform& platform
989 , std::vector<const File*>& result) {
Nick Kledzik070e1a72011-12-20 00:07:11 +0000990 llvm::OwningPtr<llvm::MemoryBuffer> mb;
991 llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
992 if ( ec )
993 return ec;
994
Nick Kledzik1a6615d2012-03-08 00:18:30 +0000995 return parseObjectText(mb.get(), platform, result);
Nick Kledzik070e1a72011-12-20 00:07:11 +0000996}
997
998
Michael J. Spencer773a8fb2011-12-18 08:27:59 +0000999} // namespace yaml
1000} // namespace lld