Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / android_crazy_linker / src / src / crazy_linker_shared_library.h
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.
4
5 #ifndef CRAZY_LINKER_SHARED_LIBRARY_H
6 #define CRAZY_LINKER_SHARED_LIBRARY_H
7
8 #include <link.h>
9
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"
17
18 namespace crazy {
19
20 class LibraryList;
21 class LibraryView;
22
23 // A class that models a shared library loaded by the crazy linker.
24
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).
30
31 class SharedLibrary {
32  public:
33   SharedLibrary();
34   ~SharedLibrary();
35
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_; }
42
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
50   // enabled.
51   // On failure, return false and set |error| message.
52   //
53   // After this, the caller should load all library dependencies,
54   // Then call Relocate() and CallConstructors() to complete the
55   // operation.
56   bool Load(const char* full_path,
57             size_t load_address,
58             size_t file_offset,
59             bool no_map_exec_support_fallback_enabled,
60             Error* error);
61
62   // Relocate this library, assuming all its dependencies are already
63   // loaded in |lib_list|. On failure, return false and set |error|
64   // message.
65   bool Relocate(LibraryList* lib_list,
66                 Vector<LibraryView*>* dependencies,
67                 Error* error);
68
69   void GetInfo(size_t* load_address,
70                size_t* load_size,
71                size_t* relro_start,
72                size_t* relro_size) {
73     *load_address = view_.load_address();
74     *load_size = view_.load_size();
75     *relro_start = relro_start_;
76     *relro_size = relro_size_;
77   }
78
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();
84   }
85
86   // Call all constructors in the library.
87   void CallConstructors();
88
89   // Call all destructors in the library.
90   void CallDestructors();
91
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);
95
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,
101                                    void** sym_addr,
102                                    size_t* sym_size) {
103     return symbols_.LookupNearestByAddress(
104         address, load_bias(), sym_name, sym_addr, sym_size);
105   }
106
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);
110
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
116   // |error| message.
117   bool CreateSharedRelro(size_t load_address,
118                          size_t* relro_start,
119                          size_t* relro_size,
120                          int* relro_fd,
121                          Error* error);
122
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,
127                       size_t relro_size,
128                       int relro_fd,
129                       Error* error);
130
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);
137
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();
142
143   // Helper class to iterate over dependencies in a given SharedLibrary.
144   // Usage:
145   //    SharedLibary::DependencyIterator iter(lib);
146   //    while (iter.GetNext() {
147   //      dependency_name = iter.GetName();
148   //      ...
149   //    }
150   class DependencyIterator {
151    public:
152     DependencyIterator(SharedLibrary* lib)
153         : iter_(&lib->view_), symbols_(&lib->symbols_), dep_name_(NULL) {}
154
155     bool GetNext();
156
157     const char* GetName() const { return dep_name_; }
158
159    private:
160     DependencyIterator();
161     DependencyIterator(const DependencyIterator&);
162     DependencyIterator& operator=(const DependencyIterator&);
163
164     ElfView::DynamicIterator iter_;
165     const ElfSymbols* symbols_;
166     const char* dep_name_;
167   };
168
169   typedef void (*linker_function_t)();
170
171  private:
172   friend class LibraryList;
173
174   ElfView view_;
175   ElfSymbols symbols_;
176
177   ELF::Addr relro_start_;
178   ELF::Addr relro_size_;
179   bool relro_used_;
180
181   SharedLibrary* list_next_;
182   SharedLibrary* list_prev_;
183   unsigned flags_;
184
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_;
193
194 #ifdef __arm__
195   // ARM EABI section used for stack unwinding.
196   unsigned* arm_exidx_;
197   size_t arm_exidx_count_;
198 #endif
199
200 #if defined(__arm__) || defined(__aarch64__)
201   // Packed relocations data, NULL if absent.
202   uint8_t* packed_relocations_;
203 #endif
204
205   link_map_t link_map_;
206
207   bool has_DT_SYMBOLIC_;
208
209   void* java_vm_;
210
211   const char* base_name_;
212   char full_path_[512];
213 };
214
215 }  // namespace crazy
216
217 #endif  // CRAZY_LINKER_SHARED_LIBRARY_H