diff options
Diffstat (limited to 'third_party/abseil-cpp/absl/debugging/symbolize_elf.inc')
-rw-r--r-- | third_party/abseil-cpp/absl/debugging/symbolize_elf.inc | 134 |
1 files changed, 20 insertions, 114 deletions
diff --git a/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc b/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc index 3ff343d64f..c371635ffa 100644 --- a/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +++ b/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc @@ -57,7 +57,6 @@ #include <unistd.h> #include <algorithm> -#include <array> #include <atomic> #include <cerrno> #include <cinttypes> @@ -75,11 +74,6 @@ #include "absl/base/port.h" #include "absl/debugging/internal/demangle.h" #include "absl/debugging/internal/vdso_support.h" -#include "absl/strings/string_view.h" - -#if defined(__FreeBSD__) && !defined(ElfW) -#define ElfW(x) __ElfN(x) -#endif namespace absl { ABSL_NAMESPACE_BEGIN @@ -88,12 +82,6 @@ ABSL_NAMESPACE_BEGIN static char *argv0_value = nullptr; void InitializeSymbolizer(const char *argv0) { -#ifdef ABSL_HAVE_VDSO_SUPPORT - // We need to make sure VDSOSupport::Init() is called before any setuid or - // chroot calls, so InitializeSymbolizer() should be called very early in the - // life of a program. - absl::debugging_internal::VDSOSupport::Init(); -#endif if (argv0_value != nullptr) { free(argv0_value); argv0_value = nullptr; @@ -161,15 +149,13 @@ struct FileMappingHint { // Moreover, we are using only TryLock(), if the decorator list // is being modified (is busy), we skip all decorators, and possibly // loose some info. Sorry, that's the best we could do. -ABSL_CONST_INIT absl::base_internal::SpinLock g_decorators_mu( - absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY); +base_internal::SpinLock g_decorators_mu(base_internal::kLinkerInitialized); const int kMaxFileMappingHints = 8; int g_num_file_mapping_hints; FileMappingHint g_file_mapping_hints[kMaxFileMappingHints]; // Protects g_file_mapping_hints. -ABSL_CONST_INIT absl::base_internal::SpinLock g_file_mapping_mu( - absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY); +base_internal::SpinLock g_file_mapping_mu(base_internal::kLinkerInitialized); // Async-signal-safe function to zero a buffer. // memset() is not guaranteed to be async-signal-safe. @@ -189,7 +175,6 @@ struct ObjFile { fd(-1), elf_type(-1) { SafeMemZero(&elf_header, sizeof(elf_header)); - SafeMemZero(&phdr[0], sizeof(phdr)); } char *filename; @@ -202,10 +187,6 @@ struct ObjFile { int fd; int elf_type; ElfW(Ehdr) elf_header; - - // PT_LOAD program header describing executable code. - // Normally we expect just one, but SWIFT binaries have two. - std::array<ElfW(Phdr), 2> phdr; }; // Build 4-way associative cache for symbols. Within each cache line, symbols @@ -515,7 +496,7 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType( const int kMaxSectionNameLen = 64; bool ForEachSection(int fd, - const std::function<bool(absl::string_view name, + const std::function<bool(const std::string &name, const ElfW(Shdr) &)> &callback) { ElfW(Ehdr) elf_header; if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { @@ -537,7 +518,7 @@ bool ForEachSection(int fd, return false; } off_t name_offset = shstrtab.sh_offset + out.sh_name; - char header_name[kMaxSectionNameLen]; + char header_name[kMaxSectionNameLen + 1]; ssize_t n_read = ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset); if (n_read == -1) { @@ -546,8 +527,9 @@ bool ForEachSection(int fd, // Long read? return false; } + header_name[n_read] = '\0'; - absl::string_view name(header_name, strnlen(header_name, n_read)); + std::string name(header_name); if (!callback(name, out)) { break; } @@ -705,16 +687,6 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( const char *start_address = ComputeOffset(original_start_address, relocation); -#ifdef __arm__ - // ARM functions are always aligned to multiples of two bytes; the - // lowest-order bit in start_address is ignored by the CPU and indicates - // whether the function contains ARM (0) or Thumb (1) code. We don't care - // about what encoding is being used; we just want the real start address - // of the function. - start_address = reinterpret_cast<const char *>( - reinterpret_cast<uintptr_t>(start_address) & ~1); -#endif - if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { // The opd section is mapped into memory. Just dereference @@ -1292,36 +1264,6 @@ static bool MaybeInitializeObjFile(ObjFile *obj) { ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename); return false; } - const int phnum = obj->elf_header.e_phnum; - const int phentsize = obj->elf_header.e_phentsize; - size_t phoff = obj->elf_header.e_phoff; - size_t num_executable_load_segments = 0; - for (int j = 0; j < phnum; j++) { - ElfW(Phdr) phdr; - if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) { - ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d", - obj->filename, j); - return false; - } - phoff += phentsize; - constexpr int rx = PF_X | PF_R; - if (phdr.p_type != PT_LOAD || (phdr.p_flags & rx) != rx) { - // Not a LOAD segment, or not executable code. - continue; - } - if (num_executable_load_segments < obj->phdr.size()) { - memcpy(&obj->phdr[num_executable_load_segments++], &phdr, sizeof(phdr)); - } else { - ABSL_RAW_LOG(WARNING, "%s: too many executable LOAD segments", - obj->filename); - break; - } - } - if (num_executable_load_segments == 0) { - // This object has no "r-x" LOAD segments. That's unexpected. - ABSL_RAW_LOG(WARNING, "%s: no executable LOAD segments", obj->filename); - return false; - } } return true; } @@ -1345,52 +1287,23 @@ const char *Symbolizer::GetSymbol(const void *const pc) { int fd = -1; if (obj != nullptr) { if (MaybeInitializeObjFile(obj)) { - const size_t start_addr = reinterpret_cast<size_t>(obj->start_addr); - if (obj->elf_type == ET_DYN && start_addr >= obj->offset) { + if (obj->elf_type == ET_DYN && + reinterpret_cast<uint64_t>(obj->start_addr) >= obj->offset) { // This object was relocated. // // For obj->offset > 0, adjust the relocation since a mapping at offset // X in the file will have a start address of [true relocation]+X. - relocation = start_addr - obj->offset; - - // Note: some binaries have multiple "rx" LOAD segments. We must - // find the right one. - ElfW(Phdr) *phdr = nullptr; - for (size_t j = 0; j < obj->phdr.size(); j++) { - ElfW(Phdr) &p = obj->phdr[j]; - if (p.p_type != PT_LOAD) { - // We only expect PT_LOADs. This must be PT_NULL that we didn't - // write over (i.e. we exhausted all interesting PT_LOADs). - ABSL_RAW_CHECK(p.p_type == PT_NULL, "unexpected p_type"); - break; - } - if (pc < reinterpret_cast<void *>(start_addr + p.p_memsz)) { - phdr = &p; - break; - } - } - if (phdr == nullptr) { - // That's unexpected. Hope for the best. - ABSL_RAW_LOG( - WARNING, - "%s: unable to find LOAD segment for pc: %p, start_addr: %zx", - obj->filename, pc, start_addr); - } else { - // Adjust relocation in case phdr.p_vaddr != 0. - // This happens for binaries linked with `lld --rosegment`, and for - // binaries linked with BFD `ld -z separate-code`. - relocation -= phdr->p_vaddr - phdr->p_offset; - } + relocation = reinterpret_cast<ptrdiff_t>(obj->start_addr) - obj->offset; } fd = obj->fd; - if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_, - sizeof(symbol_buf_), tmp_buf_, - sizeof(tmp_buf_)) == SYMBOL_FOUND) { - // Only try to demangle the symbol name if it fit into symbol_buf_. - DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_, - sizeof(tmp_buf_)); - } + } + if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_, + sizeof(symbol_buf_), tmp_buf_, + sizeof(tmp_buf_)) == SYMBOL_FOUND) { + // Only try to demangle the symbol name if it fit into symbol_buf_. + DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_, + sizeof(tmp_buf_)); } } else { #if ABSL_HAVE_VDSO_SUPPORT @@ -1461,7 +1374,7 @@ int InstallSymbolDecorator(SymbolDecorator decorator, void *arg) { if (!g_decorators_mu.TryLock()) { // Someone else is using decorators. Get out. - return -2; + return false; } int ret = ticket; if (g_num_decorators >= kMaxDecorators) { @@ -1489,7 +1402,7 @@ bool RegisterFileMappingHint(const void *start, const void *end, uint64_t offset if (g_num_file_mapping_hints >= kMaxFileMappingHints) { ret = false; } else { - // TODO(ckennelly): Move this into a string copy routine. + // TODO(ckennelly): Move this into a std::string copy routine. int len = strlen(filename); char *dst = static_cast<char *>( base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena())); @@ -1540,7 +1453,7 @@ bool GetFileMappingHint(const void **start, const void **end, uint64_t *offset, bool Symbolize(const void *pc, char *out, int out_size) { // Symbolization is very slow under tsan. - ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); + ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN(); SAFE_ASSERT(out_size >= 0); debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer(); const char *name = s->GetSymbol(pc); @@ -1559,16 +1472,9 @@ bool Symbolize(const void *pc, char *out, int out_size) { } } debugging_internal::FreeSymbolizer(s); - ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END(); + ANNOTATE_IGNORE_READS_AND_WRITES_END(); return ok; } ABSL_NAMESPACE_END } // namespace absl - -extern "C" bool AbslInternalGetFileMappingHint(const void **start, - const void **end, uint64_t *offset, - const char **filename) { - return absl::debugging_internal::GetFileMappingHint(start, end, offset, - filename); -} |