├── .clang-format ├── .gitmodules ├── Android.bp ├── AndroidVersions.md ├── ArmExidx.cpp ├── ArmExidx.h ├── AsmGetRegsMips.S ├── AsmGetRegsMips64.S ├── AsmGetRegsX86.S ├── AsmGetRegsX86_64.S ├── Check.h ├── DexFile.cpp ├── DexFile.h ├── DexFiles.cpp ├── DwarfCfa.cpp ├── DwarfCfa.h ├── DwarfDebugFrame.h ├── DwarfEhFrame.h ├── DwarfEhFrameWithHdr.cpp ├── DwarfEhFrameWithHdr.h ├── DwarfEncoding.h ├── DwarfMemory.cpp ├── DwarfOp.cpp ├── DwarfOp.h ├── DwarfSection.cpp ├── Elf.cpp ├── ElfInterface.cpp ├── ElfInterfaceArm.cpp ├── ElfInterfaceArm.h ├── Global.cpp ├── GlobalDebugImpl.h ├── JitDebug.cpp ├── LocalUnwinder.cpp ├── Log.cpp ├── MapInfo.cpp ├── Maps.cpp ├── Memory.cpp ├── MemoryBuffer.h ├── MemoryCache.h ├── MemoryFileAtOffset.h ├── MemoryLocal.h ├── MemoryMte.cpp ├── MemoryOffline.h ├── MemoryOfflineBuffer.h ├── MemoryRange.h ├── MemoryRemote.h ├── MemoryXz.h ├── OWNERS ├── Regs.cpp ├── RegsArm.cpp ├── RegsArm64.cpp ├── RegsInfo.h ├── RegsMips.cpp ├── RegsMips64.cpp ├── RegsX86.cpp ├── RegsX86_64.cpp ├── Symbols.cpp ├── Symbols.h ├── TEST_MAPPING ├── ThreadEntry.cpp ├── ThreadEntry.h ├── ThreadUnwinder.cpp ├── Unwinder.cpp ├── android-base ├── errno_restorer.h ├── file.cpp ├── file.h ├── log_main.h ├── logging.h ├── macros.h ├── off64_t.h ├── stringprintf.cpp ├── stringprintf.h ├── strings.cpp ├── strings.h ├── unique_fd.h └── utf8.h ├── cmake ├── CMakeLists.txt └── lzma │ └── CMakeLists.txt ├── getline.c ├── getline.h ├── include ├── GlobalDebugInterface.h └── unwindstack │ ├── Arch.h │ ├── DexFiles.h │ ├── DwarfError.h │ ├── DwarfLocation.h │ ├── DwarfMemory.h │ ├── DwarfSection.h │ ├── DwarfStructs.h │ ├── Elf.h │ ├── ElfInterface.h │ ├── Error.h │ ├── Global.h │ ├── JitDebug.h │ ├── LocalUnwinder.h │ ├── Log.h │ ├── MachineArm.h │ ├── MachineArm64.h │ ├── MachineMips.h │ ├── MachineMips64.h │ ├── MachineX86.h │ ├── MachineX86_64.h │ ├── MapInfo.h │ ├── Maps.h │ ├── Memory.h │ ├── Regs.h │ ├── RegsArm.h │ ├── RegsArm64.h │ ├── RegsGetLocal.h │ ├── RegsMips.h │ ├── RegsMips64.h │ ├── RegsX86.h │ ├── RegsX86_64.h │ ├── SharedString.h │ ├── UcontextArm.h │ ├── UcontextArm64.h │ ├── UcontextMips.h │ ├── UcontextMips64.h │ ├── UcontextX86.h │ ├── UcontextX86_64.h │ ├── Unwinder.h │ ├── UserArm.h │ ├── UserArm64.h │ ├── UserMips.h │ ├── UserMips64.h │ ├── UserX86.h │ └── UserX86_64.h ├── procinfo └── process_map.h ├── tools ├── unwind.cpp ├── unwind_for_offline.cpp ├── unwind_info.cpp ├── unwind_reg_info.cpp └── unwind_symbols.cpp └── unistdfix.h /.clang-format: -------------------------------------------------------------------------------- 1 | ../.clang-format-2 -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lzma"] 2 | path = lzma 3 | url = https://android.googlesource.com/platform/external/lzma 4 | -------------------------------------------------------------------------------- /ArmExidx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_ARM_EXIDX_H 18 | #define _LIBUNWINDSTACK_ARM_EXIDX_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace unwindstack { 26 | 27 | // Forward declarations. 28 | class Memory; 29 | class RegsArm; 30 | 31 | enum ArmStatus : size_t { 32 | ARM_STATUS_NONE = 0, 33 | ARM_STATUS_NO_UNWIND, 34 | ARM_STATUS_FINISH, 35 | ARM_STATUS_RESERVED, 36 | ARM_STATUS_SPARE, 37 | ARM_STATUS_TRUNCATED, 38 | ARM_STATUS_READ_FAILED, 39 | ARM_STATUS_MALFORMED, 40 | ARM_STATUS_INVALID_ALIGNMENT, 41 | ARM_STATUS_INVALID_PERSONALITY, 42 | }; 43 | 44 | enum ArmOp : uint8_t { 45 | ARM_OP_FINISH = 0xb0, 46 | }; 47 | 48 | enum ArmLogType : uint8_t { 49 | ARM_LOG_NONE, 50 | ARM_LOG_FULL, 51 | ARM_LOG_BY_REG, 52 | }; 53 | 54 | class ArmExidx { 55 | public: 56 | ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory) 57 | : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {} 58 | virtual ~ArmExidx() {} 59 | 60 | void LogRawData(); 61 | 62 | void LogByReg(); 63 | 64 | bool ExtractEntryData(uint32_t entry_offset); 65 | 66 | bool Eval(); 67 | 68 | bool Decode(); 69 | 70 | std::deque* data() { return &data_; } 71 | 72 | ArmStatus status() { return status_; } 73 | uint64_t status_address() { return status_address_; } 74 | 75 | RegsArm* regs() { return regs_; } 76 | 77 | uint32_t cfa() { return cfa_; } 78 | void set_cfa(uint32_t cfa) { cfa_ = cfa; } 79 | 80 | bool pc_set() { return pc_set_; } 81 | void set_pc_set(bool pc_set) { pc_set_ = pc_set; } 82 | 83 | void set_log(ArmLogType log_type) { log_type_ = log_type; } 84 | void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; } 85 | void set_log_indent(uint8_t indent) { log_indent_ = indent; } 86 | 87 | private: 88 | bool GetByte(uint8_t* byte); 89 | void AdjustRegisters(int32_t offset); 90 | 91 | bool DecodePrefix_10_00(uint8_t byte); 92 | bool DecodePrefix_10_01(uint8_t byte); 93 | bool DecodePrefix_10_10(uint8_t byte); 94 | bool DecodePrefix_10_11_0000(); 95 | bool DecodePrefix_10_11_0001(); 96 | bool DecodePrefix_10_11_0010(); 97 | bool DecodePrefix_10_11_0011(); 98 | bool DecodePrefix_10_11_01nn(); 99 | bool DecodePrefix_10_11_1nnn(uint8_t byte); 100 | bool DecodePrefix_10(uint8_t byte); 101 | 102 | bool DecodePrefix_11_000(uint8_t byte); 103 | bool DecodePrefix_11_001(uint8_t byte); 104 | bool DecodePrefix_11_010(uint8_t byte); 105 | bool DecodePrefix_11(uint8_t byte); 106 | 107 | RegsArm* regs_ = nullptr; 108 | uint32_t cfa_ = 0; 109 | std::deque data_; 110 | ArmStatus status_ = ARM_STATUS_NONE; 111 | uint64_t status_address_ = 0; 112 | 113 | Memory* elf_memory_; 114 | Memory* process_memory_; 115 | 116 | ArmLogType log_type_ = ARM_LOG_NONE; 117 | uint8_t log_indent_ = 0; 118 | bool log_skip_execution_ = false; 119 | bool pc_set_ = false; 120 | int32_t log_cfa_offset_ = 0; 121 | std::map log_regs_; 122 | }; 123 | 124 | } // namespace unwindstack 125 | 126 | #endif // _LIBUNWINDSTACK_ARM_EXIDX_H 127 | -------------------------------------------------------------------------------- /AsmGetRegsMips.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | .text 30 | .type AsmGetRegs, %function 31 | .globl AsmGetRegs 32 | .ent AsmGetRegs 33 | .balign 16 34 | AsmGetRegs: 35 | .cfi_startproc 36 | .cfi_def_cfa $sp, 0 37 | .set push 38 | .set noreorder 39 | .cpload $t9 40 | sw $zero, 0($a0) 41 | .set noat 42 | sw $at, 4($a0) 43 | .set at 44 | sw $v0, 8($a0) 45 | sw $v1, 12($a0) 46 | sw $a0, 16($a0) 47 | sw $a1, 20($a0) 48 | sw $a2, 24($a0) 49 | sw $a3, 28($a0) 50 | sw $t0, 32($a0) 51 | sw $t1, 36($a0) 52 | sw $t2, 40($a0) 53 | sw $t3, 44($a0) 54 | sw $t4, 48($a0) 55 | sw $t5, 52($a0) 56 | sw $t6, 56($a0) 57 | sw $t7, 60($a0) 58 | sw $s0, 64($a0) 59 | sw $s1, 68($a0) 60 | sw $s2, 72($a0) 61 | sw $s3, 76($a0) 62 | sw $s4, 80($a0) 63 | sw $s5, 84($a0) 64 | sw $s6, 88($a0) 65 | sw $s7, 92($a0) 66 | sw $t8, 96($a0) 67 | sw $t9, 100($a0) 68 | sw $k0, 104($a0) 69 | sw $k1, 108($a0) 70 | sw $gp, 112($a0) 71 | sw $sp, 116($a0) 72 | sw $s8, 120($a0) 73 | sw $ra, 124($a0) 74 | jalr $zero, $ra 75 | sw $ra, 128($a0) // set PC to the calling function 76 | 77 | .set pop 78 | .cfi_endproc 79 | .size AsmGetRegs, .-AsmGetRegs 80 | .end AsmGetRegs 81 | -------------------------------------------------------------------------------- /AsmGetRegsMips64.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | .text 30 | .type AsmGetRegs, %function 31 | .globl AsmGetRegs 32 | .ent AsmGetRegs 33 | .balign 16 34 | AsmGetRegs: 35 | .cfi_startproc 36 | .cfi_def_cfa $sp, 0 37 | .set push 38 | .set noreorder 39 | .cpload $t9 40 | sd $zero, 0($a0) 41 | .set noat 42 | sd $at, 8($a0) 43 | .set at 44 | sd $v0, 16($a0) 45 | sd $v1, 24($a0) 46 | sd $a0, 32($a0) 47 | sd $a1, 40($a0) 48 | sd $a2, 48($a0) 49 | sd $a3, 56($a0) 50 | sd $a4, 64($a0) 51 | sd $a5, 72($a0) 52 | sd $a6, 80($a0) 53 | sd $a7, 88($a0) 54 | sd $t0, 96($a0) 55 | sd $t1, 104($a0) 56 | sd $t2, 112($a0) 57 | sd $t3, 120($a0) 58 | sd $s0, 128($a0) 59 | sd $s1, 136($a0) 60 | sd $s2, 144($a0) 61 | sd $s3, 152($a0) 62 | sd $s4, 160($a0) 63 | sd $s5, 168($a0) 64 | sd $s6, 176($a0) 65 | sd $s7, 184($a0) 66 | sd $t8, 192($a0) 67 | sd $t9, 200($a0) 68 | sd $k0, 208($a0) 69 | sd $k1, 216($a0) 70 | sd $gp, 224($a0) 71 | sd $sp, 232($a0) 72 | sd $s8, 240($a0) 73 | sd $ra, 248($a0) 74 | jalr $zero, $ra 75 | sd $ra, 256($a0) // set PC to the calling function 76 | 77 | .set pop 78 | .cfi_endproc 79 | .size AsmGetRegs, .-AsmGetRegs 80 | .end AsmGetRegs 81 | -------------------------------------------------------------------------------- /AsmGetRegsX86.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | .text 30 | .global AsmGetRegs 31 | .balign 16 32 | .type AsmGetRegs, @function 33 | AsmGetRegs: 34 | .cfi_startproc 35 | mov 4(%esp), %eax 36 | movl $0, (%eax) 37 | movl %ecx, 4(%eax) 38 | movl %edx, 8(%eax) 39 | movl %ebx, 12(%eax) 40 | 41 | /* ESP */ 42 | leal 4(%esp), %ecx 43 | movl %ecx, 16(%eax) 44 | 45 | movl %ebp, 20(%eax) 46 | movl %esi, 24(%eax) 47 | movl %edi, 28(%eax) 48 | 49 | /* EIP */ 50 | movl (%esp), %ecx 51 | movl %ecx, 32(%eax) 52 | 53 | mov %cs, 36(%eax) 54 | mov %ss, 40(%eax) 55 | mov %ds, 44(%eax) 56 | mov %es, 48(%eax) 57 | mov %fs, 52(%eax) 58 | mov %gs, 56(%eax) 59 | ret 60 | 61 | .cfi_endproc 62 | .size AsmGetRegs, .-AsmGetRegs 63 | -------------------------------------------------------------------------------- /AsmGetRegsX86_64.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | .text 30 | .global AsmGetRegs 31 | .balign 16 32 | .type AsmGetRegs, @function 33 | AsmGetRegs: 34 | .cfi_startproc 35 | movq %rax, (%rdi) 36 | movq %rdx, 8(%rdi) 37 | movq %rcx, 16(%rdi) 38 | movq %rbx, 24(%rdi) 39 | movq %rsi, 32(%rdi) 40 | movq %rdi, 40(%rdi) 41 | movq %rbp, 48(%rdi) 42 | 43 | /* RSP */ 44 | lea 8(%rsp), %rax 45 | movq %rax, 56(%rdi) 46 | 47 | movq %r8, 64(%rdi) 48 | movq %r9, 72(%rdi) 49 | movq %r10, 80(%rdi) 50 | movq %r11, 88(%rdi) 51 | movq %r12, 96(%rdi) 52 | movq %r13, 104(%rdi) 53 | movq %r14, 112(%rdi) 54 | movq %r15, 120(%rdi) 55 | 56 | /* RIP */ 57 | movq (%rsp), %rax 58 | movq %rax, 128(%rdi) 59 | ret 60 | 61 | .cfi_endproc 62 | .size AsmGetRegs, .-AsmGetRegs 63 | -------------------------------------------------------------------------------- /Check.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_CHECK_H 18 | #define _LIBUNWINDSTACK_CHECK_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | #define CHECK(assertion) \ 27 | if (__builtin_expect(!(assertion), false)) { \ 28 | log(0, "%s:%d: %s\n", __FILE__, __LINE__, #assertion); \ 29 | abort(); \ 30 | } 31 | 32 | } // namespace unwindstack 33 | 34 | #endif // _LIBUNWINDSTACK_CHECK_H 35 | -------------------------------------------------------------------------------- /DexFile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #define LOG_TAG "unwind" 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include "DexFile.h" 35 | #include "MemoryBuffer.h" 36 | 37 | namespace unwindstack { 38 | 39 | static bool CheckDexSupport() { 40 | if (std::string err_msg; !art_api::dex::TryLoadLibdexfile(&err_msg)) { 41 | ALOGW("Failed to initialize DEX file support: %s", err_msg.c_str()); 42 | return false; 43 | } 44 | return true; 45 | } 46 | 47 | std::unique_ptr DexFile::Create(uint64_t base_addr, uint64_t file_size, Memory* memory, 48 | MapInfo* info) { 49 | static bool has_dex_support = CheckDexSupport(); 50 | if (!has_dex_support || file_size == 0) { 51 | return nullptr; 52 | } 53 | 54 | // Try to map the file directly from disk. 55 | std::unique_ptr dex_memory; 56 | if (info != nullptr && !info->name.empty()) { 57 | if (info->start <= base_addr && base_addr < info->end) { 58 | uint64_t offset_in_file = (base_addr - info->start) + info->offset; 59 | if (file_size <= info->end - base_addr) { 60 | dex_memory = Memory::CreateFileMemory(info->name, offset_in_file, file_size); 61 | // On error, the results is null and we fall through to the fallback code-path. 62 | } 63 | } 64 | } 65 | 66 | // Fallback: make copy in local buffer. 67 | if (dex_memory.get() == nullptr) { 68 | std::unique_ptr copy(new MemoryBuffer); 69 | if (!copy->Resize(file_size)) { 70 | return nullptr; 71 | } 72 | if (!memory->ReadFully(base_addr, copy->GetPtr(0), file_size)) { 73 | return nullptr; 74 | } 75 | dex_memory = std::move(copy); 76 | } 77 | 78 | const char* location = info != nullptr ? info->name.c_str() : ""; 79 | std::unique_ptr dex; 80 | art_api::dex::DexFile::Create(dex_memory->GetPtr(), file_size, nullptr, location, &dex); 81 | if (dex != nullptr) { 82 | return std::unique_ptr( 83 | new DexFile(std::move(dex_memory), base_addr, file_size, std::move(dex))); 84 | } 85 | return nullptr; 86 | } 87 | 88 | bool DexFile::GetFunctionName(uint64_t dex_pc, SharedString* method_name, uint64_t* method_offset) { 89 | uint64_t dex_offset = dex_pc - base_addr_; // Convert absolute PC to file-relative offset. 90 | 91 | // Lookup the function in the cache. 92 | auto it = symbols_.upper_bound(dex_offset); 93 | if (it == symbols_.end() || dex_offset < it->second.offset) { 94 | // Lookup the function in the underlying dex file. 95 | size_t found = dex_->FindMethodAtOffset(dex_offset, [&](const auto& method) { 96 | size_t code_size, name_size; 97 | uint32_t offset = method.GetCodeOffset(&code_size); 98 | const char* name = method.GetQualifiedName(/*with_params=*/false, &name_size); 99 | it = symbols_.emplace(offset + code_size, Info{offset, std::string(name, name_size)}).first; 100 | }); 101 | if (found == 0) { 102 | return false; 103 | } 104 | } 105 | 106 | // Return the found function. 107 | *method_offset = dex_offset - it->second.offset; 108 | *method_name = it->second.name; 109 | return true; 110 | } 111 | 112 | } // namespace unwindstack 113 | -------------------------------------------------------------------------------- /DexFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DEX_FILE_H 18 | #define _LIBUNWINDSTACK_DEX_FILE_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | #include 31 | 32 | namespace unwindstack { 33 | 34 | struct MapInfo; 35 | class Memory; 36 | 37 | class DexFile { 38 | struct Info { 39 | uint32_t offset; // Symbol start offset (relative to start of dex file). 40 | SharedString name; 41 | }; 42 | 43 | public: 44 | bool IsValidPc(uint64_t dex_pc) { 45 | return base_addr_ <= dex_pc && (dex_pc - base_addr_) < file_size_; 46 | } 47 | 48 | bool GetFunctionName(uint64_t dex_pc, SharedString* method_name, uint64_t* method_offset); 49 | 50 | static std::unique_ptr Create(uint64_t base_addr, uint64_t file_size, Memory* memory, 51 | MapInfo* info); 52 | 53 | private: 54 | DexFile(std::unique_ptr&& memory, uint64_t base_addr, uint64_t file_size, 55 | std::unique_ptr&& dex) 56 | : memory_(std::move(memory)), 57 | base_addr_(base_addr), 58 | file_size_(file_size), 59 | dex_(std::move(dex)) {} 60 | 61 | std::unique_ptr memory_; // Memory range containing the dex file. 62 | uint64_t base_addr_ = 0; // Absolute address where this DEX file is in memory. 63 | uint64_t file_size_ = 0; // Total number of bytes in the dex file. 64 | std::unique_ptr dex_; // Loaded underling dex object. 65 | 66 | std::map symbols_; // Cache of read symbols (keyed by *end* offset). 67 | }; 68 | 69 | } // namespace unwindstack 70 | 71 | #endif // _LIBUNWINDSTACK_DEX_FILE_H 72 | -------------------------------------------------------------------------------- /DexFiles.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #if defined(DEXFILE_SUPPORT) 20 | #include "DexFile.h" 21 | #endif 22 | 23 | #include "GlobalDebugImpl.h" 24 | 25 | namespace unwindstack { 26 | 27 | #if defined(DEXFILE_SUPPORT) 28 | 29 | template <> 30 | bool GlobalDebugInterface::Load(Maps* maps, std::shared_ptr& memory, uint64_t addr, 31 | uint64_t size, /*out*/ std::unique_ptr& dex) { 32 | dex = DexFile::Create(addr, size, memory.get(), maps->Find(addr)); 33 | return dex.get() != nullptr; 34 | } 35 | 36 | std::unique_ptr CreateDexFiles(ArchEnum arch, std::shared_ptr& memory, 37 | std::vector search_libs) { 38 | return CreateGlobalDebugImpl(arch, memory, search_libs, "__dex_debug_descriptor"); 39 | } 40 | 41 | #else 42 | 43 | template <> 44 | bool GlobalDebugInterface::Load(Maps*, std::shared_ptr&, uint64_t, uint64_t, 45 | std::unique_ptr&) { 46 | return false; 47 | } 48 | 49 | std::unique_ptr CreateDexFiles(ArchEnum, std::shared_ptr&, 50 | std::vector) { 51 | return nullptr; 52 | } 53 | 54 | #endif 55 | 56 | } // namespace unwindstack 57 | -------------------------------------------------------------------------------- /DwarfDebugFrame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_DEBUG_FRAME_H 18 | #define _LIBUNWINDSTACK_DWARF_DEBUG_FRAME_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | 26 | namespace unwindstack { 27 | 28 | template 29 | class DwarfDebugFrame : public DwarfSectionImpl { 30 | public: 31 | DwarfDebugFrame(Memory* memory) : DwarfSectionImpl(memory) { 32 | this->cie32_value_ = static_cast(-1); 33 | this->cie64_value_ = static_cast(-1); 34 | } 35 | virtual ~DwarfDebugFrame() = default; 36 | 37 | uint64_t GetCieOffsetFromFde32(uint32_t pointer) override { 38 | return this->entries_offset_ + pointer; 39 | } 40 | 41 | uint64_t GetCieOffsetFromFde64(uint64_t pointer) override { 42 | return this->entries_offset_ + pointer; 43 | } 44 | 45 | uint64_t AdjustPcFromFde(uint64_t pc) override { return pc; } 46 | }; 47 | 48 | } // namespace unwindstack 49 | 50 | #endif // _LIBUNWINDSTACK_DWARF_DEBUG_FRAME_H 51 | -------------------------------------------------------------------------------- /DwarfEhFrame.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_EH_FRAME_H 18 | #define _LIBUNWINDSTACK_DWARF_EH_FRAME_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace unwindstack { 26 | 27 | template 28 | class DwarfEhFrame : public DwarfSectionImpl { 29 | public: 30 | DwarfEhFrame(Memory* memory) : DwarfSectionImpl(memory) {} 31 | virtual ~DwarfEhFrame() = default; 32 | 33 | uint64_t GetCieOffsetFromFde32(uint32_t pointer) override { 34 | return this->memory_.cur_offset() - pointer - 4; 35 | } 36 | 37 | uint64_t GetCieOffsetFromFde64(uint64_t pointer) override { 38 | return this->memory_.cur_offset() - pointer - 8; 39 | } 40 | 41 | uint64_t AdjustPcFromFde(uint64_t pc) override { 42 | // The eh_frame uses relative pcs. 43 | return pc + this->memory_.cur_offset() - 4; 44 | } 45 | }; 46 | 47 | } // namespace unwindstack 48 | 49 | #endif // _LIBUNWINDSTACK_DWARF_EH_FRAME_H 50 | -------------------------------------------------------------------------------- /DwarfEhFrameWithHdr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_EH_FRAME_WITH_HDR_H 18 | #define _LIBUNWINDSTACK_DWARF_EH_FRAME_WITH_HDR_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | 26 | namespace unwindstack { 27 | 28 | // Forward declarations. 29 | class Memory; 30 | 31 | template 32 | class DwarfEhFrameWithHdr : public DwarfSectionImpl { 33 | public: 34 | // Add these so that the protected members of DwarfSectionImpl 35 | // can be accessed without needing a this->. 36 | using DwarfSectionImpl::memory_; 37 | using DwarfSectionImpl::last_error_; 38 | 39 | struct FdeInfo { 40 | AddressType pc; 41 | uint64_t offset; 42 | }; 43 | 44 | DwarfEhFrameWithHdr(Memory* memory) : DwarfSectionImpl(memory) {} 45 | virtual ~DwarfEhFrameWithHdr() = default; 46 | 47 | uint64_t GetCieOffsetFromFde32(uint32_t pointer) override { 48 | return memory_.cur_offset() - pointer - 4; 49 | } 50 | 51 | uint64_t GetCieOffsetFromFde64(uint64_t pointer) override { 52 | return memory_.cur_offset() - pointer - 8; 53 | } 54 | 55 | uint64_t AdjustPcFromFde(uint64_t pc) override { 56 | // The eh_frame uses relative pcs. 57 | return pc + memory_.cur_offset() - 4; 58 | } 59 | 60 | bool EhFrameInit(uint64_t offset, uint64_t size, int64_t section_bias); 61 | bool Init(uint64_t offset, uint64_t size, int64_t section_bias) override; 62 | 63 | const DwarfFde* GetFdeFromPc(uint64_t pc) override; 64 | 65 | bool GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset); 66 | 67 | const FdeInfo* GetFdeInfoFromIndex(size_t index); 68 | 69 | void GetFdes(std::vector* fdes) override; 70 | 71 | protected: 72 | uint8_t version_ = 0; 73 | uint8_t table_encoding_ = 0; 74 | size_t table_entry_size_ = 0; 75 | 76 | uint64_t hdr_entries_offset_ = 0; 77 | uint64_t hdr_entries_data_offset_ = 0; 78 | uint64_t hdr_section_bias_ = 0; 79 | 80 | uint64_t fde_count_ = 0; 81 | std::unordered_map fde_info_; 82 | }; 83 | 84 | } // namespace unwindstack 85 | 86 | #endif // _LIBUNWINDSTACK_DWARF_EH_FRAME_WITH_HDR_H 87 | -------------------------------------------------------------------------------- /DwarfEncoding.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_ENCODING_H 18 | #define _LIBUNWINDSTACK_DWARF_ENCODING_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum DwarfEncoding : uint8_t { 25 | DW_EH_PE_omit = 0xff, 26 | 27 | DW_EH_PE_absptr = 0x00, 28 | DW_EH_PE_uleb128 = 0x01, 29 | DW_EH_PE_udata2 = 0x02, 30 | DW_EH_PE_udata4 = 0x03, 31 | DW_EH_PE_udata8 = 0x04, 32 | DW_EH_PE_sleb128 = 0x09, 33 | DW_EH_PE_sdata2 = 0x0a, 34 | DW_EH_PE_sdata4 = 0x0b, 35 | DW_EH_PE_sdata8 = 0x0c, 36 | 37 | DW_EH_PE_pcrel = 0x10, 38 | DW_EH_PE_textrel = 0x20, 39 | DW_EH_PE_datarel = 0x30, 40 | DW_EH_PE_funcrel = 0x40, 41 | DW_EH_PE_aligned = 0x50, 42 | 43 | // The following are special values used to encode CFA and OP operands. 44 | DW_EH_PE_udata1 = 0x0d, 45 | DW_EH_PE_sdata1 = 0x0e, 46 | DW_EH_PE_block = 0x0f, 47 | }; 48 | 49 | } // namespace unwindstack 50 | 51 | #endif // _LIBUNWINDSTACK_DWARF_ENCODING_H 52 | -------------------------------------------------------------------------------- /DwarfOp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_OP_H 18 | #define _LIBUNWINDSTACK_DWARF_OP_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "DwarfEncoding.h" 30 | #include "RegsInfo.h" 31 | 32 | namespace unwindstack { 33 | 34 | // Forward declarations. 35 | class DwarfMemory; 36 | class Memory; 37 | template 38 | class RegsImpl; 39 | 40 | template 41 | class DwarfOp { 42 | // Signed version of AddressType 43 | typedef typename std::make_signed::type SignedType; 44 | 45 | public: 46 | DwarfOp(DwarfMemory* memory, Memory* regular_memory) 47 | : memory_(memory), regular_memory_(regular_memory) {} 48 | virtual ~DwarfOp() = default; 49 | 50 | bool Decode(); 51 | 52 | bool Eval(uint64_t start, uint64_t end); 53 | 54 | void GetLogInfo(uint64_t start, uint64_t end, std::vector* lines); 55 | 56 | AddressType StackAt(size_t index) { return stack_[index]; } 57 | size_t StackSize() { return stack_.size(); } 58 | 59 | void set_regs_info(RegsInfo* regs_info) { regs_info_ = regs_info; } 60 | 61 | const DwarfErrorData& last_error() { return last_error_; } 62 | DwarfErrorCode LastErrorCode() { return last_error_.code; } 63 | uint64_t LastErrorAddress() { return last_error_.address; } 64 | 65 | bool dex_pc_set() { return dex_pc_set_; } 66 | 67 | bool is_register() { return is_register_; } 68 | 69 | uint8_t cur_op() { return cur_op_; } 70 | 71 | Memory* regular_memory() { return regular_memory_; } 72 | 73 | protected: 74 | AddressType OperandAt(size_t index) { return operands_[index]; } 75 | size_t OperandsSize() { return operands_.size(); } 76 | 77 | AddressType StackPop() { 78 | AddressType value = stack_.front(); 79 | stack_.pop_front(); 80 | return value; 81 | } 82 | 83 | private: 84 | DwarfMemory* memory_; 85 | Memory* regular_memory_; 86 | 87 | RegsInfo* regs_info_; 88 | bool dex_pc_set_ = false; 89 | bool is_register_ = false; 90 | DwarfErrorData last_error_{DWARF_ERROR_NONE, 0}; 91 | uint8_t cur_op_; 92 | std::vector operands_; 93 | std::deque stack_; 94 | 95 | inline AddressType bool_to_dwarf_bool(bool value) { return value ? 1 : 0; } 96 | 97 | // Op processing functions. 98 | bool op_deref(); 99 | bool op_deref_size(); 100 | bool op_push(); 101 | bool op_dup(); 102 | bool op_drop(); 103 | bool op_over(); 104 | bool op_pick(); 105 | bool op_swap(); 106 | bool op_rot(); 107 | bool op_abs(); 108 | bool op_and(); 109 | bool op_div(); 110 | bool op_minus(); 111 | bool op_mod(); 112 | bool op_mul(); 113 | bool op_neg(); 114 | bool op_not(); 115 | bool op_or(); 116 | bool op_plus(); 117 | bool op_plus_uconst(); 118 | bool op_shl(); 119 | bool op_shr(); 120 | bool op_shra(); 121 | bool op_xor(); 122 | bool op_bra(); 123 | bool op_eq(); 124 | bool op_ge(); 125 | bool op_gt(); 126 | bool op_le(); 127 | bool op_lt(); 128 | bool op_ne(); 129 | bool op_skip(); 130 | bool op_lit(); 131 | bool op_reg(); 132 | bool op_regx(); 133 | bool op_breg(); 134 | bool op_bregx(); 135 | bool op_nop(); 136 | bool op_not_implemented(); 137 | 138 | using OpHandleFuncPtr = bool (DwarfOp::*)(); 139 | static const OpHandleFuncPtr kOpHandleFuncList[]; 140 | }; 141 | 142 | } // namespace unwindstack 143 | 144 | #endif // _LIBUNWINDSTACK_DWARF_OP_H 145 | -------------------------------------------------------------------------------- /ElfInterfaceArm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_ELF_INTERFACE_ARM_H 18 | #define _LIBUNWINDSTACK_ELF_INTERFACE_ARM_H 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | namespace unwindstack { 30 | 31 | class ElfInterfaceArm : public ElfInterface32 { 32 | public: 33 | ElfInterfaceArm(Memory* memory) : ElfInterface32(memory) {} 34 | virtual ~ElfInterfaceArm() = default; 35 | 36 | class iterator : public std::iterator { 37 | public: 38 | iterator(ElfInterfaceArm* interface, size_t index) : interface_(interface), index_(index) { } 39 | 40 | iterator& operator++() { index_++; return *this; } 41 | iterator& operator++(int increment) { index_ += increment; return *this; } 42 | iterator& operator--() { index_--; return *this; } 43 | iterator& operator--(int decrement) { index_ -= decrement; return *this; } 44 | 45 | bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; } 46 | bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; } 47 | 48 | uint32_t operator*() { 49 | uint32_t addr = interface_->addrs_[index_]; 50 | if (addr == 0) { 51 | if (!interface_->GetPrel31Addr(interface_->start_offset_ + index_ * 8, &addr)) { 52 | return 0; 53 | } 54 | interface_->addrs_[index_] = addr; 55 | } 56 | return addr; 57 | } 58 | 59 | private: 60 | ElfInterfaceArm* interface_ = nullptr; 61 | size_t index_ = 0; 62 | }; 63 | 64 | iterator begin() { return iterator(this, 0); } 65 | iterator end() { return iterator(this, total_entries_); } 66 | 67 | bool Init(int64_t* section_bias) override; 68 | 69 | bool GetPrel31Addr(uint32_t offset, uint32_t* addr); 70 | 71 | bool FindEntry(uint32_t pc, uint64_t* entry_offset); 72 | 73 | void HandleUnknownType(uint32_t type, uint64_t ph_offset, uint64_t ph_filesz) override; 74 | 75 | bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished, 76 | bool* is_signal_frame) override; 77 | 78 | bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished); 79 | 80 | bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* offset) override; 81 | 82 | uint64_t start_offset() { return start_offset_; } 83 | 84 | size_t total_entries() { return total_entries_; } 85 | 86 | void set_load_bias(uint64_t load_bias) { load_bias_ = load_bias; } 87 | 88 | protected: 89 | uint64_t start_offset_ = 0; 90 | size_t total_entries_ = 0; 91 | uint64_t load_bias_ = 0; 92 | 93 | std::unordered_map addrs_; 94 | }; 95 | 96 | } // namespace unwindstack 97 | 98 | #endif // _LIBUNWINDSTACK_ELF_INTERFACE_ARM_H 99 | -------------------------------------------------------------------------------- /Global.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace unwindstack { 31 | 32 | Global::Global(std::shared_ptr& memory) : memory_(memory) {} 33 | Global::Global(std::shared_ptr& memory, std::vector& search_libs) 34 | : memory_(memory), search_libs_(search_libs) {} 35 | 36 | void Global::SetArch(ArchEnum arch) { 37 | if (arch_ == ARCH_UNKNOWN) { 38 | arch_ = arch; 39 | ProcessArch(); 40 | } 41 | } 42 | 43 | bool Global::Searchable(const std::string& name) { 44 | if (search_libs_.empty()) { 45 | return true; 46 | } 47 | 48 | if (name.empty()) { 49 | return false; 50 | } 51 | 52 | const char* base_name = basename(name.c_str()); 53 | for (const std::string& lib : search_libs_) { 54 | if (base_name == lib) { 55 | return true; 56 | } 57 | } 58 | return false; 59 | } 60 | 61 | void Global::FindAndReadVariable(Maps* maps, const char* var_str) { 62 | std::string variable(var_str); 63 | // When looking for global variables, do not arbitrarily search every 64 | // readable map. Instead look for a specific pattern that must exist. 65 | // The pattern should be a readable map, followed by a read-write 66 | // map with a non-zero offset. 67 | // For example: 68 | // f0000-f1000 0 r-- /system/lib/libc.so 69 | // f1000-f2000 1000 r-x /system/lib/libc.so 70 | // f2000-f3000 2000 rw- /system/lib/libc.so 71 | // This also works: 72 | // f0000-f2000 0 r-- /system/lib/libc.so 73 | // f2000-f3000 2000 rw- /system/lib/libc.so 74 | // It is also possible to see empty maps after the read-only like so: 75 | // f0000-f1000 0 r-- /system/lib/libc.so 76 | // f1000-f2000 0 --- 77 | // f2000-f3000 1000 r-x /system/lib/libc.so 78 | // f3000-f4000 2000 rw- /system/lib/libc.so 79 | MapInfo* map_zero = nullptr; 80 | for (const auto& info : *maps) { 81 | if (info->offset != 0 && (info->flags & (PROT_READ | PROT_WRITE)) == (PROT_READ | PROT_WRITE) && 82 | map_zero != nullptr && Searchable(info->name) && info->name == map_zero->name) { 83 | Elf* elf = map_zero->GetElf(memory_, arch()); 84 | uint64_t ptr; 85 | if (elf->GetGlobalVariableOffset(variable, &ptr) && ptr != 0) { 86 | uint64_t offset_end = info->offset + info->end - info->start; 87 | if (ptr >= info->offset && ptr < offset_end) { 88 | ptr = info->start + ptr - info->offset; 89 | if (ReadVariableData(ptr)) { 90 | break; 91 | } 92 | } 93 | } 94 | } else if (info->offset == 0 && !info->name.empty()) { 95 | map_zero = info.get(); 96 | } 97 | } 98 | } 99 | 100 | } // namespace unwindstack 101 | -------------------------------------------------------------------------------- /JitDebug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | 19 | #include 20 | 21 | #include "GlobalDebugImpl.h" 22 | #include "MemoryBuffer.h" 23 | 24 | namespace unwindstack { 25 | 26 | template <> 27 | bool GlobalDebugInterface::Load(Maps*, std::shared_ptr& memory, uint64_t addr, 28 | uint64_t size, /*out*/ std::unique_ptr& elf) { 29 | std::unique_ptr copy(new MemoryBuffer()); 30 | if (!copy->Resize(size) || !memory->ReadFully(addr, copy->GetPtr(0), size)) { 31 | return false; 32 | } 33 | elf.reset(new Elf(copy.release())); 34 | return elf->Init() && elf->valid(); 35 | } 36 | 37 | std::unique_ptr CreateJitDebug(ArchEnum arch, std::shared_ptr& memory, 38 | std::vector search_libs) { 39 | return CreateGlobalDebugImpl(arch, memory, search_libs, "__jit_debug_descriptor"); 40 | } 41 | 42 | } // namespace unwindstack 43 | -------------------------------------------------------------------------------- /LocalUnwinder.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | namespace unwindstack { 45 | 46 | bool LocalUnwinder::Init() { 47 | pthread_rwlock_init(&maps_rwlock_, nullptr); 48 | 49 | // Create the maps. 50 | maps_.reset(new unwindstack::LocalUpdatableMaps()); 51 | if (!maps_->Parse()) { 52 | maps_.reset(); 53 | return false; 54 | } 55 | 56 | process_memory_ = unwindstack::Memory::CreateProcessMemoryThreadCached(getpid()); 57 | 58 | return true; 59 | } 60 | 61 | bool LocalUnwinder::ShouldSkipLibrary(const std::string& map_name) { 62 | for (const std::string& skip_library : skip_libraries_) { 63 | if (skip_library == map_name) { 64 | return true; 65 | } 66 | } 67 | return false; 68 | } 69 | 70 | bool LocalUnwinder::Unwind(std::vector* frame_info, size_t max_frames) { 71 | std::unique_ptr regs(unwindstack::Regs::CreateFromLocal()); 72 | unwindstack::RegsGetLocal(regs.get()); 73 | ArchEnum arch = regs->Arch(); 74 | 75 | // Clear any cached data from previous unwinds. 76 | process_memory_->Clear(); 77 | 78 | size_t num_frames = 0; 79 | bool adjust_pc = false; 80 | while (true) { 81 | uint64_t cur_pc = regs->pc(); 82 | uint64_t cur_sp = regs->sp(); 83 | 84 | MapInfo* map_info = maps_->Find(cur_pc); 85 | if (map_info == nullptr) { 86 | break; 87 | } 88 | 89 | Elf* elf = map_info->GetElf(process_memory_, arch); 90 | uint64_t rel_pc = elf->GetRelPc(cur_pc, map_info); 91 | uint64_t step_pc = rel_pc; 92 | uint64_t pc_adjustment; 93 | if (adjust_pc) { 94 | pc_adjustment = GetPcAdjustment(rel_pc, elf, arch); 95 | } else { 96 | pc_adjustment = 0; 97 | } 98 | step_pc -= pc_adjustment; 99 | 100 | bool finished = false; 101 | bool is_signal_frame = false; 102 | if (elf->StepIfSignalHandler(rel_pc, regs.get(), process_memory_.get())) { 103 | step_pc = rel_pc; 104 | } else if (!elf->Step(step_pc, regs.get(), process_memory_.get(), &finished, 105 | &is_signal_frame)) { 106 | finished = true; 107 | } 108 | 109 | // Skip any locations that are within this library. 110 | if (num_frames != 0 || !ShouldSkipLibrary(map_info->name)) { 111 | // Add frame information. 112 | SharedString func_name; 113 | uint64_t func_offset; 114 | if (elf->GetFunctionName(rel_pc, &func_name, &func_offset)) { 115 | frame_info->emplace_back(map_info, cur_pc - pc_adjustment, rel_pc - pc_adjustment, 116 | func_name, func_offset); 117 | } else { 118 | frame_info->emplace_back(map_info, cur_pc - pc_adjustment, rel_pc - pc_adjustment, "", 0); 119 | } 120 | num_frames++; 121 | } 122 | 123 | if (finished || frame_info->size() == max_frames || 124 | (cur_pc == regs->pc() && cur_sp == regs->sp())) { 125 | break; 126 | } 127 | adjust_pc = true; 128 | } 129 | return num_frames != 0; 130 | } 131 | 132 | } // namespace unwindstack 133 | -------------------------------------------------------------------------------- /Log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #define LOG_TAG "unwind" 24 | #include 25 | 26 | #include 27 | 28 | #include 29 | 30 | namespace unwindstack { 31 | 32 | static bool g_print_to_stdout = false; 33 | 34 | void log_to_stdout(bool enable) { 35 | g_print_to_stdout = enable; 36 | } 37 | 38 | // Send the data to the log. 39 | void log(uint8_t indent, const char* format, ...) { 40 | std::string real_format; 41 | if (indent > 0) { 42 | real_format = android::base::StringPrintf("%*s%s", 2 * indent, " ", format); 43 | } else { 44 | real_format = format; 45 | } 46 | va_list args; 47 | va_start(args, format); 48 | if (g_print_to_stdout) { 49 | real_format += '\n'; 50 | vprintf(real_format.c_str(), args); 51 | } else { 52 | LOG_PRI_VA(ANDROID_LOG_INFO, LOG_TAG, real_format.c_str(), args); 53 | } 54 | va_end(args); 55 | } 56 | 57 | } // namespace unwindstack 58 | -------------------------------------------------------------------------------- /MemoryBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_BUFFER_H 18 | #define _LIBUNWINDSTACK_MEMORY_BUFFER_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | class MemoryBuffer : public Memory { 30 | public: 31 | MemoryBuffer() = default; 32 | virtual ~MemoryBuffer() { free(raw_); } 33 | 34 | size_t Read(uint64_t addr, void* dst, size_t size) override; 35 | 36 | uint8_t* GetPtr(size_t offset) override; 37 | 38 | bool Resize(size_t size) { 39 | void* new_raw = realloc(raw_, size); 40 | if (new_raw == nullptr) { 41 | free(raw_); 42 | raw_ = nullptr; 43 | size_ = 0; 44 | return false; 45 | } 46 | raw_ = reinterpret_cast(new_raw); 47 | size_ = size; 48 | return true; 49 | } 50 | 51 | uint64_t Size() { return size_; } 52 | 53 | private: 54 | uint8_t* raw_ = nullptr; 55 | size_t size_ = 0; 56 | }; 57 | 58 | } // namespace unwindstack 59 | 60 | #endif // _LIBUNWINDSTACK_MEMORY_BUFFER_H 61 | -------------------------------------------------------------------------------- /MemoryCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_CACHE_H 18 | #define _LIBUNWINDSTACK_MEMORY_CACHE_H 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | namespace unwindstack { 31 | 32 | class MemoryCacheBase : public Memory { 33 | public: 34 | MemoryCacheBase(Memory* memory) : impl_(memory) {} 35 | virtual ~MemoryCacheBase() = default; 36 | 37 | size_t Read(uint64_t addr, void* dst, size_t size) override { 38 | // Only look at the cache for small reads. 39 | if (size > 64) { 40 | return impl_->Read(addr, dst, size); 41 | } 42 | return CachedRead(addr, dst, size); 43 | } 44 | 45 | long ReadTag(uint64_t addr) override { return impl_->ReadTag(addr); } 46 | 47 | protected: 48 | constexpr static size_t kCacheBits = 12; 49 | constexpr static size_t kCacheMask = (1 << kCacheBits) - 1; 50 | constexpr static size_t kCacheSize = 1 << kCacheBits; 51 | 52 | using CacheDataType = std::unordered_map; 53 | 54 | virtual size_t CachedRead(uint64_t addr, void* dst, size_t size) = 0; 55 | 56 | size_t InternalCachedRead(uint64_t addr, void* dst, size_t size, CacheDataType* cache); 57 | 58 | std::unique_ptr impl_; 59 | }; 60 | 61 | class MemoryCache : public MemoryCacheBase { 62 | public: 63 | MemoryCache(Memory* memory) : MemoryCacheBase(memory) {} 64 | virtual ~MemoryCache() = default; 65 | 66 | size_t CachedRead(uint64_t addr, void* dst, size_t size) override; 67 | 68 | void Clear() override; 69 | 70 | protected: 71 | CacheDataType cache_; 72 | 73 | std::mutex cache_lock_; 74 | }; 75 | 76 | class MemoryThreadCache : public MemoryCacheBase { 77 | public: 78 | MemoryThreadCache(Memory* memory); 79 | virtual ~MemoryThreadCache(); 80 | 81 | size_t CachedRead(uint64_t addr, void* dst, size_t size) override; 82 | 83 | void Clear() override; 84 | 85 | protected: 86 | std::optional thread_cache_; 87 | }; 88 | 89 | } // namespace unwindstack 90 | 91 | #endif // _LIBUNWINDSTACK_MEMORY_CACHE_H 92 | -------------------------------------------------------------------------------- /MemoryFileAtOffset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_FILE_AT_OFFSET_H 18 | #define _LIBUNWINDSTACK_MEMORY_FILE_AT_OFFSET_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | class MemoryFileAtOffset : public Memory { 27 | public: 28 | MemoryFileAtOffset() = default; 29 | virtual ~MemoryFileAtOffset(); 30 | 31 | bool Init(const std::string& file, uint64_t offset, uint64_t size = UINT64_MAX); 32 | 33 | uint8_t* GetPtr(size_t addr = 0) override { return addr < size_ ? data_ + addr : nullptr; } 34 | 35 | size_t Read(uint64_t addr, void* dst, size_t size) override; 36 | 37 | size_t Size() { return size_; } 38 | 39 | void Clear() override; 40 | 41 | protected: 42 | size_t size_ = 0; 43 | size_t offset_ = 0; 44 | uint8_t* data_ = nullptr; 45 | }; 46 | 47 | } // namespace unwindstack 48 | 49 | #endif // _LIBUNWINDSTACK_MEMORY_FILE_AT_OFFSET_H 50 | -------------------------------------------------------------------------------- /MemoryLocal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_LOCAL_H 18 | #define _LIBUNWINDSTACK_MEMORY_LOCAL_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | class MemoryLocal : public Memory { 27 | public: 28 | MemoryLocal() = default; 29 | virtual ~MemoryLocal() = default; 30 | 31 | size_t Read(uint64_t addr, void* dst, size_t size) override; 32 | long ReadTag(uint64_t addr) override; 33 | }; 34 | 35 | } // namespace unwindstack 36 | 37 | #endif // _LIBUNWINDSTACK_MEMORY_LOCAL_H 38 | -------------------------------------------------------------------------------- /MemoryMte.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "MemoryLocal.h" 22 | #include "MemoryRemote.h" 23 | 24 | namespace unwindstack { 25 | 26 | long MemoryRemote::ReadTag(uint64_t addr) { 27 | return -1; 28 | } 29 | 30 | long MemoryLocal::ReadTag(uint64_t addr) { 31 | return -1; 32 | } 33 | 34 | } // namespace unwindstack 35 | -------------------------------------------------------------------------------- /MemoryOffline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_OFFLINE_H 18 | #define _LIBUNWINDSTACK_MEMORY_OFFLINE_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #include "MemoryRange.h" 29 | 30 | namespace unwindstack { 31 | 32 | class MemoryOffline : public Memory { 33 | public: 34 | MemoryOffline() = default; 35 | virtual ~MemoryOffline() = default; 36 | 37 | bool Init(const std::string& file, uint64_t offset); 38 | 39 | size_t Read(uint64_t addr, void* dst, size_t size) override; 40 | 41 | private: 42 | std::unique_ptr memory_; 43 | }; 44 | 45 | class MemoryOfflineParts : public Memory { 46 | public: 47 | MemoryOfflineParts() = default; 48 | virtual ~MemoryOfflineParts(); 49 | 50 | void Add(MemoryOffline* memory) { memories_.push_back(memory); } 51 | 52 | size_t Read(uint64_t addr, void* dst, size_t size) override; 53 | 54 | private: 55 | std::vector memories_; 56 | }; 57 | 58 | } // namespace unwindstack 59 | 60 | #endif // _LIBUNWINDSTACK_MEMORY_OFFLINE_H 61 | -------------------------------------------------------------------------------- /MemoryOfflineBuffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_OFFLINE_BUFFER_H 18 | #define _LIBUNWINDSTACK_MEMORY_OFFLINE_BUFFER_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | class MemoryOfflineBuffer : public Memory { 27 | public: 28 | MemoryOfflineBuffer(const uint8_t* data, uint64_t start, uint64_t end); 29 | virtual ~MemoryOfflineBuffer() = default; 30 | 31 | void Reset(const uint8_t* data, uint64_t start, uint64_t end); 32 | 33 | size_t Read(uint64_t addr, void* dst, size_t size) override; 34 | 35 | private: 36 | const uint8_t* data_; 37 | uint64_t start_; 38 | uint64_t end_; 39 | }; 40 | 41 | } // namespace unwindstack 42 | 43 | #endif // _LIBUNWINDSTACK_MEMORY_OFFLINE_BUFFER_H 44 | -------------------------------------------------------------------------------- /MemoryRange.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_RANGE_H 18 | #define _LIBUNWINDSTACK_MEMORY_RANGE_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | namespace unwindstack { 29 | 30 | // MemoryRange maps one address range onto another. 31 | // The range [src_begin, src_begin + length) in the underlying Memory is mapped onto offset, 32 | // such that range.read(offset) is equivalent to underlying.read(src_begin). 33 | class MemoryRange : public Memory { 34 | public: 35 | MemoryRange(const std::shared_ptr& memory, uint64_t begin, uint64_t length, 36 | uint64_t offset); 37 | virtual ~MemoryRange() = default; 38 | 39 | size_t Read(uint64_t addr, void* dst, size_t size) override; 40 | 41 | uint64_t offset() { return offset_; } 42 | uint64_t length() { return length_; } 43 | 44 | private: 45 | std::shared_ptr memory_; 46 | uint64_t begin_; 47 | uint64_t length_; 48 | uint64_t offset_; 49 | }; 50 | 51 | class MemoryRanges : public Memory { 52 | public: 53 | MemoryRanges() = default; 54 | virtual ~MemoryRanges() = default; 55 | 56 | void Insert(MemoryRange* memory); 57 | 58 | size_t Read(uint64_t addr, void* dst, size_t size) override; 59 | 60 | private: 61 | std::map> maps_; 62 | }; 63 | 64 | } // namespace unwindstack 65 | 66 | #endif // _LIBUNWINDSTACK_MEMORY_RANGE_H 67 | -------------------------------------------------------------------------------- /MemoryRemote.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_REMOTE_H 18 | #define _LIBUNWINDSTACK_MEMORY_REMOTE_H 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | class MemoryRemote : public Memory { 30 | public: 31 | MemoryRemote(pid_t pid) : pid_(pid), read_redirect_func_(0) {} 32 | virtual ~MemoryRemote() = default; 33 | 34 | size_t Read(uint64_t addr, void* dst, size_t size) override; 35 | long ReadTag(uint64_t addr) override; 36 | 37 | pid_t pid() { return pid_; } 38 | 39 | private: 40 | pid_t pid_; 41 | std::atomic_uintptr_t read_redirect_func_; 42 | }; 43 | 44 | } // namespace unwindstack 45 | 46 | #endif // _LIBUNWINDSTACK_MEMORY_REMOTE_H 47 | -------------------------------------------------------------------------------- /MemoryXz.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_XZ_H 18 | #define _LIBUNWINDSTACK_MEMORY_XZ_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace unwindstack { 27 | 28 | class MemoryXz : public Memory { 29 | public: 30 | MemoryXz(Memory* memory, uint64_t addr, uint64_t size, const std::string& name); 31 | ~MemoryXz(); 32 | 33 | bool Init(); 34 | size_t Size() { return size_; } 35 | size_t Read(uint64_t addr, void* dst, size_t size) override; 36 | 37 | // Methods used in tests. 38 | size_t MemoryUsage() { return used_; } 39 | size_t BlockCount() { return blocks_.size(); } 40 | size_t BlockSize() { return 1 << block_size_log2_; } 41 | 42 | private: 43 | static constexpr size_t kMaxCompressedSize = 1 << 30; // 1GB. Arbitrary. 44 | 45 | struct XzBlock { 46 | std::unique_ptr decompressed_data; 47 | uint32_t decompressed_size; 48 | uint32_t compressed_offset; 49 | uint32_t compressed_size; 50 | uint16_t stream_flags; 51 | }; 52 | bool ReadBlocks(); 53 | bool Decompress(XzBlock* block); 54 | 55 | // Compressed input. 56 | Memory* compressed_memory_; 57 | uint64_t compressed_addr_; 58 | uint64_t compressed_size_; 59 | std::string name_; 60 | 61 | // Decompressed output. 62 | std::vector blocks_; 63 | uint32_t used_ = 0; // Memory usage of the currently decompressed blocks. 64 | uint32_t size_ = 0; // Decompressed size of all blocks. 65 | uint32_t block_size_log2_ = 31; 66 | 67 | // Statistics (used only for optional debug log messages). 68 | static std::atomic_size_t total_used_; // Currently decompressed memory (current memory use). 69 | static std::atomic_size_t total_size_; // Size of mini-debug-info if it was all decompressed. 70 | static std::atomic_size_t total_open_; // Number of mini-debug-info files currently in use. 71 | }; 72 | 73 | } // namespace unwindstack 74 | 75 | #endif // _LIBUNWINDSTACK_MEMORY_XZ_H 76 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | cferris@google.com 2 | -------------------------------------------------------------------------------- /Regs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | namespace unwindstack { 40 | 41 | // The largest user structure. 42 | constexpr size_t MAX_USER_REGS_SIZE = sizeof(mips64_user_regs) + 10; 43 | 44 | // This function assumes that reg_data is already aligned to a 64 bit value. 45 | // If not this could crash with an unaligned access. 46 | Regs* Regs::RemoteGet(pid_t pid) { 47 | // Make the buffer large enough to contain the largest registers type. 48 | std::vector buffer(MAX_USER_REGS_SIZE / sizeof(uint64_t)); 49 | struct iovec io; 50 | io.iov_base = buffer.data(); 51 | io.iov_len = buffer.size() * sizeof(uint64_t); 52 | 53 | if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, reinterpret_cast(&io)) == -1) { 54 | return nullptr; 55 | } 56 | 57 | switch (io.iov_len) { 58 | case sizeof(x86_user_regs): 59 | return RegsX86::Read(buffer.data()); 60 | case sizeof(x86_64_user_regs): 61 | return RegsX86_64::Read(buffer.data()); 62 | case sizeof(arm_user_regs): 63 | return RegsArm::Read(buffer.data()); 64 | case sizeof(arm64_user_regs): 65 | return RegsArm64::Read(buffer.data()); 66 | case sizeof(mips_user_regs): 67 | return RegsMips::Read(buffer.data()); 68 | case sizeof(mips64_user_regs): 69 | return RegsMips64::Read(buffer.data()); 70 | } 71 | return nullptr; 72 | } 73 | 74 | Regs* Regs::CreateFromUcontext(ArchEnum arch, void* ucontext) { 75 | switch (arch) { 76 | case ARCH_X86: 77 | return RegsX86::CreateFromUcontext(ucontext); 78 | case ARCH_X86_64: 79 | return RegsX86_64::CreateFromUcontext(ucontext); 80 | case ARCH_ARM: 81 | return RegsArm::CreateFromUcontext(ucontext); 82 | case ARCH_ARM64: 83 | return RegsArm64::CreateFromUcontext(ucontext); 84 | case ARCH_MIPS: 85 | return RegsMips::CreateFromUcontext(ucontext); 86 | case ARCH_MIPS64: 87 | return RegsMips64::CreateFromUcontext(ucontext); 88 | case ARCH_UNKNOWN: 89 | default: 90 | return nullptr; 91 | } 92 | } 93 | 94 | ArchEnum Regs::CurrentArch() { 95 | #if defined(__arm__) 96 | return ARCH_ARM; 97 | #elif defined(__aarch64__) 98 | return ARCH_ARM64; 99 | #elif defined(__i386__) 100 | return ARCH_X86; 101 | #elif defined(__x86_64__) 102 | return ARCH_X86_64; 103 | #else 104 | abort(); 105 | #endif 106 | } 107 | 108 | Regs* Regs::CreateFromLocal() { 109 | Regs* regs; 110 | #if defined(__arm__) 111 | regs = new RegsArm(); 112 | #elif defined(__aarch64__) 113 | regs = new RegsArm64(); 114 | #elif defined(__i386__) 115 | regs = new RegsX86(); 116 | #elif defined(__x86_64__) 117 | regs = new RegsX86_64(); 118 | #else 119 | abort(); 120 | #endif 121 | return regs; 122 | } 123 | 124 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch) { 125 | switch (arch) { 126 | case ARCH_ARM: { 127 | if (!elf->valid()) { 128 | return 2; 129 | } 130 | 131 | uint64_t load_bias = elf->GetLoadBias(); 132 | if (rel_pc < load_bias) { 133 | if (rel_pc < 2) { 134 | return 0; 135 | } 136 | return 2; 137 | } 138 | uint64_t adjusted_rel_pc = rel_pc - load_bias; 139 | if (adjusted_rel_pc < 5) { 140 | if (adjusted_rel_pc < 2) { 141 | return 0; 142 | } 143 | return 2; 144 | } 145 | 146 | if (adjusted_rel_pc & 1) { 147 | // This is a thumb instruction, it could be 2 or 4 bytes. 148 | uint32_t value; 149 | if (!elf->memory()->ReadFully(adjusted_rel_pc - 5, &value, sizeof(value)) || 150 | (value & 0xe000f000) != 0xe000f000) { 151 | return 2; 152 | } 153 | } 154 | return 4; 155 | } 156 | case ARCH_ARM64: { 157 | if (rel_pc < 4) { 158 | return 0; 159 | } 160 | return 4; 161 | } 162 | case ARCH_MIPS: 163 | case ARCH_MIPS64: { 164 | if (rel_pc < 8) { 165 | return 0; 166 | } 167 | // For now, just assume no compact branches 168 | return 8; 169 | } 170 | case ARCH_X86: 171 | case ARCH_X86_64: { 172 | if (rel_pc == 0) { 173 | return 0; 174 | } 175 | return 1; 176 | } 177 | case ARCH_UNKNOWN: 178 | return 0; 179 | } 180 | } 181 | 182 | } // namespace unwindstack 183 | -------------------------------------------------------------------------------- /RegsInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_INFO_H 18 | #define _LIBUNWINDSTACK_REGS_INFO_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | template 27 | struct RegsInfo { 28 | static constexpr size_t MAX_REGISTERS = 64; 29 | 30 | RegsInfo(RegsImpl* regs) : regs(regs) {} 31 | 32 | RegsImpl* regs = nullptr; 33 | uint64_t saved_reg_map = 0; 34 | AddressType saved_regs[MAX_REGISTERS]; 35 | 36 | inline AddressType Get(uint32_t reg) { 37 | if (IsSaved(reg)) { 38 | return saved_regs[reg]; 39 | } 40 | return (*regs)[reg]; 41 | } 42 | 43 | inline AddressType* Save(uint32_t reg) { 44 | if (reg >= MAX_REGISTERS) { 45 | // This should never happen since all currently supported 46 | // architectures have < 64 total registers. 47 | abort(); 48 | } 49 | saved_reg_map |= 1ULL << reg; 50 | saved_regs[reg] = (*regs)[reg]; 51 | return &(*regs)[reg]; 52 | } 53 | 54 | inline bool IsSaved(uint32_t reg) { 55 | if (reg > MAX_REGISTERS) { 56 | // This should never happen since all currently supported 57 | // architectures have < 64 total registers. 58 | abort(); 59 | } 60 | return saved_reg_map & (1ULL << reg); 61 | } 62 | 63 | inline uint16_t Total() { return regs->total_regs(); } 64 | }; 65 | 66 | } // namespace unwindstack 67 | 68 | #endif // _LIBUNWINDSTACK_REGS_INFO_H 69 | -------------------------------------------------------------------------------- /Symbols.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_SYMBOLS_H 18 | #define _LIBUNWINDSTACK_SYMBOLS_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | namespace unwindstack { 30 | 31 | // Forward declaration. 32 | class Memory; 33 | 34 | class Symbols { 35 | struct Info { 36 | uint32_t size; // Symbol size in bytes. 37 | uint32_t index; // Index into *sorted* symbol table. 38 | SharedString name; 39 | }; 40 | 41 | public: 42 | Symbols(uint64_t offset, uint64_t size, uint64_t entry_size, uint64_t str_offset, 43 | uint64_t str_size); 44 | virtual ~Symbols() = default; 45 | 46 | template 47 | bool GetName(uint64_t addr, Memory* elf_memory, SharedString* name, uint64_t* func_offset); 48 | 49 | template 50 | bool GetGlobal(Memory* elf_memory, const std::string& name, uint64_t* memory_address); 51 | 52 | void ClearCache() { 53 | symbols_.clear(); 54 | remap_.reset(); 55 | } 56 | 57 | private: 58 | template 59 | Info* BinarySearch(uint64_t addr, Memory* elf_memory, uint64_t* func_offset); 60 | 61 | template 62 | void BuildRemapTable(Memory* elf_memory); 63 | 64 | const uint64_t offset_; 65 | const uint64_t count_; 66 | const uint64_t entry_size_; 67 | const uint64_t str_offset_; 68 | const uint64_t str_end_; 69 | 70 | std::map symbols_; // Cache of read symbols (keyed by function *end* address). 71 | std::optional> remap_; // Indices of function symbols sorted by address. 72 | 73 | // Cache of global data (non-function) symbols. 74 | std::unordered_map> global_variables_; 75 | }; 76 | 77 | } // namespace unwindstack 78 | 79 | #endif // _LIBUNWINDSTACK_SYMBOLS_H 80 | -------------------------------------------------------------------------------- /TEST_MAPPING: -------------------------------------------------------------------------------- 1 | { 2 | "presubmit": [ 3 | { 4 | "name": "libunwindstack_unit_test" 5 | }, 6 | { 7 | "name": "CtsSimpleperfTestCases" 8 | }, 9 | { 10 | "name": "debuggerd_test" 11 | }, 12 | { 13 | "name": "CtsPerfettoTestCases" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /ThreadEntry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #include 27 | 28 | #include "ThreadEntry.h" 29 | 30 | namespace unwindstack { 31 | 32 | std::mutex ThreadEntry::entries_mutex_; 33 | std::map ThreadEntry::entries_; 34 | 35 | // Assumes that ThreadEntry::entries_mutex_ has already been locked before 36 | // creating a ThreadEntry object. 37 | ThreadEntry::ThreadEntry(pid_t tid) : tid_(tid), ref_count_(1), wait_value_(0) { 38 | // Add ourselves to the global list. 39 | entries_[tid_] = this; 40 | } 41 | 42 | ThreadEntry* ThreadEntry::Get(pid_t tid, bool create) { 43 | ThreadEntry* entry = nullptr; 44 | 45 | std::lock_guard guard(entries_mutex_); 46 | auto iter = entries_.find(tid); 47 | if (iter == entries_.end()) { 48 | if (create) { 49 | entry = new ThreadEntry(tid); 50 | } 51 | } else { 52 | entry = iter->second; 53 | entry->ref_count_++; 54 | } 55 | 56 | return entry; 57 | } 58 | 59 | void ThreadEntry::Remove(ThreadEntry* entry) { 60 | entry->Unlock(); 61 | 62 | std::lock_guard guard(entries_mutex_); 63 | if (--entry->ref_count_ == 0) { 64 | delete entry; 65 | } 66 | } 67 | 68 | // Assumes that ThreadEntry::entries_mutex_ has already been locked before 69 | // deleting a ThreadEntry object. 70 | ThreadEntry::~ThreadEntry() { 71 | auto iter = entries_.find(tid_); 72 | if (iter != entries_.end()) { 73 | entries_.erase(iter); 74 | } 75 | } 76 | 77 | bool ThreadEntry::Wait(WaitType type) { 78 | static const std::chrono::duration wait_time(std::chrono::seconds(5)); 79 | std::unique_lock lock(wait_mutex_); 80 | if (wait_cond_.wait_for(lock, wait_time, [this, type] { return wait_value_ == type; })) { 81 | return true; 82 | } else { 83 | log_async_safe("pthread_cond_timedwait for value %d failed", type); 84 | return false; 85 | } 86 | } 87 | 88 | void ThreadEntry::Wake() { 89 | wait_mutex_.lock(); 90 | wait_value_++; 91 | wait_mutex_.unlock(); 92 | 93 | wait_cond_.notify_one(); 94 | } 95 | 96 | void ThreadEntry::CopyUcontextFromSigcontext(void* sigcontext) { 97 | ucontext_t* ucontext = reinterpret_cast(sigcontext); 98 | // The only thing the unwinder cares about is the mcontext data. 99 | memcpy(&ucontext_.uc_mcontext, &ucontext->uc_mcontext, sizeof(ucontext->uc_mcontext)); 100 | } 101 | 102 | } // namespace unwindstack 103 | -------------------------------------------------------------------------------- /ThreadEntry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_THREAD_ENTRY_H 18 | #define _LIBUNWINDSTACK_THREAD_ENTRY_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace unwindstack { 29 | 30 | enum WaitType : int { 31 | WAIT_FOR_UCONTEXT = 1, 32 | WAIT_FOR_UNWIND_TO_COMPLETE, 33 | WAIT_FOR_THREAD_TO_RESTART, 34 | }; 35 | 36 | class ThreadEntry { 37 | public: 38 | static ThreadEntry* Get(pid_t tid, bool create = true); 39 | 40 | static void Remove(ThreadEntry* entry); 41 | 42 | void Wake(); 43 | 44 | bool Wait(WaitType type); 45 | 46 | void CopyUcontextFromSigcontext(void* sigcontext); 47 | 48 | inline void Lock() { 49 | mutex_.lock(); 50 | 51 | // Always reset the wait value since this could be the first or nth 52 | // time this entry is locked. 53 | wait_value_ = 0; 54 | } 55 | 56 | inline void Unlock() { mutex_.unlock(); } 57 | 58 | inline ucontext_t* GetUcontext() { return &ucontext_; } 59 | 60 | private: 61 | ThreadEntry(pid_t tid); 62 | ~ThreadEntry(); 63 | 64 | pid_t tid_; 65 | int ref_count_; 66 | std::mutex mutex_; 67 | std::mutex wait_mutex_; 68 | std::condition_variable wait_cond_; 69 | int wait_value_; 70 | ucontext_t ucontext_; 71 | 72 | static std::mutex entries_mutex_; 73 | static std::map entries_; 74 | }; 75 | 76 | } // namespace unwindstack 77 | 78 | #endif // _LIBUNWINDSTACK_THREAD_ENTRY_H 79 | -------------------------------------------------------------------------------- /android-base/errno_restorer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "errno.h" 20 | 21 | #include "android-base/macros.h" 22 | 23 | namespace android { 24 | namespace base { 25 | 26 | class ErrnoRestorer { 27 | public: 28 | ErrnoRestorer() : saved_errno_(errno) {} 29 | 30 | ~ErrnoRestorer() { errno = saved_errno_; } 31 | 32 | // Allow this object to be used as part of && operation. 33 | explicit operator bool() const { return true; } 34 | 35 | private: 36 | const int saved_errno_; 37 | 38 | DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer); 39 | }; 40 | 41 | } // namespace base 42 | } // namespace android -------------------------------------------------------------------------------- /android-base/file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "android-base/macros.h" 25 | #include "android-base/off64_t.h" 26 | #include "android-base/unique_fd.h" 27 | 28 | #if !defined(_WIN32) && !defined(O_BINARY) 29 | /** Windows needs O_BINARY, but Unix never mangles line endings. */ 30 | #define O_BINARY 0 31 | #endif 32 | 33 | #if defined(_WIN32) && !defined(O_CLOEXEC) 34 | /** Windows has O_CLOEXEC but calls it O_NOINHERIT for some reason. */ 35 | #define O_CLOEXEC O_NOINHERIT 36 | #endif 37 | 38 | class TemporaryFile { 39 | public: 40 | TemporaryFile(); 41 | explicit TemporaryFile(const std::string& tmp_dir); 42 | ~TemporaryFile(); 43 | 44 | // Release the ownership of fd, caller is reponsible for closing the 45 | // fd or stream properly. 46 | int release(); 47 | // Don't remove the temporary file in the destructor. 48 | void DoNotRemove() { remove_file_ = false; } 49 | 50 | int fd; 51 | char path[1024]; 52 | 53 | private: 54 | void init(const std::string& tmp_dir); 55 | 56 | bool remove_file_ = true; 57 | 58 | DISALLOW_COPY_AND_ASSIGN(TemporaryFile); 59 | }; 60 | 61 | class TemporaryDir { 62 | public: 63 | TemporaryDir(); 64 | ~TemporaryDir(); 65 | // Don't remove the temporary dir in the destructor. 66 | void DoNotRemove() { remove_dir_and_contents_ = false; } 67 | 68 | char path[1024]; 69 | 70 | private: 71 | bool init(const std::string& tmp_dir); 72 | 73 | bool remove_dir_and_contents_ = true; 74 | 75 | DISALLOW_COPY_AND_ASSIGN(TemporaryDir); 76 | }; 77 | 78 | namespace android { 79 | namespace base { 80 | 81 | bool ReadFdToString(borrowed_fd fd, std::string* content); 82 | bool ReadFileToString(const std::string& path, std::string* content, 83 | bool follow_symlinks = false); 84 | 85 | bool WriteStringToFile(const std::string& content, const std::string& path, 86 | bool follow_symlinks = false); 87 | bool WriteStringToFd(const std::string& content, borrowed_fd fd); 88 | 89 | #if !defined(_WIN32) 90 | bool WriteStringToFile(const std::string& content, const std::string& path, 91 | mode_t mode, uid_t owner, gid_t group, 92 | bool follow_symlinks = false); 93 | #endif 94 | 95 | bool ReadFully(borrowed_fd fd, void* data, size_t byte_count); 96 | 97 | // Reads `byte_count` bytes from the file descriptor at the specified offset. 98 | // Returns false if there was an IO error or EOF was reached before reading `byte_count` bytes. 99 | // 100 | // NOTE: On Linux/Mac, this function wraps pread, which provides atomic read support without 101 | // modifying the read pointer of the file descriptor. On Windows, however, the read pointer does 102 | // get modified. This means that ReadFullyAtOffset can be used concurrently with other calls to the 103 | // same function, but concurrently seeking or reading incrementally can lead to unexpected 104 | // behavior. 105 | bool ReadFullyAtOffset(borrowed_fd fd, void* data, size_t byte_count, off64_t offset); 106 | 107 | bool WriteFully(borrowed_fd fd, const void* data, size_t byte_count); 108 | 109 | bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr); 110 | 111 | #if !defined(_WIN32) 112 | bool Realpath(const std::string& path, std::string* result); 113 | bool Readlink(const std::string& path, std::string* result); 114 | #endif 115 | 116 | std::string GetExecutablePath(); 117 | std::string GetExecutableDirectory(); 118 | 119 | // Like the regular basename and dirname, but thread-safe on all 120 | // platforms and capable of correctly handling exotic Windows paths. 121 | std::string Basename(const std::string& path); 122 | std::string Dirname(const std::string& path); 123 | 124 | } // namespace base 125 | } // namespace android -------------------------------------------------------------------------------- /android-base/off64_t.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #if defined(__APPLE__) 20 | /** Mac OS has always had a 64-bit off_t, so it doesn't have off64_t. */ 21 | typedef off_t off64_t; 22 | #endif -------------------------------------------------------------------------------- /android-base/stringprintf.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "android-base/stringprintf.h" 18 | 19 | #include 20 | 21 | #include 22 | 23 | namespace android { 24 | namespace base { 25 | 26 | void StringAppendV(std::string* dst, const char* format, va_list ap) { 27 | // First try with a small fixed size buffer 28 | char space[1024]; 29 | 30 | // It's possible for methods that use a va_list to invalidate 31 | // the data in it upon use. The fix is to make a copy 32 | // of the structure before using it and use that copy instead. 33 | va_list backup_ap; 34 | va_copy(backup_ap, ap); 35 | int result = vsnprintf(space, sizeof(space), format, backup_ap); 36 | va_end(backup_ap); 37 | 38 | if (result < static_cast(sizeof(space))) { 39 | if (result >= 0) { 40 | // Normal case -- everything fit. 41 | dst->append(space, result); 42 | return; 43 | } 44 | 45 | if (result < 0) { 46 | // Just an error. 47 | return; 48 | } 49 | } 50 | 51 | // Increase the buffer size to the size requested by vsnprintf, 52 | // plus one for the closing \0. 53 | int length = result + 1; 54 | char* buf = new char[length]; 55 | 56 | // Restore the va_list before we use it again 57 | va_copy(backup_ap, ap); 58 | result = vsnprintf(buf, length, format, backup_ap); 59 | va_end(backup_ap); 60 | 61 | if (result >= 0 && result < length) { 62 | // It fit 63 | dst->append(buf, result); 64 | } 65 | delete[] buf; 66 | } 67 | 68 | std::string StringPrintf(const char* fmt, ...) { 69 | va_list ap; 70 | va_start(ap, fmt); 71 | std::string result; 72 | StringAppendV(&result, fmt, ap); 73 | va_end(ap); 74 | return result; 75 | } 76 | 77 | void StringAppendF(std::string* dst, const char* format, ...) { 78 | va_list ap; 79 | va_start(ap, format); 80 | StringAppendV(dst, format, ap); 81 | va_end(ap); 82 | } 83 | 84 | } // namespace base 85 | } // namespace android 86 | -------------------------------------------------------------------------------- /android-base/stringprintf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2011 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef ANDROID_BASE_STRINGPRINTF_H 18 | #define ANDROID_BASE_STRINGPRINTF_H 19 | 20 | #include 21 | #include 22 | 23 | namespace android { 24 | namespace base { 25 | 26 | // These printf-like functions are implemented in terms of vsnprintf, so they 27 | // use the same attribute for compile-time format string checking. On Windows, 28 | // if the mingw version of vsnprintf is used, use `gnu_printf' which allows z 29 | // in %zd and PRIu64 (and related) to be recognized by the compile-time 30 | // checking. 31 | #define FORMAT_ARCHETYPE __printf__ 32 | #ifdef __USE_MINGW_ANSI_STDIO 33 | #if __USE_MINGW_ANSI_STDIO 34 | #undef FORMAT_ARCHETYPE 35 | #define FORMAT_ARCHETYPE gnu_printf 36 | #endif 37 | #endif 38 | 39 | // Returns a string corresponding to printf-like formatting of the arguments. 40 | std::string StringPrintf(const char* fmt, ...) 41 | __attribute__((__format__(FORMAT_ARCHETYPE, 1, 2))); 42 | 43 | // Appends a printf-like formatting of the arguments to 'dst'. 44 | void StringAppendF(std::string* dst, const char* fmt, ...) 45 | __attribute__((__format__(FORMAT_ARCHETYPE, 2, 3))); 46 | 47 | // Appends a printf-like formatting of the arguments to 'dst'. 48 | void StringAppendV(std::string* dst, const char* format, va_list ap) 49 | __attribute__((__format__(FORMAT_ARCHETYPE, 2, 0))); 50 | 51 | #undef FORMAT_ARCHETYPE 52 | 53 | } // namespace base 54 | } // namespace android 55 | 56 | #endif // ANDROID_BASE_STRINGPRINTF_H 57 | -------------------------------------------------------------------------------- /android-base/strings.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "android-base/strings.h" 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | namespace android { 26 | namespace base { 27 | 28 | #define CHECK_NE(a, b) \ 29 | if ((a) == (b)) abort(); 30 | 31 | std::vector Split(const std::string& s, 32 | const std::string& delimiters) { 33 | CHECK_NE(delimiters.size(), 0U); 34 | 35 | std::vector result; 36 | 37 | size_t base = 0; 38 | size_t found; 39 | while (true) { 40 | found = s.find_first_of(delimiters, base); 41 | result.push_back(s.substr(base, found - base)); 42 | if (found == s.npos) break; 43 | base = found + 1; 44 | } 45 | 46 | return result; 47 | } 48 | 49 | std::string Trim(const std::string& s) { 50 | std::string result; 51 | 52 | if (s.size() == 0) { 53 | return result; 54 | } 55 | 56 | size_t start_index = 0; 57 | size_t end_index = s.size() - 1; 58 | 59 | // Skip initial whitespace. 60 | while (start_index < s.size()) { 61 | if (!isspace(s[start_index])) { 62 | break; 63 | } 64 | start_index++; 65 | } 66 | 67 | // Skip terminating whitespace. 68 | while (end_index >= start_index) { 69 | if (!isspace(s[end_index])) { 70 | break; 71 | } 72 | end_index--; 73 | } 74 | 75 | // All spaces, no beef. 76 | if (end_index < start_index) { 77 | return ""; 78 | } 79 | // Start_index is the first non-space, end_index is the last one. 80 | return s.substr(start_index, end_index - start_index + 1); 81 | } 82 | 83 | // These cases are probably the norm, so we mark them extern in the header to 84 | // aid compile time and binary size. 85 | template std::string Join(const std::vector&, char); 86 | template std::string Join(const std::vector&, char); 87 | template std::string Join(const std::vector&, const std::string&); 88 | template std::string Join(const std::vector&, const std::string&); 89 | 90 | bool StartsWith(std::string_view s, std::string_view prefix) { 91 | return s.substr(0, prefix.size()) == prefix; 92 | } 93 | 94 | bool StartsWith(std::string_view s, char prefix) { 95 | return !s.empty() && s.front() == prefix; 96 | } 97 | 98 | bool StartsWithIgnoreCase(std::string_view s, std::string_view prefix) { 99 | return s.size() >= prefix.size() && strncasecmp(s.data(), prefix.data(), prefix.size()) == 0; 100 | } 101 | 102 | bool EndsWith(std::string_view s, std::string_view suffix) { 103 | return s.size() >= suffix.size() && s.substr(s.size() - suffix.size(), suffix.size()) == suffix; 104 | } 105 | 106 | bool EndsWith(std::string_view s, char suffix) { 107 | return !s.empty() && s.back() == suffix; 108 | } 109 | 110 | bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix) { 111 | return s.size() >= suffix.size() && 112 | strncasecmp(s.data() + (s.size() - suffix.size()), suffix.data(), suffix.size()) == 0; 113 | } 114 | 115 | bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs) { 116 | return lhs.size() == rhs.size() && strncasecmp(lhs.data(), rhs.data(), lhs.size()) == 0; 117 | } 118 | 119 | std::string StringReplace(std::string_view s, std::string_view from, std::string_view to, 120 | bool all) { 121 | if (from.empty()) return std::string(s); 122 | 123 | std::string result; 124 | std::string_view::size_type start_pos = 0; 125 | do { 126 | std::string_view::size_type pos = s.find(from, start_pos); 127 | if (pos == std::string_view::npos) break; 128 | 129 | result.append(s.data() + start_pos, pos - start_pos); 130 | result.append(to.data(), to.size()); 131 | 132 | start_pos = pos + from.size(); 133 | } while (all); 134 | result.append(s.data() + start_pos, s.size() - start_pos); 135 | return result; 136 | } 137 | 138 | } // namespace base 139 | } // namespace android -------------------------------------------------------------------------------- /android-base/strings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | namespace android { 25 | namespace base { 26 | 27 | // Splits a string into a vector of strings. 28 | // 29 | // The string is split at each occurrence of a character in delimiters. 30 | // 31 | // The empty string is not a valid delimiter list. 32 | std::vector Split(const std::string& s, 33 | const std::string& delimiters); 34 | 35 | // Trims whitespace off both ends of the given string. 36 | std::string Trim(const std::string& s); 37 | 38 | // Joins a container of things into a single string, using the given separator. 39 | template 40 | std::string Join(const ContainerT& things, SeparatorT separator) { 41 | if (things.empty()) { 42 | return ""; 43 | } 44 | 45 | std::ostringstream result; 46 | result << *things.begin(); 47 | for (auto it = std::next(things.begin()); it != things.end(); ++it) { 48 | result << separator << *it; 49 | } 50 | return result.str(); 51 | } 52 | 53 | // We instantiate the common cases in strings.cpp. 54 | extern template std::string Join(const std::vector&, char); 55 | extern template std::string Join(const std::vector&, char); 56 | extern template std::string Join(const std::vector&, const std::string&); 57 | extern template std::string Join(const std::vector&, const std::string&); 58 | 59 | // Tests whether 's' starts with 'prefix'. 60 | bool StartsWith(std::string_view s, std::string_view prefix); 61 | bool StartsWith(std::string_view s, char prefix); 62 | bool StartsWithIgnoreCase(std::string_view s, std::string_view prefix); 63 | 64 | // Tests whether 's' ends with 'suffix'. 65 | bool EndsWith(std::string_view s, std::string_view suffix); 66 | bool EndsWith(std::string_view s, char suffix); 67 | bool EndsWithIgnoreCase(std::string_view s, std::string_view suffix); 68 | 69 | // Tests whether 'lhs' equals 'rhs', ignoring case. 70 | bool EqualsIgnoreCase(std::string_view lhs, std::string_view rhs); 71 | 72 | // Removes `prefix` from the start of the given string and returns true (if 73 | // it was present), false otherwise. 74 | inline bool ConsumePrefix(std::string_view* s, std::string_view prefix) { 75 | if (!StartsWith(*s, prefix)) return false; 76 | s->remove_prefix(prefix.size()); 77 | return true; 78 | } 79 | 80 | // Removes `suffix` from the end of the given string and returns true (if 81 | // it was present), false otherwise. 82 | inline bool ConsumeSuffix(std::string_view* s, std::string_view suffix) { 83 | if (!EndsWith(*s, suffix)) return false; 84 | s->remove_suffix(suffix.size()); 85 | return true; 86 | } 87 | 88 | // Replaces `from` with `to` in `s`, once if `all == false`, or as many times as 89 | // there are matches if `all == true`. 90 | [[nodiscard]] std::string StringReplace(std::string_view s, std::string_view from, 91 | std::string_view to, bool all); 92 | 93 | } // namespace base 94 | } // namespace android -------------------------------------------------------------------------------- /android-base/utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #ifdef _WIN32 20 | #include 21 | #include 22 | #else 23 | // Bring in prototypes for standard APIs so that we can import them into the utf8 namespace. 24 | #include // open 25 | #include // fopen 26 | #include // mkdir 27 | #include // unlink 28 | #endif 29 | 30 | namespace android { 31 | namespace base { 32 | 33 | // Only available on Windows because this is only needed on Windows. 34 | #ifdef _WIN32 35 | // Convert size number of UTF-16 wchar_t's to UTF-8. Returns whether the 36 | // conversion was done successfully. 37 | bool WideToUTF8(const wchar_t* utf16, const size_t size, std::string* utf8); 38 | 39 | // Convert a NULL-terminated string of UTF-16 characters to UTF-8. Returns 40 | // whether the conversion was done successfully. 41 | bool WideToUTF8(const wchar_t* utf16, std::string* utf8); 42 | 43 | // Convert a UTF-16 std::wstring (including any embedded NULL characters) to 44 | // UTF-8. Returns whether the conversion was done successfully. 45 | bool WideToUTF8(const std::wstring& utf16, std::string* utf8); 46 | 47 | // Convert size number of UTF-8 char's to UTF-16. Returns whether the conversion 48 | // was done successfully. 49 | bool UTF8ToWide(const char* utf8, const size_t size, std::wstring* utf16); 50 | 51 | // Convert a NULL-terminated string of UTF-8 characters to UTF-16. Returns 52 | // whether the conversion was done successfully. 53 | bool UTF8ToWide(const char* utf8, std::wstring* utf16); 54 | 55 | // Convert a UTF-8 std::string (including any embedded NULL characters) to 56 | // UTF-16. Returns whether the conversion was done successfully. 57 | bool UTF8ToWide(const std::string& utf8, std::wstring* utf16); 58 | 59 | // Convert a file system path, represented as a NULL-terminated string of 60 | // UTF-8 characters, to a UTF-16 string representing the same file system 61 | // path using the Windows extended-lengh path representation. 62 | // 63 | // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#MAXPATH: 64 | // ```The Windows API has many functions that also have Unicode versions to 65 | // permit an extended-length path for a maximum total path length of 32,767 66 | // characters. To specify an extended-length path, use the "\\?\" prefix. 67 | // For example, "\\?\D:\very long path".``` 68 | // 69 | // Returns whether the conversion was done successfully. 70 | bool UTF8PathToWindowsLongPath(const char* utf8, std::wstring* utf16); 71 | #endif 72 | 73 | // The functions in the utf8 namespace take UTF-8 strings. For Windows, these 74 | // are wrappers, for non-Windows these just expose existing APIs. To call these 75 | // functions, use: 76 | // 77 | // // anonymous namespace to avoid conflict with existing open(), unlink(), etc. 78 | // namespace { 79 | // // Import functions into anonymous namespace. 80 | // using namespace android::base::utf8; 81 | // 82 | // void SomeFunction(const char* name) { 83 | // int fd = open(name, ...); // Calls android::base::utf8::open(). 84 | // ... 85 | // unlink(name); // Calls android::base::utf8::unlink(). 86 | // } 87 | // } 88 | namespace utf8 { 89 | 90 | #ifdef _WIN32 91 | FILE* fopen(const char* name, const char* mode); 92 | int mkdir(const char* name, mode_t mode); 93 | int open(const char* name, int flags, ...); 94 | int unlink(const char* name); 95 | #else 96 | using ::fopen; 97 | using ::mkdir; 98 | using ::open; 99 | using ::unlink; 100 | #endif 101 | 102 | } // namespace utf8 103 | } // namespace base 104 | } // namespace android -------------------------------------------------------------------------------- /cmake/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(UNWINDSTACK_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../) 2 | 3 | #if (NOT TARGET lzma) 4 | # add_subdirectory(lzma) 5 | #endif() 6 | 7 | enable_language(ASM) 8 | 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") 10 | include_directories(${UNWINDSTACK_ROOT} ${UNWINDSTACK_ROOT}/include ${UNWINDSTACK_ROOT}/lzma/C) 11 | file(GLOB UNWINDSTACK_SOURCES 12 | ${UNWINDSTACK_ROOT}/ArmExidx.cpp 13 | ${UNWINDSTACK_ROOT}/DexFiles.cpp 14 | ${UNWINDSTACK_ROOT}/DwarfCfa.cpp 15 | ${UNWINDSTACK_ROOT}/DwarfDebugFrame.cpp 16 | ${UNWINDSTACK_ROOT}/DwarfEhFrame.cpp 17 | ${UNWINDSTACK_ROOT}/DwarfMemory.cpp 18 | ${UNWINDSTACK_ROOT}/DwarfOp.cpp 19 | ${UNWINDSTACK_ROOT}/DwarfSection.cpp 20 | ${UNWINDSTACK_ROOT}/Elf.cpp 21 | ${UNWINDSTACK_ROOT}/ElfInterface.cpp 22 | ${UNWINDSTACK_ROOT}/Global.cpp 23 | ${UNWINDSTACK_ROOT}/JitDebug.cpp 24 | ${UNWINDSTACK_ROOT}/Log.cpp 25 | ${UNWINDSTACK_ROOT}/MapInfo.cpp 26 | ${UNWINDSTACK_ROOT}/Maps.cpp 27 | ${UNWINDSTACK_ROOT}/Memory.cpp 28 | ${UNWINDSTACK_ROOT}/MemoryMte.cpp 29 | ${UNWINDSTACK_ROOT}/Regs.cpp 30 | ${UNWINDSTACK_ROOT}/Symbols.cpp 31 | ${UNWINDSTACK_ROOT}/ElfInterfaceArm.cpp 32 | ${UNWINDSTACK_ROOT}/android-base/stringprintf.cpp 33 | ${UNWINDSTACK_ROOT}/android-base/file.cpp 34 | ${UNWINDSTACK_ROOT}/android-base/strings.cpp 35 | ${UNWINDSTACK_ROOT}/getline.c 36 | ${UNWINDSTACK_ROOT}/RegsArm.cpp 37 | ${UNWINDSTACK_ROOT}/RegsArm64.cpp 38 | ${UNWINDSTACK_ROOT}/RegsMips.cpp 39 | ${UNWINDSTACK_ROOT}/RegsMips64.cpp 40 | ${UNWINDSTACK_ROOT}/RegsX86.cpp 41 | ${UNWINDSTACK_ROOT}/RegsX86_64.cpp 42 | ${UNWINDSTACK_ROOT}/DwarfEhFrameWithHdr.cpp 43 | ${UNWINDSTACK_ROOT}/Unwinder.cpp 44 | ) 45 | 46 | if(${CMAKE_SYSTEM_PROCESSOR} MATCHES arm) 47 | elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES x86_64) 48 | file(GLOB UNWINDSTACK_SOURCES_ASMGETREGS 49 | ${UNWINDSTACK_ROOT}/AsmGetRegsX86_64.S 50 | ) 51 | elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES i686) 52 | file(GLOB UNWINDSTACK_SOURCES_ASMGETREGS 53 | ${UNWINDSTACK_ROOT}/AsmGetRegsX86.S 54 | ) 55 | 56 | else() 57 | add_definitions(-DEM_ARM=40) 58 | endif() 59 | 60 | add_library(unwindstack STATIC 61 | ${UNWINDSTACK_SOURCES} 62 | ${UNWINDSTACK_SOURCES_ASMGETREGS} 63 | ) 64 | # target_link_libraries(unwindstack lzma) 65 | -------------------------------------------------------------------------------- /cmake/lzma/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LZMA_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../lzma) 2 | 3 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_7ZIP_ST -Wno-empty-body") 4 | include_directories(${LZMA_ROOT}/C) 5 | file(GLOB LZMA_SOURCES 6 | ${LZMA_ROOT}/C/7zAlloc.c 7 | ${LZMA_ROOT}/C/7zArcIn.c 8 | ${LZMA_ROOT}/C/7zBuf2.c 9 | ${LZMA_ROOT}/C/7zBuf.c 10 | ${LZMA_ROOT}/C/7zCrc.c 11 | ${LZMA_ROOT}/C/7zCrcOpt.c 12 | ${LZMA_ROOT}/C/7zDec.c 13 | ${LZMA_ROOT}/C/7zFile.c 14 | ${LZMA_ROOT}/C/7zStream.c 15 | ${LZMA_ROOT}/C/Aes.c 16 | ${LZMA_ROOT}/C/AesOpt.c 17 | ${LZMA_ROOT}/C/Alloc.c 18 | ${LZMA_ROOT}/C/Bcj2.c 19 | ${LZMA_ROOT}/C/Bra86.c 20 | ${LZMA_ROOT}/C/Bra.c 21 | ${LZMA_ROOT}/C/BraIA64.c 22 | ${LZMA_ROOT}/C/CpuArch.c 23 | ${LZMA_ROOT}/C/Delta.c 24 | ${LZMA_ROOT}/C/LzFind.c 25 | ${LZMA_ROOT}/C/Lzma2Dec.c 26 | ${LZMA_ROOT}/C/Lzma2Enc.c 27 | ${LZMA_ROOT}/C/Lzma86Dec.c 28 | ${LZMA_ROOT}/C/Lzma86Enc.c 29 | ${LZMA_ROOT}/C/LzmaDec.c 30 | ${LZMA_ROOT}/C/LzmaEnc.c 31 | ${LZMA_ROOT}/C/LzmaLib.c 32 | ${LZMA_ROOT}/C/Ppmd7.c 33 | ${LZMA_ROOT}/C/Ppmd7Dec.c 34 | ${LZMA_ROOT}/C/Ppmd7Enc.c 35 | ${LZMA_ROOT}/C/Sha256.c 36 | ${LZMA_ROOT}/C/Sort.c 37 | ${LZMA_ROOT}/C/Xz.c 38 | ${LZMA_ROOT}/C/XzCrc64.c 39 | ${LZMA_ROOT}/C/XzCrc64Opt.c 40 | ${LZMA_ROOT}/C/XzDec.c 41 | ${LZMA_ROOT}/C/XzEnc.c 42 | ${LZMA_ROOT}/C/XzIn.c 43 | ) 44 | add_library(lzma STATIC ${LZMA_SOURCES}) 45 | -------------------------------------------------------------------------------- /getline.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp $ */ 2 | 3 | /*- 4 | * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 | * All rights reserved. 6 | * 7 | * This code is derived from software contributed to The NetBSD Foundation 8 | * by Christos Zoulas. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #include "getline.h" 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | ssize_t 40 | getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp) 41 | { 42 | char *ptr, *eptr; 43 | 44 | 45 | if (*buf == NULL || *bufsiz == 0) { 46 | *bufsiz = BUFSIZ; 47 | if ((*buf = malloc(*bufsiz)) == NULL) 48 | return -1; 49 | } 50 | 51 | for (ptr = *buf, eptr = *buf + *bufsiz;;) { 52 | int c = fgetc(fp); 53 | if (c == -1) { 54 | if (feof(fp)) { 55 | ssize_t diff = (ssize_t)(ptr - *buf); 56 | if (diff != 0) { 57 | *ptr = '\0'; 58 | return diff; 59 | } 60 | } 61 | return -1; 62 | } 63 | *ptr++ = c; 64 | if (c == delimiter) { 65 | *ptr = '\0'; 66 | return ptr - *buf; 67 | } 68 | if (ptr + 2 >= eptr) { 69 | char *nbuf; 70 | size_t nbufsiz = *bufsiz * 2; 71 | ssize_t d = ptr - *buf; 72 | if ((nbuf = realloc(*buf, nbufsiz)) == NULL) 73 | return -1; 74 | *buf = nbuf; 75 | *bufsiz = nbufsiz; 76 | eptr = nbuf + nbufsiz; 77 | ptr = nbuf + d; 78 | } 79 | } 80 | } 81 | 82 | ssize_t 83 | getline(char **buf, size_t *bufsiz, FILE *fp) 84 | { 85 | return getdelim(buf, bufsiz, '\n', fp); 86 | } 87 | -------------------------------------------------------------------------------- /getline.h: -------------------------------------------------------------------------------- 1 | #ifndef GETLINE_H_ 2 | #define GETLINE_H_ 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | ssize_t getline(char **buf, size_t *bufsiz, FILE *fp); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif //GETLINE_H_ -------------------------------------------------------------------------------- /include/GlobalDebugInterface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_GLOBAL_DEBUG_INTERFACE_H 18 | #define _LIBUNWINDSTACK_GLOBAL_DEBUG_INTERFACE_H 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | namespace unwindstack { 26 | 27 | // Base class for architecture specific implementations (see "GlobalDebugImpl.h"). 28 | // It provides access to JITed ELF files, and loaded DEX files in the ART runtime. 29 | template 30 | class GlobalDebugInterface { 31 | public: 32 | virtual ~GlobalDebugInterface() {} 33 | 34 | virtual bool GetFunctionName(Maps* maps, uint64_t pc, SharedString* name, uint64_t* offset) = 0; 35 | 36 | virtual Symfile* Find(Maps* maps, uint64_t pc) = 0; 37 | 38 | protected: 39 | bool Load(Maps* maps, std::shared_ptr& memory, uint64_t addr, uint64_t size, 40 | /*out*/ std::unique_ptr& dex); 41 | }; 42 | 43 | } // namespace unwindstack 44 | 45 | #endif // _LIBUNWINDSTACK_GLOBAL_DEBUG_INTERFACE_H 46 | -------------------------------------------------------------------------------- /include/unwindstack/Arch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_ARCH_H 18 | #define _LIBUNWINDSTACK_ARCH_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum ArchEnum : uint8_t { 25 | ARCH_UNKNOWN = 0, 26 | ARCH_ARM, 27 | ARCH_ARM64, 28 | ARCH_X86, 29 | ARCH_X86_64, 30 | ARCH_MIPS, 31 | ARCH_MIPS64, 32 | }; 33 | 34 | static inline bool ArchIs32Bit(ArchEnum arch) { 35 | switch (arch) { 36 | case ARCH_ARM: 37 | case ARCH_X86: 38 | case ARCH_MIPS: 39 | return true; 40 | default: 41 | return false; 42 | } 43 | } 44 | 45 | } // namespace unwindstack 46 | 47 | #endif // _LIBUNWINDSTACK_ARCH_H 48 | -------------------------------------------------------------------------------- /include/unwindstack/DexFiles.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DEX_FILES_H 18 | #define _LIBUNWINDSTACK_DEX_FILES_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | enum ArchEnum : uint8_t; 30 | class DexFile; 31 | class Memory; 32 | 33 | using DexFiles = GlobalDebugInterface; 34 | 35 | std::unique_ptr CreateDexFiles(ArchEnum arch, std::shared_ptr& memory, 36 | std::vector search_libs = {}); 37 | 38 | } // namespace unwindstack 39 | 40 | #endif // _LIBUNWINDSTACK_DEX_FILES_H 41 | -------------------------------------------------------------------------------- /include/unwindstack/DwarfError.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_ERROR_H 18 | #define _LIBUNWINDSTACK_DWARF_ERROR_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum DwarfErrorCode : uint8_t { 25 | DWARF_ERROR_NONE, 26 | DWARF_ERROR_MEMORY_INVALID, 27 | DWARF_ERROR_ILLEGAL_VALUE, 28 | DWARF_ERROR_ILLEGAL_STATE, 29 | DWARF_ERROR_STACK_INDEX_NOT_VALID, 30 | DWARF_ERROR_NOT_IMPLEMENTED, 31 | DWARF_ERROR_TOO_MANY_ITERATIONS, 32 | DWARF_ERROR_CFA_NOT_DEFINED, 33 | DWARF_ERROR_UNSUPPORTED_VERSION, 34 | DWARF_ERROR_NO_FDES, 35 | }; 36 | 37 | struct DwarfErrorData { 38 | DwarfErrorCode code; 39 | uint64_t address; 40 | }; 41 | 42 | } // namespace unwindstack 43 | 44 | #endif // _LIBUNWINDSTACK_DWARF_ERROR_H 45 | -------------------------------------------------------------------------------- /include/unwindstack/DwarfLocation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_LOCATION_H 18 | #define _LIBUNWINDSTACK_DWARF_LOCATION_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | struct DwarfCie; 27 | 28 | enum DwarfLocationEnum : uint8_t { 29 | DWARF_LOCATION_INVALID = 0, 30 | DWARF_LOCATION_UNDEFINED, 31 | DWARF_LOCATION_OFFSET, 32 | DWARF_LOCATION_VAL_OFFSET, 33 | DWARF_LOCATION_REGISTER, 34 | DWARF_LOCATION_EXPRESSION, 35 | DWARF_LOCATION_VAL_EXPRESSION, 36 | DWARF_LOCATION_PSEUDO_REGISTER, 37 | }; 38 | 39 | struct DwarfLocation { 40 | DwarfLocationEnum type; 41 | uint64_t values[2]; 42 | }; 43 | 44 | struct DwarfLocations : public std::unordered_map { 45 | const DwarfCie* cie; 46 | // The range of PCs where the locations are valid (end is exclusive). 47 | uint64_t pc_start = 0; 48 | uint64_t pc_end = 0; 49 | }; 50 | 51 | } // namespace unwindstack 52 | 53 | #endif // _LIBUNWINDSTACK_DWARF_LOCATION_H 54 | -------------------------------------------------------------------------------- /include/unwindstack/DwarfMemory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_MEMORY_H 18 | #define _LIBUNWINDSTACK_DWARF_MEMORY_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | // Forward declarations. 25 | class Memory; 26 | 27 | class DwarfMemory { 28 | public: 29 | DwarfMemory(Memory* memory) : memory_(memory) {} 30 | virtual ~DwarfMemory() = default; 31 | 32 | bool ReadBytes(void* dst, size_t num_bytes); 33 | 34 | template 35 | bool ReadSigned(uint64_t* value); 36 | 37 | bool ReadULEB128(uint64_t* value); 38 | 39 | bool ReadSLEB128(int64_t* value); 40 | 41 | template 42 | size_t GetEncodedSize(uint8_t encoding); 43 | 44 | bool AdjustEncodedValue(uint8_t encoding, uint64_t* value); 45 | 46 | template 47 | bool ReadEncodedValue(uint8_t encoding, uint64_t* value); 48 | 49 | uint64_t cur_offset() { return cur_offset_; } 50 | void set_cur_offset(uint64_t cur_offset) { cur_offset_ = cur_offset; } 51 | 52 | void set_pc_offset(int64_t offset) { pc_offset_ = offset; } 53 | void clear_pc_offset() { pc_offset_ = INT64_MAX; } 54 | 55 | void set_data_offset(uint64_t offset) { data_offset_ = offset; } 56 | void clear_data_offset() { data_offset_ = static_cast(-1); } 57 | 58 | void set_func_offset(uint64_t offset) { func_offset_ = offset; } 59 | void clear_func_offset() { func_offset_ = static_cast(-1); } 60 | 61 | void set_text_offset(uint64_t offset) { text_offset_ = offset; } 62 | void clear_text_offset() { text_offset_ = static_cast(-1); } 63 | 64 | private: 65 | Memory* memory_; 66 | uint64_t cur_offset_ = 0; 67 | 68 | int64_t pc_offset_ = INT64_MAX; 69 | uint64_t data_offset_ = static_cast(-1); 70 | uint64_t func_offset_ = static_cast(-1); 71 | uint64_t text_offset_ = static_cast(-1); 72 | }; 73 | 74 | } // namespace unwindstack 75 | 76 | #endif // _LIBUNWINDSTACK_DWARF_MEMORY_H 77 | -------------------------------------------------------------------------------- /include/unwindstack/DwarfStructs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_DWARF_STRUCTS_H 18 | #define _LIBUNWINDSTACK_DWARF_STRUCTS_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | namespace unwindstack { 25 | 26 | struct DwarfCie { 27 | uint8_t version = 0; 28 | uint8_t fde_address_encoding = 0; 29 | uint8_t lsda_encoding = 0; 30 | uint8_t segment_size = 0; 31 | std::vector augmentation_string; 32 | uint64_t personality_handler = 0; 33 | uint64_t cfa_instructions_offset = 0; 34 | uint64_t cfa_instructions_end = 0; 35 | uint64_t code_alignment_factor = 0; 36 | int64_t data_alignment_factor = 0; 37 | uint64_t return_address_register = 0; 38 | bool is_signal_frame = false; 39 | }; 40 | 41 | struct DwarfFde { 42 | uint64_t cie_offset = 0; 43 | uint64_t cfa_instructions_offset = 0; 44 | uint64_t cfa_instructions_end = 0; 45 | uint64_t pc_start = 0; 46 | uint64_t pc_end = 0; 47 | uint64_t lsda_address = 0; 48 | const DwarfCie* cie = nullptr; 49 | }; 50 | 51 | constexpr uint16_t CFA_REG = static_cast(-1); 52 | 53 | } // namespace unwindstack 54 | 55 | #endif // _LIBUNWINDSTACK_DWARF_STRUCTS_H 56 | -------------------------------------------------------------------------------- /include/unwindstack/Elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_ELF_H 18 | #define _LIBUNWINDSTACK_ELF_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #if !defined(EM_AARCH64) 34 | #define EM_AARCH64 183 35 | #endif 36 | 37 | namespace unwindstack { 38 | 39 | // Forward declaration. 40 | struct MapInfo; 41 | class Regs; 42 | 43 | class Elf { 44 | public: 45 | Elf(Memory* memory) : memory_(memory) {} 46 | virtual ~Elf() = default; 47 | 48 | bool Init(); 49 | 50 | void InitGnuDebugdata(); 51 | 52 | void Invalidate(); 53 | 54 | std::string GetSoname(); 55 | 56 | bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* func_offset); 57 | 58 | bool GetGlobalVariableOffset(const std::string& name, uint64_t* memory_offset); 59 | 60 | uint64_t GetRelPc(uint64_t pc, const MapInfo* map_info); 61 | 62 | bool StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory); 63 | 64 | bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished, 65 | bool* is_signal_frame); 66 | 67 | bool Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, 68 | Memory* process_memory, bool* finished); 69 | 70 | ElfInterface* CreateInterfaceFromMemory(Memory* memory); 71 | 72 | std::string GetBuildID(); 73 | 74 | int64_t GetLoadBias() { return load_bias_; } 75 | 76 | bool IsValidPc(uint64_t pc); 77 | 78 | bool GetTextRange(uint64_t* addr, uint64_t* size); 79 | 80 | void GetLastError(ErrorData* data); 81 | ErrorCode GetLastErrorCode(); 82 | uint64_t GetLastErrorAddress(); 83 | 84 | bool valid() { return valid_; } 85 | 86 | uint32_t machine_type() { return machine_type_; } 87 | 88 | uint8_t class_type() { return class_type_; } 89 | 90 | ArchEnum arch() { return arch_; } 91 | 92 | Memory* memory() { return memory_.get(); } 93 | 94 | ElfInterface* interface() { return interface_.get(); } 95 | 96 | ElfInterface* gnu_debugdata_interface() { return gnu_debugdata_interface_.get(); } 97 | 98 | static bool IsValidElf(Memory* memory); 99 | 100 | static bool GetInfo(Memory* memory, uint64_t* size); 101 | 102 | static int64_t GetLoadBias(Memory* memory); 103 | 104 | static std::string GetBuildID(Memory* memory); 105 | 106 | static void SetCachingEnabled(bool enable); 107 | static bool CachingEnabled() { return cache_enabled_; } 108 | 109 | static void CacheLock(); 110 | static void CacheUnlock(); 111 | static void CacheAdd(MapInfo* info); 112 | static bool CacheGet(MapInfo* info); 113 | static bool CacheAfterCreateMemory(MapInfo* info); 114 | 115 | protected: 116 | bool valid_ = false; 117 | int64_t load_bias_ = 0; 118 | std::unique_ptr interface_; 119 | std::unique_ptr memory_; 120 | uint32_t machine_type_; 121 | uint8_t class_type_; 122 | ArchEnum arch_; 123 | // Protect calls that can modify internal state of the interface object. 124 | std::mutex lock_; 125 | 126 | std::unique_ptr gnu_debugdata_memory_; 127 | std::unique_ptr gnu_debugdata_interface_; 128 | 129 | static bool cache_enabled_; 130 | static std::unordered_map, bool>>* cache_; 131 | static std::mutex* cache_lock_; 132 | }; 133 | 134 | } // namespace unwindstack 135 | 136 | #endif // _LIBUNWINDSTACK_ELF_H 137 | -------------------------------------------------------------------------------- /include/unwindstack/Error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_ERROR_H 18 | #define _LIBUNWINDSTACK_ERROR_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | // A bit map of warnings, multiple warnings can be set at the same time. 25 | enum WarningCode : uint64_t { 26 | WARNING_NONE = 0, 27 | WARNING_DEX_PC_NOT_IN_MAP = 0x1, // A dex pc was found, but it doesn't exist 28 | // in any valid map. 29 | }; 30 | 31 | enum ErrorCode : uint8_t { 32 | ERROR_NONE, // No error. 33 | ERROR_MEMORY_INVALID, // Memory read failed. 34 | ERROR_UNWIND_INFO, // Unable to use unwind information to unwind. 35 | ERROR_UNSUPPORTED, // Encountered unsupported feature. 36 | ERROR_INVALID_MAP, // Unwind in an invalid map. 37 | ERROR_MAX_FRAMES_EXCEEDED, // The number of frames exceed the total allowed. 38 | ERROR_REPEATED_FRAME, // The last frame has the same pc/sp as the next. 39 | ERROR_INVALID_ELF, // Unwind in an invalid elf. 40 | ERROR_THREAD_DOES_NOT_EXIST, // Attempt to unwind a local thread that does 41 | // not exist. 42 | ERROR_THREAD_TIMEOUT, // Timeout trying to unwind a local thread. 43 | ERROR_SYSTEM_CALL, // System call failed while unwinding. 44 | ERROR_MAX = ERROR_SYSTEM_CALL, 45 | }; 46 | 47 | static inline const char* GetErrorCodeString(ErrorCode error) { 48 | switch (error) { 49 | case ERROR_NONE: 50 | return "None"; 51 | case ERROR_MEMORY_INVALID: 52 | return "Memory Invalid"; 53 | case ERROR_UNWIND_INFO: 54 | return "Unwind Info"; 55 | case ERROR_UNSUPPORTED: 56 | return "Unsupported"; 57 | case ERROR_INVALID_MAP: 58 | return "Invalid Map"; 59 | case ERROR_MAX_FRAMES_EXCEEDED: 60 | return "Maximum Frames Exceeded"; 61 | case ERROR_REPEATED_FRAME: 62 | return "Repeated Frame"; 63 | case ERROR_INVALID_ELF: 64 | return "Invalid Elf"; 65 | case ERROR_THREAD_DOES_NOT_EXIST: 66 | return "Thread Does Not Exist"; 67 | case ERROR_THREAD_TIMEOUT: 68 | return "Thread Timeout"; 69 | case ERROR_SYSTEM_CALL: 70 | return "System Call Failed"; 71 | } 72 | } 73 | 74 | struct ErrorData { 75 | ErrorCode code; 76 | uint64_t address; // Only valid when code is ERROR_MEMORY_INVALID. 77 | // Indicates the failing address. 78 | }; 79 | 80 | } // namespace unwindstack 81 | 82 | #endif // _LIBUNWINDSTACK_ERROR_H 83 | -------------------------------------------------------------------------------- /include/unwindstack/Global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_GLOBAL_H 18 | #define _LIBUNWINDSTACK_GLOBAL_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | namespace unwindstack { 32 | 33 | // Forward declarations. 34 | class Maps; 35 | struct MapInfo; 36 | 37 | class Global { 38 | public: 39 | explicit Global(std::shared_ptr& memory); 40 | Global(std::shared_ptr& memory, std::vector& search_libs); 41 | virtual ~Global() = default; 42 | 43 | void SetArch(ArchEnum arch); 44 | 45 | ArchEnum arch() { return arch_; } 46 | 47 | protected: 48 | bool Searchable(const std::string& name); 49 | void FindAndReadVariable(Maps* maps, const char* variable); 50 | 51 | virtual bool ReadVariableData(uint64_t offset) = 0; 52 | 53 | virtual void ProcessArch() = 0; 54 | 55 | ArchEnum arch_ = ARCH_UNKNOWN; 56 | 57 | std::shared_ptr memory_; 58 | std::vector search_libs_; 59 | }; 60 | 61 | } // namespace unwindstack 62 | 63 | #endif // _LIBUNWINDSTACK_GLOBAL_H 64 | -------------------------------------------------------------------------------- /include/unwindstack/JitDebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_JIT_DEBUG_H 18 | #define _LIBUNWINDSTACK_JIT_DEBUG_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | enum ArchEnum : uint8_t; 30 | class Elf; 31 | class Memory; 32 | 33 | using JitDebug = GlobalDebugInterface; 34 | 35 | std::unique_ptr CreateJitDebug(ArchEnum arch, std::shared_ptr& memory, 36 | std::vector search_libs = {}); 37 | 38 | } // namespace unwindstack 39 | 40 | #endif // _LIBUNWINDSTACK_JIT_DEBUG_H 41 | -------------------------------------------------------------------------------- /include/unwindstack/LocalUnwinder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_LOCAL_UNWINDER_H 18 | #define _LIBUNWINDSTACK_LOCAL_UNWINDER_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | namespace unwindstack { 33 | 34 | // Forward declarations. 35 | class Elf; 36 | struct MapInfo; 37 | 38 | struct LocalFrameData { 39 | LocalFrameData(MapInfo* map_info, uint64_t pc, uint64_t rel_pc, const std::string& function_name, 40 | uint64_t function_offset) 41 | : map_info(map_info), 42 | pc(pc), 43 | rel_pc(rel_pc), 44 | function_name(function_name), 45 | function_offset(function_offset) {} 46 | 47 | MapInfo* map_info; 48 | uint64_t pc; 49 | uint64_t rel_pc; 50 | std::string function_name; 51 | uint64_t function_offset; 52 | }; 53 | 54 | // This is a specialized class that should only be used for doing local unwinds. 55 | // The Unwind call can be made as multiple times on the same object, and it can 56 | // be called by multiple threads at the same time. 57 | // It is designed to be used in debugging circumstances to get a stack trace 58 | // as fast as possible. 59 | class LocalUnwinder { 60 | public: 61 | LocalUnwinder() = default; 62 | LocalUnwinder(const std::vector& skip_libraries) : skip_libraries_(skip_libraries) {} 63 | ~LocalUnwinder() = default; 64 | 65 | bool Init(); 66 | 67 | bool Unwind(std::vector* frame_info, size_t max_frames); 68 | 69 | bool ShouldSkipLibrary(const std::string& map_name); 70 | 71 | MapInfo* GetMapInfo(uint64_t pc); 72 | 73 | ErrorCode LastErrorCode() { return last_error_.code; } 74 | uint64_t LastErrorAddress() { return last_error_.address; } 75 | 76 | private: 77 | pthread_rwlock_t maps_rwlock_; 78 | std::unique_ptr maps_ = nullptr; 79 | std::shared_ptr process_memory_; 80 | std::vector skip_libraries_; 81 | ErrorData last_error_; 82 | }; 83 | 84 | } // namespace unwindstack 85 | 86 | #endif // _LIBUNWINDSTACK_LOCAL_UNWINDER_H 87 | -------------------------------------------------------------------------------- /include/unwindstack/Log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_LOG_H 18 | #define _LIBUNWINDSTACK_LOG_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | void log_to_stdout(bool enable); 25 | void log(uint8_t indent, const char* format, ...); 26 | void log_async_safe(const char* format, ...); 27 | 28 | } // namespace unwindstack 29 | 30 | #endif // _LIBUNWINDSTACK_LOG_H 31 | -------------------------------------------------------------------------------- /include/unwindstack/MachineArm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MACHINE_ARM_H 18 | #define _LIBUNWINDSTACK_MACHINE_ARM_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum ArmReg : uint16_t { 25 | ARM_REG_R0 = 0, 26 | ARM_REG_R1, 27 | ARM_REG_R2, 28 | ARM_REG_R3, 29 | ARM_REG_R4, 30 | ARM_REG_R5, 31 | ARM_REG_R6, 32 | ARM_REG_R7, 33 | ARM_REG_R8, 34 | ARM_REG_R9, 35 | ARM_REG_R10, 36 | ARM_REG_R11, 37 | ARM_REG_R12, 38 | ARM_REG_R13, 39 | ARM_REG_R14, 40 | ARM_REG_R15, 41 | ARM_REG_LAST, 42 | 43 | ARM_REG_SP = ARM_REG_R13, 44 | ARM_REG_LR = ARM_REG_R14, 45 | ARM_REG_PC = ARM_REG_R15, 46 | }; 47 | 48 | } // namespace unwindstack 49 | 50 | #endif // _LIBUNWINDSTACK_MACHINE_ARM_H 51 | -------------------------------------------------------------------------------- /include/unwindstack/MachineArm64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MACHINE_ARM64_H 18 | #define _LIBUNWINDSTACK_MACHINE_ARM64_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum Arm64Reg : uint16_t { 25 | ARM64_REG_R0 = 0, 26 | ARM64_REG_R1, 27 | ARM64_REG_R2, 28 | ARM64_REG_R3, 29 | ARM64_REG_R4, 30 | ARM64_REG_R5, 31 | ARM64_REG_R6, 32 | ARM64_REG_R7, 33 | ARM64_REG_R8, 34 | ARM64_REG_R9, 35 | ARM64_REG_R10, 36 | ARM64_REG_R11, 37 | ARM64_REG_R12, 38 | ARM64_REG_R13, 39 | ARM64_REG_R14, 40 | ARM64_REG_R15, 41 | ARM64_REG_R16, 42 | ARM64_REG_R17, 43 | ARM64_REG_R18, 44 | ARM64_REG_R19, 45 | ARM64_REG_R20, 46 | ARM64_REG_R21, 47 | ARM64_REG_R22, 48 | ARM64_REG_R23, 49 | ARM64_REG_R24, 50 | ARM64_REG_R25, 51 | ARM64_REG_R26, 52 | ARM64_REG_R27, 53 | ARM64_REG_R28, 54 | ARM64_REG_R29, 55 | ARM64_REG_R30, 56 | ARM64_REG_R31, 57 | ARM64_REG_PC, 58 | ARM64_REG_PSTATE, 59 | ARM64_REG_LAST, 60 | 61 | ARM64_REG_SP = ARM64_REG_R31, 62 | ARM64_REG_LR = ARM64_REG_R30, 63 | 64 | // Pseudo registers. These are not machine registers. 65 | 66 | // AARCH64 Return address signed state pseudo-register 67 | ARM64_PREG_RA_SIGN_STATE = 34, 68 | ARM64_PREG_FIRST = ARM64_PREG_RA_SIGN_STATE, 69 | ARM64_PREG_LAST, 70 | }; 71 | 72 | } // namespace unwindstack 73 | 74 | #endif // _LIBUNWINDSTACK_MACHINE_ARM64_H 75 | -------------------------------------------------------------------------------- /include/unwindstack/MachineMips.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MACHINE_MIPS_H 18 | #define _LIBUNWINDSTACK_MACHINE_MIPS_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum MipsReg : uint16_t { 25 | MIPS_REG_R0 = 0, 26 | MIPS_REG_R1, 27 | MIPS_REG_R2, 28 | MIPS_REG_R3, 29 | MIPS_REG_R4, 30 | MIPS_REG_R5, 31 | MIPS_REG_R6, 32 | MIPS_REG_R7, 33 | MIPS_REG_R8, 34 | MIPS_REG_R9, 35 | MIPS_REG_R10, 36 | MIPS_REG_R11, 37 | MIPS_REG_R12, 38 | MIPS_REG_R13, 39 | MIPS_REG_R14, 40 | MIPS_REG_R15, 41 | MIPS_REG_R16, 42 | MIPS_REG_R17, 43 | MIPS_REG_R18, 44 | MIPS_REG_R19, 45 | MIPS_REG_R20, 46 | MIPS_REG_R21, 47 | MIPS_REG_R22, 48 | MIPS_REG_R23, 49 | MIPS_REG_R24, 50 | MIPS_REG_R25, 51 | MIPS_REG_R26, 52 | MIPS_REG_R27, 53 | MIPS_REG_R28, 54 | MIPS_REG_R29, 55 | MIPS_REG_R30, 56 | MIPS_REG_R31, 57 | MIPS_REG_PC, 58 | MIPS_REG_LAST, 59 | 60 | MIPS_REG_SP = MIPS_REG_R29, 61 | MIPS_REG_RA = MIPS_REG_R31, 62 | }; 63 | 64 | } // namespace unwindstack 65 | 66 | #endif // _LIBUNWINDSTACK_MACHINE_MIPS_H -------------------------------------------------------------------------------- /include/unwindstack/MachineMips64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MACHINE_MIPS64_H 18 | #define _LIBUNWINDSTACK_MACHINE_MIPS64_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | enum Mips64Reg : uint16_t { 25 | MIPS64_REG_R0 = 0, 26 | MIPS64_REG_R1, 27 | MIPS64_REG_R2, 28 | MIPS64_REG_R3, 29 | MIPS64_REG_R4, 30 | MIPS64_REG_R5, 31 | MIPS64_REG_R6, 32 | MIPS64_REG_R7, 33 | MIPS64_REG_R8, 34 | MIPS64_REG_R9, 35 | MIPS64_REG_R10, 36 | MIPS64_REG_R11, 37 | MIPS64_REG_R12, 38 | MIPS64_REG_R13, 39 | MIPS64_REG_R14, 40 | MIPS64_REG_R15, 41 | MIPS64_REG_R16, 42 | MIPS64_REG_R17, 43 | MIPS64_REG_R18, 44 | MIPS64_REG_R19, 45 | MIPS64_REG_R20, 46 | MIPS64_REG_R21, 47 | MIPS64_REG_R22, 48 | MIPS64_REG_R23, 49 | MIPS64_REG_R24, 50 | MIPS64_REG_R25, 51 | MIPS64_REG_R26, 52 | MIPS64_REG_R27, 53 | MIPS64_REG_R28, 54 | MIPS64_REG_R29, 55 | MIPS64_REG_R30, 56 | MIPS64_REG_R31, 57 | MIPS64_REG_PC, 58 | MIPS64_REG_LAST, 59 | 60 | MIPS64_REG_SP = MIPS64_REG_R29, 61 | MIPS64_REG_RA = MIPS64_REG_R31, 62 | }; 63 | 64 | } // namespace unwindstack 65 | 66 | #endif // _LIBUNWINDSTACK_MACHINE_MIPS64_H -------------------------------------------------------------------------------- /include/unwindstack/MachineX86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MACHINE_X86_H 18 | #define _LIBUNWINDSTACK_MACHINE_X86_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | // Matches the numbers for the registers as generated by compilers. 25 | // If this is changed, then unwinding will fail. 26 | enum X86Reg : uint16_t { 27 | X86_REG_EAX = 0, 28 | X86_REG_ECX = 1, 29 | X86_REG_EDX = 2, 30 | X86_REG_EBX = 3, 31 | X86_REG_ESP = 4, 32 | X86_REG_EBP = 5, 33 | X86_REG_ESI = 6, 34 | X86_REG_EDI = 7, 35 | X86_REG_EIP = 8, 36 | X86_REG_EFL = 9, 37 | X86_REG_CS = 10, 38 | X86_REG_SS = 11, 39 | X86_REG_DS = 12, 40 | X86_REG_ES = 13, 41 | X86_REG_FS = 14, 42 | X86_REG_GS = 15, 43 | X86_REG_LAST, 44 | 45 | X86_REG_SP = X86_REG_ESP, 46 | X86_REG_PC = X86_REG_EIP, 47 | }; 48 | 49 | } // namespace unwindstack 50 | 51 | #endif // _LIBUNWINDSTACK_MACHINE_X86_H 52 | -------------------------------------------------------------------------------- /include/unwindstack/MachineX86_64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MACHINE_X86_64_H 18 | #define _LIBUNWINDSTACK_MACHINE_X86_64_H 19 | 20 | #include 21 | 22 | namespace unwindstack { 23 | 24 | // Matches the numbers for the registers as generated by compilers. 25 | // If this is changed, then unwinding will fail. 26 | enum X86_64Reg : uint16_t { 27 | X86_64_REG_RAX = 0, 28 | X86_64_REG_RDX = 1, 29 | X86_64_REG_RCX = 2, 30 | X86_64_REG_RBX = 3, 31 | X86_64_REG_RSI = 4, 32 | X86_64_REG_RDI = 5, 33 | X86_64_REG_RBP = 6, 34 | X86_64_REG_RSP = 7, 35 | X86_64_REG_R8 = 8, 36 | X86_64_REG_R9 = 9, 37 | X86_64_REG_R10 = 10, 38 | X86_64_REG_R11 = 11, 39 | X86_64_REG_R12 = 12, 40 | X86_64_REG_R13 = 13, 41 | X86_64_REG_R14 = 14, 42 | X86_64_REG_R15 = 15, 43 | X86_64_REG_RIP = 16, 44 | X86_64_REG_LAST, 45 | 46 | X86_64_REG_SP = X86_64_REG_RSP, 47 | X86_64_REG_PC = X86_64_REG_RIP, 48 | }; 49 | 50 | } // namespace unwindstack 51 | 52 | #endif // _LIBUNWINDSTACK_MACHINE_X86_64_H 53 | -------------------------------------------------------------------------------- /include/unwindstack/MapInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MAP_INFO_H 18 | #define _LIBUNWINDSTACK_MAP_INFO_H 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | namespace unwindstack { 31 | 32 | class MemoryFileAtOffset; 33 | 34 | struct MapInfo { 35 | MapInfo(MapInfo* prev_map, MapInfo* prev_real_map, uint64_t start, uint64_t end, uint64_t offset, 36 | uint64_t flags, const char* name) 37 | : start(start), 38 | end(end), 39 | offset(offset), 40 | flags(flags), 41 | name(name), 42 | prev_map(prev_map), 43 | prev_real_map(prev_real_map), 44 | load_bias(INT64_MAX), 45 | build_id(0) { 46 | if (prev_real_map != nullptr) prev_real_map->next_real_map = this; 47 | } 48 | MapInfo(MapInfo* prev_map, MapInfo* prev_real_map, uint64_t start, uint64_t end, uint64_t offset, 49 | uint64_t flags, const std::string& name) 50 | : start(start), 51 | end(end), 52 | offset(offset), 53 | flags(flags), 54 | name(name), 55 | prev_map(prev_map), 56 | prev_real_map(prev_real_map), 57 | load_bias(INT64_MAX), 58 | build_id(0) { 59 | if (prev_real_map != nullptr) prev_real_map->next_real_map = this; 60 | } 61 | ~MapInfo(); 62 | 63 | uint64_t start = 0; 64 | uint64_t end = 0; 65 | uint64_t offset = 0; 66 | uint16_t flags = 0; 67 | SharedString name; 68 | std::shared_ptr elf; 69 | // The offset of the beginning of this mapping to the beginning of the 70 | // ELF file. 71 | // elf_offset == offset - elf_start_offset. 72 | // This value is only non-zero if the offset is non-zero but there is 73 | // no elf signature found at that offset. 74 | uint64_t elf_offset = 0; 75 | // This value is the offset into the file of the map in memory that is the 76 | // start of the elf. This is not equal to offset when the linker splits 77 | // shared libraries into a read-only and read-execute map. 78 | uint64_t elf_start_offset = 0; 79 | 80 | MapInfo* prev_map = nullptr; 81 | // This is the previous map that is not empty with a 0 offset. For 82 | // example, this set of maps: 83 | // 1000-2000 r--p 000000 00:00 0 libc.so 84 | // 2000-3000 ---p 000000 00:00 0 libc.so 85 | // 3000-4000 r-xp 003000 00:00 0 libc.so 86 | // The last map's prev_map would point to the 2000-3000 map, while the 87 | // prev_real_map would point to the 1000-2000 map. 88 | MapInfo* prev_real_map = nullptr; 89 | 90 | // Same as above but set to point to the next map. 91 | MapInfo* next_real_map = nullptr; 92 | 93 | std::atomic_int64_t load_bias; 94 | 95 | // This is a pointer to a new'd std::string. 96 | // Using an atomic value means that we don't need to lock and will 97 | // make it easier to move to a fine grained lock in the future. 98 | std::atomic build_id; 99 | 100 | // Set to true if the elf file data is coming from memory. 101 | bool memory_backed_elf = false; 102 | 103 | // This function guarantees it will never return nullptr. 104 | Elf* GetElf(const std::shared_ptr& process_memory, ArchEnum expected_arch); 105 | 106 | uint64_t GetLoadBias(const std::shared_ptr& process_memory); 107 | 108 | Memory* CreateMemory(const std::shared_ptr& process_memory); 109 | 110 | bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* func_offset); 111 | 112 | // Returns the raw build id read from the elf data. 113 | SharedString GetBuildID(); 114 | 115 | // Used internally, and by tests. It sets the value only if it was not already set. 116 | SharedString SetBuildID(std::string&& new_build_id); 117 | 118 | // Returns the printable version of the build id (hex dump of raw data). 119 | std::string GetPrintableBuildID(); 120 | 121 | inline bool IsBlank() { return offset == 0 && flags == 0 && name.empty(); } 122 | 123 | private: 124 | MapInfo(const MapInfo&) = delete; 125 | void operator=(const MapInfo&) = delete; 126 | 127 | Memory* GetFileMemory(); 128 | bool InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory); 129 | 130 | // Protect the creation of the elf object. 131 | std::mutex mutex_; 132 | }; 133 | 134 | } // namespace unwindstack 135 | 136 | #endif // _LIBUNWINDSTACK_MAP_INFO_H 137 | -------------------------------------------------------------------------------- /include/unwindstack/Maps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MAPS_H 18 | #define _LIBUNWINDSTACK_MAPS_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | namespace unwindstack { 31 | 32 | // Special flag to indicate a map is in /dev/. However, a map in 33 | // /dev/ashmem/... does not set this flag. 34 | static constexpr int MAPS_FLAGS_DEVICE_MAP = 0x8000; 35 | // Special flag to indicate that this map represents an elf file 36 | // created by ART for use with the gdb jit debug interface. 37 | // This should only ever appear in offline maps data. 38 | static constexpr int MAPS_FLAGS_JIT_SYMFILE_MAP = 0x4000; 39 | 40 | class Maps { 41 | public: 42 | virtual ~Maps() = default; 43 | 44 | Maps() = default; 45 | 46 | // Maps are not copyable but movable, because they own pointers to MapInfo 47 | // objects. 48 | Maps(const Maps&) = delete; 49 | Maps& operator=(const Maps&) = delete; 50 | Maps(Maps&&) = default; 51 | Maps& operator=(Maps&&) = default; 52 | 53 | virtual MapInfo* Find(uint64_t pc); 54 | 55 | virtual bool Parse(); 56 | 57 | virtual const std::string GetMapsFile() const { return ""; } 58 | 59 | void Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name, 60 | uint64_t load_bias); 61 | 62 | void Sort(); 63 | 64 | typedef std::vector>::iterator iterator; 65 | iterator begin() { return maps_.begin(); } 66 | iterator end() { return maps_.end(); } 67 | 68 | typedef std::vector>::const_iterator const_iterator; 69 | const_iterator begin() const { return maps_.begin(); } 70 | const_iterator end() const { return maps_.end(); } 71 | 72 | size_t Total() { return maps_.size(); } 73 | 74 | MapInfo* Get(size_t index) { 75 | if (index >= maps_.size()) return nullptr; 76 | return maps_[index].get(); 77 | } 78 | 79 | protected: 80 | std::vector> maps_; 81 | }; 82 | 83 | class RemoteMaps : public Maps { 84 | public: 85 | RemoteMaps(pid_t pid) : pid_(pid) {} 86 | virtual ~RemoteMaps() = default; 87 | 88 | virtual const std::string GetMapsFile() const override; 89 | 90 | private: 91 | pid_t pid_; 92 | }; 93 | 94 | class LocalMaps : public RemoteMaps { 95 | public: 96 | LocalMaps() : RemoteMaps(getpid()) {} 97 | virtual ~LocalMaps() = default; 98 | }; 99 | 100 | class LocalUpdatableMaps : public Maps { 101 | public: 102 | LocalUpdatableMaps(); 103 | virtual ~LocalUpdatableMaps() = default; 104 | 105 | MapInfo* Find(uint64_t pc) override; 106 | 107 | bool Parse() override; 108 | 109 | const std::string GetMapsFile() const override; 110 | 111 | bool Reparse(); 112 | 113 | protected: 114 | std::vector> saved_maps_; 115 | 116 | pthread_rwlock_t maps_rwlock_; 117 | }; 118 | 119 | class BufferMaps : public Maps { 120 | public: 121 | BufferMaps(const char* buffer) : buffer_(buffer) {} 122 | virtual ~BufferMaps() = default; 123 | 124 | bool Parse() override; 125 | 126 | private: 127 | const char* buffer_; 128 | }; 129 | 130 | class FileMaps : public Maps { 131 | public: 132 | FileMaps(const std::string& file) : file_(file) {} 133 | virtual ~FileMaps() = default; 134 | 135 | const std::string GetMapsFile() const override { return file_; } 136 | 137 | protected: 138 | const std::string file_; 139 | }; 140 | 141 | } // namespace unwindstack 142 | 143 | #endif // _LIBUNWINDSTACK_MAPS_H 144 | -------------------------------------------------------------------------------- /include/unwindstack/Memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_MEMORY_H 18 | #define _LIBUNWINDSTACK_MEMORY_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | class Memory { 30 | public: 31 | Memory() = default; 32 | virtual ~Memory() = default; 33 | 34 | static std::shared_ptr CreateProcessMemory(pid_t pid); 35 | static std::shared_ptr CreateProcessMemoryCached(pid_t pid); 36 | static std::shared_ptr CreateProcessMemoryThreadCached(pid_t pid); 37 | static std::shared_ptr CreateOfflineMemory(const uint8_t* data, uint64_t start, 38 | uint64_t end); 39 | static std::unique_ptr CreateFileMemory(const std::string& path, uint64_t offset, 40 | uint64_t size = UINT64_MAX); 41 | 42 | virtual bool ReadString(uint64_t addr, std::string* dst, size_t max_read); 43 | 44 | virtual void Clear() {} 45 | 46 | // Get pointer to directly access the data for buffers that support it. 47 | virtual uint8_t* GetPtr(size_t /*addr*/ = 0) { return nullptr; } 48 | 49 | virtual size_t Read(uint64_t addr, void* dst, size_t size) = 0; 50 | virtual long ReadTag(uint64_t) { return -1; } 51 | 52 | bool ReadFully(uint64_t addr, void* dst, size_t size); 53 | 54 | inline bool Read32(uint64_t addr, uint32_t* dst) { 55 | return ReadFully(addr, dst, sizeof(uint32_t)); 56 | } 57 | 58 | inline bool Read64(uint64_t addr, uint64_t* dst) { 59 | return ReadFully(addr, dst, sizeof(uint64_t)); 60 | } 61 | }; 62 | 63 | } // namespace unwindstack 64 | 65 | #endif // _LIBUNWINDSTACK_MEMORY_H 66 | -------------------------------------------------------------------------------- /include/unwindstack/Regs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_H 18 | #define _LIBUNWINDSTACK_REGS_H 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | namespace unwindstack { 30 | 31 | // Forward declarations. 32 | class Elf; 33 | class Memory; 34 | 35 | class Regs { 36 | public: 37 | enum LocationEnum : uint8_t { 38 | LOCATION_UNKNOWN = 0, 39 | LOCATION_REGISTER, 40 | LOCATION_SP_OFFSET, 41 | }; 42 | 43 | struct Location { 44 | Location(LocationEnum type, int16_t value) : type(type), value(value) {} 45 | 46 | LocationEnum type; 47 | int16_t value; 48 | }; 49 | 50 | Regs(uint16_t total_regs, const Location& return_loc) 51 | : total_regs_(total_regs), return_loc_(return_loc) {} 52 | virtual ~Regs() = default; 53 | 54 | virtual ArchEnum Arch() = 0; 55 | 56 | bool Is32Bit() { return ArchIs32Bit(Arch()); } 57 | 58 | virtual void* RawData() = 0; 59 | virtual uint64_t pc() = 0; 60 | virtual uint64_t sp() = 0; 61 | 62 | virtual void set_pc(uint64_t pc) = 0; 63 | virtual void set_sp(uint64_t sp) = 0; 64 | 65 | uint64_t dex_pc() { return dex_pc_; } 66 | void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; } 67 | 68 | virtual void ResetPseudoRegisters() {} 69 | virtual bool SetPseudoRegister(uint16_t, uint64_t) { return false; } 70 | virtual bool GetPseudoRegister(uint16_t, uint64_t*) { return false; } 71 | 72 | virtual bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) = 0; 73 | 74 | virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0; 75 | 76 | virtual void IterateRegisters(std::function) = 0; 77 | 78 | uint16_t total_regs() { return total_regs_; } 79 | 80 | virtual Regs* Clone() = 0; 81 | 82 | static ArchEnum CurrentArch(); 83 | static Regs* RemoteGet(pid_t pid); 84 | static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext); 85 | static Regs* CreateFromLocal(); 86 | 87 | protected: 88 | uint16_t total_regs_; 89 | Location return_loc_; 90 | uint64_t dex_pc_ = 0; 91 | }; 92 | 93 | template 94 | class RegsImpl : public Regs { 95 | public: 96 | RegsImpl(uint16_t total_regs, Location return_loc) 97 | : Regs(total_regs, return_loc), regs_(total_regs) {} 98 | virtual ~RegsImpl() = default; 99 | 100 | inline AddressType& operator[](size_t reg) { return regs_[reg]; } 101 | 102 | void* RawData() override { return regs_.data(); } 103 | 104 | virtual void IterateRegisters(std::function fn) override { 105 | for (size_t i = 0; i < regs_.size(); ++i) { 106 | fn(std::to_string(i).c_str(), regs_[i]); 107 | } 108 | } 109 | 110 | protected: 111 | std::vector regs_; 112 | }; 113 | 114 | uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch); 115 | 116 | } // namespace unwindstack 117 | 118 | #endif // _LIBUNWINDSTACK_REGS_H 119 | -------------------------------------------------------------------------------- /include/unwindstack/RegsArm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_ARM_H 18 | #define _LIBUNWINDSTACK_REGS_ARM_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | // Forward declarations. 30 | class Memory; 31 | 32 | class RegsArm : public RegsImpl { 33 | public: 34 | RegsArm(); 35 | virtual ~RegsArm() = default; 36 | 37 | ArchEnum Arch() override final; 38 | 39 | bool SetPcFromReturnAddress(Memory* process_memory) override; 40 | 41 | bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override; 42 | 43 | void IterateRegisters(std::function) override final; 44 | 45 | uint64_t pc() override; 46 | uint64_t sp() override; 47 | 48 | void set_pc(uint64_t pc) override; 49 | void set_sp(uint64_t sp) override; 50 | 51 | Regs* Clone() override final; 52 | 53 | static Regs* Read(void* data); 54 | 55 | static Regs* CreateFromUcontext(void* ucontext); 56 | }; 57 | 58 | } // namespace unwindstack 59 | 60 | #endif // _LIBUNWINDSTACK_REGS_ARM_H 61 | -------------------------------------------------------------------------------- /include/unwindstack/RegsArm64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_ARM64_H 18 | #define _LIBUNWINDSTACK_REGS_ARM64_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | namespace unwindstack { 29 | 30 | // Forward declarations. 31 | class Memory; 32 | 33 | class RegsArm64 : public RegsImpl { 34 | public: 35 | RegsArm64(); 36 | virtual ~RegsArm64() = default; 37 | 38 | ArchEnum Arch() override final; 39 | 40 | bool SetPcFromReturnAddress(Memory* process_memory) override; 41 | 42 | bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override; 43 | 44 | void IterateRegisters(std::function) override final; 45 | 46 | uint64_t pc() override; 47 | uint64_t sp() override; 48 | 49 | void set_pc(uint64_t pc) override; 50 | void set_sp(uint64_t sp) override; 51 | 52 | void ResetPseudoRegisters() override; 53 | 54 | bool SetPseudoRegister(uint16_t id, uint64_t value) override; 55 | 56 | bool GetPseudoRegister(uint16_t id, uint64_t* value) override; 57 | 58 | bool IsRASigned(); 59 | 60 | void SetPACMask(uint64_t mask); 61 | 62 | Regs* Clone() override final; 63 | 64 | static Regs* Read(void* data); 65 | 66 | static Regs* CreateFromUcontext(void* ucontext); 67 | 68 | protected: 69 | uint64_t pseudo_regs_[Arm64Reg::ARM64_PREG_LAST - Arm64Reg::ARM64_PREG_FIRST]; 70 | uint64_t pac_mask_; 71 | }; 72 | 73 | } // namespace unwindstack 74 | 75 | #endif // _LIBUNWINDSTACK_REGS_ARM64_H 76 | -------------------------------------------------------------------------------- /include/unwindstack/RegsGetLocal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_REGS_GET_LOCAL_H 30 | #define _LIBUNWINDSTACK_REGS_GET_LOCAL_H 31 | 32 | namespace unwindstack { 33 | 34 | #if defined(__arm__) 35 | 36 | inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) { 37 | asm volatile( 38 | ".align 2\n" 39 | "bx pc\n" 40 | "nop\n" 41 | ".code 32\n" 42 | "stmia %[base], {r0-r12}\n" 43 | "add r2, %[base], #52\n" 44 | "mov r3, r13\n" 45 | "mov r4, r14\n" 46 | "mov r5, r15\n" 47 | "stmia r2, {r3-r5}\n" 48 | "orr %[base], pc, #1\n" 49 | "bx %[base]\n" 50 | : [ base ] "+r"(reg_data) 51 | : 52 | : "r2", "r3", "r4", "r5", "memory"); 53 | } 54 | 55 | #elif defined(__aarch64__) 56 | 57 | inline __attribute__((__always_inline__)) void AsmGetRegs(void* reg_data) { 58 | asm volatile( 59 | "1:\n" 60 | "stp x0, x1, [%[base], #0]\n" 61 | "stp x2, x3, [%[base], #16]\n" 62 | "stp x4, x5, [%[base], #32]\n" 63 | "stp x6, x7, [%[base], #48]\n" 64 | "stp x8, x9, [%[base], #64]\n" 65 | "stp x10, x11, [%[base], #80]\n" 66 | "stp x12, x13, [%[base], #96]\n" 67 | "stp x14, x15, [%[base], #112]\n" 68 | "stp x16, x17, [%[base], #128]\n" 69 | "stp x18, x19, [%[base], #144]\n" 70 | "stp x20, x21, [%[base], #160]\n" 71 | "stp x22, x23, [%[base], #176]\n" 72 | "stp x24, x25, [%[base], #192]\n" 73 | "stp x26, x27, [%[base], #208]\n" 74 | "stp x28, x29, [%[base], #224]\n" 75 | "str x30, [%[base], #240]\n" 76 | "mov x12, sp\n" 77 | "adr x13, 1b\n" 78 | "stp x12, x13, [%[base], #248]\n" 79 | : [base] "+r"(reg_data) 80 | : 81 | : "x12", "x13", "memory"); 82 | } 83 | 84 | #elif defined(__i386__) || defined(__x86_64__) 85 | 86 | extern "C" void AsmGetRegs(void* regs); 87 | 88 | #endif 89 | 90 | inline __attribute__((__always_inline__)) void RegsGetLocal(Regs* regs) { 91 | AsmGetRegs(regs->RawData()); 92 | } 93 | 94 | 95 | } // namespace unwindstack 96 | 97 | #endif // _LIBUNWINDSTACK_REGS_GET_LOCAL_H 98 | -------------------------------------------------------------------------------- /include/unwindstack/RegsMips.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_MIPS_H 18 | #define _LIBUNWINDSTACK_REGS_MIPS_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | // Forward declarations. 30 | class Memory; 31 | 32 | class RegsMips : public RegsImpl { 33 | public: 34 | RegsMips(); 35 | virtual ~RegsMips() = default; 36 | 37 | ArchEnum Arch() override final; 38 | 39 | bool SetPcFromReturnAddress(Memory* process_memory) override; 40 | 41 | bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override; 42 | 43 | void IterateRegisters(std::function) override final; 44 | 45 | uint64_t pc() override; 46 | uint64_t sp() override; 47 | 48 | void set_pc(uint64_t pc) override; 49 | void set_sp(uint64_t sp) override; 50 | 51 | Regs* Clone() override final; 52 | 53 | static Regs* Read(void* data); 54 | 55 | static Regs* CreateFromUcontext(void* ucontext); 56 | }; 57 | 58 | } // namespace unwindstack 59 | 60 | #endif // _LIBUNWINDSTACK_REGS_MIPS_H 61 | -------------------------------------------------------------------------------- /include/unwindstack/RegsMips64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_MIPS64_H 18 | #define _LIBUNWINDSTACK_REGS_MIPS64_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | // Forward declarations. 30 | class Memory; 31 | 32 | class RegsMips64 : public RegsImpl { 33 | public: 34 | RegsMips64(); 35 | virtual ~RegsMips64() = default; 36 | 37 | ArchEnum Arch() override final; 38 | 39 | bool SetPcFromReturnAddress(Memory* process_memory) override; 40 | 41 | bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override; 42 | 43 | void IterateRegisters(std::function) override final; 44 | 45 | uint64_t pc() override; 46 | uint64_t sp() override; 47 | 48 | void set_pc(uint64_t pc) override; 49 | void set_sp(uint64_t sp) override; 50 | 51 | Regs* Clone() override final; 52 | 53 | static Regs* Read(void* data); 54 | 55 | static Regs* CreateFromUcontext(void* ucontext); 56 | }; 57 | 58 | } // namespace unwindstack 59 | 60 | #endif // _LIBUNWINDSTACK_REGS_MIPS64_H 61 | -------------------------------------------------------------------------------- /include/unwindstack/RegsX86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_X86_H 18 | #define _LIBUNWINDSTACK_REGS_X86_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | // Forward declarations. 30 | class Memory; 31 | struct x86_ucontext_t; 32 | 33 | class RegsX86 : public RegsImpl { 34 | public: 35 | RegsX86(); 36 | virtual ~RegsX86() = default; 37 | 38 | ArchEnum Arch() override final; 39 | 40 | bool SetPcFromReturnAddress(Memory* process_memory) override; 41 | 42 | bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override; 43 | 44 | void SetFromUcontext(x86_ucontext_t* ucontext); 45 | 46 | void IterateRegisters(std::function) override final; 47 | 48 | uint64_t pc() override; 49 | uint64_t sp() override; 50 | 51 | void set_pc(uint64_t pc) override; 52 | void set_sp(uint64_t sp) override; 53 | 54 | Regs* Clone() override final; 55 | 56 | static Regs* Read(void* data); 57 | 58 | static Regs* CreateFromUcontext(void* ucontext); 59 | }; 60 | 61 | } // namespace unwindstack 62 | 63 | #endif // _LIBUNWINDSTACK_REGS_X86_H 64 | -------------------------------------------------------------------------------- /include/unwindstack/RegsX86_64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_REGS_X86_64_H 18 | #define _LIBUNWINDSTACK_REGS_X86_64_H 19 | 20 | #include 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace unwindstack { 28 | 29 | // Forward declarations. 30 | class Memory; 31 | struct x86_64_ucontext_t; 32 | 33 | class RegsX86_64 : public RegsImpl { 34 | public: 35 | RegsX86_64(); 36 | virtual ~RegsX86_64() = default; 37 | 38 | ArchEnum Arch() override final; 39 | 40 | bool SetPcFromReturnAddress(Memory* process_memory) override; 41 | 42 | bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override; 43 | 44 | void SetFromUcontext(x86_64_ucontext_t* ucontext); 45 | 46 | void IterateRegisters(std::function) override final; 47 | 48 | uint64_t pc() override; 49 | uint64_t sp() override; 50 | 51 | void set_pc(uint64_t pc) override; 52 | void set_sp(uint64_t sp) override; 53 | 54 | Regs* Clone() override final; 55 | 56 | static Regs* Read(void* data); 57 | 58 | static Regs* CreateFromUcontext(void* ucontext); 59 | }; 60 | 61 | } // namespace unwindstack 62 | 63 | #endif // _LIBUNWINDSTACK_REGS_X86_64_H 64 | -------------------------------------------------------------------------------- /include/unwindstack/SharedString.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBUNWINDSTACK_SHAREDSTRING_H 18 | #define _LIBUNWINDSTACK_SHAREDSTRING_H 19 | 20 | #include 21 | #include 22 | 23 | namespace unwindstack { 24 | 25 | // Ref-counted read-only string. Used to avoid string allocations/copies. 26 | // It is intended to be transparent std::string replacement in most cases. 27 | class SharedString { 28 | public: 29 | SharedString() : data_() {} 30 | SharedString(std::string&& s) : data_(std::make_shared(std::move(s))) {} 31 | SharedString(const std::string& s) : SharedString(std::string(s)) {} 32 | SharedString(const char* s) : SharedString(std::string(s)) {} 33 | 34 | void clear() { data_.reset(); } 35 | bool is_null() const { return data_.get() == nullptr; } 36 | bool empty() const { return is_null() ? true : data_->empty(); } 37 | const char* c_str() const { return is_null() ? "" : data_->c_str(); } 38 | const size_t size() const { return is_null() ? 0 : data_->size(); } 39 | 40 | operator const std::string&() const { 41 | [[clang::no_destroy]] static const std::string empty; 42 | return data_ ? *data_.get() : empty; 43 | } 44 | 45 | operator std::string_view() const { return static_cast(*this); } 46 | 47 | private: 48 | std::shared_ptr data_; 49 | }; 50 | 51 | static inline bool operator==(const SharedString& a, SharedString& b) { 52 | return static_cast(a) == static_cast(b); 53 | } 54 | static inline bool operator==(const SharedString& a, std::string_view b) { 55 | return static_cast(a) == b; 56 | } 57 | static inline bool operator==(std::string_view a, const SharedString& b) { 58 | return a == static_cast(b); 59 | } 60 | static inline bool operator!=(const SharedString& a, SharedString& b) { 61 | return !(a == b); 62 | } 63 | static inline bool operator!=(const SharedString& a, std::string_view b) { 64 | return !(a == b); 65 | } 66 | static inline bool operator!=(std::string_view a, const SharedString& b) { 67 | return !(a == b); 68 | } 69 | static inline std::string operator+(const SharedString& a, const char* b) { 70 | return static_cast(a) + b; 71 | } 72 | static inline std::string operator+(const char* a, const SharedString& b) { 73 | return a + static_cast(b); 74 | } 75 | 76 | } // namespace unwindstack 77 | #endif // _LIBUNWINDSTACK_SHAREDSTRING_H 78 | -------------------------------------------------------------------------------- /include/unwindstack/UcontextArm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_UCONTEXT_ARM_H 30 | #define _LIBUNWINDSTACK_UCONTEXT_ARM_H 31 | 32 | #include 33 | 34 | #include 35 | 36 | namespace unwindstack { 37 | 38 | struct arm_stack_t { 39 | uint32_t ss_sp; // void __user* 40 | int32_t ss_flags; // int 41 | uint32_t ss_size; // size_t 42 | }; 43 | 44 | struct arm_mcontext_t { 45 | uint32_t trap_no; // unsigned long 46 | uint32_t error_code; // unsigned long 47 | uint32_t oldmask; // unsigned long 48 | uint32_t regs[ARM_REG_LAST]; // unsigned long 49 | uint32_t cpsr; // unsigned long 50 | uint32_t fault_address; // unsigned long 51 | }; 52 | 53 | struct arm_ucontext_t { 54 | uint32_t uc_flags; // unsigned long 55 | uint32_t uc_link; // struct ucontext* 56 | arm_stack_t uc_stack; 57 | arm_mcontext_t uc_mcontext; 58 | // Nothing else is used, so don't define it. 59 | }; 60 | 61 | } // namespace unwindstack 62 | 63 | #endif // _LIBUNWINDSTACK_UCONTEXT_ARM_H 64 | -------------------------------------------------------------------------------- /include/unwindstack/UcontextArm64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_UCONTEXT_ARM64_H 30 | #define _LIBUNWINDSTACK_UCONTEXT_ARM64_H 31 | 32 | #include 33 | 34 | #include 35 | 36 | namespace unwindstack { 37 | 38 | struct arm64_stack_t { 39 | uint64_t ss_sp; // void __user* 40 | int32_t ss_flags; // int 41 | uint64_t ss_size; // size_t 42 | }; 43 | 44 | struct arm64_sigset_t { 45 | uint64_t sig; // unsigned long 46 | }; 47 | 48 | struct arm64_mcontext_t { 49 | uint64_t fault_address; // __u64 50 | uint64_t regs[ARM64_REG_LAST]; // __u64 51 | uint64_t pstate; // __u64 52 | // Nothing else is used, so don't define it. 53 | }; 54 | 55 | struct arm64_ucontext_t { 56 | uint64_t uc_flags; // unsigned long 57 | uint64_t uc_link; // struct ucontext* 58 | arm64_stack_t uc_stack; 59 | arm64_sigset_t uc_sigmask; 60 | // The kernel adds extra padding after uc_sigmask to match glibc sigset_t on ARM64. 61 | char __padding[128 - sizeof(arm64_sigset_t)]; 62 | // The full structure requires 16 byte alignment, but our partial structure 63 | // doesn't, so force the alignment. 64 | arm64_mcontext_t uc_mcontext __attribute__((aligned(16))); 65 | }; 66 | 67 | } // namespace unwindstack 68 | 69 | #endif // _LIBUNWINDSTACK_UCONTEXT_ARM64_H 70 | -------------------------------------------------------------------------------- /include/unwindstack/UcontextMips.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_UCONTEXT_MIPS_H 30 | #define _LIBUNWINDSTACK_UCONTEXT_MIPS_H 31 | 32 | #include 33 | 34 | #include 35 | 36 | namespace unwindstack { 37 | 38 | struct mips_stack_t { 39 | uint32_t ss_sp; // void __user* 40 | uint32_t ss_size; // size_t 41 | int32_t ss_flags; // int 42 | }; 43 | 44 | struct mips_mcontext_t { 45 | uint32_t sc_regmask; 46 | uint32_t sc_status; 47 | uint64_t sc_pc; 48 | uint64_t sc_regs[32]; 49 | // Nothing else is used, so don't define it. 50 | }; 51 | 52 | struct mips_ucontext_t { 53 | uint32_t uc_flags; // unsigned long 54 | uint32_t uc_link; // struct ucontext* 55 | mips_stack_t uc_stack; 56 | mips_mcontext_t uc_mcontext; 57 | // Nothing else is used, so don't define it. 58 | }; 59 | 60 | } // namespace unwindstack 61 | 62 | #endif // _LIBUNWINDSTACK_UCONTEXT_MIPS_H 63 | -------------------------------------------------------------------------------- /include/unwindstack/UcontextMips64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_UCONTEXT_MIPS64_H 30 | #define _LIBUNWINDSTACK_UCONTEXT_MIPS64_H 31 | 32 | #include 33 | 34 | #include 35 | 36 | namespace unwindstack { 37 | 38 | struct mips64_stack_t { 39 | uint64_t ss_sp; // void __user* 40 | uint64_t ss_size; // size_t 41 | int32_t ss_flags; // int 42 | }; 43 | 44 | struct mips64_mcontext_t { 45 | uint64_t sc_regs[32]; 46 | uint64_t sc_fpregs[32]; 47 | uint64_t sc_mdhi; 48 | uint64_t sc_hi1; 49 | uint64_t sc_hi2; 50 | uint64_t sc_hi3; 51 | uint64_t sc_mdlo; 52 | uint64_t sc_lo1; 53 | uint64_t sc_lo2; 54 | uint64_t sc_lo3; 55 | uint64_t sc_pc; 56 | // Nothing else is used, so don't define it. 57 | }; 58 | 59 | struct mips64_ucontext_t { 60 | uint64_t uc_flags; // unsigned long 61 | uint64_t uc_link; // struct ucontext* 62 | mips64_stack_t uc_stack; 63 | mips64_mcontext_t uc_mcontext; 64 | // Nothing else is used, so don't define it. 65 | }; 66 | 67 | } // namespace unwindstack 68 | 69 | #endif // _LIBUNWINDSTACK_UCONTEXT_MIPS64_H 70 | -------------------------------------------------------------------------------- /include/unwindstack/UcontextX86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_UCONTEXT_X86_H 30 | #define _LIBUNWINDSTACK_UCONTEXT_X86_H 31 | 32 | #include 33 | 34 | #include 35 | 36 | namespace unwindstack { 37 | 38 | struct x86_stack_t { 39 | uint32_t ss_sp; // void __user* 40 | int32_t ss_flags; // int 41 | uint32_t ss_size; // size_t 42 | }; 43 | 44 | struct x86_mcontext_t { 45 | uint32_t gs; 46 | uint32_t fs; 47 | uint32_t es; 48 | uint32_t ds; 49 | uint32_t edi; 50 | uint32_t esi; 51 | uint32_t ebp; 52 | uint32_t esp; 53 | uint32_t ebx; 54 | uint32_t edx; 55 | uint32_t ecx; 56 | uint32_t eax; 57 | uint32_t trapno; 58 | uint32_t err; 59 | uint32_t eip; 60 | uint32_t cs; 61 | uint32_t efl; 62 | uint32_t uesp; 63 | uint32_t ss; 64 | // Only care about the registers, skip everything else. 65 | }; 66 | 67 | struct x86_ucontext_t { 68 | uint32_t uc_flags; // unsigned long 69 | uint32_t uc_link; // struct ucontext* 70 | x86_stack_t uc_stack; 71 | x86_mcontext_t uc_mcontext; 72 | // Nothing else is used, so don't define it. 73 | }; 74 | 75 | } // namespace unwindstack 76 | 77 | #endif // _LIBUNWINDSTACK_UCONTEXT_X86_H 78 | -------------------------------------------------------------------------------- /include/unwindstack/UcontextX86_64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_UCONTEXT_X86_64_H 30 | #define _LIBUNWINDSTACK_UCONTEXT_X86_64_H 31 | 32 | #include 33 | 34 | #include 35 | 36 | namespace unwindstack { 37 | 38 | struct x86_64_stack_t { 39 | uint64_t ss_sp; // void __user* 40 | int32_t ss_flags; // int 41 | int32_t pad; 42 | uint64_t ss_size; // size_t 43 | }; 44 | 45 | struct x86_64_mcontext_t { 46 | uint64_t r8; 47 | uint64_t r9; 48 | uint64_t r10; 49 | uint64_t r11; 50 | uint64_t r12; 51 | uint64_t r13; 52 | uint64_t r14; 53 | uint64_t r15; 54 | uint64_t rdi; 55 | uint64_t rsi; 56 | uint64_t rbp; 57 | uint64_t rbx; 58 | uint64_t rdx; 59 | uint64_t rax; 60 | uint64_t rcx; 61 | uint64_t rsp; 62 | uint64_t rip; 63 | uint64_t efl; 64 | uint64_t csgsfs; 65 | uint64_t err; 66 | uint64_t trapno; 67 | uint64_t oldmask; 68 | uint64_t cr2; 69 | // Only care about the registers, skip everything else. 70 | }; 71 | 72 | struct x86_64_ucontext_t { 73 | uint64_t uc_flags; // unsigned long 74 | uint64_t uc_link; // struct ucontext* 75 | x86_64_stack_t uc_stack; 76 | x86_64_mcontext_t uc_mcontext; 77 | // Nothing else is used, so don't define it. 78 | }; 79 | 80 | } // namespace unwindstack 81 | 82 | #endif // _LIBUNWINDSTACK_UCONTEXT_X86_64_H 83 | -------------------------------------------------------------------------------- /include/unwindstack/UserArm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_USER_ARM_H 30 | #define _LIBUNWINDSTACK_USER_ARM_H 31 | 32 | namespace unwindstack { 33 | 34 | struct arm_user_regs { 35 | uint32_t regs[18]; 36 | }; 37 | 38 | } // namespace unwindstack 39 | 40 | #endif // _LIBUNWINDSTACK_USER_ARM_H 41 | -------------------------------------------------------------------------------- /include/unwindstack/UserArm64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_USER_ARM64_H 30 | #define _LIBUNWINDSTACK_USER_ARM64_H 31 | 32 | namespace unwindstack { 33 | 34 | struct arm64_user_regs { 35 | uint64_t regs[31]; 36 | uint64_t sp; 37 | uint64_t pc; 38 | uint64_t pstate; 39 | }; 40 | 41 | } // namespace unwindstack 42 | 43 | #endif // _LIBUNWINDSTACK_USER_ARM64_H 44 | -------------------------------------------------------------------------------- /include/unwindstack/UserMips.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_USER_MIPS_H 30 | #define _LIBUNWINDSTACK_USER_MIPS_H 31 | 32 | namespace unwindstack { 33 | 34 | enum Mips32UserReg : uint16_t { 35 | MIPS32_EF_R0 = 6, 36 | MIPS32_EF_CP0_EPC = 40, 37 | }; 38 | 39 | struct mips_user_regs { 40 | uint32_t regs[45]; 41 | }; 42 | 43 | } // namespace unwindstack 44 | 45 | #endif // _LIBUNWINDSTACK_USER_MIPS_H 46 | -------------------------------------------------------------------------------- /include/unwindstack/UserMips64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_USER_MIPS64_H 30 | #define _LIBUNWINDSTACK_USER_MIPS64_H 31 | 32 | namespace unwindstack { 33 | 34 | enum Mips64UserReg : uint16_t { 35 | MIPS64_EF_R0 = 0, 36 | MIPS64_EF_CP0_EPC = 34, 37 | }; 38 | 39 | struct mips64_user_regs { 40 | uint64_t regs[45]; 41 | }; 42 | 43 | } // namespace unwindstack 44 | 45 | #endif // _LIBUNWINDSTACK_USER_MIPS64_H 46 | -------------------------------------------------------------------------------- /include/unwindstack/UserX86.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_USER_X86_H 30 | #define _LIBUNWINDSTACK_USER_X86_H 31 | 32 | namespace unwindstack { 33 | 34 | struct x86_user_regs { 35 | uint32_t ebx; 36 | uint32_t ecx; 37 | uint32_t edx; 38 | uint32_t esi; 39 | uint32_t edi; 40 | uint32_t ebp; 41 | uint32_t eax; 42 | uint32_t xds; 43 | uint32_t xes; 44 | uint32_t xfs; 45 | uint32_t xgs; 46 | uint32_t orig_eax; 47 | uint32_t eip; 48 | uint32_t xcs; 49 | uint32_t eflags; 50 | uint32_t esp; 51 | uint32_t xss; 52 | }; 53 | 54 | } // namespace unwindstack 55 | 56 | #endif // _LIBUNWINDSTACK_USER_X86_H 57 | -------------------------------------------------------------------------------- /include/unwindstack/UserX86_64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in 12 | * the documentation and/or other materials provided with the 13 | * distribution. 14 | * 15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef _LIBUNWINDSTACK_USER_X86_64_H 30 | #define _LIBUNWINDSTACK_USER_X86_64_H 31 | 32 | namespace unwindstack { 33 | 34 | struct x86_64_user_regs { 35 | uint64_t r15; 36 | uint64_t r14; 37 | uint64_t r13; 38 | uint64_t r12; 39 | uint64_t rbp; 40 | uint64_t rbx; 41 | uint64_t r11; 42 | uint64_t r10; 43 | uint64_t r9; 44 | uint64_t r8; 45 | uint64_t rax; 46 | uint64_t rcx; 47 | uint64_t rdx; 48 | uint64_t rsi; 49 | uint64_t rdi; 50 | uint64_t orig_rax; 51 | uint64_t rip; 52 | uint64_t cs; 53 | uint64_t eflags; 54 | uint64_t rsp; 55 | uint64_t ss; 56 | uint64_t fs_base; 57 | uint64_t gs_base; 58 | uint64_t ds; 59 | uint64_t es; 60 | uint64_t fs; 61 | uint64_t gs; 62 | }; 63 | 64 | } // namespace unwindstack 65 | 66 | #endif // _LIBUNWINDSTACK_USER_X86_64_H 67 | -------------------------------------------------------------------------------- /tools/unwind.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | static bool Attach(pid_t pid) { 38 | if (ptrace(PTRACE_SEIZE, pid, 0, 0) == -1) { 39 | return false; 40 | } 41 | 42 | if (ptrace(PTRACE_INTERRUPT, pid, 0, 0) == -1) { 43 | ptrace(PTRACE_DETACH, pid, 0, 0); 44 | return false; 45 | } 46 | 47 | // Allow at least 1 second to attach properly. 48 | for (size_t i = 0; i < 1000; i++) { 49 | siginfo_t si; 50 | if (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) == 0) { 51 | return true; 52 | } 53 | usleep(1000); 54 | } 55 | printf("%d: Failed to stop.\n", pid); 56 | return false; 57 | } 58 | 59 | void DoUnwind(pid_t pid) { 60 | unwindstack::Regs* regs = unwindstack::Regs::RemoteGet(pid); 61 | if (regs == nullptr) { 62 | printf("Unable to get remote reg data\n"); 63 | return; 64 | } 65 | 66 | printf("ABI: "); 67 | switch (regs->Arch()) { 68 | case unwindstack::ARCH_ARM: 69 | printf("arm"); 70 | break; 71 | case unwindstack::ARCH_X86: 72 | printf("x86"); 73 | break; 74 | case unwindstack::ARCH_ARM64: 75 | printf("arm64"); 76 | break; 77 | case unwindstack::ARCH_X86_64: 78 | printf("x86_64"); 79 | break; 80 | case unwindstack::ARCH_MIPS: 81 | printf("mips"); 82 | break; 83 | case unwindstack::ARCH_MIPS64: 84 | printf("mips64"); 85 | break; 86 | default: 87 | printf("unknown\n"); 88 | return; 89 | } 90 | printf("\n"); 91 | 92 | unwindstack::UnwinderFromPid unwinder(1024, pid); 93 | unwinder.SetRegs(regs); 94 | unwinder.Unwind(); 95 | 96 | // Print the frames. 97 | for (size_t i = 0; i < unwinder.NumFrames(); i++) { 98 | printf("%s\n", unwinder.FormatFrame(i).c_str()); 99 | } 100 | } 101 | 102 | int main(int argc, char** argv) { 103 | if (argc != 2) { 104 | printf("Usage: unwind \n"); 105 | return 1; 106 | } 107 | 108 | pid_t pid = atoi(argv[1]); 109 | if (!Attach(pid)) { 110 | printf("Failed to attach to pid %d: %s\n", pid, strerror(errno)); 111 | return 1; 112 | } 113 | 114 | DoUnwind(pid); 115 | 116 | ptrace(PTRACE_DETACH, pid, 0, 0); 117 | 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /tools/unwind_symbols.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | int main(int argc, char** argv) { 31 | if (argc != 2 && argc != 3) { 32 | printf("Usage: unwind_symbols []\n"); 33 | printf(" Dump all function symbols in ELF_FILE. If FUNC_ADDRESS is\n"); 34 | printf(" specified, then get the function at that address.\n"); 35 | printf(" FUNC_ADDRESS must be a hex number.\n"); 36 | return 1; 37 | } 38 | 39 | struct stat st; 40 | if (stat(argv[1], &st) == -1) { 41 | printf("Cannot stat %s: %s\n", argv[1], strerror(errno)); 42 | return 1; 43 | } 44 | if (!S_ISREG(st.st_mode)) { 45 | printf("%s is not a regular file.\n", argv[1]); 46 | return 1; 47 | } 48 | 49 | uint64_t func_addr; 50 | if (argc == 3) { 51 | char* name; 52 | func_addr = strtoull(argv[2], &name, 16); 53 | if (*name != '\0') { 54 | printf("%s is not a hex number.\n", argv[2]); 55 | return 1; 56 | } 57 | } 58 | 59 | // Send all log messages to stdout. 60 | unwindstack::log_to_stdout(true); 61 | 62 | unwindstack::Elf elf(unwindstack::Memory::CreateFileMemory(argv[1], 0).release()); 63 | if (!elf.Init() || !elf.valid()) { 64 | printf("%s is not a valid elf file.\n", argv[1]); 65 | return 1; 66 | } 67 | 68 | std::string soname(elf.GetSoname()); 69 | if (!soname.empty()) { 70 | printf("Soname: %s\n\n", soname.c_str()); 71 | } 72 | 73 | switch (elf.machine_type()) { 74 | case EM_ARM: 75 | printf("ABI: arm\n"); 76 | break; 77 | case EM_AARCH64: 78 | printf("ABI: arm64\n"); 79 | break; 80 | case EM_386: 81 | printf("ABI: x86\n"); 82 | break; 83 | case EM_X86_64: 84 | printf("ABI: x86_64\n"); 85 | break; 86 | default: 87 | printf("ABI: unknown\n"); 88 | return 1; 89 | } 90 | 91 | std::string name; 92 | if (argc == 3) { 93 | unwindstack::SharedString cur_name; 94 | uint64_t func_offset; 95 | if (!elf.GetFunctionName(func_addr, &cur_name, &func_offset)) { 96 | printf("No known function at 0x%" PRIx64 "\n", func_addr); 97 | return 1; 98 | } 99 | printf("<0x%" PRIx64 ">", func_addr - func_offset); 100 | if (func_offset != 0) { 101 | printf("+%" PRId64, func_offset); 102 | } 103 | printf(": %s\n", cur_name.c_str()); 104 | return 0; 105 | } 106 | 107 | // This is a crude way to get the symbols in order. 108 | for (const auto& entry : elf.interface()->pt_loads()) { 109 | uint64_t start = entry.second.offset; 110 | uint64_t end = entry.second.table_size; 111 | for (uint64_t addr = start; addr < end; addr += 4) { 112 | unwindstack::SharedString cur_name; 113 | uint64_t func_offset; 114 | if (elf.GetFunctionName(addr, &cur_name, &func_offset)) { 115 | if (cur_name != name) { 116 | printf("<0x%" PRIx64 "> Function: %s\n", addr - func_offset, cur_name.c_str()); 117 | } 118 | name = cur_name; 119 | } 120 | } 121 | } 122 | 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /unistdfix.h: -------------------------------------------------------------------------------- 1 | #undef TEMP_FAILURE_RETRY 2 | #define TEMP_FAILURE_RETRY(exp) ({ \ 3 | __typeof__(exp) _rc; \ 4 | do { \ 5 | _rc = (exp); \ 6 | } while (_rc == -1 && errno == EINTR); \ 7 | _rc; }) 8 | --------------------------------------------------------------------------------