Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: base/android/linker/crazy_linker/include/crazy_linker.h

Issue 23717023: Android: Add chrome-specific dynamic linker. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rename library Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 #ifndef CRAZY_LINKER_H
5 #define CRAZY_LINKER_H
6
7 // This is the crazy linker, a custom dynamic linker that can be used
8 // by NDK applications to load shared libraries (not executables) with
9 // a twist.
10 //
11 // Compared to the dynamic linker, the crazy one has the following
12 // features:
13 //
14 // - It can use an arbitrary search path.
15 //
16 // - It can load a library at a memory fixed address.
17 //
18 // - It can share the RELRO section between two libraries
19 // loaded at the same address in two distinct processes.
20 //
21 #include <dlfcn.h>
22 #include <stddef.h>
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 // Function attribute to indicate that it needs to be exported by
29 // the library.
30 #define _CRAZY_PUBLIC __attribute__((__visibility__("default")))
31
32 // Status values returned by crazy linker functions to indicate
33 // success or failure. They were chosen to match boolean values,
34 // this allows one to test for failures with:
35 //
36 // if (!crazy_linker_function(....)) {
37 // ... an error occured.
38 // }
39 //
40 // If the function called used a crazy_context_t, it is possible to
41 // retrieve the error details with crazy_context_get_error().
42 typedef enum {
43 CRAZY_STATUS_KO = 0,
44 CRAZY_STATUS_OK = 1
45 } crazy_status_t;
46
47 // Opaque handle to a context object that will hold parameters
48 // for the crazy linker's operations. For example, this is where
49 // you would set the explicit load address, and other user-provided
50 // values before calling functions like crazy_linker_load().
51 //
52 // The context holds a list of library search paths, initialized to
53 // the content of the LD_LIBRARY_PATH variable on creation.
54 //
55 // The context also holds a string buffer to hold error messages that
56 // can be queried with crazy_context_get_error().
57 typedef struct crazy_context_t crazy_context_t;
58
59 // Create a new context object.
60 crazy_context_t* crazy_context_create(void) _CRAZY_PUBLIC;
61
62 // Return current error string, or NULL if there was no error.
63 const char* crazy_context_get_error(crazy_context_t* context)
64 _CRAZY_PUBLIC;
65
66 // Clear error in a given context.
67 void crazy_context_clear_error(crazy_context_t* context)
68 _CRAZY_PUBLIC;
69
70 // Set the explicit load address in a context object. Value 0 means
71 // the address is randomized.
72 void crazy_context_set_load_address(crazy_context_t* context,
73 size_t load_address) _CRAZY_PUBLIC;
74
75 // Return the current load address in a context.
76 size_t crazy_context_get_load_address(crazy_context_t* context)
77 _CRAZY_PUBLIC;
78
79 // Set the explicit file offset in a context object. The value should
80 // always page-aligned, or the load will fail.
81 void crazy_context_set_file_offset(crazy_context_t* context,
82 size_t file_offset) _CRAZY_PUBLIC;
83
84 // Return the current file offset in a context object.
85 size_t crazy_context_get_file_offset(crazy_context_t* context);
86
87 // Add one or more paths to the list of library search paths held
88 // by a given context. |path| is a string using a column (:) as a
89 // list separator. As with the PATH variable, an empty list item
90 // is equivalent to '.', the current directory.
91 // This can fail if too many paths are added to the context.
92 crazy_status_t crazy_context_add_search_path(crazy_context_t* context,
93 const char* file_path)
94 _CRAZY_PUBLIC;
95
96 // Find the ELF binary that contains |address|, and add its directory
97 // path to the context's list of search directories. This is useful to
98 // load libraries in the same directory than the current program itself.
99 crazy_status_t crazy_context_add_search_path_for_address(
100 crazy_context_t* context,
101 void* address) _CRAZY_PUBLIC;
102
103 // Reset the search paths to the value of the LD_LIBRARY_PATH
104 // environment variable.
105 void crazy_context_reset_search_paths(crazy_context_t* context)
106 _CRAZY_PUBLIC;
107
108 // Destroy a given context object.
109 void crazy_context_destroy(crazy_context_t* context) _CRAZY_PUBLIC;
110
111 // Opaque handle to a library as seen/loaded by the crazy linker.
112 typedef struct crazy_library_t crazy_library_t;
113
114 // Try to open or load a library with the crazy linker.
115 // |lib_name| if the library name or path. If it contains a directory
116 // separator (/), this is treated as a explicit file path, otherwise
117 // it is treated as a base name, and the context's search path list
118 // will be used to locate the corresponding file.
119 // |context| is a linker context handle. Can be NULL for defaults.
120 // On success, return CRAZY_STATUS_OK and sets |*library|.
121 // Libraries are reference-counted, trying to open the same library
122 // twice will return the same library handle.
123 //
124 // NOTE: The load address and file offset from the context only apply
125 // to the library being loaded (when not already in the process). If the
126 // operations needs to load any dependency libraries, these will use
127 // offset and address values of 0 to do so.
128 //
129 // NOTE: It is possible to open system libraries (e.g. "libc.so")
130 // with this function. If the library is already in the process,
131 // a proper crazy_library_t handle will be returned for it. If the
132 // system library is not loaded yet, it will be loaded through
133 // dlopen() instead of the crazy linker.
134 crazy_status_t crazy_library_open(crazy_library_t** library,
135 const char* lib_name,
136 crazy_context_t* context)
137 _CRAZY_PUBLIC;
138
139 // A structure used to hold information about a given library.
140 // |load_address| is the library's actual (page-aligned) load address.
141 // |load_size| is the library's actual (page-aligned) size.
142 // |relro_start| is the address of the library's RELRO section in memory.
143 // |relso_size| is the size of the library's RELRO section (or 0 if none).
144 // |relro_fd| is the ashmem file descriptor for the shared section, or -1.
145 typedef struct {
146 size_t load_address;
147 size_t load_size;
148 size_t relro_start;
149 size_t relro_size;
150 int relro_fd;
151 } crazy_library_info_t;
152
153 // Retrieve information about a given library.
154 // |library| is a library handle.
155 // |context| will get an error message on failure.
156 // On success, return true and sets |*info|.
157 // Note that this function will fail for system libraries.
158 crazy_status_t crazy_library_get_info(crazy_library_t* library,
159 crazy_context_t* context,
160 crazy_library_info_t* info);
161
162
163 // Enable RELRO section sharing for this library. This can only be
164 // called once per library loaded through crazy_library_open(), and
165 // will only work for non-system libraries.
166 // On success, return CRAZY_STATUS_OK and sets |*library_info| with
167 // all relevant data. On failure, return CRAZY_STATUS_KO and sets
168 // the error message in |context|.
169 crazy_status_t crazy_library_enable_relro_sharing(
170 crazy_library_t* library,
171 crazy_context_t* context) _CRAZY_PUBLIC;
172
173 // Use the shared RELRO section of the same library loaded in a different
174 // address space. On success, return CRAZY_STATUS_OK and owns |relro_fd|.
175 // On failure, return CRAZY_STATUS_KO and sets error message in |context|.
176 // |library| is the library handle.
177 // |relro_start| is the address of the RELRO section in memory.
178 // |relro_size| is the size of the RELRO section.
179 // |relro_fd| is the file descriptor for the shared RELRO ashmem region.
180 // |context| will receive an error in case of failure.
181 // NOTE: This will fail if this is a system library, or if the RELRO
182 // parameters do not match the library's actual load address.
183 crazy_status_t crazy_library_use_relro_sharing(
184 crazy_library_t* library,
185 size_t relro_start,
186 size_t relro_size,
187 int relro_fd,
188 crazy_context_t* context) _CRAZY_PUBLIC;
189
190 // Look for a library named |library_name| in the set of currently
191 // loaded libraries, and return a handle for it in |*library| on success.
192 // Note that this increments the reference count on the library, thus
193 // the caller shall call crazy_library_close() when it's done with it.
194 crazy_status_t crazy_library_find_by_name(const char* library_name,
195 crazy_library_t** library);
196
197 // Find the library that contains a given |address| in memory.
198 // On success, return CRAZY_STATUS_OK and sets |*library|.
199 crazy_status_t crazy_linker_find_library_from_address(
200 void* address, crazy_library_t** library) _CRAZY_PUBLIC;
201
202 // Lookup a symbol's address by its |symbol_name| in a given library.
203 // This only looks at the symbols in |library|.
204 // On success, returns CRAZY_STATUS_OK and sets |*symbol_address|,
205 // which could be NULL for some symbols.
206 crazy_status_t crazy_library_find_symbol(
207 crazy_library_t* library,
208 const char* symbol_name,
209 void** symbol_address) _CRAZY_PUBLIC;
210
211 // Lookup a symbol's address in all libraries known by the crazy linker.
212 // |symbol_name| is the symbol name. On success, returns CRAZY_STATUS_OK
213 // and sets |*symbol_address|.
214 // NOTE: This will _not_ look into system libraries that were not opened
215 // with the crazy linker.
216 crazy_status_t crazy_linker_find_symbol(
217 const char* symbol_name,
218 void** symbol_address) _CRAZY_PUBLIC;
219
220 // Find the in-process library that contains a given memory address.
221 // Note that this works even if the memory is inside a system library that
222 // was not previously opened with crazy_library_open().
223 // |address| is the memory address.
224 // On success, returns CRAZY_STATUS_OK and sets |*library|.
225 // The caller muyst call crazy_library_close() once it's done with the
226 // library.
227 crazy_status_t crazy_library_find_from_address(
228 void* address, crazy_library_t** library) _CRAZY_PUBLIC;
229
230 // Close a library. This decrements its reference count. If it reaches
231 // zero, the library be unloaded from the process.
232 void crazy_library_close(crazy_library_t* library) _CRAZY_PUBLIC;
233
234 #ifdef __cplusplus
235 } /* extern "C" */
236 #endif
237
238 #endif /* CRAZY_LINKER_H */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698