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()|.
dummy_function_end_of_ordered_text()31 void dummy_function_end_of_ordered_text() {
32   asm(".word 0x21bad44d");
33   asm(".word 0xb815c5b0");
34 }
35 
dummy_function_start_of_ordered_text()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 
IsOrderingSane()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