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 35namespace llvm { 36 37/// startFunction - This callback is invoked when a new machine function is 38/// about to be emitted. 39void 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. 71bool 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 141void 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. 167void 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