blob: 2e2bc59d3548fa78d9a425740bc01bc142c555e5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
//===- lib/Driver/Targets.cpp - Linker Targets ----------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// Concrete instances of the Target interface.
///
//===----------------------------------------------------------------------===//
#include "lld/Driver/Target.h"
#include "lld/Core/LinkerOptions.h"
#include "lld/Core/TargetInfo.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
#include "lld/ReaderWriter/ELFTargetInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
#include <set>
using namespace lld;
using namespace std::placeholders;
class ELFTarget : public Target {
public:
ELFTarget(std::unique_ptr<ELFTargetInfo> ti)
: Target(std::unique_ptr<TargetInfo>(ti.get())),
_elfTargetInfo(*ti.release()), _readerELF(createReaderELF(
_elfTargetInfo, std::bind(&ELFTarget::getReader, this, _1))),
_readerYAML(createReaderYAML(*_targetInfo)),
_writer(createWriterELF(_elfTargetInfo)),
_writerYAML(createWriterYAML(*_targetInfo)) {
}
virtual ErrorOr<lld::Reader&> getReader(const LinkerInput &input) {
auto kind = input.getKind();
if (!kind)
return error_code(kind);
if (*kind == InputKind::YAML)
return *_readerYAML;
if (*kind == InputKind::Object)
return *_readerELF;
return llvm::make_error_code(llvm::errc::invalid_argument);
}
virtual ErrorOr<lld::Writer&> getWriter() {
return _targetInfo->getLinkerOptions()._outputYAML ? *_writerYAML
: *_writer;
}
protected:
const ELFTargetInfo &_elfTargetInfo;
std::unique_ptr<lld::Reader> _readerELF, _readerYAML;
std::unique_ptr<lld::Writer> _writer, _writerYAML;
};
class X86LinuxTarget LLVM_FINAL : public ELFTarget {
public:
X86LinuxTarget(std::unique_ptr<ELFTargetInfo> ti)
: ELFTarget(std::move(ti)) {}
};
class HexagonTarget LLVM_FINAL : public ELFTarget {
public:
HexagonTarget(std::unique_ptr<ELFTargetInfo> ti)
: ELFTarget(std::move(ti)) {}
};
std::unique_ptr<Target> Target::create(const LinkerOptions &lo) {
llvm::Triple t(lo._target);
// Create a TargetInfo.
std::unique_ptr<ELFTargetInfo> ti(ELFTargetInfo::create(lo));
// Create the Target
if (t.getOS() == llvm::Triple::Linux && (t.getArch() == llvm::Triple::x86 ||
t.getArch() == llvm::Triple::x86_64))
return std::unique_ptr<Target>(new X86LinuxTarget(std::move(ti)));
else if (t.getArch() == llvm::Triple::hexagon)
return std::unique_ptr<Target>(new HexagonTarget(std::move(ti)));
return std::unique_ptr<Target>();
}
|