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