| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |