mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-11-03 20:53:13 +03:00 
			
		
		
		
	The ucontext_t type has a tag struct ucontext. As with previous such issues for siginfo_t and stack_t, this tag is not permitted by POSIX (is not in a reserved namespace), and so namespace conformance means breaking C++ name mangling for this type. In this case, the type does need to have some tag rather than just a typedef name, because it includes a pointer to itself. This patch uses struct ucontext_t as the new tag, so the type is mangled as ucontext_t (the POSIX *_t reservation applies in all namespaces, not just the namespace of ordinary identifiers). Another reserved name such as struct __ucontext could of course be used. Because of other namespace issues, this patch does not by itself fix bug 21457 or allow any XFAILs to be removed. Tested for x86_64, and with build-many-glibcs.py. [BZ #21457] * sysdeps/arm/sys/ucontext.h (struct ucontext): Rename to struct ucontext_t. * sysdeps/generic/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/i386/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/m68k/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/mips/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/alpha/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/arm/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/hppa/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/ia64/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/m68k/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/mips/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/nios2/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/s390/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/sh/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/sparc/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/tile/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/unix/sysv/linux/x86/sys/ucontext.h (struct ucontext): Likewise. * sysdeps/powerpc/powerpc32/backtrace.c (struct rt_signal_frame_32): Likewise. * sysdeps/powerpc/powerpc64/backtrace.c (struct signal_frame_64): Likewise. * sysdeps/unix/sysv/linux/aarch64/kernel_rt_sigframe.h (struct kernel_rt_sigframe): Likewise. * sysdeps/unix/sysv/linux/aarch64/sigcontextinfo.h (SIGCONTEXT): Likewise. * sysdeps/unix/sysv/linux/arm/register-dump.h (register_dump): Likewise. * sysdeps/unix/sysv/linux/arm/sigcontextinfo.h (SIGCONTEXT): Likewise. * sysdeps/unix/sysv/linux/hppa/profil-counter.h (__profil_counter): Likewise. * sysdeps/unix/sysv/linux/microblaze/sigcontextinfo.h (SIGCONTEXT): Likewise. * sysdeps/unix/sysv/linux/mips/kernel_rt_sigframe.h (struct kernel_rt_sigframe): Likewise. * sysdeps/unix/sysv/linux/nios2/kernel_rt_sigframe.h (struct kernel_rt_sigframe): Likewise. * sysdeps/unix/sysv/linux/nios2/sigcontextinfo.h (SIGCONTEXT): Likewise. * sysdeps/unix/sysv/linux/sh/makecontext.S (__makecontext): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/makecontext.c (__start_context): Likewise. * sysdeps/unix/sysv/linux/tile/sigcontextinfo.h (SIGCONTEXT): Likewise. * sysdeps/unix/sysv/linux/x86_64/register-dump.h (register_dump): Likewise. * sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h (SIGCONTEXT): Likewise.
		
			
				
	
	
		
			105 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Return backtrace of current program state.
 | 
						|
   Copyright (C) 1998-2017 Free Software Foundation, Inc.
 | 
						|
   This file is part of the GNU C Library.
 | 
						|
 | 
						|
   The GNU C Library is free software; you can redistribute it and/or
 | 
						|
   modify it under the terms of the GNU Library General Public License as
 | 
						|
   published by the Free Software Foundation; either version 2 of the
 | 
						|
   License, or (at your option) any later version.
 | 
						|
 | 
						|
   The GNU C Library is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
   Library General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU Library General Public
 | 
						|
   License along with the GNU C Library; see the file COPYING.LIB.  If
 | 
						|
   not, see <http://www.gnu.org/licenses/>.  */
 | 
						|
 | 
						|
#include <stddef.h>
 | 
						|
#include <string.h>
 | 
						|
#include <signal.h>
 | 
						|
#include <stdint.h>
 | 
						|
 | 
						|
#include <execinfo.h>
 | 
						|
#include <libc-vdso.h>
 | 
						|
 | 
						|
/* This is the stack layout we see with every stack frame.
 | 
						|
   Note that every routine is required by the ABI to lay out the stack
 | 
						|
   like this.
 | 
						|
 | 
						|
            +----------------+        +-----------------+
 | 
						|
    %r1  -> | %r1 last frame--------> | %r1 last frame--->...  --> NULL
 | 
						|
            |                |        |                 |
 | 
						|
            | cr save        |        | cr save	  |
 | 
						|
            |                |        |                 |
 | 
						|
            | (unused)       |        | return address  |
 | 
						|
            +----------------+        +-----------------+
 | 
						|
*/
 | 
						|
struct layout
 | 
						|
{
 | 
						|
  struct layout *next;
 | 
						|
  long int condition_register;
 | 
						|
  void *return_address;
 | 
						|
};
 | 
						|
 | 
						|
/* Since the signal handler is just like any other function it needs to
 | 
						|
   save/restore its LR and it will save it into callers stack frame.
 | 
						|
   Since a signal handler doesn't have a caller, the kernel creates a
 | 
						|
   dummy frame to make it look like it has a caller.  */
 | 
						|
struct signal_frame_64 {
 | 
						|
#define SIGNAL_FRAMESIZE 128
 | 
						|
  char dummy[SIGNAL_FRAMESIZE];
 | 
						|
  ucontext_t uc;
 | 
						|
  /* We don't care about the rest, since the IP value is at 'uc' field.  */
 | 
						|
};
 | 
						|
 | 
						|
static inline int
 | 
						|
is_sigtramp_address (void *nip)
 | 
						|
{
 | 
						|
#ifdef SHARED
 | 
						|
  if (nip == VDSO_SYMBOL (sigtramp_rt64))
 | 
						|
    return 1;
 | 
						|
#endif
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
__backtrace (void **array, int size)
 | 
						|
{
 | 
						|
  struct layout *current;
 | 
						|
  int count;
 | 
						|
 | 
						|
  /* Force gcc to spill LR.  */
 | 
						|
  asm volatile ("" : "=l"(current));
 | 
						|
 | 
						|
  /* Get the address on top-of-stack.  */
 | 
						|
  asm volatile ("ld %0,0(1)" : "=r"(current));
 | 
						|
 | 
						|
  for (				count = 0;
 | 
						|
       current != NULL && 	count < size;
 | 
						|
       current = current->next, count++)
 | 
						|
    {
 | 
						|
      array[count] = current->return_address;
 | 
						|
 | 
						|
      /* Check if the symbol is the signal trampoline and get the interrupted
 | 
						|
       * symbol address from the trampoline saved area.  */
 | 
						|
      if (is_sigtramp_address (current->return_address))
 | 
						|
        {
 | 
						|
	  struct signal_frame_64 *sigframe = (struct signal_frame_64*) current;
 | 
						|
          array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP];
 | 
						|
	  current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1];
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  /* It's possible the second-last stack frame can't return
 | 
						|
     (that is, it's __libc_start_main), in which case
 | 
						|
     the CRT startup code will have set its LR to 'NULL'.  */
 | 
						|
  if (count > 0 && array[count-1] == NULL)
 | 
						|
    count--;
 | 
						|
 | 
						|
  return count;
 | 
						|
}
 | 
						|
weak_alias (__backtrace, backtrace)
 | 
						|
libc_hidden_def (__backtrace)
 |