1/* 2 * Copyright 2011-2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "librsloader.h" 18 19#include "ELFObject.h" 20#include "ELFSectionSymTab.h" 21#include "ELFSymbol.h" 22 23#include "utils/serialize.h" 24 25#define LOG_TAG "bcc" 26#include "cutils/log.h" 27 28#include <llvm/Support/ELF.h> 29 30#if defined(__LP64__) || defined(__x86_64__) 31static inline RSExecRef wrap(ELFObject<64> *object) { 32 return reinterpret_cast<RSExecRef>(object); 33} 34#else 35static inline RSExecRef wrap(ELFObject<32> *object) { 36 return reinterpret_cast<RSExecRef>(object); 37} 38#endif 39 40#if defined(__LP64__) || defined(__x86_64__) 41static inline ELFObject<64> *unwrap(RSExecRef object) { 42 return reinterpret_cast<ELFObject<64> *>(object); 43} 44#else 45static inline ELFObject<32> *unwrap(RSExecRef object) { 46 return reinterpret_cast<ELFObject<32> *>(object); 47} 48#endif 49 50extern "C" RSExecRef rsloaderCreateExec(unsigned char const *buf, 51 size_t buf_size, 52 RSFindSymbolFn find_symbol, 53 void *find_symbol_context) { 54 RSExecRef object = rsloaderLoadExecutable(buf, buf_size); 55 if (!object) { 56 return NULL; 57 } 58 59 if (!rsloaderRelocateExecutable(object, find_symbol, find_symbol_context)) { 60 rsloaderDisposeExec(object); 61 return NULL; 62 } 63 64 return object; 65} 66 67extern "C" RSExecRef rsloaderLoadExecutable(unsigned char const *buf, 68 size_t buf_size) { 69 ArchiveReaderLE AR(buf, buf_size); 70 71#if defined(__LP64__) || defined(__x86_64__) 72 std::unique_ptr<ELFObject<64> > object(ELFObject<64>::read(AR)); 73#else 74 std::unique_ptr<ELFObject<32> > object(ELFObject<32>::read(AR)); 75#endif 76 if (!object) { 77 ALOGE("Unable to load the ELF object."); 78 return NULL; 79 } 80 81 return wrap(object.release()); 82} 83 84extern "C" int rsloaderRelocateExecutable(RSExecRef object_, 85 RSFindSymbolFn find_symbol, 86 void *find_symbol_context) { 87#if defined(__LP64__) || defined(__x86_64__) 88 ELFObject<64>* object = unwrap(object_); 89#else 90 ELFObject<32>* object = unwrap(object_); 91#endif 92 object->relocate(find_symbol, find_symbol_context); 93 return (object->getMissingSymbols() == 0); 94} 95 96extern "C" void rsloaderUpdateSectionHeaders(RSExecRef object_, 97 unsigned char *buf) { 98#if defined(__LP64__) || defined(__x86_64__) 99 ELFObject<64> *object = unwrap(object_); 100#else 101 ELFObject<32> *object = unwrap(object_); 102#endif 103 104 // Remap the section header addresses to match the loaded code 105#if defined(__LP64__) || defined(__x86_64__) 106 llvm::ELF::Elf64_Ehdr* header = reinterpret_cast<llvm::ELF::Elf64_Ehdr*>(buf); 107#else 108 llvm::ELF::Elf32_Ehdr* header = reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(buf); 109#endif 110 111#if defined(__LP64__) || defined(__x86_64__) 112 llvm::ELF::Elf64_Shdr* shtab = 113 reinterpret_cast<llvm::ELF::Elf64_Shdr*>(buf + header->e_shoff); 114#else 115 llvm::ELF::Elf32_Shdr* shtab = 116 reinterpret_cast<llvm::ELF::Elf32_Shdr*>(buf + header->e_shoff); 117#endif 118 119 for (int i = 0; i < header->e_shnum; i++) { 120 if (shtab[i].sh_flags & SHF_ALLOC) { 121#if defined(__LP64__) || defined(__x86_64__) 122 ELFSectionBits<64>* bits = 123 static_cast<ELFSectionBits<64>*>(object->getSectionByIndex(i)); 124#else 125 ELFSectionBits<32>* bits = 126 static_cast<ELFSectionBits<32>*>(object->getSectionByIndex(i)); 127#endif 128 if (bits) { 129 const unsigned char* addr = bits->getBuffer(); 130#if defined(__LP64__) || defined(__x86_64__) 131 shtab[i].sh_addr = reinterpret_cast<llvm::ELF::Elf64_Addr>(addr); 132#else 133 shtab[i].sh_addr = reinterpret_cast<llvm::ELF::Elf32_Addr>(addr); 134#endif 135 } 136 } 137 } 138} 139 140extern "C" void rsloaderDisposeExec(RSExecRef object) { 141 delete unwrap(object); 142} 143 144extern "C" void *rsloaderGetSymbolAddress(RSExecRef object_, 145 char const *name) { 146#if defined(__LP64__) || defined(__x86_64__) 147 ELFObject<64> *object = unwrap(object_); 148 149 ELFSectionSymTab<64> *symtab = 150 static_cast<ELFSectionSymTab<64> *>(object->getSectionByName(".symtab")); 151#else 152 ELFObject<32> *object = unwrap(object_); 153 154 ELFSectionSymTab<32> *symtab = 155 static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 156#endif 157 158 if (!symtab) { 159 return NULL; 160 } 161 162#if defined(__LP64__) || defined(__x86_64__) 163 ELFSymbol<64> *symbol = symtab->getByName(name); 164#else 165 ELFSymbol<32> *symbol = symtab->getByName(name); 166#endif 167 168 if (!symbol) { 169 ALOGV("Symbol not found: %s\n", name); 170 return NULL; 171 } 172 173 int machine = object->getHeader()->getMachine(); 174 175 return symbol->getAddress(machine, false); 176} 177 178extern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) { 179#if defined(__LP64__) || defined(__x86_64__) 180 ELFObject<64> *object = unwrap(object_); 181 182 ELFSectionSymTab<64> *symtab = 183 static_cast<ELFSectionSymTab<64> *>(object->getSectionByName(".symtab")); 184#else 185 ELFObject<32> *object = unwrap(object_); 186 187 ELFSectionSymTab<32> *symtab = 188 static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 189#endif 190 if (!symtab) { 191 return 0; 192 } 193 194#if defined(__LP64__) || defined(__x86_64__) 195 ELFSymbol<64> *symbol = symtab->getByName(name); 196#else 197 ELFSymbol<32> *symbol = symtab->getByName(name); 198#endif 199 200 if (!symbol) { 201 ALOGV("Symbol not found: %s\n", name); 202 return 0; 203 } 204 205 return (size_t)symbol->getSize(); 206} 207 208extern "C" size_t rsloaderGetFuncCount(RSExecRef object) { 209#if defined(__LP64__) || defined(__x86_64__) 210 ELFSectionSymTab<64> *symtab = static_cast<ELFSectionSymTab<64> *>( 211#else 212 ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 213#endif 214 unwrap(object)->getSectionByName(".symtab")); 215 216 if (!symtab) { 217 return 0; 218 } 219 220 return symtab->getFuncCount(); 221} 222 223extern "C" void rsloaderGetFuncNameList(RSExecRef object, 224 size_t size, 225 char const **list) { 226#if defined(__LP64__) || defined(__x86_64__) 227 ELFSectionSymTab<64> *symtab = static_cast<ELFSectionSymTab<64> *>( 228#else 229 ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 230#endif 231 unwrap(object)->getSectionByName(".symtab")); 232 233 if (symtab) { 234 symtab->getFuncNameList(size, list); 235 } 236} 237