Home | History | Annotate | Download | only in CodeGen
      1 //===-- lib/CodeGen/ELFCodeEmitter.cpp ------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #define DEBUG_TYPE "elfce"
     11 
     12 #include "ELF.h"
     13 #include "ELFWriter.h"
     14 #include "ELFCodeEmitter.h"
     15 #include "llvm/Constants.h"
     16 #include "llvm/DerivedTypes.h"
     17 #include "llvm/Function.h"
     18 #include "llvm/CodeGen/BinaryObject.h"
     19 #include "llvm/CodeGen/MachineConstantPool.h"
     20 #include "llvm/CodeGen/MachineFunction.h"
     21 #include "llvm/CodeGen/MachineJumpTableInfo.h"
     22 #include "llvm/CodeGen/MachineRelocation.h"
     23 #include "llvm/Target/TargetData.h"
     24 #include "llvm/Target/TargetELFWriterInfo.h"
     25 #include "llvm/Target/TargetMachine.h"
     26 #include "llvm/MC/MCAsmInfo.h"
     27 #include "llvm/Support/Debug.h"
     28 #include "llvm/Support/ErrorHandling.h"
     29 #include "llvm/Support/raw_ostream.h"
     30 
     31 //===----------------------------------------------------------------------===//
     32 //                       ELFCodeEmitter Implementation
     33 //===----------------------------------------------------------------------===//
     34 
     35 namespace llvm {
     36 
     37 /// startFunction - This callback is invoked when a new machine function is
     38 /// about to be emitted.
     39 void ELFCodeEmitter::startFunction(MachineFunction &MF) {
     40   DEBUG(dbgs() << "processing function: "
     41         << MF.getFunction()->getName() << "\n");
     42 
     43   // Get the ELF Section that this function belongs in.
     44   ES = &EW.getTextSection(MF.getFunction());
     45 
     46   // Set the desired binary object to be used by the code emitters
     47   setBinaryObject(ES);
     48 
     49   // Get the function alignment in bytes
     50   unsigned Align = (1 << MF.getAlignment());
     51 
     52   // The function must start on its required alignment
     53   ES->emitAlignment(Align);
     54 
     55   // Update the section alignment if needed.
     56   ES->Align = std::max(ES->Align, Align);
     57 
     58   // Record the function start offset
     59   FnStartOff = ES->getCurrentPCOffset();
     60 
     61   // Emit constant pool and jump tables to their appropriate sections.
     62   // They need to be emitted before the function because in some targets
     63   // the later may reference JT or CP entry address.
     64   emitConstantPool(MF.getConstantPool());
     65   if (MF.getJumpTableInfo())
     66     emitJumpTables(MF.getJumpTableInfo());
     67 }
     68 
     69 /// finishFunction - This callback is invoked after the function is completely
     70 /// finished.
     71 bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
     72   // Add a symbol to represent the function.
     73   const Function *F = MF.getFunction();
     74   ELFSym *FnSym = ELFSym::getGV(F, EW.getGlobalELFBinding(F), ELF::STT_FUNC,
     75                                 EW.getGlobalELFVisibility(F));
     76   FnSym->SectionIdx = ES->SectionIdx;
     77   FnSym->Size = ES->getCurrentPCOffset()-FnStartOff;
     78   EW.AddPendingGlobalSymbol(F, true);
     79 
     80   // Offset from start of Section
     81   FnSym->Value = FnStartOff;
     82 
     83   if (!F->hasPrivateLinkage())
     84     EW.SymbolList.push_back(FnSym);
     85 
     86   // Patch up Jump Table Section relocations to use the real MBBs offsets
     87   // now that the MBB label offsets inside the function are known.
     88   if (MF.getJumpTableInfo()) {
     89     ELFSection &JTSection = EW.getJumpTableSection();
     90     for (std::vector<MachineRelocation>::iterator MRI = JTRelocations.begin(),
     91          MRE = JTRelocations.end(); MRI != MRE; ++MRI) {
     92       MachineRelocation &MR = *MRI;
     93       uintptr_t MBBOffset = getMachineBasicBlockAddress(MR.getBasicBlock());
     94       MR.setResultPointer((void*)MBBOffset);
     95       MR.setConstantVal(ES->SectionIdx);
     96       JTSection.addRelocation(MR);
     97     }
     98   }
     99 
    100   // If we have emitted any relocations to function-specific objects such as
    101   // basic blocks, constant pools entries, or jump tables, record their
    102   // addresses now so that we can rewrite them with the correct addresses later
    103   for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
    104     MachineRelocation &MR = Relocations[i];
    105     intptr_t Addr;
    106     if (MR.isGlobalValue()) {
    107       EW.AddPendingGlobalSymbol(MR.getGlobalValue());
    108     } else if (MR.isExternalSymbol()) {
    109       EW.AddPendingExternalSymbol(MR.getExternalSymbol());
    110     } else if (MR.isBasicBlock()) {
    111       Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
    112       MR.setConstantVal(ES->SectionIdx);
    113       MR.setResultPointer((void*)Addr);
    114     } else if (MR.isConstantPoolIndex()) {
    115       Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
    116       MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
    117       MR.setResultPointer((void*)Addr);
    118     } else if (MR.isJumpTableIndex()) {
    119       ELFSection &JTSection = EW.getJumpTableSection();
    120       Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
    121       MR.setConstantVal(JTSection.SectionIdx);
    122       MR.setResultPointer((void*)Addr);
    123     } else {
    124       llvm_unreachable("Unhandled relocation type");
    125     }
    126     ES->addRelocation(MR);
    127   }
    128 
    129   // Clear per-function data structures.
    130   JTRelocations.clear();
    131   Relocations.clear();
    132   CPLocations.clear();
    133   CPSections.clear();
    134   JTLocations.clear();
    135   MBBLocations.clear();
    136   return false;
    137 }
    138 
    139 /// emitConstantPool - For each constant pool entry, figure out which section
    140 /// the constant should live in and emit the constant
    141 void ELFCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
    142   const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
    143   if (CP.empty()) return;
    144 
    145   // TODO: handle PIC codegen
    146   assert(TM.getRelocationModel() != Reloc::PIC_ &&
    147          "PIC codegen not yet handled for elf constant pools!");
    148 
    149   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
    150     MachineConstantPoolEntry CPE = CP[i];
    151 
    152     // Record the constant pool location and the section index
    153     ELFSection &CstPool = EW.getConstantPoolSection(CPE);
    154     CPLocations.push_back(CstPool.size());
    155     CPSections.push_back(CstPool.SectionIdx);
    156 
    157     if (CPE.isMachineConstantPoolEntry())
    158       assert(0 && "CPE.isMachineConstantPoolEntry not supported yet");
    159 
    160     // Emit the constant to constant pool section
    161     EW.EmitGlobalConstant(CPE.Val.ConstVal, CstPool);
    162   }
    163 }
    164 
    165 /// emitJumpTables - Emit all the jump tables for a given jump table info
    166 /// record to the appropriate section.
    167 void ELFCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
    168   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
    169   if (JT.empty()) return;
    170 
    171   // FIXME: handle PIC codegen
    172   assert(TM.getRelocationModel() != Reloc::PIC_ &&
    173          "PIC codegen not yet handled for elf jump tables!");
    174 
    175   const TargetELFWriterInfo *TEW = TM.getELFWriterInfo();
    176   unsigned EntrySize = 4; //MJTI->getEntrySize();
    177 
    178   // Get the ELF Section to emit the jump table
    179   ELFSection &JTSection = EW.getJumpTableSection();
    180 
    181   // For each JT, record its offset from the start of the section
    182   for (unsigned i = 0, e = JT.size(); i != e; ++i) {
    183     const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
    184 
    185     // Record JT 'i' offset in the JT section
    186     JTLocations.push_back(JTSection.size());
    187 
    188     // Each MBB entry in the Jump table section has a relocation entry
    189     // against the current text section.
    190     for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
    191       unsigned MachineRelTy = TEW->getAbsoluteLabelMachineRelTy();
    192       MachineRelocation MR =
    193         MachineRelocation::getBB(JTSection.size(), MachineRelTy, MBBs[mi]);
    194 
    195       // Add the relocation to the Jump Table section
    196       JTRelocations.push_back(MR);
    197 
    198       // Output placeholder for MBB in the JT section
    199       for (unsigned s=0; s < EntrySize; ++s)
    200         JTSection.emitByte(0);
    201     }
    202   }
    203 }
    204 
    205 } // end namespace llvm
    206