Cleanup MachO writer and code emitter. Fix 80 cols problems, remove extra spaces, shrink down includes and move some methods out-of-line

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74817 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2009-07-06 06:40:51 +00:00
parent 8ae058a815
commit 752e928e6b
5 changed files with 205 additions and 186 deletions

View File

@ -14,17 +14,14 @@
#ifndef MACHO_H
#define MACHO_H
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/CodeGen/BinaryObject.h"
#include "llvm/Target/TargetAsmInfo.h"
#include <string>
#include <vector>
namespace llvm {
typedef std::vector<unsigned char> DataBuffer;
class GlobalValue;
class TargetAsmInfo;
/// MachOSym - This struct contains information about each symbol that is
/// added to logical symbol table for the module. This is eventually
@ -111,7 +108,7 @@ struct MachOHeader {
/// HeaderData - The actual data for the header which we are building
/// up for emission to the file.
DataBuffer HeaderData;
std::vector<unsigned char> HeaderData;
// Constants for the filetype field
// see <mach-o/loader.h> for additional info on the various types
@ -292,7 +289,7 @@ struct MachOSection : public BinaryObject {
/// RelocBuffer - A buffer to hold the mach-o relocations before we write
/// them out at the appropriate location in the file.
DataBuffer RelocBuffer;
std::vector<unsigned char> RelocBuffer;
// Constants for the section types (low 8 bits of flags field)
// see <mach-o/loader.h>

View File

@ -7,13 +7,18 @@
//
//===----------------------------------------------------------------------===//
#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/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineRelocation.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/OutputBuffer.h"
#include <vector>
@ -24,6 +29,13 @@
namespace llvm {
MachOCodeEmitter::MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) :
ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) {
is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
isLittleEndian = TM.getTargetData()->isLittleEndian();
TAI = TM.getTargetAsmInfo();
}
/// startFunction - This callback is invoked when a new machine function is
/// about to be emitted.
@ -141,7 +153,8 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
for (unsigned j = 0; j < Size; ++j)
SecDataOut.outbyte(0);
MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i], TM.getTargetData(), Sec);
MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i],
TM.getTargetData(), Sec);
}
}

View File

@ -10,10 +10,13 @@
#ifndef MACHOCODEEMITTER_H
#define MACHOCODEEMITTER_H
#include "MachOWriter.h"
#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include <map>
namespace llvm {
class MachOWriter;
/// MachOCodeEmitter - This class is used by the MachOWriter to emit the code
/// for functions to the Mach-O file.
@ -36,12 +39,7 @@ class MachOCodeEmitter : public ObjectCodeEmitter {
std::map<uint64_t, uintptr_t> Labels;
public:
MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) :
ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) {
is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
isLittleEndian = TM.getTargetData()->isLittleEndian();
TAI = TM.getTargetAsmInfo();
}
MachOCodeEmitter(MachOWriter &mow, MachOSection &mos);
virtual void startFunction(MachineFunction &MF);
virtual bool finishFunction(MachineFunction &MF);

View File

