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