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