blob: adea85d73f5fc0c883175d2638b3f626b750b117 [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 Chienf7015fd2012-03-18 01:19:37 +080087const void* ElfLoader::GetMethodCodeAddr(size_t elf_idx,
88 const Method* method) const {
89 CHECK_LT(elf_idx, executables_.size());
90 CHECK(method != NULL);
91 return GetAddr(elf_idx, LLVMLongName(method).c_str());
92}
93
94
95const Method::InvokeStub* ElfLoader::
96GetMethodInvokeStubAddr(size_t elf_idx, const Method* method) const {
97 CHECK_LT(elf_idx, executables_.size());
98 CHECK(method != NULL);
99 return reinterpret_cast<const Method::InvokeStub*>(
100 GetAddr(elf_idx, LLVMStubName(method).c_str()));
101}
102
103
104const void* ElfLoader::GetAddr(size_t elf_idx, const char* sym_name) const {
105 CHECK_LT(elf_idx, executables_.size());
106 CHECK(executables_[elf_idx] != NULL);
107 return rsloaderGetSymbolAddress(executables_[elf_idx], sym_name);
108}
109
110
111} // namespace compiler_llvm
112} // namespace art