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

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

Issue 2050803003: Update to Chromium //base at Chromium commit e3a753f17bac62738b0dbf0b36510f767b081e4b. (Closed) Base URL: https://github.com/domokit/base.git@master
Patch Set: Created 4 years, 6 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.base.library_loader; 5 package org.chromium.base.library_loader;
6 6
7 import android.os.Build; 7 import android.os.Build;
8 import android.os.Bundle; 8 import android.os.Bundle;
9 import android.os.Parcel; 9 import android.os.Parcel;
10 import android.os.ParcelFileDescriptor; 10 import android.os.ParcelFileDescriptor;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 * - In a service process, finishLibraryLoad() and/or loadLibrary() may 141 * - In a service process, finishLibraryLoad() and/or loadLibrary() may
142 * block until the RELRO section Bundle is received. This is typically 142 * block until the RELRO section Bundle is received. This is typically
143 * done by calling useSharedRelros() from another thread. 143 * done by calling useSharedRelros() from another thread.
144 * 144 *
145 * This method also ensures the process uses the shared RELROs. 145 * This method also ensures the process uses the shared RELROs.
146 */ 146 */
147 public abstract class Linker { 147 public abstract class Linker {
148 // Log tag for this class. 148 // Log tag for this class.
149 private static final String TAG = "cr.library_loader"; 149 private static final String TAG = "cr.library_loader";
150 150
151 // Name of the library that contains our JNI code.
152 private static final String LINKER_JNI_LIBRARY = "chromium_android_linker";
153
151 // Constants used to control the behaviour of the browser process with 154 // Constants used to control the behaviour of the browser process with
152 // regards to the shared RELRO section. Not applicable to ModernLinker. 155 // regards to the shared RELRO section. Not applicable to ModernLinker.
153 // NEVER -> The browser never uses it itself. 156 // NEVER -> The browser never uses it itself.
154 // LOW_RAM_ONLY -> It is only used on devices with low RAM. 157 // LOW_RAM_ONLY -> It is only used on devices with low RAM.
155 // ALWAYS -> It is always used. 158 // ALWAYS -> It is always used.
156 // NOTE: These names are known and expected by the Linker test scripts. 159 // NOTE: These names are known and expected by the Linker test scripts.
157 public static final int BROWSER_SHARED_RELRO_CONFIG_NEVER = 0; 160 public static final int BROWSER_SHARED_RELRO_CONFIG_NEVER = 0;
158 public static final int BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY = 1; 161 public static final int BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY = 1;
159 public static final int BROWSER_SHARED_RELRO_CONFIG_ALWAYS = 2; 162 public static final int BROWSER_SHARED_RELRO_CONFIG_ALWAYS = 2;
160 163
(...skipping 12 matching lines...) Expand all
173 public static final int MEMORY_DEVICE_CONFIG_INIT = 0; 176 public static final int MEMORY_DEVICE_CONFIG_INIT = 0;
174 public static final int MEMORY_DEVICE_CONFIG_LOW = 1; 177 public static final int MEMORY_DEVICE_CONFIG_LOW = 1;
175 public static final int MEMORY_DEVICE_CONFIG_NORMAL = 2; 178 public static final int MEMORY_DEVICE_CONFIG_NORMAL = 2;
176 179
177 // Indicates if this is a low-memory device or not. The default is to 180 // Indicates if this is a low-memory device or not. The default is to
178 // determine this by probing the system at runtime, but this can be forced 181 // determine this by probing the system at runtime, but this can be forced
179 // for testing by calling setMemoryDeviceConfigForTesting(). 182 // for testing by calling setMemoryDeviceConfigForTesting().
180 // Not used by ModernLinker. 183 // Not used by ModernLinker.
181 protected int mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_INIT; 184 protected int mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_INIT;
182 185
183 // Name of the library that contains our JNI code.
184 protected static final String LINKER_JNI_LIBRARY = "chromium_android_linker" ;
185
186 // Set to true to enable debug logs. 186 // Set to true to enable debug logs.
187 protected static final boolean DEBUG = false; 187 protected static final boolean DEBUG = false;
188 188
189 // Used to pass the shared RELRO Bundle through Binder. 189 // Used to pass the shared RELRO Bundle through Binder.
190 public static final String EXTRA_LINKER_SHARED_RELROS = 190 public static final String EXTRA_LINKER_SHARED_RELROS =
191 "org.chromium.base.android.linker.shared_relros"; 191 "org.chromium.base.android.linker.shared_relros";
192 192
193 // Guards all access to the linker. 193 // Guards all access to the linker.
194 protected final Object mLock = new Object(); 194 protected final Object mLock = new Object();
195 195
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } 250 }
251 } 251 }
252 252
253 /** 253 /**
254 * Check that native library linker tests are enabled. 254 * Check that native library linker tests are enabled.
255 * If not enabled, calls to testing functions will fail with an assertion 255 * If not enabled, calls to testing functions will fail with an assertion
256 * error. 256 * error.
257 * 257 *
258 * @return true if native library linker tests are enabled. 258 * @return true if native library linker tests are enabled.
259 */ 259 */
260 public static boolean areLinkerTestsEnabled() { 260 public static boolean areTestsEnabled() {
261 return NativeLibraries.sEnableLinkerTests; 261 return NativeLibraries.sEnableLinkerTests;
262 } 262 }
263 263
264 /** 264 /**
265 * Assert for testing. 265 * Assert for testing.
266 * Hard assertion. Cannot be disabled. Used only by testing methods. 266 * Hard assertion. Cannot be disabled. Used only by testing methods.
267 */ 267 */
268 private static void assertForTesting(boolean flag) { 268 private static void assertForTesting(boolean flag) {
269 if (!flag) { 269 if (!flag) {
270 throw new AssertionError(); 270 throw new AssertionError();
(...skipping 14 matching lines...) Expand all
285 } 285 }
286 } 286 }
287 287
288 /** 288 /**
289 * Set Linker implementation type. 289 * Set Linker implementation type.
290 * For testing. Sets either a LegacyLinker or a ModernLinker. Must be called 290 * For testing. Sets either a LegacyLinker or a ModernLinker. Must be called
291 * before getInstance(). 291 * before getInstance().
292 * 292 *
293 * @param type LINKER_IMPLEMENTATION_LEGACY or LINKER_IMPLEMENTATION_MODERN 293 * @param type LINKER_IMPLEMENTATION_LEGACY or LINKER_IMPLEMENTATION_MODERN
294 */ 294 */
295 public static final void setLinkerImplementationForTesting(int type) { 295 public static final void setImplementationForTesting(int type) {
296 // Sanity check. This method may only be called during tests. 296 // Sanity check. This method may only be called during tests.
297 assertLinkerTestsAreEnabled(); 297 assertLinkerTestsAreEnabled();
298 assertForTesting( 298 assertForTesting(
299 type == LINKER_IMPLEMENTATION_LEGACY || type == LINKER_IMPLEMENT ATION_MODERN); 299 type == LINKER_IMPLEMENTATION_LEGACY || type == LINKER_IMPLEMENT ATION_MODERN);
300 300
301 synchronized (sSingletonLock) { 301 synchronized (sSingletonLock) {
302 assertForTesting(sSingleton == null); 302 assertForTesting(sSingleton == null);
303 303
304 if (type == LINKER_IMPLEMENTATION_MODERN) { 304 if (type == LINKER_IMPLEMENTATION_MODERN) {
305 sSingleton = ModernLinker.create(); 305 sSingleton = ModernLinker.create();
306 } else if (type == LINKER_IMPLEMENTATION_LEGACY) { 306 } else if (type == LINKER_IMPLEMENTATION_LEGACY) {
307 sSingleton = LegacyLinker.create(); 307 sSingleton = LegacyLinker.create();
308 } else { 308 } else {
309 return; 309 return;
310 } 310 }
311 Log.i(TAG, "Forced linker: " + sSingleton.getClass().getName()); 311 Log.i(TAG, "Forced linker: " + sSingleton.getClass().getName());
312 } 312 }
313 } 313 }
314 314
315 /** 315 /**
316 * Get Linker implementation type. 316 * Get Linker implementation type.
317 * For testing. 317 * For testing.
318 * 318 *
319 * @return LINKER_IMPLEMENTATION_LEGACY or LINKER_IMPLEMENTATION_MODERN 319 * @return LINKER_IMPLEMENTATION_LEGACY or LINKER_IMPLEMENTATION_MODERN
320 */ 320 */
321 public int getLinkerImplementationForTesting() { 321 public int getImplementationForTesting() {
322 // Sanity check. This method may only be called during tests. 322 // Sanity check. This method may only be called during tests.
323 assertLinkerTestsAreEnabled(); 323 assertLinkerTestsAreEnabled();
324 assertForTesting(sSingleton != null);
325 324
326 if (sSingleton instanceof ModernLinker) { 325 synchronized (sSingletonLock) {
327 return LINKER_IMPLEMENTATION_MODERN; 326 assertForTesting(sSingleton != null);
328 } else if (sSingleton instanceof LegacyLinker) { 327
329 return LINKER_IMPLEMENTATION_LEGACY; 328 if (sSingleton instanceof ModernLinker) {
329 return LINKER_IMPLEMENTATION_MODERN;
330 } else if (sSingleton instanceof LegacyLinker) {
331 return LINKER_IMPLEMENTATION_LEGACY;
332 }
333 Log.e(TAG, "Invalid linker: " + sSingleton.getClass().getName());
334 return 0;
330 } 335 }
331 Log.e(TAG, "Invalid linker: " + sSingleton.getClass().getName());
332 return 0;
333 } 336 }
334 337
335 /** 338 /**
336 * A public interface used to run runtime linker tests after loading 339 * A public interface used to run runtime linker tests after loading
337 * libraries. Should only be used to implement the linker unit tests, 340 * libraries. Should only be used to implement the linker unit tests,
338 * which is controlled by the value of NativeLibraries.sEnableLinkerTests 341 * which is controlled by the value of NativeLibraries.sEnableLinkerTests
339 * configured at build time. 342 * configured at build time.
340 */ 343 */
341 public interface TestRunner { 344 public interface TestRunner {
342 /** 345 /**
343 * Run runtime checks and return true if they all pass. 346 * Run runtime checks and return true if they all pass.
344 * 347 *
345 * @param memoryDeviceConfig The current memory device configuration. 348 * @param memoryDeviceConfig The current memory device configuration.
346 * @param inBrowserProcess true iff this is the browser process. 349 * @param inBrowserProcess true iff this is the browser process.
347 * @return true if all checks pass. 350 * @return true if all checks pass.
348 */ 351 */
349 public boolean runChecks(int memoryDeviceConfig, boolean inBrowserProces s); 352 public boolean runChecks(int memoryDeviceConfig, boolean inBrowserProces s);
350 } 353 }
351 354
352 /** 355 /**
353 * Set the TestRunner by its class name. It will be instantiated at 356 * Set the TestRunner by its class name. It will be instantiated at
354 * runtime after all libraries are loaded. 357 * runtime after all libraries are loaded.
355 * 358 *
356 * @param testRunnerClassName null or a String for the class name of the 359 * @param testRunnerClassName null or a String for the class name of the
357 * TestRunner to use. 360 * TestRunner to use.
358 */ 361 */
359 public void setTestRunnerClassNameForTesting(String testRunnerClassName) { 362 public void setTestRunnerClassNameForTesting(String testRunnerClassName) {
360 if (DEBUG) { 363 if (DEBUG) {
361 Log.i(TAG, "setTestRunnerByClassNameForTesting(" + testRunnerClassNa me + ") called"); 364 Log.i(TAG, "setTestRunnerClassNameForTesting(" + testRunnerClassName + ") called");
362 } 365 }
363 // Sanity check. This method may only be called during tests. 366 // Sanity check. This method may only be called during tests.
364 assertLinkerTestsAreEnabled(); 367 assertLinkerTestsAreEnabled();
365 368
366 synchronized (mLock) { 369 synchronized (mLock) {
367 assertForTesting(mTestRunnerClassName == null); 370 assertForTesting(mTestRunnerClassName == null);
368 mTestRunnerClassName = testRunnerClassName; 371 mTestRunnerClassName = testRunnerClassName;
369 } 372 }
370 } 373 }
371 374
372 /** 375 /**
373 * Call this to retrieve the name of the current TestRunner class name 376 * Call this to retrieve the name of the current TestRunner class name
374 * if any. This can be useful to pass it from the browser process to 377 * if any. This can be useful to pass it from the browser process to
375 * child ones. 378 * child ones.
376 * 379 *
377 * @return null or a String holding the name of the class implementing 380 * @return null or a String holding the name of the class implementing
378 * the TestRunner set by calling setTestRunnerClassNameForTesting() previous ly. 381 * the TestRunner set by calling setTestRunnerClassNameForTesting() previous ly.
379 */ 382 */
380 public String getTestRunnerClassNameForTesting() { 383 public String getTestRunnerClassNameForTesting() {
381 // Sanity check. This method may only be called during tests. 384 // Sanity check. This method may only be called during tests.
382 assertLinkerTestsAreEnabled(); 385 assertLinkerTestsAreEnabled();
383 386
384 synchronized (mLock) { 387 synchronized (mLock) {
385 return mTestRunnerClassName; 388 return mTestRunnerClassName;
386 } 389 }
387 } 390 }
388 391
389 /** 392 /**
393 * Set up the Linker for a test.
394 * Convenience function that calls setImplementationForTesting() to force an
395 * implementation, and then setTestRunnerClassNameForTesting() to set the te st
396 * class name.
397 *
398 * On first call, instantiates a Linker of the requested type and sets its t est
399 * runner class name. On subsequent calls, checks that the singleton produce d by
400 * the first call matches the requested type and test runner class name.
401 */
402 public static void setupForTesting(int type, String testRunnerClassName) {
403 if (DEBUG) {
404 Log.i(TAG, "setupForTesting(" + type + ", " + testRunnerClassName + ") called");
405 }
406 // Sanity check. This method may only be called during tests.
407 assertLinkerTestsAreEnabled();
408
409 synchronized (sSingletonLock) {
410 // If this is the first call, configure the Linker to the given type and test class.
411 if (sSingleton == null) {
412 setImplementationForTesting(type);
413 sSingleton.setTestRunnerClassNameForTesting(testRunnerClassName) ;
414 return;
415 }
416
417 // If not the first call, check that the Linker configuration matche s this request.
418 assertForTesting(sSingleton.getImplementationForTesting() == type);
419 String ourTestRunnerClassName = sSingleton.getTestRunnerClassNameFor Testing();
420 if (testRunnerClassName == null) {
421 assertForTesting(ourTestRunnerClassName == null);
422 } else {
423 assertForTesting(ourTestRunnerClassName.equals(testRunnerClassNa me));
424 }
425 }
426 }
427
428 /**
390 * Instantiate and run the current TestRunner, if any. The TestRunner implem entation 429 * Instantiate and run the current TestRunner, if any. The TestRunner implem entation
391 * must be instantiated _after_ all libraries are loaded to ensure that its 430 * must be instantiated _after_ all libraries are loaded to ensure that its
392 * native methods are properly registered. 431 * native methods are properly registered.
393 * 432 *
394 * @param memoryDeviceConfig LegacyLinker memory config, or 0 if unused 433 * @param memoryDeviceConfig LegacyLinker memory config, or 0 if unused
395 * @param inBrowserProcess true if in the browser process 434 * @param inBrowserProcess true if in the browser process
396 */ 435 */
397 protected void runTestRunnerClassForTesting(int memoryDeviceConfig, boolean inBrowserProcess) { 436 protected void runTestRunnerClassForTesting(int memoryDeviceConfig, boolean inBrowserProcess) {
398 if (DEBUG) { 437 if (DEBUG) {
399 Log.i(TAG, "runTestRunnerClassForTesting called"); 438 Log.i(TAG, "runTestRunnerClassForTesting called");
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 */ 503 */
465 public boolean isChromiumLinkerLibrary(String library) { 504 public boolean isChromiumLinkerLibrary(String library) {
466 return library.equals(LINKER_JNI_LIBRARY) || library.equals(LINKER_JNI_L IBRARY + ".cr"); 505 return library.equals(LINKER_JNI_LIBRARY) || library.equals(LINKER_JNI_L IBRARY + ".cr");
467 } 506 }
468 507
469 /** 508 /**
470 * Load the Linker JNI library. Throws UnsatisfiedLinkError on error. 509 * Load the Linker JNI library. Throws UnsatisfiedLinkError on error.
471 * In a component build, the suffix ".cr" is added to each library name, so 510 * In a component build, the suffix ".cr" is added to each library name, so
472 * if the initial load fails we retry with a suffix. 511 * if the initial load fails we retry with a suffix.
473 */ 512 */
474 protected void loadLinkerJNILibrary() { 513 protected static void loadLinkerJniLibrary() {
475 String libName = "lib" + LINKER_JNI_LIBRARY + ".so"; 514 String libName = "lib" + LINKER_JNI_LIBRARY + ".so";
476 if (DEBUG) { 515 if (DEBUG) {
477 Log.i(TAG, "Loading " + libName); 516 Log.i(TAG, "Loading " + libName);
478 } 517 }
479 try { 518 try {
480 System.loadLibrary(LINKER_JNI_LIBRARY); 519 System.loadLibrary(LINKER_JNI_LIBRARY);
481 } catch (UnsatisfiedLinkError e) { 520 } catch (UnsatisfiedLinkError e) {
482 Log.w(TAG, "Couldn't load " + libName + ", trying " + libName + ".so "); 521 Log.w(TAG, "Couldn't load " + libName + ", trying " + libName + ".cr ");
483 System.loadLibrary(LINKER_JNI_LIBRARY + ".cr"); 522 System.loadLibrary(LINKER_JNI_LIBRARY + ".cr");
484 } 523 }
485 } 524 }
486 525
487 /** 526 /**
488 * Obtain a random base load address at which to place loaded libraries. 527 * Obtain a random base load address at which to place loaded libraries.
489 * 528 *
490 * @return new base load address 529 * @return new base load address
491 */ 530 */
492 protected long getRandomBaseLoadAddress() { 531 protected long getRandomBaseLoadAddress() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 Log.i(TAG, "loadLibraryAtAnyAddress: " + zipFilePath + ", " + libFil ePath); 585 Log.i(TAG, "loadLibraryAtAnyAddress: " + zipFilePath + ", " + libFil ePath);
547 } 586 }
548 final boolean isFixedAddressPermitted = false; 587 final boolean isFixedAddressPermitted = false;
549 loadLibraryImpl(zipFilePath, libFilePath, isFixedAddressPermitted); 588 loadLibraryImpl(zipFilePath, libFilePath, isFixedAddressPermitted);
550 } 589 }
551 590
552 /** 591 /**
553 * Call this method to determine if the chromium project must load the libra ry 592 * Call this method to determine if the chromium project must load the libra ry
554 * directly from a zip file. 593 * directly from a zip file.
555 */ 594 */
556 public boolean isInZipFile() { 595 public static boolean isInZipFile() {
557 // The auto-generated NativeLibraries.sUseLibraryInZipFile variable will be true 596 // The auto-generated NativeLibraries.sUseLibraryInZipFile variable will be true
558 // if the library remains embedded in the APK zip file on the target. 597 // if the library remains embedded in the APK zip file on the target.
559 return NativeLibraries.sUseLibraryInZipFile; 598 return NativeLibraries.sUseLibraryInZipFile;
560 } 599 }
561 600
562 /** 601 /**
563 * Call this method to determine if this chromium project must 602 * Call this method to determine if this chromium project must
564 * use this linker. If not, System.loadLibrary() should be used to load 603 * use this linker. If not, System.loadLibrary() should be used to load
565 * libraries instead. 604 * libraries instead.
566 */ 605 */
567 public abstract boolean isUsed(); 606 public static boolean isUsed() {
607 // The auto-generated NativeLibraries.sUseLinker variable will be true i f the
608 // build has not explicitly disabled Linker features.
609 return NativeLibraries.sUseLinker;
610 }
568 611
569 /** 612 /**
570 * Call this method to determine if the linker will try to use shared RELROs 613 * Call this method to determine if the linker will try to use shared RELROs
571 * for the browser process. 614 * for the browser process.
572 */ 615 */
573 public abstract boolean isUsingBrowserSharedRelros(); 616 public abstract boolean isUsingBrowserSharedRelros();
574 617
575 /** 618 /**
576 * Call this method just before loading any native shared libraries in this process. 619 * Call this method just before loading any native shared libraries in this process.
577 */ 620 */
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 * Return a random address that should be free to be mapped with the given s ize. 814 * Return a random address that should be free to be mapped with the given s ize.
772 * Maps an area large enough for the largest library we might attempt to loa d, 815 * Maps an area large enough for the largest library we might attempt to loa d,
773 * and if successful then unmaps it and returns the address of the area allo cated 816 * and if successful then unmaps it and returns the address of the area allo cated
774 * by the system (with ASLR). The idea is that this area should remain free of 817 * by the system (with ASLR). The idea is that this area should remain free of
775 * other mappings until we map our library into it. 818 * other mappings until we map our library into it.
776 * 819 *
777 * @return address to pass to future mmap, or 0 on error. 820 * @return address to pass to future mmap, or 0 on error.
778 */ 821 */
779 private static native long nativeGetRandomBaseLoadAddress(); 822 private static native long nativeGetRandomBaseLoadAddress();
780 } 823 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698