1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/* 2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011-2012, The Android Open Source Project 3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License. 6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at 7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software 11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and 14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License. 15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */ 16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "librsloader.h" 18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFObject.h" 20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionSymTab.h" 21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSymbol.h" 22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/serialize.h" 24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define LOG_TAG "bcc" 26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "cutils/log.h" 27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/ADT/OwningPtr.h> 29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/Support/ELF.h> 30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesstatic inline RSExecRef wrap(ELFObject<32> *object) { 32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return reinterpret_cast<RSExecRef>(object); 33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesstatic inline ELFObject<32> *unwrap(RSExecRef object) { 36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return reinterpret_cast<ELFObject<32> *>(object); 37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" RSExecRef rsloaderCreateExec(unsigned char const *buf, 40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t buf_size, 41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines RSFindSymbolFn find_symbol, 42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *find_symbol_context) { 43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines RSExecRef object = rsloaderLoadExecutable(buf, buf_size); 44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!object) { 45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return NULL; 46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!rsloaderRelocateExecutable(object, find_symbol, find_symbol_context)) { 49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsloaderDisposeExec(object); 50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return NULL; 51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return object; 54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" RSExecRef rsloaderLoadExecutable(unsigned char const *buf, 57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t buf_size) { 58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ArchiveReaderLE AR(buf, buf_size); 59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::OwningPtr<ELFObject<32> > object(ELFObject<32>::read(AR)); 61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!object) { 62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ALOGE("Unable to load the ELF object."); 63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return NULL; 64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return wrap(object.take()); 67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" int rsloaderRelocateExecutable(RSExecRef object_, 70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines RSFindSymbolFn find_symbol, 71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *find_symbol_context) { 72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFObject<32>* object = unwrap(object_); 73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines object->relocate(find_symbol, find_symbol_context); 75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return (object->getMissingSymbols() == 0); 76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void rsloaderUpdateSectionHeaders(RSExecRef object_, 79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char *buf) { 80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFObject<32> *object = unwrap(object_); 81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Remap the section header addresses to match the loaded code 83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::ELF::Elf32_Ehdr* header = reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(buf); 84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines llvm::ELF::Elf32_Shdr* shtab = 86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines reinterpret_cast<llvm::ELF::Elf32_Shdr*>(buf + header->e_shoff); 87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (int i = 0; i < header->e_shnum; i++) { 89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (shtab[i].sh_flags & SHF_ALLOC) { 90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionBits<32>* bits = 91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static_cast<ELFSectionBits<32>*>(object->getSectionByIndex(i)); 92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (bits) { 93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines const unsigned char* addr = bits->getBuffer(); 94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines shtab[i].sh_addr = reinterpret_cast<llvm::ELF::Elf32_Addr>(addr); 95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void rsloaderDisposeExec(RSExecRef object) { 101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines delete unwrap(object); 102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void *rsloaderGetSymbolAddress(RSExecRef object_, 105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines char const *name) { 106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFObject<32> *object = unwrap(object_); 107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionSymTab<32> *symtab = 109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!symtab) { 112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return NULL; 113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSymbol<32> *symbol = symtab->getByName(name); 116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!symbol) { 118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ALOGV("Symbol not found: %s\n", name); 119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return NULL; 120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines int machine = object->getHeader()->getMachine(); 123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return symbol->getAddress(machine, false); 125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) { 128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFObject<32> *object = unwrap(object_); 129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionSymTab<32> *symtab = 131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!symtab) { 134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return 0; 135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSymbol<32> *symbol = symtab->getByName(name); 138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!symbol) { 140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ALOGV("Symbol not found: %s\n", name); 141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return 0; 142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return (size_t)symbol->getSize(); 145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" size_t rsloaderGetFuncCount(RSExecRef object) { 148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unwrap(object)->getSectionByName(".symtab")); 150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 151b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!symtab) { 152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return 0; 153b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 154b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 155b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return symtab->getFuncCount(); 156b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 157b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 158b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void rsloaderGetFuncNameList(RSExecRef object, 159b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t size, 160b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines char const **list) { 161b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 162b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unwrap(object)->getSectionByName(".symtab")); 163b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 164b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (symtab) { 165b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines symtab->getFuncNameList(size, list); 166b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 167b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 168