//
//===----------------------------------------------------------------------===//
+#include "MachO.h"
+#include "MachOWriter.h"
#include "MachOCodeEmitter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/CodeGen/MachineRelocation.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/OutputBuffer.h"
+#include <vector>
//===----------------------------------------------------------------------===//
// MachOCodeEmitter Implementation
//===----------------------------------------------------------------------===//
namespace llvm {
-
+
+MachOCodeEmitter::MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) :
+ ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) {
+ is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
+ isLittleEndian = TM.getTargetData()->isLittleEndian();
+ MAI = TM.getMCAsmInfo();
+}
+
/// startFunction - This callback is invoked when a new machine function is
/// about to be emitted.
// Get the Mach-O Section that this function belongs in.
MachOSection *MOS = MOW.getTextSection();
- // FIXME: better memory management
- MOS->SectionData.reserve(4096);
- BufferBegin = &MOS->SectionData[0];
- BufferEnd = BufferBegin + MOS->SectionData.capacity();
-
// Upgrade the section alignment if required.
if (MOS->align < Align) MOS->align = Align;
- // Round the size up to the correct alignment for starting the new function.
- if ((MOS->size & ((1 << Align) - 1)) != 0) {
- MOS->size += (1 << Align);
- MOS->size &= ~((1 << Align) - 1);
- }
+ MOS->emitAlignment(Align);
+
+ // Create symbol for function entry
+ const GlobalValue *FuncV = MF.getFunction();
+ MachOSym FnSym(FuncV, MOW.Mang->getMangledName(FuncV), MOS->Index, MAI);
+ FnSym.n_value = getCurrentPCOffset();
- // FIXME: Using MOS->size directly here instead of calculating it from the
- // output buffer size (impossible because the code emitter deals only in raw
- // bytes) forces us to manually synchronize size and write padding zero bytes
- // to the output buffer for all non-text sections. For text sections, we do
- // not synchonize the output buffer, and we just blow up if anyone tries to
- // write non-code to it. An assert should probably be added to
- // AddSymbolToSection to prevent calling it on the text section.
- CurBufferPtr = BufferBegin + MOS->size;
+ // add it to the symtab.
+ MOW.SymbolTable.push_back(FnSym);
}
/// finishFunction - This callback is invoked after the function is completely
// Get the Mach-O Section that this function belongs in.
MachOSection *MOS = MOW.getTextSection();
- // Get a symbol for the function to add to the symbol table
- // FIXME: it seems like we should call something like AddSymbolToSection
- // in startFunction rather than changing the section size and symbol n_value
- // here.
- const GlobalValue *FuncV = MF.getFunction();
- MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI);
- FnSym.n_value = MOS->size;
- MOS->size = CurBufferPtr - BufferBegin;
-
// Emit constant pool to appropriate section(s)
emitConstantPool(MF.getConstantPool());
// FIXME: This should be a set or something that uniques
MOW.PendingGlobals.push_back(MR.getGlobalValue());
} else {
- assert(0 && "Unhandled relocation type");
+ llvm_unreachable("Unhandled relocation type");
}
- MOS->Relocations.push_back(MR);
+ MOS->addRelocation(MR);
}
Relocations.clear();
-
- // Finally, add it to the symtab.
- MOW.SymbolTable.push_back(FnSym);
// Clear per-function data structures.
CPLocations.clear();
unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
- OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
+ OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
- CPLocations.push_back(Sec->SectionData.size());
+ CPLocations.push_back(Sec->size());
CPSections.push_back(Sec->Index);
-
- // FIXME: remove when we have unified size + output buffer
- Sec->size += Size;
// Allocate space in the section for the global.
// FIXME: need alignment?
for (unsigned j = 0; j < Size; ++j)
SecDataOut.outbyte(0);
- MOW.InitMem(CP[i].Val.ConstVal, &Sec->SectionData[0], CPLocations[i],
- TM.getTargetData(), Sec->Relocations);
+ MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i],
+ TM.getTargetData(), Sec);
}
}
/// emitJumpTables - Emit all the jump tables for a given jump table info
/// record to the appropriate section.
-
void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty()) return;
MachOSection *Sec = MOW.getJumpTableSection();
unsigned TextSecIndex = MOW.getTextSection()->Index;
- OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
+ OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
for (unsigned i = 0, e = JT.size(); i != e; ++i) {
// For each jump table, record its offset from the start of the section,
// reserve space for the relocations to the MBBs, and add the relocations.
const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
- JTLocations.push_back(Sec->SectionData.size());
+ JTLocations.push_back(Sec->size());
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
- MachineRelocation MR(MOW.GetJTRelocation(Sec->SectionData.size(),
- MBBs[mi]));
+ MachineRelocation MR(MOW.GetJTRelocation(Sec->size(), MBBs[mi]));
MR.setResultPointer((void *)JTLocations[i]);
MR.setConstantVal(TextSecIndex);
- Sec->Relocations.push_back(MR);
+ Sec->addRelocation(MR);
SecDataOut.outaddr(0);
}
}
- // FIXME: remove when we have unified size + output buffer
- Sec->size = Sec->SectionData.size();
}
} // end namespace llvm