ELFObjectWriter.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFObjectWriter.cpp ------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LinkerConfig.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/system_error.h> 17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm; 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectWriter 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend, 25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const LinkerConfig& pConfig) 26d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : ObjectWriter(pBackend), ELFWriter(pBackend), 27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config(pConfig) { 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter::~ELFObjectWriter() 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaollvm::error_code ELFObjectWriter::writeObject(Module& pModule, 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out name pool sections: .symtab, .strtab 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao target().emitRegNamePools(pModule, pOutput); 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out regular ELF sections 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sect, sectEnd = pModule.end(); 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = pModule.begin(); sect != sectEnd; ++sect) { 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* region = NULL; 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // request output region 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch((*sect)->kind()) { 46d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Note: 47d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if ((*sect)->getSectionData() == NULL) 48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao continue; 49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // Fall through 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Regular: 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Target: 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Debug: 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::GCCExceptTable: 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: { 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao region = pOutput.request((*sect)->offset(), (*sect)->size()); 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == region) { 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") + 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::Twine((*sect)->name()) + 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::Twine("'.\n")); 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Null: 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::BSS: 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::MetaData: 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Version: 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrameHdr: 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::StackNote: 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore these sections 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: { 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::errs() << "WARNING: unsupported section kind: " 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*sect)->kind() 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << " of section " 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*sect)->name() 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << ".\n"; 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out sections with data 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch((*sect)->kind()) { 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Regular: 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Debug: 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::GCCExceptTable: 88d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao case LDFileFormat::Note: 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: { 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: if optimization of exception handling sections is enabled, 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // then we should emit these sections by the other way. 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSectionData(**sect, *region); 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 96d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao emitRelocation(m_Config, **sect, *region); 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Target: 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao target().emitSectionData(**sect, *region); 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for loop 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitELFShStrTab(target().getOutputFormat()->getShStrTab(), 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule, 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput); 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.targets().is32Bits()) { 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out ELF header 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out section header table 113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao writeELF32Header(m_Config, 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule, 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput); 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao emitELF32SectionHeader(pModule, m_Config, pOutput); 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao else if (m_Config.targets().is64Bits()) { 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out ELF header 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out section header table 122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao writeELF64Header(m_Config, 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule, 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput); 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao emitELF64SectionHeader(pModule, m_Config, pOutput); 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return make_error_code(errc::not_supported); 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput.clear(); 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return llvm::make_error_code(llvm::errc::success); 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135