ELFDynObjReader.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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 <llvm/ADT/Twine.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/OwningPtr.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFDynObjReader.h> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFReader.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h> 1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFDynObjReader 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFDynObjReader::ELFDynObjReader(GNULDBackend& pBackend, FragmentLinker& pLinker) 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : DynObjReader(), 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pELFReader(0), 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_Linker(pLinker) { 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_pELFReader = new ELFReader<32, true>(pBackend); 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFDynObjReader::~ELFDynObjReader() 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pELFReader; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isMyFormat 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFDynObjReader::isMyFormat(Input &pInput) const 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pInput.hasMemArea()); 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Don't warning about the frequently requests. 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // MemoryArea has a list of cache to handle this. 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t hdr_size = m_pELFReader->getELFHeaderSize(); 4867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(), 4967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao hdr_size); 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t* ELF_hdr = region->start(); 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool result = true; 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!m_pELFReader->isELF(ELF_hdr)) 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (!m_pELFReader->isMyEndian(ELF_hdr)) 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (!m_pELFReader->isMyMachine(ELF_hdr)) 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else if (Input::DynObj != m_pELFReader->fileType(ELF_hdr)) 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = false; 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pInput.memArea()->release(region); 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readHeader 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFDynObjReader::readHeader(Input& pInput) 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pInput.hasMemArea()); 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t hdr_size = m_pELFReader->getELFHeaderSize(); 7167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(), 7267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao hdr_size); 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint8_t* ELF_hdr = region->start(); 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool shdr_result = m_pELFReader->readSectionHeaders(pInput, ELF_hdr); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pInput.memArea()->release(region); 77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // read .dynamic to get the correct SONAME 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang bool dyn_result = m_pELFReader->readDynamic(pInput); 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return (shdr_result && dyn_result); 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readSymbols 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFDynObjReader::readSymbols(Input& pInput) 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pInput.hasMemArea()); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* symtab_shdr = pInput.context()->getSection(".dynsym"); 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == symtab_shdr) { 91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang note(diag::note_has_no_symtab) << pInput.name() 92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pInput.path() 93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << ".dynsym"; 94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* strtab_shdr = symtab_shdr->getLink(); 98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (NULL == strtab_shdr) { 99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang fatal(diag::fatal_cannot_read_strtab) << pInput.name() 100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << pInput.path() 101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang << ".dynsym"; 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return false; 103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao MemoryRegion* symtab_region = pInput.memArea()->request( 10667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size()); 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 10867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao MemoryRegion* strtab_region = pInput.memArea()->request( 10967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size()); 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* strtab = reinterpret_cast<char*>(strtab_region->start()); 11167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao bool result = m_pELFReader->readSymbols(pInput, m_Linker, *symtab_region, 11267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao strtab); 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pInput.memArea()->release(symtab_region); 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pInput.memArea()->release(strtab_region); 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 119