1 //===- llvm/MC/MCObjectWriter.h - Object File Writer Interface --*- 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 #ifndef LLVM_MC_MCOBJECTWRITER_H
10 #define LLVM_MC_MCOBJECTWRITER_H
11 
12 #include "llvm/ADT/Triple.h"
13 #include <cstdint>
14 
15 namespace llvm {
16 
17 class MCAsmLayout;
18 class MCAssembler;
19 class MCFixup;
20 class MCFragment;
21 class MCSymbol;
22 class MCSymbolRefExpr;
23 class MCValue;
24 
25 /// Defines the object file and target independent interfaces used by the
26 /// assembler backend to write native file format object files.
27 ///
28 /// The object writer contains a few callbacks used by the assembler to allow
29 /// the object writer to modify the assembler data structures at appropriate
30 /// points. Once assembly is complete, the object writer is given the
31 /// MCAssembler instance, which contains all the symbol and section data which
32 /// should be emitted as part of writeObject().
33 class MCObjectWriter {
34 protected:
35   MCObjectWriter() = default;
36 
37 public:
38   MCObjectWriter(const MCObjectWriter &) = delete;
39   MCObjectWriter &operator=(const MCObjectWriter &) = delete;
40   virtual ~MCObjectWriter();
41 
42   /// lifetime management
reset()43   virtual void reset() {}
44 
45   /// \name High-Level API
46   /// @{
47 
48   /// Perform any late binding of symbols (for example, to assign symbol
49   /// indices for use when generating relocations).
50   ///
51   /// This routine is called by the assembler after layout and relaxation is
52   /// complete.
53   virtual void executePostLayoutBinding(MCAssembler &Asm,
54                                         const MCAsmLayout &Layout) = 0;
55 
56   /// Record a relocation entry.
57   ///
58   /// This routine is called by the assembler after layout and relaxation, and
59   /// post layout binding. The implementation is responsible for storing
60   /// information about the relocation so that it can be emitted during
61   /// writeObject().
62   virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
63                                 const MCFragment *Fragment,
64                                 const MCFixup &Fixup, MCValue Target,
65                                 uint64_t &FixedValue) = 0;
66 
67   /// Check whether the difference (A - B) between two symbol references is
68   /// fully resolved.
69   ///
70   /// Clients are not required to answer precisely and may conservatively return
71   /// false, even when a difference is fully resolved.
72   bool isSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
73                                           const MCSymbolRefExpr *A,
74                                           const MCSymbolRefExpr *B,
75                                           bool InSet) const;
76 
77   virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
78                                                       const MCSymbol &A,
79                                                       const MCSymbol &B,
80                                                       bool InSet) const;
81 
82   virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
83                                                       const MCSymbol &SymA,
84                                                       const MCFragment &FB,
85                                                       bool InSet,
86                                                       bool IsPCRel) const;
87 
88   /// ELF only. Mark that we have seen GNU ABI usage (e.g. SHF_GNU_RETAIN).
markGnuAbi()89   virtual void markGnuAbi() {}
90 
91   /// Tell the object writer to emit an address-significance table during
92   /// writeObject(). If this function is not called, all symbols are treated as
93   /// address-significant.
emitAddrsigSection()94   virtual void emitAddrsigSection() {}
95 
96   /// Record the given symbol in the address-significance table to be written
97   /// diring writeObject().
addAddrsigSymbol(const MCSymbol * Sym)98   virtual void addAddrsigSymbol(const MCSymbol *Sym) {}
99 
100   /// Write the object file and returns the number of bytes written.
101   ///
102   /// This routine is called by the assembler after layout and relaxation is
103   /// complete, fixups have been evaluated and applied, and relocations
104   /// generated.
105   virtual uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) = 0;
106 
107   /// @}
108 };
109 
110 /// Base class for classes that define behaviour that is specific to both the
111 /// target and the object format.
112 class MCObjectTargetWriter {
113 public:
114   virtual ~MCObjectTargetWriter() = default;
115   virtual Triple::ObjectFormatType getFormat() const = 0;
116 };
117 
118 } // end namespace llvm
119 
120 #endif // LLVM_MC_MCOBJECTWRITER_H
121