diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-08-04 18:09:10 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-08-04 18:09:10 -0700 |
| commit | 2f635c3ce9be74f9e9ffb71324f7ba51bd2987f4 (patch) | |
| tree | f04b0f4fb7a0e5ce0e36829bfd9aaa032447ac2a /lib/libunwind/src/Unwind_AIXExtras.cpp | |
| parent | c0d9578a84c95f66f34729f6c8842a98a995f223 (diff) | |
| download | zig-2f635c3ce9be74f9e9ffb71324f7ba51bd2987f4.tar.gz zig-2f635c3ce9be74f9e9ffb71324f7ba51bd2987f4.zip | |
update libunwind to LLVM 15
release/15.x commit 134fd359a5d884f16662a9edd22ab24feeb1498c
Diffstat (limited to 'lib/libunwind/src/Unwind_AIXExtras.cpp')
| -rw-r--r-- | lib/libunwind/src/Unwind_AIXExtras.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/libunwind/src/Unwind_AIXExtras.cpp b/lib/libunwind/src/Unwind_AIXExtras.cpp new file mode 100644 index 0000000000..7e47f70186 --- /dev/null +++ b/lib/libunwind/src/Unwind_AIXExtras.cpp @@ -0,0 +1,63 @@ +//===--------------------- Unwind_AIXExtras.cpp -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// +//===----------------------------------------------------------------------===// + +// This file is only used for AIX. +#if defined(_AIX) + +#include "config.h" +#include "libunwind_ext.h" +#include <sys/debug.h> + +namespace libunwind { +// getFuncNameFromTBTable +// Get the function name from its traceback table. +char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen, + unw_word_t *Offset) { + uint32_t *p = reinterpret_cast<uint32_t *>(Pc); + *Offset = 0; + + // Keep looking forward until a word of 0 is found. The traceback + // table starts at the following word. + while (*p) + p++; + tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1); + + if (!TBTable->tb.name_present) + return NULL; + + // Get to the name of the function. + p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext); + + // Skip field parminfo if it exists. + if (TBTable->tb.fixedparms || TBTable->tb.floatparms) + p++; + + // If the tb_offset field exisits, get the offset from the start of + // the function to pc. Skip the field. + if (TBTable->tb.has_tboff) { + unw_word_t StartIp = + reinterpret_cast<uintptr_t>(TBTable) - *p - sizeof(uint32_t); + *Offset = Pc - StartIp; + p++; + } + + // Skip field hand_mask if it exists. + if (TBTable->tb.int_hndl) + p++; + + // Skip fields ctl_info and ctl_info_disp if they exist. + if (TBTable->tb.has_ctl) { + p += 1 + *p; + } + + NameLen = *(reinterpret_cast<uint16_t *>(p)); + return reinterpret_cast<char *>(p) + sizeof(uint16_t); +} +} // namespace libunwind +#endif // defined(_AIX) |
