// 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(linker_script_start_of_text); const size_t kEndOfText = reinterpret_cast(linker_script_end_of_text); const size_t kStartOfOrderedText = reinterpret_cast(dummy_function_start_of_ordered_text); const size_t kEndOfOrderedText = reinterpret_cast(dummy_function_end_of_ordered_text); bool IsOrderingSane() { size_t here = reinterpret_cast(&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)