
/*--------------------------------------------------------------------*/
/*--- Stack management.                                 m_stacks.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2000-2013 Julian Seward 
      jseward@acm.org

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program 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
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#include "pub_core_basics.h"
#include "pub_core_debuglog.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_stacks.h"
#include "pub_core_tooliface.h"

// For expensive debugging
#define EDEBUG(fmt, args...) //VG_(debugLog)(2, "stacks", fmt, ## args)

/*
   The stack
   ~~~~~~~~~
   The stack's segment seems to be dynamically extended downwards by
   the kernel as the stack pointer moves down.  Initially, a 1-page
   (4k) stack is allocated.  When SP moves below that for the first
   time, presumably a page fault occurs.  The kernel detects that the
   faulting address is in the range from SP - VG_STACK_REDZONE_SZB
   upwards to the current valid stack.  It then extends the stack
   segment downwards for enough to cover the faulting address, and
   resumes the process (invisibly).  The process is unaware of any of
   this.

   That means that Valgrind can't spot when the stack segment is being
   extended.  Fortunately, we want to precisely and continuously
   update stack permissions around SP, so we need to spot all writes
   to SP anyway.

   The deal is: when SP is assigned a lower value, the stack is being
   extended.  Create suitably-permissioned pages to fill in any holes
   between the old stack ptr and this one, if necessary.  Then mark
   all bytes in the area just "uncovered" by this SP change as
   write-only.

   When SP goes back up, mark the area receded over as unreadable and
   unwritable.

   Just to record the SP boundary conditions somewhere convenient: 
   SP - VG_STACK_REDZONE_SZB always points to the lowest live byte in
   the stack.  All addresses below SP - VG_STACK_REDZONE_SZB are not
   live; those at and above it are.

   We do not concern ourselves here with the VG_STACK_REDZONE_SZB
   bias; that is handled by new_mem_stack/die_mem_stack.
*/

/*
 * This structure holds information about the start and end addresses of
 * registered stacks.  There's always at least one stack registered:
 * the main process stack.  It will be the first stack registered and
 * so will have a stack id of 0.  The user does not need to register
 * this stack: Valgrind does it automatically right before it starts
 * running the client.  No other stacks are automatically registered by
 * Valgrind, however.
 */
typedef struct _Stack {
   UWord id;
   Addr start; // Lowest stack byte, included.
   Addr end;   // Highest stack byte, included.
   struct _Stack *next;
} Stack;

static Stack *stacks;
static UWord next_id;  /* Next id we hand out to a newly registered stack */

/*
 * These are the id, start and end values of the current stack.  If the
 * stack pointer falls outside the range of the current stack, we search
 * the stacks list above for a matching stack.
 */
static Stack *current_stack;

/* Find 'st' in the stacks_list and move it one step closer the the
   front of the list, so as to make subsequent searches for it
   cheaper. */
static void move_Stack_one_step_forward ( Stack* st )
{
   Stack *st0, *st1, *st2;
   if (st == stacks)
      return; /* already at head of list */
   vg_assert(st != NULL);
   st0 = stacks;
   st1 = NULL;
   st2 = NULL;
   while (True) {
      if (st0 == NULL || st0 == st) break;
      st2 = st1;
      st1 = st0;
      st0 = st0->next;
   }
   vg_assert(st0 == st);
   if (st0 != NULL && st1 != NULL && st2 != NULL) {
      Stack* tmp;
      /* st0 points to st, st1 to its predecessor, and st2 to st1's
         predecessor.  Swap st0 and st1, that is, move st0 one step
         closer to the start of the list. */
      vg_assert(st2->next == st1);
      vg_assert(st1->next == st0);
      tmp = st0->next;
      st2->next = st0;
      st0->next = st1;
      st1->next = tmp;
   }
   else
   if (st0 != NULL && st1 != NULL && st2 == NULL) {
      /* it's second in the list. */
      vg_assert(stacks == st1);
      vg_assert(st1->next == st0);
      st1->next = st0->next;
      st0->next = st1;
      stacks = st0;
   }
}

