Home | History | Annotate | Download | only in LD
      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