1 //===- ELFDynObjReader.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 <llvm/ADT/Twine.h> 10 #include <llvm/ADT/OwningPtr.h> 11 #include <llvm/Support/ErrorHandling.h> 12 13 #include <mcld/LD/ELFDynObjReader.h> 14 #include <mcld/LD/ELFReader.h> 15 #include <mcld/MC/MCLDInput.h> 16 #include <mcld/MC/MCLinker.h> 17 #include <mcld/Target/GNULDBackend.h> 18 #include <mcld/Support/MemoryRegion.h> 19 20 #include <string> 21 22 using namespace mcld; 23 24 //========================== 25 // ELFDynObjReader 26 ELFDynObjReader::ELFDynObjReader(GNULDBackend& pBackend, MCLinker& pLinker) 27 : DynObjReader(), 28 m_pELFReader(0), 29 m_Linker(pLinker) { 30 if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) 31 m_pELFReader = new ELFReader<32, true>(pBackend); 32 } 33 34 ELFDynObjReader::~ELFDynObjReader() 35 { 36 delete m_pELFReader; 37 } 38 39 /// isMyFormat 40 bool ELFDynObjReader::isMyFormat(Input &pInput) const 41 { 42 assert(pInput.hasMemArea()); 43 44 // Don't warning about the frequently requests. 45 // MemoryArea has a list of cache to handle this. 46 size_t hdr_size = m_pELFReader->getELFHeaderSize(); 47 MemoryRegion* region = pInput.memArea()->request(0, hdr_size); 48 49 uint8_t* ELF_hdr = region->start(); 50 bool result = true; 51 if (!m_pELFReader->isELF(ELF_hdr)) 52 result = false; 53 else if (!m_pELFReader->isMyEndian(ELF_hdr)) 54 result = false; 55 else if (!m_pELFReader->isMyMachine(ELF_hdr)) 56 result = false; 57 else if (MCLDFile::DynObj != m_pELFReader->fileType(ELF_hdr)) 58 result = false; 59 pInput.memArea()->release(region); 60 return result; 61 } 62 63 /// readDSO 64 bool ELFDynObjReader::readDSO(Input& pInput) 65 { 66 assert(pInput.hasMemArea()); 67 68 size_t hdr_size = m_pELFReader->getELFHeaderSize(); 69 MemoryRegion* region = pInput.memArea()->request(0, hdr_size); 70 uint8_t* ELF_hdr = region->start(); 71 72 bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr); 73 pInput.memArea()->release(region); 74 return result; 75 } 76 77 /// readSymbols 78 bool ELFDynObjReader::readSymbols(Input& pInput) 79 { 80 assert(pInput.hasMemArea()); 81 82 LDSection* symtab_shdr = pInput.context()->getSection(".dynsym"); 83 LDSection* strtab_shdr = symtab_shdr->getLink(); 84 if (NULL == symtab_shdr || NULL == strtab_shdr) 85 return false; 86 87 MemoryRegion* symtab_region = pInput.memArea()->request(symtab_shdr->offset(), 88 symtab_shdr->size()); 89 90 MemoryRegion* strtab_region = pInput.memArea()->request(strtab_shdr->offset(), 91 strtab_shdr->size()); 92 char* strtab = reinterpret_cast<char*>(strtab_region->start()); 93 bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region, strtab); 94 pInput.memArea()->release(symtab_region); 95 pInput.memArea()->release(strtab_region); 96 97 return result; 98 } 99 100