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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectReader.h"
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Input.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFReader.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrameReader.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h"
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h"
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h"
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h"
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h"
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/Support/ELF.h>
2387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/Twine.h>
2487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <llvm/ADT/StringRef.h>
2587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <string>
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <cassert>
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectReader
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// constructor
35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFObjectReader::ELFObjectReader(GNULDBackend& pBackend,
36d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 IRBuilder& pBuilder,
37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 const LinkerConfig& pConfig)
3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : ObjectReader(),
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pELFReader(NULL),
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pEhFrameReader(NULL),
4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Builder(pBuilder),
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_ReadFlag(ParseEhFrame),
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Backend(pBackend),
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Config(pConfig) {
45d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (pConfig.targets().is32Bits() && pConfig.targets().isLittleEndian()) {
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_pELFReader = new ELFReader<32, true>(pBackend);
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else if (pConfig.targets().is64Bits() &&
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines             pConfig.targets().isLittleEndian()) {
496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    m_pELFReader = new ELFReader<64, true>(pBackend);
506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_pEhFrameReader = new EhFrameReader();
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// destructor
5637b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFObjectReader::~ELFObjectReader() {
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  delete m_pELFReader;
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  delete m_pEhFrameReader;
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// isMyFormat
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFObjectReader::isMyFormat(Input& pInput, bool& pContinue) const {
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Don't warning about the frequently requests.
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // MemoryArea has a list of cache to handle this.
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hdr_size = m_pELFReader->getELFHeaderSize();
6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInput.memArea()->size() < hdr_size)
6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  llvm::StringRef region =
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pInput.memArea()->request(pInput.fileOffset(), hdr_size);
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const char* ELF_hdr = region.begin();
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool result = true;
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!m_pELFReader->isELF(ELF_hdr)) {
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pContinue = true;
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else if (Input::Object != m_pELFReader->fileType(ELF_hdr)) {
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pContinue = true;
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else if (!m_pELFReader->isMyEndian(ELF_hdr)) {
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pContinue = false;
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  } else if (!m_pELFReader->isMyMachine(ELF_hdr)) {
8687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    pContinue = false;
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    result = false;
8887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  }
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readHeader - read section header and create LDSections.
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFObjectReader::readHeader(Input& pInput) {
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t hdr_size = m_pELFReader->getELFHeaderSize();
9787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pInput.memArea()->size() < hdr_size)
9887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    return false;
9987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  llvm::StringRef region =
10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pInput.memArea()->request(pInput.fileOffset(), hdr_size);
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const char* ELF_hdr = region.begin();
103cfcb22478ca64c308df58f9abe6fa2dedb213c16Stephen Hines  m_Backend.mergeFlags(pInput, ELF_hdr);
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  bool result = m_pELFReader->readSectionHeaders(pInput, ELF_hdr);
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// readSections - read all regular sections.
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFObjectReader::readSections(Input& pInput) {
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // handle sections
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDContext::sect_iterator section, sectEnd = pInput.context()->sectEnd();
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (section = pInput.context()->sectBegin(); section != sectEnd; ++section) {
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // ignore the section if the LDSection* in input context is NULL
11437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (*section == NULL)
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      continue;
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    switch ((*section)->kind()) {
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** group sections **/
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Group: {
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assert((*section)->getLink() != NULL);
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        ResolveInfo* signature = m_pELFReader->readSignature(
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines            pInput, *(*section)->getLink(), (*section)->getInfo());
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        bool exist = false;
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (signature->nameSize() == 0 &&
126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang            ResolveInfo::Section == signature->type()) {
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // if the signature is a section symbol in input object, we use the
128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          // section name as group signature.
129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          signatures().insert((*section)->name(), exist);
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        } else {
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          signatures().insert(signature->name(), exist);
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        if (exist) {
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // if this is not the first time we see this group signature, then
13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          // ignore all the members in this group (set Ignore)
13787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          llvm::StringRef region = pInput.memArea()->request(
13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines              pInput.fileOffset() + (*section)->offset(), (*section)->size());
13987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          const llvm::ELF::Elf32_Word* value =
14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines              reinterpret_cast<const llvm::ELF::Elf32_Word*>(region.begin());
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines          size_t size = region.size() / sizeof(llvm::ELF::Elf32_Word);
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          if (llvm::ELF::GRP_COMDAT == *value) {
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            for (size_t index = 1; index < size; ++index) {
14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines              pInput.context()->getSection(value[index])->setKind(
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                  LDFileFormat::Ignore);
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            }
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
15022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        ResolveInfo::Destroy(signature);
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      /** linkonce sections **/
154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      case LDFileFormat::LinkOnce: {
155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        bool exist = false;
156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        // .gnu.linkonce + "." + type + "." + name
15737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        llvm::StringRef name(
15837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            llvm::StringRef((*section)->name()).drop_front(14));
159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        signatures().insert(name.split(".").second, exist);
160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        if (!exist) {
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          if (name.startswith("wi")) {
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            (*section)->setKind(LDFileFormat::Debug);
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            if (m_Config.options().stripDebug())
164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines              (*section)->setKind(LDFileFormat::Ignore);
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            else {
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines              SectionData* sd = IRBuilder::CreateSectionData(**section);
167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines              if (!m_pELFReader->readRegularSection(pInput, *sd))
168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                fatal(diag::err_cannot_read_section) << (*section)->name();
169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            }
170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          } else {
1710dea6bc96bb52346737966839ac68644f7939f58Stephen Hines            if (((*section)->flag() & llvm::ELF::SHF_EXECINSTR) != 0)
1720dea6bc96bb52346737966839ac68644f7939f58Stephen Hines              (*section)->setKind(LDFileFormat::TEXT);
1730dea6bc96bb52346737966839ac68644f7939f58Stephen Hines            else
1740dea6bc96bb52346737966839ac68644f7939f58Stephen Hines              (*section)->setKind(LDFileFormat::DATA);
175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            SectionData* sd = IRBuilder::CreateSectionData(**section);
176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines            if (!m_pELFReader->readRegularSection(pInput, *sd))
177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines              fatal(diag::err_cannot_read_section) << (*section)->name();
178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          }
179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        } else {
180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          (*section)->setKind(LDFileFormat::Ignore);
181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        }
182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines        break;
183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      }
1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** relocation sections **/
1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Relocation: {
18637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        assert((*section)->getLink() != NULL);
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        size_t link_index = (*section)->getLink()->index();
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        LDSection* link_sect = pInput.context()->getSection(link_index);
18937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        if (link_sect == NULL || link_sect->kind() == LDFileFormat::Ignore) {
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // Relocation sections of group members should also be part of the
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // group. Thus, if the associated member sections are ignored, the
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          // related relocations should be also ignored.
19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*section)->setKind(LDFileFormat::Ignore);
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        }
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** normal sections **/
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: support Version Kind
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Version:
20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      // FIXME: support GCCExceptTable Kind
20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::GCCExceptTable:
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** Fall through **/
2030dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      case LDFileFormat::TEXT:
2040dea6bc96bb52346737966839ac68644f7939f58Stephen Hines      case LDFileFormat::DATA:
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Note:
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::MetaData: {
20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        SectionData* sd = IRBuilder::CreateSectionData(**section);
20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!m_pELFReader->readRegularSection(pInput, *sd))
209affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_section) << (*section)->name();
210affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
211affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::Debug:
21337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case LDFileFormat::DebugString: {
214d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if (m_Config.options().stripDebug()) {
21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          (*section)->setKind(LDFileFormat::Ignore);
21637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        } else {
21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          SectionData* sd = IRBuilder::CreateSectionData(**section);
21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!m_pELFReader->readRegularSection(pInput, *sd)) {
21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            fatal(diag::err_cannot_read_section) << (*section)->name();
22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
222affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
223affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame: {
22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        EhFrame* eh_frame = IRBuilder::CreateEhFrame(**section);
22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
22787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        // We don't really parse EhFrame if this is a partial linking
22887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if ((m_Config.codeGenType() != LinkerConfig::Object) &&
22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            (m_ReadFlag & ParseEhFrame)) {
23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!m_pEhFrameReader->read<32, true>(pInput, *eh_frame)) {
23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // if we failed to parse a .eh_frame, we should not parse the rest
23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            // .eh_frame.
23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            m_ReadFlag ^= ParseEhFrame;
23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
23537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        } else {
23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          if (!m_pELFReader->readRegularSection(pInput,
237f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines                                                *eh_frame->getSectionData())) {
23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao            fatal(diag::err_cannot_read_section) << (*section)->name();
23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** target dependent sections **/
2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Target: {
24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        SectionData* sd = IRBuilder::CreateSectionData(**section);
24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (!m_Backend.readSection(pInput, *sd)) {
247affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          fatal(diag::err_cannot_read_target_section) << (*section)->name();
24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      /** BSS sections **/
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::BSS: {
25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        IRBuilder::CreateBSS(**section);
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        break;
2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      // ignore
2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::Null:
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      case LDFileFormat::NamePool:
25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Ignore:
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::StackNote:
2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        continue;
262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      // warning
263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrameHdr:
264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      default: {
26537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        warning(diag::warn_illegal_input_section)
26637b74a387bb3993387029859c2d9d051c41c724eStephen Hines            << (*section)->name() << pInput.name() << pInput.path();
267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    }
27037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of for all sections
2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// readSymbols - read symbols from the input relocatable object.
27637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFObjectReader::readSymbols(Input& pInput) {
2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* symtab_shdr = pInput.context()->getSection(".symtab");
28037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (symtab_shdr == NULL) {
28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    note(diag::note_has_no_symtab) << pInput.name() << pInput.path()
282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   << ".symtab";
283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return true;
284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  LDSection* strtab_shdr = symtab_shdr->getLink();
28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (strtab_shdr == NULL) {
28837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    fatal(diag::fatal_cannot_read_strtab) << pInput.name() << pInput.path()
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                          << ".symtab";
2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
29387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef symtab_region = pInput.memArea()->request(
29487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      pInput.fileOffset() + symtab_shdr->offset(), symtab_shdr->size());
29587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::StringRef strtab_region = pInput.memArea()->request(
29687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      pInput.fileOffset() + strtab_shdr->offset(), strtab_shdr->size());
29787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  const char* strtab = strtab_region.begin();
29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  bool result =
29937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pELFReader->readSymbols(pInput, m_Builder, symtab_region, strtab);
3005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
3015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
30337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFObjectReader::readRelocations(Input& pInput) {
3045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(pInput.hasMemArea());
3055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  MemoryArea* mem = pInput.memArea();
30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  LDContext::sect_iterator rs, rsEnd = pInput.context()->relocSectEnd();
30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (rs = pInput.context()->relocSectBegin(); rs != rsEnd; ++rs) {
30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    if (LDFileFormat::Ignore == (*rs)->kind())
31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      continue;
3115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint32_t offset = pInput.fileOffset() + (*rs)->offset();
31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    uint32_t size = (*rs)->size();
31487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    llvm::StringRef region = mem->request(offset, size);
31537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    IRBuilder::CreateRelocData(
31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        **rs);  ///< create relocation data for the header
31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch ((*rs)->type()) {
31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case llvm::ELF::SHT_RELA: {
31987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (!m_pELFReader->readRela(pInput, **rs, region)) {
32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return false;
32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case llvm::ELF::SHT_REL: {
32587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        if (!m_pELFReader->readRel(pInput, **rs, region)) {
32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          return false;
32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
33037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default: {  ///< should not enter
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return false;
33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
33337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of switch
33437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of for all relocation data
33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return true;
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
33937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
340