/* mmap.c -- Memory allocation with mmap.
   Copyright (C) 2012-2017 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Google.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    (1) Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

    (2) Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in
    the documentation and/or other materials provided with the
    distribution.

    (3) The name of the author may not be used to
    endorse or promote products derived from this software without
    specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.  */

#include "config.h"

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>

#include "backtrace.h"
#include "internal.h"

/* Memory allocation on systems that provide anonymous mmap.  This
   permits the backtrace functions to be invoked from a signal
   handler, assuming that mmap is async-signal safe.  */

#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif

#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
#endif

/* A list of free memory blocks.  */

struct backtrace_freelist_struct
{
  /* Next on list.  */
  struct backtrace_freelist_struct *next;
  /* Size of this block, including this structure.  */
  size_t size;
};

/* Free memory allocated by backtrace_alloc.  */

static void
backtrace_free_locked (struct backtrace_state *state, void *addr, size_t size)
{
  /* Just leak small blocks.  We don't have to be perfect.  */
  if (size >= sizeof (struct backtrace_freelist_struct))
    {
      struct backtrace_freelist_struct *p;

      p = (struct backtrace_freelist_struct *) addr;
      p->next = state->freelist;
      p->size = size;
      state->freelist = p;
    }
}

/* Allocate memory like malloc.  If ERROR_CALLBACK is NULL, don't
   report an error.  */

void *
backtrace_alloc (struct backtrace_state *state,
		 size_t size, backtrace_error_callback error_callback,
		 void *data)
{
  void *ret;
  int locked;
  struct backtrace_freelist_struct **pp;
  size_t pagesize;
  size_t asksize;
  void *page;

  ret = NULL;

  /* If we can acquire the lock, then see if there is space on the
     free list.  If we can't acquire the lock, drop straight into
     using mmap.  __sync_lock_test_and_set returns the old state of
     the lock, so we have acquired it if it returns 0.  */

  if (!state->threaded)
    locked = 1;
  else
    locked = __sync_lock_test_and_set (&state->lock_alloc, 1) == 0;

  if (locked)
    {
      for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next)
	{
	  if ((*pp)->size >= size)
	    {
	      struct backtrace_freelist_struct *p;

	      p = *pp;
	      *pp = p->next;

	      /* Round for alignment; we assume that no type we care about
		 is more than 8 bytes.  */
	      size = (size + 7) & ~ (size_t) 7;
	      if (size < p->size)
		backtrace_free_locked (state, (char *) p + size,
				       p->size - size);

	      ret = (void *) p;

	      break;
	    }
	}

      if (state->threaded)
	__sync_lock_release (&state->lock_alloc);
    }

  if (ret == NULL)
    {
      /* Allocate a new page.  */

      pagesize = getpagesize ();
      asksize = (size + pagesize - 1) & ~ (pagesize - 1);
      page = mmap (NULL, asksize, PROT_READ | PROT_WRITE,
		   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
      if (page == MAP_FAILED)
	{
	  if (error_callback)
	    error_callback (data, "mmap", errno);
	}
      else
	{
	  size = (size + 7) & ~ (size_t) 7;
	  if (size < asksize)
	    backtrace_free (state, (char *) page + size, asksize - size,
			    error_callback, data);

	  ret = page;
	}
    }

  return ret;
}

/* Free memory allocated by backtrace_alloc.  */

void
backtrace_free (struct backtrace_state *state, void *addr, size_t size,
		backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
		void *data ATTRIBUTE_UNUSED)
{
  int locked;

  /* If we are freeing a large aligned block, just release it back to
     the system.  This case arises when growing a vector for a large
     binary with lots of debug info.  Calling munmap here may cause us
     to call mmap again if there is also a large shared library; we
     just live with that.  */
  if (size >= 16 * 4096)
    {
      size_t pagesize;

      pagesize = getpagesize ();
      if (((uintptr_t) addr & (pagesize - 1)) == 0
	  && (size & (pagesize - 1)) == 0)
	{
	  /* If munmap fails for some reason, just add the block to
	     the freelist.  */
	  if (munmap (addr, size) == 0)
	    return;
	}
    }

  /* If we can acquire the lock, add the new space to the free list.
     If we can't acquire the lock, just leak the memory.
     __sync_lock_test_and_set returns the old state of the lock, so we
     have acquired it if it returns 0.  */

  if (!state->threaded)
    locked = 1;
  else
    locked = __sync_lock_test_and_set (&state->lock_alloc, 1) == 0;

  if (locked)
    {
      backtrace_free_locked (state, addr, size);

      if (state->threaded)
	__sync_lock_release (&state->lock_alloc);
    }
}

/* Grow VEC by SIZE bytes.  */

void *
backtrace_vector_grow (struct backtrace_state *state,size_t size,
		       backtrace_error_callback error_callback,
		       void *data, struct backtrace_vector *vec)
{
  void *ret;

  if (size > vec->alc)
    {
      size_t pagesize;
      size_t alc;
      void *base;

      pagesize = getpagesize ();
      alc = vec->size + size;
      if (vec->size == 0)
	alc = 16 * size;
      else if (alc < pagesize)
	{
	  alc *= 2;
	  if (alc > pagesize)
	    alc = pagesize;
	}
      else
	{
	  alc *= 2;
	  alc = (alc + pagesize - 1) & ~ (pagesize - 1);
	}
      base = backtrace_alloc (state, alc, error_callback, data);
      if (base == NULL)
	return NULL;
      if (vec->base != NULL)
	{
	  memcpy (base, vec->base, vec->size);
	  backtrace_free (state, vec->base, vec->size + vec->alc,
			  error_callback, data);
	}
      vec->base = base;
      vec->alc = alc - vec->size;
    }

  ret = (char *) vec->base + vec->size;
  vec->size += size;
  vec->alc -= size;
  return ret;
}

/* Finish the current allocation on VEC.  */

void *
backtrace_vector_finish (
  struct backtrace_state *state ATTRIBUTE_UNUSED,
  struct backtrace_vector *vec,
  backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
  void *data ATTRIBUTE_UNUSED)
{
  void *ret;

  ret = vec->base;
  vec->base = (char *) vec->base + vec->size;
  vec->size = 0;
  return ret;
}

/* Release any extra space allocated for VEC.  */

int
backtrace_vector_release (struct backtrace_state *state,
			  struct backtrace_vector *vec,
			  backtrace_error_callback error_callback,
			  void *data)
{
  size_t size;
  size_t alc;
  size_t aligned;

  /* Make sure that the block that we free is aligned on an 8-byte
     boundary.  */
  size = vec->size;
  alc = vec->alc;
  aligned = (size + 7) & ~ (size_t) 7;
  alc -= aligned - size;

  backtrace_free (state, (char *) vec->base + aligned, alc,
		  error_callback, data);
  vec->alc = 0;
  return 1;
}