/* Find what stack an address falls into. */
static Stack* find_stack_by_addr(Addr sp)
{
   static UWord n_fails = 0;
   static UWord n_searches = 0;
   static UWord n_steps = 0;
   Stack *i = stacks;
   n_searches++;
   if (0 && 0 == (n_searches % 10000))
      VG_(printf)("(hgdev) %lu searches, %lu steps, %lu fails\n",
                  n_searches, n_steps+1, n_fails);
   /* fast track common case */
   if (i && sp >= i->start && sp <= i->end)
      return i;
   /* else search the list */
   while (i) {
      n_steps++;
      if (sp >= i->start && sp <= i->end) {
         if (1 && (n_searches & 0x3F) == 0) {
            move_Stack_one_step_forward( i );
         }
         return i;
      }
      i = i->next;
   }
   n_fails++;
   return NULL;
}

/*
 * Register a new stack from start - end.  This is invoked from the
 * VALGRIND_STACK_REGISTER client request, and is also called just before
 * we start the client running, to register the main process stack.
 */
UWord VG_(register_stack)(Addr start, Addr end)
{
   Stack *i;

   if (start > end) {
      /* If caller provides addresses in reverse order, swap them.
         Ugly but not doing that breaks backward compatibility with
         (user) code registering stacks with start/end inverted . */
      Addr t = end;
      end = start;
      start = t;
   }

   i = VG_(malloc)("stacks.rs.1", sizeof(Stack));
   i->start = start;
   i->end = end;
   i->id = next_id++;
   i->next = stacks;
   stacks = i;

   if (i->id == 0) {
      current_stack = i;
   }

   VG_(debugLog)(2, "stacks", "register [%p-%p] as stack %lu\n",
                    (void*)start, (void*)end, i->id);

   return i->id;
}

/*
 * Deregister a stack.  This is invoked from the VALGRIND_STACK_DEREGISTER
 * client request.
 */
void VG_(deregister_stack)(UWord id)
{
   Stack *i = stacks;
   Stack *prev = NULL;

   VG_(debugLog)(2, "stacks", "deregister stack %lu\n", id);

   if (current_stack && current_stack->id == id) { 
      current_stack = NULL;
   }

   while(i) {
      if (i->id == id) {
         if(prev == NULL) {
            stacks = i->next;
         } else {
            prev->next = i->next;
         }
         VG_(free)(i);
         return;
      }
      prev = i;
      i = i->next;
   }
}

/*
 * Change a stack.  This is invoked from the VALGRIND_STACK_CHANGE client
 * request and from the stack growth stuff the signals module when
 * extending the main process stack.
 */
void VG_(change_stack)(UWord id, Addr start, Addr end)
{
   Stack *i = stacks;

   while (i) {
      if (i->id == id) {
         VG_(debugLog)(2, "stacks", 
                       "change stack %lu from [%p-%p] to [%p-%p]\n",
                       id, (void*)i->start, (void*)i->end,
                           (void*)start,    (void*)end);
         /* FIXME : swap start/end like VG_(register_stack) ??? */
         i->start = start;
         i->end = end;
         return;
      }
      i = i->next;
   }
}

/*
 * Find the bounds of the stack (if any) which includes the
 * specified stack pointer.
 */
void VG_(stack_limits)(Addr SP, Addr *start, Addr *end )
{
   Stack* stack = find_stack_by_addr(SP);

   if (stack) {
      *start = stack->start;
      *end = stack->end;
   }
}

/* complaints_stack_switch reports that SP has changed by more than some
   threshold amount (by default, 2MB).  We take this to mean that the
   application is switching to a new stack, for whatever reason.
   
   JRS 20021001: following discussions with John Regehr, if a stack
   switch happens, it seems best not to mess at all with memory
   permissions.  Seems to work well with Netscape 4.X.  Really the
   only remaining difficulty is knowing exactly when a stack switch is
   happening. */
