forked from OSchip/llvm-project
Changed ELFCodeEmitter to inherit from ObjectCodeEmitter
llvm-svn: 74821
This commit is contained in:
parent
5d569c563d
commit
f539f03289
|
@ -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()) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue