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