diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2009-06-05 00:22:10 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2009-06-05 00:22:10 +0000 |
commit | 5d4191039645f2eeb90148d7359199ad21c75347 (patch) | |
tree | 9265142bcd2e2d85eb1ecf56d1467429e060634c | |
parent | 9f5f322a032cc22b5375cf698ac58fe7644547c0 (diff) | |
download | external_llvm-5d4191039645f2eeb90148d7359199ad21c75347.zip external_llvm-5d4191039645f2eeb90148d7359199ad21c75347.tar.gz external_llvm-5d4191039645f2eeb90148d7359199ad21c75347.tar.bz2 |
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
-rw-r--r-- | lib/CodeGen/ELFCodeEmitter.cpp | 78 | ||||
-rw-r--r-- | lib/CodeGen/ELFCodeEmitter.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/ELFWriter.h | 6 |
3 files changed, 57 insertions, 32 deletions
diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp index 0a0245f..9e8accd 100644 --- a/lib/CodeGen/ELFCodeEmitter.cpp +++ b/lib/CodeGen/ELFCodeEmitter.cpp @@ -7,17 +7,17 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "elfce" + #include "ELFCodeEmitter.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/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Support/Mangler.h" -#include "llvm/Support/OutputBuffer.h" +#include "llvm/Support/Debug.h" //===----------------------------------------------------------------------===// // ELFCodeEmitter Implementation @@ -27,39 +27,54 @@ namespace llvm { /// startFunction - This callback is invoked when a new machine function is /// about to be emitted. -void ELFCodeEmitter::startFunction(MachineFunction &F) { - // Align the output buffer to the appropriate alignment. - unsigned Align = 16; // FIXME: GENERICIZE!! +void ELFCodeEmitter::startFunction(MachineFunction &MF) { + const TargetData *TD = TM.getTargetData(); + 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. - ES = &EW.getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS, - ELFWriter::ELFSection::SHF_EXECINSTR | - ELFWriter::ELFSection::SHF_ALLOC); - OutBuffer = &ES->SectionData; - cerr << "FIXME: This code needs to be updated for changes in the " - << "CodeEmitter interfaces. In particular, this should set " - << "BufferBegin/BufferEnd/CurBufferPtr, not deal with OutBuffer!"; - abort(); + ES = &EW.getTextSection(); + + // FIXME: better memory management, this will be replaced by BinaryObjects + ES->SectionData.reserve(4096); + BufferBegin = &ES->SectionData[0]; + BufferEnd = BufferBegin + ES->SectionData.capacity(); // Upgrade the section alignment if required. if (ES->Align < Align) ES->Align = Align; - // Add padding zeros to the end of the buffer to make sure that the - // function will start on the correct byte alignment within the section. - OutputBuffer OB(*OutBuffer, - TM.getTargetData()->getPointerSizeInBits() == 64, - TM.getTargetData()->isLittleEndian()); - OB.align(Align); - FnStart = OutBuffer->size(); + // Round the size up to the correct alignment for starting the new function. + 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; } /// finishFunction - This callback is invoked after the function is completely /// finished. -bool ELFCodeEmitter::finishFunction(MachineFunction &F) { - // We now know the size of the function, add a symbol to represent it. - ELFWriter::ELFSym FnSym(F.getFunction()); +bool ELFCodeEmitter::finishFunction(MachineFunction &MF) { + // Add a symbol to represent the function. + ELFWriter::ELFSym FnSym(MF.getFunction()); // Figure out the binding (linkage) of the symbol. - switch (F.getFunction()->getLinkage()) { + switch (MF.getFunction()->getLinkage()) { default: // appending linkage is illegal for functions. assert(0 && "Unknown linkage type!"); @@ -79,15 +94,20 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &F) { break; } - ES->Size = OutBuffer->size(); - + // Set the symbol type as a function FnSym.SetType(ELFWriter::ELFSym::STT_FUNC); + FnSym.SectionIdx = ES->SectionIdx; - FnSym.Value = FnStart; // Value = Offset from start of Section. - FnSym.Size = OutBuffer->size()-FnStart; + FnSym.Size = CurBufferPtr-FnStartPtr; + + // Offset from start of Section + FnSym.Value = FnStartPtr-BufferBegin; // Finally, add it to the symtab. EW.SymbolTable.push_back(FnSym); + + // Update Section Size + ES->Size = CurBufferPtr - BufferBegin; return false; } diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h index 11ebcc8..7ea4d71 100644 --- a/lib/CodeGen/ELFCodeEmitter.h +++ b/lib/CodeGen/ELFCodeEmitter.h @@ -22,10 +22,9 @@ namespace llvm { ELFWriter &EW; TargetMachine &TM; ELFWriter::ELFSection *ES; // Section to write to. - std::vector<unsigned char> *OutBuffer; - size_t FnStart; + uint8_t *FnStartPtr; 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); bool finishFunction(MachineFunction &F); diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h index 31aa05a..63d692b 100644 --- a/lib/CodeGen/ELFWriter.h +++ b/lib/CodeGen/ELFWriter.h @@ -168,6 +168,12 @@ namespace llvm { return *SN; } + ELFSection &getTextSection() { + return getSection(".text", ELFWriter::ELFSection::SHT_PROGBITS, + ELFWriter::ELFSection::SHF_EXECINSTR | + ELFWriter::ELFSection::SHF_ALLOC); + } + ELFSection &getDataSection() { return getSection(".data", ELFSection::SHT_PROGBITS, ELFSection::SHF_WRITE | ELFSection::SHF_ALLOC); |