181ad6265SDimitry Andric //===--------------------- Unwind_AIXExtras.cpp -------------------------===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric // 881ad6265SDimitry Andric //===----------------------------------------------------------------------===// 981ad6265SDimitry Andric 1081ad6265SDimitry Andric // This file is only used for AIX. 1181ad6265SDimitry Andric #if defined(_AIX) 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric #include "config.h" 1481ad6265SDimitry Andric #include "libunwind_ext.h" 1581ad6265SDimitry Andric #include <sys/debug.h> 1681ad6265SDimitry Andric 1781ad6265SDimitry Andric namespace libunwind { 1881ad6265SDimitry Andric // getFuncNameFromTBTable 1981ad6265SDimitry Andric // Get the function name from its traceback table. getFuncNameFromTBTable(uintptr_t Pc,uint16_t & NameLen,unw_word_t * Offset)2081ad6265SDimitry Andricchar *getFuncNameFromTBTable(uintptr_t Pc, uint16_t &NameLen, 2181ad6265SDimitry Andric unw_word_t *Offset) { 2281ad6265SDimitry Andric uint32_t *p = reinterpret_cast<uint32_t *>(Pc); 2381ad6265SDimitry Andric *Offset = 0; 2481ad6265SDimitry Andric 2581ad6265SDimitry Andric // Keep looking forward until a word of 0 is found. The traceback 2681ad6265SDimitry Andric // table starts at the following word. 2781ad6265SDimitry Andric while (*p) 2881ad6265SDimitry Andric p++; 2981ad6265SDimitry Andric tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1); 3081ad6265SDimitry Andric 3181ad6265SDimitry Andric if (!TBTable->tb.name_present) 3281ad6265SDimitry Andric return NULL; 3381ad6265SDimitry Andric 3481ad6265SDimitry Andric // Get to the name of the function. 3581ad6265SDimitry Andric p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext); 3681ad6265SDimitry Andric 3781ad6265SDimitry Andric // Skip field parminfo if it exists. 3881ad6265SDimitry Andric if (TBTable->tb.fixedparms || TBTable->tb.floatparms) 3981ad6265SDimitry Andric p++; 4081ad6265SDimitry Andric 41*bdd1243dSDimitry Andric // If the tb_offset field exists, get the offset from the start of 4281ad6265SDimitry Andric // the function to pc. Skip the field. 4381ad6265SDimitry Andric if (TBTable->tb.has_tboff) { 4481ad6265SDimitry Andric unw_word_t StartIp = 4581ad6265SDimitry Andric reinterpret_cast<uintptr_t>(TBTable) - *p - sizeof(uint32_t); 4681ad6265SDimitry Andric *Offset = Pc - StartIp; 4781ad6265SDimitry Andric p++; 4881ad6265SDimitry Andric } 4981ad6265SDimitry Andric 5081ad6265SDimitry Andric // Skip field hand_mask if it exists. 5181ad6265SDimitry Andric if (TBTable->tb.int_hndl) 5281ad6265SDimitry Andric p++; 5381ad6265SDimitry Andric 5481ad6265SDimitry Andric // Skip fields ctl_info and ctl_info_disp if they exist. 5581ad6265SDimitry Andric if (TBTable->tb.has_ctl) { 5681ad6265SDimitry Andric p += 1 + *p; 5781ad6265SDimitry Andric } 5881ad6265SDimitry Andric 5981ad6265SDimitry Andric NameLen = *(reinterpret_cast<uint16_t *>(p)); 6081ad6265SDimitry Andric return reinterpret_cast<char *>(p) + sizeof(uint16_t); 6181ad6265SDimitry Andric } 6281ad6265SDimitry Andric } // namespace libunwind 6381ad6265SDimitry Andric #endif // defined(_AIX) 64