Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
35294 views
1
//===-- RISCVELFStreamer.cpp - RISC-V ELF Target Streamer Methods ---------===//
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 RISC-V specific target streamer methods.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "RISCVELFStreamer.h"
14
#include "RISCVAsmBackend.h"
15
#include "RISCVBaseInfo.h"
16
#include "RISCVMCTargetDesc.h"
17
#include "llvm/BinaryFormat/ELF.h"
18
#include "llvm/MC/MCAsmBackend.h"
19
#include "llvm/MC/MCAssembler.h"
20
#include "llvm/MC/MCCodeEmitter.h"
21
#include "llvm/MC/MCContext.h"
22
#include "llvm/MC/MCObjectWriter.h"
23
#include "llvm/MC/MCSectionELF.h"
24
#include "llvm/MC/MCSubtargetInfo.h"
25
#include "llvm/MC/MCValue.h"
26
#include "llvm/Support/LEB128.h"
27
#include "llvm/Support/RISCVAttributes.h"
28
29
using namespace llvm;
30
31
// This part is for ELF object output.
32
RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
33
const MCSubtargetInfo &STI)
34
: RISCVTargetStreamer(S), CurrentVendor("riscv") {
35
MCAssembler &MCA = getStreamer().getAssembler();
36
const FeatureBitset &Features = STI.getFeatureBits();
37
auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
38
setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
39
MAB.getTargetOptions().getABIName()));
40
setFlagsFromFeatures(STI);
41
// `j label` in `.option norelax; j label; .option relax; ...; label:` needs a
42
// relocation to ensure the jump target is correct after linking. This is due
43
// to a limitation that shouldForceRelocation has to make the decision upfront
44
// without knowing a possibly future .option relax. When RISCVAsmParser is used,
45
// its ParseInstruction may call setForceRelocs as well.
46
if (STI.hasFeature(RISCV::FeatureRelax))
47
static_cast<RISCVAsmBackend &>(MAB).setForceRelocs();
48
}
49
50
RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {
51
return static_cast<RISCVELFStreamer &>(Streamer);
52
}
53
54
void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
55
void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
56
void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
57
void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
58
void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
59
void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
60
void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
61
void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
62
63
void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
64
getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
65
}
66
67
void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
68
StringRef String) {
69
getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
70
}
71
72
void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
73
unsigned IntValue,
74
StringRef StringValue) {
75
getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
76
/*OverwriteExisting=*/true);
77
}
78
79
void RISCVTargetELFStreamer::finishAttributeSection() {
80
RISCVELFStreamer &S = getStreamer();
81
if (S.Contents.empty())
82
return;
83
84
S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
85
ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
86
}
87
88
void RISCVTargetELFStreamer::finish() {
89
RISCVTargetStreamer::finish();
90
ELFObjectWriter &W = getStreamer().getWriter();
91
RISCVABI::ABI ABI = getTargetABI();
92
93
unsigned EFlags = W.getELFHeaderEFlags();
94
95
if (hasRVC())
96
EFlags |= ELF::EF_RISCV_RVC;
97
if (hasTSO())
98
EFlags |= ELF::EF_RISCV_TSO;
99
100
switch (ABI) {
101
case RISCVABI::ABI_ILP32:
102
case RISCVABI::ABI_LP64:
103
break;
104
case RISCVABI::ABI_ILP32F:
105
case RISCVABI::ABI_LP64F:
106
EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
107
break;
108
case RISCVABI::ABI_ILP32D:
109
case RISCVABI::ABI_LP64D:
110
EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
111
break;
112
case RISCVABI::ABI_ILP32E:
113
case RISCVABI::ABI_LP64E:
114
EFlags |= ELF::EF_RISCV_RVE;
115
break;
116
case RISCVABI::ABI_Unknown:
117
llvm_unreachable("Improperly initialised target ABI");
118
}
119
120
W.setELFHeaderEFlags(EFlags);
121
}
122
123
void RISCVTargetELFStreamer::reset() {
124
AttributeSection = nullptr;
125
}
126
127
void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
128
getStreamer().getAssembler().registerSymbol(Symbol);
129
cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);
130
}
131
132
void RISCVELFStreamer::reset() {
133
static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
134
MCELFStreamer::reset();
135
LastMappingSymbols.clear();
136
LastEMS = EMS_None;
137
}
138
139
void RISCVELFStreamer::emitDataMappingSymbol() {
140
if (LastEMS == EMS_Data)
141
return;
142
emitMappingSymbol("$d");
143
LastEMS = EMS_Data;
144
}
145
146
void RISCVELFStreamer::emitInstructionsMappingSymbol() {
147
if (LastEMS == EMS_Instructions)
148
return;
149
emitMappingSymbol("$x");
150
LastEMS = EMS_Instructions;
151
}
152
153
void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
154
auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
155
emitLabel(Symbol);
156
Symbol->setType(ELF::STT_NOTYPE);
157
Symbol->setBinding(ELF::STB_LOCAL);
158
}
159
160
void RISCVELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
161
// We have to keep track of the mapping symbol state of any sections we
162
// use. Each one should start off as EMS_None, which is provided as the
163
// default constructor by DenseMap::lookup.
164
LastMappingSymbols[getPreviousSection().first] = LastEMS;
165
LastEMS = LastMappingSymbols.lookup(Section);
166
167
MCELFStreamer::changeSection(Section, Subsection);
168
}
169
170
void RISCVELFStreamer::emitInstruction(const MCInst &Inst,
171
const MCSubtargetInfo &STI) {
172
emitInstructionsMappingSymbol();
173
MCELFStreamer::emitInstruction(Inst, STI);
174
}
175
176
void RISCVELFStreamer::emitBytes(StringRef Data) {
177
emitDataMappingSymbol();
178
MCELFStreamer::emitBytes(Data);
179
}
180
181
void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
182
SMLoc Loc) {
183
emitDataMappingSymbol();
184
MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
185
}
186
187
void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
188
SMLoc Loc) {
189
emitDataMappingSymbol();
190
MCELFStreamer::emitValueImpl(Value, Size, Loc);
191
}
192
193
namespace llvm {
194
MCELFStreamer *createRISCVELFStreamer(MCContext &C,
195
std::unique_ptr<MCAsmBackend> MAB,
196
std::unique_ptr<MCObjectWriter> MOW,
197
std::unique_ptr<MCCodeEmitter> MCE) {
198
RISCVELFStreamer *S =
199
new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));
200
return S;
201
}
202
} // namespace llvm
203
204