Home | History | Annotate | Download | only in library_loader
      1 // Copyright 2017 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/android/library_loader/anchor_functions.h"
      6 
      7 #include "base/logging.h"
      8 #include "build/build_config.h"
      9 
     10 #if BUILDFLAG(SUPPORTS_CODE_ORDERING)
     11 
     12 // These functions are here to delimit the start and end of the ordered part of
     13 // .text. They require a suitably constructed orderfile, with these functions at
     14 // the beginning and end.
     15 //
     16 // These functions are weird: this is due to ICF (Identical Code Folding).
     17 // The linker merges functions that have the same code, which would be the case
     18 // if these functions were empty, or simple.
     19 // Gold's flag --icf=safe will *not* alias functions when their address is used
     20 // in code, but as of November 2017, we use the default setting that
     21 // deduplicates function in this case as well.
     22 //
     23 // Thus these functions are made to be unique, using inline .word in assembly.
     24 //
     25 // Note that code |CheckOrderingSanity()| below will make sure that these
     26 // functions are not aliased, in case the toolchain becomes really clever.
     27 extern "C" {
     28 
     29 // These functions have a well-defined ordering in this file, see the comment
     30 // in |IsOrderingSane()|.
     31 void dummy_function_end_of_ordered_text() {
     32   asm(".word 0x21bad44d");
     33   asm(".word 0xb815c5b0");
     34 }
     35 
     36 void dummy_function_start_of_ordered_text() {
     37   asm(".word 0xe4a07375");
     38   asm(".word 0x66dda6dc");
     39 }
     40 
     41 // These two symbols are defined by anchor_functions.lds and delimit the start
     42 // and end of .text.
     43 void linker_script_start_of_text();
     44 void linker_script_end_of_text();
     45 
     46 }  // extern "C"
     47 
     48 namespace base {
     49 namespace android {
     50 
     51 const size_t kStartOfText =
     52     reinterpret_cast<size_t>(linker_script_start_of_text);
     53 const size_t kEndOfText = reinterpret_cast<size_t>(linker_script_end_of_text);
     54 const size_t kStartOfOrderedText =
     55     reinterpret_cast<size_t>(dummy_function_start_of_ordered_text);
     56 const size_t kEndOfOrderedText =
     57     reinterpret_cast<size_t>(dummy_function_end_of_ordered_text);
     58 
     59 bool IsOrderingSane() {
     60   size_t here = reinterpret_cast<size_t>(&IsOrderingSane);
     61   // The symbols linker_script_start_of_text and linker_script_end_of_text
     62   // should cover all of .text, and dummy_function_start_of_ordered_text and
     63   // dummy_function_end_of_ordered_text should cover the ordered part of it.
     64   // This check is intended to catch the lack of ordering.
     65   //
     66   // Ordered text can start at the start of text, but should not cover the
     67   // entire range. Most addresses are distinct nonetheless as the symbols are
     68   // different, but linker-defined symbols have zero size and therefore the
     69   // start address could be the same as the address of
     70   // dummy_function_start_of_ordered_text.
     71   return kStartOfText < here && here < kEndOfText &&
     72          kStartOfOrderedText < kEndOfOrderedText &&
     73          kStartOfText <= kStartOfOrderedText && kEndOfOrderedText < kEndOfText;
     74 }
     75 
     76 }  // namespace android
     77 }  // namespace base
     78 
     79 #endif  // BUILDFLAG(SUPPORTS_CODE_ORDERING)
     80