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 1079795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao const 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 1179795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liaosize_t ELFObjectLoaderImpl::getSymbolSize(const char *pName) const { 1189795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao if (mSymTab == NULL) { 1199795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao return 0; 1209795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1219795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1229795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao const ELFSymbol<32> *symbol = mSymTab->getByName(pName); 1239795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1249795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao if (symbol == NULL) { 1259795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao ALOGV("Request symbol '%s' is not found in the object!", pName); 1269795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao return 0; 1279795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1289795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1299795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao return static_cast<size_t>(symbol->getSize()); 1309795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1319795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao} 1329795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1339795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liaobool 1349795754a34648d962f00ced51183b759b9eaf2b2Shih-wei LiaoELFObjectLoaderImpl::getSymbolNameList(android::Vector<const char *>& pNameList, 1359795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao ObjectLoader::SymbolType pType) const { 1369795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao if (mSymTab == NULL) { 1379795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao return false; 1389795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1399795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1409795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao unsigned elf_type; 1419795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao switch (pType) { 1429795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao case ObjectLoader::kFunctionType: { 1439795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao elf_type = llvm::ELF::STT_FUNC; 1449795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao break; 1459795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1469795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao case ObjectLoader::kUnknownType: { 1479795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao break; 1489795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1499795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao default: { 1509795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao assert(false && "Invalid symbol type given!"); 1519795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao return false; 1529795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1539795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1549795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1559795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao for (size_t i = 0, e = mSymTab->size(); i != e; i++) { 1569795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao ELFSymbol<32> *symbol = (*mSymTab)[i]; 1579795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao if (symbol == NULL) { 1589795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao continue; 1599795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1609795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1619795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao if ((pType == ObjectLoader::kUnknownType) || 1629795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao (symbol->getType() == elf_type)) { 1639795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao const char *symbol_name = symbol->getName(); 1649795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao if (symbol_name != NULL) { 1659795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao pNameList.push_back(symbol_name); 1669795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1679795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1689795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao } 1699795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1709795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao return true; 1719795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao} 1729795754a34648d962f00ced51183b759b9eaf2b2Shih-wei Liao 1730f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr ChangELFObjectLoaderImpl::~ELFObjectLoaderImpl() { 1740f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang delete mObject; 1750f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang return; 1760f9cad99f9e3c4db42e9836cc0e316c3a84448f5Zonr Chang} 177