ELFObjectLoaderImpl.cpp revision ef73a242762bcd8113b9b65ceccbe7d909b5acbc
10f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang/* 20f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * Copyright 2012, The Android Open Source Project 30f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * 40f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 50f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * you may not use this file except in compliance with the License. 60f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * You may obtain a copy of the License at 70f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * 80f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 90f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * 100f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * Unless required by applicable law or agreed to in writing, software 110f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 120f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * See the License for the specific language governing permissions and 140f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang * limitations under the License. 150f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang */ 160f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 170f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include "ELFObjectLoaderImpl.h" 180f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 190f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include <llvm/Support/ELF.h> 200f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 210f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang// The following files are included from librsloader. 220f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include "ELFObject.h" 230f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include "ELFSectionSymTab.h" 240f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include "ELFSymbol.h" 250f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang#include "utils/serialize.h" 260f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 27c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/ExecutionEngine/SymbolResolverInterface.h" 28ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h" 290f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 300f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changusing namespace bcc; 310f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 320f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changbool ELFObjectLoaderImpl::load(const void *pMem, size_t pMemSize) { 330f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ArchiveReaderLE reader(reinterpret_cast<const unsigned char *>(pMem), 340f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang pMemSize); 350f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 360f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang mObject = ELFObject<32>::read(reader); 370f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (mObject == NULL) { 380f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ALOGE("Unable to load the ELF object!"); 390f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return false; 400f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 410f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 420f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang // Retrive the pointer to the symbol table. 430f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang mSymTab = static_cast<ELFSectionSymTab<32> *>( 440f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang mObject->getSectionByName(".symtab")); 450f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (mSymTab == NULL) { 460f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ALOGW("Object doesn't contain any symbol table."); 470f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 480f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 490f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return true; 500f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang} 510f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 520f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changbool ELFObjectLoaderImpl::relocate(SymbolResolverInterface &pResolver) { 530f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang mObject->relocate(SymbolResolverInterface::LookupFunction, &pResolver); 540f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 550f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (mObject->getMissingSymbols()) { 560f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ALOGE("Some symbols are found to be undefined during relocation!"); 570f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return false; 580f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 590f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 600f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return true; 610f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang} 620f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 630f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changbool ELFObjectLoaderImpl::prepareDebugImage(void *pDebugImg, 640f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang size_t pDebugImgSize) { 650f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang // Update the value of sh_addr in pDebugImg to its corresponding section in 660f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang // the mObject. 670f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang llvm::ELF::Elf32_Ehdr *elf_header = 680f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang reinterpret_cast<llvm::ELF::Elf32_Ehdr *>(pDebugImg); 690f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 700f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (elf_header->e_shoff > pDebugImgSize) { 710f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ALOGE("Invalid section header table offset found! (e_shoff = %d)", 720f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang elf_header->e_shoff); 730f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return false; 740f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 750f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 760f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if ((elf_header->e_shoff + 770f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang sizeof(llvm::ELF::Elf32_Shdr) * elf_header->e_shnum) > pDebugImgSize) { 780f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ALOGE("Invalid image supplied (debug image doesn't contain all the section" 790f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang "header or corrupted image)! (e_shoff = %d, e_shnum = %d)", 800f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang elf_header->e_shoff, elf_header->e_shnum); 810f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return false; 820f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 830f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 840f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang llvm::ELF::Elf32_Shdr *section_header_table = 850f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang reinterpret_cast<llvm::ELF::Elf32_Shdr *>( 860f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang reinterpret_cast<uint8_t*>(pDebugImg) + elf_header->e_shoff); 870f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 880f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang for (unsigned i = 0; i < elf_header->e_shnum; i++) { 890f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (section_header_table[i].sh_flags & llvm::ELF::SHF_ALLOC) { 900f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ELFSectionBits<32> *section = 910f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang static_cast<ELFSectionBits<32> *>(mObject->getSectionByIndex(i)); 920f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (section != NULL) { 930f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang section_header_table[i].sh_addr = 940f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang reinterpret_cast<llvm::ELF::Elf32_Addr>(section->getBuffer()); 950f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 960f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 970f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 980f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 990f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return true; 1000f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang} 1010f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 1020f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Changvoid *ELFObjectLoaderImpl::getSymbolAddress(const char *pName) const { 1030f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (mSymTab == NULL) { 1040f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return NULL; 1050f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 1060f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 1070f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ELFSymbol<32> *symbol = mSymTab->getByName(pName); 1080f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang if (symbol == NULL) { 1090f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang ALOGV("Request symbol '%s' is not found in the object!", pName); 1100f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return NULL; 1110f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang } 1120f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 1130f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return symbol->getAddress(mObject->getHeader()->getMachine(), 1140f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang /* autoAlloc */false); 1150f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang} 1160f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang 1170f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr ChangELFObjectLoaderImpl::~ELFObjectLoaderImpl() { 1180f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang delete mObject; 1190f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return; 1200f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang} 121