1//===--------------------- Unwind_AIXExtras.cpp -------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//===----------------------------------------------------------------------===//
9
10// This file is only used for AIX.
11#if defined(_AIX)
12
13#include "config.h"
14#include "libunwind_ext.h"
15#include <sys/debug.h>
16
17namespace libunwind {
18// getFuncNameFromTBTable
19// Get the function name from its traceback table.
20char *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen,
21 unw_word_t *Offset) {
22 uint32_t *p = reinterpret_cast<uint32_t *>(Pc);
23 *Offset = 0;
24
25 // Keep looking forward until a word of 0 is found. The traceback
26 // table starts at the following word.
27 while (*p)
28 p++;
29 tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);
30
31 if (!TBTable->tb.name_present)
32 return NULL;
33
34 // Get to the name of the function.
35 p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);
36
37 // Skip field parminfo if it exists.
38 if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
39 p++;
40
41 // If the tb_offset field exists, get the offset from the start of
42 // the function to pc. Skip the field.
43 if (TBTable->tb.has_tboff) {
44 unw_word_t StartIp =
45 reinterpret_cast<uintptr_t>(TBTable) - *p - sizeof(uint32_t);
46 *Offset = Pc - StartIp;
47 p++;
48 }
49
50 // Skip field hand_mask if it exists.
51 if (TBTable->tb.int_hndl)
52 p++;
53
54 // Skip fields ctl_info and ctl_info_disp if they exist.
55 if (TBTable->tb.has_ctl) {
56 p += 1 + *p;
57 }
58
59 NameLen = *(reinterpret_cast<uint16_t *>(p));
60 return reinterpret_cast<char *>(p) + sizeof(uint16_t);
61}
62} // namespace libunwind
63#endif // defined(_AIX)
64

source code of libunwind/src/Unwind_AIXExtras.cpp