// #3. ".bss" entry - global variables without initializers. [ if needed ]
// ...
// #N. ".shstrtab" entry - String table for the section names.
-
//
// NOTE: This code should eventually be extended to support 64-bit ELF (this
// won't be hard), but we haven't done so yet!
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
+#include <iostream>
using namespace llvm;
//===----------------------------------------------------------------------===//
ELFCodeEmitter(ELFWriter &ew) : EW(ew), OutBuffer(0) {}
void startFunction(MachineFunction &F);
- void finishFunction(MachineFunction &F);
+ bool finishFunction(MachineFunction &F);
- void emitConstantPool(MachineConstantPool *MCP) {
- if (MCP->isEmpty()) return;
- assert(0 && "unimp");
- }
- virtual void emitByte(unsigned char B) {
- OutBuffer->push_back(B);
- }
- virtual void emitWordAt(unsigned W, unsigned *Ptr) {
- assert(0 && "ni");
- }
- virtual void emitWord(unsigned W) {
- assert(0 && "ni");
- }
- virtual uint64_t getCurrentPCValue() {
- return OutBuffer->size();
- }
- virtual uint64_t getCurrentPCOffset() {
- return OutBuffer->size()-FnStart;
- }
void addRelocation(const MachineRelocation &MR) {
assert(0 && "relo not handled yet!");
}
- virtual uint64_t getConstantPoolEntryAddress(unsigned Index) {
+
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
+ }
+
+ virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(0 && "CP not implementated yet!");
return 0;
}
+ virtual intptr_t getJumpTableEntryAddress(unsigned Index) const {
+ assert(0 && "JT not implementated yet!");
+ return 0;
+ }
+
+ virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
+ assert(0 && "JT not implementated yet!");
+ return 0;
+ }
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
void startFunctionStub(unsigned StubSize) {
ELFWriter::ELFSection::SHF_EXECINSTR |
ELFWriter::ELFSection::SHF_ALLOC);
OutBuffer = &ES->SectionData;
-
+ std::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();
+
// 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.
size_t SectionOff = OutBuffer->size();
ELFWriter::align(*OutBuffer, Align);
-
+
FnStart = OutBuffer->size();
}
/// finishFunction - This callback is invoked after the function is completely
/// finished.
-void ELFCodeEmitter::finishFunction(MachineFunction &F) {
+bool ELFCodeEmitter::finishFunction(MachineFunction &F) {
// We now know the size of the function, add a symbol to represent it.
ELFWriter::ELFSym FnSym(F.getFunction());
-
+
// Figure out the binding (linkage) of the symbol.
switch (F.getFunction()->getLinkage()) {
default:
FnSym.SectionIdx = ES->SectionIdx;
FnSym.Value = FnStart; // Value = Offset from start of Section.
FnSym.Size = OutBuffer->size()-FnStart;
-
+
// Finally, add it to the symtab.
EW.SymbolTable.push_back(FnSym);
+ return false;
}
//===----------------------------------------------------------------------===//
e_machine = 0; // e_machine defaults to 'No Machine'
e_flags = 0; // e_flags defaults to 0, no flags.
- is64Bit = TM.getTargetData().getPointerSizeInBits() == 64;
- isLittleEndian = TM.getTargetData().isLittleEndian();
+ is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
+ isLittleEndian = TM.getTargetData()->isLittleEndian();
// Create the machine code emitter object for this target.
MCE = new ELFCodeEmitter(*this);
// Local alias to shortenify coming code.
std::vector<unsigned char> &FH = FileHeader;
-
+
outbyte(FH, 0x7F); // EI_MAG0
outbyte(FH, 'E'); // EI_MAG1
outbyte(FH, 'L'); // EI_MAG2
outbyte(FH, isLittleEndian ? 1 : 2); // EI_DATA
outbyte(FH, 1); // EI_VERSION
FH.resize(16); // EI_PAD up to 16 bytes.
-
+
// This should change for shared objects.
outhalf(FH, 1); // e_type = ET_REL
outhalf(FH, e_machine); // e_machine = whatever the target wants
outhalf(FH, 0); // e_phnum = # prog header entries = 0
outhalf(FH, is64Bit ? 64 : 40); // e_shentsize = sect hdr entry size
-
+
ELFHeader_e_shnum_Offset = FH.size();
outhalf(FH, 0); // e_shnum = # of section header ents
ELFHeader_e_shstrndx_Offset = FH.size();
SymbolTable.push_back(ExternalSym);
return;
}
-
+
const Type *GVType = (const Type*)GV->getType();
- unsigned Align = TM.getTargetData().getTypeAlignment(GVType);
- unsigned Size = TM.getTargetData().getTypeSize(GVType);
+ unsigned Align = TM.getTargetData()->getTypeAlignment(GVType);
+ unsigned Size = TM.getTargetData()->getTypeSize(GVType);
// If this global has a zero initializer, it is part of the .bss or common
// section.
// Now that we know where all of the sections will be emitted, set the e_shnum
// entry in the ELF header.
fixhalf(FileHeader, NumSections, ELFHeader_e_shnum_Offset);
-
+
// Now that we know the offset in the file of the section table, update the
// e_shoff address in the ELF header.
fixaddr(FileHeader, FileOff, ELFHeader_e_shoff_Offset);
-
+
// Now that we know all of the data in the file header, emit it and all of the
// sections!
O.write((char*)&FileHeader[0], FileHeader.size());
if (S.Align)
for (size_t NewFileOff = (FileOff+S.Align-1) & ~(S.Align-1);
FileOff != NewFileOff; ++FileOff)
- O.put(0xAB);
+ O.put((char)0xAB);
O.write((char*)&S.SectionData[0], S.SectionData.size());
FileOff += S.SectionData.size();
// Align output for the section table.
for (size_t NewFileOff = (FileOff+TableAlign-1) & ~(TableAlign-1);
FileOff != NewFileOff; ++FileOff)
- O.put(0xAB);
-
+ O.put((char)0xAB);
+
// Emit the section table itself.
O.write((char*)&Table[0], Table.size());
}