126 lines
3.9 KiB
C++
126 lines
3.9 KiB
C++
//===-- MachOWriter.cpp - Target-independent Mach-O Writer code -----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the target-independent Mach-O writer. This file writes
|
|
// out the Mach-O file in the following order:
|
|
//
|
|
// #1 FatHeader (universal-only)
|
|
// #2 FatArch (universal-only, 1 per universal arch)
|
|
// Per arch:
|
|
// #3 Header
|
|
// #4 Load Commands
|
|
// #5 Sections
|
|
// #6 Relocations
|
|
// #7 Symbols
|
|
// #8 Strings
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "MachOWriter.h"
|
|
#include "llvm/Function.h"
|
|
#include "llvm/CodeGen/FileWriters.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/MC/MCAsmInfo.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCCodeEmitter.h"
|
|
#include "llvm/MC/MCInst.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/FormattedStream.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/Target/Mangler.h"
|
|
#include "llvm/Target/TargetData.h"
|
|
#include "llvm/Target/TargetLowering.h"
|
|
#include "llvm/Target/TargetLoweringObjectFile.h"
|
|
using namespace llvm;
|
|
|
|
namespace llvm {
|
|
MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
|
|
TargetMachine &TM,
|
|
const MCAsmInfo *T,
|
|
MCCodeEmitter *MCE) {
|
|
return new MachOWriter(O, TM, T, MCE);
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MachOWriter Implementation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
char MachOWriter::ID = 0;
|
|
|
|
MachOWriter::MachOWriter(formatted_raw_ostream &o, TargetMachine &tm,
|
|
const MCAsmInfo *T, MCCodeEmitter *MCE)
|
|
: MachineFunctionPass(&ID), O(o), TM(tm), MAI(T), MCCE(MCE),
|
|
OutContext(*new MCContext()),
|
|
OutStreamer(*createMachOStreamer(OutContext, O, MCCE)) {
|
|
}
|
|
|
|
MachOWriter::~MachOWriter() {
|
|
delete &OutStreamer;
|
|
delete &OutContext;
|
|
delete MCCE;
|
|
}
|
|
|
|
bool MachOWriter::doInitialization(Module &M) {
|
|
// Initialize TargetLoweringObjectFile.
|
|
TM.getTargetLowering()->getObjFileLowering().Initialize(OutContext, TM);
|
|
|
|
return false;
|
|
}
|
|
|
|
/// doFinalization - Now that the module has been completely processed, emit
|
|
/// the Mach-O file to 'O'.
|
|
bool MachOWriter::doFinalization(Module &M) {
|
|
OutStreamer.Finish();
|
|
return false;
|
|
}
|
|
|
|
bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
|
|
const Function *F = MF.getFunction();
|
|
TargetLoweringObjectFile &TLOF = TM.getTargetLowering()->getObjFileLowering();
|
|
const MCSection *S = TLOF.SectionForGlobal(F, Mang, TM);
|
|
OutStreamer.SwitchSection(S);
|
|
|
|
for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
|
|
I != E; ++I) {
|
|
// Print a label for the basic block.
|
|
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
|
|
II != IE; ++II) {
|
|
const MachineInstr *MI = II;
|
|
MCInst OutMI;
|
|
OutMI.setOpcode(MI->getOpcode());
|
|
|
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
|
const MachineOperand &MO = MI->getOperand(i);
|
|
MCOperand MCOp;
|
|
|
|
switch (MO.getType()) {
|
|
default:
|
|
MI->dump();
|
|
llvm_unreachable("unknown operand type");
|
|
case MachineOperand::MO_Register:
|
|
// Ignore all implicit register operands.
|
|
if (MO.isImplicit()) continue;
|
|
MCOp = MCOperand::CreateReg(MO.getReg());
|
|
break;
|
|
case MachineOperand::MO_Immediate:
|
|
MCOp = MCOperand::CreateImm(MO.getImm());
|
|
break;
|
|
}
|
|
OutMI.addOperand(MCOp);
|
|
}
|
|
|
|
OutStreamer.EmitInstruction(OutMI);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|