blob: 07072dfc2ae954ba7e6b894dc626dc7688b93b95 [file] [log] [blame]
Logan Chienf7015fd2012-03-18 01:19:37 +08001/*
2 * Copyright (C) 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 "elf_loader.h"
18
19#include "compiled_method.h"
Logan Chien0f0899a2012-03-23 10:48:18 +080020#include "elf_image.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080021#include "logging.h"
Logan Chien0c717dd2012-03-28 18:31:07 +080022#include "oat_file.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080023#include "object.h"
24#include "runtime_support_llvm.h"
25#include "utils_llvm.h"
26
27#include <android/librsloader.h>
28
29namespace art {
30namespace compiler_llvm {
31
32
33ElfLoader::~ElfLoader() {
34 // Release every ELF object
35 for (size_t i = 0; i < executables_.size(); ++i) {
36 rsloaderDisposeExec(executables_[i]);
37 }
38}
39
40
Logan Chien0c717dd2012-03-28 18:31:07 +080041bool ElfLoader::LoadElfAt(size_t elf_idx,
42 const ElfImage& elf_image,
43 OatFile::RelocationBehavior reloc) {
Logan Chienf7015fd2012-03-18 01:19:37 +080044 if (elf_idx < executables_.size() && executables_[elf_idx] != NULL) {
45 return false;
46 }
47
48 if (elf_idx >= executables_.size()) {
49 executables_.resize(elf_idx + 1);
50 }
51
Logan Chien0c717dd2012-03-28 18:31:07 +080052 RSExecRef executable = rsloaderLoadExecutable(elf_image.begin(),
53 elf_image.size());
Logan Chienf7015fd2012-03-18 01:19:37 +080054
55 if (executable == NULL) {
Logan Chien0f0899a2012-03-23 10:48:18 +080056 LOG(WARNING) << "Failed to load ELF"
Logan Chien3fe0c602012-03-27 21:14:37 +080057 << " image: " << static_cast<const void*>(elf_image.begin())
Logan Chien0f0899a2012-03-23 10:48:18 +080058 << " size: " << elf_image.size();
Logan Chienf7015fd2012-03-18 01:19:37 +080059 return false;
60 }
61
Logan Chien0c717dd2012-03-28 18:31:07 +080062 if (reloc == OatFile::kRelocAll) {
63 if (!rsloaderRelocateExecutable(executable,
64 art_find_runtime_support_func, NULL)) {
65 LOG(ERROR) << "Failed to relocate the ELF image";
66 rsloaderDisposeExec(executable);
67 return false;
68 }
69 }
70
Logan Chienf7015fd2012-03-18 01:19:37 +080071 executables_[elf_idx] = executable;
72 return true;
73}
74
75
Logan Chien0c717dd2012-03-28 18:31:07 +080076void ElfLoader::RelocateExecutable() {
77 for (size_t i = 0; i < executables_.size(); ++i) {
78 if (executables_[i] != NULL &&
79 !rsloaderRelocateExecutable(executables_[i],
80 art_find_runtime_support_func, NULL)) {
81 LOG(FATAL) << "Failed to relocate ELF image " << i;
82 }
83 }
84}
85
86
Logan Chien937105a2012-04-02 02:37:37 +080087const void* ElfLoader::GetMethodCodeAddr(uint16_t elf_idx,
88 uint16_t elf_func_idx) const {
Logan Chienf7015fd2012-03-18 01:19:37 +080089 CHECK_LT(elf_idx, executables_.size());
Logan Chien937105a2012-04-02 02:37:37 +080090 return GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str());
Logan Chienf7015fd2012-03-18 01:19:37 +080091}
92
93
94const Method::InvokeStub* ElfLoader::
Logan Chien937105a2012-04-02 02:37:37 +080095GetMethodInvokeStubAddr(uint16_t elf_idx, uint16_t elf_func_idx) const {
Logan Chienf7015fd2012-03-18 01:19:37 +080096 CHECK_LT(elf_idx, executables_.size());
Logan Chienf7015fd2012-03-18 01:19:37 +080097 return reinterpret_cast<const Method::InvokeStub*>(
Logan Chien937105a2012-04-02 02:37:37 +080098 GetAddr(elf_idx, ElfFuncName(elf_func_idx).c_str()));
Logan Chienf7015fd2012-03-18 01:19:37 +080099}
100
101
Logan Chien14924fe2012-04-03 18:33:37 +0800102size_t ElfLoader::GetCodeSize(uint16_t elf_idx, uint16_t elf_func_idx) const {
103 CHECK_LT(elf_idx, executables_.size());
104 CHECK(executables_[elf_idx] != NULL);
105 return rsloaderGetSymbolSize(executables_[elf_idx],
106 ElfFuncName(elf_func_idx).c_str());
107}
108
109
Logan Chienf7015fd2012-03-18 01:19:37 +0800110const void* ElfLoader::GetAddr(size_t elf_idx, const char* sym_name) const {
111 CHECK_LT(elf_idx, executables_.size());
112 CHECK(executables_[elf_idx] != NULL);
113 return rsloaderGetSymbolAddress(executables_[elf_idx], sym_name);
114}
115
116
117} // namespace compiler_llvm
118} // namespace art