ELFObjectReader.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectReader.h>
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <string>
12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cassert>
13cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/Twine.h>
16cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInput.h>
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/ELFReader.h>
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrameReader.h>
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h>
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h>
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h>
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectReader
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// constructor
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectReader::ELFObjectReader(GNULDBackend& pBackend, FragmentLinker& pLinker)
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : ObjectReader(),
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pELFReader(NULL),
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_pEhFrameReader(NULL),
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_Linker(pLinker),
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_ReadFlag(ParseEhFrame),
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_Backend(pBackend) {
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (32 == pBackend.bitclass() && pBackend.isLittleEndian()) {
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pELFReader = new ELFReader<32, true>(pBackend);
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pEhFrameReader = new EhFrameReader();
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// destructor
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectReader::~ELFObjectReader()
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  delete m_pELFReader;
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrameReader;
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isMyFormat
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::isMyFormat(Input &pInput) const
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Don't warning about the frequently requests.
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // MemoryArea has a list of cache to handle this.
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hdr_size = m_pELFReader->getELFHeaderSize();
6267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
6367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                     hdr_size);
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t* ELF_hdr = region->start();
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool result = true;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!m_pELFReader->isELF(ELF_hdr))
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (!m_pELFReader->isMyEndian(ELF_hdr))
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if (!m_pELFReader->isMyMachine(ELF_hdr))
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else if (Input::Object != m_pELFReader->fileType(ELF_hdr))
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(region);
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readHeader - read section header and create LDSections.
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFObjectReader::readHeader(Input& pInput)
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hdr_size = m_pELFReader->getELFHeaderSize();
8567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* region = pInput.memArea()->request(pInput.fileOffset(),
8667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                                                     hdr_size);
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint8_t* ELF_hdr = region->start();
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool result = m_pELFReader->readSectionHeaders(pInput, ELF_hdr);
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(region);
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readSections - read all regular sections.
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readSections(Input& pInput)
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // handle sections
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ignore the section if the LDSection* in input context is NULL
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    if (NULL == *section)
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    switch((*section)->kind()) {
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** group sections **/
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Group: {
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        assert(NULL != (*section)->getLink());
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        ResolveInfo* signature =
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              m_pELFReader->readSignature(pInput,
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          *(*section)->getLink(),
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                          (*section)->getInfo());
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        bool exist = false;
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (0 == signature->nameSize() &&
114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            ResolveInfo::Section == signature->type()) {
115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // if the signature is a section symbol in input object, we use the
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // section name as group signature.
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          signatures().insert((*section)->name(), exist);
118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        } else {
119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          signatures().insert(signature->name(), exist);
120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (exist) {
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // if this is not the first time we see this group signature, then
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // ignore all the members in this group (set Ignore)
12567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao          MemoryRegion* region = pInput.memArea()->request(
12667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao               pInput.fileOffset() + (*section)->offset(), (*section)->size());
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          llvm::ELF::Elf32_Word* value =
12867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao                     reinterpret_cast<llvm::ELF::Elf32_Word*>(region->start());
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          size_t size = region->size() / sizeof(llvm::ELF::Elf32_Word);
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (llvm::ELF::GRP_COMDAT == *value) {
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            for (size_t index = 1; index < size; ++index) {
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao              pInput.context()->getSection(value[index])->setKind(LDFileFormat::Ignore);
13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          pInput.memArea()->release(region);
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ResolveInfo::Destroy(signature);
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** relocation sections **/
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Relocation: {
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        assert(NULL != (*section)->getLink());
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        size_t link_index = (*section)->getLink()->index();
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* link_sect = pInput.context()->getSection(link_index);
14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == link_sect || LDFileFormat::Ignore == link_sect->kind()) {
1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Relocation sections of group members should also be part of the
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // group. Thus, if the associated member sections are ignored, the
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // related relocations should be also ignored.
15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*section)->setKind(LDFileFormat::Ignore);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** normal sections **/
15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: support Version Kind
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Version:
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: support GCCExceptTable Kind
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::GCCExceptTable:
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** Fall through **/
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Regular:
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Note:
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::MetaData: {
16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        SectionData* sd = IRBuilder::CreateSectionData(**section);
16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!m_pELFReader->readRegularSection(pInput, *sd))
165affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_section) << (*section)->name();
166affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
167affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Debug: {
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (m_Linker.getLDInfo().options().stripDebug()) {
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*section)->setKind(LDFileFormat::Ignore);
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else {
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          SectionData* sd = IRBuilder::CreateSectionData(**section);
17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!m_pELFReader->readRegularSection(pInput, *sd)) {
17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            fatal(diag::err_cannot_read_section) << (*section)->name();
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
178affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
179affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame: {
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        EhFrame* eh_frame = IRBuilder::CreateEhFrame(**section);
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (m_Linker.getLDInfo().options().hasEhFrameHdr() &&
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            (m_ReadFlag & ParseEhFrame)) {
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // if --eh-frame-hdr option is given, parse .eh_frame.
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!m_pEhFrameReader->read<32, true>(pInput, *eh_frame)) {
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // if we failed to parse a .eh_frame, we should not parse the rest
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // .eh_frame.
19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            m_ReadFlag ^= ParseEhFrame;
19122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        else {
19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!m_pELFReader->readRegularSection(pInput,
19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                                eh_frame->getSectionData())) {
19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            fatal(diag::err_cannot_read_section) << (*section)->name();
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** target dependent sections **/
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Target: {
20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        SectionData* sd = IRBuilder::CreateSectionData(**section);
20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!m_Backend.readSection(pInput, *sd)) {
205affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_target_section) << (*section)->name();
20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** BSS sections **/
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::BSS: {
21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        IRBuilder::CreateBSS(**section);
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Null:
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::NamePool:
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Ignore:
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::StackNote:
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
220affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // warning
221affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrameHdr:
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      default: {
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        warning(diag::warn_illegal_input_section) << (*section)->name()
224affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                  << pInput.name()
225affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                                  << pInput.path();
226affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
227affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  } // end of for all sections
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSymbols - read symbols into FragmentLinker from the input relocatable object.
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readSymbols(Input& pInput)
2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* symtab_shdr = pInput.context()->getSection(".symtab");
240affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == symtab_shdr) {
241affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    note(diag::note_has_no_symtab) << pInput.name()
242affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   << pInput.path()
243affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   << ".symtab";
244affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
245affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
246affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* strtab_shdr = symtab_shdr->getLink();
248affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (NULL == strtab_shdr) {
249affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    fatal(diag::fatal_cannot_read_strtab) << pInput.name()
250affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << pInput.path()
251affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << ".symtab";
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
25567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* symtab_region = pInput.memArea()->request(
25667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao             pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size());
25767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  MemoryRegion* strtab_region = pInput.memArea()->request(
25867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao             pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  char* strtab = reinterpret_cast<char*>(strtab_region->start());
2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool result = m_pELFReader->readSymbols(pInput,
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          m_Linker,
2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          *symtab_region,
2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                          strtab);
2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(symtab_region);
2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pInput.memArea()->release(strtab_region);
2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool ELFObjectReader::readRelocations(Input& pInput)
2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryArea* mem = pInput.memArea();
27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDContext::sect_iterator rs, rsEnd = pInput.context()->relocSectEnd();
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (rs = pInput.context()->relocSectBegin(); rs != rsEnd; ++rs) {
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LDFileFormat::Ignore == (*rs)->kind())
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint32_t offset = pInput.fileOffset() + (*rs)->offset();
28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint32_t size = (*rs)->size();
28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MemoryRegion* region = mem->request(offset, size);
28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    IRBuilder::CreateRelocData(**rs); ///< create relocation data for the header
28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch ((*rs)->type()) {
28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case llvm::ELF::SHT_RELA: {
28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!m_pELFReader->readRela(pInput, m_Linker, **rs, *region)) {
28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          mem->release(region);
28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return false;
28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case llvm::ELF::SHT_REL: {
29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!m_pELFReader->readRel(pInput, m_Linker, **rs, *region)) {
29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          mem->release(region);
29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return false;
29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default: { ///< should not enter
29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        mem->release(region);
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    } // end of switch
30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    mem->release(region);
30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of for all relocation data
30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
3085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
310