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/ADT/OwningPtr.h> 29 #include <llvm/Support/ELF.h> 30 31 static inline RSExecRef wrap(ELFObject<32> *object) { 32 return reinterpret_cast<RSExecRef>(object); 33 } 34 35 static inline ELFObject<32> *unwrap(RSExecRef object) { 36 return reinterpret_cast<ELFObject<32> *>(object); 37 } 38 39 extern "C" RSExecRef rsloaderCreateExec(unsigned char const *buf, 40 size_t buf_size, 41 RSFindSymbolFn find_symbol, 42 void *find_symbol_context) { 43 RSExecRef object = rsloaderLoadExecutable(buf, buf_size); 44 if (!object) { 45 return NULL; 46 } 47 48 if (!rsloaderRelocateExecutable(object, find_symbol, find_symbol_context)) { 49 rsloaderDisposeExec(object); 50 return NULL; 51 } 52 53 return object; 54 } 55 56 extern "C" RSExecRef rsloaderLoadExecutable(unsigned char const *buf, 57 size_t buf_size) { 58 ArchiveReaderLE AR(buf, buf_size); 59 60 llvm::OwningPtr<ELFObject<32> > object(ELFObject<32>::read(AR)); 61 if (!object) { 62 ALOGE("Unable to load the ELF object."); 63 return NULL; 64 } 65 66 return wrap(object.take()); 67 } 68 69 extern "C" int rsloaderRelocateExecutable(RSExecRef object_, 70 RSFindSymbolFn find_symbol, 71 void *find_symbol_context) { 72 ELFObject<32>* object = unwrap(object_); 73 74 object->relocate(find_symbol, find_symbol_context); 75 return (object->getMissingSymbols() == 0); 76 } 77 78 extern "C" void rsloaderUpdateSectionHeaders(RSExecRef object_, 79 unsigned char *buf) { 80 ELFObject<32> *object = unwrap(object_); 81 82 // Remap the section header addresses to match the loaded code 83 llvm::ELF::Elf32_Ehdr* header = reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(buf); 84 85 llvm::ELF::Elf32_Shdr* shtab = 86 reinterpret_cast<llvm::ELF::Elf32_Shdr*>(buf + header->e_shoff); 87 88 for (int i = 0; i < header->e_shnum; i++) { 89 if (shtab[i].sh_flags & SHF_ALLOC) { 90 ELFSectionBits<32>* bits = 91 static_cast<ELFSectionBits<32>*>(object->getSectionByIndex(i)); 92 if (bits) { 93 const unsigned char* addr = bits->getBuffer(); 94 shtab[i].sh_addr = reinterpret_cast<llvm::ELF::Elf32_Addr>(addr); 95 } 96 } 97 } 98 } 99 100 extern "C" void rsloaderDisposeExec(RSExecRef object) { 101 delete unwrap(object); 102 } 103 104 extern "C" void *rsloaderGetSymbolAddress(RSExecRef object_, 105 char const *name) { 106 ELFObject<32> *object = unwrap(object_); 107 108 ELFSectionSymTab<32> *symtab = 109 static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 110 111 if (!symtab) { 112 return NULL; 113 } 114 115 ELFSymbol<32> *symbol = symtab->getByName(name); 116 117 if (!symbol) { 118 ALOGV("Symbol not found: %s\n", name); 119 return NULL; 120 } 121 122 int machine = object->getHeader()->getMachine(); 123 124 return symbol->getAddress(machine, false); 125 } 126 127 extern "C" size_t rsloaderGetSymbolSize(RSExecRef object_, char const *name) { 128 ELFObject<32> *object = unwrap(object_); 129 130 ELFSectionSymTab<32> *symtab = 131 static_cast<ELFSectionSymTab<32> *>(object->getSectionByName(".symtab")); 132 133 if (!symtab) { 134 return 0; 135 } 136 137 ELFSymbol<32> *symbol = symtab->getByName(name); 138 139 if (!symbol) { 140 ALOGV("Symbol not found: %s\n", name); 141 return 0; 142 } 143 144 return (size_t)symbol->getSize(); 145 } 146 147 extern "C" size_t rsloaderGetFuncCount(RSExecRef object) { 148 ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 149 unwrap(object)->getSectionByName(".symtab")); 150 151 if (!symtab) { 152 return 0; 153 } 154 155 return symtab->getFuncCount(); 156 } 157 158 extern "C" void rsloaderGetFuncNameList(RSExecRef object, 159 size_t size, 160 char const **list) { 161 ELFSectionSymTab<32> *symtab = static_cast<ELFSectionSymTab<32> *>( 162 unwrap(object)->getSectionByName(".symtab")); 163 164 if (symtab) { 165 symtab->getFuncNameList(size, list); 166 } 167 } 168