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) {
29
30 PLTPCRelativeSpecifier = ELF::R_RISCV_PLT32;
32
33 SmallDataSection = getContext().getELFSection(
35 SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
37 SmallRODataSection =
39 SmallROData4Section = getContext().getELFSection(
40 ".srodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 4);
41 SmallROData8Section = getContext().getELFSection(
42 ".srodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 8);
43 SmallROData16Section = getContext().getELFSection(
44 ".srodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 16);
45 SmallROData32Section = getContext().getELFSection(
46 ".srodata.cst32", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE, 32);
47}
48
50 const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
51 int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
52 auto &Ctx = getContext();
53 const MCExpr *Res = MCSymbolRefExpr::create(Sym, Ctx);
55 Res, MCConstantExpr::create(Offset + MV.getConstant(), Ctx), Ctx);
56 return MCSpecifierExpr::create(Res, ELF::R_RISCV_GOT32_PCREL, Ctx);
57}
58
60 bool UsesLabelDifference, const Function &F) const {
61 // With the large code model, keep the jump table in the function's section.
62 if (TM->getCodeModel() == CodeModel::Large)
63 return true;
65 UsesLabelDifference, F);
66}
67
68// A address must be loaded from a small section if its size is less than the
69// small section size threshold. Data in this section could be addressed by
70// using gp_rel operator.
72 // gcc has traditionally not treated zero-sized objects as small data, so this
73 // is effectively part of the ABI.
74 return Size > 0 && Size <= SSThreshold;
75}
76
77// Return true if this global address should be placed into small data/bss
78// section.
80 const GlobalObject *GO, const TargetMachine &TM) const {
81 // Only global variables, not functions.
83 if (!GVA)
84 return false;
85
86 // If the variable has an explicit section, it is placed in that section.
87 if (GVA->hasSection()) {
88 StringRef Section = GVA->getSection();
89
90 // Explicitly placing any variable in the small data section overrides
91 // the global -G value.
92 if (Section == ".sdata" || Section == ".sbss")
93 return true;
94
95 // Otherwise reject putting the variable to small section if it has an
96 // explicit section name.
97 return false;
98 }
99
100 if (((GVA->hasExternalLinkage() && GVA->isDeclaration()) ||
101 GVA->hasCommonLinkage()))
102 return false;
103
104 Type *Ty = GVA->getValueType();
105 // It is possible that the type of the global is unsized, i.e. a declaration
106 // of a extern struct. In this case don't presume it is in the small data
107 // section. This happens e.g. when building the FreeBSD kernel.
108 if (!Ty->isSized())
109 return false;
110
111 return isInSmallSection(
113}
114
116 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
117 // Handle Small Section classification here.
118 if (isGlobalInSmallSection(GO, TM)) {
119 // Emit to an unique sdata/sbss section when -fdata-section is set.
120 // However, if a symbol has an explicit sdata/sbss section, place it in that
121 // section.
122 bool EmitUniquedSection = TM.getDataSections() && !GO->hasSection();
123
124 if (Kind.isBSS()) {
125 if (EmitUniquedSection) {
126 SmallString<128> Name(".sbss.");
127 Name.append(GO->getName());
128 return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
130 }
131
132 return SmallBSSSection;
133 }
134
135 if (Kind.isData()) {
136 if (EmitUniquedSection) {
137 SmallString<128> Name(".sdata.");
138 Name.append(GO->getName());
139 return getContext().getELFSection(Name.str(), ELF::SHT_PROGBITS,
141 }
142
143 return SmallDataSection;
144 }
145 }
146
147 // Otherwise, we work the same as ELF.
149}
150
154 M.getModuleFlagsMetadata(ModuleFlags);
155
156 for (const auto &MFE : ModuleFlags) {
157 StringRef Key = MFE.Key->getString();
158 if (Key == "SmallDataLimit") {
159 SSThreshold = mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue();
160 break;
161 }
162 }
163}
164
165/// Return true if this constant should be placed into small data section.
167 const DataLayout &DL, const Constant *CN) const {
168 return isInSmallSection(DL.getTypeAllocSize(CN->getType()));
169}
170
172 const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment,
173 const Function *F) const {
174
175 // The large code model has to put constant pools close to the program, so we
176 // put them in the .text section. Large code model doesn't support PIC, so
177 // there should be no dynamic relocations that would require `.data.rel.ro`
178 // (which could be too far away anyway).
179 if (TM->getCodeModel() == CodeModel::Large) {
180 if (F)
182 else
183 return TextSection;
184 }
185
186 if (C && isConstantInSmallSection(DL, C)) {
187 if (Kind.isMergeableConst4())
188 return SmallROData4Section;
189 if (Kind.isMergeableConst8())
190 return SmallROData8Section;
191 if (Kind.isMergeableConst16())
192 return SmallROData16Section;
193 if (Kind.isMergeableConst32())
194 return SmallROData32Section;
195 // LLVM only generate up to .rodata.cst32, and use .rodata section if more
196 // than 32 bytes, so just use .srodata here.
197 return SmallRODataSection;
198 }
199
200 // Otherwise, we work the same as ELF.
202 Alignment, F);
203}
204
206 SmallVectorImpl<char> &OutName, const GlobalValue *GV,
207 const TargetMachine &TM) const {
208 // RISC-V does not use section-relative relocations so any global symbol must
209 // be accessed via at least a linker-private symbol.
210 getMangler().getNameWithPrefix(OutName, GV, /*CannotUsePrivateLabel=*/true);
211}
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.
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
void getModuleMetadata(Module &M) override
Get the module-level metadata that the platform cares about.
bool isInSmallSection(uint64_t Size) const
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, const Function &F) const override
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
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
void Initialize(MCContext &Ctx, const TargetMachine &TM) override
This method must be called before any actual lowering is done.
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 getModuleMetadata(Module &M) override
Get the module-level metadata that the platform cares about.
MCSection * SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const override
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