ELFDynObjReader.cpp revision 67e37f1be98c926645219cfb47fab9e90d8c725c
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 22using namespace mcld; 23 24//========================== 25// ELFDynObjReader 26ELFDynObjReader::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 34ELFDynObjReader::~ELFDynObjReader() 35{ 36 delete m_pELFReader; 37} 38 39/// isMyFormat 40bool 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(pInput.fileOffset(), 48 hdr_size); 49 50 uint8_t* ELF_hdr = region->start(); 51 bool result = true; 52 if (!m_pELFReader->isELF(ELF_hdr)) 53 result = false; 54 else if (!m_pELFReader->isMyEndian(ELF_hdr)) 55 result = false; 56 else if (!m_pELFReader->isMyMachine(ELF_hdr)) 57 result = false; 58 else if (MCLDFile::DynObj != m_pELFReader->fileType(ELF_hdr)) 59 result = false; 60 pInput.memArea()->release(region); 61 return result; 62} 63 64/// readDSO 65bool ELFDynObjReader::readDSO(Input& pInput) 66{ 67 assert(pInput.hasMemArea()); 68 69 size_t hdr_size = m_pELFReader->getELFHeaderSize(); 70 MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(), 71 hdr_size); 72 uint8_t* ELF_hdr = region->start(); 73 74 bool shdr_result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr); 75 pInput.memArea()->release(region); 76 77 // read .dynamic to get the correct SONAME 78 bool dyn_result = m_pELFReader->readDynamic(pInput); 79 80 return (shdr_result && dyn_result); 81} 82 83/// readSymbols 84bool ELFDynObjReader::readSymbols(Input& pInput) 85{ 86 assert(pInput.hasMemArea()); 87 88 LDSection* symtab_shdr = pInput.context()->getSection(".dynsym"); 89 if (NULL == symtab_shdr) { 90 note(diag::note_has_no_symtab) << pInput.name() 91 << pInput.path() 92 << ".dynsym"; 93 return true; 94 } 95 96 LDSection* strtab_shdr = symtab_shdr->getLink(); 97 if (NULL == strtab_shdr) { 98 fatal(diag::fatal_cannot_read_strtab) << pInput.name() 99 << pInput.path() 100 << ".dynsym"; 101 return false; 102 } 103 104 MemoryRegion* symtab_region = pInput.memArea()->request( 105 pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size()); 106 107 MemoryRegion* strtab_region = pInput.memArea()->request( 108 pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size()); 109 char* strtab = reinterpret_cast<char*>(strtab_region->start()); 110 bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region, 111 strtab); 112 pInput.memArea()->release(symtab_region); 113 pInput.memArea()->release(strtab_region); 114 115 return result; 116} 117 118