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> 16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MemoryRegion.h> 17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/MsgHandling.h> 1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Object/ObjectBuilder.h> 1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cstring> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/ADT/StringRef.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/ADT/Twine.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/ELF.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/Host.h> 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <iostream> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace mcld; 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader<32, true> 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// constructor 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::ELFReader(GNULDBackend& pBackend) 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : ELFReaderIF(pBackend) { 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// destructor 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::~ELFReader() 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isELF - is this a ELF file 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::isELF(void* pELFHeader) const 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4)) 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRegularSection - read a regular section and create fragments. 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::readRegularSection(Input& pInput, SectionData& pSD) const 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t size = pSD.getSection().size(); 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder::AppendFragment(*frag, pSD); 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSymbols - read ELF symbols and create LDSymbol 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readSymbols(Input& pInput, 68d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder& pBuilder, 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const MemoryRegion& pRegion, 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* pStrTab) const 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get number of symbols 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym); 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Sym* symtab = 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const llvm::ELF::Elf32_Sym*>(pRegion.start()); 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_name = 0x0; 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_value = 0x0; 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_size = 0x0; 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_info = 0x0; 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_other = 0x0; 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // skip the first NULL symbol 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.context()->addSymbol(LDSymbol::Null()); 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 87f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// recording symbols added from DynObj to analyze weak alias 88f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo> potential_aliases; 89f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool is_dyn_obj = (pInput.type()==Input::DynObj); 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 1; idx < entsize; ++idx) { 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_info = symtab[idx].st_info; 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = symtab[idx].st_other; 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_name = symtab[idx].st_name; 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_value = symtab[idx].st_value; 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_size = symtab[idx].st_size; 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = symtab[idx].st_shndx; 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_name = mcld::bswap32(symtab[idx].st_name); 102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_value = mcld::bswap32(symtab[idx].st_value); 103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_size = mcld::bswap32(symtab[idx].st_size); 104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(symtab[idx].st_shndx); 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the section should not be included, set the st_shndx SHN_UNDEF 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // - A section in interrelated groups are not included. 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pInput.type() == Input::Object && 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx < llvm::ELF::SHN_LORESERVE && 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx != llvm::ELF::SHN_UNDEF) { 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == pInput.context()->getSection(st_shndx)) 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = llvm::ELF::SHN_UNDEF; 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_type 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_desc 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_binding 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_value - ld_value must be section relative. 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_vis 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // get section 132d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LDSection* section = NULL; 133d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao section = pInput.context()->getSection(st_shndx); 135d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 137d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::string ld_name; 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section == ld_type) { 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Section symbol's st_name is the section index. 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != section && "get a invalid section"); 141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = section->name(); 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = std::string(pStrTab + st_name); 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol *psym = 148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol(pInput, 149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_name, 150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_type, 151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_desc, 152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_binding, 153f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines st_size, 154f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_value, 155f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines section, ld_vis); 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ( is_dyn_obj 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && NULL!=psym 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && ResolveInfo::Undefined!=ld_desc 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && (ResolveInfo::Global==ld_binding || 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Weak==ld_binding) 162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && ResolveInfo::Object==ld_type ) { 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AliasInfo p; 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.pt_alias = psym; 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_binding = ld_binding; 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_value = ld_value; 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines potential_aliases.push_back(p); 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 169f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for loop 171f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // analyze weak alias 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: it is better to let IRBuilder handle alias anlysis. 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 1. eliminate code duplication 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 2. easy to know if a symbol is from .so 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // (so that it may be a potential alias) 177f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ( is_dyn_obj ) { 178f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort symbols by symbol value and then weak before strong 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::sort( potential_aliases.begin(), potential_aliases.end(), less); 180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for each weak symbol, find out all its aliases, and 182f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // then link them as a circular list in Module 183f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator sym_it, sym_e; 184f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_e = potential_aliases.end(); 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (sym_it = potential_aliases.begin(); sym_it!=sym_e; ++sym_it) { 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::Weak!=sym_it->ld_binding) 187f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module& pModule = pBuilder.getModule(); 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator alias_it = sym_it+1; 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while(alias_it!=sym_e) { 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ( sym_it->ld_value != alias_it->ld_value ) 193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 194f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (sym_it+1==alias_it) 196f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.CreateAliasList(*sym_it->pt_alias->resolveInfo()); 197f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.addAlias(*alias_it->pt_alias->resolveInfo()); 198f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++alias_it; 199f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 200f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 201f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_it = alias_it-1; 202f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }// end of for loop 203f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 204f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader::read relocations - read ELF rela and rel, and create Relocation 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ELFReader::readRela - read ELF rela and create Relocation 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRela(Input& pInput, 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 21422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const MemoryRegion& pRegion) const 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rela 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela); 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rela* relaTab = 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const llvm::ELF::Elf32_Rela*>(pRegion.start()); 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx=0; idx < entsize; ++idx) { 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_info = 0x0; 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int32_t r_addend = 0; 22521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_offset = relaTab[idx].r_offset; 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_info = relaTab[idx].r_info; 22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_addend = relaTab[idx].r_addend; 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 231d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_offset = mcld::bswap32(relaTab[idx].r_offset); 232d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_info = mcld::bswap32(relaTab[idx].r_info); 233d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_addend = mcld::bswap32(relaTab[idx].r_addend); 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t r_type = static_cast<unsigned char>(r_info); 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_sym = (r_info >> 8); 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == symbol) { 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 243d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 24722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRel - read ELF rel and create Relocation 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRel(Input& pInput, 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const MemoryRegion& pRegion) const 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rel 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel); 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rel* relTab = 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const llvm::ELF::Elf32_Rel*>(pRegion.start()); 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx=0; idx < entsize; ++idx) { 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_info = 0x0; 26121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_offset = relTab[idx].r_offset; 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_info = relTab[idx].r_info; 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 266d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_offset = mcld::bswap32(relTab[idx].r_offset); 267d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_info = mcld::bswap32(relTab[idx].r_info); 26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t r_type = static_cast<unsigned char>(r_info); 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_sym = (r_info >> 8); 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == symbol) { 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 278d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyEndian - is this ELF file in the same endian to me? 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::isMyEndian(void* pELFHeader) const 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyMachine - is this ELF file generated for the same machine. 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::isMyMachine(void* pELFHeader) const 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 29821433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 299d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (hdr->e_machine == target().getInfo().machine()); 300d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// fileType - return the file type 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput::Type ELFReader<32, true>::fileType(void* pELFHeader) const 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 30622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t type = 0x0; 30921433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao type = hdr->e_type; 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 312d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao type = mcld::bswap16(hdr->e_type); 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(type) { 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_REL: 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Object; 31722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_EXEC: 31822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Exec; 31922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_DYN: 32022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::DynObj; 32122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_CORE: 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::CoreFile; 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_NONE: 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Unknown; 32622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSectionHeaders - read ELF section header table and create LDSections 33022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool 33122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const 33222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* ehdr = 33422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 33522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 33622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t shoff = 0x0; 33722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t shentsize = 0x0; 3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shnum = 0x0; 3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shstrtab = 0x0; 34022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 34121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 34222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shoff = ehdr->e_shoff; 34322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shentsize = ehdr->e_shentsize; 34422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shnum = ehdr->e_shnum; 34522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab = ehdr->e_shstrndx; 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 34722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 348d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shoff = mcld::bswap32(ehdr->e_shoff); 349d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shentsize = mcld::bswap16(ehdr->e_shentsize); 350d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shnum = mcld::bswap16(ehdr->e_shnum); 351d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shstrtab = mcld::bswap16(ehdr->e_shstrndx); 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 35422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the file has no section header table, e_shoff holds zero. 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 == shoff) 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf32_Shdr *shdr = NULL; 3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* shdr_region = NULL; 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_name = 0x0; 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_type = 0x0; 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_flags = 0x0; 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_offset = 0x0; 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_size = 0x0; 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_link = 0x0; 36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_info = 0x0; 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_addralign = 0x0; 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize); 3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start()); 3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 37521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap32(shdr->sh_size); 3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(shdr_region); 3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum * shentsize); 3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf32_Shdr * shdrTab = 3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start()); 3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get .shstrtab first 3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 40021433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdr->sh_offset; 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_size = shdr->sh_size; 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 405d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdr->sh_offset); 406d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_size = mcld::bswap32(shdr->sh_size); 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* sect_name_region = pInput.memArea()->request( 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + sh_offset, sh_size); 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* sect_name = 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const char*>(sect_name_region->start()); 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList link_info_list; 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create all LDSections, including first NULL section. 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < shnum; ++idx) { 41821433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_name = shdrTab[idx].sh_name; 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_type = shdrTab[idx].sh_type; 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_flags = shdrTab[idx].sh_flags; 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdrTab[idx].sh_offset; 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_size = shdrTab[idx].sh_size; 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_link = shdrTab[idx].sh_link; 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_info = shdrTab[idx].sh_info; 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign = shdrTab[idx].sh_addralign; 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 429d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_name = mcld::bswap32(shdrTab[idx].sh_name); 430d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_type = mcld::bswap32(shdrTab[idx].sh_type); 431d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_flags = mcld::bswap32(shdrTab[idx].sh_flags); 432d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdrTab[idx].sh_offset); 433d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_size = mcld::bswap32(shdrTab[idx].sh_size); 434d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_link = mcld::bswap32(shdrTab[idx].sh_link); 435d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_info = mcld::bswap32(shdrTab[idx].sh_info); 436d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign); 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = IRBuilder::CreateELFHeader(pInput, 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sect_name+sh_name, 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_type, 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_flags, 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign); 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setSize(sh_size); 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setOffset(sh_offset); 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setInfo(sh_info); 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sh_link != 0x0 || sh_info != 0x0) { 44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfo link_info = { section, sh_link, sh_info }; 45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao link_info_list.push_back(link_info); 45122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 45222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up InfoLink 45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList::iterator info, infoEnd = link_info_list.end(); 45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (info = link_info_list.begin(); info != infoEnd; ++info) { 45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::NamePool == info->section->kind() || 45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Group == info->section->kind() || 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Note == info->section->kind()) { 46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao info->section->setLink(pInput.context()->getSection(info->sh_link)); 46122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Relocation == info->section->kind()) { 46422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao info->section->setLink(pInput.context()->getSection(info->sh_info)); 46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(shdr_region); 47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(sect_name_region); 47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSignature - read a symbol from the given Input and index in symtab 47622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This is used to get the signature of a group section. 47722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoResolveInfo* ELFReader<32, true>::readSignature(Input& pInput, 47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSymTab, 47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t pSymIdx) const 480affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* symtab = &pSymTab; 48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* strtab = symtab->getLink(); 48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != symtab && NULL != strtab); 48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 48522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + symtab->offset() + 48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(llvm::ELF::Elf32_Sym) * pSymIdx; 48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symbol_region = 48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym)); 48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Sym* entry = 49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start()); 49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_name = 0x0; 49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_info = 0x0; 49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_other = 0x0; 49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_info = entry->st_info; 49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = entry->st_other; 49821433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_name = entry->st_name; 50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = entry->st_shndx; 50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 503d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_name = mcld::bswap32(entry->st_name); 504d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(entry->st_shndx); 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pInput.memArea()->request( 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + strtab->offset(), strtab->size()); 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::StringRef ld_name( 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<char*>(strtab_region->start() + st_name)); 513affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo* result = ResolveInfo::Create(ld_name); 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setSource(pInput.type() == Input::DynObj); 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setDesc(getSymDesc(st_shndx, pInput)); 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setVisibility(getSymVisibility(st_other)); 520affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // release regions 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(symbol_region); 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(strtab_region); 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readDynamic - read ELF .dynamic in input dynobj 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readDynamic(Input& pInput) const 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pInput.type() == Input::DynObj); 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == dynamic_sect) { 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynamic"; 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynstr_sect = dynamic_sect->getLink(); 53722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == dynstr_sect) { 53822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynstr"; 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 54022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 54122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dynamic_region = pInput.memArea()->request( 54222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 54322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 54422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dynstr_region = pInput.memArea()->request( 54522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 54622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 54722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != dynamic_region && NULL != dynstr_region); 54822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 54922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Dyn* dynamic = 55022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (llvm::ELF::Elf32_Dyn*) dynamic_region->start(); 55122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* dynstr = (const char*) dynstr_region->start(); 55222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool hasSOName = false; 55322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf32_Dyn); 55422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 55522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < numOfEntries; ++idx) { 55622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 55722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Sword d_tag = 0x0; 55822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Word d_val = 0x0; 55922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 56021433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 56122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_tag = dynamic[idx].d_tag; 56222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_val = dynamic[idx].d_un.d_val; 56322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } else { 564d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_tag = mcld::bswap32(dynamic[idx].d_tag); 565d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_val = mcld::bswap32(dynamic[idx].d_un.d_val); 56622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 56722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 56822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (d_tag) { 56922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_SONAME: 57022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(d_val < dynstr_sect->size()); 57122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 57222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hasSOName = true; 57322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 57422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NEEDED: 57522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: 57622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 57722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NULL: 57822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 57922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 58022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 58122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 58222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if there is no SONAME in .dynamic, then set it from input path 58422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!hasSOName) 58522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(pInput.path().filename().native()); 58622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 58722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(dynamic_region); 58822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(dynstr_region); 589affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 590affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 59122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader<64, true> 5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// constructor 5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::ELFReader(GNULDBackend& pBackend) 5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : ELFReaderIF(pBackend) { 5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// destructor 6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::~ELFReader() 6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isELF - is this a ELF file 6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::isELF(void* pELFHeader) const 6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4)) 6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRegularSection - read a regular section and create fragments. 6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool 6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::readRegularSection(Input& pInput, SectionData& pSD) const 6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t size = pSD.getSection().size(); 6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSymbols - read ELF symbols and create LDSymbol 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readSymbols(Input& pInput, 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder& pBuilder, 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const MemoryRegion& pRegion, 6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* pStrTab) const 6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get number of symbols 6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf64_Sym); 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Sym* symtab = 6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Sym*>(pRegion.start()); 6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t st_name = 0x0; 6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_value = 0x0; 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_size = 0x0; 6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_info = 0x0; 6426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_other = 0x0; 6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // skip the first NULL symbol 6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.context()->addSymbol(LDSymbol::Null()); 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 648f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// recording symbols added from DynObj to analyze weak alias 649f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo> potential_aliases; 650f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines bool is_dyn_obj = (pInput.type()==Input::DynObj); 6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 1; idx < entsize; ++idx) { 6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_info = symtab[idx].st_info; 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = symtab[idx].st_other; 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 65521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = symtab[idx].st_name; 6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = symtab[idx].st_value; 6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size = symtab[idx].st_size; 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = symtab[idx].st_shndx; 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = mcld::bswap32(symtab[idx].st_name); 6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = mcld::bswap64(symtab[idx].st_value); 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size = mcld::bswap64(symtab[idx].st_size); 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(symtab[idx].st_shndx); 6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the section should not be included, set the st_shndx SHN_UNDEF 6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // - A section in interrelated groups are not included. 6706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pInput.type() == Input::Object && 6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx < llvm::ELF::SHN_LORESERVE && 6726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx != llvm::ELF::SHN_UNDEF) { 6736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == pInput.context()->getSection(st_shndx)) 6746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = llvm::ELF::SHN_UNDEF; 6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_type 6786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 6796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_desc 6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_binding 6846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 6856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_value - ld_value must be section relative. 6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_vis 6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get section 6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = NULL; 6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section = pInput.context()->getSection(st_shndx); 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::string ld_name; 6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Section == ld_type) { 7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Section symbol's st_name is the section index. 7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != section && "get a invalid section"); 7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = section->name(); 7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = std::string(pStrTab + st_name); 7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 708f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines LDSymbol *psym = 709f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pBuilder.AddSymbol(pInput, 710f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_name, 711f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_type, 712f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_desc, 713f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_binding, 714f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines st_size, 715f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ld_value, 716f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines section, ld_vis); 717f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 718f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ( is_dyn_obj 719f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && NULL!=psym 720f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && ResolveInfo::Undefined!=ld_desc 721f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && (ResolveInfo::Global==ld_binding || 722f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ResolveInfo::Weak==ld_binding) 723f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines && ResolveInfo::Object==ld_type ) { 724f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AliasInfo p; 725f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.pt_alias = psym; 726f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_binding = ld_binding; 727f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_value = ld_value; 728f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines potential_aliases.push_back(p); 729f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 730f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for loop 732f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 733f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // analyze weak alias here 734f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ( is_dyn_obj ) { 735f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort symbols by symbol value and then weak before strong 736f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::sort( potential_aliases.begin(), potential_aliases.end(), less); 737f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 738f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for each weak symbol, find out all its aliases, and 739f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // then link them as a circular list in Module 740f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator sym_it, sym_e; 741f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_e = potential_aliases.end(); 742f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines for (sym_it = potential_aliases.begin(); sym_it!=sym_e; ++sym_it) { 743f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (ResolveInfo::Weak!=sym_it->ld_binding) 744f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 745f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 746f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module& pModule = pBuilder.getModule(); 747f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator alias_it = sym_it+1; 748f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines while(alias_it!=sym_e) { 749f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if ( sym_it->ld_value != alias_it->ld_value ) 750f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 751f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 752f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines if (sym_it+1==alias_it) 753f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.CreateAliasList(*sym_it->pt_alias->resolveInfo()); 754f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.addAlias(*alias_it->pt_alias->resolveInfo()); 755f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++alias_it; 756f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 757f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 758f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_it = alias_it-1; 759f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines }// end of for loop 760f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 7616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 7656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader::read relocations - read ELF rela and rel, and create Relocation 7666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 7676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// ELFReader::readRela - read ELF rela and create Relocation 7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRela(Input& pInput, 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const MemoryRegion& pRegion) const 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rela 7736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rela); 7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rela* relaTab = 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rela*>(pRegion.start()); 7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx=0; idx < entsize; ++idx) { 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_info = 0x0; 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int64_t r_addend = 0; 78121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = relaTab[idx].r_offset; 7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = relaTab[idx].r_info; 7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_addend = relaTab[idx].r_addend; 7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = mcld::bswap64(relaTab[idx].r_offset); 7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = mcld::bswap64(relaTab[idx].r_info); 7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_addend = mcld::bswap64(relaTab[idx].r_addend); 7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_type = static_cast<uint32_t>(r_info); 7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_sym = (r_info >> 32); 7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == symbol) { 7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 8026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRel - read ELF rel and create Relocation 8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRel(Input& pInput, 8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const MemoryRegion& pRegion) const 8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rel 8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rel); 8116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rel* relTab = 8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rel*>(pRegion.start()); 8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx=0; idx < entsize; ++idx) { 8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_info = 0x0; 81721433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = relTab[idx].r_offset; 8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = relTab[idx].r_info; 8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = mcld::bswap64(relTab[idx].r_offset); 8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = mcld::bswap64(relTab[idx].r_info); 8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_type = static_cast<uint32_t>(r_info); 8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_sym = (r_info >> 32); 8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == symbol) { 8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyEndian - is this ELF file in the same endian to me? 8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::isMyEndian(void* pELFHeader) const 8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyMachine - is this ELF file generated for the same machine. 8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::isMyMachine(void* pELFHeader) const 8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 8516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 85421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_machine == target().getInfo().machine()); 8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// fileType - return the file type 8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesInput::Type ELFReader<64, true>::fileType(void* pELFHeader) const 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t type = 0x0; 86521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = hdr->e_type; 8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = mcld::bswap16(hdr->e_type); 8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(type) { 8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_REL: 8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Object; 8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_EXEC: 8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Exec; 8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_DYN: 8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::DynObj; 8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_CORE: 8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::CoreFile; 8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_NONE: 8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Unknown; 8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSectionHeaders - read ELF section header table and create LDSections 8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool 8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const 8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* ehdr = 8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t shoff = 0x0; 8936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t shentsize = 0x0; 8946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shnum = 0x0; 8956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shstrtab = 0x0; 8966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 89721433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 8986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff = ehdr->e_shoff; 8996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = ehdr->e_shentsize; 9006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = ehdr->e_shnum; 9016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = ehdr->e_shstrndx; 9026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff = mcld::bswap64(ehdr->e_shoff); 9056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = mcld::bswap16(ehdr->e_shentsize); 9066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = mcld::bswap16(ehdr->e_shnum); 9076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = mcld::bswap16(ehdr->e_shstrndx); 9086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the file has no section header table, e_shoff holds zero. 9116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0x0 == shoff) 9126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 9136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Shdr *shdr = NULL; 9156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* shdr_region = NULL; 9166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_name = 0x0; 9176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_type = 0x0; 9186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_flags = 0x0; 9196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_offset = 0x0; 9206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_size = 0x0; 9216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_link = 0x0; 9226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_info = 0x0; 9236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_addralign = 0x0; 9246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 9266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 9276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 9286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize); 9296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr*>(shdr_region->start()); 9306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 93121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 9336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 9346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 9376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(shdr_region); 9406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 9426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 9436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 9456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 9506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum * shentsize); 9516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Shdr * shdrTab = 9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Shdr*>(shdr_region->start()); 9536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get .shstrtab first 9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 95621433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdr->sh_offset; 9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdr->sh_offset); 9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* sect_name_region = pInput.memArea()->request( 9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + sh_offset, sh_size); 9676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* sect_name = 9686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const char*>(sect_name_region->start()); 9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList link_info_list; 9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create all LDSections, including first NULL section. 9736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < shnum; ++idx) { 97421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_name = shdrTab[idx].sh_name; 9766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type = shdrTab[idx].sh_type; 9776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags = shdrTab[idx].sh_flags; 9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdrTab[idx].sh_offset; 9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdrTab[idx].sh_size; 9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdrTab[idx].sh_link; 9816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_info = shdrTab[idx].sh_info; 9826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = shdrTab[idx].sh_addralign; 9836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_name = mcld::bswap32(shdrTab[idx].sh_name); 9866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type = mcld::bswap32(shdrTab[idx].sh_type); 9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags = mcld::bswap64(shdrTab[idx].sh_flags); 9886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdrTab[idx].sh_offset); 9896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdrTab[idx].sh_size); 9906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdrTab[idx].sh_link); 9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_info = mcld::bswap32(shdrTab[idx].sh_info); 9926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = mcld::bswap64(shdrTab[idx].sh_addralign); 9936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = IRBuilder::CreateELFHeader(pInput, 9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sect_name+sh_name, 9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type, 9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags, 9996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign); 10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setSize(sh_size); 10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setOffset(sh_offset); 10026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setInfo(sh_info); 10036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (sh_link != 0x0 || sh_info != 0x0) { 10056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfo link_info = { section, sh_link, sh_info }; 10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines link_info_list.push_back(link_info); 10076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 10096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set up InfoLink 10116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList::iterator info, infoEnd = link_info_list.end(); 10126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (info = link_info_list.begin(); info != infoEnd; ++info) { 10136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LDFileFormat::NamePool == info->section->kind() || 10146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDFileFormat::Group == info->section->kind() || 10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDFileFormat::Note == info->section->kind()) { 10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_link)); 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 10186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LDFileFormat::Relocation == info->section->kind()) { 10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_info)); 10216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 10226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(shdr_region); 10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(sect_name_region); 10276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 10296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSignature - read a symbol from the given Input and index in symtab 10326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// This is used to get the signature of a group section. 10336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo* ELFReader<64, true>::readSignature(Input& pInput, 10346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSymTab, 10356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t pSymIdx) const 10366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 10376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* symtab = &pSymTab; 10386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* strtab = symtab->getLink(); 10396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != symtab && NULL != strtab); 10406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + symtab->offset() + 10426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf64_Sym) * pSymIdx; 10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* symbol_region = 10446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf64_Sym)); 10456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Sym* entry = 10466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Sym*>(symbol_region->start()); 10476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t st_name = 0x0; 10496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_info = 0x0; 10506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_other = 0x0; 10516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 10526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_info = entry->st_info; 10536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = entry->st_other; 105421433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 10556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = entry->st_name; 10566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = entry->st_shndx; 10576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 10596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = mcld::bswap32(entry->st_name); 10606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(entry->st_shndx); 10616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* strtab_region = pInput.memArea()->request( 10646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + strtab->offset(), strtab->size()); 10656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 10676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::StringRef ld_name( 10686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<char*>(strtab_region->start() + st_name)); 10696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo* result = ResolveInfo::Create(ld_name); 10716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setSource(pInput.type() == Input::DynObj); 10726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 10736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setDesc(getSymDesc(st_shndx, pInput)); 10746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 10756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setVisibility(getSymVisibility(st_other)); 10766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // release regions 10786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(symbol_region); 10796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(strtab_region); 10806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 10826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readDynamic - read ELF .dynamic in input dynobj 10856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readDynamic(Input& pInput) const 10866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 10876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pInput.type() == Input::DynObj); 10886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 10896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == dynamic_sect) { 10906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynamic"; 10916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynstr_sect = dynamic_sect->getLink(); 10936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == dynstr_sect) { 10946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynstr"; 10956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* dynamic_region = pInput.memArea()->request( 10986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 10996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* dynstr_region = pInput.memArea()->request( 11016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 11026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != dynamic_region && NULL != dynstr_region); 11046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Dyn* dynamic = 11066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (llvm::ELF::Elf64_Dyn*) dynamic_region->start(); 11076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* dynstr = (const char*) dynstr_region->start(); 11086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool hasSOName = false; 11096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf64_Dyn); 11106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < numOfEntries; ++idx) { 11126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Sxword d_tag = 0x0; 11146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Xword d_val = 0x0; 11156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 111621433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 11176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = dynamic[idx].d_tag; 11186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = dynamic[idx].d_un.d_val; 11196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 11206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = mcld::bswap64(dynamic[idx].d_tag); 11216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = mcld::bswap64(dynamic[idx].d_un.d_val); 11226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (d_tag) { 11256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_SONAME: 11266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(d_val < dynstr_sect->size()); 11276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 11286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hasSOName = true; 11296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 11306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NEEDED: 11316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 11326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 11336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NULL: 11346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 11356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 11366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 11386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is no SONAME in .dynamic, then set it from input path 11406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!hasSOName) 11416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(pInput.path().filename().native()); 11426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(dynamic_region); 11446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(dynstr_region); 11456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 11466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 11476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1148