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 
161 class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
162   mutable unsigned NextUniqueID = 0;
163   const TargetMachine *TM = nullptr;
164 
165 public:
166   ~TargetLoweringObjectFileCOFF() override = default;
167 
168   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
169   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
170                                       const TargetMachine &TM) const override;
171 
172   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
173                                     const TargetMachine &TM) const override;
174 
175   void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
176                          const TargetMachine &TM) const override;
177 
178   MCSection *getSectionForJumpTable(const Function &F,
179                                     const TargetMachine &TM) const override;
180 
181   /// Emit Obj-C garbage collection and linker options.
182   void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override;
183 
184   MCSection *getStaticCtorSection(unsigned Priority,
185                                   const MCSymbol *KeySym) const override;
186   MCSection *getStaticDtorSection(unsigned Priority,
187                                   const MCSymbol *KeySym) const override;
188 
189   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
190                                        const GlobalValue *RHS,
191                                        const TargetMachine &TM) const override;
192 
193   /// Given a mergeable constant with the specified size and relocation
194   /// information, return a section that it should be placed in.
195   MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
196                                    const Constant *C,
197                                    Align &Alignment) const override;
198 
199 private:
200   void emitLinkerDirectives(MCStreamer &Streamer, Module &M) const;
201 };
202 
203 class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
204   mutable unsigned NextUniqueID = 0;
205 
206 public:
207   TargetLoweringObjectFileWasm() = default;
208   ~TargetLoweringObjectFileWasm() override = default;
209 
210   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
211                                       const TargetMachine &TM) const override;
212 
213   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
214                                     const TargetMachine &TM) const override;
215 
216   bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
217                                            const Function &F) const override;
218 
219   void InitializeWasm();
220   MCSection *getStaticCtorSection(unsigned Priority,
221                                   const MCSymbol *KeySym) const override;
222   MCSection *getStaticDtorSection(unsigned Priority,
223                                   const MCSymbol *KeySym) const override;
224 
225   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
226                                        const GlobalValue *RHS,
227                                        const TargetMachine &TM) const override;
228 };
229 
230 class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
231 public:
232   TargetLoweringObjectFileXCOFF() = default;
233   ~TargetLoweringObjectFileXCOFF() override = default;
234 
235   static bool ShouldEmitEHBlock(const MachineFunction *MF);
236   static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF);
237 
238   static MCSymbol *getEHInfoTableSymbol(const MachineFunction *MF);
239 
240   void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
241 
242   bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
243                                            const Function &F) const override;
244 
245   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
246                                       const TargetMachine &TM) const override;
247 
248   MCSection *getStaticCtorSection(unsigned Priority,
249                                   const MCSymbol *KeySym) const override;
250   MCSection *getStaticDtorSection(unsigned Priority,
251                                   const MCSymbol *KeySym) const override;
252 
253   const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
254                                        const GlobalValue *RHS,
255                                        const TargetMachine &TM) const override;
256 
257   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
258                                     const TargetMachine &TM) const override;
259 
260   MCSection *getSectionForJumpTable(const Function &F,
261                                     const TargetMachine &TM) const override;
262 
263   /// Given a constant with the SectionKind, return a section that it should be
264   /// placed in.
265   MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
266                                    const Constant *C,
267                                    Align &Alignment) const override;
268 
269   static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV);
270 
271   MCSection *
272   getSectionForFunctionDescriptor(const Function *F,
273                                   const TargetMachine &TM) const override;
274   MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
275                                    const TargetMachine &TM) const override;
276 
277   /// For external functions, this will always return a function descriptor
278   /// csect.
279   MCSection *
280   getSectionForExternalReference(const GlobalObject *GO,
281                                  const TargetMachine &TM) const override;
282 
283   /// For functions, this will always return a function descriptor symbol.
284   MCSymbol *getTargetSymbol(const GlobalValue *GV,
285                             const TargetMachine &TM) const override;
286 
287   MCSymbol *getFunctionEntryPointSymbol(const GlobalValue *Func,
288                                         const TargetMachine &TM) const override;
289 
290   /// For functions, this will return the LSDA section. If option
291   /// -ffunction-sections is on, this will return a unique csect with the
292   /// function name appended to .gcc_except_table as a suffix of the LSDA
293   /// section name.
294   MCSection *getSectionForLSDA(const Function &F, const MCSymbol &FnSym,
295                                const TargetMachine &TM) const override;
296 };
297 
298 class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
299 public:
300   TargetLoweringObjectFileGOFF();
301   ~TargetLoweringObjectFileGOFF() override = default;
302 
303   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
304                                     const TargetMachine &TM) const override;
305   MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
306                                       const TargetMachine &TM) const override;
307 };
308 
309 } // end namespace llvm
310 
311 #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
312