1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- ELFExecWriter.cpp --------------------------------------------------===// 2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// The MCLinker Project 4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source 6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details. 7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// 8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===// 9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFExecWriter.h> 10affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/LDSymbol.h> 11affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Target/GNULDBackend.h> 12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLDInput.h> 13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLDOutput.h> 14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLDInfo.h> 15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLinker.h> 16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/ELF.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <vector> 18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 19affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace llvm; 20affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace mcld; 21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//========================== 24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// ELFExecWriter 25affc150dc44fab1911775a49636d0ce85333b634Zonr ChangELFExecWriter::ELFExecWriter(GNULDBackend& pBackend, MCLinker& pLinker) 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang : ExecWriter(pBackend), 27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFWriter(pBackend), 28affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Backend(pBackend), 29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker(pLinker) { 30affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 31affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 33affc150dc44fab1911775a49636d0ce85333b634Zonr ChangELFExecWriter::~ELFExecWriter() 34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 37affc150dc44fab1911775a49636d0ce85333b634Zonr Changllvm::error_code ELFExecWriter::writeExecutable(Output& pOutput) 38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // write out the interpreter section: .interp 40affc150dc44fab1911775a49636d0ce85333b634Zonr Chang target().emitInterp(pOutput, m_Linker.getLDInfo()); 41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out name pool sections: .dynsym, .dynstr, .hash 43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang target().emitDynNamePools(pOutput, 44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getOutputSymbols(), 45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLayout(), 46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLDInfo()); 47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out name pool sections: .symtab, .strtab 49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang target().emitRegNamePools(pOutput, 50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getOutputSymbols(), 51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLayout(), 52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLDInfo()); 53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out regular ELF sections 55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang unsigned int secIdx = 0; 56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang unsigned int secEnd = pOutput.context()->numOfSections(); 57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (secIdx = 0; secIdx < secEnd; ++secIdx) { 58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang LDSection* sect = pOutput.context()->getSection(secIdx); 59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang MemoryRegion* region = NULL; 60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // request output region 61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang switch(sect->kind()) { 62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Regular: 63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Relocation: 64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Target: 65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Debug: 66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::GCCExceptTable: 67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrame: { 68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang region = pOutput.memArea()->request(sect->offset(), sect->size()); 69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == region) { 70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section[") + 71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::Twine(secIdx) + 72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::Twine("] - `") + 73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang sect->name() + 74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::Twine("'.\n")); 75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Null: 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::NamePool: 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::BSS: 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Note: 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::MetaData: 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Version: 84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrameHdr: 85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // ignore these sections 86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang continue; 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: { 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang llvm::errs() << "WARNING: unsupported section kind: " 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << sect->kind() 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << " of section " 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << sect->name() 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << ".\n"; 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang continue; 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // write out sections with data 98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang switch(sect->kind()) { 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Regular: 100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Debug: 101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::GCCExceptTable: 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::EhFrame: { 103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // FIXME: if optimization of exception handling sections is enabled, 104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // then we should emit these sections by the other way. 105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitSectionData(m_Linker.getLayout(), *sect, *region); 106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Relocation: 109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitRelocation(m_Linker.getLayout(), pOutput, *sect, *region); 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang case LDFileFormat::Target: 112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang target().emitSectionData(pOutput, 113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *sect, 114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLDInfo(), 115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLayout(), 116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang *region); 117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang break; 118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang default: 119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang continue; 120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } // end of for loop 122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (32 == target().bitclass()) { 124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out ELF header 125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out section header table 126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitELF32ShStrTab(pOutput, m_Linker); 127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang writeELF32Header(m_Linker.getLDInfo(), 129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLayout(), 130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang target(), 131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput); 132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitELF32ProgramHeader(pOutput, target()); 134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitELF32SectionHeader(pOutput, m_Linker); 136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else if (64 == target().bitclass()) { 138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out ELF header 139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Write out section header table 140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitELF64ShStrTab(pOutput, m_Linker); 141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang writeELF64Header(m_Linker.getLDInfo(), 143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang m_Linker.getLayout(), 144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang target(), 145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput); 146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitELF64ProgramHeader(pOutput, target()); 148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang emitELF64SectionHeader(pOutput, m_Linker); 150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang else 152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return make_error_code(errc::not_supported); 153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pOutput.memArea()->clear(); 155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return llvm::make_error_code(llvm::errc::success); 156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 158