//===-- 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