Index: third_party/crazy_linker/crazy_linker/src/crazy_linker_shared_library.h |
diff --git a/third_party/crazy_linker/crazy_linker/src/crazy_linker_shared_library.h b/third_party/crazy_linker/crazy_linker/src/crazy_linker_shared_library.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..18299b5a1d78284fbe6d5b086958b21559beabc8 |
--- /dev/null |
+++ b/third_party/crazy_linker/crazy_linker/src/crazy_linker_shared_library.h |
@@ -0,0 +1,185 @@ |
+// 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_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). |
+ |
+struct SharedLibrary { |
+ const ELF::Phdr* phdr; |
+ size_t phnum; |
+ ELF::Addr load_bias; |
+ |
+ ELF::Addr entry; |
+ ELF::Addr base; |
+ size_t size; |
+ |
+ ELF::Dyn* dynamic; |
+ size_t dynamic_count; |
+ ELF::Word dynamic_flags; |
+ |
+ SharedLibrary* list_next; |
+ SharedLibrary* list_prev; |
+ unsigned flags; |
+ |
+ const char* strtab; |
+ ELF::Sym* symtab; |
+ |
+ size_t nbucket; |
+ size_t nchain; |
+ unsigned* bucket; |
+ unsigned* chain; |
+ |
+ typedef void (*linker_function_t)(); |
+ |
+ 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; |
+ |
+ size_t relro_start; |
+ size_t relro_size; |
+ int relro_fd; |
+ |
+ const char* base_name; |
+ char full_path[512]; |
+ |
+ SharedLibrary(); |
+ ~SharedLibrary(); |
+ |
+ // 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); |
+ |
+ // 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. |
+ ELF::Sym* LookupSymbolEntry(const char* symbol_name); |
+ |
+ // Return the address of a given |symbol_name| if it is exported |
+ // by the library, NULL otherwise. |
+ void* FindAddressForSymbol(const char* symbol_name); |
+ |
+ // Find the symbol entry in this library that matches a given |
+ // address in memory. Returns NULL on failure. |
+ ELF::Sym* FindSymbolForAddress(void* address); |
+ |
+ // Prepare the relro section for sharing with another process. |
+ // On success, return true and sets relro_fd to an ashmem file |
+ // descriptor holding the shared RELRO section. On failure |
+ // return false ands sets |error| message. |
+ bool EnableSharedRelro(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); |
+ |
+ // 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) |
+ : dynamic_(lib->dynamic), |
+ strtab_(lib->strtab), |
+ dep_name_(NULL) {} |
+ |
+ bool GetNext() { |
+ dep_name_ = NULL; |
bulach
2013/09/09 16:14:15
nit: maybe move this to the .cc file?
I think for
digit1
2013/09/10 09:23:30
Done.
|
+ for (;;) { |
+ if (dynamic_->d_tag == 0) |
+ return false; |
+ |
+ if (dynamic_->d_tag != DT_NEEDED) { |
+ dynamic_ ++; |
bulach
2013/09/09 16:14:15
nit: remove space after dynamic here and 164
digit1
2013/09/10 09:23:30
Done.
|
+ continue; |
+ } |
+ |
+ dep_name_ = strtab_ + dynamic_->d_un.d_val; |
+ dynamic_ ++; |
+ return true; |
+ } |
+ } |
+ |
+ const char* GetName() const { return dep_name_; } |
+ |
+ private: |
+ DependencyIterator(); |
+ DependencyIterator(const DependencyIterator&); |
+ DependencyIterator& operator=(const DependencyIterator&); |
+ |
+ ELF::Dyn* dynamic_; |
+ const char* strtab_; |
+ const char* dep_name_; |
+ }; |
+ |
+}; |
+ |
+} // namespace crazy |
+ |
+#endif // CRAZY_LINKER_SHARED_LIBRARY_H |