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