1 //==- llvm/CodeGen/TargetLoweringObjectFileImpl.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_TARGETLOWERINGOBJECTFILEIMPL_H
15 #define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
16 
17 #include "llvm/ADT/SmallPtrSet.h"
18 #include "llvm/BinaryFormat/XCOFF.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/Target/TargetLoweringObjectFile.h"
21 
22 namespace llvm {
23 
24 class GlobalValue;
25 class MachineModuleInfo;
26 class MachineFunction;
27 class MCContext;
28 class MCExpr;
29 class MCSection;
30 class MCSymbol;
31 class Module;
32 class TargetMachine;
33 
34 class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
35   bool UseInitArray = false;
36   mutable unsigned NextUniqueID = 1;  // ID 0 is reserved for execute-only sections
37   SmallPtrSet<GlobalObject *, 2> Used;
38 
39 protected:
40   MCSymbolRefExpr::VariantKind PLTRelativeVariantKind =
41       MCSymbolRefExpr::VK_None;
42 
43 public:
44   TargetLoweringObjectFileELF();
45   ~TargetLoweringObjectFileELF() override = default;
46 
47   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
48 
49   void getModuleMetadata(Module &M) override;
50 
51   /// Emit Obj-C garbage collection and linker options.
52   void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
53 
54   void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &DL,
55                             const MCSymbol *Sym) const override;
56 
57   /// Given a constant with the SectionKind, return a section that it should be
58   /// placed in.
59   MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
60                                    const Constant *C,
61                                    Align &Alignment) const override;
62 
63   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
64                                       const TargetMachine &TM) const override;
65 
66   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
67                                     const TargetMachine &TM) const override;
68 
69   MCSection *getSectionForJumpTable(const Function &F,
70                                     const TargetMachine &TM) const override;
71   MCSection *getSectionForLSDA(const Function &F, const MCSymbol &FnSym,
72                                const TargetMachine &TM) const override;
73 
74   MCSection *
75   getSectionForMachineBasicBlock(const Function &F,
76                                  const MachineBasicBlock &MBB,
77                                  const TargetMachine &TM) const override;
78 
79   MCSection *
80   getUniqueSectionForFunction(const Function &F,
81                               const TargetMachine &TM) const override;
82 
83   bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
84                                            const Function &F) const override;
85 
86   /// Return an MCExpr to use for a reference to the specified type info global
87   /// variable from exception handling information.
88   const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
89                                         unsigned Encoding,
90                                         const TargetMachine &TM,
91                                         MachineModuleInfo *MMI,
92                                         MCStreamer &Streamer) const override;
93 
94   // The symbol that gets passed to .cfi_personality.
95   MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
96                                     const TargetMachine &TM,
97                                     MachineModuleInfo *MMI) const override;
98 
99   void InitializeELF(bool UseInitArray_);
100   MCSection *getStaticCtorSection(unsigned Priority,
101                                   const MCSymbol *KeySym) const override;
102   MCSection *getStaticDtorSection(unsigned Priority,
103                                   const MCSymbol *KeySym) const override;
104 
105   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
106                                        const GlobalValue *RHS,
107                                        const TargetMachine &TM) const override;
108 
109   const MCExpr *lowerDSOLocalEquivalent(const DSOLocalEquivalent *Equiv,
110                                         const TargetMachine &TM) const override;
111 
112   MCSection *getSectionForCommandLines() const override;
113 };
114 
115 class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
116 public:
117   TargetLoweringObjectFileMachO();
118   ~TargetLoweringObjectFileMachO() override = default;
119 
120   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
121 
122   MCSection *getStaticDtorSection(unsigned Priority,
123                                   const MCSymbol *KeySym) const override;
124 
125   /// Emit the module flags that specify the garbage collection information.
126   void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
127 
128   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
129                                     const TargetMachine &TM) const override;
130 
131   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
132                                       const TargetMachine &TM) const override;
133 
134   MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
135                                    const Constant *C,
136                                    Align &Alignment) const override;
137 
138   /// The mach-o version of this method defaults to returning a stub reference.
139   const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
140                                         unsigned Encoding,
141                                         const TargetMachine &TM,
142                                         MachineModuleInfo *MMI,
143                                         MCStreamer &Streamer) const override;
144 
145   // The symbol that gets passed to .cfi_personality.
146   MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
147                                     const TargetMachine &TM,
148                                     MachineModuleInfo *MMI) const override;
149 
150   /// Get MachO PC relative GOT entry relocation
151   const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
152                                           const MCSymbol *Sym,
153                                           const MCValue &MV, int64_t Offset,
154                                           MachineModuleInfo *MMI,
155                                           MCStreamer &Streamer) const override;
156 
157   void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
158                          const TargetMachine &TM) const override;
159 
160   MCSection *getSectionForCommandLines() const override;
161 };
162 
163 class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
164   mutable unsigned NextUniqueID = 0;
165   const TargetMachine *TM = nullptr;
166 
167 public:
168   ~TargetLoweringObjectFileCOFF() override = default;
169 
170   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
171   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
172                                       const TargetMachine &TM) const override;
173 
174   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
175                                     const TargetMachine &TM) const override;
176 
177   void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
178                          const TargetMachine &TM) const override;
179 
180   MCSection *getSectionForJumpTable(const Function &F,
181                                     const TargetMachine &TM) const override;
182 
183   bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
184                                            const Function &F) const override;
185 
186   /// Emit Obj-C garbage collection and linker options.
187   void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
188 
189   MCSection *getStaticCtorSection(unsigned Priority,
190                                   const MCSymbol *KeySym) const override;
191   MCSection *getStaticDtorSection(unsigned Priority,
192                                   const MCSymbol *KeySym) const override;
193 
194   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
195                                        const GlobalValue *RHS,
196                                        const TargetMachine &TM) const override;
197 
198   /// Given a mergeable constant with the specified size and relocation
199   /// information, return a section that it should be placed in.
200   MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
201                                    const Constant *C,
202                                    Align &Alignment) const override;
203 
204 private:
205   void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const;
206 };
207 
208 class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
209   mutable unsigned NextUniqueID = 0;
210 
211 public:
212   TargetLoweringObjectFileWasm() = default;
213   ~TargetLoweringObjectFileWasm() override = default;
214 
215   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
216                                       const TargetMachine &TM) const override;
217 
218   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
219                                     const TargetMachine &TM) const override;
220 
221   bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
222                                            const Function &F) const override;
223 
224   void InitializeWasm();
225   MCSection *getStaticCtorSection(unsigned Priority,
226                                   const MCSymbol *KeySym) const override;
227   MCSection *getStaticDtorSection(unsigned Priority,
228                                   const MCSymbol *KeySym) const override;
229 
230   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
231                                        const GlobalValue *RHS,
232                                        const TargetMachine &TM) const override;
233 };
234 
235 class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
236 public:
237   TargetLoweringObjectFileXCOFF() = default;
238   ~TargetLoweringObjectFileXCOFF() override = default;
239 
240   static bool ShouldEmitEHBlock(const MachineFunction *MF);
241   static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF);
242 
243   static MCSymbol *getEHInfoTableSymbol(const MachineFunction *MF);
244 
245   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
246 
247   bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
248                                            const Function &F) const override;
249 
250   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
251                                       const TargetMachine &TM) const override;
252 
253   MCSection *getStaticCtorSection(unsigned Priority,
254                                   const MCSymbol *KeySym) const override;
255   MCSection *getStaticDtorSection(unsigned Priority,
256                                   const MCSymbol *KeySym) const override;
257 
258   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
259                                        const GlobalValue *RHS,
260                                        const TargetMachine &TM) const override;
261 
262   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
263                                     const TargetMachine &TM) const override;
264 
265   MCSection *getSectionForJumpTable(const Function &F,
266                                     const TargetMachine &TM) const override;
267 
268   /// Given a constant with the SectionKind, return a section that it should be
269   /// placed in.
270   MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
271                                    const Constant *C,
272                                    Align &Alignment) const override;
273 
274   static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV);
275 
276   MCSection *
277   getSectionForFunctionDescriptor(const Function *F,
278                                   const TargetMachine &TM) const override;
279   MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
280                                    const TargetMachine &TM) const override;
281 
282   /// For external functions, this will always return a function descriptor
283   /// csect.
284   MCSection *
285   getSectionForExternalReference(const GlobalObject *GO,
286                                  const TargetMachine &TM) const override;
287 
288   /// For functions, this will always return a function descriptor symbol.
289   MCSymbol *getTargetSymbol(const GlobalValue *GV,
290                             const TargetMachine &TM) const override;
291 
292   MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
293                                         const TargetMachine &TM) const override;
294 
295   /// For functions, this will return the LSDA section. If option
296   /// -ffunction-sections is on, this will return a unique csect with the
297   /// function name appended to .gcc_except_table as a suffix of the LSDA
298   /// section name.
299   MCSection *getSectionForLSDA(const Function &F, const MCSymbol &FnSym,
300                                const TargetMachine &TM) const override;
301 };
302 
303 class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
304 public:
305   TargetLoweringObjectFileGOFF();
306   ~TargetLoweringObjectFileGOFF() override = default;
307 
308   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
309                                     const TargetMachine &TM) const override;
310   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
311                                       const TargetMachine &TM) const override;
312 };
313 
314 } // end namespace llvm
315 
316 #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
317