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 using 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 36 bool ELFBinaryReader::isMyFormat(Input& pInput, bool &pContinue) const 37 { 38 pContinue = true; 39 return m_Config.options().isBinaryInput(); 40 } 41 42 bool ELFBinaryReader::readBinary(Input& pInput) 43 { 44 // section: NULL 45 m_Builder.CreateELFHeader(pInput, 46 "", 47 LDFileFormat::Null, 48 llvm::ELF::SHT_NULL, 49 0x0); 50 51 // section: .data 52 LDSection* data_sect = 53 m_Builder.CreateELFHeader(pInput, 54 ".data", 55 LDFileFormat::DATA, 56 llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC, 57 0x1); 58 59 60 SectionData* data = m_Builder.CreateSectionData(*data_sect); 61 size_t data_size = pInput.memArea()->size(); 62 Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size); 63 m_Builder.AppendFragment(*frag, *data); 64 65 // section: .shstrtab 66 m_Builder.CreateELFHeader(pInput, 67 ".shstrtab", 68 LDFileFormat::NamePool, 69 llvm::ELF::SHT_STRTAB, 70 0x1); 71 72 // section: .symtab 73 m_Builder.CreateELFHeader(pInput, 74 ".symtab", 75 LDFileFormat::NamePool, 76 llvm::ELF::SHT_SYMTAB, 77 m_Config.targets().bitclass() / 8); 78 79 // symbol: .data 80 m_Builder.AddSymbol(pInput, 81 ".data", 82 ResolveInfo::Section, 83 ResolveInfo::Define, 84 ResolveInfo::Local, 85 0x0, 86 0x0, 87 data_sect); 88 89 // Note: in Win32, the filename is wstring. Is it correct to convert 90 // filename to std::string? 91 std::string mangled_name = pInput.path().filename().native(); 92 for (std::string::iterator it = mangled_name.begin(), 93 ie = mangled_name.end(); it != ie; ++it) { 94 if (isalnum(*it) == 0) 95 *it = '_'; 96 } 97 98 // symbol: _start 99 m_Builder.AddSymbol(pInput, 100 "_binary_" + mangled_name + "_start", 101 ResolveInfo::NoType, 102 ResolveInfo::Define, 103 ResolveInfo::Global, 104 0x0, 105 0x0, 106 data_sect); 107 108 // symbol: _end 109 m_Builder.AddSymbol(pInput, 110 "_binary_" + mangled_name + "_end", 111 ResolveInfo::NoType, 112 ResolveInfo::Define, 113 ResolveInfo::Global, 114 0x0, 115 data_size, 116 data_sect); 117 118 // symbol: _size 119 m_Builder.AddSymbol(pInput, 120 "_binary_" + mangled_name + "_size", 121 ResolveInfo::NoType, 122 ResolveInfo::Define, 123 ResolveInfo::Global, 124 0x0, 125 data_size, 126 data_sect); 127 128 // section: .strtab 129 m_Builder.CreateELFHeader(pInput, 130 ".strtab", 131 LDFileFormat::NamePool, 132 llvm::ELF::SHT_STRTAB, 133 0x1); 134 135 return true; 136 } 137