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(); 103b0d0eb206527b43c771933602e147bbd7b471082Stephen 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