__attribute__((noinline))
static void complaints_stack_switch (Addr old_SP, Addr new_SP)
{
   static Int complaints = 3;
   if (VG_(clo_verbosity) > 0 && complaints > 0 && !VG_(clo_xml)) {
      Word delta  = (Word)new_SP - (Word)old_SP;
      complaints--;
      VG_(message)(Vg_UserMsg,
                   "Warning: client switching stacks?  "
                   "SP change: 0x%lx --> 0x%lx\n", old_SP, new_SP);
      VG_(message)(Vg_UserMsg,
                   "         to suppress, use: --max-stackframe=%ld "
                   "or greater\n",
                   (delta < 0 ? -delta : delta));
      if (complaints == 0)
         VG_(message)(Vg_UserMsg,
                      "         further instances of this message "
                      "will not be shown.\n");
   }
}

/* The functions VG_(unknown_SP_update) and VG_(unknown_SP_update_w_ECU)
   get called if new_mem_stack and/or die_mem_stack are
   tracked by the tool, and one of the specialised cases
   (eg. new_mem_stack_4) isn't used in preference.  

   These functions are performance critical, so are built with macros. */

// preamble + check if stack has switched.
#define IF_STACK_SWITCH_SET_current_stack_AND_RETURN                    \
   Word delta  = (Word)new_SP - (Word)old_SP;                           \
                                                                        \
   EDEBUG("current_stack  %p-%p %lu new_SP %p old_SP %p\n",             \
          (void *) (current_stack ? current_stack->start : 0x0),        \
          (void *) (current_stack ? current_stack->end : 0x0),          \
          current_stack ? current_stack->id : 0,                        \
          (void *)new_SP, (void *)old_SP);                              \
                                                                        \
   /* Check if the stack pointer is still in the same stack as before. */ \
   if (UNLIKELY(current_stack == NULL ||                                \
      new_SP < current_stack->start || new_SP > current_stack->end)) {  \
      Stack* new_stack = find_stack_by_addr(new_SP);                    \
      if (new_stack                                                     \
          && (current_stack == NULL || new_stack->id != current_stack->id)) { \
         /* The stack pointer is now in another stack.  Update the current */ \
         /* stack information and return without doing anything else. */ \
         current_stack = new_stack;                                     \
         EDEBUG("new current_stack  %p-%p %lu \n",                      \
                (void *) current_stack->start,                          \
                (void *) current_stack->end,                            \
                current_stack->id);                                     \
         return;                                                        \
      } else                                                            \
         EDEBUG("new current_stack not found\n");                       \
   }

#define IF_BIG_DELTA_complaints_AND_RETURN                              \
   if (UNLIKELY(delta < -VG_(clo_max_stackframe)                        \
                || VG_(clo_max_stackframe) < delta)) {                  \
      complaints_stack_switch(old_SP, new_SP);                          \
      return;                                                           \
   }

#define IF_SMALLER_STACK_die_mem_stack_AND_RETURN                       \
   if (delta > 0) {                                                     \
      VG_TRACK( die_mem_stack, old_SP,  delta );                        \
      return;                                                           \
   }

  
VG_REGPARM(3)
void VG_(unknown_SP_update_w_ECU)( Addr old_SP, Addr new_SP, UInt ecu ) {
   IF_STACK_SWITCH_SET_current_stack_AND_RETURN;
   IF_BIG_DELTA_complaints_AND_RETURN;
   IF_SMALLER_STACK_die_mem_stack_AND_RETURN;
   if (delta < 0) { // IF_BIGGER_STACK
      VG_TRACK( new_mem_stack_w_ECU, new_SP, -delta, ecu );
      return;
   }
   // SAME_STACK. nothing to do.
}

VG_REGPARM(2)
void VG_(unknown_SP_update)( Addr old_SP, Addr new_SP ) {
   IF_STACK_SWITCH_SET_current_stack_AND_RETURN;
   IF_BIG_DELTA_complaints_AND_RETURN;
   IF_SMALLER_STACK_die_mem_stack_AND_RETURN;
   if (delta < 0) { // IF_BIGGER_STACK
      VG_TRACK( new_mem_stack,      new_SP, -delta );
      return;
   }
   // SAME_STACK. nothing to do.
}

/*--------------------------------------------------------------------*/
/*--- end                                                          ---*/
/*--------------------------------------------------------------------*/

