1 //===-- MachOEmitter.cpp - Target-independent Mach-O Emitter code --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "MachOWriter.h"
12 #include "MachOCodeEmitter.h"
13 #include "llvm/Constants.h"
14 #include "llvm/DerivedTypes.h"
15 #include "llvm/Function.h"
16 #include "llvm/CodeGen/MachineConstantPool.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineJumpTableInfo.h"
19 #include "llvm/CodeGen/MachineRelocation.h"
20 #include "llvm/MC/MCAsmInfo.h"
21 #include "llvm/Target/TargetData.h"
22 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/Mangler.h"
25 #include "llvm/Support/OutputBuffer.h"
28 //===----------------------------------------------------------------------===//
29 // MachOCodeEmitter Implementation
30 //===----------------------------------------------------------------------===//
34 MachOCodeEmitter::MachOCodeEmitter(MachOWriter
&mow
, MachOSection
&mos
) :
35 ObjectCodeEmitter(&mos
), MOW(mow
), TM(MOW
.TM
) {
36 is64Bit
= TM
.getTargetData()->getPointerSizeInBits() == 64;
37 isLittleEndian
= TM
.getTargetData()->isLittleEndian();
38 MAI
= TM
.getMCAsmInfo();
41 /// startFunction - This callback is invoked when a new machine function is
42 /// about to be emitted.
44 void MachOCodeEmitter::startFunction(MachineFunction
&MF
) {
45 const TargetData
*TD
= TM
.getTargetData();
46 const Function
*F
= MF
.getFunction();
48 // Align the output buffer to the appropriate alignment, power of 2.
49 unsigned FnAlign
= F
->getAlignment();
50 unsigned TDAlign
= TD
->getPrefTypeAlignment(F
->getType());
51 unsigned Align
= Log2_32(std::max(FnAlign
, TDAlign
));
52 assert(!(Align
& (Align
-1)) && "Alignment is not a power of two!");
54 // Get the Mach-O Section that this function belongs in.
55 MachOSection
*MOS
= MOW
.getTextSection();
57 // Upgrade the section alignment if required.
58 if (MOS
->align
< Align
) MOS
->align
= Align
;
60 MOS
->emitAlignment(Align
);
62 // Create symbol for function entry
63 const GlobalValue
*FuncV
= MF
.getFunction();
64 MachOSym
FnSym(FuncV
, MOW
.Mang
->getMangledName(FuncV
), MOS
->Index
, MAI
);
65 FnSym
.n_value
= getCurrentPCOffset();
67 // add it to the symtab.
68 MOW
.SymbolTable
.push_back(FnSym
);
71 /// finishFunction - This callback is invoked after the function is completely
74 bool MachOCodeEmitter::finishFunction(MachineFunction
&MF
) {
76 // Get the Mach-O Section that this function belongs in.
77 MachOSection
*MOS
= MOW
.getTextSection();
79 // Emit constant pool to appropriate section(s)
80 emitConstantPool(MF
.getConstantPool());
82 // Emit jump tables to appropriate section
83 emitJumpTables(MF
.getJumpTableInfo());
85 // If we have emitted any relocations to function-specific objects such as
86 // basic blocks, constant pools entries, or jump tables, record their
87 // addresses now so that we can rewrite them with the correct addresses
89 for (unsigned i
= 0, e
= Relocations
.size(); i
!= e
; ++i
) {
90 MachineRelocation
&MR
= Relocations
[i
];
93 if (MR
.isBasicBlock()) {
94 Addr
= getMachineBasicBlockAddress(MR
.getBasicBlock());
95 MR
.setConstantVal(MOS
->Index
);
96 MR
.setResultPointer((void*)Addr
);
97 } else if (MR
.isJumpTableIndex()) {
98 Addr
= getJumpTableEntryAddress(MR
.getJumpTableIndex());
99 MR
.setConstantVal(MOW
.getJumpTableSection()->Index
);
100 MR
.setResultPointer((void*)Addr
);
101 } else if (MR
.isConstantPoolIndex()) {
102 Addr
= getConstantPoolEntryAddress(MR
.getConstantPoolIndex());
103 MR
.setConstantVal(CPSections
[MR
.getConstantPoolIndex()]);
104 MR
.setResultPointer((void*)Addr
);
105 } else if (MR
.isGlobalValue()) {
106 // FIXME: This should be a set or something that uniques
107 MOW
.PendingGlobals
.push_back(MR
.getGlobalValue());
109 llvm_unreachable("Unhandled relocation type");
111 MOS
->addRelocation(MR
);
115 // Clear per-function data structures.
119 MBBLocations
.clear();
124 /// emitConstantPool - For each constant pool entry, figure out which section
125 /// the constant should live in, allocate space for it, and emit it to the
126 /// Section data buffer.
127 void MachOCodeEmitter::emitConstantPool(MachineConstantPool
*MCP
) {
128 const std::vector
<MachineConstantPoolEntry
> &CP
= MCP
->getConstants();
129 if (CP
.empty()) return;
131 // FIXME: handle PIC codegen
132 assert(TM
.getRelocationModel() != Reloc::PIC_
&&
133 "PIC codegen not yet handled for mach-o jump tables!");
135 // Although there is no strict necessity that I am aware of, we will do what
136 // gcc for OS X does and put each constant pool entry in a section of constant
137 // objects of a certain size. That means that float constants go in the
138 // literal4 section, and double objects go in literal8, etc.
140 // FIXME: revisit this decision if we ever do the "stick everything into one
141 // "giant object for PIC" optimization.
142 for (unsigned i
= 0, e
= CP
.size(); i
!= e
; ++i
) {
143 const Type
*Ty
= CP
[i
].getType();
144 unsigned Size
= TM
.getTargetData()->getTypeAllocSize(Ty
);
146 MachOSection
*Sec
= MOW
.getConstSection(CP
[i
].Val
.ConstVal
);
147 OutputBuffer
SecDataOut(Sec
->getData(), is64Bit
, isLittleEndian
);
149 CPLocations
.push_back(Sec
->size());
150 CPSections
.push_back(Sec
->Index
);
152 // Allocate space in the section for the global.
153 // FIXME: need alignment?
154 // FIXME: share between here and AddSymbolToSection?
155 for (unsigned j
= 0; j
< Size
; ++j
)
156 SecDataOut
.outbyte(0);
158 MachOWriter::InitMem(CP
[i
].Val
.ConstVal
, CPLocations
[i
],
159 TM
.getTargetData(), Sec
);
163 /// emitJumpTables - Emit all the jump tables for a given jump table info
164 /// record to the appropriate section.
165 void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo
*MJTI
) {
166 const std::vector
<MachineJumpTableEntry
> &JT
= MJTI
->getJumpTables();
167 if (JT
.empty()) return;
169 // FIXME: handle PIC codegen
170 assert(TM
.getRelocationModel() != Reloc::PIC_
&&
171 "PIC codegen not yet handled for mach-o jump tables!");
173 MachOSection
*Sec
= MOW
.getJumpTableSection();
174 unsigned TextSecIndex
= MOW
.getTextSection()->Index
;
175 OutputBuffer
SecDataOut(Sec
->getData(), is64Bit
, isLittleEndian
);
177 for (unsigned i
= 0, e
= JT
.size(); i
!= e
; ++i
) {
178 // For each jump table, record its offset from the start of the section,
179 // reserve space for the relocations to the MBBs, and add the relocations.
180 const std::vector
<MachineBasicBlock
*> &MBBs
= JT
[i
].MBBs
;
181 JTLocations
.push_back(Sec
->size());
182 for (unsigned mi
= 0, me
= MBBs
.size(); mi
!= me
; ++mi
) {
183 MachineRelocation
MR(MOW
.GetJTRelocation(Sec
->size(), MBBs
[mi
]));
184 MR
.setResultPointer((void *)JTLocations
[i
]);
185 MR
.setConstantVal(TextSecIndex
);
186 Sec
->addRelocation(MR
);
187 SecDataOut
.outaddr(0);
192 } // end namespace llvm