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 17 namespace libunwind { 18 // getFuncNameFromTBTable 19 // Get the function name from its traceback table. 20 char *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 exisits, 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