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