X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..eb1cde05bb040f65c511ae4fa854abf1628afdf2:/gen/stack_logging.c diff --git a/gen/stack_logging.c b/gen/stack_logging.c index 4a38217..ff59ae4 100644 --- a/gen/stack_logging.c +++ b/gen/stack_logging.c @@ -3,8 +3,6 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. - * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -36,30 +34,41 @@ extern void spin_lock(int *); +static inline void *allocate_pages(unsigned) __attribute__((always_inline)); static inline void *allocate_pages(unsigned bytes) { void *address; if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes, VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) { - malloc_printf("malloc[%d]: Out of memory while stack logging\n", getpid()); + malloc_printf("*** out of memory while stack logging\n"); abort(); } return (void *)address; } +static inline void deallocate_pages(void *, unsigned) __attribute__((always_inline)); static inline void deallocate_pages(void *ptr, unsigned bytes) { vm_deallocate(mach_task_self(), (vm_address_t)ptr, bytes); } +static inline void copy_pages(const void *, void *, unsigned) __attribute__((always_inline)); static inline void copy_pages(const void *source, void *dest, unsigned bytes) { if (vm_copy(mach_task_self(), (vm_address_t)source, bytes, (vm_address_t)dest)) memmove(dest, source, bytes); } /*************** Recording stack ***********/ -static void *first_frame_address(void) { -#if 0 - return __builtin_frame_address(1); -#elif defined(__ppc__) +// The three functions below are marked as noinline to ensure consistent inlining across +// all versions of GCC and all compiler flags. The malloc stack logging code expects +// these functions to not be inlined. +// For details, see . +// +// The performance cost of not inlining these functions is negligible, and they're only +// called when MallocStackLogging is set anyway, so they won't affect normal usage. + +static __attribute__((noinline)) void *first_frame_address(void) { +#if defined(__i386__) + return __builtin_frame_address(0); +#elif defined(__ppc__) || defined(__ppc64__) void *addr; #warning __builtin_frame_address IS BROKEN IN BEAKER: RADAR #2340421 __asm__ volatile("mr %0, r1" : "=r" (addr)); @@ -70,11 +79,11 @@ static void *first_frame_address(void) { #endif } -static void *next_frame_address(void *addr) { +static __attribute__((noinline)) void *next_frame_address(void *addr) { void *ret; #if defined(__MACH__) && defined(__i386__) __asm__ volatile("movl (%1),%0" : "=r" (ret) : "r" (addr)); -#elif defined(__MACH__) && defined(__ppc__) +#elif defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)) __asm__ volatile("lwz %0,0x0(%1)" : "=r" (ret) : "b" (addr)); #elif defined(__hpux__) __asm__ volatile("ldw 0x0(%1),%0" : "=r" (ret) : "r" (addr)); @@ -89,7 +98,7 @@ static void *next_frame_address(void *addr) { #if defined(__i386__) || defined (__m68k__) #define FP_LINK_OFFSET 1 -#elif defined(__ppc__) +#elif defined(__ppc__) || defined(__ppc64__) #define FP_LINK_OFFSET 2 #elif defined(__hppa__) #define FP_LINK_OFFSET -5 @@ -99,7 +108,7 @@ static void *next_frame_address(void *addr) { #error ********** Unimplemented architecture #endif -void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) { +__attribute__((noinline)) void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) { void *addr; addr = first_frame_address(); *nb = 0; @@ -109,7 +118,7 @@ void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *nb) { buffer[*nb] = *((vm_address_t *)fp_link); (*nb)++; addr2 = next_frame_address(addr); -#if defined(__ppc__) +#if defined(__ppc__) || defined(__ppc64__) if ((unsigned)addr2 <= (unsigned)addr) break; // catch bozo frames #endif addr = addr2;