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