summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/ELFCodeEmitter.cpp43
-rw-r--r--lib/CodeGen/ELFCodeEmitter.h94
-rw-r--r--lib/CodeGen/ELFWriter.cpp29
-rw-r--r--lib/CodeGen/ELFWriter.h16
4 files changed, 51 insertions, 131 deletions
diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp
index 691f19408d..78f0dae51c 100644
--- a/lib/CodeGen/ELFCodeEmitter.cpp
+++ b/lib/CodeGen/ELFCodeEmitter.cpp
@@ -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()) {
diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h
index 982aebf8fc..d7f178d8bf 100644
--- a/lib/CodeGen/ELFCodeEmitter.h
+++ b/lib/CodeGen/ELFCodeEmitter.h
@@ -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();
- }
+ /// emitConstantPool - For each constant pool entry, figure out which
+ /// section the constant should live in and emit data to it
+ void emitConstantPool(MachineConstantPool *MCP);
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- assert(CPLocations.size() > Index && "CP not emitted!");
- return CPLocations[Index];
- }
+ /// emitJumpTables - Emit all the jump tables for a given jump table
+ /// info and record them to the appropriate section.
+ void emitJumpTables(MachineJumpTableInfo *MJTI);
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
- assert(JTLocations.size() > Index && "JT not emitted!");
- return JTLocations[Index];
- }
+ void startFunction(MachineFunction &F);
+ bool finishFunction(MachineFunction &F);
- virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
- assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
- MBBLocations[MBB->getNumber()] && "MBB not emitted!");
- return MBBLocations[MBB->getNumber()];
+ /// 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(0 && "Label address not implementated yet!");
- abort();
+ assert("getLabelAddress not implemented");
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.
- void emitConstantPool(MachineConstantPool *MCP);
-
- /// emitJumpTables - Emit all the jump tables for a given jump table info
- /// record to the appropriate section.
- void emitJumpTables(MachineJumpTableInfo *MJTI);
-
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
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 53e4da5845..ddc3670665 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -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();
diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h
index bab118c6e3..b257cfb9ee 100644
--- a/lib/CodeGen/ELFWriter.h
+++ b/lib/CodeGen/ELFWriter.h
@@ -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.