tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

location.cc (4922B)


      1 // Copyright 2012 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/location.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "base/trace_event/base_tracing.h"
     11 
     12 #if defined(COMPILER_MSVC)
     13 #include <intrin.h>
     14 #endif
     15 
     16 namespace base {
     17 
     18 namespace {
     19 
     20 // Returns the length of the given null terminated c-string.
     21 constexpr size_t StrLen(const char* str) {
     22  size_t str_len = 0;
     23  for (str_len = 0; str[str_len] != '\0'; ++str_len)
     24    ;
     25  return str_len;
     26 }
     27 
     28 // Finds the length of the build folder prefix from the file path.
     29 // TODO(ssid): Strip prefixes from stored strings in the binary. This code only
     30 // skips the prefix while reading the file name strings at runtime.
     31 constexpr size_t StrippedFilePathPrefixLength() {
     32  constexpr char path[] = __FILE__;
     33  // Only keep the file path starting from the src directory.
     34 #if defined(__clang__) && defined(_MSC_VER)
     35  constexpr char stripped[] = "base\\location.cc";
     36 #else
     37  constexpr char stripped[] = "base/location.cc";
     38 #endif
     39  constexpr size_t path_len = StrLen(path);
     40  constexpr size_t stripped_len = StrLen(stripped);
     41  static_assert(path_len >= stripped_len,
     42                "Invalid file path for base/location.cc.");
     43  return path_len - stripped_len;
     44 }
     45 
     46 constexpr size_t kStrippedPrefixLength = StrippedFilePathPrefixLength();
     47 
     48 // Returns true if the |name| string has |prefix_len| characters in the prefix
     49 // and the suffix matches the |expected| string.
     50 // TODO(ssid): With C++20 we can make base::EndsWith() constexpr and use it
     51 //  instead.
     52 constexpr bool StrEndsWith(const char* name,
     53                           size_t prefix_len,
     54                           const char* expected) {
     55  const size_t name_len = StrLen(name);
     56  const size_t expected_len = StrLen(expected);
     57  if (name_len != prefix_len + expected_len)
     58    return false;
     59  for (size_t i = 0; i < expected_len; ++i) {
     60    if (name[i + prefix_len] != expected[i])
     61      return false;
     62  }
     63  return true;
     64 }
     65 
     66 #if defined(__clang__) && defined(_MSC_VER) && !defined(MOZ_SANDBOX)
     67 static_assert(StrEndsWith(__FILE__, kStrippedPrefixLength, "base\\location.cc"),
     68              "The file name does not match the expected prefix format.");
     69 #else
     70 static_assert(StrEndsWith(__FILE__, kStrippedPrefixLength, "base/location.cc"),
     71              "The file name does not match the expected prefix format.");
     72 #endif
     73 
     74 }  // namespace
     75 
     76 Location::Location() = default;
     77 Location::Location(const Location& other) = default;
     78 Location::Location(Location&& other) noexcept = default;
     79 Location& Location::operator=(const Location& other) = default;
     80 
     81 Location::Location(const char* file_name, const void* program_counter)
     82    : file_name_(file_name), program_counter_(program_counter) {}
     83 
     84 Location::Location(const char* function_name,
     85                   const char* file_name,
     86                   int line_number,
     87                   const void* program_counter)
     88    : function_name_(function_name),
     89      file_name_(file_name),
     90      line_number_(line_number),
     91      program_counter_(program_counter) {
     92 #if !BUILDFLAG(IS_NACL)
     93  // The program counter should not be null except in a default constructed
     94  // (empty) Location object. This value is used for identity, so if it doesn't
     95  // uniquely identify a location, things will break.
     96  //
     97  // The program counter isn't supported in NaCl so location objects won't work
     98  // properly in that context.
     99  DCHECK(program_counter);
    100 #endif
    101 }
    102 
    103 std::string Location::ToString() const {
    104  if (has_source_info()) {
    105    return std::string(function_name_) + "@" + file_name_ + ":" +
    106           NumberToString(line_number_);
    107  }
    108  return StringPrintf("pc:%p", program_counter_);
    109 }
    110 
    111 void Location::WriteIntoTrace(perfetto::TracedValue context) const {
    112  auto dict = std::move(context).WriteDictionary();
    113  dict.Add("function_name", function_name_);
    114  dict.Add("file_name", file_name_);
    115  dict.Add("line_number", line_number_);
    116 }
    117 
    118 #if defined(COMPILER_MSVC)
    119 #define RETURN_ADDRESS() _ReturnAddress()
    120 #elif defined(COMPILER_GCC) && !BUILDFLAG(IS_NACL)
    121 #define RETURN_ADDRESS() \
    122  __builtin_extract_return_addr(__builtin_return_address(0))
    123 #else
    124 #define RETURN_ADDRESS() nullptr
    125 #endif
    126 
    127 #if SUPPORTS_LOCATION_BUILTINS
    128 // static
    129 NOINLINE Location Location::Current(const char* function_name,
    130                                    const char* file_name,
    131                                    int line_number) {
    132  return Location(function_name, file_name + kStrippedPrefixLength, line_number,
    133                  RETURN_ADDRESS());
    134 }
    135 #else
    136 // static
    137 NOINLINE Location Location::Current() {
    138  return Location(nullptr, RETURN_ADDRESS());
    139 }
    140 #endif
    141 //------------------------------------------------------------------------------
    142 NOINLINE const void* GetProgramCounter() {
    143  return RETURN_ADDRESS();
    144 }
    145 
    146 }  // namespace base