#ifndef ELFWRITER_H
#define ELFWRITER_H
#include "llvm/ADT/SetVector.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include <map>
namespace llvm {
class BinaryObject;
class Constant;
class ConstantInt;
class ConstantStruct;
class ELFCodeEmitter;
class ELFRelocation;
class ELFSection;
struct ELFSym;
class GlobalVariable;
class JITDebugRegisterer;
class Mangler;
class MachineCodeEmitter;
class MachineConstantPoolEntry;
class ObjectCodeEmitter;
class MCAsmInfo;
class TargetELFWriterInfo;
class TargetLoweringObjectFile;
class raw_ostream;
class SectionKind;
class MCContext;
typedef std::vector<ELFSym*>::iterator ELFSymIter;
typedef std::vector<ELFSection*>::iterator ELFSectionIter;
typedef SetVector<const GlobalValue*>::const_iterator PendingGblsIter;
typedef SetVector<const char *>::const_iterator PendingExtsIter;
typedef std::pair<const Constant *, int64_t> CstExprResTy;
class ELFWriter : public MachineFunctionPass {
friend class ELFCodeEmitter;
friend class JITDebugRegisterer;
public:
static char ID;
ObjectCodeEmitter *getObjectCodeEmitter() {
return reinterpret_cast<ObjectCodeEmitter*>(ElfCE);
}
ELFWriter(raw_ostream &O, TargetMachine &TM);
~ELFWriter();
protected:
raw_ostream &O;
TargetMachine &TM;
MCContext &OutContext;
const TargetELFWriterInfo *TEW;
Mangler *Mang;
ELFCodeEmitter *ElfCE;
const TargetLoweringObjectFile &TLOF;
const MCAsmInfo *MAI;
bool is64Bit, isLittleEndian;
bool doInitialization(Module &M);
bool runOnMachineFunction(MachineFunction &MF);
bool doFinalization(Module &M);
private:
BinaryObject ElfHdr;
std::vector<ELFSection*> SectionList;
unsigned NumSections;
std::map<std::string, ELFSection*> SectionLookup;
SetVector<const GlobalValue*> PendingGlobals;
std::map<const GlobalValue*, uint32_t> GblSymLookup;
SetVector<const char *> PendingExternals;
std::map<const char *, uint32_t> ExtSymLookup;
std::vector<ELFSym*> SymbolList;
std::vector<ELFSym*> PrivateSyms;
ELFSection &getSection(const std::string &Name, unsigned Type,
unsigned Flags = 0, unsigned Align = 0) {
ELFSection *&SN = SectionLookup[Name];
if (SN) return *SN;
SectionList.push_back(new ELFSection(Name, isLittleEndian, is64Bit));
SN = SectionList.back();
SN->SectionIdx = NumSections++;
SN->Type = Type;
SN->Flags = Flags;
SN->Link = ELFSection::SHN_UNDEF;
SN->Align = Align;
return *SN;
}
ELFSection &getNonExecStackSection() {
return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1);
}
ELFSection &getSymbolTableSection() {
return getSection(".symtab", ELFSection::SHT_SYMTAB, 0);
}
ELFSection &getStringTableSection() {
return getSection(".strtab", ELFSection::SHT_STRTAB, 0, 1);
}
ELFSection &getSectionHeaderStringTableSection() {
return getSection(".shstrtab", ELFSection::SHT_STRTAB, 0, 1);
}
ELFSection &getNullSection() {
return getSection("", ELFSection::SHT_NULL, 0);
}
ELFSection &getDataSection();
ELFSection &getBSSSection();
ELFSection &getCtorSection();
ELFSection &getDtorSection();
ELFSection &getJumpTableSection();
ELFSection &getConstantPoolSection(MachineConstantPoolEntry &CPE);
ELFSection &getTextSection(Function *F);
ELFSection &getRelocSection(ELFSection &S);
unsigned getGlobalELFBinding(const GlobalValue *GV);
unsigned getGlobalELFType(const GlobalValue *GV);
unsigned getGlobalELFVisibility(const GlobalValue *GV);
void AddPendingGlobalSymbol(const GlobalValue *GV,
bool AddToLookup = false);
void AddPendingExternalSymbol(const char *External);
void AddToSymbolList(ELFSym *GblSym);
unsigned ELFHdr_e_shoff_Offset; unsigned ELFHdr_e_shstrndx_Offset; unsigned ELFHdr_e_shnum_Offset;
private:
void EmitGlobal(const GlobalValue *GV);
void EmitGlobalConstant(const Constant *C, ELFSection &GblS);
void EmitGlobalConstantStruct(const ConstantStruct *CVS,
ELFSection &GblS);
void EmitGlobalConstantLargeInt(const ConstantInt *CI, ELFSection &S);
void EmitGlobalDataRelocation(const GlobalValue *GV, unsigned Size,
ELFSection &GblS, int64_t Offset = 0);
bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
void EmitXXStructorList(Constant *List, ELFSection &Xtor);
void EmitRelocations();
void EmitRelocation(BinaryObject &RelSec, ELFRelocation &Rel, bool HasRelA);
void EmitSectionHeader(BinaryObject &SHdrTab, const ELFSection &SHdr);
void EmitSectionTableStringTable();
void EmitSymbol(BinaryObject &SymbolTable, ELFSym &Sym);
void EmitSymbolTable();
void EmitStringTable(const std::string &ModuleName);
void OutputSectionsAndSectionTable();
void RelocateField(BinaryObject &BO, uint32_t Offset, int64_t Value,
unsigned Size);
unsigned SortSymbols();
CstExprResTy ResolveConstantExpr(const Constant *CV);
};
}
#endif