LLVM  4.0.0
MCMachObjectWriter.h
Go to the documentation of this file.
1 //===-- llvm/MC/MCMachObjectWriter.h - Mach Object Writer -------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_MC_MCMACHOBJECTWRITER_H
11 #define LLVM_MC_MCMACHOBJECTWRITER_H
12 
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/MC/MCExpr.h"
15 #include "llvm/MC/MCSection.h"
16 #include "llvm/MC/MCObjectWriter.h"
18 #include "llvm/Support/DataTypes.h"
19 #include "llvm/Support/MachO.h"
20 #include <vector>
21 
22 namespace llvm {
23 
24 class MachObjectWriter;
25 
27  const unsigned Is64Bit : 1;
28  const uint32_t CPUType;
29  const uint32_t CPUSubtype;
30  unsigned LocalDifference_RIT;
31 
32 protected:
33  MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
34  uint32_t CPUSubtype_);
35 
37  LocalDifference_RIT = Type;
38  }
39 
40 public:
41  virtual ~MCMachObjectTargetWriter();
42 
43  /// \name Lifetime Management
44  /// @{
45 
46  virtual void reset() {}
47 
48  /// @}
49 
50  /// \name Accessors
51  /// @{
52 
53  bool is64Bit() const { return Is64Bit; }
54  uint32_t getCPUType() const { return CPUType; }
55  uint32_t getCPUSubtype() const { return CPUSubtype; }
57  return LocalDifference_RIT;
58  }
59 
60  /// @}
61 
62  /// \name API
63  /// @{
64 
65  virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
66  const MCAsmLayout &Layout,
67  const MCFragment *Fragment,
68  const MCFixup &Fixup, MCValue Target,
69  uint64_t &FixedValue) = 0;
70 
71  /// @}
72 };
73 
75  /// Helper struct for containing some precomputed information on symbols.
76  struct MachSymbolData {
77  const MCSymbol *Symbol;
78  uint64_t StringIndex;
79  uint8_t SectionIndex;
80 
81  // Support lexicographic sorting.
82  bool operator<(const MachSymbolData &RHS) const;
83  };
84 
85  /// The target specific Mach-O writer instance.
86  std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
87 
88  /// \name Relocation Data
89  /// @{
90 
91  struct RelAndSymbol {
92  const MCSymbol *Sym;
94  RelAndSymbol(const MCSymbol *Sym, const MachO::any_relocation_info &MRE)
95  : Sym(Sym), MRE(MRE) {}
96  };
97 
100 
101  SectionAddrMap SectionAddress;
102 
103  /// @}
104  /// \name Symbol Table Data
105  /// @{
106 
108  std::vector<MachSymbolData> LocalSymbolData;
109  std::vector<MachSymbolData> ExternalSymbolData;
110  std::vector<MachSymbolData> UndefinedSymbolData;
111 
112  /// @}
113 
114  MachSymbolData *findSymbolData(const MCSymbol &Sym);
115 
116 public:
118  bool IsLittleEndian)
119  : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
120 
121  const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
122 
123  /// \name Lifetime management Methods
124  /// @{
125 
126  void reset() override;
127 
128  /// @}
129 
130  /// \name Utility Methods
131  /// @{
132 
133  bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
134 
135  SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
136 
137  uint64_t getSectionAddress(const MCSection *Sec) const {
138  return SectionAddress.lookup(Sec);
139  }
140  uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const;
141 
142  uint64_t getFragmentAddress(const MCFragment *Fragment,
143  const MCAsmLayout &Layout) const;
144 
145  uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const;
146 
148 
149  /// @}
150 
151  /// \name Target Writer Proxy Accessors
152  /// @{
153 
154  bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
155  bool isX86_64() const {
156  uint32_t CPUType = TargetObjectWriter->getCPUType();
157  return CPUType == MachO::CPU_TYPE_X86_64;
158  }
159 
160  /// @}
161 
162  void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
163  unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
164 
165  /// Write a segment load command.
166  ///
167  /// \param NumSections The number of sections in this segment.
168  /// \param SectionDataSize The total size of the sections.
169  void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
170  uint64_t VMAddr, uint64_t VMSize,
171  uint64_t SectionDataStartOffset,
172  uint64_t SectionDataSize, uint32_t MaxProt,
173  uint32_t InitProt);
174 
175  void writeSection(const MCAsmLayout &Layout, const MCSection &Sec,
176  uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
177  uint64_t RelocationsStart, unsigned NumRelocations);
178 
179  void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
181  uint32_t StringTableSize);
182 
184  uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
185  uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
186  uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
187  uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
188 
189  void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
190 
192  uint32_t DataSize);
193 
194  void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
195 
196  // FIXME: We really need to improve the relocation validation. Basically, we
197  // want to implement a separate computation which evaluates the relocation
198  // entry as the linker would, and verifies that the resultant fixup value is
199  // exactly what the encoder wanted. This will catch several classes of
200  // problems:
201  //
202  // - Relocation entry bugs, the two algorithms are unlikely to have the same
203  // exact bug.
204  //
205  // - Relaxation issues, where we forget to relax something.
206  //
207  // - Input errors, where something cannot be correctly encoded. 'as' allows
208  // these through in many cases.
209 
210  // Add a relocation to be output in the object file. At the time this is
211  // called, the symbol indexes are not know, so if the relocation refers
212  // to a symbol it should be passed as \p RelSymbol so that it can be updated
213  // afterwards. If the relocation doesn't refer to a symbol, nullptr should be
214  // used.
215  void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec,
217  RelAndSymbol P(RelSymbol, MRE);
218  Relocations[Sec].push_back(P);
219  }
220 
222  const MCAsmLayout &Layout,
223  const MCFragment *Fragment,
224  const MCFixup &Fixup, MCValue Target,
225  unsigned Log2Size, uint64_t &FixedValue);
226 
227  void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
228  const MCFragment *Fragment, const MCFixup &Fixup,
229  MCValue Target, uint64_t &FixedValue);
230 
231  void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
232  const MCFragment *Fragment, const MCFixup &Fixup,
233  MCValue Target, bool &IsPCRel,
234  uint64_t &FixedValue) override;
235 
237 
238  /// Compute the symbol table data.
240  std::vector<MachSymbolData> &LocalSymbolData,
241  std::vector<MachSymbolData> &ExternalSymbolData,
242  std::vector<MachSymbolData> &UndefinedSymbolData);
243 
245  const MCAsmLayout &Layout);
246 
248  const MCAsmLayout &Layout) override;
249 
251  const MCSymbol &A,
252  const MCSymbol &B,
253  bool InSet) const override;
254 
256  const MCSymbol &SymA,
257  const MCFragment &FB, bool InSet,
258  bool IsPCRel) const override;
259 
260  void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
261 };
262 
263 /// Construct a new Mach-O writer instance.
264 ///
265 /// This routine takes ownership of the target writer subclass.
266 ///
267 /// \param MOTW - The target specific Mach-O writer subclass.
268 /// \param OS - The stream to write to.
269 /// \returns The constructed object writer.
270 MCObjectWriter *createMachObjectWriter(MCMachObjectTargetWriter *MOTW,
271  raw_pwrite_stream &OS,
272  bool IsLittleEndian);
273 
274 } // End llvm namespace
275 
276 #endif
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:40
void recordScatteredRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, unsigned Log2Size, uint64_t &FixedValue)
MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
bool doesSymbolRequireExternRelocation(const MCSymbol &S)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:162
This represents an "assembler immediate".
Definition: MCValue.h:40
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
uint64_t getSectionAddress(const MCSection *Sec) const
void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
Defines the object file and target independent interfaces used by the assembler backend to write nati...
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:66
void writeDysymtabLoadCommand(uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols, uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols)
void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override
Write the object file.
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const override
struct fuzzer::@269 Flags
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
void setLocalDifferenceRelocationType(unsigned Type)
void writeSegmentLoadCommand(StringRef Name, unsigned NumSections, uint64_t VMAddr, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize, uint32_t MaxProt, uint32_t InitProt)
Write a segment load command.
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind)
Utility for building string tables with deduplicated suffixes.
void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec, MachO::any_relocation_info &MRE)
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
SectionAddrMap & getSectionAddressMap()
void writeLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
#define P(N)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
unsigned getLocalDifferenceRelocationType() const
void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize)
void writeSection(const MCAsmLayout &Layout, const MCSection &Sec, uint64_t VMAddr, uint64_t FileOffset, unsigned Flags, uint64_t RelocationsStart, unsigned NumRelocations)
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn...
Definition: CodeView.h:73
uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
Target - Wrapper for Target specific information.
MCObjectWriter * createMachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
void computeSymbolTable(MCAssembler &Asm, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
Compute the symbol table data.
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override
Record a relocation entry.
virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
void recordTLVPRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:333
const unsigned Kind
void reset() override
lifetime management
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:326
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
void bindIndirectSymbols(MCAssembler &Asm)
uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, uint32_t CPUSubtype_)