Move ELFCodeEmiter stuff to new files

llvm-svn: 72785
This commit is contained in:
Bruno Cardoso Lopes 2009-06-03 17:47:27 +00:00
parent 43896d0ee4
commit 8fa826d852
4 changed files with 184 additions and 140 deletions

View File

@ -3,6 +3,7 @@ add_llvm_library(LLVMCodeGen
CodePlacementOpt.cpp
DeadMachineInstructionElim.cpp
DwarfEHPrepare.cpp
ELFCodeEmitter.cpp
ELFWriter.cpp
GCMetadata.cpp
GCMetadataPrinter.cpp

View File

@ -0,0 +1,94 @@
//===-- lib/CodeGen/ELFCodeEmitter.cpp ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#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"
//===----------------------------------------------------------------------===//
// ELFCodeEmitter Implementation
//===----------------------------------------------------------------------===//
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!!
// 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();
// 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();
}
/// 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());
// Figure out the binding (linkage) of the symbol.
switch (F.getFunction()->getLinkage()) {
default:
// appending linkage is illegal for functions.
assert(0 && "Unknown linkage type!");
case GlobalValue::ExternalLinkage:
FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
break;
case GlobalValue::LinkOnceAnyLinkage:
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
break;
case GlobalValue::PrivateLinkage:
assert (0 && "PrivateLinkage should not be in the symbol table.");
case GlobalValue::InternalLinkage:
FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
break;
}
ES->Size = OutBuffer->size();
FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
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;
}
} // end namespace llvm

View File

@ -0,0 +1,87 @@
//===-- lib/CodeGen/ELFCodeEmitter.h ----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef ELFCODEEMITTER_H
#define ELFCODEEMITTER_H
#include "ELFWriter.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include <vector>
namespace llvm {
/// ELFCodeEmitter - This class is used by the ELFWriter to
/// emit the code for functions to the ELF file.
class ELFCodeEmitter : public MachineCodeEmitter {
ELFWriter &EW;
TargetMachine &TM;
ELFWriter::ELFSection *ES; // Section to write to.
std::vector<unsigned char> *OutBuffer;
size_t FnStart;
public:
explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F);
void addRelocation(const MachineRelocation &MR) {
assert(0 && "relo not handled yet!");
}
virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
}
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(0 && "CP not implementated yet!");
return 0;
}
virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(0 && "JT not implementated yet!");
return 0;
}
virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
assert(0 && "JT not implementated yet!");
return 0;
}
virtual uintptr_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 startGVStub(const GlobalValue* F, unsigned StubSize,
unsigned Alignment = 1) {
assert(0 && "JIT specific function called!");
abort();
}
void startGVStub(const GlobalValue* F, void *Buffer, unsigned StubSize) {
assert(0 && "JIT specific function called!");
abort();
}
void *finishGVStub(const GlobalValue *F) {
assert(0 && "JIT specific function called!");
abort();
return 0;
}
}; // end class ELFCodeEmitter
} // end namespace llvm
#endif

View File

@ -32,6 +32,7 @@
//===----------------------------------------------------------------------===//
#include "ELFWriter.h"
#include "ELFCodeEmitter.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/DerivedTypes.h"
@ -60,150 +61,11 @@ MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
return &EW->getMachineCodeEmitter();
}
//===----------------------------------------------------------------------===//
// ELFCodeEmitter Implementation
//===----------------------------------------------------------------------===//
namespace llvm {
/// ELFCodeEmitter - This class is used by the ELFWriter to emit the code for
/// functions to the ELF file.
class ELFCodeEmitter : public MachineCodeEmitter {
ELFWriter &EW;
TargetMachine &TM;
ELFWriter::ELFSection *ES; // Section to write to.
std::vector<unsigned char> *OutBuffer;
size_t FnStart;
public:
explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM), OutBuffer(0) {}
void startFunction(MachineFunction &F);
bool finishFunction(MachineFunction &F);
void addRelocation(const MachineRelocation &MR) {
assert(0 && "relo not handled yet!");
}
virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
}
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(0 && "CP not implementated yet!");
return 0;
}
virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(0 && "JT not implementated yet!");
return 0;
}
virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
assert(0 && "JT not implementated yet!");
return 0;
}
virtual uintptr_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 startGVStub(const GlobalValue* F, unsigned StubSize,
unsigned Alignment = 1) {
assert(0 && "JIT specific function called!");
abort();
}
void startGVStub(const GlobalValue* F, void *Buffer, unsigned StubSize) {
assert(0 && "JIT specific function called!");
abort();
}
void *finishGVStub(const GlobalValue *F) {
assert(0 && "JIT specific function called!");
abort();
return 0;
}
};
}
/// 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!!
// 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();
// 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();
}
/// 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());
// Figure out the binding (linkage) of the symbol.
switch (F.getFunction()->getLinkage()) {
default:
// appending linkage is illegal for functions.
assert(0 && "Unknown linkage type!");
case GlobalValue::ExternalLinkage:
FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL);
break;
case GlobalValue::LinkOnceAnyLinkage:
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK);
break;
case GlobalValue::PrivateLinkage:
assert (0 && "PrivateLinkage should not be in the symbol table.");
case GlobalValue::InternalLinkage:
FnSym.SetBind(ELFWriter::ELFSym::STB_LOCAL);
break;
}
ES->Size = OutBuffer->size();
FnSym.SetType(ELFWriter::ELFSym::STT_FUNC);
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;
}
//===----------------------------------------------------------------------===//
// ELFWriter Implementation
//===----------------------------------------------------------------------===//
ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm)
: MachineFunctionPass(&ID), O(o), TM(tm) {
e_flags = 0; // e_flags defaults to 0, no flags.