1 /* 2 * Copyright 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 "ELFObjectLoaderImpl.h" 18 19 #include <llvm/Support/ELF.h> 20 21 // The following files are included from librsloader. 22 #include "ELFObject.h" 23 #include "ELFSectionSymTab.h" 24 #include "ELFSymbol.h" 25 #include "utils/serialize.h" 26 27 #include "bcc/ExecutionEngine/SymbolResolverInterface.h" 28 #include "bcc/Support/Log.h" 29 30 using namespace bcc; 31 32 bool ELFObjectLoaderImpl::load(const void *pMem, size_t pMemSize) { 33 ArchiveReaderLE reader(reinterpret_cast<const unsigned char *>(pMem), 34 pMemSize); 35 36 #ifdef __LP64__ 37 mObject = ELFObject<64>::read(reader); 38 #else 39 mObject = ELFObject<32>::read(reader); 40 #endif 41 if (mObject == NULL) { 42 ALOGE("Unable to load the ELF object!"); 43 return false; 44 } 45 46 // Retrive the pointer to the symbol table. 47 #ifdef __LP64__ 48 mSymTab = static_cast<ELFSectionSymTab<64> *>( 49 mObject->getSectionByName(".symtab")); 50 #else 51 mSymTab = static_cast<ELFSectionSymTab<32> *>( 52 mObject->getSectionByName(".symtab")); 53 #endif 54 if (mSymTab == NULL) { 55 ALOGW("Object doesn't contain any symbol table."); 56 } 57 58 return true; 59 } 60 61 bool ELFObjectLoaderImpl::relocate(SymbolResolverInterface &pResolver) { 62 mObject->relocate(SymbolResolverInterface::LookupFunction, &pResolver); 63 64 if (mObject->getMissingSymbols()) { 65 ALOGE("Some symbols are found to be undefined during relocation!"); 66 return false; 67 } 68 69 return true; 70 } 71 72 bool ELFObjectLoaderImpl::prepareDebugImage(void *pDebugImg, 73 size_t pDebugImgSize) { 74 // Update the value of sh_addr in pDebugImg to its corresponding section in 75 // the mObject. 76 #ifdef __LP64__ 77 llvm::ELF::Elf64_Ehdr *elf_header = 78 reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(pDebugImg); 79 #else 80 llvm::ELF::Elf32_Ehdr *elf_header = 81 reinterpret_cast<llvm::ELF::Elf32_Ehdr *>(pDebugImg); 82 #endif 83 84 if (elf_header->e_shoff > pDebugImgSize) { 85 #ifdef __LP64__ 86 ALOGE("Invalid section header table offset found! (e_shoff = %ld)", 87 elf_header->e_shoff); 88 #else 89 ALOGE("Invalid section header table offset found! (e_shoff = %d)", 90 elf_header->e_shoff); 91 #endif 92 return false; 93 } 94 95 if ((elf_header->e_shoff + 96 sizeof(llvm::ELF::Elf32_Shdr) * elf_header->e_shnum) > pDebugImgSize) { 97 #ifdef __LP64__ 98 ALOGE("Invalid image supplied (debug image doesn't contain all the section" 99 "header or corrupted image)! (e_shoff = %ld, e_shnum = %d)", 100 elf_header->e_shoff, elf_header->e_shnum); 101 #else 102 ALOGE("Invalid image supplied (debug image doesn't contain all the section" 103 "header or corrupted image)! (e_shoff = %d, e_shnum = %d)", 104 elf_header->e_shoff, elf_header->e_shnum); 105 #endif 106 return false; 107 } 108 109 #ifdef __LP64__ 110 llvm::ELF::Elf64_Shdr *section_header_table = 111 reinterpret_cast<llvm::ELF::Elf64_Shdr *>( 112 reinterpret_cast<uint8_t*>(pDebugImg) + elf_header->e_shoff); 113 #else 114 llvm::ELF::Elf32_Shdr *section_header_table = 115 reinterpret_cast<llvm::ELF::Elf32_Shdr *>( 116 reinterpret_cast<uint8_t*>(pDebugImg) + elf_header->e_shoff); 117 #endif 118 119 for (unsigned i = 0; i < elf_header->e_shnum; i++) { 120 if (section_header_table[i].sh_flags & llvm::ELF::SHF_ALLOC) { 121 #ifdef __LP64__ 122 ELFSectionBits<64> *section = 123 static_cast<ELFSectionBits<64> *>(mObject->getSectionByIndex(i)); 124 #else 125 ELFSectionBits<32> *section = 126 static_cast<ELFSectionBits<32> *>(mObject->getSectionByIndex(i)); 127 #endif 128 if (section != NULL) { 129 uintptr_t address = reinterpret_cast<uintptr_t>(section->getBuffer()); 130 #ifdef __LP64__ 131 LOG_FATAL_IF(address > 0xFFFFFFFFFFFFFFFFu, "Out of bound address for Elf64_Addr"); 132 section_header_table[i].sh_addr = static_cast<llvm::ELF::Elf64_Addr>(address); 133 #else 134 LOG_FATAL_IF(address > 0xFFFFFFFFu, "Out of bound address for Elf32_Addr"); 135 section_header_table[i].sh_addr = static_cast<llvm::ELF::Elf32_Addr>(address); 136 #endif 137 } 138 } 139 } 140 141 return true; 142 } 143 144 void *ELFObjectLoaderImpl::getSymbolAddress(const char *pName) const { 145 if (mSymTab == NULL) { 146 return NULL; 147 } 148 149 #ifdef __LP64__ 150 const ELFSymbol<64> *symbol = mSymTab->getByName(pName); 151 #else 152 const ELFSymbol<32> *symbol = mSymTab->getByName(pName); 153 #endif 154 if (symbol == NULL) { 155 ALOGV("Request symbol '%s' is not found in the object!", pName); 156 return NULL; 157 } 158 159 return symbol->getAddress(mObject->getHeader()->getMachine(), 160 /* autoAlloc */false); 161 } 162 163 size_t ELFObjectLoaderImpl::getSymbolSize(const char *pName) const { 164 if (mSymTab == NULL) { 165 return 0; 166 } 167 168 #ifdef __LP64__ 169 const ELFSymbol<64> *symbol = mSymTab->getByName(pName); 170 #else 171 const ELFSymbol<32> *symbol = mSymTab->getByName(pName); 172 #endif 173 174 if (symbol == NULL) { 175 ALOGV("Request symbol '%s' is not found in the object!", pName); 176 return 0; 177 } 178 179 return static_cast<size_t>(symbol->getSize()); 180 181 } 182 183 bool 184 ELFObjectLoaderImpl::getSymbolNameList(android::Vector<const char *>& pNameList, 185 ObjectLoader::SymbolType pType) const { 186 if (mSymTab == NULL) { 187 return false; 188 } 189 190 unsigned elf_type; 191 switch (pType) { 192 case ObjectLoader::kFunctionType: { 193 elf_type = llvm::ELF::STT_FUNC; 194 break; 195 } 196 case ObjectLoader::kUnknownType: { 197 break; 198 } 199 default: { 200 assert(false && "Invalid symbol type given!"); 201 return false; 202 } 203 } 204 205 for (size_t i = 0, e = mSymTab->size(); i != e; i++) { 206 #ifdef __LP64__ 207 ELFSymbol<64> *symbol = (*mSymTab)[i]; 208 #else 209 ELFSymbol<32> *symbol = (*mSymTab)[i]; 210 #endif 211 if (symbol == NULL) { 212 continue; 213 } 214 215 if ((pType == ObjectLoader::kUnknownType) || 216 (symbol->getType() == elf_type)) { 217 const char *symbol_name = symbol->getName(); 218 if (symbol_name != NULL) { 219 pNameList.push_back(symbol_name); 220 } 221 } 222 } 223 224 return true; 225 } 226 227 ELFObjectLoaderImpl::~ELFObjectLoaderImpl() { 228 delete mObject; 229 return; 230 } 231