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/ADT/ArrayRef.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/MC/MCObjectFileInfo.h"
21 #include "llvm/MC/SectionKind.h"
22 #include <cstdint>
23 
24 namespace llvm {
25 
26 class GlobalValue;
27 class MachineModuleInfo;
28 class Mangler;
29 class MCContext;
30 class MCExpr;
31 class MCSection;
32 class MCSymbol;
33 class MCSymbolRefExpr;
34 class MCStreamer;
35 class MCValue;
36 class TargetMachine;
37 
38 class TargetLoweringObjectFile : public MCObjectFileInfo {
39   MCContext *Ctx = nullptr;
40 
41   /// Name-mangler for global names.
42   Mangler *Mang = nullptr;
43 
44 protected:
45   bool SupportIndirectSymViaGOTPCRel = false;
46   bool SupportGOTPCRelWithOffset = true;
47   bool SupportDebugThreadLocalLocation = true;
48 
49   /// PersonalityEncoding, LSDAEncoding, TTypeEncoding - Some encoding values
50   /// for EH.
51   unsigned PersonalityEncoding = 0;
52   unsigned LSDAEncoding = 0;
53   unsigned TTypeEncoding = 0;
54   unsigned CallSiteEncoding = 0;
55 
56   /// This section contains the static constructor pointer list.
57   MCSection *StaticCtorSection = nullptr;
58 
59   /// This section contains the static destructor pointer list.
60   MCSection *StaticDtorSection = nullptr;
61 
62 public:
63   TargetLoweringObjectFile() = default;
64   TargetLoweringObjectFile(const TargetLoweringObjectFile &) = delete;
65   TargetLoweringObjectFile &
66   operator=(const TargetLoweringObjectFile &) = delete;
67   virtual ~TargetLoweringObjectFile();
68 
69   MCContext &getContext() const { return *Ctx; }
70   Mangler &getMangler() const { return *Mang; }
71 
72   /// This method must be called before any actual lowering is done.  This
73   /// specifies the current context for codegen, and gives the lowering
74   /// implementations a chance to set up their default sections.
75   virtual void Initialize(MCContext &ctx, const TargetMachine &TM);
76 
77   virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
78                                     const MCSymbol *Sym) const;
79 
80   /// Emit the module-level metadata that the platform cares about.
81   virtual void emitModuleMetadata(MCStreamer &Streamer, Module &M) const {}
82 
83   /// Get the module-level metadata that the platform cares about.
84   virtual void getModuleMetadata(Module &M) {}
85 
86   /// Given a constant with the SectionKind, return a section that it should be
87   /// placed in.
88   virtual MCSection *getSectionForConstant(const DataLayout &DL,
89                                            SectionKind Kind,
90                                            const Constant *C,
91                                            unsigned &Align) const;
92 
93   /// Classify the specified global variable into a set of target independent
94   /// categories embodied in SectionKind.
95   static SectionKind getKindForGlobal(const GlobalObject *GO,
96                                       const TargetMachine &TM);
97 
98   /// This method computes the appropriate section to emit the specified global
99   /// variable or function definition. This should not be passed external (or
100   /// available externally) globals.
101   MCSection *SectionForGlobal(const GlobalObject *GO, SectionKind Kind,
102                               const TargetMachine &TM) const;
103 
104   /// This method computes the appropriate section to emit the specified global
105   /// variable or function definition. This should not be passed external (or
106   /// available externally) globals.
107   MCSection *SectionForGlobal(const GlobalObject *GO,
108                               const TargetMachine &TM) const {
109     return SectionForGlobal(GO, getKindForGlobal(GO, TM), TM);
110   }
111 
112   virtual void getNameWithPrefix(SmallVectorImpl<char> &OutName,
113                                  const GlobalValue *GV,
114                                  const TargetMachine &TM) const;
115 
116   virtual MCSection *getSectionForJumpTable(const Function &F,
117                                             const TargetMachine &TM) const;
118 
119   virtual bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
120                                                    const Function &F) const;
121 
122   /// Targets should implement this method to assign a section to globals with
123   /// an explicit section specfied. The implementation of this method can
124   /// assume that GO->hasSection() is true.
125   virtual MCSection *
126   getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
127                            const TargetMachine &TM) const = 0;
128 
129   /// Return an MCExpr to use for a reference to the specified global variable
130   /// from exception handling information.
131   virtual const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
132                                                 unsigned Encoding,
133                                                 const TargetMachine &TM,
134                                                 MachineModuleInfo *MMI,
135                                                 MCStreamer &Streamer) const;
136 
137   /// Return the MCSymbol for a private symbol with global value name as its
138   /// base, with the specified suffix.
139   MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,
140                                          StringRef Suffix,
141                                          const TargetMachine &TM) const;
142 
143   // The symbol that gets passed to .cfi_personality.
144   virtual MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV,
145                                             const TargetMachine &TM,
146                                             MachineModuleInfo *MMI) const;
147 
148   unsigned getPersonalityEncoding() const { return PersonalityEncoding; }
149   unsigned getLSDAEncoding() const { return LSDAEncoding; }
150   unsigned getTTypeEncoding() const { return TTypeEncoding; }
151   unsigned getCallSiteEncoding() const { return CallSiteEncoding; }
152 
153   const MCExpr *getTTypeReference(const MCSymbolRefExpr *Sym, unsigned Encoding,
154                                   MCStreamer &Streamer) const;
155 
156   virtual MCSection *getStaticCtorSection(unsigned Priority,
157                                           const MCSymbol *KeySym) const {
158     return StaticCtorSection;
159   }
160 
161   virtual MCSection *getStaticDtorSection(unsigned Priority,
162                                           const MCSymbol *KeySym) const {
163     return StaticDtorSection;
164   }
165 
166   /// Create a symbol reference to describe the given TLS variable when
167   /// emitting the address in debug info.
168   virtual const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const;
169 
170   virtual const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
171                                                const GlobalValue *RHS,
172                                                const TargetMachine &TM) const {
173     return nullptr;
174   }
175 
176   /// Target supports replacing a data "PC"-relative access to a symbol
177   /// through another symbol, by accessing the later via a GOT entry instead?
178   bool supportIndirectSymViaGOTPCRel() const {
179     return SupportIndirectSymViaGOTPCRel;
180   }
181 
182   /// Target GOT "PC"-relative relocation supports encoding an additional
183   /// binary expression with an offset?
184   bool supportGOTPCRelWithOffset() const {
185     return SupportGOTPCRelWithOffset;
186   }
187 
188   /// Target supports TLS offset relocation in debug section?
189   bool supportDebugThreadLocalLocation() const {
190     return SupportDebugThreadLocalLocation;
191   }
192 
193   /// Get the target specific PC relative GOT entry relocation
194   virtual const MCExpr *getIndirectSymViaGOTPCRel(const GlobalValue *GV,
195                                                   const MCSymbol *Sym,
196                                                   const MCValue &MV,
197                                                   int64_t Offset,
198                                                   MachineModuleInfo *MMI,
199                                                   MCStreamer &Streamer) const {
200     return nullptr;
201   }
202 
203   virtual void emitLinkerFlagsForGlobal(raw_ostream &OS,
204                                         const GlobalValue *GV) const {}
205 
206   virtual void emitLinkerFlagsForUsed(raw_ostream &OS,
207                                       const GlobalValue *GV) const {}
208 
209   /// If supported, return the section to use for the llvm.commandline
210   /// metadata. Otherwise, return nullptr.
211   virtual MCSection *getSectionForCommandLines() const {
212     return nullptr;
213   }
214 
215 protected:
216   virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
217                                             SectionKind Kind,
218                                             const TargetMachine &TM) const = 0;
219 };
220 
221 } // end namespace llvm
222 
223 #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILE_H
224