LLVM 24.0.0git
RISCVTargetObjectFile.cpp
Go to the documentation of this file.
1//===-- RISCVTargetObjectFile.cpp - RISC-V Object Info --------------------===//
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
11#include "RISCVTargetMachine.h"
13#include "llvm/IR/Mangler.h"
14#include "llvm/IR/Module.h"
15#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCValue.h"
18
19using namespace llvm;
20
25
27 const TargetMachine &TM,
28 const Module &M) {
30
31 PLTPCRelativeSpecifier = ELF::R_RISCV_PLT32;
33
34 SmallDataSection = getContext().getELFSection(
36 SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
38 SmallRODataSection =
40 SmallROData4Section = getContext().getELFSection(
41 ".srodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
42 SmallROData8Section = getContext().getELFSection(
43 ".srodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
44 SmallROData16Section = getContext().getELFSection(
45 ".srodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
46 SmallROData32Section = getContext().getELFSection(
47 ".srodata.cst32", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
48
50 M.getModuleFlagsMetadata(ModuleFlags);
51
52 for (const auto &MFE : ModuleFlags) {
53 StringRef Key = MFE.Key->getString();
54 if (Key == "SmallDataLimit") {
55 SSThreshold = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
56 break;
57 }
58 }
59}
60
62 const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
63 int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
64 auto &Ctx = getContext();
65 const MCExpr *Res = MCSymbolRefExpr::create(Sym, Ctx);
67 Res, MCConstantExpr::create(Offset + MV.getConstant(), Ctx), Ctx);
68 return MCSpecifierExpr::create(Res, ELF::R_RISCV_GOT32_PCREL, Ctx);
69}
70
72 bool UsesLabelDifference, const Function &F) const {
73 // With the large code model, keep the jump table in the function's section.
74 if (TM->getCodeModel() == CodeModel::Large)
75 return true;
77 UsesLabelDifference, F);
78}
79
80// A address must be loaded from a small section if its size is less than the
81// small section size threshold. Data in this section could be addressed by
82// using gp_rel operator.
84 // gcc has traditionally not treated zero-sized objects as small data, so this
85 // is effectively part of the ABI.
86 return Size > 0 && Size <= SSThreshold;
87}
88
89// Return true if this global address should be placed into small data/bss
90// section.
92 const GlobalObject *GO, const TargetMachine &TM) const {
93 // Only global variables, not functions.
95 if (!GVA)
96 return false;
97
98 // If the variable has an explicit section, it is placed in that section.
99 if (GVA->hasSection()) {
100 StringRef Section = GVA->getSection();
101
102 // Explicitly placing any variable in the small data section overrides
103 // the global -G value.
104 if (Section == ".sdata" || Section == ".sbss")
105 return true;
106
107 // Otherwise reject putting the variable to small section if it has an
108 // explicit section name.
109 return false;
110 }
111
112 if (((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
113 GVA->hasCommonLinkage()))
114 return false;
115
116 Type *Ty = GVA->getValueType();
117 // It is possible that the type of the global is unsized, i.e. a declaration
118 // of a extern struct. In this case don't presume it is in the small data
119 // section. This happens e.g. when building the FreeBSD kernel.
120 if (!Ty->isSized())
121 return false;
122
123 return isInSmallSection(
125}
126
128 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
129 // Handle Small Section classification here.
130 if (isGlobalInSmallSection(GO, TM)) {
131 // Emit to an unique sdata/sbss section when -fdata-section is set.
132 // However, if a symbol has an explicit sdata/sbss section, place it in that
133 // section.
134 bool EmitUniquedSection = TM.getDataSections() && !GO->hasSection();
135
136 if (Kind.isBSS()) {
137 if (EmitUniquedSection) {
138 SmallString<128> Name(".sbss.");
139 Name.append(GO->getName());
140 return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
142 }
143
144 return SmallBSSSection;
145 }
146
147 if (Kind.isData()) {
148 if (EmitUniquedSection) {
149 SmallString<128> Name(".sdata.");
150 Name.append(GO->getName());
151 return getContext().getELFSection(Name.str(), ELF::SHT_PROGBITS,
153 }
154
155 return SmallDataSection;
156 }
157 }
158
159 // Otherwise, we work the same as ELF.
161}
162
163/// Return true if this constant should be placed into small data section.
165 const DataLayout &DL, const Constant *CN) const {
166 return isInSmallSection(DL.getTypeAllocSize(CN->getType()));
167}
168
170 const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment,
171 const Function *F) const {
172
173 // The large code model has to put constant pools close to the program, so we
174 // put them in the .text section. Large code model doesn't support PIC, so
175 // there should be no dynamic relocations that would require `.data.rel.ro`
176 // (which could be too far away anyway).
177 if (TM->getCodeModel() == CodeModel::Large) {
178 if (F)
180 else
181 return TextSection;
182 }
183
184 if (C && isConstantInSmallSection(DL, C)) {
185 if (Kind.isMergeableConst4())
186 return SmallROData4Section;
187 if (Kind.isMergeableConst8())
188 return SmallROData8Section;
189 if (Kind.isMergeableConst16())
190 return SmallROData16Section;
191 if (Kind.isMergeableConst32())
192 return SmallROData32Section;
193 // LLVM only generate up to .rodata.cst32, and use .rodata section if more
194 // than 32 bytes, so just use .srodata here.
195 return SmallRODataSection;
196 }
197
198 // Otherwise, we work the same as ELF.
200 Alignment, F);
201}
202
204 SmallVectorImpl<char> &OutName, const GlobalValue *GV,
205 const TargetMachine &TM) const {
206 // RISC-V does not use section-relative relocations so any global symbol must
207 // be accessed via at least a linker-private symbol.
208 getMangler().getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/true);
209}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
std::unique_ptr< MCStreamer > && Streamer
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
StringRef getSection() const
Get the custom section of this global if it has one.
bool hasSection() const
Check if this global has a custom object file section.
bool hasExternalLinkage() const
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:205
bool hasCommonLinkage() const
Type * getValueType() const
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition MCContext.h:550
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
MCSection * TextSection
Section directive for standard text.
MCContext & getContext() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:580
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Streaming machine code generation interface.
Definition MCStreamer.h:222
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
int64_t getConstant() const
Definition MCValue.h:44
This class contains meta information specific to a module.
LLVM_ABI void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition Mangler.cpp:121
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
MCSection * getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment, const Function *F) const override
Given a constant with the SectionKind, return a section that it should be placed in.
void initialize(MCContext &Ctx, const TargetMachine &TM, const Module &M) override
This method must be called before any actual lowering is done.
bool isGlobalInSmallSection(const GlobalObject *GO, const TargetMachine &TM) const
Return true if this global address should be placed into small data/bss section.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
bool isInSmallSection(uint64_t Size) const
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, const Function &F) const override
unsigned getTextSectionAlignment() const override
bool isConstantInSmallSection(const DataLayout &DL, const Constant *CN) const
Return true if this constant should be placed into small data section.
const MCExpr * getIndirectSymViaGOTPCRel(const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const override
Get the target specific PC relative GOT entry relocation.
unsigned getTextSectionAlignment() const override
void getNameWithPrefix(SmallVectorImpl< char > &OutName, const GlobalValue *GV, const TargetMachine &TM) const override
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition SectionKind.h:22
static SectionKind getText()
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
MCSection * getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment, const Function *F) const override
Given a constant with the SectionKind, return a section that it should be placed in.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
void initialize(MCContext &Ctx, const TargetMachine &TM, const Module &M) override
This method must be called before any actual lowering is done.
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, const Function &F) const override
MCSection * SectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const
This method computes the appropriate section to emit the specified global variable or function defini...
Primary interface to the complete machine description for the target machine.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
@ SHF_MERGE
Definition ELF.h:1265
@ SHF_ALLOC
Definition ELF.h:1259
@ SHF_WRITE
Definition ELF.h:1256
@ SHT_PROGBITS
Definition ELF.h:1157
@ SHT_NOBITS
Definition ELF.h:1164
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:679
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39