15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFDynObjReader.cpp ------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h> 10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 11d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LinkerConfig.h> 12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/IRBuilder.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFReader.h> 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/MC/Input.h> 15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 16f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/MemoryArea.h> 17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 18f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/ADT/StringRef.h> 19d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/ADT/Twine.h> 20d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFDynObjReader 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 29d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynObjReader::ELFDynObjReader(GNULDBackend& pBackend, 30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder& pBuilder, 31d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const LinkerConfig& pConfig) 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : DynObjReader(), 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pELFReader(0), 34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Builder(pBuilder) { 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (pConfig.targets().is32Bits() && pConfig.targets().isLittleEndian()) 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pELFReader = new ELFReader<32, true>(pBackend); 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pConfig.targets().is64Bits() && pConfig.targets().isLittleEndian()) 386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pELFReader = new ELFReader<64, true>(pBackend); 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFDynObjReader::~ELFDynObjReader() 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pELFReader; 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isMyFormat 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFDynObjReader::isMyFormat(Input &pInput, bool &pContinue) const 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pInput.hasMemArea()); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Don't warning about the frequently requests. 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // MemoryArea has a list of cache to handle this. 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t hdr_size = m_pELFReader->getELFHeaderSize(); 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pInput.memArea()->size() < hdr_size) 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef region = pInput.memArea()->request(pInput.fileOffset(), 58f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines hdr_size); 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* ELF_hdr = region.begin(); 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool result = true; 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!m_pELFReader->isELF(ELF_hdr)) { 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pContinue = true; 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } else if (Input::DynObj != m_pELFReader->fileType(ELF_hdr)) { 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pContinue = true; 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } else if (!m_pELFReader->isMyEndian(ELF_hdr)) { 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pContinue = false; 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } else if (!m_pELFReader->isMyMachine(ELF_hdr)) { 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pContinue = false; 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readHeader 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFDynObjReader::readHeader(Input& pInput) 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pInput.hasMemArea()); 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t hdr_size = m_pELFReader->getELFHeaderSize(); 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef region = pInput.memArea()->request(pInput.fileOffset(), 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines hdr_size); 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* ELF_hdr = region.begin(); 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool shdr_result = m_pELFReader->readSectionHeaders(pInput, ELF_hdr); 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // read .dynamic to get the correct SONAME 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bool dyn_result = m_pELFReader->readDynamic(pInput); 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (shdr_result && dyn_result); 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readSymbols 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFDynObjReader::readSymbols(Input& pInput) 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pInput.hasMemArea()); 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* symtab_shdr = pInput.context()->getSection(".dynsym"); 102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == symtab_shdr) { 103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang note(diag::note_has_no_symtab) << pInput.name() 104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pInput.path() 105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << ".dynsym"; 106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* strtab_shdr = symtab_shdr->getLink(); 110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == strtab_shdr) { 111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::fatal_cannot_read_strtab) << pInput.name() 112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pInput.path() 113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << ".dynsym"; 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 117f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef symtab_region = pInput.memArea()->request( 118f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size()); 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 120f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef strtab_region = pInput.memArea()->request( 121f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size()); 122f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* strtab = strtab_region.begin(); 123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao bool result = m_pELFReader->readSymbols(pInput, m_Builder, 124f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines symtab_region, strtab); 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 128