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/Support/ELF.h>
29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
308d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
31db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTangstatic inline RSExecRef wrap(ELFObject<64> *object) {
32db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  return reinterpret_cast<RSExecRef>(object);
33db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang}
34db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesstatic inline RSExecRef wrap(ELFObject<32> *object) {
36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return reinterpret_cast<RSExecRef>(object);
37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
38db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
408d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
41db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTangstatic inline ELFObject<64> *unwrap(RSExecRef object) {
42db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  return reinterpret_cast<ELFObject<64> *>(object);
43db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang}
44db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesstatic inline ELFObject<32> *unwrap(RSExecRef object) {
46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return reinterpret_cast<ELFObject<32> *>(object);
47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
48db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" RSExecRef rsloaderCreateExec(unsigned char const *buf,
51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                        size_t buf_size,
52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                        RSFindSymbolFn find_symbol,
53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                        void *find_symbol_context) {
54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  RSExecRef object = rsloaderLoadExecutable(buf, buf_size);
55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!object) {
56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return NULL;
57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!rsloaderRelocateExecutable(object, find_symbol, find_symbol_context)) {
60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    rsloaderDisposeExec(object);
61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return NULL;
62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return object;
65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" RSExecRef rsloaderLoadExecutable(unsigned char const *buf,
68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                            size_t buf_size) {
69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ArchiveReaderLE AR(buf, buf_size);
70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
718d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
72d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  std::unique_ptr<ELFObject<64> > object(ELFObject<64>::read(AR));
73db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
74d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  std::unique_ptr<ELFObject<32> > object(ELFObject<32>::read(AR));
75db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!object) {
77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    ALOGE("Unable to load the ELF object.");
78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return NULL;
79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
81d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  return wrap(object.release());
82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" int rsloaderRelocateExecutable(RSExecRef object_,
85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                          RSFindSymbolFn find_symbol,
86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                          void *find_symbol_context) {
878d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
88db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFObject<64>* object = unwrap(object_);
89db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFObject<32>* object = unwrap(object_);
91db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  object->relocate(find_symbol, find_symbol_context);
93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return (object->getMissingSymbols() == 0);
94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void rsloaderUpdateSectionHeaders(RSExecRef object_,
97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                             unsigned char *buf) {
988d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
99db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFObject<64> *object = unwrap(object_);
100db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFObject<32> *object = unwrap(object_);
102db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  // Remap the section header addresses to match the loaded code
1058d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
106db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  llvm::ELF::Elf64_Ehdr* header = reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(buf);
107db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  llvm::ELF::Elf32_Ehdr* header = reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(buf);
109db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
1118d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
112db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  llvm::ELF::Elf64_Shdr* shtab =
113db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang      reinterpret_cast<llvm::ELF::Elf64_Shdr*>(buf + header->e_shoff);
114db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  llvm::ELF::Elf32_Shdr* shtab =
116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      reinterpret_cast<llvm::ELF::Elf32_Shdr*>(buf + header->e_shoff);
117db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  for (int i = 0; i < header->e_shnum; i++) {
120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    if (shtab[i].sh_flags & SHF_ALLOC) {
1218d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
122db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang      ELFSectionBits<64>* bits =
123db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang          static_cast<ELFSectionBits<64>*>(object->getSectionByIndex(i));
124db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      ELFSectionBits<32>* bits =
126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          static_cast<ELFSectionBits<32>*>(object->getSectionByIndex(i));
127db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      if (bits) {
129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        const unsigned char* addr = bits->getBuffer();
1308d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
131db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang        shtab[i].sh_addr = reinterpret_cast<llvm::ELF::Elf64_Addr>(addr);
132f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers#else
133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        shtab[i].sh_addr = reinterpret_cast<llvm::ELF::Elf32_Addr>(addr);
134f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers#endif
135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      }
136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    }
137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void rsloaderDisposeExec(RSExecRef object) {
141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  delete unwrap(object);
142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void *rsloaderGetSymbolAddress(RSExecRef object_,
145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                          char const *name) {
1468d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
147db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFObject<64> *object = unwrap(object_);
148db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang
149db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFSectionSymTab<64> *symtab =
150db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang    static_cast<ELFSectionSymTab<64> *>(object->getSectionByName(".symtab"));
151db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFObject<32> *object = unwrap(object_);
153b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
154b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionSymTab<32> *symtab =
155b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab"));
156db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
157b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
158b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!symtab) {
159b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return NULL;
160b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
161b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
1628d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
163db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFSymbol<64> *symbol = symtab->getByName(name);
164db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
165b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbol<32> *symbol = symtab->getByName(name);
166db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
167b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
168b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!symbol) {
169b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    ALOGV("Symbol not found: %s\n", name);
170b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return NULL;
171b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
172b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
173b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  int machine = object->getHeader()->getMachine();
174b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
175b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return symbol->getAddress(machine, false);
176b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
177b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
178b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) {
1798d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
180db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFObject<64> *object = unwrap(object_);
181db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang
182db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFSectionSymTab<64> *symtab =
183db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang    static_cast<ELFSectionSymTab<64> *>(object->getSectionByName(".symtab"));
184db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
185b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFObject<32> *object = unwrap(object_);
186b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
187b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionSymTab<32> *symtab =
188b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab"));
189db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
190b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!symtab) {
191b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
192b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
193b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
1948d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
195db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFSymbol<64> *symbol = symtab->getByName(name);
196db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
197b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbol<32> *symbol = symtab->getByName(name);
198db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
199b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
200b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!symbol) {
201b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    ALOGV("Symbol not found: %s\n", name);
202b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
203b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
204b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
205b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return (size_t)symbol->getSize();
206b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
207b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
208b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" size_t rsloaderGetFuncCount(RSExecRef object) {
2098d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
210db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFSectionSymTab<64> *symtab = static_cast<ELFSectionSymTab<64> *>(
211db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
212b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>(
213db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
214b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    unwrap(object)->getSectionByName(".symtab"));
215b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
216b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!symtab) {
217b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
218b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
219b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
220b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return symtab->getFuncCount();
221b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
222b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
223b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesextern "C" void rsloaderGetFuncNameList(RSExecRef object,
224b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                        size_t size,
225b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                                        char const **list) {
2268d50174ff0e80bc3846f9dfd6f7d154fc4949db4Logan Chien#if defined(__LP64__) || defined(__x86_64__)
227db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang  ELFSectionSymTab<64> *symtab = static_cast<ELFSectionSymTab<64> *>(
228db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#else
229b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>(
230db2ffd2e9c7b7949905621e55a73d3431cf4fc90WeiTang#endif
231b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    unwrap(object)->getSectionByName(".symtab"));
232b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
233b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (symtab) {
234b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    symtab->getFuncNameList(size, list);
235b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
236b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
237