diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/CodeGen/ELF.h | 227 | ||||
-rw-r--r-- | lib/CodeGen/ELFCodeEmitter.cpp | 205 | ||||
-rw-r--r-- | lib/CodeGen/ELFCodeEmitter.h | 78 | ||||
-rw-r--r-- | lib/CodeGen/ELFWriter.cpp | 1105 | ||||
-rw-r--r-- | lib/CodeGen/ELFWriter.h | 251 |
6 files changed, 0 insertions, 1868 deletions
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 09d109b7bc..0868eebe2e 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -12,8 +12,6 @@ add_llvm_library(LLVMCodeGen DFAPacketizer.cpp DwarfEHPrepare.cpp EdgeBundles.cpp - ELFCodeEmitter.cpp - ELFWriter.cpp ExecutionDepsFix.cpp ExpandISelPseudos.cpp ExpandPostRAPseudos.cpp diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h deleted file mode 100644 index 5b634682cc..0000000000 --- a/lib/CodeGen/ELF.h +++ /dev/null @@ -1,227 +0,0 @@ -//===-- lib/CodeGen/ELF.h - ELF constants and data structures ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header contains common, non-processor-specific data structures and -// constants for the ELF file format. -// -// The details of the ELF32 bits in this file are largely based on the Tool -// Interface Standard (TIS) Executable and Linking Format (ELF) Specification -// Version 1.2, May 1995. The ELF64 is based on HP/Intel definition of the -// ELF-64 object file format document, Version 1.5 Draft 2 May 27, 1998 -// -//===----------------------------------------------------------------------===// - -#ifndef CODEGEN_ELF_H -#define CODEGEN_ELF_H - -#include "llvm/CodeGen/BinaryObject.h" -#include "llvm/CodeGen/MachineRelocation.h" -#include "llvm/Support/ELF.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { - class GlobalValue; - - /// ELFSym - This struct contains information about each symbol that is - /// added to logical symbol table for the module. This is eventually - /// turned into a real symbol table in the file. - struct ELFSym { - - // ELF symbols are related to llvm ones by being one of the two llvm - // types, for the other ones (section, file, func) a null pointer is - // assumed by default. - union { - const GlobalValue *GV; // If this is a pointer to a GV - const char *Ext; // If this is a pointer to a named symbol - } Source; - - // Describes from which source type this ELF symbol comes from, - // they can be GlobalValue, ExternalSymbol or neither. - enum { - isGV, // The Source.GV field is valid. - isExtSym, // The Source.ExtSym field is valid. - isOther // Not a GlobalValue or External Symbol - }; - unsigned SourceType; - - bool isGlobalValue() const { return SourceType == isGV; } - bool isExternalSym() const { return SourceType == isExtSym; } - - // getGlobalValue - If this is a global value which originated the - // elf symbol, return a reference to it. - const GlobalValue *getGlobalValue() const { - assert(SourceType == isGV && "This is not a global value"); - return Source.GV; - } - - // getExternalSym - If this is an external symbol which originated the - // elf symbol, return a reference to it. - const char *getExternalSymbol() const { - assert(SourceType == isExtSym && "This is not an external symbol"); - return Source.Ext; - } - - // getGV - From a global value return a elf symbol to represent it - static ELFSym *getGV(const GlobalValue *GV, unsigned Bind, - unsigned Type, unsigned Visibility) { - ELFSym *Sym = new ELFSym(); - Sym->Source.GV = GV; - Sym->setBind(Bind); - Sym->setType(Type); - Sym->setVisibility(Visibility); - Sym->SourceType = isGV; - return Sym; - } - - // getExtSym - Create and return an elf symbol to represent an - // external symbol - static ELFSym *getExtSym(const char *Ext) { - ELFSym *Sym = new ELFSym(); - Sym->Source.Ext = Ext; - Sym->setBind(ELF::STB_GLOBAL); - Sym->setType(ELF::STT_NOTYPE); - Sym->setVisibility(ELF::STV_DEFAULT); - Sym->SourceType = isExtSym; - return Sym; - } - - // getSectionSym - Returns a elf symbol to represent an elf section - static ELFSym *getSectionSym() { - ELFSym *Sym = new ELFSym(); - Sym->setBind(ELF::STB_LOCAL); - Sym->setType(ELF::STT_SECTION); - Sym->setVisibility(ELF::STV_DEFAULT); - Sym->SourceType = isOther; - return Sym; - } - - // getFileSym - Returns a elf symbol to represent the module identifier - static ELFSym *getFileSym() { - ELFSym *Sym = new ELFSym(); - Sym->setBind(ELF::STB_LOCAL); - Sym->setType(ELF::STT_FILE); - Sym->setVisibility(ELF::STV_DEFAULT); - Sym->SectionIdx = 0xfff1; // ELFSection::SHN_ABS; - Sym->SourceType = isOther; - return Sym; - } - - // getUndefGV - Returns a STT_NOTYPE symbol - static ELFSym *getUndefGV(const GlobalValue *GV, unsigned Bind) { - ELFSym *Sym = new ELFSym(); - Sym->Source.GV = GV; - Sym->setBind(Bind); - Sym->setType(ELF::STT_NOTYPE); - Sym->setVisibility(ELF::STV_DEFAULT); - Sym->SectionIdx = 0; //ELFSection::SHN_UNDEF; - Sym->SourceType = isGV; - return Sym; - } - - // ELF specific fields - unsigned NameIdx; // Index in .strtab of name, once emitted. - uint64_t Value; - unsigned Size; - uint8_t Info; - uint8_t Other; - unsigned short SectionIdx; - - // Symbol index into the Symbol table - unsigned SymTabIdx; - - ELFSym() : SourceType(isOther), NameIdx(0), Value(0), - Size(0), Info(0), Other(ELF::STV_DEFAULT), SectionIdx(0), - SymTabIdx(0) {} - - unsigned getBind() const { return (Info >> 4) & 0xf; } - unsigned getType() const { return Info & 0xf; } - bool isLocalBind() const { return getBind() == ELF::STB_LOCAL; } - bool isFileType() const { return getType() == ELF::STT_FILE; } - - void setBind(unsigned X) { - assert(X == (X & 0xF) && "Bind value out of range!"); - Info = (Info & 0x0F) | (X << 4); - } - - void setType(unsigned X) { - assert(X == (X & 0xF) && "Type value out of range!"); - Info = (Info & 0xF0) | X; - } - - void setVisibility(unsigned V) { - assert(V == (V & 0x3) && "Visibility value out of range!"); - Other = V; - } - }; - - /// ELFSection - This struct contains information about each section that is - /// emitted to the file. This is eventually turned into the section header - /// table at the end of the file. - class ELFSection : public BinaryObject { - public: - // ELF specific fields - unsigned NameIdx; // sh_name - .shstrtab idx of name, once emitted. - unsigned Type; // sh_type - Section contents & semantics - unsigned Flags; // sh_flags - Section flags. - uint64_t Addr; // sh_addr - The mem addr this section is in. - unsigned Offset; // sh_offset - Offset from the file start - unsigned Size; // sh_size - The section size. - unsigned Link; // sh_link - Section header table index link. - unsigned Info; // sh_info - Auxiliary information. - unsigned Align; // sh_addralign - Alignment of section. - unsigned EntSize; // sh_entsize - Size of entries in the section e - - /// SectionIdx - The number of the section in the Section Table. - unsigned short SectionIdx; - - /// Sym - The symbol to represent this section if it has one. - ELFSym *Sym; - - /// getSymIndex - Returns the symbol table index of the symbol - /// representing this section. - unsigned getSymbolTableIndex() const { - assert(Sym && "section not present in the symbol table"); - return Sym->SymTabIdx; - } - - ELFSection(const std::string &name, bool isLittleEndian, bool is64Bit) - : BinaryObject(name, isLittleEndian, is64Bit), Type(0), Flags(0), Addr(0), - Offset(0), Size(0), Link(0), Info(0), Align(0), EntSize(0), Sym(0) {} - }; - - /// ELFRelocation - This class contains all the information necessary to - /// to generate any 32-bit or 64-bit ELF relocation entry. - class ELFRelocation { - uint64_t r_offset; // offset in the section of the object this applies to - uint32_t r_symidx; // symbol table index of the symbol to use - uint32_t r_type; // machine specific relocation type - int64_t r_add; // explicit relocation addend - bool r_rela; // if true then the addend is part of the entry - // otherwise the addend is at the location specified - // by r_offset - public: - uint64_t getInfo(bool is64Bit) const { - if (is64Bit) - return ((uint64_t)r_symidx << 32) + ((uint64_t)r_type & 0xFFFFFFFFL); - else - return (r_symidx << 8) + (r_type & 0xFFL); - } - - uint64_t getOffset() const { return r_offset; } - int64_t getAddend() const { return r_add; } - - ELFRelocation(uint64_t off, uint32_t sym, uint32_t type, - bool rela = true, int64_t addend = 0) : - r_offset(off), r_symidx(sym), r_type(type), - r_add(addend), r_rela(rela) {} - }; - -} // end namespace llvm - -#endif diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp deleted file mode 100644 index 660424c3c1..0000000000 --- a/lib/CodeGen/ELFCodeEmitter.cpp +++ /dev/null @@ -1,205 +0,0 @@ -//===-- 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. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "elfce" - -#include "ELF.h" -#include "ELFWriter.h" -#include "ELFCodeEmitter.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/CodeGen/BinaryObject.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/CodeGen/MachineRelocation.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetELFWriterInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" - -//===----------------------------------------------------------------------===// -// ELFCodeEmitter Implementation -//===----------------------------------------------------------------------===// - -namespace llvm { - -/// startFunction - This callback is invoked when a new machine function is -/// about to be emitted. -void ELFCodeEmitter::startFunction(MachineFunction &MF) { - DEBUG(dbgs() << "processing function: " - << MF.getFunction()->getName() << "\n"); - - // Get the ELF Section that this function belongs in. - ES = &EW.getTextSection(MF.getFunction()); - - // Set the desired binary object to be used by the code emitters - setBinaryObject(ES); - - // Get the function alignment in bytes - unsigned Align = (1 << MF.getAlignment()); - - // The function must start on its required alignment - ES->emitAlignment(Align); - - // Update the section alignment if needed. - ES->Align = std::max(ES->Align, Align); - - // Record the function start offset - FnStartOff = ES->getCurrentPCOffset(); - - // Emit constant pool and jump tables to their appropriate sections. - // They need to be emitted before the function because in some targets - // the later may reference JT or CP entry address. - emitConstantPool(MF.getConstantPool()); - if (MF.getJumpTableInfo()) - emitJumpTables(MF.getJumpTableInfo()); -} - -/// finishFunction - This callback is invoked after the function is completely -/// finished. -bool ELFCodeEmitter::finishFunction(MachineFunction &MF) { - // Add a symbol to represent the function. - const Function *F = MF.getFunction(); - ELFSym *FnSym = ELFSym::getGV(F, EW.getGlobalELFBinding(F), ELF::STT_FUNC, - EW.getGlobalELFVisibility(F)); - FnSym->SectionIdx = ES->SectionIdx; - FnSym->Size = ES->getCurrentPCOffset()-FnStartOff; - EW.AddPendingGlobalSymbol(F, true); - - // Offset from start of Section - FnSym->Value = FnStartOff; - - if (!F->hasPrivateLinkage()) - EW.SymbolList.push_back(FnSym); - - // Patch up Jump Table Section relocations to use the real MBBs offsets - // now that the MBB label offsets inside the function are known. - if (MF.getJumpTableInfo()) { - ELFSection &JTSection = EW.getJumpTableSection(); - for (std::vector<MachineRelocation>::iterator MRI = JTRelocations.begin(), - MRE = JTRelocations.end(); MRI != MRE; ++MRI) { - MachineRelocation &MR = *MRI; - uintptr_t MBBOffset = getMachineBasicBlockAddress(MR.getBasicBlock()); - MR.setResultPointer((void*)MBBOffset); - MR.setConstantVal(ES->SectionIdx); - JTSection.addRelocation(MR); - } - } - - // If we have emitted any relocations to function-specific objects such as - // basic blocks, constant pools entries, or jump tables, record their - // addresses now so that we can rewrite them with the correct addresses later - for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { - MachineRelocation &MR = Relocations[i]; - intptr_t Addr; - if (MR.isGlobalValue()) { - EW.AddPendingGlobalSymbol(MR.getGlobalValue()); - } else if (MR.isExternalSymbol()) { - EW.AddPendingExternalSymbol(MR.getExternalSymbol()); - } else if (MR.isBasicBlock()) { - Addr = getMachineBasicBlockAddress(MR.getBasicBlock()); - MR.setConstantVal(ES->SectionIdx); - MR.setResultPointer((void*)Addr); - } else if (MR.isConstantPoolIndex()) { - Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex()); - MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]); - MR.setResultPointer((void*)Addr); - } else if (MR.isJumpTableIndex()) { - ELFSection &JTSection = EW.getJumpTableSection(); - Addr = getJumpTableEntryAddress(MR.getJumpTableIndex()); - MR.setConstantVal(JTSection.SectionIdx); - MR.setResultPointer((void*)Addr); - } else { - llvm_unreachable("Unhandled relocation type"); - } - ES->addRelocation(MR); - } - - // Clear per-function data structures. - JTRelocations.clear(); - Relocations.clear(); - CPLocations.clear(); - CPSections.clear(); - JTLocations.clear(); - MBBLocations.clear(); - return false; -} - -/// emitConstantPool - For each constant pool entry, figure out which section -/// the constant should live in and emit the constant -void ELFCodeEmitter::emitConstantPool(MachineConstantPool *MCP) { - const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); - if (CP.empty()) return; - - // TODO: handle PIC codegen - assert(TM.getRelocationModel() != Reloc::PIC_ && - "PIC codegen not yet handled for elf constant pools!"); - - for (unsigned i = 0, e = CP.size(); i != e; ++i) { - MachineConstantPoolEntry CPE = CP[i]; - - // Record the constant pool location and the section index - ELFSection &CstPool = EW.getConstantPoolSection(CPE); - CPLocations.push_back(CstPool.size()); - CPSections.push_back(CstPool.SectionIdx); - - if (CPE.isMachineConstantPoolEntry()) - assert(0 && "CPE.isMachineConstantPoolEntry not supported yet"); - - // Emit the constant to constant pool section - EW.EmitGlobalConstant(CPE.Val.ConstVal, CstPool); - } -} - -/// emitJumpTables - Emit all the jump tables for a given jump table info -/// record to the appropriate section. -void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { - const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); - if (JT.empty()) return; - - // FIXME: handle PIC codegen - assert(TM.getRelocationModel() != Reloc::PIC_ && - "PIC codegen not yet handled for elf jump tables!"); - - const TargetELFWriterInfo *TEW = TM.getELFWriterInfo(); - unsigned EntrySize = 4; //MJTI->getEntrySize(); - - // Get the ELF Section to emit the jump table - ELFSection &JTSection = EW.getJumpTableSection(); - - // For each JT, record its offset from the start of the section - for (unsigned i = 0, e = JT.size(); i != e; ++i) { - const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; - - // Record JT 'i' offset in the JT section - JTLocations.push_back(JTSection.size()); - - // Each MBB entry in the Jump table section has a relocation entry - // against the current text section. - for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { - unsigned MachineRelTy = TEW->getAbsoluteLabelMachineRelTy(); - MachineRelocation MR = - MachineRelocation::getBB(JTSection.size(), MachineRelTy, MBBs[mi]); - - // Add the relocation to the Jump Table section - JTRelocations.push_back(MR); - - // Output placeholder for MBB in the JT section - for (unsigned s=0; s < EntrySize; ++s) - JTSection.emitByte(0); - } - } -} - -} // end namespace llvm diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h deleted file mode 100644 index 8671c674ee..0000000000 --- a/lib/CodeGen/ELFCodeEmitter.h +++ /dev/null @@ -1,78 +0,0 @@ -//===-- 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 "llvm/CodeGen/ObjectCodeEmitter.h" -#include <vector> - -namespace llvm { - class ELFWriter; - class ELFSection; - - /// ELFCodeEmitter - This class is used by the ELFWriter to - /// emit the code for functions to the ELF file. - class ELFCodeEmitter : public ObjectCodeEmitter { - ELFWriter &EW; - - /// Target machine description - TargetMachine &TM; - - /// Section containing code for functions - ELFSection *ES; - - /// Relocations - Record relocations needed by the current function - std::vector<MachineRelocation> Relocations; - - /// JTRelocations - Record relocations needed by the relocation - /// section. - std::vector<MachineRelocation> JTRelocations; - - /// FnStartPtr - Function offset from the beginning of ELFSection 'ES' - uintptr_t FnStartOff; - public: - explicit ELFCodeEmitter(ELFWriter &ew) : EW(ew), TM(EW.TM) {} - - /// addRelocation - Register new relocations for this function - void addRelocation(const MachineRelocation &MR) { - Relocations.push_back(MR); - } - - /// emitConstantPool - For each constant pool entry, figure out which - /// section the constant should live in and emit data to it - void emitConstantPool(MachineConstantPool *MCP); - - /// emitJumpTables - Emit all the jump tables for a given jump table - /// info and record them to the appropriate section. - void emitJumpTables(MachineJumpTableInfo *MJTI); - - void startFunction(MachineFunction &F); - bool finishFunction(MachineFunction &F); - - /// emitLabel - Emits a label - virtual void emitLabel(MCSymbol *Label) { - assert(0 && "emitLabel not implemented"); - } - - /// getLabelAddress - Return the address of the specified LabelID, - /// only usable after the LabelID has been emitted. - virtual uintptr_t getLabelAddress(MCSymbol *Label) const { - assert(0 && "getLabelAddress not implemented"); - return 0; - } - - virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) {} - -}; // end class ELFCodeEmitter - -} // end namespace llvm - -#endif - diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp deleted file mode 100644 index f2c2185658..0000000000 --- a/lib/CodeGen/ELFWriter.cpp +++ /dev/null @@ -1,1105 +0,0 @@ -//===-- ELFWriter.cpp - Target-independent ELF Writer code ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the target-independent ELF writer. This file writes out -// the ELF file in the following order: -// -// #1. ELF Header -// #2. '.text' section -// #3. '.data' section -// #4. '.bss' section (conceptual position in file) -// ... -// #X. '.shstrtab' section -// #Y. Section Table -// -// The entries in the section table are laid out as: -// #0. Null entry [required] -// #1. ".text" entry - the program code -// #2. ".data" entry - global variables with initializers. [ if needed ] -// #3. ".bss" entry - global variables without initializers. [ if needed ] -// ... -// #N. ".shstrtab" entry - String table for the section names. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "elfwriter" -#include "ELF.h" -#include "ELFWriter.h" -#include "ELFCodeEmitter.h" -#include "llvm/Constants.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/DerivedTypes.h" -#include "llvm/CodeGen/BinaryObject.h" -#include "llvm/CodeGen/MachineCodeEmitter.h" -#include "llvm/CodeGen/ObjectCodeEmitter.h" -#include "llvm/CodeGen/MachineCodeEmitter.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCSectionELF.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetELFWriterInfo.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/SmallString.h" -using namespace llvm; - -char ELFWriter::ID = 0; - -//===----------------------------------------------------------------------===// -// ELFWriter Implementation -//===----------------------------------------------------------------------===// - -ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm) - : MachineFunctionPass(ID), O(o), TM(tm), - OutContext(*new MCContext(*TM.getMCAsmInfo(), *TM.getRegisterInfo(), - &TM.getTargetLowering()->getObjFileLowering())), - TLOF(TM.getTargetLowering()->getObjFileLowering()), - is64Bit(TM.getTargetData()->getPointerSizeInBits() == 64), - isLittleEndian(TM.getTargetData()->isLittleEndian()), - ElfHdr(isLittleEndian, is64Bit) { - - MAI = TM.getMCAsmInfo(); - TEW = TM.getELFWriterInfo(); - - // Create the object code emitter object for this target. - ElfCE = new ELFCodeEmitter(*this); - - // Initial number of sections - NumSections = 0; -} - -ELFWriter::~ELFWriter() { - delete ElfCE; - delete &OutContext; - - while(!SymbolList.empty()) { - delete SymbolList.back(); - SymbolList.pop_back(); - } - - while(!PrivateSyms.empty()) { - delete PrivateSyms.back(); - PrivateSyms.pop_back(); - } - - while(!SectionList.empty()) { - delete SectionList.back(); - SectionList.pop_back(); - } - - // Release the name mangler object. - delete Mang; Mang = 0; -} - -// doInitialization - Emit the file header and all of the global variables for -// the module to the ELF file. -bool ELFWriter::doInitialization(Module &M) { - // Initialize TargetLoweringObjectFile. - const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(OutContext, TM); - - Mang = new Mangler(OutContext, *TM.getTargetData()); - - // ELF Header - // ---------- - // Fields e_shnum e_shstrndx are only known after all section have - // been emitted. They locations in the ouput buffer are recorded so - // to be patched up later. - // - // Note - // ---- - // emitWord method behaves differently for ELF32 and ELF64, writing - // 4 bytes in the former and 8 in the last for *_off and *_addr elf types - - ElfHdr.emitByte(0x7f); // e_ident[EI_MAG0] - ElfHdr.emitByte('E'); // e_ident[EI_MAG1] - ElfHdr.emitByte('L'); // e_ident[EI_MAG2] - ElfHdr.emitByte('F'); // e_ident[EI_MAG3] - - ElfHdr.emitByte(TEW->getEIClass()); // e_ident[EI_CLASS] - ElfHdr.emitByte(TEW->getEIData()); // e_ident[EI_DATA] - ElfHdr.emitByte(ELF::EV_CURRENT); // e_ident[EI_VERSION] - ElfHdr.emitAlignment(16); // e_ident[EI_NIDENT-EI_PAD] - - ElfHdr.emitWord16(ELF::ET_REL); // e_type - ElfHdr.emitWord16(TEW->getEMachine()); // e_machine = target - ElfHdr.emitWord32(ELF::EV_CURRENT); // e_version - ElfHdr.emitWord(0); // e_entry, no entry point in .o file - ElfHdr.emitWord(0); // e_phoff, no program header for .o - ELFHdr_e_shoff_Offset = ElfHdr.size(); - ElfHdr.emitWord(0); // e_shoff = sec hdr table off in bytes - ElfHdr.emitWord32(TEW->getEFlags()); // e_flags = whatever the target wants - ElfHdr.emitWord16(TEW->getHdrSize()); // e_ehsize = ELF header size - ElfHdr.emitWord16(0); // e_phentsize = prog header entry size - ElfHdr.emitWord16(0); // e_phnum = # prog header entries = 0 - - // e_shentsize = Section header entry size - ElfHdr.emitWord16(TEW->getSHdrSize()); - - // e_shnum = # of section header ents - ELFHdr_e_shnum_Offset = ElfHdr.size(); - ElfHdr.emitWord16(0); // Placeholder - - // e_shstrndx = Section # of '.shstrtab' - ELFHdr_e_shstrndx_Offset = ElfHdr.size(); - ElfHdr.emitWord16(0); // Placeholder - - // Add the null section, which is required to be first in the file. - getNullSection(); - - // The first entry in the symtab is the null symbol and the second - // is a local symbol containing the module/file name - SymbolList.push_back(new ELFSym()); - SymbolList.push_back(ELFSym::getFileSym()); - - return false; -} - -// AddPendingGlobalSymbol - Add a global to be processed and to -// the global symbol lookup, use a zero index because the table -// index will be determined later. -void ELFWriter::AddPendingGlobalSymbol(const GlobalValue *GV, - bool AddToLookup /* = false */) { - PendingGlobals.insert(GV); - if (AddToLookup) - GblSymLookup[GV] = 0; -} - -// AddPendingExternalSymbol - Add the external to be processed -// and to the external symbol lookup, use a zero index because -// the symbol table index will be determined later. -void ELFWriter::AddPendingExternalSymbol(const char *External) { - PendingExternals.insert(External); - ExtSymLookup[External] = 0; -} - -ELFSection &ELFWriter::getDataSection() { - const MCSectionELF *Data = (const MCSectionELF *)TLOF.getDataSection(); - return getSection(Data->getSectionName(), Data->getType(), - Data->getFlags(), 4); -} - -ELFSection &ELFWriter::getBSSSection() { - const MCSectionELF *BSS = (const MCSectionELF *)TLOF.getBSSSection(); - return getSection(BSS->getSectionName(), BSS->getType(), BSS->getFlags(), 4); -} - -// getCtorSection - Get the static constructor section -ELFSection &ELFWriter::getCtorSection() { - const MCSectionELF *Ctor = (const MCSectionELF *)TLOF.getStaticCtorSection(); - return getSection(Ctor->getSectionName(), Ctor->getType(), Ctor->getFlags()); -} - -// getDtorSection - Get the static destructor section -ELFSection &ELFWriter::getDtorSection() { - const MCSectionELF *Dtor = (const MCSectionELF *)TLOF.getStaticDtorSection(); - return getSection(Dtor->getSectionName(), Dtor->getType(), Dtor->getFlags()); -} - -// getTextSection - Get the text section for the specified function -ELFSection &ELFWriter::getTextSection(const Function *F) { - const MCSectionELF *Text = - (const MCSectionELF *)TLOF.SectionForGlobal(F, Mang, TM); - return getSection(Text->getSectionName(), Text->getType(), Text->getFlags()); -} - -// getJumpTableSection - Get a read only section for constants when -// emitting jump tables. TODO: add PIC support -ELFSection &ELFWriter::getJumpTableSection() { - const MCSectionELF *JT = - (const MCSectionELF *)TLOF.getSectionForConstant(SectionKind::getReadOnly()); - return getSection(JT->getSectionName(), JT->getType(), JT->getFlags(), - TM.getTargetData()->getPointerABIAlignment()); -} - -// getConstantPoolSection - Get a constant pool section based on the machine -// constant pool entry type and relocation info. -ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) { - SectionKind Kind; - switch (CPE.getRelocationInfo()) { - default: llvm_unreachable("Unknown section kind"); - case 2: Kind = SectionKind::getReadOnlyWithRel(); break; - case 1: - Kind = SectionKind::getReadOnlyWithRelLocal(); - break; - case 0: - switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) { - case 4: Kind = SectionKind::getMergeableConst4(); break; - case 8: Kind = SectionKind::getMergeableConst8(); break; - case 16: Kind = SectionKind::getMergeableConst16(); break; - default: Kind = SectionKind::getMergeableConst(); break; - } - } - - const MCSectionELF *CPSect = - (const MCSectionELF *)TLOF.getSectionForConstant(Kind); - return getSection(CPSect->getSectionName(), CPSect->getType(), - CPSect->getFlags(), CPE.getAlignment()); -} - -// getRelocSection - Return the relocation section of section 'S'. 'RelA' -// is true if the relocation section contains entries with addends. -ELFSection &ELFWriter::getRelocSection(ELFSection &S) { - unsigned SectionType = TEW->hasRelocationAddend() ? - ELF::SHT_RELA : ELF::SHT_REL; - - std::string SectionName(".rel"); - if (TEW->hasRelocationAddend()) - SectionName.append("a"); - SectionName.append(S.getName()); - - return getSection(SectionName, SectionType, 0, TEW->getPrefELFAlignment()); -} - -// getGlobalELFVisibility - Returns the ELF specific visibility type -unsigned ELFWriter::getGlobalELFVisibility(const GlobalValue *GV) { - switch (GV->getVisibility()) { - default: - llvm_unreachable("unknown visibility type"); - case GlobalValue::DefaultVisibility: - return ELF::STV_DEFAULT; - case GlobalValue::HiddenVisibility: - return ELF::STV_HIDDEN; - case GlobalValue::ProtectedVisibility: - return ELF::STV_PROTECTED; - } - return 0; -} - -// getGlobalELFBinding - Returns the ELF specific binding type -unsigned ELFWriter::getGlobalELFBinding(const GlobalValue *GV) { - if (GV->hasInternalLinkage()) - return ELF::STB_LOCAL; - - if (GV->isWeakForLinker() && !GV->hasCommonLinkage()) - return ELF::STB_WEAK; - - return ELF::STB_GLOBAL; -} - -// getGlobalELFType - Returns the ELF specific type for a global -unsigned ELFWriter::getGlobalELFType(const GlobalValue *GV) { - if (GV->isDeclaration()) - return ELF::STT_NOTYPE; - - if (isa<Function>(GV)) - return ELF::STT_FUNC; - - return ELF::STT_OBJECT; -} - -// IsELFUndefSym - True if the global value must be marked as a symbol -// which points to a SHN_UNDEF section. This means that the symbol has -// no definition on the module. -static bool IsELFUndefSym(const GlobalValue *GV) { - return GV->isDeclaration() || (isa<Function>(GV)); -} - -// AddToSymbolList - Update the symbol lookup and If the symbol is -// private add it to PrivateSyms list, otherwise to SymbolList. -void ELFWriter::AddToSymbolList(ELFSym *GblSym) { - assert(GblSym->isGlobalValue() && "Symbol must be a global value"); - - const GlobalValue *GV = GblSym->getGlobalValue(); - if (GV->hasPrivateLinkage()) { - // For a private symbols, keep track of the index inside - // the private list since it will never go to the symbol - // table and won't be patched up later. - PrivateSyms.push_back(GblSym); - GblSymLookup[GV] = PrivateSyms.size()-1; - } else { - // Non private symbol are left with zero indices until - // they are patched up during the symbol table emition - // (where the indicies are created). - SymbolList.push_back(GblSym); - GblSymLookup[GV] = 0; - } -} - -/// HasCommonSymbols - True if this section holds common symbols, this is -/// indicated on the ELF object file by a symbol with SHN_COMMON section -/// header index. -static bool HasCommonSymbols(const MCSectionELF &S) { - // FIXME: this is wrong, a common symbol can be in .data for example. - if (StringRef(S.getSectionName()).startswith(".gnu.linkonce.")) - return true; - - return false; -} - - -// EmitGlobal - Choose the right section for global and emit it -void ELFWriter::EmitGlobal(const GlobalValue *GV) { - - // Check if the referenced symbol is already emitted - if (GblSymLookup.find(GV) != GblSymLookup.end()) - return; - - // Handle ELF Bind, Visibility and Type for the current symbol - unsigned SymBind = getGlobalELFBinding(GV); - unsigned SymType = getGlobalELFType(GV); - bool IsUndefSym = IsELFUndefSym(GV); - - ELFSym *GblSym = IsUndefSym ? ELFSym::getUndefGV(GV, SymBind) - : ELFSym::getGV(GV, SymBind, SymType, getGlobalELFVisibility(GV)); - - if (!IsUndefSym) { - assert(isa<GlobalVariable>(GV) && "GV not a global variable!"); - const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); - - // Handle special llvm globals - if (EmitSpecialLLVMGlobal(GVar)) - return; - - // Get the ELF section where this global belongs from TLOF - const MCSectionELF *S = - (const MCSectionELF *)TLOF.SectionForGlobal(GV, Mang, TM); - ELFSection &ES = - getSection(S->getSectionName(), S->getType(), S->getFlags()); - SectionKind Kind = S->getKind(); - - // The symbol align should update the section alignment if needed - const TargetData *TD = TM.getTargetData(); - unsigned Align = TD->getPreferredAlignment(GVar); - unsigned Size = TD->getTypeAllocSize(GVar->getInitializer()->getType()); - GblSym->Size = Size; - - if (HasCommonSymbols(*S)) { // Symbol must go to a common section - GblSym->SectionIdx = ELF::SHN_COMMON; - - // A new linkonce section is created for each global in the - // common section, the default alignment is 1 and the symbol - // value contains its alignment. - ES.Align = 1; - GblSym->Value = Align; - - } else if (Kind.isBSS() || Kind.isThreadBSS()) { // Symbol goes to BSS. - GblSym->SectionIdx = ES.SectionIdx; - - // Update the size with alignment and the next object can - // start in the right offset in the section - if (Align) ES.Size = (ES.Size + Align-1) & ~(Align-1); - ES.Align = std::max(ES.Align, Align); - - // GblSym->Value should contain the virtual offset inside the section. - // Virtual because the BSS space is not allocated on ELF objects - GblSym->Value = ES.Size; - ES.Size += Size; - - } else { // The symbol must go to some kind of data section - GblSym->SectionIdx = ES.SectionIdx; - - // GblSym->Value should contain the symbol offset inside the section, - // and all symbols should start on their required alignment boundary |