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__) 31 static inline RSExecRef wrap(ELFObject<64> *object) { 32 return reinterpret_cast<RSExecRef>(object); 33 } 34 #else 35 static inline RSExecRef wrap(ELFObject<32> *object) { 36 return reinterpret_cast<RSExecRef>(object); 37 } 38 #endif 39 40 #if defined(__LP64__) || defined(__x86_64__) 41 static inline ELFObject<64> *unwrap(RSExecRef object) { 42 return reinterpret_cast<ELFObject<64> *>(object); 43 } 44 #else 45 static inline ELFObject<32> *unwrap(RSExecRef object) { 46 return reinterpret_cast<ELFObject<32> *>(object); 47 } 48 #endif 49 50 extern "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 67 extern "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 84 extern "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 96 extern "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 140 extern "C" void rsloaderDisposeExec(RSExecRef object) { 141 delete unwrap(object); 142 } 143 144 extern "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 178 extern "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 208 extern "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 223 extern "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