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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFReader.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDContext.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Object/ObjectBuilder.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNUInfo.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 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 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <cstring> 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld { 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader<32, true> 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// constructor 3737b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFReader<32, true>::ELFReader(GNULDBackend& pBackend) : ELFReaderIF(pBackend) { 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// destructor 4137b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFReader<32, true>::~ELFReader() { 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isELF - is this a ELF file 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<32, true>::isELF(const void* pELFHeader) const { 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (memcmp(llvm::ELF::ElfMagic, hdr, 4) == 0) 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return false; 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRegularSection - read a regular section and create fragments. 5437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<32, true>::readRegularSection(Input& pInput, 5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines SectionData& pSD) const { 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t size = pSD.getSection().size(); 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ObjectBuilder::AppendFragment(*frag, pSD); 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSymbols - read ELF symbols and create LDSymbol 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readSymbols(Input& pInput, 66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder& pBuilder, 67f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion, 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const char* pStrTab) const { 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get number of symbols 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Sym); 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Sym* symtab = 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Sym*>(pRegion.begin()); 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t st_name = 0x0; 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_value = 0x0; 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t st_size = 0x0; 7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_info = 0x0; 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_other = 0x0; 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // skip the first NULL symbol 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.context()->addSymbol(LDSymbol::Null()); 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 84f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// recording symbols added from DynObj to analyze weak alias 85f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo> potential_aliases; 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool is_dyn_obj = (pInput.type() == Input::DynObj); 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 1; idx < entsize; ++idx) { 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_info = symtab[idx].st_info; 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = symtab[idx].st_other; 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = symtab[idx].st_name; 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_value = symtab[idx].st_value; 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_size = symtab[idx].st_size; 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = symtab[idx].st_shndx; 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = mcld::bswap32(symtab[idx].st_name); 98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_value = mcld::bswap32(symtab[idx].st_value); 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_size = mcld::bswap32(symtab[idx].st_size); 100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(symtab[idx].st_shndx); 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the section should not be included, set the st_shndx SHN_UNDEF 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // - A section in interrelated groups are not included. 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.type() == Input::Object && st_shndx < llvm::ELF::SHN_LORESERVE && 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx != llvm::ELF::SHN_UNDEF) { 10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.context()->getSection(st_shndx) == NULL) 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = llvm::ELF::SHN_UNDEF; 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_type 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_desc 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_binding 11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Binding ld_binding = 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hines getSymBinding((st_info >> 4), st_shndx, st_other); 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_value - ld_value must be section relative. 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_vis 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 127d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // get section 128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LDSection* section = NULL; 12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 130d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao section = pInput.context()->getSection(st_shndx); 131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 133d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::string ld_name; 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section == ld_type) { 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Section symbol's st_name is the section index. 13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(section != NULL && "get a invalid section"); 137d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = section->name(); 13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 139d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = std::string(pStrTab + st_name); 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 142f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LDSymbol* psym = pBuilder.AddSymbol(pInput, 143f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_name, 144f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_type, 145f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_desc, 146f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_binding, 147f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines st_size, 148f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_value, 149f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines section, 150f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_vis); 151f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (is_dyn_obj && psym != NULL && ResolveInfo::Undefined != ld_desc && 15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines (ResolveInfo::Global == ld_binding || 15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Weak == ld_binding) && 15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object == ld_type) { 156f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AliasInfo p; 157f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.pt_alias = psym; 158f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_binding = ld_binding; 159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_value = ld_value; 160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines potential_aliases.push_back(p); 161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for loop 163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 164f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // analyze weak alias 165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // FIXME: it is better to let IRBuilder handle alias anlysis. 166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 1. eliminate code duplication 167f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // 2. easy to know if a symbol is from .so 168f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // (so that it may be a potential alias) 169f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (is_dyn_obj) { 170f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort symbols by symbol value and then weak before strong 171f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::sort(potential_aliases.begin(), potential_aliases.end(), less); 172f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 173f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for each weak symbol, find out all its aliases, and 174f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // then link them as a circular list in Module 175f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator sym_it, sym_e; 176f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_e = potential_aliases.end(); 17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (sym_it = potential_aliases.begin(); sym_it != sym_e; ++sym_it) { 17837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (ResolveInfo::Weak != sym_it->ld_binding) 179f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 180f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 181f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module& pModule = pBuilder.getModule(); 18237b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::vector<AliasInfo>::iterator alias_it = sym_it + 1; 18337b74a387bb3993387029859c2d9d051c41c724eStephen Hines while (alias_it != sym_e) { 184f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it->ld_value != alias_it->ld_value) 185f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 186f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 187f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it + 1 == alias_it) 188f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.CreateAliasList(*sym_it->pt_alias->resolveInfo()); 189f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.addAlias(*alias_it->pt_alias->resolveInfo()); 190f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++alias_it; 191f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 192f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 193f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines sym_it = alias_it - 1; 19437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for loop 195f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 196f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader::read relocations - read ELF rela and rel, and create Relocation 20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ELFReader::readRela - read ELF rela and create Relocation 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRela(Input& pInput, 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 20637b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef pRegion) const { 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rela 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela); 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rela* relaTab = 210f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Rela*>(pRegion.begin()); 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (size_t idx = 0; idx < entsize; ++idx) { 213f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 214f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 21522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 21637b74a387bb3993387029859c2d9d051c41c724eStephen Hines int32_t r_addend = 0; 21737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!target() 21837b74a387bb3993387029859c2d9d051c41c724eStephen Hines .readRelocation(relaTab[idx], r_type, r_sym, r_offset, r_addend)) { 219f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 22037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 22337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (symbol == NULL) { 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 22622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 227d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRel - read ELF rel and create Relocation 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRel(Input& pInput, 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 23537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef pRegion) const { 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rel 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel); 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rel* relTab = 239f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Rel*>(pRegion.begin()); 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24137b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (size_t idx = 0; idx < entsize; ++idx) { 242f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 243f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 246f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!target().readRelocation(relTab[idx], r_type, r_sym, r_offset)) 247f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 24822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 25037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (symbol == NULL) { 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 254d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 25537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyEndian - is this ELF file in the same endian to me? 26037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<32, true>::isMyEndian(const void* pELFHeader) const { 261f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 262f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyMachine - is this ELF file generated for the same machine. 26837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<32, true>::isMyMachine(const void* pELFHeader) const { 269f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 270f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27221433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 273d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (hdr->e_machine == target().getInfo().machine()); 274d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// fileType - return the file type 27837b74a387bb3993387029859c2d9d051c41c724eStephen HinesInput::Type ELFReader<32, true>::fileType(const void* pELFHeader) const { 279f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* hdr = 280f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t type = 0x0; 28221433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao type = hdr->e_type; 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 285d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao type = mcld::bswap16(hdr->e_type); 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (type) { 28837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_REL: 28937b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::Object; 29037b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_EXEC: 29137b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::Exec; 29237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_DYN: 29337b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::DynObj; 29437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_CORE: 29537b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::CoreFile; 29637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_NONE: 29737b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 29837b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::Unknown; 29922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSectionHeaders - read ELF section header table and create LDSections 303f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<32, true>::readSectionHeaders(Input& pInput, 30437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const void* pELFHeader) const { 305f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Ehdr* ehdr = 306f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Ehdr*>(pELFHeader); 30722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t shoff = 0x0; 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t shentsize = 0x0; 31037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t shnum = 0x0; 31137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t shstrtab = 0x0; 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 31321433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 31437b74a387bb3993387029859c2d9d051c41c724eStephen Hines shoff = ehdr->e_shoff; 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shentsize = ehdr->e_shentsize; 31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines shnum = ehdr->e_shnum; 31737b74a387bb3993387029859c2d9d051c41c724eStephen Hines shstrtab = ehdr->e_shstrndx; 31837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 31937b74a387bb3993387029859c2d9d051c41c724eStephen Hines shoff = mcld::bswap32(ehdr->e_shoff); 320d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shentsize = mcld::bswap16(ehdr->e_shentsize); 32137b74a387bb3993387029859c2d9d051c41c724eStephen Hines shnum = mcld::bswap16(ehdr->e_shnum); 32237b74a387bb3993387029859c2d9d051c41c724eStephen Hines shstrtab = mcld::bswap16(ehdr->e_shstrndx); 32322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 32422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the file has no section header table, e_shoff holds zero. 32637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (shoff == 0x0) 32722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 32937b74a387bb3993387029859c2d9d051c41c724eStephen Hines const llvm::ELF::Elf32_Shdr* shdr = NULL; 330f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef shdr_region; 33137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_name = 0x0; 33237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_type = 0x0; 33337b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_flags = 0x0; 33437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_offset = 0x0; 33537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_size = 0x0; 33637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_link = 0x0; 33737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_info = 0x0; 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_addralign = 0x0; 33922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 34237b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr_region = 34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput.memArea()->request(pInput.fileOffset() + shoff, shentsize); 344f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines shdr = reinterpret_cast<const llvm::ELF::Elf32_Shdr*>(shdr_region.begin()); 3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 34621433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 34937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap32(shdr->sh_size); 3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 3556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 3576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 36237b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr_region = 36337b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput.memArea()->request(pInput.fileOffset() + shoff, shnum * shentsize); 364f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Shdr* shdrTab = 365f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Shdr*>(shdr_region.begin()); 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get .shstrtab first 3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 36921433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdr->sh_offset; 37137b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = shdr->sh_size; 37237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 373d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdr->sh_offset); 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = mcld::bswap32(shdr->sh_size); 37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 37737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef sect_name_region = 37837b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput.memArea()->request(pInput.fileOffset() + sh_offset, sh_size); 379f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* sect_name = sect_name_region.begin(); 38022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList link_info_list; 38222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create all LDSections, including first NULL section. 38422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < shnum; ++idx) { 38521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 38637b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_name = shdrTab[idx].sh_name; 38737b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_type = shdrTab[idx].sh_type; 38837b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_flags = shdrTab[idx].sh_flags; 38937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_offset = shdrTab[idx].sh_offset; 39037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = shdrTab[idx].sh_size; 39137b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_link = shdrTab[idx].sh_link; 39237b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_info = shdrTab[idx].sh_info; 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign = shdrTab[idx].sh_addralign; 39437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 39537b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_name = mcld::bswap32(shdrTab[idx].sh_name); 39637b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_type = mcld::bswap32(shdrTab[idx].sh_type); 39737b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_flags = mcld::bswap32(shdrTab[idx].sh_flags); 39837b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_offset = mcld::bswap32(shdrTab[idx].sh_offset); 39937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = mcld::bswap32(shdrTab[idx].sh_size); 40037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_link = mcld::bswap32(shdrTab[idx].sh_link); 40137b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_info = mcld::bswap32(shdrTab[idx].sh_info); 402d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign); 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40537b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection* section = IRBuilder::CreateELFHeader( 40637b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput, sect_name + sh_name, sh_type, sh_flags, sh_addralign); 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setSize(sh_size); 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setOffset(sh_offset); 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setInfo(sh_info); 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sh_link != 0x0 || sh_info != 0x0) { 41237b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkInfo link_info = {section, sh_link, sh_info}; 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao link_info_list.push_back(link_info); 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up InfoLink 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList::iterator info, infoEnd = link_info_list.end(); 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (info = link_info_list.begin(); info != infoEnd; ++info) { 420f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (LDFileFormat::Relocation == info->section->kind()) 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao info->section->setLink(pInput.context()->getSection(info->sh_info)); 422f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else 423f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_link)); 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 42822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSignature - read a symbol from the given Input and index in symtab 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This is used to get the signature of a group section. 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoResolveInfo* ELFReader<32, true>::readSignature(Input& pInput, 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSymTab, 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t pSymIdx) const { 43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* symtab = &pSymTab; 43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* strtab = symtab->getLink(); 43637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(symtab != NULL && strtab != NULL); 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + symtab->offset() + 43937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sizeof(llvm::ELF::Elf32_Sym) * pSymIdx; 440f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef symbol_region = 441f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym)); 442f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf32_Sym* entry = 443f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Sym*>(symbol_region.begin()); 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t st_name = 0x0; 44637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_info = 0x0; 44737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_other = 0x0; 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 44937b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_info = entry->st_info; 45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = entry->st_other; 45121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = entry->st_name; 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = entry->st_shndx; 45437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 45537b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = mcld::bswap32(entry->st_name); 456d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(entry->st_shndx); 45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 459f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef strtab_region = pInput.memArea()->request( 460f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + strtab->offset(), strtab->size()); 46122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 463f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef ld_name(strtab_region.begin() + st_name); 464affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo* result = ResolveInfo::Create(ld_name); 46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setSource(pInput.type() == Input::DynObj); 46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 46822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setDesc(getSymDesc(st_shndx, pInput)); 46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setVisibility(getSymVisibility(st_other)); 471affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readDynamic - read ELF .dynamic in input dynobj 47637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<32, true>::readDynamic(Input& pInput) const { 47722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pInput.type() == Input::DynObj); 47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 47937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (dynamic_sect == NULL) { 48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynamic"; 48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynstr_sect = dynamic_sect->getLink(); 48337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (dynstr_sect == NULL) { 48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynstr"; 48522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 487f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynamic_region = pInput.memArea()->request( 488f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 490f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynstr_region = pInput.memArea()->request( 491f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Dyn* dynamic = 494f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf32_Dyn*>(dynamic_region.begin()); 495f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* dynstr = dynstr_region.begin(); 49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool hasSOName = false; 49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf32_Dyn); 49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < numOfEntries; ++idx) { 50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Sword d_tag = 0x0; 50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Word d_val = 0x0; 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50321433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_tag = dynamic[idx].d_tag; 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_val = dynamic[idx].d_un.d_val; 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } else { 507d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_tag = mcld::bswap32(dynamic[idx].d_tag); 508d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_val = mcld::bswap32(dynamic[idx].d_un.d_val); 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (d_tag) { 51222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_SONAME: 51322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(d_val < dynstr_sect->size()); 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hasSOName = true; 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NEEDED: 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NULL: 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if there is no SONAME in .dynamic, then set it from input path 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!hasSOName) 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(pInput.path().filename().native()); 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 530affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 531affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader<64, true> 5356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// constructor 53737b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFReader<64, true>::ELFReader(GNULDBackend& pBackend) : ELFReaderIF(pBackend) { 5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// destructor 54137b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFReader<64, true>::~ELFReader() { 5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isELF - is this a ELF file 54537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<64, true>::isELF(const void* pELFHeader) const { 546f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 547f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 54837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (memcmp(llvm::ELF::ElfMagic, hdr, 4) == 0) 5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRegularSection - read a regular section and create fragments. 55437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<64, true>::readRegularSection(Input& pInput, 55537b74a387bb3993387029859c2d9d051c41c724eStephen Hines SectionData& pSD) const { 5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t size = pSD.getSection().size(); 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSymbols - read ELF symbols and create LDSymbol 5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readSymbols(Input& pInput, 5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder& pBuilder, 567f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef pRegion, 56837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const char* pStrTab) const { 5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get number of symbols 570f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Sym); 5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Sym* symtab = 572f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Sym*>(pRegion.begin()); 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 57437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t st_name = 0x0; 5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_value = 0x0; 57637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t st_size = 0x0; 57737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_info = 0x0; 57837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_other = 0x0; 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // skip the first NULL symbol 5826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.context()->addSymbol(LDSymbol::Null()); 5836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 584f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines /// recording symbols added from DynObj to analyze weak alias 585f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo> potential_aliases; 58637b74a387bb3993387029859c2d9d051c41c724eStephen Hines bool is_dyn_obj = (pInput.type() == Input::DynObj); 5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 1; idx < entsize; ++idx) { 58837b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_info = symtab[idx].st_info; 5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = symtab[idx].st_other; 5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 59121433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 59237b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = symtab[idx].st_name; 5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = symtab[idx].st_value; 59437b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_size = symtab[idx].st_size; 5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = symtab[idx].st_shndx; 59637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 59737b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = mcld::bswap32(symtab[idx].st_name); 5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = mcld::bswap64(symtab[idx].st_value); 59937b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_size = mcld::bswap64(symtab[idx].st_size); 6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(symtab[idx].st_shndx); 6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the section should not be included, set the st_shndx SHN_UNDEF 6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // - A section in interrelated groups are not included. 60537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.type() == Input::Object && st_shndx < llvm::ELF::SHN_LORESERVE && 6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx != llvm::ELF::SHN_UNDEF) { 60737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pInput.context()->getSection(st_shndx) == NULL) 6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = llvm::ELF::SHN_UNDEF; 6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_type 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_desc 6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_binding 61837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Binding ld_binding = 61937b74a387bb3993387029859c2d9d051c41c724eStephen Hines getSymBinding((st_info >> 4), st_shndx, st_other); 6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_value - ld_value must be section relative. 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_vis 6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get section 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = NULL; 62937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section = pInput.context()->getSection(st_shndx); 6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::string ld_name; 6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Section == ld_type) { 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Section symbol's st_name is the section index. 63637b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(section != NULL && "get a invalid section"); 6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = section->name(); 63837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = std::string(pStrTab + st_name); 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 642f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines LDSymbol* psym = pBuilder.AddSymbol(pInput, 643f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_name, 644f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_type, 645f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_desc, 646f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_binding, 647f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines st_size, 648f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_value, 649f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines section, 650f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ld_vis); 651f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 65237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (is_dyn_obj && psym != NULL && ResolveInfo::Undefined != ld_desc && 65337b74a387bb3993387029859c2d9d051c41c724eStephen Hines (ResolveInfo::Global == ld_binding || 65437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Weak == ld_binding) && 65537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ResolveInfo::Object == ld_type) { 656f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines AliasInfo p; 657f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.pt_alias = psym; 658f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_binding = ld_binding; 659f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines p.ld_value = ld_value; 660f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines potential_aliases.push_back(p); 661f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 66237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for loop 663f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 664f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // analyze weak alias here 665f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (is_dyn_obj) { 666f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // sort symbols by symbol value and then weak before strong 667f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::sort(potential_aliases.begin(), potential_aliases.end(), less); 668f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 669f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // for each weak symbol, find out all its aliases, and 670f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // then link them as a circular list in Module 671f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines std::vector<AliasInfo>::iterator sym_it, sym_e; 672f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sym_e = potential_aliases.end(); 67337b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (sym_it = potential_aliases.begin(); sym_it != sym_e; ++sym_it) { 67437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (ResolveInfo::Weak != sym_it->ld_binding) 675f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines continue; 676f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 677f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines Module& pModule = pBuilder.getModule(); 67837b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::vector<AliasInfo>::iterator alias_it = sym_it + 1; 67937b74a387bb3993387029859c2d9d051c41c724eStephen Hines while (alias_it != sym_e) { 680f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it->ld_value != alias_it->ld_value) 681f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines break; 682f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 683f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (sym_it + 1 == alias_it) 684f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.CreateAliasList(*sym_it->pt_alias->resolveInfo()); 685f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines pModule.addAlias(*alias_it->pt_alias->resolveInfo()); 686f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines ++alias_it; 687f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 688f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 689f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines sym_it = alias_it - 1; 69037b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for loop 691f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines } 6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader::read relocations - read ELF rela and rel, and create Relocation 6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// ELFReader::readRela - read ELF rela and create Relocation 6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRela(Input& pInput, 7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 70137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef pRegion) const { 7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rela 7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rela); 7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rela* relaTab = 705f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rela*>(pRegion.begin()); 7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 70737b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (size_t idx = 0; idx < entsize; ++idx) { 708f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 709f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 7106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 71137b74a387bb3993387029859c2d9d051c41c724eStephen Hines int64_t r_addend = 0; 71237b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (!target() 71337b74a387bb3993387029859c2d9d051c41c724eStephen Hines .readRelocation(relaTab[idx], r_type, r_sym, r_offset, r_addend)) { 714f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 71837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (symbol == NULL) { 7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 72337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRel - read ELF rel and create Relocation 7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRel(Input& pInput, 7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 73037b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef pRegion) const { 7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rel 7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rel); 7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rel* relTab = 734f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rel*>(pRegion.begin()); 7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 73637b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (size_t idx = 0; idx < entsize; ++idx) { 737f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Relocation::Type r_type = 0x0; 738f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines uint32_t r_sym = 0x0; 7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 740f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!target().readRelocation(relTab[idx], r_type, r_sym, r_offset)) 741f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return false; 7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 74437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (symbol == NULL) { 7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 74937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyEndian - is this ELF file in the same endian to me? 75437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<64, true>::isMyEndian(const void* pELFHeader) const { 755f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 756f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 7596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyMachine - is this ELF file generated for the same machine. 76237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<64, true>::isMyMachine(const void* pELFHeader) const { 763f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 764f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 76621433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 7676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_machine == target().getInfo().machine()); 7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// fileType - return the file type 77237b74a387bb3993387029859c2d9d051c41c724eStephen HinesInput::Type ELFReader<64, true>::fileType(const void* pELFHeader) const { 773f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* hdr = 774f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t type = 0x0; 77621433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) 7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = hdr->e_type; 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = mcld::bswap16(hdr->e_type); 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 78137b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (type) { 78237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_REL: 78337b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::Object; 78437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_EXEC: 78537b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::Exec; 78637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_DYN: 78737b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::DynObj; 78837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_CORE: 78937b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::CoreFile; 79037b74a387bb3993387029859c2d9d051c41c724eStephen Hines case llvm::ELF::ET_NONE: 79137b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 79237b74a387bb3993387029859c2d9d051c41c724eStephen Hines return Input::Unknown; 7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSectionHeaders - read ELF section header table and create LDSections 797f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesbool ELFReader<64, true>::readSectionHeaders(Input& pInput, 79837b74a387bb3993387029859c2d9d051c41c724eStephen Hines const void* pELFHeader) const { 799f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Ehdr* ehdr = 800f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Ehdr*>(pELFHeader); 8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 80237b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t shoff = 0x0; 8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t shentsize = 0x0; 80437b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t shnum = 0x0; 80537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t shstrtab = 0x0; 8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 80721433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 80837b74a387bb3993387029859c2d9d051c41c724eStephen Hines shoff = ehdr->e_shoff; 8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = ehdr->e_shentsize; 81037b74a387bb3993387029859c2d9d051c41c724eStephen Hines shnum = ehdr->e_shnum; 81137b74a387bb3993387029859c2d9d051c41c724eStephen Hines shstrtab = ehdr->e_shstrndx; 81237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 81337b74a387bb3993387029859c2d9d051c41c724eStephen Hines shoff = mcld::bswap64(ehdr->e_shoff); 8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = mcld::bswap16(ehdr->e_shentsize); 81537b74a387bb3993387029859c2d9d051c41c724eStephen Hines shnum = mcld::bswap16(ehdr->e_shnum); 81637b74a387bb3993387029859c2d9d051c41c724eStephen Hines shstrtab = mcld::bswap16(ehdr->e_shstrndx); 8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the file has no section header table, e_shoff holds zero. 82037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (shoff == 0x0) 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 82337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const llvm::ELF::Elf64_Shdr* shdr = NULL; 824f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef shdr_region; 82537b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_name = 0x0; 82637b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_type = 0x0; 82737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t sh_flags = 0x0; 82837b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t sh_offset = 0x0; 82937b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint64_t sh_size = 0x0; 83037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_link = 0x0; 83137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t sh_info = 0x0; 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_addralign = 0x0; 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 83637b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr_region = 83737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput.memArea()->request(pInput.fileOffset() + shoff, shentsize); 838f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines shdr = reinterpret_cast<const llvm::ELF::Elf64_Shdr*>(shdr_region.begin()); 8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 84021433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 84337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 8516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 85637b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr_region = 85737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput.memArea()->request(pInput.fileOffset() + shoff, shnum * shentsize); 858f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Shdr* shdrTab = 859f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Shdr*>(shdr_region.begin()); 8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get .shstrtab first 8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 86321433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdr->sh_offset; 86537b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = shdr->sh_size; 86637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdr->sh_offset); 86837b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = mcld::bswap64(shdr->sh_size); 8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 87137b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::StringRef sect_name_region = 87237b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput.memArea()->request(pInput.fileOffset() + sh_offset, sh_size); 873f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* sect_name = sect_name_region.begin(); 8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList link_info_list; 8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create all LDSections, including first NULL section. 8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < shnum; ++idx) { 87921433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 88037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_name = shdrTab[idx].sh_name; 88137b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_type = shdrTab[idx].sh_type; 88237b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_flags = shdrTab[idx].sh_flags; 88337b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_offset = shdrTab[idx].sh_offset; 88437b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = shdrTab[idx].sh_size; 88537b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_link = shdrTab[idx].sh_link; 88637b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_info = shdrTab[idx].sh_info; 8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = shdrTab[idx].sh_addralign; 88837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 88937b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_name = mcld::bswap32(shdrTab[idx].sh_name); 89037b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_type = mcld::bswap32(shdrTab[idx].sh_type); 89137b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_flags = mcld::bswap64(shdrTab[idx].sh_flags); 89237b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_offset = mcld::bswap64(shdrTab[idx].sh_offset); 89337b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_size = mcld::bswap64(shdrTab[idx].sh_size); 89437b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_link = mcld::bswap32(shdrTab[idx].sh_link); 89537b74a387bb3993387029859c2d9d051c41c724eStephen Hines sh_info = mcld::bswap32(shdrTab[idx].sh_info); 8966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = mcld::bswap64(shdrTab[idx].sh_addralign); 8976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 89937b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection* section = IRBuilder::CreateELFHeader( 90037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pInput, sect_name + sh_name, sh_type, sh_flags, sh_addralign); 9016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setSize(sh_size); 9026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setOffset(sh_offset); 9036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section->setInfo(sh_info); 9046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (sh_link != 0x0 || sh_info != 0x0) { 90637b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkInfo link_info = {section, sh_link, sh_info}; 9076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines link_info_list.push_back(link_info); 9086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 90937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // end of for 9106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // set up InfoLink 9126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList::iterator info, infoEnd = link_info_list.end(); 9136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (info = link_info_list.begin(); info != infoEnd; ++info) { 914f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (LDFileFormat::Relocation == info->section->kind()) 9156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_info)); 916f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else 917f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_link)); 9186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 9216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 9226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSignature - read a symbol from the given Input and index in symtab 9246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// This is used to get the signature of a group section. 9256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo* ELFReader<64, true>::readSignature(Input& pInput, 9266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSymTab, 92737b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t pSymIdx) const { 9286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* symtab = &pSymTab; 9296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* strtab = symtab->getLink(); 93037b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(symtab != NULL && strtab != NULL); 9316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + symtab->offset() + 93337b74a387bb3993387029859c2d9d051c41c724eStephen Hines sizeof(llvm::ELF::Elf64_Sym) * pSymIdx; 934f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef symbol_region = 935f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf64_Sym)); 936f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const llvm::ELF::Elf64_Sym* entry = 937f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Sym*>(symbol_region.begin()); 9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 93937b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint32_t st_name = 0x0; 94037b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_info = 0x0; 94137b74a387bb3993387029859c2d9d051c41c724eStephen Hines uint8_t st_other = 0x0; 9426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 94337b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_info = entry->st_info; 9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = entry->st_other; 94521433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 94637b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = entry->st_name; 9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = entry->st_shndx; 94837b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 94937b74a387bb3993387029859c2d9d051c41c724eStephen Hines st_name = mcld::bswap32(entry->st_name); 9506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(entry->st_shndx); 9516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 953f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef strtab_region = pInput.memArea()->request( 954f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + strtab->offset(), strtab->size()); 9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 957f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef ld_name(strtab_region.begin() + st_name); 9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo* result = ResolveInfo::Create(ld_name); 9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setSource(pInput.type() == Input::DynObj); 9616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setDesc(getSymDesc(st_shndx, pInput)); 9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 9646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setVisibility(getSymVisibility(st_other)); 9656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 9676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 9686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readDynamic - read ELF .dynamic in input dynobj 97037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFReader<64, true>::readDynamic(Input& pInput) const { 9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pInput.type() == Input::DynObj); 9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 97337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (dynamic_sect == NULL) { 9746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynamic"; 9756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynstr_sect = dynamic_sect->getLink(); 97737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (dynstr_sect == NULL) { 9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynstr"; 9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 981f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynamic_region = pInput.memArea()->request( 982f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 9836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 984f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::StringRef dynstr_region = pInput.memArea()->request( 985f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 9866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Dyn* dynamic = 988f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Dyn*>(dynamic_region.begin()); 989f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* dynstr = dynstr_region.begin(); 9906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool hasSOName = false; 9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf64_Dyn); 9926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < numOfEntries; ++idx) { 9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Sxword d_tag = 0x0; 9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Xword d_val = 0x0; 9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 99721433dddd6366055d6b305675f4afca0b4592dcdStephen Hines if (llvm::sys::IsLittleEndianHost) { 9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = dynamic[idx].d_tag; 9996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = dynamic[idx].d_un.d_val; 10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = mcld::bswap64(dynamic[idx].d_tag); 10026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = mcld::bswap64(dynamic[idx].d_un.d_val); 10036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (d_tag) { 10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_SONAME: 10076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(d_val < dynstr_sect->size()); 10086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 10096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hasSOName = true; 10106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NEEDED: 10126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 10136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NULL: 10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is no SONAME in .dynamic, then set it from input path 10216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!hasSOName) 10226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(pInput.path().filename().native()); 10236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 102637b74a387bb3993387029859c2d9d051c41c724eStephen Hines 102737b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 1028