source: rtems/c/src/exec/score/src/heapallocate.c @ 66fedb46

4.104.114.84.95
Last change on this file since 66fedb46 was 66fedb46, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 28, 2000 at 9:47:39 PM

2000-11-28 Chris Johns <ccj@…>

  • src/heapallocate.c: Do not allow the size to overflow when adjusting it. A test allocated a stack of -1 (~0). This actually resulted in a stack being allocated but with a size of 0xb. The allocator did not test the size to see if it rolled through 0 and so allowed the allocation to happen, the thread to get created. The task crashed as you would expect.
  • Property mode set to 100644
File size: 3.0 KB
Line 
1/*
2 *  Heap Handler
3 *
4 *  COPYRIGHT (c) 1989-1999.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.OARcorp.com/rtems/license.html.
10 *
11 *  $Id$
12 */
13
14
15#include <rtems/system.h>
16#include <rtems/score/sysstate.h>
17#include <rtems/score/heap.h>
18
19/*PAGE
20 *
21 *  _Heap_Allocate
22 *
23 *  This kernel routine allocates the requested size of memory
24 *  from the specified heap.
25 *
26 *  Input parameters:
27 *    the_heap  - pointer to heap header.
28 *    size      - size in bytes of the memory block to allocate.
29 *
30 *  Output parameters:
31 *    returns - starting address of memory block allocated
32 */
33
34void *_Heap_Allocate(
35  Heap_Control        *the_heap,
36  unsigned32           size
37)
38{
39  unsigned32  excess;
40  unsigned32  the_size;
41  Heap_Block *the_block;
42  Heap_Block *next_block;
43  Heap_Block *temporary_block;
44  void       *ptr;
45  unsigned32  offset;
46
47  /*
48   * Catch the case of a user allocating close to the limit of the
49   * unsigned32.
50   */
51
52  if ( size >= (-1 - HEAP_BLOCK_USED_OVERHEAD) )
53    return( NULL );
54
55  excess   = size % the_heap->page_size;
56  the_size = size + the_heap->page_size + HEAP_BLOCK_USED_OVERHEAD;
57 
58  if ( excess )
59    the_size += the_heap->page_size - excess;
60
61  if ( the_size < sizeof( Heap_Block ) )
62    the_size = sizeof( Heap_Block );
63
64  for ( the_block = the_heap->first;
65        ;
66        the_block = the_block->next ) {
67    if ( the_block == _Heap_Tail( the_heap ) )
68      return( NULL );
69    if ( the_block->front_flag >= the_size )
70      break;
71  }
72
73  if ( (the_block->front_flag - the_size) >
74       (the_heap->page_size + HEAP_BLOCK_USED_OVERHEAD) ) {
75    the_block->front_flag -= the_size;
76    next_block             = _Heap_Next_block( the_block );
77    next_block->back_flag  = the_block->front_flag;
78
79    temporary_block            = _Heap_Block_at( next_block, the_size );
80    temporary_block->back_flag =
81    next_block->front_flag     = _Heap_Build_flag( the_size,
82                                    HEAP_BLOCK_USED );
83    ptr = _Heap_Start_of_user_area( next_block );
84  } else {
85    next_block                = _Heap_Next_block( the_block );
86    next_block->back_flag     = _Heap_Build_flag( the_block->front_flag,
87                                   HEAP_BLOCK_USED );
88    the_block->front_flag     = next_block->back_flag;
89    the_block->next->previous = the_block->previous;
90    the_block->previous->next = the_block->next;
91    ptr = _Heap_Start_of_user_area( the_block );
92  }
93 
94  /*
95   * round ptr up to a multiple of page size
96   * Have to save the bump amount in the buffer so that free can figure it out
97   */
98 
99  offset = the_heap->page_size - (((unsigned32) ptr) & (the_heap->page_size - 1));
100  ptr = _Addresses_Add_offset( ptr, offset );
101  *(((unsigned32 *) ptr) - 1) = offset;
102
103#ifdef RTEMS_DEBUG
104  {
105      unsigned32 ptr_u32;
106      ptr_u32 = (unsigned32) ptr;
107      if (ptr_u32 & (the_heap->page_size - 1))
108          abort();
109  }
110#endif
111
112  return ptr;
113}
114
Note: See TracBrowser for help on using the repository browser.