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

Side by Side Diff: base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java

Issue 1641513004: Update //base to chromium 9659b08ea5a34f889dc4166217f438095ddc10d2 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 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 2015 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 package org.chromium.base.library_loader;
6
7 import android.os.Bundle;
8 import android.os.Parcel;
9
10 import org.chromium.base.CalledByNative;
11 import org.chromium.base.Log;
12 import org.chromium.base.SysUtils;
13 import org.chromium.base.ThreadUtils;
14
15 import java.util.HashMap;
16 import java.util.Locale;
17 import java.util.Map;
18
19 import javax.annotation.Nullable;
20
21 /*
22 * For more, see Technical note, Security considerations, and the explanation
23 * of how this class is supposed to be used in Linker.java.
24 */
25
26 /**
27 * Provides a concrete implementation of the Chromium Linker.
28 *
29 * This Linker implementation uses the crazy linker to map and then run Chrome
30 * for Android.
31 *
32 * For more on the operations performed by the Linker, see {@link Linker}.
33 */
34 class LegacyLinker extends Linker {
35 // Log tag for this class.
36 private static final String TAG = "cr.library_loader";
37
38 // Name of the library that contains our JNI code.
39 private static final String LINKER_JNI_LIBRARY = "chromium_android_linker";
40
41 // Becomes true after linker initialization.
42 private boolean mInitialized = false;
43
44 // Set to true to indicate that the system supports safe sharing of RELRO se ctions.
45 private boolean mRelroSharingSupported = false;
46
47 // Set to true if this runs in the browser process. Disabled by initServiceP rocess().
48 // TODO(petrcermak): This flag can be incorrectly set to false (even though this might run in
49 // the browser process) on low-memory devices.
50 private boolean mInBrowserProcess = true;
51
52 // Becomes true to indicate this process needs to wait for a shared RELRO in
53 // finishLibraryLoad().
54 private boolean mWaitForSharedRelros = false;
55
56 // Becomes true when initialization determines that the browser process can use the
57 // shared RELRO.
58 private boolean mBrowserUsesSharedRelro = false;
59
60 // The map of all RELRO sections either created or used in this process.
61 private Bundle mSharedRelros = null;
62
63 // Current common random base load address.
64 private long mBaseLoadAddress = 0;
65
66 // Current fixed-location load address for the next library called by loadLi brary().
67 private long mCurrentLoadAddress = 0;
68
69 // Becomes true once prepareLibraryLoad() has been called.
70 private boolean mPrepareLibraryLoadCalled = false;
71
72 // The map of libraries that are currently loaded in this process.
73 protected HashMap<String, LibInfo> mLoadedLibraries = null;
74
75 // Used internally to initialize the linker's static data. Assume lock is he ld.
76 private void ensureInitializedLocked() {
77 assert Thread.holdsLock(mLock);
78
79 if (mInitialized) {
80 return;
81 }
82
83 mRelroSharingSupported = false;
84 if (NativeLibraries.sUseLinker) {
85 if (DEBUG) {
86 Log.i(TAG, "Loading lib" + LINKER_JNI_LIBRARY + ".so");
87 }
88 try {
89 System.loadLibrary(LINKER_JNI_LIBRARY);
90 } catch (UnsatisfiedLinkError e) {
91 // In a component build, the ".cr" suffix is added to each libra ry name.
92 Log.w(TAG, "Couldn't load lib" + LINKER_JNI_LIBRARY + ".so, "
93 + "trying lib" + LINKER_JNI_LIBRARY + ".cr.so");
94 System.loadLibrary(LINKER_JNI_LIBRARY + ".cr");
95 }
96 mRelroSharingSupported = nativeCanUseSharedRelro();
97 if (!mRelroSharingSupported) {
98 Log.w(TAG, "This system cannot safely share RELRO sections");
99 } else {
100 if (DEBUG) {
101 Log.i(TAG, "This system supports safe shared RELRO sections" );
102 }
103 }
104
105 if (mMemoryDeviceConfig == MEMORY_DEVICE_CONFIG_INIT) {
106 if (SysUtils.isLowEndDevice()) {
107 mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_LOW;
108 } else {
109 mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_NORMAL;
110 }
111 }
112
113 switch (BROWSER_SHARED_RELRO_CONFIG) {
114 case BROWSER_SHARED_RELRO_CONFIG_NEVER:
115 mBrowserUsesSharedRelro = false;
116 break;
117 case BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY:
118 if (mMemoryDeviceConfig == MEMORY_DEVICE_CONFIG_LOW) {
119 mBrowserUsesSharedRelro = true;
120 Log.w(TAG, "Low-memory device: shared RELROs used in all processes");
121 } else {
122 mBrowserUsesSharedRelro = false;
123 }
124 break;
125 case BROWSER_SHARED_RELRO_CONFIG_ALWAYS:
126 Log.w(TAG, "Beware: shared RELROs used in all processes!");
127 mBrowserUsesSharedRelro = true;
128 break;
129 default:
130 assert false : "Unreached";
131 break;
132 }
133 } else {
134 if (DEBUG) {
135 Log.i(TAG, "Linker disabled");
136 }
137 }
138
139 if (!mRelroSharingSupported) {
140 // Sanity.
141 mBrowserUsesSharedRelro = false;
142 mWaitForSharedRelros = false;
143 }
144
145 mInitialized = true;
146 }
147
148 /**
149 * Call this method to determine if this chromium project must
150 * use this linker. If not, System.loadLibrary() should be used to load
151 * libraries instead.
152 */
153 @Override
154 public boolean isUsed() {
155 // Only GYP targets that are APKs and have the 'use_chromium_linker' var iable
156 // defined as 1 will use this linker. For all others (the default), the
157 // auto-generated NativeLibraries.sUseLinker variable will be false.
158 if (!NativeLibraries.sUseLinker) return false;
159
160 synchronized (mLock) {
161 ensureInitializedLocked();
162 // At the moment, there is also no point in using this linker if the
163 // system does not support RELRO sharing safely.
164 return mRelroSharingSupported;
165 }
166 }
167
168 /**
169 * Call this method to determine if the linker will try to use shared RELROs
170 * for the browser process.
171 */
172 @Override
173 public boolean isUsingBrowserSharedRelros() {
174 synchronized (mLock) {
175 ensureInitializedLocked();
176 return mBrowserUsesSharedRelro;
177 }
178 }
179
180 /**
181 * Call this method to determine if the chromium project must load
182 * the library directly from the zip file.
183 */
184 @Override
185 public boolean isInZipFile() {
186 return NativeLibraries.sUseLibraryInZipFile;
187 }
188
189 /**
190 * Call this method just before loading any native shared libraries in this process.
191 */
192 @Override
193 public void prepareLibraryLoad() {
194 if (DEBUG) {
195 Log.i(TAG, "prepareLibraryLoad() called");
196 }
197 synchronized (mLock) {
198 mPrepareLibraryLoadCalled = true;
199
200 if (mInBrowserProcess) {
201 // Force generation of random base load address, as well
202 // as creation of shared RELRO sections in this process.
203 setupBaseLoadAddressLocked();
204 }
205 }
206 }
207
208 /**
209 * Call this method just after loading all native shared libraries in this p rocess.
210 * Note that when in a service process, this will block until the RELRO bund le is
211 * received, i.e. when another thread calls useSharedRelros().
212 */
213 @Override
214 public void finishLibraryLoad() {
215 if (DEBUG) {
216 Log.i(TAG, "finishLibraryLoad() called");
217 }
218 synchronized (mLock) {
219 if (DEBUG) {
220 Log.i(TAG,
221 String.format(Locale.US,
222 "mInBrowserProcess=%s mBrowserUsesSharedRelro=%s mWaitForSharedRelros=%s",
223 mInBrowserProcess ? "true" : "false",
224 mBrowserUsesSharedRelro ? "true" : "false",
225 mWaitForSharedRelros ? "true" : "false"));
226 }
227
228 if (mLoadedLibraries == null) {
229 if (DEBUG) {
230 Log.i(TAG, "No libraries loaded");
231 }
232 } else {
233 if (mInBrowserProcess) {
234 // Create new Bundle containing RELRO section information
235 // for all loaded libraries. Make it available to getSharedR elros().
236 mSharedRelros = createBundleFromLibInfoMap(mLoadedLibraries) ;
237 if (DEBUG) {
238 Log.i(TAG, "Shared RELRO created");
239 dumpBundle(mSharedRelros);
240 }
241
242 if (mBrowserUsesSharedRelro) {
243 useSharedRelrosLocked(mSharedRelros);
244 }
245 }
246
247 if (mWaitForSharedRelros) {
248 assert !mInBrowserProcess;
249
250 // Wait until the shared relro bundle is received from useSh aredRelros().
251 while (mSharedRelros == null) {
252 try {
253 mLock.wait();
254 } catch (InterruptedException ie) {
255 // no-op
256 }
257 }
258 useSharedRelrosLocked(mSharedRelros);
259 // Clear the Bundle to ensure its file descriptor references can't be reused.
260 mSharedRelros.clear();
261 mSharedRelros = null;
262 }
263 }
264
265 if (NativeLibraries.sEnableLinkerTests && mTestRunnerClassName != nu ll) {
266 // The TestRunner implementation must be instantiated _after_
267 // all libraries are loaded to ensure that its native methods
268 // are properly registered.
269 if (DEBUG) {
270 Log.i(TAG, "Instantiating " + mTestRunnerClassName);
271 }
272 TestRunner testRunner = null;
273 try {
274 testRunner = (TestRunner) Class.forName(mTestRunnerClassName ).newInstance();
275 } catch (Exception e) {
276 Log.e(TAG, "Could not extract test runner class name", e);
277 testRunner = null;
278 }
279 if (testRunner != null) {
280 if (!testRunner.runChecks(mMemoryDeviceConfig, mInBrowserPro cess)) {
281 Log.wtf(TAG, "Linker runtime tests failed in this proces s!!");
282 assert false;
283 } else {
284 Log.i(TAG, "All linker tests passed!");
285 }
286 }
287 }
288 }
289 if (DEBUG) {
290 Log.i(TAG, "finishLibraryLoad() exiting");
291 }
292 }
293
294 /**
295 * Call this to send a Bundle containing the shared RELRO sections to be
296 * used in this process. If initServiceProcess() was previously called,
297 * finishLibraryLoad() will not exit until this method is called in another
298 * thread with a non-null value.
299 * @param bundle The Bundle instance containing a map of shared RELRO sectio ns
300 * to use in this process.
301 */
302 @Override
303 public void useSharedRelros(Bundle bundle) {
304 // Ensure the bundle uses the application's class loader, not the framew ork
305 // one which doesn't know anything about LibInfo.
306 // Also, hold a fresh copy of it so the caller can't recycle it.
307 Bundle clonedBundle = null;
308 if (bundle != null) {
309 bundle.setClassLoader(LibInfo.class.getClassLoader());
310 clonedBundle = new Bundle(LibInfo.class.getClassLoader());
311 Parcel parcel = Parcel.obtain();
312 bundle.writeToParcel(parcel, 0);
313 parcel.setDataPosition(0);
314 clonedBundle.readFromParcel(parcel);
315 parcel.recycle();
316 }
317 if (DEBUG) {
318 Log.i(TAG, "useSharedRelros() called with " + bundle + ", cloned " + clonedBundle);
319 }
320 synchronized (mLock) {
321 // Note that in certain cases, this can be called before
322 // initServiceProcess() in service processes.
323 mSharedRelros = clonedBundle;
324 // Tell any listener blocked in finishLibraryLoad() about it.
325 mLock.notifyAll();
326 }
327 }
328
329 /**
330 * Call this to retrieve the shared RELRO sections created in this process,
331 * after loading all libraries.
332 * @return a new Bundle instance, or null if RELRO sharing is disabled on
333 * this system, or if initServiceProcess() was called previously.
334 */
335 @Override
336 public Bundle getSharedRelros() {
337 if (DEBUG) {
338 Log.i(TAG, "getSharedRelros() called");
339 }
340 synchronized (mLock) {
341 if (!mInBrowserProcess) {
342 if (DEBUG) {
343 Log.i(TAG, "... returning null Bundle");
344 }
345 return null;
346 }
347
348 // Return the Bundle created in finishLibraryLoad().
349 if (DEBUG) {
350 Log.i(TAG, "... returning " + mSharedRelros);
351 }
352 return mSharedRelros;
353 }
354 }
355
356 /**
357 * Call this method before loading any libraries to indicate that this
358 * process shall neither create or reuse shared RELRO sections.
359 */
360 @Override
361 public void disableSharedRelros() {
362 if (DEBUG) {
363 Log.i(TAG, "disableSharedRelros() called");
364 }
365 synchronized (mLock) {
366 mInBrowserProcess = false;
367 mWaitForSharedRelros = false;
368 mBrowserUsesSharedRelro = false;
369 }
370 }
371
372 /**
373 * Call this method before loading any libraries to indicate that this
374 * process is ready to reuse shared RELRO sections from another one.
375 * Typically used when starting service processes.
376 * @param baseLoadAddress the base library load address to use.
377 */
378 @Override
379 public void initServiceProcess(long baseLoadAddress) {
380 if (DEBUG) {
381 Log.i(TAG,
382 String.format(Locale.US, "initServiceProcess(0x%x) called", baseLoadAddress));
383 }
384 synchronized (mLock) {
385 ensureInitializedLocked();
386 mInBrowserProcess = false;
387 mBrowserUsesSharedRelro = false;
388 if (mRelroSharingSupported) {
389 mWaitForSharedRelros = true;
390 mBaseLoadAddress = baseLoadAddress;
391 mCurrentLoadAddress = baseLoadAddress;
392 }
393 }
394 }
395
396 /**
397 * Retrieve the base load address of all shared RELRO sections.
398 * This also enforces the creation of shared RELRO sections in
399 * prepareLibraryLoad(), which can later be retrieved with getSharedRelros() .
400 * @return a common, random base load address, or 0 if RELRO sharing is
401 * disabled.
402 */
403 @Override
404 public long getBaseLoadAddress() {
405 synchronized (mLock) {
406 ensureInitializedLocked();
407 if (!mInBrowserProcess) {
408 Log.w(TAG, "Shared RELRO sections are disabled in this process!" );
409 return 0;
410 }
411
412 setupBaseLoadAddressLocked();
413 if (DEBUG) {
414 Log.i(TAG, String.format(Locale.US, "getBaseLoadAddress() return s 0x%x",
415 mBaseLoadAddress));
416 }
417 return mBaseLoadAddress;
418 }
419 }
420
421 // Used internally to lazily setup the common random base load address.
422 private void setupBaseLoadAddressLocked() {
423 assert Thread.holdsLock(mLock);
424 if (mBaseLoadAddress == 0) {
425 long address = computeRandomBaseLoadAddress();
426 mBaseLoadAddress = address;
427 mCurrentLoadAddress = address;
428 if (address == 0) {
429 // If the computed address is 0, there are issues with finding e nough
430 // free address space, so disable RELRO shared / fixed load addr esses.
431 Log.w(TAG, "Disabling shared RELROs due address space pressure") ;
432 mBrowserUsesSharedRelro = false;
433 mWaitForSharedRelros = false;
434 }
435 }
436 }
437
438 /**
439 * Compute a random base load address at which to place loaded libraries.
440 * @return new base load address, or 0 if the system does not support
441 * RELRO sharing.
442 */
443 private long computeRandomBaseLoadAddress() {
444 // nativeGetRandomBaseLoadAddress() returns an address at which it has p reviously
445 // successfully mapped an area of the given size, on the basis that we w ill be
446 // able, with high probability, to map our library into it.
447 //
448 // One issue with this is that we do not yet know the size of the librar y that
449 // we will load is. So here we pass a value that we expect will always b e larger
450 // than that needed. If it is smaller the library mapping may still succ eed. The
451 // other issue is that although highly unlikely, there is no guarantee t hat
452 // something else does not map into the area we are going to use between here and
453 // when we try to map into it.
454 //
455 // The above notes mean that all of this is probablistic. It is however okay to do
456 // because if, worst case and unlikely, we get unlucky in our choice of address,
457 // the back-out and retry without the shared RELRO in the ChildProcessSe rvice will
458 // keep things running.
459 final long maxExpectedBytes = 192 * 1024 * 1024;
460 final long address = nativeGetRandomBaseLoadAddress(maxExpectedBytes);
461 if (DEBUG) {
462 Log.i(TAG, String.format(Locale.US, "Random native base load address : 0x%x", address));
463 }
464 return address;
465 }
466
467 // Used for debugging only.
468 private void dumpBundle(Bundle bundle) {
469 if (DEBUG) {
470 Log.i(TAG, "Bundle has " + bundle.size() + " items: " + bundle);
471 }
472 }
473
474 /**
475 * Use the shared RELRO section from a Bundle received form another process.
476 * Call this after calling setBaseLoadAddress() then loading all libraries
477 * with loadLibrary().
478 * @param bundle Bundle instance generated with createSharedRelroBundle() in
479 * another process.
480 */
481 private void useSharedRelrosLocked(Bundle bundle) {
482 assert Thread.holdsLock(mLock);
483
484 if (DEBUG) {
485 Log.i(TAG, "Linker.useSharedRelrosLocked() called");
486 }
487
488 if (bundle == null) {
489 if (DEBUG) {
490 Log.i(TAG, "null bundle!");
491 }
492 return;
493 }
494
495 if (!mRelroSharingSupported) {
496 if (DEBUG) {
497 Log.i(TAG, "System does not support RELRO sharing");
498 }
499 return;
500 }
501
502 if (mLoadedLibraries == null) {
503 if (DEBUG) {
504 Log.i(TAG, "No libraries loaded!");
505 }
506 return;
507 }
508
509 if (DEBUG) {
510 dumpBundle(bundle);
511 }
512 HashMap<String, LibInfo> relroMap = createLibInfoMapFromBundle(bundle);
513
514 // Apply the RELRO section to all libraries that were already loaded.
515 for (Map.Entry<String, LibInfo> entry : relroMap.entrySet()) {
516 String libName = entry.getKey();
517 LibInfo libInfo = entry.getValue();
518 if (!nativeUseSharedRelro(libName, libInfo)) {
519 Log.w(TAG, "Could not use shared RELRO section for " + libName);
520 } else {
521 if (DEBUG) {
522 Log.i(TAG, "Using shared RELRO section for " + libName);
523 }
524 }
525 }
526
527 // In service processes, close all file descriptors from the map now.
528 if (!mInBrowserProcess) closeLibInfoMap(relroMap);
529
530 if (DEBUG) {
531 Log.i(TAG, "Linker.useSharedRelrosLocked() exiting");
532 }
533 }
534
535 /**
536 * Load a native shared library with the Chromium linker. If the zip file
537 * is not null, the shared library must be uncompressed and page aligned
538 * inside the zipfile. Note the crazy linker treats libraries and files as
539 * equivalent, so you can only open one library in a given zip file. The
540 * library must not be the Chromium linker library.
541 *
542 * @param zipFilePath The path of the zip file containing the library (or nu ll).
543 * @param libFilePath The path of the library (possibly in the zip file).
544 */
545 @Override
546 public void loadLibrary(@Nullable String zipFilePath, String libFilePath) {
547 if (DEBUG) {
548 Log.i(TAG, "loadLibrary: " + zipFilePath + ", " + libFilePath);
549 }
550
551 synchronized (mLock) {
552 ensureInitializedLocked();
553
554 // Security: Ensure prepareLibraryLoad() was called before.
555 // In theory, this can be done lazily here, but it's more consistent
556 // to use a pair of functions (i.e. prepareLibraryLoad() + finishLib raryLoad())
557 // that wrap all calls to loadLibrary() in the library loader.
558 assert mPrepareLibraryLoadCalled;
559
560 if (mLoadedLibraries == null) {
561 mLoadedLibraries = new HashMap<String, LibInfo>();
562 }
563
564 if (mLoadedLibraries.containsKey(libFilePath)) {
565 if (DEBUG) {
566 Log.i(TAG, "Not loading " + libFilePath + " twice");
567 }
568 return;
569 }
570
571 LibInfo libInfo = new LibInfo();
572 long loadAddress = 0;
573 if ((mInBrowserProcess && mBrowserUsesSharedRelro) || mWaitForShared Relros) {
574 // Load the library at a fixed address.
575 loadAddress = mCurrentLoadAddress;
576 }
577
578 String sharedRelRoName = libFilePath;
579 if (zipFilePath != null) {
580 if (!nativeLoadLibraryInZipFile(zipFilePath, libFilePath, loadAd dress, libInfo)) {
581 String errorMessage =
582 "Unable to load library: " + libFilePath + ", in: " + zipFilePath;
583 Log.e(TAG, errorMessage);
584 throw new UnsatisfiedLinkError(errorMessage);
585 }
586 sharedRelRoName = zipFilePath;
587 } else {
588 if (!nativeLoadLibrary(libFilePath, loadAddress, libInfo)) {
589 String errorMessage = "Unable to load library: " + libFilePa th;
590 Log.e(TAG, errorMessage);
591 throw new UnsatisfiedLinkError(errorMessage);
592 }
593 }
594
595 // Print the load address to the logcat when testing the linker. The format
596 // of the string is expected by the Python test_runner script as one of:
597 // BROWSER_LIBRARY_ADDRESS: <library-name> <address>
598 // RENDERER_LIBRARY_ADDRESS: <library-name> <address>
599 // Where <library-name> is the library name, and <address> is the he xadecimal load
600 // address.
601 if (NativeLibraries.sEnableLinkerTests) {
602 Log.i(TAG, String.format(Locale.US, "%s_LIBRARY_ADDRESS: %s %x",
603 mInBrowserProcess ? "BROWSER" : "RENDERER", l ibFilePath,
604 libInfo.mLoadAddress));
605 }
606
607 if (mInBrowserProcess) {
608 // Create a new shared RELRO section at the 'current' fixed load address.
609 if (!nativeCreateSharedRelro(sharedRelRoName, mCurrentLoadAddres s, libInfo)) {
610 Log.w(TAG,
611 String.format(Locale.US, "Could not create shared RE LRO for %s at %x",
612 libFilePath, mCurrentLoadAddress));
613 } else {
614 if (DEBUG) {
615 Log.i(TAG,
616 String.format(Locale.US, "Created shared RELRO f or %s at %x: %s",
617 sharedRelRoName, mCurrentLoadAddress, li bInfo.toString()));
618 }
619 }
620 }
621
622 if (mCurrentLoadAddress != 0) {
623 // Compute the next current load address. If mBaseLoadAddress
624 // is not 0, this is an explicit library load address. Otherwise ,
625 // this is an explicit load address for relocated RELRO sections
626 // only.
627 mCurrentLoadAddress = libInfo.mLoadAddress + libInfo.mLoadSize;
628 }
629
630 mLoadedLibraries.put(sharedRelRoName, libInfo);
631 if (DEBUG) {
632 Log.i(TAG, "Library details " + libInfo.toString());
633 }
634 }
635 }
636
637 /**
638 * Determine whether a library is the linker library. Also deal with the
639 * component build that adds a .cr suffix to the name.
640 */
641 @Override
642 public boolean isChromiumLinkerLibrary(String library) {
643 return library.equals(LINKER_JNI_LIBRARY) || library.equals(LINKER_JNI_L IBRARY + ".cr");
644 }
645
646 /**
647 * Move activity from the native thread to the main UI thread.
648 * Called from native code on its own thread. Posts a callback from
649 * the UI thread back to native code.
650 *
651 * @param opaque Opaque argument.
652 */
653 @CalledByNative
654 public static void postCallbackOnMainThread(final long opaque) {
655 ThreadUtils.postOnUiThread(new Runnable() {
656 @Override
657 public void run() {
658 nativeRunCallbackOnUiThread(opaque);
659 }
660 });
661 }
662
663 /**
664 * Native method to run callbacks on the main UI thread.
665 * Supplied by the crazy linker and called by postCallbackOnMainThread.
666 * @param opaque Opaque crazy linker arguments.
667 */
668 private static native void nativeRunCallbackOnUiThread(long opaque);
669
670 /**
671 * Native method used to load a library.
672 * @param library Platform specific library name (e.g. libfoo.so)
673 * @param loadAddress Explicit load address, or 0 for randomized one.
674 * @param libInfo If not null, the mLoadAddress and mLoadSize fields
675 * of this LibInfo instance will set on success.
676 * @return true for success, false otherwise.
677 */
678 private static native boolean nativeLoadLibrary(
679 String library, long loadAddress, LibInfo libInfo);
680
681 /**
682 * Native method used to load a library which is inside a zipfile.
683 * @param zipfileName Filename of the zip file containing the library.
684 * @param library Platform specific library name (e.g. libfoo.so)
685 * @param loadAddress Explicit load address, or 0 for randomized one.
686 * @param libInfo If not null, the mLoadAddress and mLoadSize fields
687 * of this LibInfo instance will set on success.
688 * @return true for success, false otherwise.
689 */
690 private static native boolean nativeLoadLibraryInZipFile(
691 String zipfileName, String libraryName, long loadAddress, LibInfo li bInfo);
692
693 /**
694 * Native method used to create a shared RELRO section.
695 * If the library was already loaded at the same address using
696 * nativeLoadLibrary(), this creates the RELRO for it. Otherwise,
697 * this loads a new temporary library at the specified address,
698 * creates and extracts the RELRO section from it, then unloads it.
699 * @param library Library name.
700 * @param loadAddress load address, which can be different from the one
701 * used to load the library in the current process!
702 * @param libInfo libInfo instance. On success, the mRelroStart, mRelroSize
703 * and mRelroFd will be set.
704 * @return true on success, false otherwise.
705 */
706 private static native boolean nativeCreateSharedRelro(
707 String library, long loadAddress, LibInfo libInfo);
708
709 /**
710 * Native method used to use a shared RELRO section.
711 * @param library Library name.
712 * @param libInfo A LibInfo instance containing valid RELRO information
713 * @return true on success.
714 */
715 private static native boolean nativeUseSharedRelro(String library, LibInfo l ibInfo);
716
717 /**
718 * Checks that the system supports shared RELROs. Old Android kernels
719 * have a bug in the way they check Ashmem region protection flags, which
720 * makes using shared RELROs unsafe. This method performs a simple runtime
721 * check for this misfeature, even though nativeEnableSharedRelro() will
722 * always fail if this returns false.
723 */
724 private static native boolean nativeCanUseSharedRelro();
725
726 /**
727 * Return a random address that should be free to be mapped with the given s ize.
728 * Maps an area of size bytes, and if successful then unmaps it and returns
729 * the address of the area allocated by the system (with ASLR). The idea is
730 * that this area should remain free of other mappings until we map our libr ary
731 * into it.
732 * @param sizeBytes Size of area in bytes to search for.
733 * @return address to pass to future mmap, or 0 on error.
734 */
735 private static native long nativeGetRandomBaseLoadAddress(long sizeBytes);
736 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698