ELFObjectWriter.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/system_error.h> 1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm; 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectWriter 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend, 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao FragmentLinker& pLinker) 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : ObjectWriter(pBackend), ELFWriter(pBackend), m_Linker(pLinker) { 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter::~ELFObjectWriter() 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaollvm::error_code ELFObjectWriter::writeObject(Module& pModule, 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out name pool sections: .symtab, .strtab 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao target().emitRegNamePools(pModule, pOutput); 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out regular ELF sections 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Module::iterator sect, sectEnd = pModule.end(); 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (sect = pModule.begin(); sect != sectEnd; ++sect) { 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* region = NULL; 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // request output region 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch((*sect)->kind()) { 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Regular: 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Target: 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Debug: 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::GCCExceptTable: 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: { 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao region = pOutput.request((*sect)->offset(), (*sect)->size()); 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == region) { 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") + 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::Twine((*sect)->name()) + 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::Twine("'.\n")); 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Null: 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::NamePool: 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::BSS: 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Note: 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::MetaData: 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Version: 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrameHdr: 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::StackNote: 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // ignore these sections 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: { 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::errs() << "WARNING: unsupported section kind: " 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*sect)->kind() 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << " of section " 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << (*sect)->name() 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao << ".\n"; 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // write out sections with data 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch((*sect)->kind()) { 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Regular: 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Debug: 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::GCCExceptTable: 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::EhFrame: { 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // FIXME: if optimization of exception handling sections is enabled, 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // then we should emit these sections by the other way. 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitSectionData(**sect, *region); 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Relocation: 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitRelocation(m_Linker.getLDInfo(), **sect, *region); 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case LDFileFormat::Target: 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao target().emitSectionData(**sect, *region); 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for loop 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitELFShStrTab(target().getOutputFormat()->getShStrTab(), 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule, 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput); 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (32 == target().bitclass()) { 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out ELF header 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out section header table 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao writeELF32Header(m_Linker.getLDInfo(), 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule, 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput); 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitELF32SectionHeader(pModule, m_Linker.getLDInfo(), pOutput); 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (64 == target().bitclass()) { 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out ELF header 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Write out section header table 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao writeELF64Header(m_Linker.getLDInfo(), 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pModule, 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput); 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao emitELF64SectionHeader(pModule, m_Linker.getLDInfo(), pOutput); 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return make_error_code(errc::not_supported); 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pOutput.clear(); 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return llvm::make_error_code(llvm::errc::success); 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 129