16f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===- ELFReader.cpp ------------------------------------------------------===// 26f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 36f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// The MCLinker Project 46f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 56f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// This file is distributed under the University of Illinois Open Source 66f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// License. See LICENSE.TXT for details. 76f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// 86f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 96f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/ELFReaderIf.h> 106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/IRBuilder.h> 126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/FillFragment.h> 136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/EhFrame.h> 146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/SectionData.h> 156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Target/GNULDBackend.h> 166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <cstring> 186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/StringRef.h> 206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/Twine.h> 216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h> 226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Host.h> 236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace mcld; 256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReaderIF 286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymType 306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo::Type ELFReaderIF::getSymType(uint8_t pInfo, uint16_t pShndx) const 316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Type result = static_cast<ResolveInfo::Type>(pInfo & 0xF); 336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHN_ABS == pShndx && ResolveInfo::Section == result) { 346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In Mips, __gp_disp is a special section symbol. Its name comes from 356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // .strtab, not .shstrtab. However, it is unique. Only it is also a ABS 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // symbol. So here is a tricky to identify __gp_disp and convert it to 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Object symbol. 386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Object; 396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymDesc 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo::Desc ELFReaderIF::getSymDesc(uint16_t pShndx, const Input& pInput) const 466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_UNDEF) 486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Undefined; 496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx < llvm::ELF::SHN_LORESERVE) { 516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // an ELF symbol defined in a section which we are not including 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be treated as an Undefined. 536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref Google gold linker: symtab.cc: 1086 546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == pInput.context()->getSection(pShndx) || 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDFileFormat::Ignore == pInput.context()->getSection(pShndx)->kind()) 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Undefined; 576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Define; 586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_ABS) 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Define; 626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_COMMON) 646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Common; 656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx >= llvm::ELF::SHN_LOPROC && 676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pShndx <= llvm::ELF::SHN_HIPROC) 686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getSymDesc(pShndx); 696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: ELF weak alias should be ResolveInfo::Indirect 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::NoneDesc; 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymBinding 756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo::Binding 766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReaderIF::getSymBinding(uint8_t pBinding, uint16_t pShndx, uint8_t pVis) const 776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if --just-symbols option is enabled, the symbol must covert to Absolute 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(pBinding) { 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::STB_LOCAL: 846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Local; 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::STB_GLOBAL: 86f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (pShndx == llvm::ELF::SHN_ABS) 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return ResolveInfo::Absolute; 886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Global; 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::STB_WEAK: 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Weak; 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::NoneBinding; 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymFragmentRef 976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesFragmentRef* 986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReaderIF::getSymFragmentRef(Input& pInput, 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t pShndx, 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t pOffset) const 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (Input::DynObj == pInput.type()) 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_UNDEF) 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx >= llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* sect_hdr = pInput.context()->getSection(pShndx); 1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == sect_hdr) 1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unreachable(diag::unreachable_invalid_section_idx) << pShndx 1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pInput.path().native(); 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LDFileFormat::Ignore == sect_hdr->kind()) 1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LDFileFormat::Group == sect_hdr->kind()) 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Create(*sect_hdr, pOffset); 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymVisibility 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo::Visibility 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReaderIF::getSymVisibility(uint8_t pVis) const 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return static_cast<ResolveInfo::Visibility>(pVis); 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymValue - get the section offset of the symbol. 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFReaderIF::getSymValue(uint64_t pValue, 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t pShndx, 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Input& pInput) const 1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (Input::Object == pInput.type()) { 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In relocatable files, st_value holds alignment constraints for a symbol 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // whose section index is SHN_COMMON 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_COMMON || pShndx == llvm::ELF::SHN_ABS) { 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pValue; 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In relocatable files, st_value holds a section offset for a defined symbol. 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if --just-symbols option are enabled, convert the value from section offset 1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // to virtual address by adding input section's virtual address. 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // The section's virtual address in relocatable files is normally zero, but 1516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // people can use link script to change it. 1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pValue; 1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In executable and shared object files, st_value holds a virtual address. 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // the virtual address is needed for alias identification. 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return pValue; 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 160