1 //===- ELFBinaryReader.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/ELFBinaryReader.h" 10 11 #include "mcld/IRBuilder.h" 12 #include "mcld/LinkerConfig.h" 13 #include "mcld/MC/Input.h" 14 #include "mcld/Support/MemoryArea.h" 15 16 #include <llvm/Support/ELF.h> 17 18 #include <cctype> 19 20 namespace mcld { 21 22 //===----------------------------------------------------------------------===// 23 // ELFBinaryReader 24 //===----------------------------------------------------------------------===// 25 /// constructor 26 ELFBinaryReader::ELFBinaryReader(IRBuilder& pBuilder, 27 const LinkerConfig& pConfig) 28 : m_Builder(pBuilder), m_Config(pConfig) { 29 } 30 31 /// destructor 32 ELFBinaryReader::~ELFBinaryReader() { 33 } 34 35 bool ELFBinaryReader::isMyFormat(Input& pInput, bool& pContinue) const { 36 pContinue = true; 37 return m_Config.options().isBinaryInput(); 38 } 39 40 bool ELFBinaryReader::readBinary(Input& pInput) { 41 // section: NULL 42 m_Builder.CreateELFHeader( 43 pInput, "", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0); 44 45 // section: .data 46 LDSection* data_sect = 47 m_Builder.CreateELFHeader(pInput, 48 ".data", 49 LDFileFormat::DATA, 50 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC, 51 0x1); 52 53 SectionData* data = m_Builder.CreateSectionData(*data_sect); 54 size_t data_size = pInput.memArea()->size(); 55 Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size); 56 m_Builder.AppendFragment(*frag, *data); 57 58 // section: .shstrtab 59 m_Builder.CreateELFHeader( 60 pInput, ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1); 61 62 // section: .symtab 63 m_Builder.CreateELFHeader(pInput, 64 ".symtab", 65 LDFileFormat::NamePool, 66 llvm::ELF::SHT_SYMTAB, 67 m_Config.targets().bitclass() / 8); 68 69 // symbol: .data 70 m_Builder.AddSymbol(pInput, 71 ".data", 72 ResolveInfo::Section, 73 ResolveInfo::Define, 74 ResolveInfo::Local, 75 0x0, 76 0x0, 77 data_sect); 78 79 // Note: in Win32, the filename is wstring. Is it correct to convert 80 // filename to std::string? 81 std::string mangled_name = pInput.path().filename().native(); 82 for (std::string::iterator it = mangled_name.begin(), ie = mangled_name.end(); 83 it != ie; 84 ++it) { 85 if (isalnum(*it) == 0) 86 *it = '_'; 87 } 88 89 // symbol: _start 90 m_Builder.AddSymbol(pInput, 91 "_binary_" + mangled_name + "_start", 92 ResolveInfo::NoType, 93 ResolveInfo::Define, 94 ResolveInfo::Global, 95 0x0, 96 0x0, 97 data_sect); 98 99 // symbol: _end 100 m_Builder.AddSymbol(pInput, 101 "_binary_" + mangled_name + "_end", 102 ResolveInfo::NoType, 103 ResolveInfo::Define, 104 ResolveInfo::Global, 105 0x0, 106 data_size, 107 data_sect); 108 109 // symbol: _size 110 m_Builder.AddSymbol(pInput, 111 "_binary_" + mangled_name + "_size", 112 ResolveInfo::NoType, 113 ResolveInfo::Define, 114 ResolveInfo::Global, 115 0x0, 116 data_size, 117 data_sect); 118 119 // section: .strtab 120 m_Builder.CreateELFHeader( 121 pInput, ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1); 122 123 return true; 124 } 125 126 } // namespace mcld 127