brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · 0565757 Raw
247 lines · plain
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9// Test that _Unwind_Backtrace() walks up from a signal handler and produces10// a correct traceback when the function raising the signal does not save11// the link register or does not store the stack back chain.12 13// REQUIRES: target={{.+}}-aix{{.*}}14 15// Test when the function raising the signal does not save the link register16// RUN: %{cxx} -x c++ %s -o %t.exe -DCXX_CODE %{flags} %{compile_flags}17// RUN: %{exec} %t.exe18 19// Test when the function raising the signal does not store stack back chain.20// RUN: %{cxx} -x c++ -c %s -o %t1.o -DCXX_CODE -DNOBACKCHAIN %{flags} \21// RUN:   %{compile_flags}22// RUN: %{cxx} -c %s -o %t2.o %{flags} %{compile_flags}23// RUN: %{cxx} -o %t1.exe %t1.o %t2.o %{flags} %{link_flags}24// RUN: %{exec} %t1.exe25 26#ifdef CXX_CODE27 28#undef NDEBUG29#include <assert.h>30#include <signal.h>31#include <stdio.h>32#include <stdlib.h>33#include <string.h>34#include <sys/debug.h>35#include <unwind.h>36 37#define NAME_ARRAY_SIZE 1038#define NAMES_EXPECTED   639 40const char* namesExpected[] = {"handler", "abc", "bar", "foo", "main",41                               "__start"};42char *namesObtained[NAME_ARRAY_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};43 44int funcIndex = 0;45 46// Get the function name from traceback table.47char *getFuncName(uintptr_t pc, uint16_t *nameLen) {48  uint32_t *p = reinterpret_cast<uint32_t *>(pc);49 50  // Keep looking forward until a word of 0 is found. The traceback51  // table starts at the following word.52  while (*p)53    ++p;54  tbtable *TBTable = reinterpret_cast<tbtable *>(p + 1);55 56  if (!TBTable->tb.name_present)57    return NULL;58 59  // Get to the optional portion of the traceback table.60  p = reinterpret_cast<uint32_t *>(&TBTable->tb_ext);61 62  // Skip field parminfo if it exists.63  if (TBTable->tb.fixedparms || TBTable->tb.floatparms)64    ++p;65 66  // Skip field tb_offset if it exists.67  if (TBTable->tb.has_tboff)68    ++p;69 70  // Skip field hand_mask if it exists.71  if (TBTable->tb.int_hndl)72    ++p;73 74  // Skip fields ctl_info and ctl_info_disp if they exist.75  if (TBTable->tb.has_ctl)76    p += 1 + *p;77 78  *nameLen = *reinterpret_cast<uint16_t *>(p);79  return reinterpret_cast<char *>(p) + sizeof(uint16_t);80}81 82_Unwind_Reason_Code callBack(struct _Unwind_Context *uc, void *arg) {83  (void)arg;84  uint16_t nameLen;85  uintptr_t ip = _Unwind_GetIP(uc);86  if (funcIndex < NAME_ARRAY_SIZE)87    namesObtained[funcIndex++] = strndup(getFuncName(ip, &nameLen), nameLen);88  return _URC_NO_REASON;89}90 91extern "C" void handler(int signum) {92  (void)signum;93  // Walk stack frames for traceback.94  _Unwind_Backtrace(callBack, NULL);95 96  // Verify the traceback.97  assert(funcIndex <= NAMES_EXPECTED && "Obtained names more than expected");98  for (int i = 0; i < funcIndex; ++i) {99    assert(!strcmp(namesExpected[i], namesObtained[i]) &&100           "Function names do not match");101    free(namesObtained[i]);102  }103  exit(0);104}105 106#ifdef NOBACKCHAIN107// abc() is in assembly. It raises signal SIGSEGV and does not store108// the stack back chain.109extern "C" void abc();110 111#else112volatile int *null = 0;113 114// abc() raises signal SIGSEGV and does not save the link register.115extern "C" __attribute__((noinline)) void abc() {116  // Produce a SIGSEGV.117  *null = 0;118}119#endif120 121extern "C" __attribute__((noinline)) void bar() {122  abc();123}124 125extern "C" __attribute__((noinline)) void foo() {126  bar();127}128 129int main(int, char**) {130  // Set signal handler for SIGSEGV.131  signal(SIGSEGV, handler);132  foo();133  return 0;134}135 136#else // Assembly code for abc().137// This assembly code is similar to the following C code but it saves the138// link register.139//140// int *badp = 0;141// void abc() {142//   *badp = 0;143// }144 145#ifdef __64BIT__146        .csect [PR],5147        .file   "abc.c"148        .globl  abc[DS]                 # -- Begin function abc149        .globl  .abc150        .align  4151        .csect abc[DS],3152        .vbyte  8, .abc                 # @abc153        .vbyte  8, TOC[TC0]154        .vbyte  8, 0155        .csect [PR],5156.abc:157# %bb.0:                                # %entry158        mflr 0159        std 0, 16(1)160        ld 3, L..C0(2)                  # @badp161        bl $+4162        ld 4, 0(3)163        li 3, 0164        stw 3, 0(4)165        ld 0, 16(1)166        mtlr 0167        blr168L..abc0:169        .vbyte  4, 0x00000000           # Traceback table begin170        .byte   0x00                    # Version = 0171        .byte   0x09                    # Language = CPlusPlus172        .byte   0x20                    # -IsGlobalLinkage, -IsOutOfLineEpilogOrPrologue173                                        # +HasTraceBackTableOffset, -IsInternalProcedure174                                        # -HasControlledStorage, -IsTOCless175                                        # -IsFloatingPointPresent176                                        # -IsFloatingPointOperationLogOrAbortEnabled177        .byte   0x61                    # -IsInterruptHandler, +IsFunctionNamePresent, +IsAllocaUsed178                                        # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved179        .byte   0x00                    # -IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0180        .byte   0x01                    # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 1181        .byte   0x00                    # NumberOfFixedParms = 0182        .byte   0x01                    # NumberOfFPParms = 0, +HasParmsOnStack183        .vbyte  4, L..abc0-.abc         # Function size184        .vbyte  2, 0x0003               # Function name len = 3185        .byte   "abc"                   # Function Name186        .byte   0x1f                    # AllocaUsed187                                        # -- End function188        .csect badp[RW],3189        .globl  badp[RW]                # @badp190        .align  3191        .vbyte  8, 0192        .toc193L..C0:194        .tc badp[TC],badp[RW]195#else196        .csect [PR],5197        .file   "abc.c"198        .globl  abc[DS]                 # -- Begin function abc199        .globl  .abc200        .align  4201        .csect abc[DS],2202        .vbyte  4, .abc                 # @abc203        .vbyte  4, TOC[TC0]204        .vbyte  4, 0205        .csect [PR],5206.abc:207# %bb.0:                                # %entry208        mflr 0209        stw 0, 8(1)210        lwz 3, L..C0(2)                 # @badp211        bl $+4212        lwz 4, 0(3)213        li 3, 0214        stw 3, 0(4)215        lwz 0, 8(1)216        mtlr 0217        blr218L..abc0:219        .vbyte  4, 0x00000000           # Traceback table begin220        .byte   0x00                    # Version = 0221        .byte   0x09                    # Language = CPlusPlus222        .byte   0x20                    # -IsGlobalLinkage, -IsOutOfLineEpilogOrPrologue223                                        # +HasTraceBackTableOffset, -IsInternalProcedure224                                        # -HasControlledStorage, -IsTOCless225                                        # -IsFloatingPointPresent226                                        # -IsFloatingPointOperationLogOrAbortEnabled227        .byte   0x61                    # -IsInterruptHandler, +IsFunctionNamePresent, +IsAllocaUsed228                                        # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved229        .byte   0x00                    # -IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0230        .byte   0x01                    # -HasExtensionTable, -HasVectorInfo, NumOfGPRsSaved = 1231        .byte   0x00                    # NumberOfFixedParms = 0232        .byte   0x01                    # NumberOfFPParms = 0, +HasParmsOnStack233        .vbyte  4, L..abc0-.abc         # Function size234        .vbyte  2, 0x0003               # Function name len = 3235        .byte   "abc"                   # Function Name236        .byte   0x1f                    # AllocaUsed237                                        # -- End function238        .csect badp[RW],2239        .globl  badp[RW]                # @badp240        .align  2241        .vbyte  4, 0242        .toc243L..C0:244        .tc badp[TC],badp[RW]245#endif // __64BIT__246#endif // CXX_CODE247