ELF Code Emitter now uses CurBufferPtr, BufferBegin and BufferEnd, as do JIT and

MachO Writer. This will change with the arrival of ObjectCodeEmitter and
BinaryObject


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72906 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bruno Cardoso Lopes 2009-06-05 00:22:10 +00:00
parent 9f5f322a03
commit 5d41910396
3 changed files with 57 additions and 32 deletions

View File

@ -7,17 +7,17 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define DEBUG_TYPE "elfce"
#include "ELFCodeEmitter.h" #include "ELFCodeEmitter.h"
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/OutputBuffer.h"
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ELFCodeEmitter Implementation // ELFCodeEmitter Implementation
@ -27,39 +27,54 @@ namespace llvm {
/// startFunction - This callback is invoked when a new machine function is /// startFunction - This callback is invoked when a new machine function is
/// about to be emitted. /// about to be emitted.
void ELFCodeEmitter::startFunction(MachineFunction &F) { void ELFCodeEmitter::startFunction(MachineFunction &MF) {
// Align the output buffer to the appropriate alignment. const TargetData *TD = TM.getTargetData();
unsigned Align = 16; // FIXME: GENERICIZE!! const Function *F = MF.getFunction();
// Align the output buffer to the appropriate alignment, power of 2.
unsigned FnAlign = F->getAlignment();
unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
unsigned Align = std::max(FnAlign, TDAlign);
assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
// Get the ELF Section that this function belongs in. // Get the ELF Section that this function belongs in.
ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS, ES = &EW.getTextSection();
ELFWriter::ELFSection::SHF_EXECINSTR |
ELFWriter::ELFSection::SHF_ALLOC); // FIXME: better memory management, this will be replaced by BinaryObjects
OutBuffer = &ES->SectionData; ES->SectionData.reserve(4096);
cerr << "FIXME: This code needs to be updated for changes in the " BufferBegin = &ES->SectionData[0];
<< "CodeEmitter interfaces. In particular, this should set " BufferEnd = BufferBegin + ES->SectionData.capacity();
<< "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!";
abort();
// Upgrade the section alignment if required. // Upgrade the section alignment if required.
if (ES->Align < Align) ES->Align = Align; if (ES->Align < Align) ES->Align = Align;
// Add padding zeros to the end of the buffer to make sure that the // Round the size up to the correct alignment for starting the new function.
// function will start on the correct byte alignment within the section. ES->Size = (ES->Size + (Align-1)) & (-Align);
OutputBuffer OB(*OutBuffer,
TM.getTargetData()->getPointerSizeInBits() == 64, // Snaity check on allocated space for text section
TM.getTargetData()->isLittleEndian()); assert( ES->Size < 4096 && "no more space in TextSection" );
OB.align(Align);
FnStart = OutBuffer->size(); // 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;
} }
/// finishFunction - This callback is invoked after the function is completely /// finishFunction - This callback is invoked after the function is completely
/// finished. /// finished.
bool ELFCodeEmitter::finishFunction(MachineFunction &F) { bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
// We now know the size of the function, add a symbol to represent it. // Add a symbol to represent the function.
ELFWriter::ELFSym FnSym(F.getFunction()); ELFWriter::ELFSym FnSym(MF.getFunction());
// Figure out the binding (linkage) of the symbol. // Figure out the binding (linkage) of the symbol.
switch (F.getFunction()->getLinkage()) { switch (MF.getFunction()->getLinkage()) {
default: default:
// appending linkage is illegal for functions. // appending linkage is illegal for functions.
assert(0 && "Unknown linkage type!"); assert(0 && "Unknown linkage type!");
@ -79,15 +94,20 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &F) {
break; break;
} }
ES->Size = OutBuffer->size(); // Set the symbol type as a function
FnSym.SetType(ELFWriter::ELFSym::STT_FUNC); FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
FnSym.SectionIdx = ES->SectionIdx; FnSym.SectionIdx = ES->SectionIdx;
FnSym.Value = FnStart; // Value = Offset from start of Section. FnSym.Size = CurBufferPtr-FnStartPtr;
FnSym.Size = OutBuffer->size()-FnStart;
// Offset from start of Section
FnSym.Value = FnStartPtr-BufferBegin;
// Finally, add it to the symtab. // Finally, add it to the symtab.
EW.SymbolTable.push_back(FnSym); EW.SymbolTable.push_back(FnSym);
// Update Section Size
ES->Size = CurBufferPtr - BufferBegin;
return false; return false;
} }

View File

@ -22,10 +22,9 @@ namespace llvm {
ELFWriter &EW; ELFWriter &EW;
TargetMachine &TM; TargetMachine &TM;
ELFWriter::ELFSection *ES; // Section to write to. ELFWriter::ELFSection *ES; // Section to write to.
std::vector<unsigned char> *OutBuffer; uint8_t *FnStartPtr;
size_t FnStart;
public: public:
explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {} explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM) {}
void startFunction(MachineFunction &F); void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F); bool finishFunction(MachineFunction &F);

View File

@ -168,6 +168,12 @@ namespace llvm {
return *SN; return *SN;
} }
ELFSection &getTextSection() {
return getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS,
ELFWriter::ELFSection::SHF_EXECINSTR |
ELFWriter::ELFSection::SHF_ALLOC);
}
ELFSection &getDataSection() { ELFSection &getDataSection() {
return getSection(".data", ELFSection::SHT_PROGBITS, return getSection(".data", ELFSection::SHT_PROGBITS,
ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC); ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC);