//===--------------------- 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 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(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(p + 1); if (!TBTable->tb.name_present) return NULL; // Get to the name of the function. p = reinterpret_cast(&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(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(p)); return reinterpret_cast(p) + sizeof(uint16_t); } } // namespace libunwind #endif // defined(_AIX)