Commit fdb31883 authored by Egor Pasko's avatar Egor Pasko Committed by Commit Bot

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: default avatarYaron Friedman <yfriedman@chromium.org>
Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517838}
parent 70f8551d
...@@ -2654,7 +2654,6 @@ if (is_android) { ...@@ -2654,7 +2654,6 @@ if (is_android) {
"android/java/src/org/chromium/base/library_loader/LibraryLoader.java", "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/Linker.java",
"android/java/src/org/chromium/base/library_loader/LoaderErrors.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/NativeLibraryPreloader.java",
"android/java/src/org/chromium/base/library_loader/ProcessInitException.java", "android/java/src/org/chromium/base/library_loader/ProcessInitException.java",
"android/java/src/org/chromium/base/metrics/CachedMetrics.java", "android/java/src/org/chromium/base/metrics/CachedMetrics.java",
......
...@@ -4,13 +4,11 @@ ...@@ -4,13 +4,11 @@
package org.chromium.base.library_loader; package org.chromium.base.library_loader;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.os.Parcelable; import android.os.Parcelable;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.base.annotations.AccessedByNative; import org.chromium.base.annotations.AccessedByNative;
...@@ -153,7 +151,7 @@ public abstract class Linker { ...@@ -153,7 +151,7 @@ public abstract class Linker {
private static final String LINKER_JNI_LIBRARY = "chromium_android_linker"; private static final String LINKER_JNI_LIBRARY = "chromium_android_linker";
// Constants used to control the behaviour of the browser process with // Constants used to control the behaviour of the browser process with
// regards to the shared RELRO section. Not applicable to ModernLinker. // regards to the shared RELRO section.
// NEVER -> The browser never uses it itself. // NEVER -> The browser never uses it itself.
// LOW_RAM_ONLY -> It is only used on devices with low RAM. // LOW_RAM_ONLY -> It is only used on devices with low RAM.
// ALWAYS -> It is always used. // ALWAYS -> It is always used.
...@@ -164,13 +162,12 @@ public abstract class Linker { ...@@ -164,13 +162,12 @@ public abstract class Linker {
// Configuration variable used to control how the browser process uses the // Configuration variable used to control how the browser process uses the
// shared RELRO. Only change this while debugging linker-related issues. // 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. // NOTE: This variable's name is known and expected by the Linker test scripts.
public static final int BROWSER_SHARED_RELRO_CONFIG = public static final int BROWSER_SHARED_RELRO_CONFIG =
BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY; BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY;
// Constants used to control the memory device config. Can be set explicitly // Constants used to control the memory device config. Can be set explicitly
// by setMemoryDeviceConfigForTesting(). Not applicable to ModernLinker. // by setMemoryDeviceConfigForTesting().
// INIT -> Value is undetermined (will check at runtime). // INIT -> Value is undetermined (will check at runtime).
// LOW -> This is a low-memory device. // LOW -> This is a low-memory device.
// NORMAL -> This is not a low-memory device. // NORMAL -> This is not a low-memory device.
...@@ -181,7 +178,6 @@ public abstract class Linker { ...@@ -181,7 +178,6 @@ public abstract class Linker {
// Indicates if this is a low-memory device or not. The default is to // 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 // determine this by probing the system at runtime, but this can be forced
// for testing by calling setMemoryDeviceConfigForTesting(). // for testing by calling setMemoryDeviceConfigForTesting().
// Not used by ModernLinker.
protected int mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_INIT; protected int mMemoryDeviceConfig = MEMORY_DEVICE_CONFIG_INIT;
// Set to true to enable debug logs. // Set to true to enable debug logs.
...@@ -208,13 +204,6 @@ public abstract class Linker { ...@@ -208,13 +204,6 @@ public abstract class Linker {
// ensure that we don't try to load outside the area originally requested. // ensure that we don't try to load outside the area originally requested.
protected static final int ADDRESS_SPACE_RESERVATION = 192 * 1024 * 1024; 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. // Singleton.
private static Linker sSingleton; private static Linker sSingleton;
private static Object sSingletonLock = new Object(); private static Object sSingletonLock = new Object();
...@@ -223,35 +212,18 @@ public abstract class Linker { ...@@ -223,35 +212,18 @@ public abstract class Linker {
protected Linker() { } protected Linker() { }
/** /**
* Get singleton instance. Returns either a LegacyLinker or a ModernLinker. * Get singleton instance. Returns a LegacyLinker.
*
* 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. * @return the Linker implementation instance.
*/ */
public static final Linker getInstance() { 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) { synchronized (sSingletonLock) {
if (sSingleton == null) { if (sSingleton == null) {
// With incremental install, it's important to fall back to the "normal" sSingleton = LegacyLinker.create();
// 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; return sSingleton;
} }
...@@ -292,56 +264,6 @@ public abstract class Linker { ...@@ -292,56 +264,6 @@ 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 * A public interface used to run runtime linker tests after loading
* libraries. Should only be used to implement the linker unit tests, * libraries. Should only be used to implement the linker unit tests,
...@@ -397,32 +319,30 @@ public abstract class Linker { ...@@ -397,32 +319,30 @@ public abstract class Linker {
} }
/** /**
* Set up the Linker for a test. * Sets the test class name.
* 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 * 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 * runner class name. On subsequent calls, checks that the singleton produced by
* the first call matches the requested type and test runner class name. * the first call matches the test runner class name.
*/ */
public static final void setupForTesting(int type, String testRunnerClassName) { public static final void setupForTesting(String testRunnerClassName) {
if (DEBUG) { if (DEBUG) {
Log.i(TAG, "setupForTesting(" + type + ", " + testRunnerClassName + ") called"); Log.i(TAG, "setupForTesting(" + testRunnerClassName + ") called");
} }
// Sanity check. This method may only be called during tests. // Sanity check. This method may only be called during tests.
assertLinkerTestsAreEnabled(); assertLinkerTestsAreEnabled();
synchronized (sSingletonLock) { synchronized (sSingletonLock) {
// If this is the first call, configure the Linker to the given type and test class. // If this is the first call, instantiate the Linker and the test class.
if (sSingleton == null) { if (sSingleton == null) {
setImplementationForTesting(type); assertLinkerTestsAreEnabled();
assertForTesting(sSingleton == null);
sSingleton = LegacyLinker.create();
sSingleton.setTestRunnerClassNameForTesting(testRunnerClassName); sSingleton.setTestRunnerClassNameForTesting(testRunnerClassName);
return; return;
} }
// If not the first call, check that the Linker configuration matches this request. // If not the first call, check that the Linker configuration matches this request.
assertForTesting(sSingleton.getImplementationForTesting() == type);
String ourTestRunnerClassName = sSingleton.getTestRunnerClassNameForTesting(); String ourTestRunnerClassName = sSingleton.getTestRunnerClassNameForTesting();
if (testRunnerClassName == null) { if (testRunnerClassName == null) {
assertForTesting(ourTestRunnerClassName == null); assertForTesting(ourTestRunnerClassName == null);
......
...@@ -13,8 +13,6 @@ shared_library("chromium_android_linker") { ...@@ -13,8 +13,6 @@ shared_library("chromium_android_linker") {
"legacy_linker_jni.h", "legacy_linker_jni.h",
"linker_jni.cc", "linker_jni.cc",
"linker_jni.h", "linker_jni.h",
"modern_linker_jni.cc",
"modern_linker_jni.h",
] ]
# The NDK contains the crazy_linker here: # The NDK contains the crazy_linker here:
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <string.h> #include <string.h>
#include "legacy_linker_jni.h" #include "legacy_linker_jni.h"
#include "modern_linker_jni.h"
namespace chromium_android_linker { namespace chromium_android_linker {
...@@ -224,8 +223,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { ...@@ -224,8 +223,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
} }
// Initialize linker base and implementations. // Initialize linker base and implementations.
if (!LinkerJNIInit(vm, env) if (!LinkerJNIInit(vm, env) || !LegacyLinkerJNIInit(vm, env)) {
|| !LegacyLinkerJNIInit(vm, env) || !ModernLinkerJNIInit(vm, env)) {
return -1; 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,7 +9,6 @@ from pylib.linker import test_case ...@@ -9,7 +9,6 @@ from pylib.linker import test_case
with host_paths.SysPath(host_paths.BUILD_COMMON_PATH): with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
import unittest_util import unittest_util
_MODERN_LINKER_MINIMUM_SDK_INT = 23
class LinkerTestInstance(test_instance.TestInstance): class LinkerTestInstance(test_instance.TestInstance):
...@@ -26,15 +25,11 @@ class LinkerTestInstance(test_instance.TestInstance): ...@@ -26,15 +25,11 @@ class LinkerTestInstance(test_instance.TestInstance):
def test_filter(self): def test_filter(self):
return self._test_filter return self._test_filter
def GetTests(self, min_device_sdk): def GetTests(self):
tests = [ tests = [
test_case.LinkerSharedRelroTest(is_modern_linker=False, test_case.LinkerSharedRelroTest(is_low_memory=False),
is_low_memory=False), test_case.LinkerSharedRelroTest(is_low_memory=True)
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: if self._test_filter:
filtered_names = unittest_util.FilterTestNames( filtered_names = unittest_util.FilterTestNames(
......
...@@ -124,17 +124,12 @@ class AddressList(list): ...@@ -124,17 +124,12 @@ class AddressList(list):
class LinkerTestCaseBase(object): class LinkerTestCaseBase(object):
"""Base class for linker test cases.""" """Base class for linker test cases."""
def __init__(self, is_modern_linker=False, is_low_memory=False): def __init__(self, is_low_memory=False):
"""Create a test case. """Create a test case.
Args: Args:
is_modern_linker: True to test ModernLinker, False to test LegacyLinker.
is_low_memory: True to simulate a low-memory device, False otherwise. is_low_memory: True to simulate a low-memory device, False otherwise.
""" """
self.is_modern_linker = is_modern_linker test_suffix = 'ForLegacyLinker'
if is_modern_linker:
test_suffix = 'ForModernLinker'
else:
test_suffix = 'ForLegacyLinker'
self.is_low_memory = is_low_memory self.is_low_memory = is_low_memory
if is_low_memory: if is_low_memory:
test_suffix += 'LowMemoryDevice' test_suffix += 'LowMemoryDevice'
...@@ -167,10 +162,7 @@ class LinkerTestCaseBase(object): ...@@ -167,10 +162,7 @@ class LinkerTestCaseBase(object):
logging.info('Running linker test: %s', self.tagged_name) logging.info('Running linker test: %s', self.tagged_name)
# Create command-line file on device. # Create command-line file on device.
if self.is_modern_linker: command_line_flags = ''
command_line_flags = '--use-linker=modern'
else:
command_line_flags = '--use-linker=legacy'
if self.is_low_memory: if self.is_low_memory:
command_line_flags += ' --low-memory-device' command_line_flags += ' --low-memory-device'
device.WriteFile(_COMMAND_LINE_FILE, command_line_flags) device.WriteFile(_COMMAND_LINE_FILE, command_line_flags)
......
...@@ -27,10 +27,6 @@ public class ChromiumLinkerParams { ...@@ -27,10 +27,6 @@ public class ChromiumLinkerParams {
// registered in the service process. // registered in the service process.
public final String mTestRunnerClassNameForTesting; 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 = private static final String EXTRA_LINKER_PARAMS_BASE_LOAD_ADDRESS =
"org.chromium.content.common.linker_params.base_load_address"; "org.chromium.content.common.linker_params.base_load_address";
...@@ -40,27 +36,20 @@ public class ChromiumLinkerParams { ...@@ -40,27 +36,20 @@ public class ChromiumLinkerParams {
private static final String EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME = private static final String EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME =
"org.chromium.content.common.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) { public ChromiumLinkerParams(long baseLoadAddress, boolean waitForSharedRelro) {
mBaseLoadAddress = baseLoadAddress; mBaseLoadAddress = baseLoadAddress;
mWaitForSharedRelro = waitForSharedRelro; mWaitForSharedRelro = waitForSharedRelro;
mTestRunnerClassNameForTesting = null; mTestRunnerClassNameForTesting = null;
mLinkerImplementationForTesting = 0;
} }
/** /**
* Use this constructor to create a LinkerParams instance for testing. * Use this constructor to create a LinkerParams instance for testing.
*/ */
public ChromiumLinkerParams(long baseLoadAddress, public ChromiumLinkerParams(
boolean waitForSharedRelro, long baseLoadAddress, boolean waitForSharedRelro, String testRunnerClassName) {
String testRunnerClassName,
int linkerImplementation) {
mBaseLoadAddress = baseLoadAddress; mBaseLoadAddress = baseLoadAddress;
mWaitForSharedRelro = waitForSharedRelro; mWaitForSharedRelro = waitForSharedRelro;
mTestRunnerClassNameForTesting = testRunnerClassName; mTestRunnerClassNameForTesting = testRunnerClassName;
mLinkerImplementationForTesting = linkerImplementation;
} }
/** /**
...@@ -73,8 +62,7 @@ public class ChromiumLinkerParams { ...@@ -73,8 +62,7 @@ public class ChromiumLinkerParams {
public static ChromiumLinkerParams create(Bundle bundle) { public static ChromiumLinkerParams create(Bundle bundle) {
if (!bundle.containsKey(EXTRA_LINKER_PARAMS_BASE_LOAD_ADDRESS) if (!bundle.containsKey(EXTRA_LINKER_PARAMS_BASE_LOAD_ADDRESS)
|| !bundle.containsKey(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO) || !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 null;
} }
return new ChromiumLinkerParams(bundle); return new ChromiumLinkerParams(bundle);
...@@ -85,8 +73,6 @@ public class ChromiumLinkerParams { ...@@ -85,8 +73,6 @@ public class ChromiumLinkerParams {
mWaitForSharedRelro = bundle.getBoolean(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO, false); mWaitForSharedRelro = bundle.getBoolean(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO, false);
mTestRunnerClassNameForTesting = mTestRunnerClassNameForTesting =
bundle.getString(EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME); bundle.getString(EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME);
mLinkerImplementationForTesting =
bundle.getInt(EXTRA_LINKER_PARAMS_LINKER_IMPLEMENTATION, 0);
} }
/** /**
...@@ -99,7 +85,6 @@ public class ChromiumLinkerParams { ...@@ -99,7 +85,6 @@ public class ChromiumLinkerParams {
bundle.putBoolean(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO, mWaitForSharedRelro); bundle.putBoolean(EXTRA_LINKER_PARAMS_WAIT_FOR_SHARED_RELRO, mWaitForSharedRelro);
bundle.putString( bundle.putString(
EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME, mTestRunnerClassNameForTesting); EXTRA_LINKER_PARAMS_TEST_RUNNER_CLASS_NAME, mTestRunnerClassNameForTesting);
bundle.putInt(EXTRA_LINKER_PARAMS_LINKER_IMPLEMENTATION, mLinkerImplementationForTesting);
} }
// For debugging traces only. // For debugging traces only.
...@@ -107,8 +92,8 @@ public class ChromiumLinkerParams { ...@@ -107,8 +92,8 @@ public class ChromiumLinkerParams {
public String toString() { public String toString() {
return String.format(Locale.US, return String.format(Locale.US,
"LinkerParams(baseLoadAddress:0x%x, waitForSharedRelro:%s, " "LinkerParams(baseLoadAddress:0x%x, waitForSharedRelro:%s, "
+ "testRunnerClassName:%s, linkerImplementation:%d", + "testRunnerClassName:%s",
mBaseLoadAddress, Boolean.toString(mWaitForSharedRelro), mBaseLoadAddress, Boolean.toString(mWaitForSharedRelro),
mTestRunnerClassNameForTesting, mLinkerImplementationForTesting); mTestRunnerClassNameForTesting);
} }
} }
...@@ -196,8 +196,7 @@ public class ContentChildProcessServiceDelegate implements ChildProcessServiceDe ...@@ -196,8 +196,7 @@ public class ContentChildProcessServiceDelegate implements ChildProcessServiceDe
// For testing, set the Linker implementation and the test runner // For testing, set the Linker implementation and the test runner
// class name to match those used by the parent. // class name to match those used by the parent.
assert mLinkerParams != null; assert mLinkerParams != null;
Linker.setupForTesting(mLinkerParams.mLinkerImplementationForTesting, Linker.setupForTesting(mLinkerParams.mTestRunnerClassNameForTesting);
mLinkerParams.mTestRunnerClassNameForTesting);
} }
return Linker.getInstance(); return Linker.getInstance();
} }
......
...@@ -577,8 +577,7 @@ public class ChildProcessLauncherHelper { ...@@ -577,8 +577,7 @@ public class ChildProcessLauncherHelper {
if (Linker.areTestsEnabled()) { if (Linker.areTestsEnabled()) {
Linker linker = Linker.getInstance(); Linker linker = Linker.getInstance();
return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRelros, return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRelros,
linker.getTestRunnerClassNameForTesting(), linker.getTestRunnerClassNameForTesting());
linker.getImplementationForTesting());
} else { } else {
return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRelros); return new ChromiumLinkerParams(sLinkerLoadAddress, waitForSharedRelros);
} }
......
...@@ -46,11 +46,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) { ...@@ -46,11 +46,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
// //
// "/dev/ashmem/RELRO:<libname> (deleted)" // "/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 // Where <libname> is the library name and '(deleted)' is actually
// added by the kernel to indicate there is no corresponding file // added by the kernel to indicate there is no corresponding file
// on the filesystem. // on the filesystem.
...@@ -59,7 +54,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) { ...@@ -59,7 +54,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
// section, but for the component build, there are several libraries, // section, but for the component build, there are several libraries,
// each one with its own RELRO. // each one with its own RELRO.
static const char kLegacyRelroSectionPattern[] = "/dev/ashmem/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 // Parse /proc/self/maps and builds a list of region mappings in this
// process. // process.
...@@ -78,7 +72,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) { ...@@ -78,7 +72,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
} }
const RE2 legacy_linker_re(kLegacyRelroSectionPattern); const RE2 legacy_linker_re(kLegacyRelroSectionPattern);
const RE2 modern_linker_re(kModernRelroSectionPattern);
int num_shared_relros = 0; int num_shared_relros = 0;
int num_bad_shared_relros = 0; int num_bad_shared_relros = 0;
...@@ -88,15 +81,8 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) { ...@@ -88,15 +81,8 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
const std::string path = region.path; const std::string path = region.path;
const bool is_legacy_relro = re2::RE2::FullMatch(path, legacy_linker_re); 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 && is_modern_relro) { if (!is_legacy_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. // Ignore any mapping that isn't a shared RELRO.
continue; continue;
} }
...@@ -127,16 +113,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) { ...@@ -127,16 +113,6 @@ jboolean RunChecks(bool in_browser_process, bool need_relros) {
continue; 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 // Check that trying to remap it read-write fails with EACCES
size_t region_size = region.end - region.start; size_t region_size = region.end - region.start;
int ret = ::mprotect(region_start, region_size, PROT_READ | PROT_WRITE); int ret = ::mprotect(region_start, region_size, PROT_READ | PROT_WRITE);
......
...@@ -39,12 +39,6 @@ public class ChromiumLinkerTestActivity extends Activity { ...@@ -39,12 +39,6 @@ public class ChromiumLinkerTestActivity extends Activity {
// target device running the test really is. // target device running the test really is.
private static final String LOW_MEMORY_DEVICE = "--low-memory-device"; 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 ShellManager mShellManager;
private ActivityWindowAndroid mWindowAndroid; private ActivityWindowAndroid mWindowAndroid;
...@@ -64,8 +58,6 @@ public class ChromiumLinkerTestActivity extends Activity { ...@@ -64,8 +58,6 @@ public class ChromiumLinkerTestActivity extends Activity {
// CommandLine.getInstance().hasSwitch() doesn't work here for some funky // CommandLine.getInstance().hasSwitch() doesn't work here for some funky
// reason, so parse the command-line differently here: // reason, so parse the command-line differently here:
boolean hasLowMemoryDeviceSwitch = false; boolean hasLowMemoryDeviceSwitch = false;
boolean hasModernLinkerSwitch = false;
boolean hasLegacyLinkerSwitch = false;
String[] commandLine = CommandLine.getJavaSwitchesOrNull(); String[] commandLine = CommandLine.getJavaSwitchesOrNull();
if (commandLine == null) { if (commandLine == null) {
Log.i(TAG, "Command line is null"); Log.i(TAG, "Command line is null");
...@@ -76,31 +68,11 @@ public class ChromiumLinkerTestActivity extends Activity { ...@@ -76,31 +68,11 @@ public class ChromiumLinkerTestActivity extends Activity {
Log.i(TAG, " '" + option + "'"); Log.i(TAG, " '" + option + "'");
if (option.equals(LOW_MEMORY_DEVICE)) { if (option.equals(LOW_MEMORY_DEVICE)) {
hasLowMemoryDeviceSwitch = true; hasLowMemoryDeviceSwitch = true;
} else if (option.equals(USE_MODERN_LINKER)) {
hasModernLinkerSwitch = true;
} else if (option.equals(USE_LEGACY_LINKER)) {
hasLegacyLinkerSwitch = true;
} }
} }
} }
if (!(hasModernLinkerSwitch || hasLegacyLinkerSwitch)) { Linker.setupForTesting(LinkerTests.class.getName());
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. // Determine which kind of device to simulate from the command-line.
int memoryDeviceConfig = Linker.MEMORY_DEVICE_CONFIG_NORMAL; int memoryDeviceConfig = Linker.MEMORY_DEVICE_CONFIG_NORMAL;
......
...@@ -23,37 +23,23 @@ public class LinkerTests implements Linker.TestRunner { ...@@ -23,37 +23,23 @@ public class LinkerTests implements Linker.TestRunner {
boolean isBrowserProcess) { boolean isBrowserProcess) {
boolean checkSharedRelro; boolean checkSharedRelro;
if (isBrowserProcess) { if (isBrowserProcess) {
Linker linker = Linker.getInstance(); switch (Linker.BROWSER_SHARED_RELRO_CONFIG) {
int linkerImplementation = linker.getImplementationForTesting(); case Linker.BROWSER_SHARED_RELRO_CONFIG_NEVER:
checkSharedRelro = false;
if (linkerImplementation == Linker.LINKER_IMPLEMENTATION_LEGACY) { break;
// LegacyLinker may share RELROs in the browser. case Linker.BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY:
switch (Linker.BROWSER_SHARED_RELRO_CONFIG) { // A shared RELRO should only be used on low-end devices.
case Linker.BROWSER_SHARED_RELRO_CONFIG_NEVER: checkSharedRelro = (memoryDeviceConfig == Linker.MEMORY_DEVICE_CONFIG_LOW);
checkSharedRelro = false; break;
break; case Linker.BROWSER_SHARED_RELRO_CONFIG_ALWAYS:
case Linker.BROWSER_SHARED_RELRO_CONFIG_LOW_RAM_ONLY: // Always check for a shared RELRO.
// A shared RELRO should only be used on low-end devices. checkSharedRelro = true;
checkSharedRelro = break;
(memoryDeviceConfig == Linker.MEMORY_DEVICE_CONFIG_LOW); default:
break; Log.e(TAG,
case Linker.BROWSER_SHARED_RELRO_CONFIG_ALWAYS: "Invalid shared RELRO linker configuration: "
// Always check for a shared RELRO. + Linker.BROWSER_SHARED_RELRO_CONFIG);
checkSharedRelro = true; return false;
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 { } else {
// Service processes should always use a shared RELRO section. // 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