15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFReader.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//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFReader.h> 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/IRBuilder.h> 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FillFragment.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/EhFrame.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/SectionData.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 16f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Target/GNUInfo.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 18f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <mcld/Support/MemoryArea.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/ADT/StringRef.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/ADT/Twine.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/ELF.h> 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/Host.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <iostream> 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace mcld; 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader<32, true> 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// constructor 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::ELFReader(GNULDBackend& pBackend) 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : ELFReaderIF(pBackend) { 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// destructor 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::~ELFReader() 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isELF - is this a ELF file 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<32, true>::isELF(const void* pELFHeader) const 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4)) 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRegularSection - read a regular section and create fragments. 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::readRegularSection(Input& pInput, SectionData& pSD) const 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t size = pSD.getSection().size(); 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder::AppendFragment(*frag, pSD); 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSymbols - read ELF symbols and create LDSymbol 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readSymbols(Input& pInput, 69d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder& pBuilder, 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion, 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* pStrTab) const 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get number of symbols 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym); 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Sym* symtab = 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Sym*>(pRegion.begin()); 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_name = 0x0; 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_value = 0x0; 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_size = 0x0; 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_info = 0x0; 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_other = 0x0; 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // skip the first NULL symbol 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.context()->addSymbol(LDSymbol::Null()); 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// recording symbols added from DynObj to analyze weak alias 89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo> potential_aliases; 90f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool is_dyn_obj = (pInput.type()==Input::DynObj); 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 1; idx < entsize; ++idx) { 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_info = symtab[idx].st_info; 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = symtab[idx].st_other; 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_name = symtab[idx].st_name; 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_value = symtab[idx].st_value; 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_size = symtab[idx].st_size; 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = symtab[idx].st_shndx; 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_name = mcld::bswap32(symtab[idx].st_name); 103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_value = mcld::bswap32(symtab[idx].st_value); 104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_size = mcld::bswap32(symtab[idx].st_size); 105d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(symtab[idx].st_shndx); 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the section should not be included, set the st_shndx SHN_UNDEF 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // - A section in interrelated groups are not included. 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pInput.type() == Input::Object && 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx < llvm::ELF::SHN_LORESERVE && 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx != llvm::ELF::SHN_UNDEF) { 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == pInput.context()->getSection(st_shndx)) 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = llvm::ELF::SHN_UNDEF; 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_type 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_desc 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_binding 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_value - ld_value must be section relative. 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_vis 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 132d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // get section 133d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LDSection* section = NULL; 134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 135d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao section = pInput.context()->getSection(st_shndx); 136d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 138d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::string ld_name; 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section == ld_type) { 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Section symbol's st_name is the section index. 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != section && "get a invalid section"); 142d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = section->name(); 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = std::string(pStrTab + st_name); 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 148f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LDSymbol* psym = pBuilder.AddSymbol(pInput, 149f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_name, 150f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_type, 151f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_desc, 152f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_binding, 153f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines st_size, 154f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_value, 155f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines section, 156f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_vis); 157f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 158f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (is_dyn_obj 159f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && NULL != psym 160f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && ResolveInfo::Undefined != ld_desc 161f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && (ResolveInfo::Global == ld_binding || 162f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ResolveInfo::Weak == ld_binding) 163f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && ResolveInfo::Object == ld_type) { 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AliasInfo p; 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.pt_alias = psym; 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_binding = ld_binding; 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_value = ld_value; 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines potential_aliases.push_back(p); 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for loop 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // analyze weak alias 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: it is better to let IRBuilder handle alias anlysis. 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 1. eliminate code duplication 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 2. easy to know if a symbol is from .so 177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // (so that it may be a potential alias) 178f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (is_dyn_obj) { 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort symbols by symbol value and then weak before strong 180f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::sort(potential_aliases.begin(), potential_aliases.end(), less); 181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for each weak symbol, find out all its aliases, and 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // then link them as a circular list in Module 184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator sym_it, sym_e; 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_e = potential_aliases.end(); 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (sym_it = potential_aliases.begin(); sym_it!=sym_e; ++sym_it) { 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::Weak!=sym_it->ld_binding) 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module& pModule = pBuilder.getModule(); 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator alias_it = sym_it+1; 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while(alias_it!=sym_e) { 193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it->ld_value != alias_it->ld_value) 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 196f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it + 1 == alias_it) 197f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.CreateAliasList(*sym_it->pt_alias->resolveInfo()); 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.addAlias(*alias_it->pt_alias->resolveInfo()); 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++alias_it; 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 201f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 202f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines sym_it = alias_it - 1; 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }// end of for loop 204f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 205f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader::read relocations - read ELF rela and rel, and create Relocation 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ELFReader::readRela - read ELF rela and create Relocation 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRela(Input& pInput, 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 215f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion) const 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rela 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela); 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rela* relaTab = 220f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Rela*>(pRegion.begin()); 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx=0; idx < entsize; ++idx) { 223f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 224f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int32_t r_addend = 0; 227f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!target().readRelocation(relaTab[idx], r_type, r_sym, r_offset, r_addend)) 228f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == symbol) { 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 235d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRel - read ELF rel and create Relocation 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRel(Input& pInput, 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 243f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion) const 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rel 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel); 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rel* relTab = 248f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Rel*>(pRegion.begin()); 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx=0; idx < entsize; ++idx) { 251f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 252f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 255f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!target().readRelocation(relTab[idx], r_type, r_sym, r_offset)) 256f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == symbol) { 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 263d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyEndian - is this ELF file in the same endian to me? 269f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<32, true>::isMyEndian(const void* pELFHeader) const 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 271f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 272f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyMachine - is this ELF file generated for the same machine. 278f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<32, true>::isMyMachine(const void* pELFHeader) const 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 280f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 281f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28321433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 284d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (hdr->e_machine == target().getInfo().machine()); 285d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// fileType - return the file type 289f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesInput::Type ELFReader<32, true>::fileType(const void* pELFHeader) const 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 291f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 292f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t type = 0x0; 29421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao type = hdr->e_type; 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 297d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao type = mcld::bswap16(hdr->e_type); 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(type) { 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_REL: 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Object; 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_EXEC: 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Exec; 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_DYN: 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::DynObj; 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_CORE: 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::CoreFile; 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_NONE: 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Unknown; 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSectionHeaders - read ELF section header table and create LDSections 315f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<32, true>::readSectionHeaders(Input& pInput, 316f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const void* pELFHeader) const 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 318f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* ehdr = 319f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t shoff = 0x0; 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t shentsize = 0x0; 3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shnum = 0x0; 3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shstrtab = 0x0; 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32621433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shoff = ehdr->e_shoff; 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shentsize = ehdr->e_shentsize; 32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shnum = ehdr->e_shnum; 33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab = ehdr->e_shstrndx; 33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 333d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shoff = mcld::bswap32(ehdr->e_shoff); 334d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shentsize = mcld::bswap16(ehdr->e_shentsize); 335d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shnum = mcld::bswap16(ehdr->e_shnum); 336d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shstrtab = mcld::bswap16(ehdr->e_shstrndx); 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the file has no section header table, e_shoff holds zero. 34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 == shoff) 34122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 343f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Shdr *shdr = NULL; 344f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef shdr_region; 34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_name = 0x0; 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_type = 0x0; 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_flags = 0x0; 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_offset = 0x0; 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_size = 0x0; 35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_link = 0x0; 35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_info = 0x0; 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_addralign = 0x0; 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize); 358f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines shdr = reinterpret_cast<const llvm::ELF::Elf32_Shdr*>(shdr_region.begin()); 3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 36021433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap32(shdr->sh_size); 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum * shentsize); 379f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Shdr* shdrTab = 380f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Shdr*>(shdr_region.begin()); 3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get .shstrtab first 3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 38421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdr->sh_offset; 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_size = shdr->sh_size; 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 389d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdr->sh_offset); 390d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_size = mcld::bswap32(shdr->sh_size); 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 393f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef sect_name_region = pInput.memArea()->request( 394f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + sh_offset, sh_size); 395f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* sect_name = sect_name_region.begin(); 39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList link_info_list; 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create all LDSections, including first NULL section. 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < shnum; ++idx) { 40121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_name = shdrTab[idx].sh_name; 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_type = shdrTab[idx].sh_type; 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_flags = shdrTab[idx].sh_flags; 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdrTab[idx].sh_offset; 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_size = shdrTab[idx].sh_size; 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_link = shdrTab[idx].sh_link; 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_info = shdrTab[idx].sh_info; 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign = shdrTab[idx].sh_addralign; 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 412d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_name = mcld::bswap32(shdrTab[idx].sh_name); 413d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_type = mcld::bswap32(shdrTab[idx].sh_type); 414d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_flags = mcld::bswap32(shdrTab[idx].sh_flags); 415d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdrTab[idx].sh_offset); 416d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_size = mcld::bswap32(shdrTab[idx].sh_size); 417d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_link = mcld::bswap32(shdrTab[idx].sh_link); 418d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_info = mcld::bswap32(shdrTab[idx].sh_info); 419d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign); 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = IRBuilder::CreateELFHeader(pInput, 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sect_name+sh_name, 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_type, 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_flags, 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign); 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setSize(sh_size); 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setOffset(sh_offset); 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setInfo(sh_info); 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sh_link != 0x0 || sh_info != 0x0) { 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfo link_info = { section, sh_link, sh_info }; 43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao link_info_list.push_back(link_info); 43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up InfoLink 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList::iterator info, infoEnd = link_info_list.end(); 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (info = link_info_list.begin(); info != infoEnd; ++info) { 440f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (LDFileFormat::Relocation == info->section->kind()) 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao info->section->setLink(pInput.context()->getSection(info->sh_info)); 442f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else 443f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_link)); 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSignature - read a symbol from the given Input and index in symtab 45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This is used to get the signature of a group section. 45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoResolveInfo* ELFReader<32, true>::readSignature(Input& pInput, 45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSymTab, 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t pSymIdx) const 454affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* symtab = &pSymTab; 45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* strtab = symtab->getLink(); 45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != symtab && NULL != strtab); 45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + symtab->offset() + 46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(llvm::ELF::Elf32_Sym) * pSymIdx; 461f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef symbol_region = 462f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym)); 463f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Sym* entry = 464f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Sym*>(symbol_region.begin()); 46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_name = 0x0; 46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_info = 0x0; 46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_other = 0x0; 46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_info = entry->st_info; 47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = entry->st_other; 47221433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_name = entry->st_name; 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = entry->st_shndx; 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 47622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 477d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_name = mcld::bswap32(entry->st_name); 478d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(entry->st_shndx); 47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 481f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef strtab_region = pInput.memArea()->request( 482f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + strtab->offset(), strtab->size()); 48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 485f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef ld_name(strtab_region.begin() + st_name); 486affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo* result = ResolveInfo::Create(ld_name); 48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setSource(pInput.type() == Input::DynObj); 48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setDesc(getSymDesc(st_shndx, pInput)); 49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setVisibility(getSymVisibility(st_other)); 493affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readDynamic - read ELF .dynamic in input dynobj 49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readDynamic(Input& pInput) const 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pInput.type() == Input::DynObj); 50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == dynamic_sect) { 50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynamic"; 50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynstr_sect = dynamic_sect->getLink(); 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == dynstr_sect) { 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynstr"; 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 510f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynamic_region = pInput.memArea()->request( 511f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 513f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynstr_region = pInput.memArea()->request( 514f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Dyn* dynamic = 517f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Dyn*>(dynamic_region.begin()); 518f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* dynstr = dynstr_region.begin(); 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool hasSOName = false; 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf32_Dyn); 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < numOfEntries; ++idx) { 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Sword d_tag = 0x0; 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Word d_val = 0x0; 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52721433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_tag = dynamic[idx].d_tag; 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_val = dynamic[idx].d_un.d_val; 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } else { 531d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_tag = mcld::bswap32(dynamic[idx].d_tag); 532d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_val = mcld::bswap32(dynamic[idx].d_un.d_val); 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (d_tag) { 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_SONAME: 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(d_val < dynstr_sect->size()); 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hasSOName = true; 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NEEDED: 54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: 54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NULL: 54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if there is no SONAME in .dynamic, then set it from input path 55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!hasSOName) 55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(pInput.path().filename().native()); 55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 554affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 555affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader<64, true> 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// constructor 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::ELFReader(GNULDBackend& pBackend) 5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : ELFReaderIF(pBackend) { 5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// destructor 5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::~ELFReader() 5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isELF - is this a ELF file 571f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<64, true>::isELF(const void* pELFHeader) const 5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 573f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 574f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4)) 5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRegularSection - read a regular section and create fragments. 5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool 5826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::readRegularSection(Input& pInput, SectionData& pSD) const 5836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t size = pSD.getSection().size(); 5866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSymbols - read ELF symbols and create LDSymbol 5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readSymbols(Input& pInput, 5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder& pBuilder, 595f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion, 5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* pStrTab) const 5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get number of symbols 599f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Sym); 6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Sym* symtab = 601f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Sym*>(pRegion.begin()); 6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t st_name = 0x0; 6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_value = 0x0; 6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_size = 0x0; 6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_info = 0x0; 6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_other = 0x0; 6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // skip the first NULL symbol 6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.context()->addSymbol(LDSymbol::Null()); 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 613f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// recording symbols added from DynObj to analyze weak alias 614f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo> potential_aliases; 615f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool is_dyn_obj = (pInput.type()==Input::DynObj); 6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 1; idx < entsize; ++idx) { 6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_info = symtab[idx].st_info; 6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = symtab[idx].st_other; 6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 62021433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = symtab[idx].st_name; 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = symtab[idx].st_value; 6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size = symtab[idx].st_size; 6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = symtab[idx].st_shndx; 6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = mcld::bswap32(symtab[idx].st_name); 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = mcld::bswap64(symtab[idx].st_value); 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size = mcld::bswap64(symtab[idx].st_size); 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(symtab[idx].st_shndx); 6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the section should not be included, set the st_shndx SHN_UNDEF 6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // - A section in interrelated groups are not included. 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pInput.type() == Input::Object && 6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx < llvm::ELF::SHN_LORESERVE && 6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx != llvm::ELF::SHN_UNDEF) { 6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == pInput.context()->getSection(st_shndx)) 6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = llvm::ELF::SHN_UNDEF; 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_type 6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_desc 6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_binding 6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_value - ld_value must be section relative. 6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_vis 6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get section 6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = NULL; 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section = pInput.context()->getSection(st_shndx); 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::string ld_name; 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Section == ld_type) { 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Section symbol's st_name is the section index. 6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != section && "get a invalid section"); 6676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = section->name(); 6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 6706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = std::string(pStrTab + st_name); 6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 673f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LDSymbol* psym = pBuilder.AddSymbol(pInput, 674f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_name, 675f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_type, 676f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_desc, 677f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_binding, 678f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines st_size, 679f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_value, 680f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines section, 681f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_vis); 682f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 683f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (is_dyn_obj 684f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && NULL != psym 685f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && ResolveInfo::Undefined != ld_desc 686f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && (ResolveInfo::Global == ld_binding || 687f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ResolveInfo::Weak == ld_binding) 688f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines && ResolveInfo::Object == ld_type ) { 689f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AliasInfo p; 690f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.pt_alias = psym; 691f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_binding = ld_binding; 692f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_value = ld_value; 693f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines potential_aliases.push_back(p); 694f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 695f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for loop 697f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 698f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // analyze weak alias here 699f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (is_dyn_obj) { 700f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort symbols by symbol value and then weak before strong 701f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::sort(potential_aliases.begin(), potential_aliases.end(), less); 702f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 703f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for each weak symbol, find out all its aliases, and 704f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // then link them as a circular list in Module 705f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator sym_it, sym_e; 706f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_e = potential_aliases.end(); 707f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (sym_it = potential_aliases.begin(); sym_it!=sym_e; ++sym_it) { 708f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::Weak!=sym_it->ld_binding) 709f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 710f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 711f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module& pModule = pBuilder.getModule(); 712f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator alias_it = sym_it+1; 713f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while(alias_it!=sym_e) { 714f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it->ld_value != alias_it->ld_value) 715f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 716f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 717f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it + 1 == alias_it) 718f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.CreateAliasList(*sym_it->pt_alias->resolveInfo()); 719f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.addAlias(*alias_it->pt_alias->resolveInfo()); 720f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++alias_it; 721f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 722f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 723f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines sym_it = alias_it - 1; 724f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }// end of for loop 725f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 7306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader::read relocations - read ELF rela and rel, and create Relocation 7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// ELFReader::readRela - read ELF rela and create Relocation 7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRela(Input& pInput, 7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 735f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion) const 7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rela 7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rela); 7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rela* relaTab = 740f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rela*>(pRegion.begin()); 7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx=0; idx < entsize; ++idx) { 743f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 744f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int64_t r_addend = 0; 747f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!target().readRelocation(relaTab[idx], 748f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines r_type, r_sym, r_offset, r_addend)) { 749f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == symbol) { 7546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 7556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 7586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 7596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRel - read ELF rel and create Relocation 7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRel(Input& pInput, 7646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 765f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion) const 7666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rel 7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rel); 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rel* relTab = 770f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rel*>(pRegion.begin()); 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx=0; idx < entsize; ++idx) { 773f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 774f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 776f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!target().readRelocation(relTab[idx], r_type, r_sym, r_offset)) 777f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == symbol) { 7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyEndian - is this ELF file in the same endian to me? 790f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<64, true>::isMyEndian(const void* pELFHeader) const 7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 792f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 793f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyMachine - is this ELF file generated for the same machine. 799f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<64, true>::isMyMachine(const void* pELFHeader) const 8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 801f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 802f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 80421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_machine == target().getInfo().machine()); 8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// fileType - return the file type 810f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesInput::Type ELFReader<64, true>::fileType(const void* pELFHeader) const 8116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 812f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 813f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t type = 0x0; 81521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = hdr->e_type; 8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = mcld::bswap16(hdr->e_type); 8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(type) { 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_REL: 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Object; 8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_EXEC: 8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Exec; 8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_DYN: 8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::DynObj; 8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_CORE: 8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::CoreFile; 8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_NONE: 8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Unknown; 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSectionHeaders - read ELF section header table and create LDSections 836f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<64, true>::readSectionHeaders(Input& pInput, 837f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const void* pELFHeader) const 8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 839f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* ehdr = 840f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t shoff = 0x0; 8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t shentsize = 0x0; 8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shnum = 0x0; 8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shstrtab = 0x0; 8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 84721433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff = ehdr->e_shoff; 8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = ehdr->e_shentsize; 8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = ehdr->e_shnum; 8516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = ehdr->e_shstrndx; 8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff = mcld::bswap64(ehdr->e_shoff); 8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = mcld::bswap16(ehdr->e_shentsize); 8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = mcld::bswap16(ehdr->e_shnum); 8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = mcld::bswap16(ehdr->e_shstrndx); 8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the file has no section header table, e_shoff holds zero. 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0x0 == shoff) 8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 864f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Shdr *shdr = NULL; 865f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef shdr_region; 8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_name = 0x0; 8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_type = 0x0; 8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_flags = 0x0; 8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_offset = 0x0; 8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_size = 0x0; 8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_link = 0x0; 8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_info = 0x0; 8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_addralign = 0x0; 8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize); 879f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines shdr = reinterpret_cast<const llvm::ELF::Elf64_Shdr*>(shdr_region.begin()); 8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 88121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 8926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 8936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 8946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 8966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 8996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum * shentsize); 900f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Shdr* shdrTab = 901f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Shdr*>(shdr_region.begin()); 9026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get .shstrtab first 9046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 90521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdr->sh_offset; 9076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 9086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdr->sh_offset); 9116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 9126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 914f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef sect_name_region = pInput.memArea()->request( 915f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + sh_offset, sh_size); 916f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* sect_name = sect_name_region.begin(); 9176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList link_info_list; 9196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create all LDSections, including first NULL section. 9216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < shnum; ++idx) { 92221433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_name = shdrTab[idx].sh_name; 9246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type = shdrTab[idx].sh_type; 9256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags = shdrTab[idx].sh_flags; 9266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdrTab[idx].sh_offset; 9276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdrTab[idx].sh_size; 9286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdrTab[idx].sh_link; 9296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_info = shdrTab[idx].sh_info; 9306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = shdrTab[idx].sh_addralign; 9316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_name = mcld::bswap32(shdrTab[idx].sh_name); 9346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type = mcld::bswap32(shdrTab[idx].sh_type); 9356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags = mcld::bswap64(shdrTab[idx].sh_flags); 9366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdrTab[idx].sh_offset); 9376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdrTab[idx].sh_size); 9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdrTab[idx].sh_link); 9396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_info = mcld::bswap32(shdrTab[idx].sh_info); 9406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = mcld::bswap64(shdrTab[idx].sh_addralign); 9416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = IRBuilder::CreateELFHeader(pInput, 9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sect_name+sh_name, 9456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type, 9466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags, 9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign); 9486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setSize(sh_size); 9496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setOffset(sh_offset); 9506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setInfo(sh_info); 9516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (sh_link != 0x0 || sh_info != 0x0) { 9536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfo link_info = { section, sh_link, sh_info }; 9546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines link_info_list.push_back(link_info); 9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 9576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set up InfoLink 9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList::iterator info, infoEnd = link_info_list.end(); 9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (info = link_info_list.begin(); info != infoEnd; ++info) { 961f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (LDFileFormat::Relocation == info->section->kind()) 9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_info)); 963f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else 964f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_link)); 9656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 9686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSignature - read a symbol from the given Input and index in symtab 9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// This is used to get the signature of a group section. 9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo* ELFReader<64, true>::readSignature(Input& pInput, 9736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSymTab, 9746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t pSymIdx) const 9756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 9766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* symtab = &pSymTab; 9776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* strtab = symtab->getLink(); 9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != symtab && NULL != strtab); 9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + symtab->offset() + 9816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf64_Sym) * pSymIdx; 982f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef symbol_region = 983f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf64_Sym)); 984f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Sym* entry = 985f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Sym*>(symbol_region.begin()); 9866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t st_name = 0x0; 9886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_info = 0x0; 9896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_other = 0x0; 9906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_info = entry->st_info; 9926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = entry->st_other; 99321433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = entry->st_name; 9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = entry->st_shndx; 9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = mcld::bswap32(entry->st_name); 9996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(entry->st_shndx); 10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1002f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef strtab_region = pInput.memArea()->request( 1003f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + strtab->offset(), strtab->size()); 10046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 1006f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef ld_name(strtab_region.begin() + st_name); 10076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo* result = ResolveInfo::Create(ld_name); 10096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setSource(pInput.type() == Input::DynObj); 10106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 10116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setDesc(getSymDesc(st_shndx, pInput)); 10126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 10136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setVisibility(getSymVisibility(st_other)); 10146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readDynamic - read ELF .dynamic in input dynobj 10196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readDynamic(Input& pInput) const 10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 10216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pInput.type() == Input::DynObj); 10226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 10236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == dynamic_sect) { 10246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynamic"; 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynstr_sect = dynamic_sect->getLink(); 10276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == dynstr_sect) { 10286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynstr"; 10296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1031f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynamic_region = pInput.memArea()->request( 1032f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 10336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1034f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynstr_region = pInput.memArea()->request( 1035f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 10366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Dyn* dynamic = 1038f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Dyn*>(dynamic_region.begin()); 1039f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* dynstr = dynstr_region.begin(); 10406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool hasSOName = false; 10416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf64_Dyn); 10426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < numOfEntries; ++idx) { 10446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Sxword d_tag = 0x0; 10466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Xword d_val = 0x0; 10476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 104821433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 10496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = dynamic[idx].d_tag; 10506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = dynamic[idx].d_un.d_val; 10516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 10526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = mcld::bswap64(dynamic[idx].d_tag); 10536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = mcld::bswap64(dynamic[idx].d_un.d_val); 10546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (d_tag) { 10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_SONAME: 10586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(d_val < dynstr_sect->size()); 10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hasSOName = true; 10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NEEDED: 10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NULL: 10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 10676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is no SONAME in .dynamic, then set it from input path 10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!hasSOName) 10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(pInput.path().filename().native()); 10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1077