1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CRAZY_LINKER_SHARED_LIBRARY_H
6 #define CRAZY_LINKER_SHARED_LIBRARY_H
10 #include "crazy_linker_elf_relro.h"
11 #include "crazy_linker_elf_symbols.h"
12 #include "crazy_linker_elf_view.h"
13 #include "crazy_linker_error.h"
14 #include "crazy_linker_rdebug.h"
15 #include "crazy_linker_util.h"
16 #include "elf_traits.h"
23 // A class that models a shared library loaded by the crazy linker.
25 // Libraries have dependencies (which are listed in their dynamic section
26 // as DT_NEEDED entries). Circular dependencies are forbidden, so they
27 // form an ADG, where the root is the crazy linker itself, since all
28 // libraries that it loads will depend on it (to ensure their
29 // dlopen/dlsym/dlclose calls are properly wrapped).
36 size_t load_address() const { return view_.load_address(); }
37 size_t load_size() const { return view_.load_size(); }
38 size_t load_bias() const { return view_.load_bias(); }
39 const ELF::Phdr* phdr() const { return view_.phdr(); }
40 size_t phdr_count() const { return view_.phdr_count(); }
41 const char* base_name() const { return base_name_; }
43 // Load a library (without its dependents) from an ELF file.
44 // Note: This does not apply relocations, nor runs constructors.
45 // |full_path| if the file full path.
46 // |load_address| is the page-aligned load address in memory, or 0.
47 // |file_offset| is the page-aligned file offset.
48 // |no_map_exec_support_fallback_enabled| is a flag whether the fallback due
49 // to lack of support for mapping the APK file with executable permission is
51 // On failure, return false and set |error| message.
53 // After this, the caller should load all library dependencies,
54 // Then call Relocate() and CallConstructors() to complete the
56 bool Load(const char* full_path,
59 bool no_map_exec_support_fallback_enabled,
62 // Relocate this library, assuming all its dependencies are already
63 // loaded in |lib_list|. On failure, return false and set |error|
65 bool Relocate(LibraryList* lib_list,
66 Vector<LibraryView*>* dependencies,
69 void GetInfo(size_t* load_address,
73 *load_address = view_.load_address();
74 *load_size = view_.load_size();
75 *relro_start = relro_start_;
76 *relro_size = relro_size_;
79 // Returns true iff a given library is mapped to a virtual address range
80 // that contains a given address.
81 bool ContainsAddress(void* address) const {
82 size_t addr = reinterpret_cast<size_t>(address);
83 return load_address() <= addr && addr <= load_address() + load_size();
86 // Call all constructors in the library.
87 void CallConstructors();
89 // Call all destructors in the library.
90 void CallDestructors();
92 // Return the ELF symbol entry for a given symbol, if defined by
93 // this library, or NULL otherwise.
94 const ELF::Sym* LookupSymbolEntry(const char* symbol_name);
96 // Find the nearest symbol near a given |address|. On success, return
97 // true and set |*sym_name| to the symbol name, |*sym_addr| to its address
98 // in memory, and |*sym_size| to its size in bytes, if any.
99 bool FindNearestSymbolForAddress(void* address,
100 const char** sym_name,
103 return symbols_.LookupNearestByAddress(
104 address, load_bias(), sym_name, sym_addr, sym_size);
107 // Return the address of a given |symbol_name| if it is exported
108 // by the library, NULL otherwise.
109 void* FindAddressForSymbol(const char* symbol_name);
111 // Create a new Ashmem region holding a copy of the library's RELRO section,
112 // potentially relocated for a new |load_address|. On success, return true
113 // and sets |*relro_start|, |*relro_size| and |*relro_fd|. Note that the
114 // RELRO start address is adjusted for |load_address|, and that the caller
115 // becomes the owner of |*relro_fd|. On failure, return false and set
117 bool CreateSharedRelro(size_t load_address,
123 // Try to use a shared relro section from another process.
124 // On success, return true. On failure return false and
125 // sets |error| message.
126 bool UseSharedRelro(size_t relro_start,
131 // Look for a symbol named 'JNI_OnLoad' in this library, and if it
132 // exists, call it with |java_vm| as the first parameter. If the
133 // function result is less than |minimum_jni_version|, fail with
134 // a message in |error|. On success, return true, and record
135 // |java_vm| to call 'JNI_OnUnload' at unload time, if present.
136 bool SetJavaVM(void* java_vm, int minimum_jni_version, Error* error);
138 // Call 'JNI_OnUnload()' is necessary, i.e. if there was a succesful call
139 // to SetJavaVM() before. This will pass the same |java_vm| value to the
140 // callback, if it is present in the library.
141 void CallJniOnUnload();
143 // Helper class to iterate over dependencies in a given SharedLibrary.
145 // SharedLibary::DependencyIterator iter(lib);
146 // while (iter.GetNext() {
147 // dependency_name = iter.GetName();
150 class DependencyIterator {
152 DependencyIterator(SharedLibrary* lib)
153 : iter_(&lib->view_), symbols_(&lib->symbols_), dep_name_(NULL) {}
157 const char* GetName() const { return dep_name_; }
160 DependencyIterator();
161 DependencyIterator(const DependencyIterator&);
162 DependencyIterator& operator=(const DependencyIterator&);
164 ElfView::DynamicIterator iter_;
165 const ElfSymbols* symbols_;
166 const char* dep_name_;
169 typedef void (*linker_function_t)();
172 friend class LibraryList;
177 ELF::Addr relro_start_;
178 ELF::Addr relro_size_;
181 SharedLibrary* list_next_;
182 SharedLibrary* list_prev_;
185 linker_function_t* preinit_array_;
186 size_t preinit_array_count_;
187 linker_function_t* init_array_;
188 size_t init_array_count_;
189 linker_function_t* fini_array_;
190 size_t fini_array_count_;
191 linker_function_t init_func_;
192 linker_function_t fini_func_;
195 // ARM EABI section used for stack unwinding.
196 unsigned* arm_exidx_;
197 size_t arm_exidx_count_;
200 #if defined(__arm__) || defined(__aarch64__)
201 // Packed relocations data, NULL if absent.
202 uint8_t* packed_relocations_;
205 link_map_t link_map_;
207 bool has_DT_SYMBOLIC_;
211 const char* base_name_;
212 char full_path_[512];
217 #endif // CRAZY_LINKER_SHARED_LIBRARY_H