blob: 34887c2b03d7ca5161a047cf589c51175a9f327c [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
Nick Kledzikabb69812012-05-31 22:34:00 +000012#include "llvm/ADT/StringRef.h"
Nick Kledzike5552772013-12-19 21:58:00 +000013#include "llvm/Support/FileUtilities.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000014#include "llvm/Support/MemoryBuffer.h"
Nick Kledzike5552772013-12-19 21:58:00 +000015#include "llvm/Support/Path.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000016#include "llvm/Support/system_error.h"
17
Ahmed Charles13c70b62014-03-13 16:20:38 +000018#include <memory>
19
Nick Kledzikabb69812012-05-31 22:34:00 +000020namespace lld {
Nick Kledzike5552772013-12-19 21:58:00 +000021
Nick Kledzikabb69812012-05-31 22:34:00 +000022Reader::~Reader() {
23}
Nick Kledzike5552772013-12-19 21:58:00 +000024
Nick Kledzik6edd7222014-01-11 01:07:43 +000025
26YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() { }
27
28
Nick Kledzike5552772013-12-19 21:58:00 +000029void Registry::add(std::unique_ptr<Reader> reader) {
30 _readers.push_back(std::move(reader));
31}
32
Nick Kledzik6edd7222014-01-11 01:07:43 +000033void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
34 _yamlHandlers.push_back(std::move(handler));
35}
36
Rui Ueyama170a1a82013-12-20 07:48:29 +000037error_code
Nick Kledzike5552772013-12-19 21:58:00 +000038Registry::parseFile(std::unique_ptr<MemoryBuffer> &mb,
Rui Ueyama170a1a82013-12-20 07:48:29 +000039 std::vector<std::unique_ptr<File>> &result) const {
Nick Kledzike5552772013-12-19 21:58:00 +000040 // Get file type.
41 StringRef content(mb->getBufferStart(), mb->getBufferSize());
42 llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
43 // Get file extension.
44 StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier());
45
46 // Ask each registered reader if it can handle this file type or extension.
47 for (const std::unique_ptr<Reader> &reader : _readers) {
48 if (reader->canParse(fileType, extension, *mb))
49 return reader->parseFile(mb, *this, result);
50 }
Rui Ueyama170a1a82013-12-20 07:48:29 +000051
52 // No Reader could parse this file.
Nick Kledzike5552772013-12-19 21:58:00 +000053 return llvm::make_error_code(llvm::errc::executable_format_error);
54}
55
56static const Registry::KindStrings kindStrings[] = {
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000057 {Reference::kindInGroup, "in-group"},
58 {Reference::kindLayoutAfter, "layout-after"},
59 {Reference::kindLayoutBefore, "layout-before"},
60 {Reference::kindGroupChild, "group-child"},
61 {Reference::kindGroupParent, "group-parent"},
62 LLD_KIND_STRING_END};
Nick Kledzike5552772013-12-19 21:58:00 +000063
64Registry::Registry() {
Rui Ueyama170a1a82013-12-20 07:48:29 +000065 addKindTable(Reference::KindNamespace::all, Reference::KindArch::all,
66 kindStrings);
Nick Kledzike5552772013-12-19 21:58:00 +000067}
68
Shankar Easwaran3d8de472014-01-27 03:09:26 +000069bool Registry::handleTaggedDoc(llvm::yaml::IO &io,
Nick Kledzik6edd7222014-01-11 01:07:43 +000070 const lld::File *&file) const {
71 for (const std::unique_ptr<YamlIOTaggedDocumentHandler> &h : _yamlHandlers) {
72 if (h->handledDocTag(io, file))
73 return true;
74 }
75 return false;
76}
77
78
Rui Ueyama170a1a82013-12-20 07:48:29 +000079void Registry::addKindTable(Reference::KindNamespace ns,
Nick Kledzike5552772013-12-19 21:58:00 +000080 Reference::KindArch arch,
81 const KindStrings array[]) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000082 KindEntry entry = { ns, arch, array };
Nick Kledzike5552772013-12-19 21:58:00 +000083 _kindEntries.push_back(entry);
84}
85
Rui Ueyama170a1a82013-12-20 07:48:29 +000086bool Registry::referenceKindFromString(StringRef inputStr,
Nick Kledzike5552772013-12-19 21:58:00 +000087 Reference::KindNamespace &ns,
Rui Ueyama170a1a82013-12-20 07:48:29 +000088 Reference::KindArch &arch,
Nick Kledzike5552772013-12-19 21:58:00 +000089 Reference::KindValue &value) const {
90 for (const KindEntry &entry : _kindEntries) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000091 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +000092 if (!inputStr.equals(pair->name))
93 continue;
94 ns = entry.ns;
95 arch = entry.arch;
96 value = pair->value;
97 return true;
98 }
99 }
100 return false;
101}
102
Rui Ueyama170a1a82013-12-20 07:48:29 +0000103bool Registry::referenceKindToString(Reference::KindNamespace ns,
104 Reference::KindArch arch,
105 Reference::KindValue value,
Nick Kledzike5552772013-12-19 21:58:00 +0000106 StringRef &str) const {
107 for (const KindEntry &entry : _kindEntries) {
108 if (entry.ns != ns)
109 continue;
110 if (entry.arch != arch)
111 continue;
Rui Ueyama170a1a82013-12-20 07:48:29 +0000112 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +0000113 if (pair->value != value)
114 continue;
115 str = pair->name;
116 return true;
117 }
118 }
119 return false;
120}
121
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000122} // end namespace lld