blob: 8797ce1669228ae17dbaf940b15d00a5f90c74ed [file] [log] [blame]
Zonr Chang0f9cad92012-04-13 14:35:45 +08001/*
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
Zonr Changc72c4dd2012-04-12 15:38:53 +080027#include "bcc/ExecutionEngine/SymbolResolverInterface.h"
Zonr Changef73a242012-04-12 16:44:01 +080028#include "bcc/Support/Log.h"
Zonr Chang0f9cad92012-04-13 14:35:45 +080029
30using namespace bcc;
31
32bool ELFObjectLoaderImpl::load(const void *pMem, size_t pMemSize) {
33 ArchiveReaderLE reader(reinterpret_cast<const unsigned char *>(pMem),
34 pMemSize);
35
WeiTange524a6f2014-04-04 23:38:30 +080036#ifdef __LP64__
37 mObject = ELFObject<64>::read(reader);
38#else
Zonr Chang0f9cad92012-04-13 14:35:45 +080039 mObject = ELFObject<32>::read(reader);
WeiTange524a6f2014-04-04 23:38:30 +080040#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +080041 if (mObject == NULL) {
42 ALOGE("Unable to load the ELF object!");
43 return false;
44 }
45
46 // Retrive the pointer to the symbol table.
WeiTange524a6f2014-04-04 23:38:30 +080047#ifdef __LP64__
48 mSymTab = static_cast<ELFSectionSymTab<64> *>(
Tim Murrayc2074ca2014-04-08 15:39:08 -070049 mObject->getSectionByName(".symtab"));
WeiTange524a6f2014-04-04 23:38:30 +080050#else
51 mSymTab = static_cast<ELFSectionSymTab<32> *>(
52 mObject->getSectionByName(".symtab"));
53#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +080054 if (mSymTab == NULL) {
55 ALOGW("Object doesn't contain any symbol table.");
56 }
57
58 return true;
59}
60
61bool 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
72bool 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.
WeiTange524a6f2014-04-04 23:38:30 +080076#ifdef __LP64__
77 llvm::ELF::Elf64_Ehdr *elf_header =
78 reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(pDebugImg);
79#else
Zonr Chang0f9cad92012-04-13 14:35:45 +080080 llvm::ELF::Elf32_Ehdr *elf_header =
WeiTange524a6f2014-04-04 23:38:30 +080081 reinterpret_cast<llvm::ELF::Elf32_Ehdr *>(pDebugImg);
82#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +080083
84 if (elf_header->e_shoff > pDebugImgSize) {
WeiTange524a6f2014-04-04 23:38:30 +080085#ifdef __LP64__
86 ALOGE("Invalid section header table offset found! (e_shoff = %ld)",
87 elf_header->e_shoff);
88#else
Zonr Chang0f9cad92012-04-13 14:35:45 +080089 ALOGE("Invalid section header table offset found! (e_shoff = %d)",
90 elf_header->e_shoff);
WeiTange524a6f2014-04-04 23:38:30 +080091#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +080092 return false;
93 }
94
95 if ((elf_header->e_shoff +
96 sizeof(llvm::ELF::Elf32_Shdr) * elf_header->e_shnum) > pDebugImgSize) {
WeiTange524a6f2014-04-04 23:38:30 +080097#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
Zonr Chang0f9cad92012-04-13 14:35:45 +0800102 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);
WeiTange524a6f2014-04-04 23:38:30 +0800105#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +0800106 return false;
107 }
108
WeiTange524a6f2014-04-04 23:38:30 +0800109#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
Zonr Chang0f9cad92012-04-13 14:35:45 +0800114 llvm::ELF::Elf32_Shdr *section_header_table =
115 reinterpret_cast<llvm::ELF::Elf32_Shdr *>(
116 reinterpret_cast<uint8_t*>(pDebugImg) + elf_header->e_shoff);
WeiTange524a6f2014-04-04 23:38:30 +0800117#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +0800118
119 for (unsigned i = 0; i < elf_header->e_shnum; i++) {
120 if (section_header_table[i].sh_flags & llvm::ELF::SHF_ALLOC) {
WeiTange524a6f2014-04-04 23:38:30 +0800121#ifdef __LP64__
122 ELFSectionBits<64> *section =
123 static_cast<ELFSectionBits<64> *>(mObject->getSectionByIndex(i));
124#else
Zonr Chang0f9cad92012-04-13 14:35:45 +0800125 ELFSectionBits<32> *section =
126 static_cast<ELFSectionBits<32> *>(mObject->getSectionByIndex(i));
WeiTange524a6f2014-04-04 23:38:30 +0800127#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +0800128 if (section != NULL) {
Ian Rogersbe07e232014-01-29 15:48:23 -0800129 uintptr_t address = reinterpret_cast<uintptr_t>(section->getBuffer());
WeiTange524a6f2014-04-04 23:38:30 +0800130#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
Ian Rogersbe07e232014-01-29 15:48:23 -0800134 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);
WeiTange524a6f2014-04-04 23:38:30 +0800136#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +0800137 }
138 }
139 }
140
141 return true;
142}
143
144void *ELFObjectLoaderImpl::getSymbolAddress(const char *pName) const {
145 if (mSymTab == NULL) {
146 return NULL;
147 }
148
WeiTange524a6f2014-04-04 23:38:30 +0800149#ifdef __LP64__
150 const ELFSymbol<64> *symbol = mSymTab->getByName(pName);
151#else
Shih-wei Liao97957542012-07-22 15:42:53 -0700152 const ELFSymbol<32> *symbol = mSymTab->getByName(pName);
WeiTange524a6f2014-04-04 23:38:30 +0800153#endif
Zonr Chang0f9cad92012-04-13 14:35:45 +0800154 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
Shih-wei Liao97957542012-07-22 15:42:53 -0700163size_t ELFObjectLoaderImpl::getSymbolSize(const char *pName) const {
164 if (mSymTab == NULL) {
165 return 0;
166 }
167
WeiTange524a6f2014-04-04 23:38:30 +0800168#ifdef __LP64__
169 const ELFSymbol<64> *symbol = mSymTab->getByName(pName);
170#else
Shih-wei Liao97957542012-07-22 15:42:53 -0700171 const ELFSymbol<32> *symbol = mSymTab->getByName(pName);
WeiTange524a6f2014-04-04 23:38:30 +0800172#endif
Shih-wei Liao97957542012-07-22 15:42:53 -0700173
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
183bool
Chris Wailes5e7d8762014-07-25 18:02:32 -0700184ELFObjectLoaderImpl::getSymbolNameList(std::vector<const char *>& pNameList,
Shih-wei Liao97957542012-07-22 15:42:53 -0700185 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++) {
WeiTange524a6f2014-04-04 23:38:30 +0800206#ifdef __LP64__
207 ELFSymbol<64> *symbol = (*mSymTab)[i];
208#else
Shih-wei Liao97957542012-07-22 15:42:53 -0700209 ELFSymbol<32> *symbol = (*mSymTab)[i];
WeiTange524a6f2014-04-04 23:38:30 +0800210#endif
Shih-wei Liao97957542012-07-22 15:42:53 -0700211 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
Zonr Chang0f9cad92012-04-13 14:35:45 +0800227ELFObjectLoaderImpl::~ELFObjectLoaderImpl() {
228 delete mObject;
229 return;
230}