1 //===-- llvm/Target/TargetLoweringObjectFile.h - Object Info ----*- C++ -*-===//
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 implements classes used to handle lowerings specific to common
10 // object file formats.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
15 #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
16 
17 #include "llvm/MC/MCObjectFileInfo.h"
18 #include "llvm/MC/MCRegister.h"
19 #include <cstdint>
20 
21 namespace llvm {
22 
23 struct Align;
24 class Constant;
25 class DataLayout;
26 class Function;
27 class GlobalObject;
28 class GlobalValue;
29 class MachineBasicBlock;
30 class MachineModuleInfo;
31 class Mangler;
32 class MCContext;
33 class MCExpr;
34 class MCSection;
35 class MCSymbol;
36 class MCSymbolRefExpr;
37 class MCStreamer;
38 class MCValue;
39 class Module;
40 class SectionKind;
41 class StringRef;
42 class TargetMachine;
43 class DSOLocalEquivalent;
44 
45 class TargetLoweringObjectFile : public MCObjectFileInfo {
46   /// Name-mangler for global names.
47   Mangler *Mang = nullptr;
48 
49 protected:
50   bool SupportIndirectSymViaGOTPCRel = false;
51   bool SupportGOTPCRelWithOffset = true;
52   bool SupportDebugThreadLocalLocation = true;
53   bool SupportDSOLocalEquivalentLowering = false;
54 
55   /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
56   /// for EH.
57   unsigned PersonalityEncoding = 0;
58   unsigned LSDAEncoding = 0;
59   unsigned TTypeEncoding = 0;
60   unsigned CallSiteEncoding = 0;
61 
62   /// This section contains the static constructor pointer list.
63   MCSection *StaticCtorSection = nullptr;
64 
65   /// This section contains the static destructor pointer list.
66   MCSection *StaticDtorSection = nullptr;
67 
68   const TargetMachine *TM = nullptr;
69 
70 public:
71   TargetLoweringObjectFile() = default;
72   TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
73   TargetLoweringObjectFile &
74   operator=(const TargetLoweringObjectFile &) = delete;
75   virtual ~TargetLoweringObjectFile();
76 
77   Mangler &getMangler() const { return *Mang; }
78 
79   /// This method must be called before any actual lowering is done.  This
80   /// specifies the current context for codegen, and gives the lowering
81   /// implementations a chance to set up their default sections.
82   virtual void Initialize(MCContext &ctx, const TargetMachine &TM);
83 
84   virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
85                                     const MCSymbol *Sym) const;
86 
87   /// Emit the module-level metadata that the platform cares about.
88   virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {}
89 
90   /// Emit Call Graph Profile metadata.
91   void emitCGProfileMetadata(MCStreamer &Streamer, Module &M) const;
92 
93   /// Get the module-level metadata that the platform cares about.
94   virtual void getModuleMetadata(Module &M) {}
95 
96   /// Given a constant with the SectionKind, return a section that it should be
97   /// placed in.
98   virtual MCSection *getSectionForConstant(const DataLayout &DL,
99                                            SectionKind Kind, const Constant *C,
100                                            Align &Alignment) const;
101 
102   virtual MCSection *
103   getSectionForMachineBasicBlock(const Function &F,
104                                  const MachineBasicBlock &MBB,
105                                  const TargetMachine &TM) const;
106 
107   virtual MCSection *
108   getUniqueSectionForFunction(const Function &F,
109                               const TargetMachine &TM) const;
110 
111   /// Classify the specified global variable into a set of target independent
112   /// categories embodied in SectionKind.
113   static SectionKind getKindForGlobal(const GlobalObject *GO,
114                                       const TargetMachine &TM);
115 
116   /// This method computes the appropriate section to emit the specified global
117   /// variable or function definition. This should not be passed external (or
118   /// available externally) globals.
119   MCSection *SectionForGlobal(const GlobalObject *GO, SectionKind Kind,
120                               const TargetMachine &TM) const;
121 
122   /// This method computes the appropriate section to emit the specified global
123   /// variable or function definition. This should not be passed external (or
124   /// available externally) globals.
125   MCSection *SectionForGlobal(const GlobalObject *GO,
126                               const TargetMachine &TM) const;
127 
128   virtual void getNameWithPrefix(SmallVectorImpl<char> &OutName,
129                                  const GlobalValue *GV,
130                                  const TargetMachine &TM) const;
131 
132   virtual MCSection *getSectionForJumpTable(const Function &F,
133                                             const TargetMachine &TM) const;
134   virtual MCSection *getSectionForLSDA(const Function &, const MCSymbol &,
135                                        const TargetMachine &) const {
136     return LSDASection;
137   }
138 
139   virtual bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
140                                                    const Function &F) const;
141 
142   /// Targets should implement this method to assign a section to globals with
143   /// an explicit section specfied. The implementation of this method can
144   /// assume that GO->hasSection() is true.
145   virtual MCSection *
146   getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
147                            const TargetMachine &TM) const = 0;
148 
149   /// Return an MCExpr to use for a reference to the specified global variable
150   /// from exception handling information.
151   virtual const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
152                                                 unsigned Encoding,
153                                                 const TargetMachine &TM,
154                                                 MachineModuleInfo *MMI,
155                                                 MCStreamer &Streamer) const;
156 
157   /// Return the MCSymbol for a private symbol with global value name as its
158   /// base, with the specified suffix.
159   MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
160                                          StringRef Suffix,
161                                          const TargetMachine &TM) const;
162 
163   // The symbol that gets passed to .cfi_personality.
164   virtual MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
165                                             const TargetMachine &TM,
166                                             MachineModuleInfo *MMI) const;
167 
168   unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
169   unsigned getLSDAEncoding() const { return LSDAEncoding; }
170   unsigned getTTypeEncoding() const { return TTypeEncoding; }
171   unsigned getCallSiteEncoding() const;
172 
173   const MCExpr *getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
174                                   MCStreamer &Streamer) const;
175 
176   virtual MCSection *getStaticCtorSection(unsigned Priority,
177                                           const MCSymbol *KeySym) const {
178     return StaticCtorSection;
179   }
180 
181   virtual MCSection *getStaticDtorSection(unsigned Priority,
182                                           const MCSymbol *KeySym) const {
183     return StaticDtorSection;
184   }
185 
186   /// Create a symbol reference to describe the given TLS variable when
187   /// emitting the address in debug info.
188   virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
189 
190   virtual const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
191                                                const GlobalValue *RHS,
192                                                const TargetMachine &TM) const {
193     return nullptr;
194   }
195 
196   /// Target supports a native lowering of a dso_local_equivalent constant
197   /// without needing to replace it with equivalent IR.
198   bool supportDSOLocalEquivalentLowering() const {
199     return SupportDSOLocalEquivalentLowering;
200   }
201 
202   virtual const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
203                                                 const TargetMachine &TM) const {
204     return nullptr;
205   }
206 
207   /// Target supports replacing a data "PC"-relative access to a symbol
208   /// through another symbol, by accessing the later via a GOT entry instead?
209   bool supportIndirectSymViaGOTPCRel() const {
210     return SupportIndirectSymViaGOTPCRel;
211   }
212 
213   /// Target GOT "PC"-relative relocation supports encoding an additional
214   /// binary expression with an offset?
215   bool supportGOTPCRelWithOffset() const {
216     return SupportGOTPCRelWithOffset;
217   }
218 
219   /// Target supports TLS offset relocation in debug section?
220   bool supportDebugThreadLocalLocation() const {
221     return SupportDebugThreadLocalLocation;
222   }
223 
224   /// Returns the register used as static base in RWPI variants.
225   virtual MCRegister getStaticBase() const { return MCRegister::NoRegister; }
226 
227   /// Get the target specific RWPI relocation.
228   virtual const MCExpr *getIndirectSymViaRWPI(const MCSymbol *Sym) const {
229     return nullptr;
230   }
231 
232   /// Get the target specific PC relative GOT entry relocation
233   virtual const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
234                                                   const MCSymbol *Sym,
235                                                   const MCValue &MV,
236                                                   int64_t Offset,
237                                                   MachineModuleInfo *MMI,
238                                                   MCStreamer &Streamer) const {
239     return nullptr;
240   }
241 
242   /// If supported, return the section to use for the llvm.commandline
243   /// metadata. Otherwise, return nullptr.
244   virtual MCSection *getSectionForCommandLines() const {
245     return nullptr;
246   }
247 
248   /// On targets that use separate function descriptor symbols, return a section
249   /// for the descriptor given its symbol. Use only with defined functions.
250   virtual MCSection *
251   getSectionForFunctionDescriptor(const Function *F,
252                                   const TargetMachine &TM) const {
253     return nullptr;
254   }
255 
256   /// On targets that support TOC entries, return a section for the entry given
257   /// the symbol it refers to.
258   /// TODO: Implement this interface for existing ELF targets.
259   virtual MCSection *getSectionForTOCEntry(const MCSymbol *S,
260                                            const TargetMachine &TM) const {
261     return nullptr;
262   }
263 
264   /// On targets that associate external references with a section, return such
265   /// a section for the given external global.
266   virtual MCSection *
267   getSectionForExternalReference(const GlobalObject *GO,
268                                  const TargetMachine &TM) const {
269     return nullptr;
270   }
271 
272   /// Targets that have a special convention for their symbols could use
273   /// this hook to return a specialized symbol.
274   virtual MCSymbol *getTargetSymbol(const GlobalValue *GV,
275                                     const TargetMachine &TM) const {
276     return nullptr;
277   }
278 
279   /// If supported, return the function entry point symbol.
280   /// Otherwise, returns nullptr.
281   /// Func must be a function or an alias which has a function as base object.
282   virtual MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
283                                                 const TargetMachine &TM) const {
284     return nullptr;
285   }
286 
287 protected:
288   virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
289                                             SectionKind Kind,
290                                             const TargetMachine &TM) const = 0;
291 };
292 
293 } // end namespace llvm
294 
295 #endif // LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
296