@ -22,25 +22,20 @@
//
//===----------------------------------------------------------------------===//
#include "MachO.h"
#include "MachOWriter.h"
#include "MachOCodeEmitter.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/FileWriters.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetJITInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachOWriterInfo.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/OutputBuffer.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
namespace llvm {
@ -61,15 +56,13 @@ ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM,
char MachOWriter::ID = 0;
MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
: MachineFunctionPass(&ID), O(o), TM(tm)
{
: MachineFunctionPass(&ID), O(o), TM(tm) {
is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
isLittleEndian = TM.getTargetData()->isLittleEndian();
TAI = TM.getTargetAsmInfo();
// Create the machine code emitter object for this target.
MachOCE = new MachOCodeEmitter(*this, *getTextSection(true));
}
@ -126,6 +119,89 @@ bool MachOWriter::doFinalization(Module &M) {
return false;
}
// getConstSection - Get constant section for Constant 'C'
MachOSection *MachOWriter::getConstSection(Constant *C) {
const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
if (CVA && CVA->isCString())
return getSection("__TEXT", "__cstring",
MachOSection::S_CSTRING_LITERALS);
const Type *Ty = C->getType();
if (Ty->isPrimitiveType() || Ty->isInteger()) {
unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
switch(Size) {
default: break; // Fall through to __TEXT,__const
case 4:
return getSection("__TEXT", "__literal4",
MachOSection::S_4BYTE_LITERALS);
case 8:
return getSection("__TEXT", "__literal8",
MachOSection::S_8BYTE_LITERALS);
case 16:
return getSection("__TEXT", "__literal16",
MachOSection::S_16BYTE_LITERALS);
}
}
return getSection("__TEXT", "__const");
}
// getJumpTableSection - Select the Jump Table section
MachOSection *MachOWriter::getJumpTableSection() {
if (TM.getRelocationModel() == Reloc::PIC_)
return getTextSection(false);
else
return getSection("__TEXT", "__const");
}
// getSection - Return the section with the specified name, creating a new
// section if one does not already exist.
MachOSection *MachOWriter::getSection(const std::string &seg,
const std::string &sect,
unsigned Flags /* = 0 */ ) {
MachOSection *MOS = SectionLookup[seg+sect];
if (MOS) return MOS;
MOS = new MachOSection(seg, sect);
SectionList.push_back(MOS);
MOS->Index = SectionList.size();
MOS->flags = MachOSection::S_REGULAR | Flags;
SectionLookup[seg+sect] = MOS;
return MOS;
}
// getTextSection - Return text section with different flags for code/data
MachOSection *MachOWriter::getTextSection(bool isCode /* = true */ ) {
if (isCode)
return getSection("__TEXT", "__text",
MachOSection::S_ATTR_PURE_INSTRUCTIONS |
MachOSection::S_ATTR_SOME_INSTRUCTIONS);
else
return getSection("__TEXT", "__text");
}
MachOSection *MachOWriter::getBSSSection() {
return getSection("__DATA", "__bss", MachOSection::S_ZEROFILL);
}
// GetJTRelocation - Get a relocation a new BB relocation based
// on target information.
MachineRelocation MachOWriter::GetJTRelocation(unsigned Offset,
MachineBasicBlock *MBB) const {
return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
}
// GetTargetRelocation - Returns the number of relocations.
unsigned MachOWriter::GetTargetRelocation(MachineRelocation &MR,
unsigned FromIdx, unsigned ToAddr,
unsigned ToIndex, OutputBuffer &RelocOut,
OutputBuffer &SecOut, bool Scattered,
bool Extern) {
return TM.getMachOWriterInfo()->GetTargetRelocation(MR, FromIdx, ToAddr,
ToIndex, RelocOut,
SecOut, Scattered,
Extern);
}
void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
const Type *Ty = GV->getType()->getElementType();
unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
@ -178,7 +254,8 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
// merged with other symbols.
if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
GV->hasCommonLinkage()) {
MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT, TAI);
MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV),
MachOSym::NO_SECT, TAI);
// For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
// bytes of the symbol.
ExtOrCommonSym.n_value = Size;
@ -225,7 +302,7 @@ void MachOWriter::EmitHeaderAndLoadCommands() {
// Step #3: write the header to the file
// Local alias to shortenify coming code.
DataBuffer &FH = Header.HeaderData;
std::vector<unsigned char> &FH = Header.HeaderData;
OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
FHOut.outword(Header.magic);
@ -388,7 +465,8 @@ void MachOWriter::BufferSymbolAndStringTable() {
// Parition the symbol table entries so that all local symbols come before
// all symbols with external linkage. { 1 | 2 3 }
std::partition(SymbolTable.begin(), SymbolTable.end(), MachOSym::PartitionByLocal);
std::partition(SymbolTable.begin(), SymbolTable.end(),
MachOSym::PartitionByLocal);
// Advance iterator to beginning of external symbols and partition so that
// all external symbols defined in this module come before all external

View File

@ -14,29 +14,27 @@
#ifndef MACHOWRITER_H
#define MACHOWRITER_H
#include "MachO.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetMachOWriterInfo.h"
#include <vector>
#include <map>
namespace llvm {
class Constant;
class GlobalVariable;
class Mangler;
class MachineRelocation;
class ObjectCodeEmitter;
class MachOCodeEmitter;
class MachODySymTab;
class MachOHeader;
class MachOSection;
class MachOSym;
class TargetData;
class TargetMachine;
class TargetAsmInfo;
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.
@ -70,35 +68,29 @@ namespace llvm {
///
Mangler *Mang;
/// MachOCE - The MachineCodeEmitter object that we are exposing to emit machine
/// code for functions to the .o file.
/// 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 TargetAsmInfo *TAI;
/// 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:
@ -106,83 +98,35 @@ namespace llvm {
/// 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) {
MachOSection *MOS = SectionLookup[seg+sect];
if (MOS) return MOS;
unsigned Flags = 0);
/// getTextSection - Return text section with different flags for code/data
MachOSection *getTextSection(bool isCode = true);
MOS = new MachOSection(seg, sect);
SectionList.push_back(MOS);
MOS->Index = SectionList.size();
MOS->flags = MachOSection::S_REGULAR | Flags;
SectionLookup[seg+sect] = MOS;
return MOS;
}
MachOSection *getTextSection(bool isCode = true) {
if (isCode)
return getSection("__TEXT", "__text",
MachOSection::S_ATTR_PURE_INSTRUCTIONS |
MachOSection::S_ATTR_SOME_INSTRUCTIONS);
else
return getSection("__TEXT", "__text");
}
MachOSection *getBSSSection() {
return getSection("__DATA", "__bss", MachOSection::S_ZEROFILL);
}
MachOSection *getDataSection() {
return getSection("__DATA", "__data");
}
MachOSection *getConstSection(Constant *C) {
const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
if (CVA && CVA->isCString())
return getSection("__TEXT", "__cstring",
MachOSection::S_CSTRING_LITERALS);
const Type *Ty = C->getType();
if (Ty->isPrimitiveType() || Ty->isInteger()) {
unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
switch(Size) {
default: break; // Fall through to __TEXT,__const
case 4:
return getSection("__TEXT", "__literal4",
MachOSection::S_4BYTE_LITERALS);
case 8:
return getSection("__TEXT", "__literal8",
MachOSection::S_8BYTE_LITERALS);
case 16:
return getSection("__TEXT", "__literal16",
MachOSection::S_16BYTE_LITERALS);
}
}
return getSection("__TEXT", "__const");
}
MachOSection *getJumpTableSection() {
if (TM.getRelocationModel() == Reloc::PIC_)
return getTextSection(false);
else
return getSection("__TEXT", "__const");
}
MachOSection *getBSSSection();
MachOSection *getConstSection(Constant *C);
MachOSection *getJumpTableSection();
/// MachOSymTab - This struct contains information about the offsets and
/// size of symbol table information.
@ -218,11 +162,11 @@ namespace llvm {
/// SymT - A buffer to hold the symbol table before we write it out at the
/// appropriate location in the file.
DataBuffer SymT;
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.
DataBuffer StrT;
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
@ -233,10 +177,8 @@ namespace llvm {
/// 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);
static void InitMem(const Constant *C, uintptr_t Offset,
const TargetData *TD, MachOSection* mos);
private:
void AddSymbolToSection(MachOSection *MOS, GlobalVariable *GV);
@ -247,25 +189,16 @@ namespace llvm {
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 {
return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
}
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) {
return TM.getMachOWriterInfo()->GetTargetRelocation(MR, FromIdx, ToAddr,
ToIndex, RelocOut,
SecOut, Scattered,
Extern);
}
unsigned GetTargetRelocation(MachineRelocation &MR, unsigned FromIdx,
unsigned ToAddr, unsigned ToIndex,
OutputBuffer &RelocOut, OutputBuffer &SecOut,
bool Scattered, bool Extern);
};
}