1  /* PR gcov-profile/97461 */
       2  /* { dg-options "-O2 -ldl -fprofile-correction" } */
       3  
       4  #define _GNU_SOURCE
       5  
       6  #include <stdio.h>
       7  #include <stdlib.h>
       8  #include <string.h>
       9  
      10  static int malloc_depth = 0;
      11  
      12  static char memory[128* 1024];
      13  static size_t memory_p = 0;
      14  
      15  void f1(void) {}
      16  void f2(void) {}
      17  
      18  typedef void (*fun_t)(void);
      19  static const fun_t funs[2] = { f1, f2, };
      20  
      21  static void * malloc_impl(size_t size) {
      22      void * r = &memory[memory_p];
      23      /* The malloc() and calloc() functions return a pointer to the allocated
      24       * memory, which is suitably aligned for any built-in type.  Use 16
      25       * bytes here as the basic alignment requirement for user-defined malloc
      26       * and calloc.  See PR97594 for the details.  */
      27      #define ROUND_UP_FOR_16B_ALIGNMENT(x) ((x + 15) & (-16))
      28  
      29      memory_p += ROUND_UP_FOR_16B_ALIGNMENT(size);
      30  
      31      // force TOPN profile
      32      funs[size % 2]();
      33      return r;
      34  }
      35  
      36  // Override default malloc, check it it get s called recursively
      37  void * malloc(size_t size) {
      38      // Must not be called recursively. Malloc implementation does not support it.
      39      if (malloc_depth != 0) __builtin_trap();
      40  
      41      ++malloc_depth;
      42        void * r = malloc_impl(size);
      43      --malloc_depth;
      44      return r;
      45  }
      46  
      47  // Called from gcov
      48  void *calloc(size_t nmemb, size_t size) {
      49      // Must not be called recursively.  Malloc implementation does not support it.
      50      if (malloc_depth != 0) __builtin_trap();
      51  
      52      ++malloc_depth;
      53        void * r = malloc_impl(size * nmemb);
      54        memset(r, 0, size * nmemb);
      55      --malloc_depth;
      56      return r;
      57  }
      58  
      59  void free(void *ptr){}
      60  
      61  int main() {
      62      void * p = malloc(8);
      63      return p != 0 ? 0 : 1;
      64  }