blob: bd7df2c44893ae16b5ce9e1f10dd54a22b6efb0b [file] [log] [blame]
Greg Fitzgerald4b6a7e32015-01-21 22:54:56 +00001//===- lib/Core/Reader.cpp ------------------------------------------------===//
Nick Kledzikabb69812012-05-31 22:34:00 +00002//
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
Rui Ueyama1d510422014-12-12 07:31:09 +000010#include "lld/Core/File.h"
Greg Fitzgerald4b6a7e32015-01-21 22:54:56 +000011#include "lld/Core/Reader.h"
Nick Kledzikabb69812012-05-31 22:34:00 +000012#include "llvm/ADT/StringRef.h"
Rafael Espindola372bc702014-06-13 17:20:48 +000013#include "llvm/Support/Errc.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"
Ahmed Charles13c70b62014-03-13 16:20:38 +000016#include <memory>
Rafael Espindola54427cc2014-06-12 17:15:58 +000017#include <system_error>
Ahmed Charles13c70b62014-03-13 16:20:38 +000018
Nick Kledzikabb69812012-05-31 22:34:00 +000019namespace lld {
Nick Kledzike5552772013-12-19 21:58:00 +000020
Rui Ueyamad62d1312014-06-04 08:39:56 +000021YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() {}
Nick Kledzik6edd7222014-01-11 01:07:43 +000022
Nick Kledzike5552772013-12-19 21:58:00 +000023void Registry::add(std::unique_ptr<Reader> reader) {
24 _readers.push_back(std::move(reader));
25}
26
Nick Kledzik6edd7222014-01-11 01:07:43 +000027void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
28 _yamlHandlers.push_back(std::move(handler));
29}
30
Rafael Espindolab1a4d3a2014-06-12 14:53:47 +000031std::error_code
Rui Ueyamadf230b22015-01-15 04:34:31 +000032Registry::loadFile(std::unique_ptr<MemoryBuffer> mb,
33 std::vector<std::unique_ptr<File>> &result) const {
Rui Ueyama55f5b2b2015-04-04 02:44:36 +000034 // Get file magic.
Nick Kledzike5552772013-12-19 21:58:00 +000035 StringRef content(mb->getBufferStart(), mb->getBufferSize());
36 llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(content);
Nick Kledzike5552772013-12-19 21:58:00 +000037
38 // Ask each registered reader if it can handle this file type or extension.
Rui Ueyama1d510422014-12-12 07:31:09 +000039 for (const std::unique_ptr<Reader> &reader : _readers) {
Rui Ueyama55f5b2b2015-04-04 02:44:36 +000040 if (!reader->canParse(fileType, *mb))
Rui Ueyama1d510422014-12-12 07:31:09 +000041 continue;
Rui Ueyamadf230b22015-01-15 04:34:31 +000042 if (std::error_code ec = reader->loadFile(std::move(mb), *this, result))
Rui Ueyama1d510422014-12-12 07:31:09 +000043 return ec;
Rui Ueyama1d510422014-12-12 07:31:09 +000044 return std::error_code();
45 }
Rui Ueyama170a1a82013-12-20 07:48:29 +000046
47 // No Reader could parse this file.
Rafael Espindola372bc702014-06-13 17:20:48 +000048 return make_error_code(llvm::errc::executable_format_error);
Nick Kledzike5552772013-12-19 21:58:00 +000049}
50
51static const Registry::KindStrings kindStrings[] = {
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000052 {Reference::kindLayoutAfter, "layout-after"},
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000053 {Reference::kindGroupChild, "group-child"},
Rui Ueyama61d7f972014-06-17 16:19:33 +000054 {Reference::kindAssociate, "associate"},
Shankar Easwaran7ac2a3d2014-03-26 16:37:13 +000055 LLD_KIND_STRING_END};
Nick Kledzike5552772013-12-19 21:58:00 +000056
57Registry::Registry() {
Rui Ueyama170a1a82013-12-20 07:48:29 +000058 addKindTable(Reference::KindNamespace::all, Reference::KindArch::all,
59 kindStrings);
Nick Kledzike5552772013-12-19 21:58:00 +000060}
61
Shankar Easwaran3d8de472014-01-27 03:09:26 +000062bool Registry::handleTaggedDoc(llvm::yaml::IO &io,
Nick Kledzik6edd7222014-01-11 01:07:43 +000063 const lld::File *&file) const {
Rui Ueyamad62d1312014-06-04 08:39:56 +000064 for (const std::unique_ptr<YamlIOTaggedDocumentHandler> &h : _yamlHandlers)
Nick Kledzik6edd7222014-01-11 01:07:43 +000065 if (h->handledDocTag(io, file))
66 return true;
Nick Kledzik6edd7222014-01-11 01:07:43 +000067 return false;
68}
69
70
Rui Ueyama170a1a82013-12-20 07:48:29 +000071void Registry::addKindTable(Reference::KindNamespace ns,
Nick Kledzike5552772013-12-19 21:58:00 +000072 Reference::KindArch arch,
73 const KindStrings array[]) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000074 KindEntry entry = { ns, arch, array };
Nick Kledzike5552772013-12-19 21:58:00 +000075 _kindEntries.push_back(entry);
76}
77
Rui Ueyama170a1a82013-12-20 07:48:29 +000078bool Registry::referenceKindFromString(StringRef inputStr,
Nick Kledzike5552772013-12-19 21:58:00 +000079 Reference::KindNamespace &ns,
Rui Ueyama170a1a82013-12-20 07:48:29 +000080 Reference::KindArch &arch,
Nick Kledzike5552772013-12-19 21:58:00 +000081 Reference::KindValue &value) const {
82 for (const KindEntry &entry : _kindEntries) {
Rui Ueyama170a1a82013-12-20 07:48:29 +000083 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +000084 if (!inputStr.equals(pair->name))
85 continue;
86 ns = entry.ns;
87 arch = entry.arch;
88 value = pair->value;
89 return true;
90 }
91 }
92 return false;
93}
94
Rui Ueyama170a1a82013-12-20 07:48:29 +000095bool Registry::referenceKindToString(Reference::KindNamespace ns,
96 Reference::KindArch arch,
97 Reference::KindValue value,
Nick Kledzike5552772013-12-19 21:58:00 +000098 StringRef &str) const {
99 for (const KindEntry &entry : _kindEntries) {
100 if (entry.ns != ns)
101 continue;
102 if (entry.arch != arch)
103 continue;
Rui Ueyama170a1a82013-12-20 07:48:29 +0000104 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
Nick Kledzike5552772013-12-19 21:58:00 +0000105 if (pair->value != value)
106 continue;
107 str = pair->name;
108 return true;
109 }
110 }
111 return false;
112}
113
Shankar Easwaran8962feb2013-03-14 16:09:49 +0000114} // end namespace lld