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