mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 22:36:09 +03:00
80 lines
3.0 KiB
C++
80 lines
3.0 KiB
C++
|
// 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)
|