From f064cc8da606f38450ff5d345ae716ff9dab3d7c Mon Sep 17 00:00:00 2001 From: Mischan Toosarani-Hausberger Date: Wed, 13 Sep 2023 18:06:00 +0200 Subject: [PATCH] chore: update 2023-09-13 commit 1c5740113b71435d1f24d05e33039fe35f7f7277 Author: Christopher Ferris Date: Wed Sep 6 14:09:01 2023 -0700 https://android.googlesource.com/platform/system/unwinding --- Demangle.cpp | 55 ++++++++++++++++++++++++++++++ Elf.cpp | 7 ---- ElfInterface.cpp | 27 +++++++++++++-- ElfInterfaceArm.h | 9 +++-- GlobalDebugImpl.h | 4 --- Regs.cpp | 14 +++----- Unwinder.cpp | 16 +++++---- include/unwindstack/Arch.h | 5 --- include/unwindstack/Demangle.h | 25 ++++++++++++++ include/unwindstack/DwarfSection.h | 9 +++-- 10 files changed, 132 insertions(+), 39 deletions(-) create mode 100644 Demangle.cpp create mode 100644 include/unwindstack/Demangle.h diff --git a/Demangle.cpp b/Demangle.cpp new file mode 100644 index 0000000..d7ca485 --- /dev/null +++ b/Demangle.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#ifdef SENTRY_REMOVED +#include +#endif //SENTRY_REMOVED + +#include + +namespace unwindstack { + +std::string DemangleNameIfNeeded(const std::string& name) { + if (name.length() < 2 || name[0] != '_') { + return name; + } + + char* demangled_str = nullptr; + if (name[1] == 'Z') { + // Try to demangle C++ name. + demangled_str = abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr); +#ifdef SENTRY_REMOVED + } else if (name[1] == 'R') { + // Try to demangle rust name. + demangled_str = rustc_demangle(name.c_str(), nullptr, nullptr, nullptr); +#endif //SENTRY_REMOVED + } + + if (demangled_str == nullptr) { + return name; + } + + std::string demangled_name(demangled_str); + free(demangled_str); + return demangled_name; +} + +} // namespace unwindstack diff --git a/Elf.cpp b/Elf.cpp index d34b015..23eeb18 100644 --- a/Elf.cpp +++ b/Elf.cpp @@ -304,11 +304,6 @@ ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) { } else if (e_machine == EM_386) { arch_ = ARCH_X86; interface.reset(new ElfInterface32(memory)); -#ifdef SENTRY_REMOVED - } else if (e_machine == EM_MIPS) { - arch_ = ARCH_MIPS; - interface.reset(new ElfInterface32(memory)); -#endif // SENTRY_REMOVED } else { // Unsupported. return nullptr; @@ -325,8 +320,6 @@ ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) { } else if (e_machine == EM_X86_64) { arch_ = ARCH_X86_64; #ifdef SENTRY_REMOVED - } else if (e_machine == EM_MIPS) { - arch_ = ARCH_MIPS64; } else if (e_machine == EM_RISCV) { arch_ = ARCH_RISCV64; #endif // SENTRY_REMOVED diff --git a/ElfInterface.cpp b/ElfInterface.cpp index fbc5a48..9ff23d3 100644 --- a/ElfInterface.cpp +++ b/ElfInterface.cpp @@ -528,12 +528,33 @@ template void ElfInterfaceImpl::GetMaxSize(Memory* memory, uint64_t* size) { EhdrType ehdr; if (!memory->ReadFully(0, &ehdr, sizeof(ehdr))) { + *size = 0; return; } - if (ehdr.e_shnum == 0) { - return; + + // If this winds up as zero, the PT_LOAD reading will get a better value. + uint64_t elf_size = ehdr.e_shoff + ehdr.e_shentsize * ehdr.e_shnum; + + // Search through the PT_LOAD values and if any result in a larger elf + // size, use that. + uint64_t offset = ehdr.e_phoff; + for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) { + PhdrType phdr; + if (!memory->ReadFully(offset, &phdr, sizeof(phdr))) { + break; + } + if (phdr.p_type == PT_LOAD) { + uint64_t end_offset; + if (__builtin_add_overflow(phdr.p_offset, phdr.p_memsz, &end_offset)) { + continue; + } + if (end_offset > elf_size) { + elf_size = end_offset; + } + } } - *size = ehdr.e_shoff + ehdr.e_shentsize * ehdr.e_shnum; + + *size = elf_size; } template diff --git a/ElfInterfaceArm.h b/ElfInterfaceArm.h index 6ee6dc9..d8cad48 100644 --- a/ElfInterfaceArm.h +++ b/ElfInterfaceArm.h @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -32,8 +31,14 @@ class ElfInterfaceArm : public ElfInterface32 { ElfInterfaceArm(Memory* memory) : ElfInterface32(memory) {} virtual ~ElfInterfaceArm() = default; - class iterator : public std::iterator { + class iterator { public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = uint32_t; + using difference_type = std::ptrdiff_t; + using pointer = uint32_t*; + using reference = uint32_t&; + iterator(ElfInterfaceArm* interface, size_t index) : interface_(interface), index_(index) { } iterator& operator++() { index_++; return *this; } diff --git a/GlobalDebugImpl.h b/GlobalDebugImpl.h index 3da1fbf..93bc8cf 100644 --- a/GlobalDebugImpl.h +++ b/GlobalDebugImpl.h @@ -410,9 +410,6 @@ std::unique_ptr> CreateGlobalDebugImpl( return std::make_unique(arch, jit_memory, search_libs, global_variable_name); } case ARCH_ARM: { -#ifdef SENTRY_REMOVED - case ARCH_MIPS: { -#endif // SENTRY_REMOVED using Impl = GlobalDebugImpl; static_assert(offsetof(typename Impl::JITCodeEntry, symfile_size) == 16, "layout"); static_assert(offsetof(typename Impl::JITCodeEntry, seqlock) == 32, "layout"); @@ -423,7 +420,6 @@ std::unique_ptr> CreateGlobalDebugImpl( case ARCH_ARM64: case ARCH_X86_64: { #ifdef SENTRY_REMOVED - case ARCH_MIPS64: case ARCH_RISCV64: { #endif // SENTRY_REMOVED using Impl = GlobalDebugImpl; diff --git a/Regs.cpp b/Regs.cpp index b4574c3..9c99d73 100644 --- a/Regs.cpp +++ b/Regs.cpp @@ -117,6 +117,10 @@ ArchEnum Regs::RemoteGetArch(pid_t pid, ErrorCode* error_code) { return ARCH_ARM; case sizeof(arm64_user_regs): return ARCH_ARM64; +#ifdef SENTRY_REMOVED + case sizeof(riscv64_user_regs): + return ARCH_RISCV64; +#endif // SENTRY_REMOVED } Log::Error("No matching size of user regs structure for pid %d: size %zu", pid, io.iov_len); @@ -224,16 +228,6 @@ uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch) { return 0; } return 4; -#ifdef SENTRY_REMOVED - } - case ARCH_MIPS: - case ARCH_MIPS64: { - if (rel_pc < 8) { - return 0; - } - // For now, just assume no compact branches - return 8; -#endif // SENTRY_REMOVED } case ARCH_X86: case ARCH_X86_64: { diff --git a/Unwinder.cpp b/Unwinder.cpp index b802514..64ad92d 100644 --- a/Unwinder.cpp +++ b/Unwinder.cpp @@ -406,13 +406,17 @@ bool UnwinderFromPid::Init() { } } - jit_debug_ptr_ = CreateJitDebug(arch_, process_memory_); - jit_debug_ = jit_debug_ptr_.get(); - SetJitDebug(jit_debug_); + // jit_debug_ and dex_files_ may have already been set, for example in + // AndroidLocalUnwinder::InternalUnwind. + if (jit_debug_ == nullptr) { + jit_debug_ptr_ = CreateJitDebug(arch_, process_memory_); + SetJitDebug(jit_debug_ptr_.get()); + } #if defined(DEXFILE_SUPPORT) - dex_files_ptr_ = CreateDexFiles(arch_, process_memory_); - dex_files_ = dex_files_ptr_.get(); - SetDexFiles(dex_files_); + if (dex_files_ == nullptr) { + dex_files_ptr_ = CreateDexFiles(arch_, process_memory_); + SetDexFiles(dex_files_ptr_.get()); + } #endif return true; diff --git a/include/unwindstack/Arch.h b/include/unwindstack/Arch.h index 41dc00e..44d0de0 100644 --- a/include/unwindstack/Arch.h +++ b/include/unwindstack/Arch.h @@ -27,8 +27,6 @@ enum ArchEnum : uint8_t { ARCH_X86, ARCH_X86_64, #ifdef SENTRY_REMOVED - ARCH_MIPS, - ARCH_MIPS64, ARCH_RISCV64, #endif // SENTRY_REMOVED }; @@ -37,9 +35,6 @@ static inline bool ArchIs32Bit(ArchEnum arch) { switch (arch) { case ARCH_ARM: case ARCH_X86: -#ifdef SENTRY_REMOVED - case ARCH_MIPS: -#endif // SENTRY_REMOVED return true; default: return false; diff --git a/include/unwindstack/Demangle.h b/include/unwindstack/Demangle.h new file mode 100644 index 0000000..8ea51bc --- /dev/null +++ b/include/unwindstack/Demangle.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace unwindstack { + +std::string DemangleNameIfNeeded(const std::string& name); + +} // namespace unwindstack diff --git a/include/unwindstack/DwarfSection.h b/include/unwindstack/DwarfSection.h index 33435b2..2318f2f 100644 --- a/include/unwindstack/DwarfSection.h +++ b/include/unwindstack/DwarfSection.h @@ -18,7 +18,6 @@ #include -#include #include #include #include @@ -42,8 +41,14 @@ class DwarfSection { DwarfSection(Memory* memory); virtual ~DwarfSection() = default; - class iterator : public std::iterator { + class iterator { public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = DwarfFde*; + using difference_type = std::ptrdiff_t; + using pointer = DwarfFde**; + using reference = DwarfFde*&; + iterator(DwarfSection* section, size_t index) : index_(index) { section->GetFdes(&fdes_); if (index_ == static_cast(-1)) {