blob: 35affd78e2b3620811a619e332169fa7687e1c1a [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
Nick Kledzik6edd7222014-01-11 01:07:43 +000024
25YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() { }
26
27
Nick Kledzike5552772013-12-19 21:58:00 +000028void Registry::add(std::unique_ptr<Reader> reader) {
29 _readers.push_back(std::move(reader));
30}
31
Nick Kledzik6edd7222014-01-11 01:07:43 +000032void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
33 _yamlHandlers.push_back(std::move(handler));
34}
35
Rui Ueyama170a1a82013-12-20 07:48:29 +000036error_code
Nick Kledzike5552772013-12-19 21:58:00 +000037Registry::parseFile(std::unique_ptr<MemoryBuffer> &mb,
Rui Ueyama170a1a82013-12-20 07:48:29 +000038 std::vector<std::unique_ptr<File>> &result) const {
Nick Kledzike5552772013-12-19 21:58:00 +000039 // Get file type.
40 StringRef content(mb->getBufferStart(), mb->getBufferSize());
41 llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
42 // Get file extension.
43 StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier());
44
45 // Ask each registered reader if it can handle this file type or extension.
46 for (const std::unique_ptr<Reader> &reader : _readers) {
47 if (reader->canParse(fileType, extension, *mb))
48 return reader->parseFile(mb, *this, result);
49 }
Rui Ueyama170a1a82013-12-20 07:48:29 +000050
51 // No Reader could parse this file.
Nick Kledzike5552772013-12-19 21:58:00 +000052 return llvm::make_error_code(llvm::errc::executable_format_error);
53}
54
55static const Registry::KindStrings kindStrings[] = {
Nick Kledzikf30e8482013-12-20 20:34:19 +000056 { Reference::kindInGroup, "in-group" },
57 { Reference::kindLayoutAfter, "layout-after" },
Rui Ueyama170a1a82013-12-20 07:48:29 +000058 { Reference::kindLayoutBefore, "layout-before" },
Nick Kledzike5552772013-12-19 21:58:00 +000059 LLD_KIND_STRING_END
60};
61
62Registry::Registry() {
Rui Ueyama170a1a82013-12-20 07:48:29 +000063 addKindTable(Reference::KindNamespace::all, Reference::KindArch::all,
64 kindStrings);
Nick Kledzike5552772013-12-19 21:58:00 +000065}
66
Nick Kledzik6edd7222014-01-11 01:07:43 +000067bool Registry::handleTaggedDoc(llvm::yaml::IO &io,
68 const lld::File *&file) const {
69 for (const std::unique_ptr<YamlIOTaggedDocumentHandler> &h : _yamlHandlers) {
70 if (h->handledDocTag(io, file))
71 return true;
72 }
73 return false;
74}
75
76
Rui Ueyama170a1a82013-12-20 07:48:29 +000077void Registry::addKindTable(Reference::KindNamespace ns,
Nick Kledzike5552772013-12-19 21:58:00 +000078 Reference::KindArch arch,
79 const KindStrings array[]) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000080 KindEntry entry = { ns, arch, array };
Nick Kledzike5552772013-12-19 21:58:00 +000081 _kindEntries.push_back(entry);
82}
83
Rui Ueyama170a1a82013-12-20 07:48:29 +000084bool Registry::referenceKindFromString(StringRef inputStr,
Nick Kledzike5552772013-12-19 21:58:00 +000085 Reference::KindNamespace &ns,
Rui Ueyama170a1a82013-12-20 07:48:29 +000086 Reference::KindArch &arch,
Nick Kledzike5552772013-12-19 21:58:00 +000087 Reference::KindValue &value) const {
88 for (const KindEntry &entry : _kindEntries) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000089 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +000090 if (!inputStr.equals(pair->name))
91 continue;
92 ns = entry.ns;
93 arch = entry.arch;
94 value = pair->value;
95 return true;
96 }
97 }
98 return false;
99}
100
Rui Ueyama170a1a82013-12-20 07:48:29 +0000101bool Registry::referenceKindToString(Reference::KindNamespace ns,
102 Reference::KindArch arch,
103 Reference::KindValue value,
Nick Kledzike5552772013-12-19 21:58:00 +0000104 StringRef &str) const {
105 for (const KindEntry &entry : _kindEntries) {
106 if (entry.ns != ns)
107 continue;
108 if (entry.arch != arch)
109 continue;
Rui Ueyama170a1a82013-12-20 07:48:29 +0000110 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +0000111 if (pair->value != value)
112 continue;
113 str = pair->name;
114 return true;
115 }
116 }
117 return false;
118}
119
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000120} // end namespace lld