Index: third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h |
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8ce381e915a667b4ce94a27db84fb7dde1dc08a1 |
--- /dev/null |
+++ b/third_party/android_crazy_linker/src/src/crazy_linker_shared_library.h |
@@ -0,0 +1,208 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CRAZY_LINKER_SHARED_LIBRARY_H |
+#define CRAZY_LINKER_SHARED_LIBRARY_H |
+ |
+#include <link.h> |
+ |
+#include "crazy_linker_elf_relro.h" |
+#include "crazy_linker_elf_symbols.h" |
+#include "crazy_linker_elf_view.h" |
+#include "crazy_linker_error.h" |
+#include "crazy_linker_rdebug.h" |
+#include "crazy_linker_util.h" |
+#include "elf_traits.h" |
+ |
+namespace crazy { |
+ |
+class LibraryList; |
+class LibraryView; |
+ |
+// A class that models a shared library loaded by the crazy linker. |
+ |
+// Libraries have dependencies (which are listed in their dynamic section |
+// as DT_NEEDED entries). Circular dependencies are forbidden, so they |
+// form an ADG, where the root is the crazy linker itself, since all |
+// libraries that it loads will depend on it (to ensure their |
+// dlopen/dlsym/dlclose calls are properly wrapped). |
+ |
+class SharedLibrary { |
+ public: |
+ SharedLibrary(); |
+ ~SharedLibrary(); |
+ |
+ size_t load_address() const { return view_.load_address(); } |
+ size_t load_size() const { return view_.load_size(); } |
+ size_t load_bias() const { return view_.load_bias(); } |
+ const ELF::Phdr* phdr() const { return view_.phdr(); } |
+ size_t phdr_count() const { return view_.phdr_count(); } |
+ const char* base_name() const { return base_name_; } |
+ |
+ // Load a library (without its dependents) from an ELF file. |
+ // Note: This does not apply relocations, nor runs constructors. |
+ // |full_path| if the file full path. |
+ // |load_address| is the page-aligned load address in memory, or 0. |
+ // |file_offset| is the page-aligned file offset. |
+ // On failure, return false and set |error| message. |
+ // |
+ // After this, the caller should load all library dependencies, |
+ // Then call Relocate() and CallConstructors() to complete the |
+ // operation. |
+ bool Load(const char* full_path, |
+ size_t load_address, |
+ size_t file_offset, |
+ Error* error); |
+ |
+ // Relocate this library, assuming all its dependencies are already |
+ // loaded in |lib_list|. On failure, return false and set |error| |
+ // message. |
+ bool Relocate(LibraryList* lib_list, |
+ Vector<LibraryView*>* dependencies, |
+ Error* error); |
+ |
+ void GetInfo(size_t* load_address, |
+ size_t* load_size, |
+ size_t* relro_start, |
+ size_t* relro_size) { |
+ *load_address = view_.load_address(); |
+ *load_size = view_.load_size(); |
+ *relro_start = relro_start_; |
+ *relro_size = relro_size_; |
+ } |
+ |
+ // Returns true iff a given library is mapped to a virtual address range |
+ // that contains a given address. |
+ bool ContainsAddress(void* address) const { |
+ size_t addr = reinterpret_cast<size_t>(address); |
+ return load_address() <= addr && addr <= load_address() + load_size(); |
+ } |
+ |
+ // Call all constructors in the library. |
+ void CallConstructors(); |
+ |
+ // Call all destructors in the library. |
+ void CallDestructors(); |
+ |
+ // Return the ELF symbol entry for a given symbol, if defined by |
+ // this library, or NULL otherwise. |
+ const ELF::Sym* LookupSymbolEntry(const char* symbol_name); |
+ |
+ // Find the nearest symbol near a given |address|. On success, return |
+ // true and set |*sym_name| to the symbol name, |*sym_addr| to its address |
+ // in memory, and |*sym_size| to its size in bytes, if any. |
+ bool FindNearestSymbolForAddress(void* address, |
+ const char** sym_name, |
+ void** sym_addr, |
+ size_t* sym_size) { |
+ return symbols_.LookupNearestByAddress( |
+ address, load_bias(), sym_name, sym_addr, sym_size); |
+ } |
+ |
+ // Return the address of a given |symbol_name| if it is exported |
+ // by the library, NULL otherwise. |
+ void* FindAddressForSymbol(const char* symbol_name); |
+ |
+ // Create a new Ashmem region holding a copy of the library's RELRO section, |
+ // potentially relocated for a new |load_address|. On success, return true |
+ // and sets |*relro_start|, |*relro_size| and |*relro_fd|. Note that the |
+ // RELRO start address is adjusted for |load_address|, and that the caller |
+ // becomes the owner of |*relro_fd|. On failure, return false and set |
+ // |error| message. |
+ bool CreateSharedRelro(size_t load_address, |
+ size_t* relro_start, |
+ size_t* relro_size, |
+ int* relro_fd, |
+ Error* error); |
+ |
+ // Try to use a shared relro section from another process. |
+ // On success, return true. On failure return false and |
+ // sets |error| message. |
+ bool UseSharedRelro(size_t relro_start, |
+ size_t relro_size, |
+ int relro_fd, |
+ Error* error); |
+ |
+ // Look for a symbol named 'JNI_OnLoad' in this library, and if it |
+ // exists, call it with |java_vm| as the first parameter. If the |
+ // function result is less than |minimum_jni_version|, fail with |
+ // a message in |error|. On success, return true, and record |
+ // |java_vm| to call 'JNI_OnUnload' at unload time, if present. |
+ bool SetJavaVM(void* java_vm, int minimum_jni_version, Error* error); |
+ |
+ // Call 'JNI_OnUnload()' is necessary, i.e. if there was a succesful call |
+ // to SetJavaVM() before. This will pass the same |java_vm| value to the |
+ // callback, if it is present in the library. |
+ void CallJniOnUnload(); |
+ |
+ // Helper class to iterate over dependencies in a given SharedLibrary. |
+ // Usage: |
+ // SharedLibary::DependencyIterator iter(lib); |
+ // while (iter.GetNext() { |
+ // dependency_name = iter.GetName(); |
+ // ... |
+ // } |
+ class DependencyIterator { |
+ public: |
+ DependencyIterator(SharedLibrary* lib) |
+ : iter_(&lib->view_), symbols_(&lib->symbols_), dep_name_(NULL) {} |
+ |
+ bool GetNext(); |
+ |
+ const char* GetName() const { return dep_name_; } |
+ |
+ private: |
+ DependencyIterator(); |
+ DependencyIterator(const DependencyIterator&); |
+ DependencyIterator& operator=(const DependencyIterator&); |
+ |
+ ElfView::DynamicIterator iter_; |
+ const ElfSymbols* symbols_; |
+ const char* dep_name_; |
+ }; |
+ |
+ typedef void (*linker_function_t)(); |
+ |
+ private: |
+ friend class LibraryList; |
+ |
+ ElfView view_; |
+ ElfSymbols symbols_; |
+ |
+ size_t relro_start_; |
+ size_t relro_size_; |
+ bool relro_used_; |
+ |
+ SharedLibrary* list_next_; |
+ SharedLibrary* list_prev_; |
+ unsigned flags_; |
+ |
+ linker_function_t* preinit_array_; |
+ size_t preinit_array_count_; |
+ linker_function_t* init_array_; |
+ size_t init_array_count_; |
+ linker_function_t* fini_array_; |
+ size_t fini_array_count_; |
+ linker_function_t init_func_; |
+ linker_function_t fini_func_; |
+ |
+#ifdef __arm__ |
+ // ARM EABI section used for stack unwinding. |
+ unsigned* arm_exidx_; |
+ size_t arm_exidx_count_; |
+#endif |
+ |
+ link_map_t link_map_; |
+ |
+ bool has_DT_SYMBOLIC_; |
+ |
+ void* java_vm_; |
+ |
+ const char* base_name_; |
+ char full_path_[512]; |
+}; |
+ |
+} // namespace crazy |
+ |
+#endif // CRAZY_LINKER_SHARED_LIBRARY_H |