Changed ELFCodeEmitter to inherit from ObjectCodeEmitter

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74821 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2009-07-06 09:26:48 +00:00
parent d7649417d1
commit 6933d3eff8
4 changed files with 55 additions and 135 deletions

View File

@ -33,47 +33,30 @@ namespace llvm {
/// startFunction - This callback is invoked when a new machine function is
/// about to be emitted.
void ELFCodeEmitter::startFunction(MachineFunction &MF) {
DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
// Get the ELF Section that this function belongs in.
ES = &EW.getTextSection();
DOUT << "processing function: " << MF.getFunction()->getName() << "\n";
// FIXME: better memory management, this will be replaced by BinaryObjects
BinaryData &BD = ES->getData();
BD.reserve(4096);
BufferBegin = &BD[0];
BufferEnd = BufferBegin + BD.capacity();
// Set the desired binary object to be used by the code emitters
setBinaryObject(ES);
// Get the function alignment in bytes
unsigned Align = (1 << MF.getAlignment());
// Align the section size with the function alignment, so the function can
// start in a aligned offset, also update the section alignment if needed.
// The function must start on its required alignment
ES->emitAlignment(Align);
// Update the section alignment if needed.
if (ES->Align < Align) ES->Align = Align;
ES->Size = (ES->Size + (Align-1)) & (-Align);
// Snaity check on allocated space for text section
assert( ES->Size < 4096 && "no more space in TextSection" );
// FIXME: Using ES->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 + ES->Size;
// Record function start address relative to BufferBegin
FnStartPtr = CurBufferPtr;
// Record the function start offset
FnStartOff = ES->getCurrentPCOffset();
}
/// finishFunction - This callback is invoked after the function is completely
/// finished.
bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
// Update Section Size
ES->Size = CurBufferPtr - BufferBegin;
// Add a symbol to represent the function.
const Function *F = MF.getFunction();
ELFSym FnSym(F);
@ -81,10 +64,10 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
FnSym.setBind(EW.getGlobalELFLinkage(F));
FnSym.setVisibility(EW.getGlobalELFVisibility(F));
FnSym.SectionIdx = ES->SectionIdx;
FnSym.Size = CurBufferPtr-FnStartPtr;
FnSym.Size = ES->getCurrentPCOffset()-FnStartOff;
// Offset from start of Section
FnSym.Value = FnStartPtr-BufferBegin;
FnSym.Value = FnStartOff;
// Locals should go on the symbol list front
if (!F->hasPrivateLinkage()) {

View File

@ -10,7 +10,7 @@
#ifndef ELFCODEEMITTER_H
#define ELFCODEEMITTER_H
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/ObjectCodeEmitter.h"
#include <vector>
namespace llvm {
@ -19,7 +19,7 @@ namespace llvm {
/// ELFCodeEmitter - This class is used by the ELFWriter to
/// emit the code for functions to the ELF file.
class ELFCodeEmitter : public MachineCodeEmitter {
class ELFCodeEmitter : public ObjectCodeEmitter {
ELFWriter &EW;
/// Target machine description
@ -28,30 +28,11 @@ namespace llvm {
/// Section containing code for functions
ELFSection *ES;
/// Relocations - These are the relocations that the function needs, as
/// emitted.
/// Relocations - Record relocations needed by the current function
std::vector<MachineRelocation> Relocations;
/// CPLocations - This is a map of constant pool indices to offsets from the
/// start of the section for that constant pool index.
std::vector<uintptr_t> CPLocations;
/// CPSections - This is a map of constant pool indices to the MachOSection
/// containing the constant pool entry for that index.
std::vector<unsigned> CPSections;
/// JTLocations - This is a map of jump table indices to offsets from the
/// start of the section for that jump table index.
std::vector<uintptr_t> JTLocations;
/// MBBLocations - This vector is a mapping from MBB ID's to their address.
/// It is filled in by the StartMachineBasicBlock callback and queried by
/// the getMachineBasicBlockAddress callback.
std::vector<uintptr_t> MBBLocations;
/// FnStartPtr - Pointer to the start location of the current function
/// in the buffer
uint8_t *FnStartPtr;
/// FnStartPtr - Function offset from the beginning of ELFSection 'ES'
uintptr_t FnStartOff;
/// JumpTableSectionIdx - Holds the index of the Jump Table Section
unsigned JumpTableSectionIdx;
@ -59,71 +40,36 @@ namespace llvm {
explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM),
JumpTableSectionIdx(0) {}
void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F);
/// addRelocation - Register new relocations for this function
void addRelocation(const MachineRelocation &MR) {
Relocations.push_back(MR);
}
virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
if (MBBLocations.size() <= (unsigned)MBB->getNumber())
MBBLocations.resize((MBB->getNumber()+1)*2);
MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
}
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(CPLocations.size() > Index && "CP not emitted!");
return CPLocations[Index];
}
virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(JTLocations.size() > Index && "JT not emitted!");
return JTLocations[Index];
}
virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
MBBLocations[MBB->getNumber()] && "MBB not emitted!");
return MBBLocations[MBB->getNumber()];
}
virtual uintptr_t getLabelAddress(uint64_t Label) const {
assert(0 && "Label address not implementated yet!");
abort();
return 0;
}
virtual void emitLabel(uint64_t LabelID) {
assert(0 && "emit Label not implementated yet!");
abort();
}
/// emitConstantPool - For each constant pool entry, figure out which section
/// the constant should live in and emit the constant.
/// emitConstantPool - For each constant pool entry, figure out which
/// section the constant should live in and emit data to it
void emitConstantPool(MachineConstantPool *MCP);
/// emitJumpTables - Emit all the jump tables for a given jump table info
/// record to the appropriate section.
/// emitJumpTables - Emit all the jump tables for a given jump table
/// info and record them to the appropriate section.
void emitJumpTables(MachineJumpTableInfo *MJTI);
void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F);
/// emitLabel - Emits a label
virtual void emitLabel(uint64_t LabelID) {
assert("emitLabel not implemented");
}
/// getLabelAddress - Return the address of the specified LabelID,
/// only usable after the LabelID has been emitted.
virtual uintptr_t getLabelAddress(uint64_t Label) const {
assert("getLabelAddress not implemented");
return 0;
}
virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) {}
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
void startGVStub(const GlobalValue* F, unsigned StubSize,
unsigned Alignment = 1) {
assert(0 && "JIT specific function called!");
abort();
}
void startGVStub(const GlobalValue* F, void *Buffer, unsigned StubSize) {
assert(0 && "JIT specific function called!");
abort();
}
void *finishGVStub(const GlobalValue *F) {
assert(0 && "JIT specific function called!");
abort();
return 0;
}
}; // end class ELFCodeEmitter
} // end namespace llvm

