aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-06-05 00:22:10 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-06-05 00:22:10 +0000
commit5d4191039645f2eeb90148d7359199ad21c75347 (patch)
tree9265142bcd2e2d85eb1ecf56d1467429e060634c
parent9f5f322a032cc22b5375cf698ac58fe7644547c0 (diff)
downloadexternal_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.cpp78
-rw-r--r--lib/CodeGen/ELFCodeEmitter.h5
-rw-r--r--lib/CodeGen/ELFWriter.h6
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);