blob: 69c5c34e073025cf54359e992c95bd9937be52d5 [file] [log] [blame]
Nick Kledzikabb69812012-05-31 22:34:00 +00001//===- lib/ReaderWriter/Reader.cpp ----------------------------------------===//
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/ReaderWriter/Reader.h"
11
12#include "llvm/ADT/OwningPtr.h"
13#include "llvm/ADT/StringRef.h"
Nick Kledzike5552772013-12-19 21:58:00 +000014#include "llvm/Support/FileUtilities.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000015#include "llvm/Support/MemoryBuffer.h"
Nick Kledzike5552772013-12-19 21:58:00 +000016#include "llvm/Support/Path.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000017#include "llvm/Support/system_error.h"
18
Nick Kledzikabb69812012-05-31 22:34:00 +000019namespace lld {
Nick Kledzike5552772013-12-19 21:58:00 +000020
Nick Kledzikabb69812012-05-31 22:34:00 +000021Reader::~Reader() {
22}
Nick Kledzike5552772013-12-19 21:58:00 +000023
24void Registry::add(std::unique_ptr<Reader> reader) {
25 _readers.push_back(std::move(reader));
26}
27
28error_code
29Registry::parseFile(std::unique_ptr<MemoryBuffer> &mb,
30 std::vector<std::unique_ptr<File>> &result) const {
31 // Get file type.
32 StringRef content(mb->getBufferStart(), mb->getBufferSize());
33 llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
34 // Get file extension.
35 StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier());
36
37 // Ask each registered reader if it can handle this file type or extension.
38 for (const std::unique_ptr<Reader> &reader : _readers) {
39 if (reader->canParse(fileType, extension, *mb))
40 return reader->parseFile(mb, *this, result);
41 }
42
43 // No Reader could parse this file.
44 return llvm::make_error_code(llvm::errc::executable_format_error);
45}
46
47static const Registry::KindStrings kindStrings[] = {
48 { Reference::kindInGroup, "in-group" },
49 { Reference::kindLayoutAfter, "layout-after" },
50 { Reference::kindLayoutBefore, "layout-before" },
51 LLD_KIND_STRING_END
52};
53
54Registry::Registry() {
55 addKindTable(Reference::KindNamespace::all, Reference::KindArch::all,
56 kindStrings);
57}
58
59void Registry::addKindTable(Reference::KindNamespace ns,
60 Reference::KindArch arch,
61 const KindStrings array[]) {
62 KindEntry entry = {ns, arch, array};
63 _kindEntries.push_back(entry);
64}
65
66bool Registry::referenceKindFromString(StringRef inputStr,
67 Reference::KindNamespace &ns,
68 Reference::KindArch &arch,
69 Reference::KindValue &value) const {
70 for (const KindEntry &entry : _kindEntries) {
71 for (const KindStrings *pair=entry.array; !pair->name.empty(); ++pair) {
72 if (!inputStr.equals(pair->name))
73 continue;
74 ns = entry.ns;
75 arch = entry.arch;
76 value = pair->value;
77 return true;
78 }
79 }
80 return false;
81}
82
83
84bool Registry::referenceKindToString(Reference::KindNamespace ns,
85 Reference::KindArch arch,
86 Reference::KindValue value,
87 StringRef &str) const {
88 for (const KindEntry &entry : _kindEntries) {
89 if (entry.ns != ns)
90 continue;
91 if (entry.arch != arch)
92 continue;
93 for (const KindStrings *pair=entry.array; !pair->name.empty(); ++pair) {
94 if (pair->value != value)
95 continue;
96 str = pair->name;
97 return true;
98 }
99 }
100 return false;
101}
102
103
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000104} // end namespace lld