summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachOWriter.h
blob: 9273f3854863cc5abee7347fb1180a1a212930f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//=== MachOWriter.h - Target-independent Mach-O writer support --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MachOWriter class.
//
//===----------------------------------------------------------------------===//

#ifndef MACHOWRITER_H
#define MACHOWRITER_H

#include "llvm/CodeGen/MachineFunctionPass.h"
#include <vector>
#include <map>

namespace llvm {
  class Constant;
  class GlobalVariable;
  class Mangler;
  class MachineBasicBlock;
  class MachineRelocation;
  class MachOCodeEmitter;
  struct MachODySymTab;
  struct MachOHeader;
  struct MachOSection;
  struct MachOSym;
  class TargetData;
  class TargetMachine;
  class MCAsmInfo;
  class ObjectCodeEmitter;
  class OutputBuffer;
  class raw_ostream;

  /// MachOWriter - This class implements the common target-independent code for
  /// writing Mach-O files.  Targets should derive a class from this to
  /// parameterize the output format.
  ///
  class MachOWriter : public MachineFunctionPass {
    friend class MachOCodeEmitter;
  public:
    static char ID;

    ObjectCodeEmitter *getObjectCodeEmitter() {
      return reinterpret_cast<ObjectCodeEmitter*>(MachOCE);
    }

    MachOWriter(raw_ostream &O, TargetMachine &TM);
    virtual ~MachOWriter();

    virtual const char *getPassName() const {
      return "Mach-O Writer";
    }

  protected:
    /// Output stream to send the resultant object file to.
    ///
    raw_ostream &O;

    /// Target machine description.
    ///
    TargetMachine &TM;

    /// Mang - The object used to perform name mangling for this module.
    ///
    Mangler *Mang;

    /// MachOCE - The MachineCodeEmitter object that we are exposing to emit
    /// machine code for functions to the .o file.
    MachOCodeEmitter *MachOCE;

    /// is64Bit/isLittleEndian - This information is inferred from the target
    /// machine directly, indicating what header values and flags to set.
    bool is64Bit, isLittleEndian;

    // Target Asm Info
    const MCAsmInfo *MAI;

    /// Header - An instance of MachOHeader that we will update while we build
    /// the file, and then emit during finalization.
    MachOHeader Header;

    /// doInitialization - Emit the file header and all of the global variables
    /// for the module to the Mach-O file.
    bool doInitialization(Module &M);

    bool runOnMachineFunction(MachineFunction &MF);

    /// doFinalization - Now that the module has been completely processed, emit
    /// the Mach-O file to 'O'.
    bool doFinalization(Module &M);

  private:

    /// SectionList - This is the list of sections that we have emitted to the
    /// file.  Once the file has been completely built, the segment load command
    /// SectionCommands are constructed from this info.
    std::vector<MachOSection*> SectionList;

    /// SectionLookup - This is a mapping from section name to SectionList entry
    std::map<std::string, MachOSection*> SectionLookup;

    /// GVSection - This is a mapping from a GlobalValue to a MachOSection,
    /// to aid in emitting relocations.
    std::map<GlobalValue*, MachOSection*> GVSection;

    /// GVOffset - This is a mapping from a GlobalValue to an offset from the
    /// start of the section in which the GV resides, to aid in emitting
    /// relocations.
    std::map<GlobalValue*, intptr_t> GVOffset;

    /// getSection - Return the section with the specified name, creating a new
    /// section if one does not already exist.
    MachOSection *getSection(const std::string &seg, const std::string &sect,
                             unsigned Flags = 0);

    /// getTextSection - Return text section with different flags for code/data
    MachOSection *getTextSection(bool isCode = true);

    MachOSection *getDataSection() {
      return getSection("__DATA", "__data");
    }

    MachOSection *getBSSSection();
    MachOSection *getConstSection(Constant *C);
    MachOSection *getJumpTableSection();

    /// MachOSymTab - This struct contains information about the offsets and
    /// size of symbol table information.
    /// segment.
    struct MachOSymTab {
      uint32_t cmd;     // LC_SYMTAB
      uint32_t cmdsize; // sizeof( MachOSymTab )
      uint32_t symoff;  // symbol table offset
      uint32_t nsyms;   // number of symbol table entries
      uint32_t stroff;  // string table offset
      uint32_t strsize; // string table size in bytes

      // Constants for the cmd field
      // see <mach-o/loader.h>
      enum { LC_SYMTAB = 0x02  // link-edit stab symbol table info
      };

      MachOSymTab() : cmd(LC_SYMTAB), cmdsize(6 * sizeof(uint32_t)), symoff(0),
        nsyms(0), stroff(0), strsize(0) { }
    };

    /// SymTab - The "stab" style symbol table information
    MachOSymTab SymTab;
    /// DySymTab - symbol table info for the dynamic link editor
    MachODySymTab DySymTab;

  protected:

    /// SymbolTable - This is the list of symbols we have emitted to the file.
    /// This actually gets rearranged before emission to the file (to put the
    /// local symbols first in the list).
    std::vector<MachOSym> SymbolTable;

    /// SymT - A buffer to hold the symbol table before we write it out at the
    /// appropriate location in the file.
    std::vector<unsigned char> SymT;

    /// StrT - A buffer to hold the string table before we write it out at the
    /// appropriate location in the file.
    std::vector<unsigned char> StrT;

    /// PendingSyms - This is a list of externally defined symbols that we have
    /// been asked to emit, but have not seen a reference to.  When a reference
    /// is seen, the symbol will move from this list to the SymbolTable.
    std::vector<GlobalValue*> PendingGlobals;

    /// DynamicSymbolTable - This is just a vector of indices into
    /// SymbolTable to aid in emitting the DYSYMTAB load command.
    std::vector<unsigned> DynamicSymbolTable;

    static void InitMem(const Constant *C, uintptr_t Offset,
                        const TargetData *TD, MachOSection* mos);

  private:
    void AddSymbolToSection(MachOSection *MOS, GlobalVariable *GV);
    void EmitGlobal(GlobalVariable *GV);
    void EmitHeaderAndLoadCommands();
    void EmitSections();
    void EmitRelocations();
    void BufferSymbolAndStringTable();
    void CalculateRelocations(MachOSection &MOS);

    // GetJTRelocation - Get a relocation a new BB relocation based
    // on target information.
    MachineRelocation GetJTRelocation(unsigned Offset,
                                      MachineBasicBlock *MBB) const;

    /// GetTargetRelocation - Returns the number of relocations.
    unsigned GetTargetRelocation(MachineRelocation &MR, unsigned FromIdx,
                                 unsigned ToAddr, unsigned ToIndex,
                                 OutputBuffer &RelocOut, OutputBuffer &SecOut,
                                 bool Scattered, bool Extern);
  };
}

#endif
OpenPOWER on IntegriCloud