diff options
Diffstat (limited to 'base/android/library_loader')
-rw-r--r-- | base/android/library_loader/README.md | 10 | ||||
-rw-r--r-- | base/android/library_loader/anchor_functions.cc | 79 | ||||
-rw-r--r-- | base/android/library_loader/anchor_functions.h | 32 | ||||
-rw-r--r-- | base/android/library_loader/anchor_functions.lds | 7 |
4 files changed, 128 insertions, 0 deletions
diff --git a/base/android/library_loader/README.md b/base/android/library_loader/README.md new file mode 100644 index 0000000000..7773b32b08 --- /dev/null +++ b/base/android/library_loader/README.md @@ -0,0 +1,10 @@ +# //base/android/library_loader + +Native code is split between this directory and: + * [//third_party/android_crazy_linker](../../../third_party/android_crazy_linker/README.chromium) + +Java code lives at: + * [//base/android/java/src/org/chromium/base/library_loader/](../java/src/org/chromium/base/library_loader/) + +A high-level guide to native code on Android exists at: + * [//docs/android_native_libraries.md](../../../docs/android_native_libraries.md) diff --git a/base/android/library_loader/anchor_functions.cc b/base/android/library_loader/anchor_functions.cc new file mode 100644 index 0000000000..0865d9d869 --- /dev/null +++ b/base/android/library_loader/anchor_functions.cc @@ -0,0 +1,79 @@ +// Copyright 2017 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. + +#include "base/android/library_loader/anchor_functions.h" + +#include "base/logging.h" +#include "build/build_config.h" + +#if BUILDFLAG(SUPPORTS_CODE_ORDERING) + +// These functions are here to delimit the start and end of the ordered part of +// .text. They require a suitably constructed orderfile, with these functions at +// the beginning and end. +// +// These functions are weird: this is due to ICF (Identical Code Folding). +// The linker merges functions that have the same code, which would be the case +// if these functions were empty, or simple. +// Gold's flag --icf=safe will *not* alias functions when their address is used +// in code, but as of November 2017, we use the default setting that +// deduplicates function in this case as well. +// +// Thus these functions are made to be unique, using inline .word in assembly. +// +// Note that code |CheckOrderingSanity()| below will make sure that these +// functions are not aliased, in case the toolchain becomes really clever. +extern "C" { + +// These functions have a well-defined ordering in this file, see the comment +// in |IsOrderingSane()|. +void dummy_function_end_of_ordered_text() { + asm(".word 0x21bad44d"); + asm(".word 0xb815c5b0"); +} + +void dummy_function_start_of_ordered_text() { + asm(".word 0xe4a07375"); + asm(".word 0x66dda6dc"); +} + +// These two symbols are defined by anchor_functions.lds and delimit the start +// and end of .text. +void linker_script_start_of_text(); +void linker_script_end_of_text(); + +} // extern "C" + +namespace base { +namespace android { + +const size_t kStartOfText = + reinterpret_cast<size_t>(linker_script_start_of_text); +const size_t kEndOfText = reinterpret_cast<size_t>(linker_script_end_of_text); +const size_t kStartOfOrderedText = + reinterpret_cast<size_t>(dummy_function_start_of_ordered_text); +const size_t kEndOfOrderedText = + reinterpret_cast<size_t>(dummy_function_end_of_ordered_text); + +bool IsOrderingSane() { + size_t here = reinterpret_cast<size_t>(&IsOrderingSane); + // The symbols linker_script_start_of_text and linker_script_end_of_text + // should cover all of .text, and dummy_function_start_of_ordered_text and + // dummy_function_end_of_ordered_text should cover the ordered part of it. + // This check is intended to catch the lack of ordering. + // + // Ordered text can start at the start of text, but should not cover the + // entire range. Most addresses are distinct nonetheless as the symbols are + // different, but linker-defined symbols have zero size and therefore the + // start address could be the same as the address of + // dummy_function_start_of_ordered_text. + return kStartOfText < here && here < kEndOfText && + kStartOfOrderedText < kEndOfOrderedText && + kStartOfText <= kStartOfOrderedText && kEndOfOrderedText < kEndOfText; +} + +} // namespace android +} // namespace base + +#endif // BUILDFLAG(SUPPORTS_CODE_ORDERING) diff --git a/base/android/library_loader/anchor_functions.h b/base/android/library_loader/anchor_functions.h new file mode 100644 index 0000000000..9894583a52 --- /dev/null +++ b/base/android/library_loader/anchor_functions.h @@ -0,0 +1,32 @@ +// Copyright 2017 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_LIBRARY_LOADER_ANCHOR_FUNCTIONS_H_ +#define BASE_ANDROID_LIBRARY_LOADER_ANCHOR_FUNCTIONS_H_ + +#include <cstdint> +#include "base/android/library_loader/anchor_functions_buildflags.h" + +#include "base/base_export.h" + +#if BUILDFLAG(SUPPORTS_CODE_ORDERING) + +namespace base { +namespace android { + +// Start and end of .text, respectively. +BASE_EXPORT extern const size_t kStartOfText; +BASE_EXPORT extern const size_t kEndOfText; +// Start and end of the ordered part of .text, respectively. +BASE_EXPORT extern const size_t kStartOfOrderedText; +BASE_EXPORT extern const size_t kEndOfOrderedText; + +// Returns true if the ordering looks sane. +BASE_EXPORT bool IsOrderingSane(); + +} // namespace android +} // namespace base +#endif // BUILDFLAG(SUPPORTS_CODE_ORDERING) + +#endif // BASE_ANDROID_LIBRARY_LOADER_ANCHOR_FUNCTIONS_H_ diff --git a/base/android/library_loader/anchor_functions.lds b/base/android/library_loader/anchor_functions.lds new file mode 100644 index 0000000000..cdeaaa2a37 --- /dev/null +++ b/base/android/library_loader/anchor_functions.lds @@ -0,0 +1,7 @@ +# Copyright 2018 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. + +# Define symbols that point to the start and end of the .text section. +PROVIDE_HIDDEN(linker_script_start_of_text = ADDR(.text)); +PROVIDE_HIDDEN(linker_script_end_of_text = ADDR(.text) + SIZEOF(.text)); |