ELFReader.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 1; idx < entsize; ++idx) { 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_info = symtab[idx].st_info; 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = symtab[idx].st_other; 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_name = symtab[idx].st_name; 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_value = symtab[idx].st_value; 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_size = symtab[idx].st_size; 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = symtab[idx].st_shndx; 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_name = mcld::bswap32(symtab[idx].st_name); 99d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_value = mcld::bswap32(symtab[idx].st_value); 100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_size = mcld::bswap32(symtab[idx].st_size); 101d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(symtab[idx].st_shndx); 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the section should not be included, set the st_shndx SHN_UNDEF 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // - A section in interrelated groups are not included. 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (pInput.type() == Input::Object && 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx < llvm::ELF::SHN_LORESERVE && 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx != llvm::ELF::SHN_UNDEF) { 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == pInput.context()->getSection(st_shndx)) 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = llvm::ELF::SHN_UNDEF; 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_type 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_desc 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_binding 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_value - ld_value must be section relative. 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_vis 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 128d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao // get section 129d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LDSection* section = NULL; 130d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 131d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao section = pInput.context()->getSection(st_shndx); 132d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 134d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao std::string ld_name; 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (ResolveInfo::Section == ld_type) { 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Section symbol's st_name is the section index. 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != section && "get a invalid section"); 138d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = section->name(); 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 141d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name = std::string(pStrTab + st_name); 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 144d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao pBuilder.AddSymbol(pInput, 145d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_name, 146d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_type, 147d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_desc, 148d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_binding, 149d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_size, 150d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ld_value, 151d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao section, ld_vis); 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for loop 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 15522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// ELFReader::read relocations - read ELF rela and rel, and create Relocation 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// ELFReader::readRela - read ELF rela and create Relocation 16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRela(Input& pInput, 16122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 16222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const MemoryRegion& pRegion) const 16322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 16422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rela 16522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela); 16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rela* relaTab = 16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const llvm::ELF::Elf32_Rela*>(pRegion.start()); 16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx=0; idx < entsize; ++idx) { 17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_info = 0x0; 17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int32_t r_addend = 0; 17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 17422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_offset = relaTab[idx].r_offset; 17522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_info = relaTab[idx].r_info; 17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_addend = relaTab[idx].r_addend; 17722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 179d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_offset = mcld::bswap32(relaTab[idx].r_offset); 180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_info = mcld::bswap32(relaTab[idx].r_info); 181d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_addend = mcld::bswap32(relaTab[idx].r_addend); 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t r_type = static_cast<unsigned char>(r_info); 18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_sym = (r_info >> 8); 18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == symbol) { 18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 19022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 19322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 19422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 19522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 19622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readRel - read ELF rel and create Relocation 19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readRel(Input& pInput, 19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSection, 19922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const MemoryRegion& pRegion) const 20022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 20122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get the number of rel 20222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel); 20322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Rel* relTab = 20422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const llvm::ELF::Elf32_Rel*>(pRegion.start()); 20522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 20622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx=0; idx < entsize; ++idx) { 20722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_offset = 0x0; 20822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_info = 0x0; 20922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 21022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_offset = relTab[idx].r_offset; 21122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao r_info = relTab[idx].r_info; 21222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 21322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 214d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_offset = mcld::bswap32(relTab[idx].r_offset); 215d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao r_info = mcld::bswap32(relTab[idx].r_info); 21622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 21722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 21822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t r_type = static_cast<unsigned char>(r_info); 21922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t r_sym = (r_info >> 8); 22022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 22122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 22222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == symbol) { 22322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 22422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 22522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 226d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 22722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 22822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 22922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 23022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyEndian - is this ELF file in the same endian to me? 23222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::isMyEndian(void* pELFHeader) const 23322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 23422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 23522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 23622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 23722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 23822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 23922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// isMyMachine - is this ELF file generated for the same machine. 24122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::isMyMachine(void* pELFHeader) const 24222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 24322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 24422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 24522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 24622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) 247d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (hdr->e_machine == target().getInfo().machine()); 248d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 24922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 25022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 25122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// fileType - return the file type 25222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoInput::Type ELFReader<32, true>::fileType(void* pELFHeader) const 25322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 25422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* hdr = 25522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 25622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t type = 0x0; 25722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) 25822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao type = hdr->e_type; 25922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else 260d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao type = mcld::bswap16(hdr->e_type); 26122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch(type) { 26322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_REL: 26422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Object; 26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_EXEC: 26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Exec; 26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_DYN: 26822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::DynObj; 26922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_CORE: 27022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::CoreFile; 27122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::ET_NONE: 27222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 27322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return Input::Unknown; 27422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSectionHeaders - read ELF section header table and create LDSections 27822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool 27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFReader<32, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const 28022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Ehdr* ehdr = 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t shoff = 0x0; 28522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t shentsize = 0x0; 2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shnum = 0x0; 2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shstrtab = 0x0; 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 29022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shoff = ehdr->e_shoff; 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shentsize = ehdr->e_shentsize; 29222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shnum = ehdr->e_shnum; 29322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao shstrtab = ehdr->e_shstrndx; 29422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 296d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shoff = mcld::bswap32(ehdr->e_shoff); 297d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shentsize = mcld::bswap16(ehdr->e_shentsize); 298d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shnum = mcld::bswap16(ehdr->e_shnum); 299d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao shstrtab = mcld::bswap16(ehdr->e_shstrndx); 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 30122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // If the file has no section header table, e_shoff holds zero. 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (0x0 == shoff) 30422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 30522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf32_Shdr *shdr = NULL; 3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* shdr_region = NULL; 30822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_name = 0x0; 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_type = 0x0; 31022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_flags = 0x0; 31122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_offset = 0x0; 31222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_size = 0x0; 31322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_link = 0x0; 31422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_info = 0x0; 31522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sh_addralign = 0x0; 31622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 3186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 3196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize); 3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start()); 3226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap32(shdr->sh_size); 3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(shdr_region); 3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum * shentsize); 3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf32_Shdr * shdrTab = 3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start()); 3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 34622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get .shstrtab first 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 34822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 34922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdr->sh_offset; 35022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_size = shdr->sh_size; 35122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 353d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdr->sh_offset); 354d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_size = mcld::bswap32(shdr->sh_size); 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 35622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* sect_name_region = pInput.memArea()->request( 35822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + sh_offset, sh_size); 35922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* sect_name = 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<const char*>(sect_name_region->start()); 36122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList link_info_list; 36322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 36422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // create all LDSections, including first NULL section. 36522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < shnum; ++idx) { 36622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 36722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_name = shdrTab[idx].sh_name; 36822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_type = shdrTab[idx].sh_type; 36922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_flags = shdrTab[idx].sh_flags; 37022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_offset = shdrTab[idx].sh_offset; 37122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_size = shdrTab[idx].sh_size; 37222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_link = shdrTab[idx].sh_link; 37322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_info = shdrTab[idx].sh_info; 37422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign = shdrTab[idx].sh_addralign; 37522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 37622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 377d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_name = mcld::bswap32(shdrTab[idx].sh_name); 378d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_type = mcld::bswap32(shdrTab[idx].sh_type); 379d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_flags = mcld::bswap32(shdrTab[idx].sh_flags); 380d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_offset = mcld::bswap32(shdrTab[idx].sh_offset); 381d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_size = mcld::bswap32(shdrTab[idx].sh_size); 382d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_link = mcld::bswap32(shdrTab[idx].sh_link); 383d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_info = mcld::bswap32(shdrTab[idx].sh_info); 384d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign); 38522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 38622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 38722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* section = IRBuilder::CreateELFHeader(pInput, 38822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sect_name+sh_name, 38922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_type, 39022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_flags, 39122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sh_addralign); 39222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setSize(sh_size); 39322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setOffset(sh_offset); 39422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao section->setInfo(sh_info); 39522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 39622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (sh_link != 0x0 || sh_info != 0x0) { 39722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfo link_info = { section, sh_link, sh_info }; 39822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao link_info_list.push_back(link_info); 39922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 40022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } // end of for 40122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 40222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // set up InfoLink 40322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LinkInfoList::iterator info, infoEnd = link_info_list.end(); 40422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (info = link_info_list.begin(); info != infoEnd; ++info) { 40522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::NamePool == info->section->kind() || 40622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Group == info->section->kind() || 40722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDFileFormat::Note == info->section->kind()) { 40822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao info->section->setLink(pInput.context()->getSection(info->sh_link)); 40922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 41022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (LDFileFormat::Relocation == info->section->kind()) { 41222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao info->section->setLink(pInput.context()->getSection(info->sh_info)); 41322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao continue; 41422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 41622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 41722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(shdr_region); 41822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(sect_name_region); 41922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return true; 42122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 42222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 42322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readSignature - read a symbol from the given Input and index in symtab 42422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// This is used to get the signature of a group section. 42522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoResolveInfo* ELFReader<32, true>::readSignature(Input& pInput, 42622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection& pSymTab, 42722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t pSymIdx) const 428affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 42922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* symtab = &pSymTab; 43022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao LDSection* strtab = symtab->getLink(); 43122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != symtab && NULL != strtab); 43222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 43322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t offset = pInput.fileOffset() + symtab->offset() + 43422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sizeof(llvm::ELF::Elf32_Sym) * pSymIdx; 43522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* symbol_region = 43622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym)); 43722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Sym* entry = 43822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start()); 43922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 44022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t st_name = 0x0; 44122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_info = 0x0; 44222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint8_t st_other = 0x0; 44322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint16_t st_shndx = 0x0; 44422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_info = entry->st_info; 44522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_other = entry->st_other; 44622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 44722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_name = entry->st_name; 44822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao st_shndx = entry->st_shndx; 44922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 45022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao else { 451d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_name = mcld::bswap32(entry->st_name); 452d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao st_shndx = mcld::bswap16(entry->st_shndx); 45322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 45422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 45522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* strtab_region = pInput.memArea()->request( 45622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + strtab->offset(), strtab->size()); 45722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 45822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // get ld_name 45922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::StringRef ld_name( 46022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reinterpret_cast<char*>(strtab_region->start() + st_name)); 461affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 46222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ResolveInfo* result = ResolveInfo::Create(ld_name); 46322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setSource(pInput.type() == Input::DynObj); 46422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 46522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setDesc(getSymDesc(st_shndx, pInput)); 46622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 46722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao result->setVisibility(getSymVisibility(st_other)); 468affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 46922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // release regions 47022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(symbol_region); 47122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(strtab_region); 47222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 47322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return result; 47422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 47522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 47622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// readDynamic - read ELF .dynamic in input dynobj 47722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaobool ELFReader<32, true>::readDynamic(Input& pInput) const 47822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 47922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(pInput.type() == Input::DynObj); 48022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 48122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == dynamic_sect) { 48222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynamic"; 48322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 48422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const LDSection* dynstr_sect = dynamic_sect->getLink(); 48522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (NULL == dynstr_sect) { 48622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao fatal(diag::err_cannot_read_section) << ".dynstr"; 48722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 48822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 48922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dynamic_region = pInput.memArea()->request( 49022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 49122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryRegion* dynstr_region = pInput.memArea()->request( 49322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 49422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(NULL != dynamic_region && NULL != dynstr_region); 49622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 49722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const llvm::ELF::Elf32_Dyn* dynamic = 49822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao (llvm::ELF::Elf32_Dyn*) dynamic_region->start(); 49922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao const char* dynstr = (const char*) dynstr_region->start(); 50022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool hasSOName = false; 50122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf32_Dyn); 50222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao for (size_t idx = 0; idx < numOfEntries; ++idx) { 50422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Sword d_tag = 0x0; 50622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao llvm::ELF::Elf32_Word d_val = 0x0; 50722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 50822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (llvm::sys::isLittleEndianHost()) { 50922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_tag = dynamic[idx].d_tag; 51022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao d_val = dynamic[idx].d_un.d_val; 51122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } else { 512d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_tag = mcld::bswap32(dynamic[idx].d_tag); 513d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao d_val = mcld::bswap32(dynamic[idx].d_un.d_val); 51422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 51522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 51622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (d_tag) { 51722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_SONAME: 51822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao assert(d_val < dynstr_sect->size()); 51922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 52022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao hasSOName = true; 52122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 52222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NEEDED: 52322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // TODO: 52422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 52522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case llvm::ELF::DT_NULL: 52622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao default: 52722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 52822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 52922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 53022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // if there is no SONAME in .dynamic, then set it from input path 53222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!hasSOName) 53322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.setName(pInput.path().filename().native()); 53422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 53522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(dynamic_region); 53622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao pInput.memArea()->release(dynstr_region); 537affc150dc44fab1911775a49636d0ce85333b634Zonr Chang return true; 538affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 53922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader<64, true> 5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// constructor 5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::ELFReader(GNULDBackend& pBackend) 5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : ELFReaderIF(pBackend) { 5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// destructor 5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::~ELFReader() 5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isELF - is this a ELF file 5546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::isELF(void* pELFHeader) const 5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4)) 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return false; 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRegularSection - read a regular section and create fragments. 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool 5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::readRegularSection(Input& pInput, SectionData& pSD) const 5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + pSD.getSection().offset(); 5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t size = pSD.getSection().size(); 5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ObjectBuilder::AppendFragment(*frag, pSD); 5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSymbols - read ELF symbols and create LDSymbol 5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readSymbols(Input& pInput, 5776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder& pBuilder, 5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const MemoryRegion& pRegion, 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* pStrTab) const 5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get number of symbols 5826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf64_Sym); 5836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Sym* symtab = 5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Sym*>(pRegion.start()); 5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t st_name = 0x0; 5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_value = 0x0; 5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t st_size = 0x0; 5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_info = 0x0; 5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_other = 0x0; 5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // skip the first NULL symbol 5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.context()->addSymbol(LDSymbol::Null()); 5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 1; idx < entsize; ++idx) { 5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_info = symtab[idx].st_info; 5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = symtab[idx].st_other; 5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = symtab[idx].st_name; 6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = symtab[idx].st_value; 6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size = symtab[idx].st_size; 6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = symtab[idx].st_shndx; 6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = mcld::bswap32(symtab[idx].st_name); 6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_value = mcld::bswap64(symtab[idx].st_value); 6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size = mcld::bswap64(symtab[idx].st_size); 6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(symtab[idx].st_shndx); 6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the section should not be included, set the st_shndx SHN_UNDEF 6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // - A section in interrelated groups are not included. 6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pInput.type() == Input::Object && 6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx < llvm::ELF::SHN_LORESERVE && 6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx != llvm::ELF::SHN_UNDEF) { 6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == pInput.context()->getSection(st_shndx)) 6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = llvm::ELF::SHN_UNDEF; 6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_type 6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_desc 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_binding 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_value - ld_value must be section relative. 6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_vis 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get section 6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = NULL; 6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section = pInput.context()->getSection(st_shndx); 6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::string ld_name; 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (ResolveInfo::Section == ld_type) { 6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Section symbol's st_name is the section index. 6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != section && "get a invalid section"); 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = section->name(); 6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name = std::string(pStrTab + st_name); 6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pBuilder.AddSymbol(pInput, 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_name, 6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_type, 6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_desc, 6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_binding, 6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_size, 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ld_value, 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines section, ld_vis); 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for loop 6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// ELFReader::read relocations - read ELF rela and rel, and create Relocation 6676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines//===----------------------------------------------------------------------===// 6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// ELFReader::readRela - read ELF rela and create Relocation 6696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRela(Input& pInput, 6706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const MemoryRegion& pRegion) const 6726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 6736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rela 6746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rela); 6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rela* relaTab = 6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rela*>(pRegion.start()); 6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx=0; idx < entsize; ++idx) { 6796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_info = 0x0; 6816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines int64_t r_addend = 0; 6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = relaTab[idx].r_offset; 6846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = relaTab[idx].r_info; 6856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_addend = relaTab[idx].r_addend; 6866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = mcld::bswap64(relaTab[idx].r_offset); 6896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = mcld::bswap64(relaTab[idx].r_info); 6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_addend = mcld::bswap64(relaTab[idx].r_addend); 6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_type = static_cast<uint32_t>(r_info); 6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_sym = (r_info >> 32); 6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == symbol) { 6976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readRel - read ELF rel and create Relocation 7066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readRel(Input& pInput, 7076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSection, 7086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const MemoryRegion& pRegion) const 7096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get the number of rel 7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf64_Rel); 7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Rel* relTab = 7136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const llvm::ELF::Elf64_Rel*>(pRegion.start()); 7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx=0; idx < entsize; ++idx) { 7166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_offset = 0x0; 7176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t r_info = 0x0; 7186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 7196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = relTab[idx].r_offset; 7206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = relTab[idx].r_info; 7216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 7236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_offset = mcld::bswap64(relTab[idx].r_offset); 7246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines r_info = mcld::bswap64(relTab[idx].r_info); 7256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_type = static_cast<uint32_t>(r_info); 7286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t r_sym = (r_info >> 32); 7296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 7316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == symbol) { 7326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 7336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 7366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } // end of for 7376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 7386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyEndian - is this ELF file in the same endian to me? 7416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::isMyEndian(void* pELFHeader) const 7426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 7446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 7476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// isMyMachine - is this ELF file generated for the same machine. 7506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::isMyMachine(void* pELFHeader) const 7516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 7536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) 7566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (hdr->e_machine == target().getInfo().machine()); 7576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 7586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// fileType - return the file type 7616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesInput::Type ELFReader<64, true>::fileType(void* pELFHeader) const 7626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* hdr = 7646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t type = 0x0; 7666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) 7676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = hdr->e_type; 7686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 7696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines type = mcld::bswap16(hdr->e_type); 7706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(type) { 7726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_REL: 7736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Object; 7746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_EXEC: 7756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Exec; 7766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_DYN: 7776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::DynObj; 7786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_CORE: 7796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::CoreFile; 7806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::ET_NONE: 7816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 7826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Input::Unknown; 7836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 7856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSectionHeaders - read ELF section header table and create LDSections 7876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool 7886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFReader<64, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const 7896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 7906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Ehdr* ehdr = 7916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(pELFHeader); 7926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t shoff = 0x0; 7946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t shentsize = 0x0; 7956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shnum = 0x0; 7966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t shstrtab = 0x0; 7976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 7986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 7996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff = ehdr->e_shoff; 8006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = ehdr->e_shentsize; 8016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = ehdr->e_shnum; 8026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = ehdr->e_shstrndx; 8036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff = mcld::bswap64(ehdr->e_shoff); 8066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize = mcld::bswap16(ehdr->e_shentsize); 8076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = mcld::bswap16(ehdr->e_shnum); 8086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = mcld::bswap16(ehdr->e_shstrndx); 8096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // If the file has no section header table, e_shoff holds zero. 8126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0x0 == shoff) 8136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 8146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Shdr *shdr = NULL; 8166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* shdr_region = NULL; 8176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_name = 0x0; 8186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_type = 0x0; 8196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_flags = 0x0; 8206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_offset = 0x0; 8216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_size = 0x0; 8226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_link = 0x0; 8236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t sh_info = 0x0; 8246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t sh_addralign = 0x0; 8256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if shnum and shstrtab overflow, the actual values are in the 1st shdr 8276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF || shstrtab == llvm::ELF::SHN_XINDEX) { 8286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 8296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shentsize); 8306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr*>(shdr_region->start()); 8316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 8336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 8346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdr->sh_link; 8356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 8386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdr->sh_link); 8396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(shdr_region); 8416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shnum == llvm::ELF::SHN_UNDEF) 8436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum = sh_size; 8446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (shstrtab == llvm::ELF::SHN_XINDEX) 8456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrtab = sh_link; 8466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shoff += shentsize; 8486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr_region = pInput.memArea()->request(pInput.fileOffset() + shoff, 8516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shnum * shentsize); 8526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Shdr * shdrTab = 8536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Shdr*>(shdr_region->start()); 8546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get .shstrtab first 8566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr = &shdrTab[shstrtab]; 8576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 8586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdr->sh_offset; 8596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdr->sh_size; 8606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdr->sh_offset); 8636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdr->sh_size); 8646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* sect_name_region = pInput.memArea()->request( 8676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + sh_offset, sh_size); 8686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* sect_name = 8696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<const char*>(sect_name_region->start()); 8706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfoList link_info_list; 8726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // create all LDSections, including first NULL section. 8746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < shnum; ++idx) { 8756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 8766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_name = shdrTab[idx].sh_name; 8776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type = shdrTab[idx].sh_type; 8786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags = shdrTab[idx].sh_flags; 8796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = shdrTab[idx].sh_offset; 8806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = shdrTab[idx].sh_size; 8816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = shdrTab[idx].sh_link; 8826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_info = shdrTab[idx].sh_info; 8836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = shdrTab[idx].sh_addralign; 8846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 8866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_name = mcld::bswap32(shdrTab[idx].sh_name); 8876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type = mcld::bswap32(shdrTab[idx].sh_type); 8886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags = mcld::bswap64(shdrTab[idx].sh_flags); 8896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_offset = mcld::bswap64(shdrTab[idx].sh_offset); 8906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_size = mcld::bswap64(shdrTab[idx].sh_size); 8916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_link = mcld::bswap32(shdrTab[idx].sh_link); 8926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_info = mcld::bswap32(shdrTab[idx].sh_info); 8936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_addralign = mcld::bswap64(shdrTab[idx].sh_addralign); 8946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 8956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 8966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* section = IRBuilder::CreateELFHeader(pInput, 8976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sect_name+sh_name, 8986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_type, 8996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sh_flags, 9006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 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) { 9066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkInfo link_info = { section, sh_link, sh_info }; 9076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines link_info_list.push_back(link_info); 9086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen 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) { 9146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LDFileFormat::NamePool == info->section->kind() || 9156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDFileFormat::Group == info->section->kind() || 9166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDFileFormat::Note == info->section->kind()) { 9176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_link)); 9186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 9196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LDFileFormat::Relocation == info->section->kind()) { 9216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines info->section->setLink(pInput.context()->getSection(info->sh_info)); 9226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines continue; 9236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(shdr_region); 9276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(sect_name_region); 9286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 9306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 9316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readSignature - read a symbol from the given Input and index in symtab 9336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// This is used to get the signature of a group section. 9346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesResolveInfo* ELFReader<64, true>::readSignature(Input& pInput, 9356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection& pSymTab, 9366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t pSymIdx) const 9376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 9386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* symtab = &pSymTab; 9396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LDSection* strtab = symtab->getLink(); 9406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != symtab && NULL != strtab); 9416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t offset = pInput.fileOffset() + symtab->offset() + 9436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sizeof(llvm::ELF::Elf64_Sym) * pSymIdx; 9446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* symbol_region = 9456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf64_Sym)); 9466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Sym* entry = 9476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<llvm::ELF::Elf64_Sym*>(symbol_region->start()); 9486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint32_t st_name = 0x0; 9506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_info = 0x0; 9516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint8_t st_other = 0x0; 9526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint16_t st_shndx = 0x0; 9536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_info = entry->st_info; 9546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_other = entry->st_other; 9556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 9566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = entry->st_name; 9576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = entry->st_shndx; 9586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 9606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_name = mcld::bswap32(entry->st_name); 9616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines st_shndx = mcld::bswap16(entry->st_shndx); 9626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* strtab_region = pInput.memArea()->request( 9656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + strtab->offset(), strtab->size()); 9666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // get ld_name 9686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::StringRef ld_name( 9696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reinterpret_cast<char*>(strtab_region->start() + st_name)); 9706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ResolveInfo* result = ResolveInfo::Create(ld_name); 9726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setSource(pInput.type() == Input::DynObj); 9736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 9746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setDesc(getSymDesc(st_shndx, pInput)); 9756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 9766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result->setVisibility(getSymVisibility(st_other)); 9776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // release regions 9796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(symbol_region); 9806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(strtab_region); 9816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 9836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 9846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// readDynamic - read ELF .dynamic in input dynobj 9866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesbool ELFReader<64, true>::readDynamic(Input& pInput) const 9876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 9886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pInput.type() == Input::DynObj); 9896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 9906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == dynamic_sect) { 9916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynamic"; 9926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* dynstr_sect = dynamic_sect->getLink(); 9946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == dynstr_sect) { 9956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::err_cannot_read_section) << ".dynstr"; 9966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 9976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 9986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* dynamic_region = pInput.memArea()->request( 9996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 10006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* dynstr_region = pInput.memArea()->request( 10026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 10036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != dynamic_region && NULL != dynstr_region); 10056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const llvm::ELF::Elf64_Dyn* dynamic = 10076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (llvm::ELF::Elf64_Dyn*) dynamic_region->start(); 10086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const char* dynstr = (const char*) dynstr_region->start(); 10096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool hasSOName = false; 10106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf64_Dyn); 10116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (size_t idx = 0; idx < numOfEntries; ++idx) { 10136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Sxword d_tag = 0x0; 10156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::Elf64_Xword d_val = 0x0; 10166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::sys::isLittleEndianHost()) { 10186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = dynamic[idx].d_tag; 10196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = dynamic[idx].d_un.d_val; 10206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 10216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_tag = mcld::bswap64(dynamic[idx].d_tag); 10226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines d_val = mcld::bswap64(dynamic[idx].d_un.d_val); 10236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (d_tag) { 10266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_SONAME: 10276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(d_val < dynstr_sect->size()); 10286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 10296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines hasSOName = true; 10306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NEEDED: 10326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: 10336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case llvm::ELF::DT_NULL: 10356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 10366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 10376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 10396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // if there is no SONAME in .dynamic, then set it from input path 10416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (!hasSOName) 10426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.setName(pInput.path().filename().native()); 10436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 10446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(dynamic_region); 10456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pInput.memArea()->release(dynstr_region); 10466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return true; 10476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 10486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1049