librsloader.cpp revision 9ed73923af9db7283a8c76b5dfa2dda5b732a852
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) { 48c9acf1fd2d58985b95793374b15cc3bdd11e271bSteve Block ALOGE("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) { 76c9ff76dbcf76753a2460e6e3887d80a196fcb9adStephen Hines ALOGV("Symbol not found: %s\n", name); 7721ca257e99974ac0044012180ace2b833525e45dLogan Chien return NULL; 7821ca257e99974ac0044012180ace2b833525e45dLogan Chien } 7921ca257e99974ac0044012180ace2b833525e45dLogan Chien 809ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh int machine = object->getHeader()->getMachine(); 819ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh 829ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh return symbol->getAddress(machine, false); 8358ed8bce80acd10ea103dc9c94f83466fa500ac9Logan Chien} 8411b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 8511b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chienextern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) { 8611b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien ELFObject<32> *object = unwrap(object_); 8711b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 8811b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien ELFSectionSymTab<32> *symtab = 8911b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 9011b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 9111b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien if (!symtab) { 9211b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien return NULL; 9311b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien } 9411b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 9511b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien ELFSymbol<32> *symbol = symtab->getByName(name); 9611b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 9711b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien if (!symbol) { 98c9ff76dbcf76753a2460e6e3887d80a196fcb9adStephen Hines ALOGV("Symbol not found: %s\n", name); 9911b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien return NULL; 10011b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien } 10111b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien 10211b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien return (size_t)symbol->getSize(); 10311b53125c58adc902c1e2a60cbe667ba2344ecceLogan Chien} 104388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 105388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chienextern "C" size_t rsloaderGetFuncCount(RSExecRef object) { 106388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 107388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien unwrap(object)->getSectionByName(".symtab")); 108388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 109388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien if (!symtab) { 110388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien return 0; 111388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien } 112388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 113388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien return symtab->getFuncCount(); 114388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien} 115388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 116388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chienextern "C" void rsloaderGetFuncNameList(RSExecRef object, 117388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien size_t size, 118388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien char const **list) { 119388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 120388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien unwrap(object)->getSectionByName(".symtab")); 121388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien 122388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien if (symtab) { 123388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien symtab->getFuncNameList(size, list); 124388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien } 125388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien} 126