mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Move ELFCodeEmiter stuff to new files
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72785 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bae049cd9e
commit
4cb31436bd
@ -3,6 +3,7 @@ add_llvm_library(LLVMCodeGen
|
|||||||
CodePlacementOpt.cpp
|
CodePlacementOpt.cpp
|
||||||
DeadMachineInstructionElim.cpp
|
DeadMachineInstructionElim.cpp
|
||||||
DwarfEHPrepare.cpp
|
DwarfEHPrepare.cpp
|
||||||
|
ELFCodeEmitter.cpp
|
||||||
ELFWriter.cpp
|
ELFWriter.cpp
|
||||||
GCMetadata.cpp
|
GCMetadata.cpp
|
||||||
GCMetadataPrinter.cpp
|
GCMetadataPrinter.cpp
|
||||||
|
94
lib/CodeGen/ELFCodeEmitter.cpp
Normal file
94
lib/CodeGen/ELFCodeEmitter.cpp
Normal 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
|
87
lib/CodeGen/ELFCodeEmitter.h
Normal file
87
lib/CodeGen/ELFCodeEmitter.h
Normal 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
|
||||||
|
|
@ -32,6 +32,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "ELFWriter.h"
|
#include "ELFWriter.h"
|
||||||
|
#include "ELFCodeEmitter.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/PassManager.h"
|
#include "llvm/PassManager.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
@ -60,145 +61,6 @@ MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM,
|
|||||||
return &EW->getMachineCodeEmitter();
|
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 Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user