//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Chris Lattner and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
-#include "llvm/CodeGen/ELFWriter.h"
+#include "ELFWriter.h"
#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/CodeGen/FileWriters.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetELFWriterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/OutputBuffer.h"
#include "llvm/Support/Streams.h"
+#include <list>
using namespace llvm;
+char ELFWriter::ID = 0;
+/// AddELFWriter - Concrete function to add the ELF writer to the function pass
+/// manager.
+MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
+ std::ostream &O,
+ TargetMachine &TM) {
+ ELFWriter *EW = new ELFWriter(O, TM);
+ PM.add(EW);
+ return &EW->getMachineCodeEmitter();
+}
+
//===----------------------------------------------------------------------===//
// ELFCodeEmitter Implementation
//===----------------------------------------------------------------------===//
std::vector<unsigned char> *OutBuffer;
size_t FnStart;
public:
- ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
+ explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F);
return 0;
}
+ virtual intptr_t getLabelAddress(uint64_t Label) const {
+ assert(0 && "Label address not implementated yet!");
+ abort();
+ return 0;
+ }
+
+ virtual void emitLabel(uint64_t LabelID) {
+ assert(0 && "emit Label not implementated yet!");
+ abort();
+ }
+
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
+
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
- void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
+ void startFunctionStub(const GlobalValue* F, unsigned StubSize,
+ unsigned Alignment = 1) {
assert(0 && "JIT specific function called!");
abort();
}
- void *finishFunctionStub(const Function *F) {
+ void *finishFunctionStub(const GlobalValue *F) {
assert(0 && "JIT specific function called!");
abort();
return 0;
// 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(TM, *OutBuffer);
+ OutputBuffer OB(*OutBuffer,
+ TM.getTargetData()->getPointerSizeInBits() == 64,
+ TM.getTargetData()->isLittleEndian());
OB.align(Align);
FnStart = OutBuffer->size();
}
// ELFWriter Implementation
//===----------------------------------------------------------------------===//
-ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) {
- e_machine = 0; // e_machine defaults to 'No Machine'
+ELFWriter::ELFWriter(std::ostream &o, TargetMachine &tm)
+ : MachineFunctionPass((intptr_t)&ID), O(o), TM(tm) {
e_flags = 0; // e_flags defaults to 0, no flags.
is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
// Local alias to shortenify coming code.
std::vector<unsigned char> &FH = FileHeader;
- OutputBuffer FHOut(TM, FH);
+ OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
FHOut.outbyte(0x7F); // EI_MAG0
FHOut.outbyte('E'); // EI_MAG1
// This should change for shared objects.
FHOut.outhalf(1); // e_type = ET_REL
- FHOut.outhalf(e_machine); // e_machine = whatever the target wants
+ FHOut.outword(TM.getELFWriterInfo()->getEMachine()); // target-defined
FHOut.outword(1); // e_version = 1
FHOut.outaddr(0); // e_entry = 0 -> no entry point in .o file
FHOut.outaddr(0); // e_phoff = 0 -> no program header for .o
}
const Type *GVType = (const Type*)GV->getType();
- unsigned Align = TM.getTargetData()->getTypeAlignment(GVType);
- unsigned Size = TM.getTargetData()->getTypeSize(GVType);
+ unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
+ unsigned Size = TM.getTargetData()->getABITypeSize(GVType);
// If this global has a zero initializer, it is part of the .bss or common
// section.
StrTab.Align = 1;
DataBuffer &StrTabBuf = StrTab.SectionData;
- OutputBuffer StrTabOut(TM, StrTabBuf);
+ OutputBuffer StrTabOut(StrTabBuf, is64Bit, isLittleEndian);
// Set the zero'th symbol to a null byte, as required.
StrTabOut.outbyte(0);
SymTab.Info = FirstNonLocalSymbol; // First non-STB_LOCAL symbol.
SymTab.EntSize = 16; // Size of each symtab entry. FIXME: wrong for ELF64
DataBuffer &SymTabBuf = SymTab.SectionData;
- OutputBuffer SymTabOut(TM, SymTabBuf);
+ OutputBuffer SymTabOut(SymTabBuf, is64Bit, isLittleEndian);
if (!is64Bit) { // 32-bit and 64-bit formats are shuffled a bit.
for (unsigned i = 0, e = SymbolTable.size(); i != e; ++i) {
// Now that we know which section number is the .shstrtab section, update the
// e_shstrndx entry in the ELF header.
- OutputBuffer FHOut(TM, FileHeader);
+ OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
FHOut.fixhalf(SHStrTab.SectionIdx, ELFHeader_e_shstrndx_Offset);
// Set the NameIdx of each section in the string table and emit the bytes for
// Now that we know where all of the sections will be emitted, set the e_shnum
// entry in the ELF header.
- OutputBuffer FHOut(TM, FileHeader);
+ OutputBuffer FHOut(FileHeader, is64Bit, isLittleEndian);
FHOut.fixhalf(NumSections, ELFHeader_e_shnum_Offset);
// Now that we know the offset in the file of the section table, update the
DataBuffer().swap(FileHeader);
DataBuffer Table;
- OutputBuffer TableOut(TM, Table);
+ OutputBuffer TableOut(Table, is64Bit, isLittleEndian);
// Emit all of the section data and build the section table itself.
while (!SectionList.empty()) {