xref: /aosp_15_r20/external/cronet/base/android/library_loader/anchor_functions.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 The Chromium Authors
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 "build/build_config.h"
8 
9 #if BUILDFLAG(SUPPORTS_CODE_ORDERING)
10 
11 // These functions are here to delimit the start and end of the ordered part of
12 // .text. They require a suitably constructed orderfile, with these functions at
13 // the beginning and end.
14 //
15 // These functions are weird: this is due to ICF (Identical Code Folding).
16 // The linker merges functions that have the same code, which would be the case
17 // if these functions were empty, or simple.
18 // Gold's flag --icf=safe will *not* alias functions when their address is used
19 // in code, but as of November 2017, we use the default setting that
20 // deduplicates function in this case as well.
21 //
22 // Thus these functions are made to be unique, using inline .word in assembly,
23 // or the equivalent directive depending on the architecture.
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 // The assembler has a different syntax depending on the architecture.
30 #if defined(ARCH_CPU_ARMEL) || defined(ARCH_CPU_ARM64)
31 
32 // These functions have a well-defined ordering in this file, see the comment
33 // in |IsOrderingSane()|.
dummy_function_end_of_ordered_text()34 void dummy_function_end_of_ordered_text() {
35   asm(".word 0x21bad44d");
36   asm(".word 0xb815c5b0");
37 }
38 
dummy_function_start_of_ordered_text()39 void dummy_function_start_of_ordered_text() {
40   asm(".word 0xe4a07375");
41   asm(".word 0x66dda6dc");
42 }
43 
44 #elif defined(ARCH_CPU_X86_FAMILY)
45 
46 void dummy_function_end_of_ordered_text() {
47   asm(".4byte 0x21bad44d");
48   asm(".4byte 0xb815c5b0");
49 }
50 
51 void dummy_function_start_of_ordered_text() {
52   asm(".4byte 0xe4a07375");
53   asm(".4byte 0x66dda6dc");
54 }
55 
56 #endif
57 
58 // These two symbols are defined by anchor_functions.lds and delimit the start
59 // and end of .text.
60 void linker_script_start_of_text();
61 void linker_script_end_of_text();
62 
63 }  // extern "C"
64 
65 namespace base {
66 namespace android {
67 
68 const size_t kStartOfText =
69     reinterpret_cast<size_t>(linker_script_start_of_text);
70 const size_t kEndOfText = reinterpret_cast<size_t>(linker_script_end_of_text);
71 const size_t kStartOfOrderedText =
72     reinterpret_cast<size_t>(dummy_function_start_of_ordered_text);
73 const size_t kEndOfOrderedText =
74     reinterpret_cast<size_t>(dummy_function_end_of_ordered_text);
75 
AreAnchorsSane()76 __attribute__((no_instrument_function)) bool AreAnchorsSane() {
77   size_t here = reinterpret_cast<size_t>(&IsOrderingSane);
78   return kStartOfText < here && here < kEndOfText;
79 }
80 
IsOrderingSane()81 __attribute__((no_instrument_function)) bool IsOrderingSane() {
82   // The symbols linker_script_start_of_text and linker_script_end_of_text
83   // should cover all of .text, and dummy_function_start_of_ordered_text and
84   // dummy_function_end_of_ordered_text should cover the ordered part of it.
85   // This check is intended to catch the lack of ordering.
86   //
87   // Ordered text can start at the start of text, but should not cover the
88   // entire range. Most addresses are distinct nonetheless as the symbols are
89   // different, but linker-defined symbols have zero size and therefore the
90   // start address could be the same as the address of
91   // dummy_function_start_of_ordered_text.
92   return AreAnchorsSane() && kStartOfOrderedText < kEndOfOrderedText &&
93          kStartOfText <= kStartOfOrderedText && kEndOfOrderedText < kEndOfText;
94 }
95 
96 }  // namespace android
97 }  // namespace base
98 
99 #endif  // BUILDFLAG(SUPPORTS_CODE_ORDERING)
100