15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFObjectReader.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//===----------------------------------------------------------------------===//
9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <string>
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert>
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h>
15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h>
18cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h>
19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/ELFReader.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/ELFObjectReader.h>
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//==========================
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectReader
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// constructor
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectReader::ELFObjectReader(GNULDBackend& pBackend, MCLinker& pLinker)
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : ObjectReader(),
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pELFReader(0),
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_Linker(pLinker)
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) {
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pELFReader = new ELFReader<32, true>(pBackend);
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// destructor
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectReader::~ELFObjectReader()
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  delete m_pELFReader;
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isMyFormat
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::isMyFormat(Input &pInput) const
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Don't warning about the frequently requests.
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // MemoryArea has a list of cache to handle this.
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hdr_size = m_pELFReader->getELFHeaderSize();
5367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
5467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                     hdr_size);
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t* ELF_hdr = region->start();
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool result = true;
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!m_pELFReader->isELF(ELF_hdr))
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (!m_pELFReader->isMyEndian(ELF_hdr))
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (!m_pELFReader->isMyMachine(ELF_hdr))
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (MCLDFile::Object != m_pELFReader->fileType(ELF_hdr))
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(region);
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readObject - read section header and create LDSections.
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readObject(Input& pInput)
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hdr_size = m_pELFReader->getELFHeaderSize();
7667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
7767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                     hdr_size);
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t* ELF_hdr = region->start();
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool result = m_pELFReader->readSectionHeaders(pInput, m_Linker, ELF_hdr);
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(region);
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readSections - read all regular sections.
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readSections(Input& pInput)
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // handle sections
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ignore the section if the LDSection* in input context is NULL
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == *section)
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch((*section)->kind()) {
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** group sections **/
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Group: {
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        assert(NULL != (*section)->getLink());
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        ResolveInfo* signature =
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              m_pELFReader->readSymbol(pInput,
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       *(*section)->getLink(),
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       m_Linker.getLDInfo(),
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                       (*section)->getInfo());
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        bool exist = false;
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (0 == std::strlen(signature->name()) &&
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            ResolveInfo::Section == signature->type()) {
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // if the signature is a section symbol in input object, we use the
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // section name as group signature.
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          signatures().insert((*section)->name(), exist);
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        } else {
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          signatures().insert(signature->name(), exist);
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (exist) {
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // if this is not the first time we see this group signature, then
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // ignore all the members in this group (set NULL)
11767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao          MemoryRegion* region = pInput.memArea()->request(
11867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao               pInput.fileOffset() + (*section)->offset(), (*section)->size());
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          llvm::ELF::Elf32_Word* value =
12067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                     reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          size_t size = region->size() / sizeof(llvm::ELF::Elf32_Word);
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (llvm::ELF::GRP_COMDAT == *value) {
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao            for (size_t index = 1; index < size; ++index)
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              pInput.context()->getSectionTable()[value[index]] = NULL;
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          pInput.memArea()->release(region);
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** relocation sections **/
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Relocation: {
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        assert(NULL != (*section)->getLink());
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        size_t link_index = (*section)->getLink()->index();
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (NULL == pInput.context()->getSectionTable()[link_index]) {
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Relocation sections of group members should also be part of the
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // group. Thus, if the associated member sections are ignored, the
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // related relocations should be also ignored.
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          *section = NULL;
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** normal sections **/
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // FIXME: support Version Kinds
1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Version:
1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** Fall through **/
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Regular:
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Note:
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Debug:
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::MetaData: {
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_section) << (*section)->name();
153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrame: {
156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!m_pELFReader->readEhFrame(pInput, m_Linker, **section))
157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_section) <<(*section)->name();
158affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
159affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
160affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::GCCExceptTable: {
161affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        //if (!m_pELFReader->readExceptionSection(pInput, m_Linker, **section))
162affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (!m_pELFReader->readRegularSection(pInput, m_Linker, **section))
163affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_section) << (*section)->name();
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** target dependent sections **/
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Target: {
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (!m_pELFReader->readTargetSection(pInput, m_Linker, **section))
169affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_target_section) << (*section)->name();
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** BSS sections **/
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::BSS: {
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        LDSection& output_bss = m_Linker.getOrCreateOutputSectHdr(
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                               (*section)->name(),
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                               LDFileFormat::BSS,
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                               llvm::ELF::SHT_NOBITS,
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                               llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE);
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
180cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        SectionData& sect_data = m_Linker.getOrCreateSectData(**section);
181cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao                                            /*  value, valsize, size*/
182cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao        FillFragment* frag = new FillFragment(0x0,   1,       (*section)->size());
1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        uint64_t size = m_Linker.getLayout().appendFragment(*frag,
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                            sect_data,
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                                            (*section)->align());
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        output_bss.setSize(output_bss.size() + size);
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Null:
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::NamePool:
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
194affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // warning
195affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrameHdr:
196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      default: {
197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        warning(diag::warn_illegal_input_section) << (*section)->name()
198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                  << pInput.name()
199affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                  << pInput.path();
200affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
201affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of for all sections
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readSymbols - read symbols into MCLinker from the input relocatable object.
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readSymbols(Input& pInput)
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* symtab_shdr = pInput.context()->getSection(".symtab");
214affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == symtab_shdr) {
215affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    note(diag::note_has_no_symtab) << pInput.name()
216affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   << pInput.path()
217affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   << ".symtab";
218affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
219affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* strtab_shdr = symtab_shdr->getLink();
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == strtab_shdr) {
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::fatal_cannot_read_strtab) << pInput.name()
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << pInput.path()
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << ".symtab";
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
22967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* symtab_region = pInput.memArea()->request(
23067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao             pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size());
23167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* strtab_region = pInput.memArea()->request(
23267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao             pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = reinterpret_cast<char*>(strtab_region->start());
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool result = m_pELFReader->readSymbols(pInput,
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          m_Linker,
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          *symtab_region,
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          strtab);
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(symtab_region);
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(strtab_region);
2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readRelocations(Input& pInput)
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryArea* mem = pInput.memArea();
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ignore the section if the LDSection* in input context is NULL
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == *section)
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if ((*section)->type() == llvm::ELF::SHT_RELA &&
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        (*section)->kind() == LDFileFormat::Relocation) {
25667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      MemoryRegion* region = mem->request(
25767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao               pInput.fileOffset() + (*section)->offset(), (*section)->size());
25867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      bool result = m_pELFReader->readRela(pInput, m_Linker, **section,
25967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                           *region);
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      mem->release(region);
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!result)
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    else if ((*section)->type() == llvm::ELF::SHT_REL &&
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao             (*section)->kind() == LDFileFormat::Relocation) {
26667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao      MemoryRegion* region = mem->request(
26767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao               pInput.fileOffset() + (*section)->offset(), (*section)->size());
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      bool result = m_pELFReader->readRel(pInput, m_Linker, **section, *region);
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      mem->release(region);
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      if (!result)
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
277