1a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao/* 2a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * Copyright 2011, The Android Open Source Project 3a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * 4a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License"); 5a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * you may not use this file except in compliance with the License. 6a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * You may obtain a copy of the License at 7a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * 8a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * http://www.apache.org/licenses/LICENSE-2.0 9a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * 10a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * Unless required by applicable law or agreed to in writing, software 11a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS, 12a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * See the License for the specific language governing permissions and 14a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao * limitations under the License. 15a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao */ 16a4e5f360d91ca11fc12b322d1a2bb25609b214d1Shih-wei Liao 1758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "librsloader.h" 1858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 1958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "ELFObject.h" 2058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "ELFSectionSymTab.h" 2158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "ELFSymbol.h" 2258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 2358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "utils/serialize.h" 2458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 2558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#define LOG_TAG "bcc" 2658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include "cutils/log.h" 2758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 2858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien#include <llvm/ADT/OwningPtr.h> 2958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 3058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienstatic inline RSExecRef wrap(ELFObject<32> *object) { 3158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return reinterpret_cast<RSExecRef>(object); 3258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 3358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 3458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienstatic inline ELFObject<32> *unwrap(RSExecRef object) { 3558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return reinterpret_cast<ELFObject<32> *>(object); 3658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 3758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 3858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienextern "C" RSExecRef 3958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan ChienrsloaderCreateExec(unsigned char const *buf, 4058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien size_t buf_size, 4158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien void *(*find_symbol)(void *, char const *), 4258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien void *find_symbol_context) { 4358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 4458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien ArchiveReaderLE AR(buf, buf_size); 4558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 4658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien llvm::OwningPtr<ELFObject<32> > object(ELFObject<32>::read(AR)); 4758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien if (!object) { 4858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien LOGE("Unable to load the ELF object."); 4958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return NULL; 5058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien } 5158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 5258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien //object->print(); 5358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien object->relocate(find_symbol, find_symbol_context); 5458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 5558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien return wrap(object.take()); 5658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 5758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 5858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienextern "C" void rsloaderDisposeExec(RSExecRef object) { 5958ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien delete unwrap(object); 6058ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 6158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 6258ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chienextern "C" void *rsloaderGetSymbolAddress(RSExecRef object_, 6358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien char const *name) { 6458ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien ELFObject<32> *object = unwrap(object_); 6558ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 6658ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien ELFSectionSymTab<32> *symtab = 6758ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 6858ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien 6921ca257e99974ac0044012180ace2b833525e45dLogan Chien if (!symtab) { 7021ca257e99974ac0044012180ace2b833525e45dLogan Chien return NULL; 7121ca257e99974ac0044012180ace2b833525e45dLogan Chien } 7221ca257e99974ac0044012180ace2b833525e45dLogan Chien 7321ca257e99974ac0044012180ace2b833525e45dLogan Chien ELFSymbol<32> *symbol = symtab->getByName(name); 7421ca257e99974ac0044012180ace2b833525e45dLogan Chien 7521ca257e99974ac0044012180ace2b833525e45dLogan Chien if (!symbol) { 7621ca257e99974ac0044012180ace2b833525e45dLogan Chien LOGE("Symbol not found: %s\n", name); 7721ca257e99974ac0044012180ace2b833525e45dLogan Chien return NULL; 7821ca257e99974ac0044012180ace2b833525e45dLogan Chien } 7921ca257e99974ac0044012180ace2b833525e45dLogan Chien 80b2584ebd9eff677283b23ab762ef411fe16ba22dLogan Chien return symbol->getAddress(false); 8158ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 8211b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 8311b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chienextern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) { 8411b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien ELFObject<32> *object = unwrap(object_); 8511b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 8611b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien ELFSectionSymTab<32> *symtab = 8711b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 8811b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 8911b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien if (!symtab) { 9011b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien return NULL; 9111b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien } 9211b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 9311b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien ELFSymbol<32> *symbol = symtab->getByName(name); 9411b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 9511b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien if (!symbol) { 9611b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien LOGE("Symbol not found: %s\n", name); 9711b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien return NULL; 9811b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien } 9911b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 10011b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien return (size_t)symbol->getSize(); 10111b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien} 102388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 103388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chienextern "C" size_t rsloaderGetFuncCount(RSExecRef object) { 104388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 105388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien unwrap(object)->getSectionByName(".symtab")); 106388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 107388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien if (!symtab) { 108388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien return 0; 109388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien } 110388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 111388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien return symtab->getFuncCount(); 112388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien} 113388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 114388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chienextern "C" void rsloaderGetFuncNameList(RSExecRef object, 115388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien size_t size, 116388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien char const **list) { 117388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 118388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien unwrap(object)->getSectionByName(".symtab")); 119388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 120388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien if (symtab) { 121388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien symtab->getFuncNameList(size, list); 122388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien } 123388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien} 124