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