Commit 39a3080e authored by Brian Sheedy's avatar Brian Sheedy Committed by Commit Bot

Revert "Use the LegacyLinker instead of the ModernLinker"

This reverts commit fdb31883.

Reason for revert: Causing VR segfaults https://logs.chromium.org/v/?s=chromium%2Fbb%2Fchromium.fyi%2FAndroid_VR_Tests%2F13834%2F%2B%2Frecipes%2Fsteps%2Fstack_tool_with_logcat_dump%2F0%2Fstdout

Original change's description:
> Use the LegacyLinker instead of the ModernLinker
> 
> Remove the ModernLinker since it becomes unused. Also remove the possibility to
> set the linker differently in tests.
> 
> Public document explaining the motivation: https://goo.gl/kWnHYr
> 
> BUG=719977 (google-internal)
> 
> Change-Id: I5b9b85817093b36127fa4a607bced57b4350a5b8
> Reviewed-on: https://chromium-review.googlesource.com/538582
> Commit-Queue: Egor Pasko <pasko@chromium.org>
> Reviewed-by: Yaron Friedman <yfriedman@chromium.org>
> Reviewed-by: Richard Coles <torne@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#517838}

TBR=pasko@chromium.org,yfriedman@chromium.org,torne@chromium.org

Change-Id: I638bd3223567a5a40babd036feca310257deaa6f
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 719977 (google-internal)
Reviewed-on: https://chromium-review.googlesource.com/779921Reviewed-by: default avatarBrian Sheedy <bsheedy@chromium.org>
Commit-Queue: Brian Sheedy <bsheedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517889}
parent 1ab2c1e3
......@@ -2654,6 +2654,7 @@ if (is_android) {
"android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
"android/java/src/org/chromium/base/library_loader/Linker.java",
"android/java/src/org/chromium/base/library_loader/LoaderErrors.java",
"android/java/src/org/chromium/base/library_loader/ModernLinker.java",
"android/java/src/org/chromium/base/library_loader/NativeLibraryPreloader.java",
"android/java/src/org/chromium/base/library_loader/ProcessInitException.java",
"android/java/src/org/chromium/base/metrics/CachedMetrics.java",
......
......@@ -4,11 +4,13 @@
package org.chromium.base.library_loader;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.annotations.AccessedByNative;
......@@ -151,7 +153,7 @@ public abstract class Linker {
private static final String LINKER_JNI_LIBRARY = "chromium_android_linker";
// Constants used to control the behaviour of the browser process with
// regards to the shared RELRO section.
// regards to the shared RELRO section. Not applicable to ModernLinker.
// NEVER -> The browser never uses it itself.
// LOW_RAM_ONLY -> It is only used on devices with low RAM.
// ALWAYS -> It is always used.
......@@ -162,12 +164,13 @@ public abstract class Linker {
// Configuration variable used to control how the browser process uses the
// shared RELRO. Only change this while debugging linker-related issues.
// Not used by ModernLinker.
// NOTE: This variable's name is known and expected by the Linker test scripts.
public static final int BROWSER_SHARED_RELRO_CONFIG =
BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY;
// Constants used to control the memory device config. Can be set explicitly
// by setMemoryDeviceConfigForTesting().
// by setMemoryDeviceConfigForTesting(). Not applicable to ModernLinker.
// INIT -> Value is undetermined (will check at runtime).
// LOW -> This is a low-memory device.
// NORMAL -> This is not a low-memory device.
......@@ -178,6 +181,7 @@ public abstract class Linker {
// Indicates if this is a low-memory device or not. The default is to
// determine this by probing the system at runtime, but this can be forced
// for testing by calling setMemoryDeviceConfigForTesting().
// Not used by ModernLinker.
protected int mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_INIT;
// Set to true to enable debug logs.
......@@ -204,6 +208,13 @@ public abstract class Linker {
// ensure that we don't try to load outside the area originally requested.
protected static final int ADDRESS_SPACE_RESERVATION = 192 * 1024 * 1024;
// Constants used to indicate a given Linker implementation, for testing.
// LEGACY -> Always uses the LegacyLinker implementation.
// MODERN -> Always uses the ModernLinker implementation.
// NOTE: These names are known and expected by the Linker test scripts.
public static final int LINKER_IMPLEMENTATION_LEGACY = 1;
public static final int LINKER_IMPLEMENTATION_MODERN = 2;
// Singleton.
private static Linker sSingleton;
private static Object sSingletonLock = new Object();
......@@ -212,18 +223,35 @@ public abstract class Linker {
protected Linker() { }
/**
* Get singleton instance. Returns a LegacyLinker.
* Get singleton instance. Returns either a LegacyLinker or a ModernLinker.
*
* Returns a ModernLinker if running on Android M or later, otherwise returns
* a LegacyLinker.
*
* ModernLinker requires OS features from Android M and later: a system linker
* that handles packed relocations and load from APK, and android_dlopen_ext()
* for shared RELRO support. It cannot run on Android releases earlier than M.
*
* LegacyLinker runs on all Android releases but it is slower and more complex
* than ModernLinker, so ModernLinker is preferred for Android M and later.
*
* @return the Linker implementation instance.
*/
public static final Linker getInstance() {
// TODO(pasko): The linker is created dynamically for historical
// reasons. Formerly there was a runtime choice between LegacyLinker and
// ModernLinker. To simplify, move the LegacyLinker logic into the
// Linker.
synchronized (sSingletonLock) {
if (sSingleton == null) {
sSingleton = LegacyLinker.create();
// With incremental install, it's important to fall back to the "normal"
// library loading path in order for the libraries to be found.
String appClass =
ContextUtils.getApplicationContext().getApplicationInfo().className;
boolean isIncrementalInstall =
appClass != null && appClass.contains("incrementalinstall");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !isIncrementalInstall) {
sSingleton = ModernLinker.create();
} else {
sSingleton = LegacyLinker.create();
}
Log.i(TAG, "Using linker: " + sSingleton.getClass().getName());
}
return sSingleton;
}
......@@ -264,6 +292,56 @@ public abstract class Linker {
}
}
/**
* Set Linker implementation type.
* For testing. Sets either a LegacyLinker or a ModernLinker. Must be called
* before getInstance().
*
* @param type LINKER_IMPLEMENTATION_LEGACY or LINKER_IMPLEMENTATION_MODERN
*/
public static final void setImplementationForTesting(int type) {
// Sanity check. This method may only be called during tests.
assertLinkerTestsAreEnabled();
assertForTesting(type == LINKER_IMPLEMENTATION_LEGACY
|| type == LINKER_IMPLEMENTATION_MODERN);
synchronized (sSingletonLock) {
assertForTesting(sSingleton == null);
if (type == LINKER_IMPLEMENTATION_MODERN) {
sSingleton = ModernLinker.create();
} else if (type == LINKER_IMPLEMENTATION_LEGACY) {
sSingleton = LegacyLinker.create();
}
Log.i(TAG, "Forced linker: " + sSingleton.getClass().getName());
}
}
/**
* Get Linker implementation type.
* For testing.
*
* @return LINKER_IMPLEMENTATION_LEGACY or LINKER_IMPLEMENTATION_MODERN
*/
public final int getImplementationForTesting() {
// Sanity check. This method may only be called during tests.
assertLinkerTestsAreEnabled();
synchronized (sSingletonLock) {
assertForTesting(sSingleton == this);
if (sSingleton instanceof ModernLinker) {
return LINKER_IMPLEMENTATION_MODERN;
} else if (sSingleton instanceof LegacyLinker) {
return LINKER_IMPLEMENTATION_LEGACY;
} else {
Log.wtf(TAG, "Invalid linker: " + sSingleton.getClass().getName());
assertForTesting(false);
}
return 0;
}
}
/**
* A public interface used to run runtime linker tests after loading
* libraries. Should only be used to implement the linker unit tests,
......@@ -319,30 +397,32 @@ public abstract class Linker {
}
/**
* Sets the test class name.
* Set up the Linker for a test.
* Convenience function that calls setImplementationForTesting() to force an
* implementation, and then setTestRunnerClassNameForTesting() to set the test
* class name.
*
* On first call, instantiates a Linker of the requested type and sets its test
* runner class name. On subsequent calls, checks that the singleton produced by
* the first call matches the test runner class name.
* the first call matches the requested type and test runner class name.
*/
public static final void setupForTesting(String testRunnerClassName) {
public static final void setupForTesting(int type, String testRunnerClassName) {
if (DEBUG) {
Log.i(TAG, "setupForTesting(" + testRunnerClassName + ") called");
Log.i(TAG, "setupForTesting(" + type + ", " + testRunnerClassName + ") called");
}
// Sanity check. This method may only be called during tests.
assertLinkerTestsAreEnabled();
synchronized (sSingletonLock) {
// If this is the first call, instantiate the Linker and the test class.
// If this is the first call, configure the Linker to the given type and test class.
if (sSingleton == null) {
assertLinkerTestsAreEnabled();
assertForTesting(sSingleton == null);
sSingleton = LegacyLinker.create();
setImplementationForTesting(type);
sSingleton.setTestRunnerClassNameForTesting(testRunnerClassName);
return;
}
// If not the first call, check that the Linker configuration matches this request.
assertForTesting(sSingleton.getImplementationForTesting() == type);
String ourTestRunnerClassName = sSingleton.getTestRunnerClassNameForTesting();
if (testRunnerClassName == null) {
assertForTesting(ourTestRunnerClassName == null);
......
......@@ -13,6 +13,8 @@ shared_library("chromium_android_linker") {
"legacy_linker_jni.h",
"linker_jni.cc",
"linker_jni.h",
"modern_linker_jni.cc",
"modern_linker_jni.h",
]
# The NDK contains the crazy_linker here:
......
......@@ -20,6 +20,7 @@
#include <string.h>
#include "legacy_linker_jni.h"
#include "modern_linker_jni.h"
namespace chromium_android_linker {
......@@ -223,7 +224,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
}
// Initialize linker base and implementations.
if (!LinkerJNIInit(vm, env) || !LegacyLinkerJNIInit(vm, env)) {
if (!LinkerJNIInit(vm, env)
|| !LegacyLinkerJNIInit(vm, env) || !ModernLinkerJNIInit(vm, env)) {
return -1;
}
......
This diff is collapsed.
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_ANDROID_LINKER_MODERN_LINKER_JNI_H_
#define BASE_ANDROID_LINKER_MODERN_LINKER_JNI_H_
#include <jni.h>
namespace chromium_android_linker {
// JNI_OnLoad() initialization hook for the modern linker.
// Sets up JNI and other initializations for native linker code.
// |vm| is the Java VM handle passed to JNI_OnLoad().
// |env| is the current JNI environment handle.
// On success, returns true.
extern bool ModernLinkerJNIInit(JavaVM* vm, JNIEnv* env);
} // namespace chromium_android_linker
#endif // BASE_ANDROID_LINKER_MODERN_LINKER_JNI_H_
......@@ -9,6 +9,7 @@ from pylib.linker import test_case
with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
import unittest_util
_MODERN_LINKER_MINIMUM_SDK_INT = 23
class LinkerTestInstance(test_instance.TestInstance):
......@@ -25,11 +26,15 @@ class LinkerTestInstance(test_instance.TestInstance):
def test_filter(self):
return self._test_filter
def GetTests(self):
def GetTests(self, min_device_sdk):
tests = [
test_case.LinkerSharedRelroTest(is_low_memory=False),
test_case.LinkerSharedRelroTest(is_low_memory=True)
test_case.LinkerSharedRelroTest(is_modern_linker=False,
is_low_memory=False),
test_case.LinkerSharedRelroTest(is_modern_linker=False,
is_low_memory=True)
]
if min_device_sdk >= _MODERN_LINKER_MINIMUM_SDK_INT:
tests.append(test_case.LinkerSharedRelroTest(is_modern_linker=True))
if self._test_filter:
filtered_names = unittest_util.FilterTestNames(
......
......@@ -124,12 +124,17 @@ class AddressList(list):
class LinkerTestCaseBase(object):
"""Base class for linker test cases."""
def __init__(self, is_low_memory=False):
def __init__(self, is_modern_linker=False, is_low_memory=False):
"""Create a test case.
Args:
is_modern_linker: True to test ModernLinker, False to test LegacyLinker.
is_low_memory: True to simulate a low-memory device, False otherwise.
"""
test_suffix = 'ForLegacyLinker'
self.is_modern_linker = is_modern_linker
if is_modern_linker:
test_suffix = 'ForModernLinker'
else:
test_suffix = 'ForLegacyLinker'
self.is_low_memory = is_low_memory
if is_low_memory:
test_suffix += 'LowMemoryDevice'
......@@ -162,7 +167,10 @@ class LinkerTestCaseBase(object):
logging.info('Running linker test: %s', self.tagged_name)
# Create command-line file on device.
command_line_flags = ''
if self.is_modern_linker:
command_line_flags = '--use-linker=modern'
else:
command_line_flags = '--use-linker=legacy'
if self.is_low_memory:
command_line_flags += ' --low-memory-device'
device.WriteFile(_COMMAND_LINE_FILE, command_line_flags)
......
......@@ -27,6 +27,10 @@ public class ChromiumLinkerParams {
// registered in the service process.
public final String mTestRunnerClassNameForTesting;
// If mTestRunnerClassNameForTesting is not empty, the Linker implementation
// to force for testing.
public final int mLinkerImplementationForTesting;
private static final String EXTRA_LINKER_PARAMS_BASE_LOAD_ADDRESS =
"org.chromium.content.common.linker_params.base_load_address";
......@@ -36,20 +40,27 @@ public class ChromiumLinkerParams {
private static final String EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME =
"org.chromium.content.common.linker_params.test_runner_class_name";
private static final String EXTRA_LINKER_PARAMS_LINKER_IMPLEMENTATION =
"org.chromium.content.common.linker_params.linker_implementation";
public ChromiumLinkerParams(long baseLoadAddress, boolean waitForSharedRelro) {
mBaseLoadAddress = baseLoadAddress;
mWaitForSharedRelro = waitForSharedRelro;
mTestRunnerClassNameForTesting = null;
mLinkerImplementationForTesting = 0;
}
/**
* Use this constructor to create a LinkerParams instance for testing.
*/
public ChromiumLinkerParams(
long baseLoadAddress, boolean waitForSharedRelro, String testRunnerClassName) {
public ChromiumLinkerParams(long baseLoadAddress,
boolean waitForSharedRelro,
String testRunnerClassName,
int linkerImplementation) {
mBaseLoadAddress = baseLoadAddress;
mWaitForSharedRelro = waitForSharedRelro;
mTestRunnerClassNameForTesting = testRunnerClassName;
mLinkerImplementationForTesting = linkerImplementation;
}
/**
......@@ -62,7 +73,8 @@ public class ChromiumLinkerParams {
public static ChromiumLinkerParams create(Bundle bundle) {
if (!bundle.containsKey(EXTRA_LINKER_PARAMS_BASE_LOAD_ADDRESS)
|| !bundle.containsKey(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO)
|| !bundle.containsKey(EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME)) {
|| !bundle.containsKey(EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME)
|| !bundle.containsKey(EXTRA_LINKER_PARAMS_LINKER_IMPLEMENTATION)) {
return null;
}
return new ChromiumLinkerParams(bundle);
......@@ -73,6 +85,8 @@ public class ChromiumLinkerParams {
mWaitForSharedRelro = bundle.getBoolean(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO, false);
mTestRunnerClassNameForTesting =
bundle.getString(EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME);
mLinkerImplementationForTesting =
bundle.getInt(EXTRA_LINKER_PARAMS_LINKER_IMPLEMENTATION, 0);
}
/**
......@@ -85,6 +99,7 @@ public class ChromiumLinkerParams {
bundle.putBoolean(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO, mWaitForSharedRelro);
bundle.putString(
EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME, mTestRunnerClassNameForTesting);
bundle.putInt(EXTRA_LINKER_PARAMS_LINKER_IMPLEMENTATION, mLinkerImplementationForTesting);
}
// For debugging traces only.
......@@ -92,8 +107,8 @@ public class ChromiumLinkerParams {
public String toString() {
return String.format(Locale.US,
"LinkerParams(baseLoadAddress:0x%x, waitForSharedRelro:%s, "
+ "testRunnerClassName:%s",
+ "testRunnerClassName:%s, linkerImplementation:%d",
mBaseLoadAddress, Boolean.toString(mWaitForSharedRelro),
mTestRunnerClassNameForTesting);
mTestRunnerClassNameForTesting, mLinkerImplementationForTesting);
}
}
......@@ -196,7 +196,8 @@ public class ContentChildProcessServiceDelegate implements ChildProcessServiceDe
// For testing, set the Linker implementation and the test runner
// class name to match those used by the parent.
assert mLinkerParams != null;
Linker.setupForTesting(mLinkerParams.mTestRunnerClassNameForTesting);
Linker.setupForTesting(mLinkerParams.mLinkerImplementationForTesting,
mLinkerParams.mTestRunnerClassNameForTesting);
}
return Linker.getInstance();
}
......
......@@ -577,7 +577,8 @@ public class ChildProcessLauncherHelper {
if (Linker.areTestsEnabled()) {
Linker linker = Linker.getInstance();
return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRelros,
linker.getTestRunnerClassNameForTesting());
linker.getTestRunnerClassNameForTesting(),
linker.getImplementationForTesting());
} else {
return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRelros);
}
......
......@@ -46,6 +46,11 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
//
// "/dev/ashmem/RELRO:<libname> (deleted)"
//
// and for the ModernLinker, something like:
//
// "/data/data/org.chromium.chromium_linker_test_apk/
// app_chromium_linker_test/RELRO:<libname> (deleted)"
//
// Where <libname> is the library name and '(deleted)' is actually
// added by the kernel to indicate there is no corresponding file
// on the filesystem.
......@@ -54,6 +59,7 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
// section, but for the component build, there are several libraries,
// each one with its own RELRO.
static const char kLegacyRelroSectionPattern[] = "/dev/ashmem/RELRO:.*";
static const char kModernRelroSectionPattern[] = "/data/.*/RELRO:.*";
// Parse /proc/self/maps and builds a list of region mappings in this
// process.
......@@ -72,6 +78,7 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
}
const RE2 legacy_linker_re(kLegacyRelroSectionPattern);
const RE2 modern_linker_re(kModernRelroSectionPattern);
int num_shared_relros = 0;
int num_bad_shared_relros = 0;
......@@ -81,8 +88,15 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
const std::string path = region.path;
const bool is_legacy_relro = re2::RE2::FullMatch(path, legacy_linker_re);
const bool is_modern_relro = re2::RE2::FullMatch(path, modern_linker_re);
if (!is_legacy_relro) {
if (is_legacy_relro && is_modern_relro) {
LOG(ERROR) << prefix
<< "FAIL RELRO cannot be both Legacy and Modern (test error)";
return false;
}
if (!is_legacy_relro && !is_modern_relro) {
// Ignore any mapping that isn't a shared RELRO.
continue;
}
......@@ -113,6 +127,16 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
continue;
}
// Shared RELROs implemented by the Android M+ system linker are not in
// ashmem. The Android M+ system linker maps everything with MAP_PRIVATE
// rather than MAP_SHARED. Remapping such a RELRO section read-write will
// therefore succeed, but it is not a problem. The memory copy-on-writes,
// and updates are not visible to either the mapped file or other processes
// mapping the same file. So... we skip the remap test for ModernLinker.
if (is_modern_relro) {
continue;
}
// Check that trying to remap it read-write fails with EACCES
size_t region_size = region.end - region.start;
int ret = ::mprotect(region_start, region_size, PROT_READ | PROT_WRITE);
......
......@@ -39,6 +39,12 @@ public class ChromiumLinkerTestActivity extends Activity {
// target device running the test really is.
private static final String LOW_MEMORY_DEVICE = "--low-memory-device";
// Use one of these on the command-line to force a specific Linker
// implementation. Passed from the main process to sub-processes so that
// everything that participates in a test uses a consistent implementation.
private static final String USE_MODERN_LINKER = "--use-linker=modern";
private static final String USE_LEGACY_LINKER = "--use-linker=legacy";
private ShellManager mShellManager;
private ActivityWindowAndroid mWindowAndroid;
......@@ -58,6 +64,8 @@ public class ChromiumLinkerTestActivity extends Activity {
// CommandLine.getInstance().hasSwitch() doesn't work here for some funky
// reason, so parse the command-line differently here:
boolean hasLowMemoryDeviceSwitch = false;
boolean hasModernLinkerSwitch = false;
boolean hasLegacyLinkerSwitch = false;
String[] commandLine = CommandLine.getJavaSwitchesOrNull();
if (commandLine == null) {
Log.i(TAG, "Command line is null");
......@@ -68,11 +76,31 @@ public class ChromiumLinkerTestActivity extends Activity {
Log.i(TAG, " '" + option + "'");
if (option.equals(LOW_MEMORY_DEVICE)) {
hasLowMemoryDeviceSwitch = true;
} else if (option.equals(USE_MODERN_LINKER)) {
hasModernLinkerSwitch = true;
} else if (option.equals(USE_LEGACY_LINKER)) {
hasLegacyLinkerSwitch = true;
}
}
}
Linker.setupForTesting(LinkerTests.class.getName());
if (!(hasModernLinkerSwitch || hasLegacyLinkerSwitch)) {
Log.e(TAG, "Missing --use-linker command line argument.");
finish();
} else if (hasModernLinkerSwitch && hasLegacyLinkerSwitch) {
Log.e(TAG, "Conflicting --use-linker command line arguments.");
finish();
}
// Set the requested Linker implementation from the command-line, and
// register the test runner class by name.
if (hasModernLinkerSwitch) {
Linker.setupForTesting(Linker.LINKER_IMPLEMENTATION_MODERN,
LinkerTests.class.getName());
} else {
Linker.setupForTesting(Linker.LINKER_IMPLEMENTATION_LEGACY,
LinkerTests.class.getName());
}
// Determine which kind of device to simulate from the command-line.
int memoryDeviceConfig = Linker.MEMORY_DEVICE_CONFIG_NORMAL;
......
......@@ -23,23 +23,37 @@ public class LinkerTests implements Linker.TestRunner {
boolean isBrowserProcess) {
boolean checkSharedRelro;
if (isBrowserProcess) {
switch (Linker.BROWSER_SHARED_RELRO_CONFIG) {
case Linker.BROWSER_SHARED_RELRO_CONFIG_NEVER:
checkSharedRelro = false;
break;
case Linker.BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY:
// A shared RELRO should only be used on low-end devices.
checkSharedRelro = (memoryDeviceConfig == Linker.MEMORY_DEVICE_CONFIG_LOW);
break;
case Linker.BROWSER_SHARED_RELRO_CONFIG_ALWAYS:
// Always check for a shared RELRO.
checkSharedRelro = true;
break;
default:
Log.e(TAG,
"Invalid shared RELRO linker configuration: "
+ Linker.BROWSER_SHARED_RELRO_CONFIG);
return false;
Linker linker = Linker.getInstance();
int linkerImplementation = linker.getImplementationForTesting();
if (linkerImplementation == Linker.LINKER_IMPLEMENTATION_LEGACY) {
// LegacyLinker may share RELROs in the browser.
switch (Linker.BROWSER_SHARED_RELRO_CONFIG) {
case Linker.BROWSER_SHARED_RELRO_CONFIG_NEVER:
checkSharedRelro = false;
break;
case Linker.BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY:
// A shared RELRO should only be used on low-end devices.
checkSharedRelro =
(memoryDeviceConfig == Linker.MEMORY_DEVICE_CONFIG_LOW);
break;
case Linker.BROWSER_SHARED_RELRO_CONFIG_ALWAYS:
// Always check for a shared RELRO.
checkSharedRelro = true;
break;
default:
Log.e(TAG, "Invalid shared RELRO linker configuration: "
+ Linker.BROWSER_SHARED_RELRO_CONFIG);
return false;
}
} else if (linkerImplementation == Linker.LINKER_IMPLEMENTATION_MODERN) {
// ModernLinker never shares RELROs in the browser.
checkSharedRelro = false;
} else {
Log.e(TAG, "Unknown linker: " + linker.getClass().getName());
return false;
}
} else {
// Service processes should always use a shared RELRO section.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment