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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFReaderIf.h" 106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/StringRef.h> 196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/ADT/Twine.h> 206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h> 216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Host.h> 226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstring> 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReaderIF 296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymType 3137b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Type ELFReaderIF::getSymType(uint8_t pInfo, 3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint16_t pShndx) const { 336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Type result = static_cast<ResolveInfo::Type>(pInfo & 0xF); 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pShndx == llvm::ELF::SHN_ABS && result == ResolveInfo::Section) { 356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In Mips, __gp_disp is a special section symbol. Its name comes from 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // .strtab, not .shstrtab. However, it is unique. Only it is also a ABS 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // symbol. So here is a tricky to identify __gp_disp and convert it to 386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Object symbol. 396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Object; 406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymDesc 4637b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Desc ELFReaderIF::getSymDesc(uint16_t pShndx, 4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Input& pInput) const { 486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_UNDEF) 496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::Undefined; 506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx < llvm::ELF::SHN_LORESERVE) { 526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // an ELF symbol defined in a section which we are not including 536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // must be treated as an Undefined. 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.context()->getSection(pShndx) == NULL || 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 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pShndx >= llvm::ELF::SHN_LOPROC && pShndx <= llvm::ELF::SHN_HIPROC) 676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getSymDesc(pShndx); 686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: ELF weak alias should be ResolveInfo::Indirect 706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::NoneDesc; 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymBinding 7437b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Binding ELFReaderIF::getSymBinding(uint8_t pBinding, 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint16_t pShndx, 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t pVis) const { 776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if --just-symbols option is enabled, the symbol must covert to Absolute 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (pBinding) { 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::STB_LOCAL: 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines return ResolveInfo::Local; 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::STB_GLOBAL: 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pShndx == llvm::ELF::SHN_ABS) 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines return ResolveInfo::Absolute; 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines return ResolveInfo::Global; 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::STB_WEAK: 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return ResolveInfo::Weak; 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return ResolveInfo::NoneBinding; 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymFragmentRef 9537b74a387bb3993387029859c2d9d051c41c724eStephen HinesFragmentRef* ELFReaderIF::getSymFragmentRef(Input& pInput, 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint16_t pShndx, 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t pOffset) const { 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.type() == Input::DynObj) 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_UNDEF) 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pShndx >= llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* sect_hdr = pInput.context()->getSection(pShndx); 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (sect_hdr == NULL) 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines unreachable(diag::unreachable_invalid_section_idx) 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines << pShndx << pInput.path().native(); 1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (sect_hdr->kind() == LDFileFormat::Ignore) 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (sect_hdr->kind() == LDFileFormat::Group) 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Null(); 1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return FragmentRef::Create(*sect_hdr, pOffset); 1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymVisibility 12337b74a387bb3993387029859c2d9d051c41c724eStephen HinesResolveInfo::Visibility ELFReaderIF::getSymVisibility(uint8_t pVis) const { 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return static_cast<ResolveInfo::Visibility>(pVis); 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSymValue - get the section offset of the symbol. 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFReaderIF::getSymValue(uint64_t pValue, 1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t pShndx, 13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Input& pInput) const { 13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.type() == Input::Object) { 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In relocatable files, st_value holds alignment constraints for a symbol 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // whose section index is SHN_COMMON 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pShndx == llvm::ELF::SHN_COMMON || pShndx == llvm::ELF::SHN_ABS) { 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pValue; 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines // In relocatable files, st_value holds a section offset for a defined 13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines // symbol. 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines // if --just-symbols option are enabled, convert the value from section 14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines // offset 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // to virtual address by adding input section's virtual address. 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // The section's virtual address in relocatable files is normally zero, but 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // people can use link script to change it. 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pValue; 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // In executable and shared object files, st_value holds a virtual address. 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // the virtual address is needed for alias identification. 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines return pValue; 1526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 155