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