ELFObjectWriter.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
1//===- ELFObjectWriter.cpp ------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include <mcld/LD/ELFObjectWriter.h> 10 11#include <mcld/Module.h> 12#include <mcld/Target/GNULDBackend.h> 13#include <mcld/Fragment/FragmentLinker.h> 14#include <mcld/Support/MemoryArea.h> 15 16#include <llvm/Support/system_error.h> 17using namespace llvm; 18using namespace mcld; 19 20//===----------------------------------------------------------------------===// 21// ELFObjectWriter 22//===----------------------------------------------------------------------===// 23ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend, 24 FragmentLinker& pLinker) 25 : ObjectWriter(pBackend), ELFWriter(pBackend), m_Linker(pLinker) { 26} 27 28ELFObjectWriter::~ELFObjectWriter() 29{ 30} 31 32llvm::error_code ELFObjectWriter::writeObject(Module& pModule, 33 MemoryArea& pOutput) 34{ 35 // Write out name pool sections: .symtab, .strtab 36 target().emitRegNamePools(pModule, pOutput); 37 38 // Write out regular ELF sections 39 Module::iterator sect, sectEnd = pModule.end(); 40 for (sect = pModule.begin(); sect != sectEnd; ++sect) { 41 MemoryRegion* region = NULL; 42 // request output region 43 switch((*sect)->kind()) { 44 case LDFileFormat::Regular: 45 case LDFileFormat::Relocation: 46 case LDFileFormat::Target: 47 case LDFileFormat::Debug: 48 case LDFileFormat::GCCExceptTable: 49 case LDFileFormat::EhFrame: { 50 region = pOutput.request((*sect)->offset(), (*sect)->size()); 51 if (NULL == region) { 52 llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") + 53 llvm::Twine((*sect)->name()) + 54 llvm::Twine("'.\n")); 55 } 56 break; 57 } 58 case LDFileFormat::Null: 59 case LDFileFormat::NamePool: 60 case LDFileFormat::BSS: 61 case LDFileFormat::Note: 62 case LDFileFormat::MetaData: 63 case LDFileFormat::Version: 64 case LDFileFormat::EhFrameHdr: 65 case LDFileFormat::StackNote: 66 // ignore these sections 67 continue; 68 default: { 69 llvm::errs() << "WARNING: unsupported section kind: " 70 << (*sect)->kind() 71 << " of section " 72 << (*sect)->name() 73 << ".\n"; 74 continue; 75 } 76 } 77 78 // write out sections with data 79 switch((*sect)->kind()) { 80 case LDFileFormat::Regular: 81 case LDFileFormat::Debug: 82 case LDFileFormat::GCCExceptTable: 83 case LDFileFormat::EhFrame: { 84 // FIXME: if optimization of exception handling sections is enabled, 85 // then we should emit these sections by the other way. 86 emitSectionData(**sect, *region); 87 break; 88 } 89 case LDFileFormat::Relocation: 90 emitRelocation(m_Linker.getLDInfo(), **sect, *region); 91 break; 92 case LDFileFormat::Target: 93 target().emitSectionData(**sect, *region); 94 break; 95 default: 96 continue; 97 } 98 } // end of for loop 99 100 emitELFShStrTab(target().getOutputFormat()->getShStrTab(), 101 pModule, 102 pOutput); 103 104 if (32 == target().bitclass()) { 105 // Write out ELF header 106 // Write out section header table 107 writeELF32Header(m_Linker.getLDInfo(), 108 pModule, 109 pOutput); 110 111 emitELF32SectionHeader(pModule, m_Linker.getLDInfo(), pOutput); 112 } 113 else if (64 == target().bitclass()) { 114 // Write out ELF header 115 // Write out section header table 116 writeELF64Header(m_Linker.getLDInfo(), 117 pModule, 118 pOutput); 119 120 emitELF64SectionHeader(pModule, m_Linker.getLDInfo(), pOutput); 121 } 122 else 123 return make_error_code(errc::not_supported); 124 125 pOutput.clear(); 126 return llvm::make_error_code(llvm::errc::success); 127} 128 129