View File

@ -51,17 +51,18 @@
#include "llvm/Support/Streams.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Debug.h"
using namespace llvm;
char ELFWriter::ID = 0;
/// AddELFWriter - Concrete function to add the ELF writer to the function pass
/// manager.
/// AddELFWriter - Add the ELF writer to the function pass manager
ObjectCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
raw_ostream &O,
TargetMachine &TM) {
raw_ostream &O,
TargetMachine &TM) {
ELFWriter *EW = new ELFWriter(O, TM);
PM.add(EW);
return (ObjectCodeEmitter*) &EW->getMachineCodeEmitter();
return EW->getObjectCodeEmitter();
}
//===----------------------------------------------------------------------===//
@ -77,15 +78,15 @@ ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
TAI = TM.getTargetAsmInfo();
TEW = TM.getELFWriterInfo();
// Create the machine code emitter object for this target.
MCE = new ELFCodeEmitter(*this);
// Create the object code emitter object for this target.
ElfCE = new ELFCodeEmitter(*this);
// Inital number of sections
NumSections = 0;
}
ELFWriter::~ELFWriter() {
delete MCE;
delete ElfCE;
}
// doInitialization - Emit the file header and all of the global variables for
@ -361,23 +362,13 @@ void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) {
bool ELFWriter::runOnMachineFunction(MachineFunction &MF) {
// Nothing to do here, this is all done through the MCE object above.
// Nothing to do here, this is all done through the ElfCE object above.
return false;
}
/// doFinalization - Now that the module has been completely processed, emit
/// the ELF file to 'O'.
bool ELFWriter::doFinalization(Module &M) {
/// FIXME: This should be removed when moving to ObjectCodeEmiter. Since the
/// current ELFCodeEmiter uses CurrBuff, ... it doesn't update S.Data
/// vector size for .text sections, so this is a quick dirty fix
ELFSection &TS = getTextSection();
if (TS.Size) {
BinaryData &BD = TS.getData();
for (unsigned e=0; e<TS.Size; ++e)
BD.push_back(BD[e]);
}
// Emit .data section placeholder
getDataSection();

View File

@ -24,15 +24,16 @@ namespace llvm {
class Constant;
class ConstantStruct;
class ELFCodeEmitter;
class ELFRelocation;
class ELFSection;
class ELFSym;
class GlobalVariable;
class Mangler;
class MachineCodeEmitter;
class ObjectCodeEmitter;
class TargetAsmInfo;
class TargetELFWriterInfo;
class raw_ostream;
class ELFSection;
class ELFSym;
class ELFRelocation;
/// ELFWriter - This class implements the common target-independent code for
/// writing ELF files. Targets should derive a class from this to
@ -43,15 +44,14 @@ namespace llvm {
public:
static char ID;
MachineCodeEmitter &getMachineCodeEmitter() const {
return *(MachineCodeEmitter*)MCE;
/// Return the ELFCodeEmitter as an instance of ObjectCodeEmitter
ObjectCodeEmitter *getObjectCodeEmitter() {
return reinterpret_cast<ObjectCodeEmitter*>(ElfCE);
}
ELFWriter(raw_ostream &O, TargetMachine &TM);
~ELFWriter();
typedef std::vector<unsigned char> DataBuffer;
protected:
/// Output stream to send the resultant object file to.
raw_ostream &O;
@ -67,7 +67,7 @@ namespace llvm {
/// MCE - The MachineCodeEmitter object that we are exposing to emit machine
/// code for functions to the .o file.
ELFCodeEmitter *MCE;
ELFCodeEmitter *ElfCE;
/// TAI - Target Asm Info, provide information about section names for
/// globals and other target specific stuff.