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 // On failure, return false and set |error| message.
50 // After this, the caller should load all library dependencies,
51 // Then call Relocate() and CallConstructors() to complete the
53 bool Load(const char* full_path,
58 // Relocate this library, assuming all its dependencies are already
59 // loaded in |lib_list|. On failure, return false and set |error|
61 bool Relocate(LibraryList* lib_list,
62 Vector<LibraryView*>* dependencies,
65 void GetInfo(size_t* load_address,
69 *load_address = view_.load_address();
70 *load_size = view_.load_size();
71 *relro_start = relro_start_;
72 *relro_size = relro_size_;
75 // Returns true iff a given library is mapped to a virtual address range
76 // that contains a given address.
77 bool ContainsAddress(void* address) const {
78 size_t addr = reinterpret_cast<size_t>(address);
79 return load_address() <= addr && addr <= load_address() + load_size();
82 // Call all constructors in the library.
83 void CallConstructors();
85 // Call all destructors in the library.
86 void CallDestructors();
88 // Return the ELF symbol entry for a given symbol, if defined by
89 // this library, or NULL otherwise.
90 const ELF::Sym* LookupSymbolEntry(const char* symbol_name);
92 // Find the nearest symbol near a given |address|. On success, return
93 // true and set |*sym_name| to the symbol name, |*sym_addr| to its address
94 // in memory, and |*sym_size| to its size in bytes, if any.
95 bool FindNearestSymbolForAddress(void* address,
96 const char** sym_name,
99 return symbols_.LookupNearestByAddress(
100 address, load_bias(), sym_name, sym_addr, sym_size);
103 // Return the address of a given |symbol_name| if it is exported
104 // by the library, NULL otherwise.
105 void* FindAddressForSymbol(const char* symbol_name);
107 // Create a new Ashmem region holding a copy of the library's RELRO section,
108 // potentially relocated for a new |load_address|. On success, return true
109 // and sets |*relro_start|, |*relro_size| and |*relro_fd|. Note that the
110 // RELRO start address is adjusted for |load_address|, and that the caller
111 // becomes the owner of |*relro_fd|. On failure, return false and set
113 bool CreateSharedRelro(size_t load_address,
119 // Try to use a shared relro section from another process.
120 // On success, return true. On failure return false and
121 // sets |error| message.
122 bool UseSharedRelro(size_t relro_start,
127 // Look for a symbol named 'JNI_OnLoad' in this library, and if it
128 // exists, call it with |java_vm| as the first parameter. If the
129 // function result is less than |minimum_jni_version|, fail with
130 // a message in |error|. On success, return true, and record
131 // |java_vm| to call 'JNI_OnUnload' at unload time, if present.
132 bool SetJavaVM(void* java_vm, int minimum_jni_version, Error* error);
134 // Call 'JNI_OnUnload()' is necessary, i.e. if there was a succesful call
135 // to SetJavaVM() before. This will pass the same |java_vm| value to the
136 // callback, if it is present in the library.
137 void CallJniOnUnload();
139 // Helper class to iterate over dependencies in a given SharedLibrary.
141 // SharedLibary::DependencyIterator iter(lib);
142 // while (iter.GetNext() {
143 // dependency_name = iter.GetName();
146 class DependencyIterator {
148 DependencyIterator(SharedLibrary* lib)
149 : iter_(&lib->view_), symbols_(&lib->symbols_), dep_name_(NULL) {}
153 const char* GetName() const { return dep_name_; }
156 DependencyIterator();
157 DependencyIterator(const DependencyIterator&);
158 DependencyIterator& operator=(const DependencyIterator&);
160 ElfView::DynamicIterator iter_;
161 const ElfSymbols* symbols_;
162 const char* dep_name_;
165 typedef void (*linker_function_t)();
168 friend class LibraryList;
173 ELF::Addr relro_start_;
174 ELF::Addr relro_size_;
177 SharedLibrary* list_next_;
178 SharedLibrary* list_prev_;
181 linker_function_t* preinit_array_;
182 size_t preinit_array_count_;
183 linker_function_t* init_array_;
184 size_t init_array_count_;
185 linker_function_t* fini_array_;
186 size_t fini_array_count_;
187 linker_function_t init_func_;
188 linker_function_t fini_func_;
191 // ARM EABI section used for stack unwinding.
192 unsigned* arm_exidx_;
193 size_t arm_exidx_count_;
196 #if defined(__arm__) || defined(__aarch64__)
197 // Packed relocations data, NULL if absent.
198 uint8_t* packed_relocations_;
201 link_map_t link_map_;
203 bool has_DT_SYMBOLIC_;
207 const char* base_name_;
208 char full_path_[512];
213 #endif // CRAZY_LINKER_SHARED_LIBRARY_H