Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Remarks/RemarkLinker.cpp
35262 views
1
//===- RemarkLinker.cpp ---------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file provides an implementation of the remark linker.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/Remarks/RemarkLinker.h"
14
#include "llvm/ADT/StringRef.h"
15
#include "llvm/Object/ObjectFile.h"
16
#include "llvm/Object/SymbolicFile.h"
17
#include "llvm/Remarks/RemarkParser.h"
18
#include "llvm/Remarks/RemarkSerializer.h"
19
#include "llvm/Support/Error.h"
20
#include <optional>
21
22
using namespace llvm;
23
using namespace llvm::remarks;
24
25
namespace llvm {
26
class raw_ostream;
27
}
28
29
static Expected<StringRef>
30
getRemarksSectionName(const object::ObjectFile &Obj) {
31
if (Obj.isMachO())
32
return StringRef("__remarks");
33
// ELF -> .remarks, but there is no ELF support at this point.
34
return createStringError(std::errc::illegal_byte_sequence,
35
"Unsupported file format.");
36
}
37
38
Expected<std::optional<StringRef>>
39
llvm::remarks::getRemarksSectionContents(const object::ObjectFile &Obj) {
40
Expected<StringRef> SectionName = getRemarksSectionName(Obj);
41
if (!SectionName)
42
return SectionName.takeError();
43
44
for (const object::SectionRef &Section : Obj.sections()) {
45
Expected<StringRef> MaybeName = Section.getName();
46
if (!MaybeName)
47
return MaybeName.takeError();
48
if (*MaybeName != *SectionName)
49
continue;
50
51
if (Expected<StringRef> Contents = Section.getContents())
52
return *Contents;
53
else
54
return Contents.takeError();
55
}
56
return std::optional<StringRef>{};
57
}
58
59
Remark &RemarkLinker::keep(std::unique_ptr<Remark> Remark) {
60
StrTab.internalize(*Remark);
61
auto Inserted = Remarks.insert(std::move(Remark));
62
return **Inserted.first;
63
}
64
65
void RemarkLinker::setExternalFilePrependPath(StringRef PrependPathIn) {
66
PrependPath = std::string(PrependPathIn);
67
}
68
69
Error RemarkLinker::link(StringRef Buffer, std::optional<Format> RemarkFormat) {
70
if (!RemarkFormat) {
71
Expected<Format> ParserFormat = magicToFormat(Buffer);
72
if (!ParserFormat)
73
return ParserFormat.takeError();
74
RemarkFormat = *ParserFormat;
75
}
76
77
Expected<std::unique_ptr<RemarkParser>> MaybeParser =
78
createRemarkParserFromMeta(
79
*RemarkFormat, Buffer, /*StrTab=*/std::nullopt,
80
PrependPath ? std::optional<StringRef>(StringRef(*PrependPath))
81
: std::optional<StringRef>());
82
if (!MaybeParser)
83
return MaybeParser.takeError();
84
85
RemarkParser &Parser = **MaybeParser;
86
87
while (true) {
88
Expected<std::unique_ptr<Remark>> Next = Parser.next();
89
if (Error E = Next.takeError()) {
90
if (E.isA<EndOfFileError>()) {
91
consumeError(std::move(E));
92
break;
93
}
94
return E;
95
}
96
97
assert(*Next != nullptr);
98
99
if (shouldKeepRemark(**Next))
100
keep(std::move(*Next));
101
}
102
return Error::success();
103
}
104
105
Error RemarkLinker::link(const object::ObjectFile &Obj,
106
std::optional<Format> RemarkFormat) {
107
Expected<std::optional<StringRef>> SectionOrErr =
108
getRemarksSectionContents(Obj);
109
if (!SectionOrErr)
110
return SectionOrErr.takeError();
111
112
if (std::optional<StringRef> Section = *SectionOrErr)
113
return link(*Section, RemarkFormat);
114
return Error::success();
115
}
116
117
Error RemarkLinker::serialize(raw_ostream &OS, Format RemarksFormat) const {
118
Expected<std::unique_ptr<RemarkSerializer>> MaybeSerializer =
119
createRemarkSerializer(RemarksFormat, SerializerMode::Standalone, OS,
120
std::move(const_cast<StringTable &>(StrTab)));
121
if (!MaybeSerializer)
122
return MaybeSerializer.takeError();
123
124
std::unique_ptr<remarks::RemarkSerializer> Serializer =
125
std::move(*MaybeSerializer);
126
127
for (const Remark &R : remarks())
128
Serializer->emit(R);
129
return Error::success();
130
}
131
132