blob: 49612fb5b8c108b0a3569b40b5285535d1cc3151 [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"
Nick Kledzikabb69812012-05-31 22:34:00 +000011#include "llvm/ADT/StringRef.h"
Nick Kledzike5552772013-12-19 21:58:00 +000012#include "llvm/Support/FileUtilities.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000013#include "llvm/Support/MemoryBuffer.h"
Nick Kledzike5552772013-12-19 21:58:00 +000014#include "llvm/Support/Path.h"
Ahmed Charles13c70b62014-03-13 16:20:38 +000015#include <memory>
Rafael Espindola54427cc2014-06-12 17:15:58 +000016#include <system_error>
Ahmed Charles13c70b62014-03-13 16:20:38 +000017
Nick Kledzikabb69812012-05-31 22:34:00 +000018namespace lld {
Nick Kledzike5552772013-12-19 21:58:00 +000019
Rui Ueyamad62d1312014-06-04 08:39:56 +000020YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() {}
Nick Kledzik6edd7222014-01-11 01:07:43 +000021
Nick Kledzike5552772013-12-19 21:58:00 +000022void Registry::add(std::unique_ptr<Reader> reader) {
23 _readers.push_back(std::move(reader));
24}
25
Nick Kledzik6edd7222014-01-11 01:07:43 +000026void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
27 _yamlHandlers.push_back(std::move(handler));
28}
29
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000030std::error_code
Nick Kledzike5552772013-12-19 21:58:00 +000031Registry::parseFile(std::unique_ptr<MemoryBuffer> &mb,
Rui Ueyama170a1a82013-12-20 07:48:29 +000032 std::vector<std::unique_ptr<File>> &result) const {
Nick Kledzike5552772013-12-19 21:58:00 +000033 // Get file type.
34 StringRef content(mb->getBufferStart(), mb->getBufferSize());
35 llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
36 // Get file extension.
37 StringRef extension = llvm::sys::path::extension(mb->getBufferIdentifier());
38
39 // Ask each registered reader if it can handle this file type or extension.
Rui Ueyamad62d1312014-06-04 08:39:56 +000040 for (const std::unique_ptr<Reader> &reader : _readers)
Nick Kledzike5552772013-12-19 21:58:00 +000041 if (reader->canParse(fileType, extension, *mb))
42 return reader->parseFile(mb, *this, result);
Rui Ueyama170a1a82013-12-20 07:48:29 +000043
44 // No Reader could parse this file.
Rafael Espindola99c78a92014-06-12 03:13:49 +000045 return std::make_error_code(std::errc::executable_format_error);
Nick Kledzike5552772013-12-19 21:58:00 +000046}
47
48static const Registry::KindStrings kindStrings[] = {
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000049 {Reference::kindInGroup, "in-group"},
50 {Reference::kindLayoutAfter, "layout-after"},
51 {Reference::kindLayoutBefore, "layout-before"},
52 {Reference::kindGroupChild, "group-child"},
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000053 LLD_KIND_STRING_END};
Nick Kledzike5552772013-12-19 21:58:00 +000054
55Registry::Registry() {
Rui Ueyama170a1a82013-12-20 07:48:29 +000056 addKindTable(Reference::KindNamespace::all, Reference::KindArch::all,
57 kindStrings);
Nick Kledzike5552772013-12-19 21:58:00 +000058}
59
Shankar Easwaran3d8de472014-01-27 03:09:26 +000060bool Registry::handleTaggedDoc(llvm::yaml::IO &io,
Nick Kledzik6edd7222014-01-11 01:07:43 +000061 const lld::File *&file) const {
Rui Ueyamad62d1312014-06-04 08:39:56 +000062 for (const std::unique_ptr<YamlIOTaggedDocumentHandler> &h : _yamlHandlers)
Nick Kledzik6edd7222014-01-11 01:07:43 +000063 if (h->handledDocTag(io, file))
64 return true;
Nick Kledzik6edd7222014-01-11 01:07:43 +000065 return false;
66}
67
68
Rui Ueyama170a1a82013-12-20 07:48:29 +000069void Registry::addKindTable(Reference::KindNamespace ns,
Nick Kledzike5552772013-12-19 21:58:00 +000070 Reference::KindArch arch,
71 const KindStrings array[]) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000072 KindEntry entry = { ns, arch, array };
Nick Kledzike5552772013-12-19 21:58:00 +000073 _kindEntries.push_back(entry);
74}
75
Rui Ueyama170a1a82013-12-20 07:48:29 +000076bool Registry::referenceKindFromString(StringRef inputStr,
Nick Kledzike5552772013-12-19 21:58:00 +000077 Reference::KindNamespace &ns,
Rui Ueyama170a1a82013-12-20 07:48:29 +000078 Reference::KindArch &arch,
Nick Kledzike5552772013-12-19 21:58:00 +000079 Reference::KindValue &value) const {
80 for (const KindEntry &entry : _kindEntries) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000081 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +000082 if (!inputStr.equals(pair->name))
83 continue;
84 ns = entry.ns;
85 arch = entry.arch;
86 value = pair->value;
87 return true;
88 }
89 }
90 return false;
91}
92
Rui Ueyama170a1a82013-12-20 07:48:29 +000093bool Registry::referenceKindToString(Reference::KindNamespace ns,
94 Reference::KindArch arch,
95 Reference::KindValue value,
Nick Kledzike5552772013-12-19 21:58:00 +000096 StringRef &str) const {
97 for (const KindEntry &entry : _kindEntries) {
98 if (entry.ns != ns)
99 continue;
100 if (entry.arch != arch)
101 continue;
Rui Ueyama170a1a82013-12-20 07:48:29 +0000102 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +0000103 if (pair->value != value)
104 continue;
105 str = pair->name;
106 return true;
107 }
108 }
109 return false;
110}
111
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000112} // end namespace lld