// Copyright 2018 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/profiler/module_cache.h" #include <dlfcn.h> #include <elf.h> #include <optional> #include <string_view> #include "base/debug/elf_reader.h" #include "build/build_config.h" #if BUILDFLAG(IS_ANDROID) extern "C" { // &__executable_start is the start address of the current module. extern const char __executable_start; // &__etext is the end addesss of the code segment in the current module. extern const char _etext; } #endif namespace base { namespace { // Returns the unique build ID for a module loaded at |module_addr|. Returns the // empty string if the function fails to get the build ID. // // Build IDs follow a cross-platform format consisting of several fields // concatenated together: // - the module's unique ID, and // - the age suffix for incremental builds. // // On POSIX, the unique ID is read from the ELF binary located at |module_addr|. // The age field is always 0. std::string GetUniqueBuildId(const void* module_addr) { … } // Returns the offset from |module_addr| to the first byte following the last // executable segment from the ELF file mapped at |module_addr|. // It's defined this way so that any executable address from this module is in // range [addr, addr + GetLastExecutableOffset(addr)). // If no executable segment is found, returns 0. size_t GetLastExecutableOffset(const void* module_addr) { … } FilePath GetDebugBasenameForModule(const void* base_address, std::string_view file) { … } class PosixModule : public ModuleCache::Module { … }; PosixModule::PosixModule(uintptr_t base_address, const std::string& build_id, const FilePath& debug_basename, size_t size) : … { … } } // namespace // static std::unique_ptr<const ModuleCache::Module> ModuleCache::CreateModuleForAddress( uintptr_t address) { … } } // namespace base