fix typo in changelog
[debian/sudo] / alloca.c
1 /* alloca.c -- allocate automatically reclaimed memory
2    (Mostly) portable public-domain implementation -- D A Gwyn
3
4    This implementation of the PWB library alloca function,
5    which is used to allocate space off the run-time stack so
6    that it is automatically reclaimed upon procedure exit,
7    was inspired by discussions with J. Q. Johnson of Cornell.
8    J.Otto Tennant <jot@cray.com> contributed the Cray support.
9
10    There are some preprocessor constants that can
11    be defined when compiling for your specific system, for
12    improved efficiency; however, the defaults should be okay.
13
14    The general concept of this implementation is to keep
15    track of all alloca-allocated blocks, and reclaim any
16    that are found to be deeper in the stack than the current
17    invocation.  This heuristic does not reclaim storage as
18    soon as it becomes invalid, but it will do so eventually.
19
20    As a special case, alloca(0) reclaims storage without
21    allocating any.  It is a good idea to use alloca(0) in
22    your main control loop, etc. to force garbage collection.  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 /* If compiling with GCC 2, this file's not needed.  */
29 #if !defined (__GNUC__) || __GNUC__ < 2
30
31 /* If someone has defined alloca as a macro,
32    there must be some other way alloca is supposed to work.  */
33 #ifndef alloca
34
35 /* If your stack is a linked list of frames, you have to
36    provide an "address metric" ADDRESS_FUNCTION macro.  */
37
38 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
39 long i00afunc ();
40 #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
41 #else
42 #define ADDRESS_FUNCTION(arg) &(arg)
43 #endif
44
45 #if __STDC__
46 typedef void *pointer;
47 #else
48 typedef char *pointer;
49 #endif
50
51 #ifndef NULL
52 #define NULL    0
53 #endif
54
55 extern pointer malloc ();
56
57 /* Define STACK_DIRECTION if you know the direction of stack
58    growth for your system; otherwise it will be automatically
59    deduced at run-time.
60
61    STACK_DIRECTION > 0 => grows toward higher addresses
62    STACK_DIRECTION < 0 => grows toward lower addresses
63    STACK_DIRECTION = 0 => direction of growth unknown  */
64
65 #ifndef STACK_DIRECTION
66 #define STACK_DIRECTION 0       /* Direction unknown.  */
67 #endif
68
69 #if STACK_DIRECTION != 0
70
71 #define STACK_DIR       STACK_DIRECTION /* Known at compile-time.  */
72
73 #else /* STACK_DIRECTION == 0; need run-time code.  */
74
75 static int stack_dir;           /* 1 or -1 once known.  */
76 #define STACK_DIR       stack_dir
77
78 static void
79 find_stack_direction ()
80 {
81   static char *addr = NULL;     /* Address of first `dummy', once known.  */
82   auto char dummy;              /* To get stack address.  */
83
84   if (addr == NULL)
85     {                           /* Initial entry.  */
86       addr = ADDRESS_FUNCTION (dummy);
87
88       find_stack_direction ();  /* Recurse once.  */
89     }
90   else
91     {
92       /* Second entry.  */
93       if (ADDRESS_FUNCTION (dummy) > addr)
94         stack_dir = 1;          /* Stack grew upward.  */
95       else
96         stack_dir = -1;         /* Stack grew downward.  */
97     }
98 }
99
100 #endif /* STACK_DIRECTION == 0 */
101
102 /* An "alloca header" is used to:
103    (a) chain together all alloca'ed blocks;
104    (b) keep track of stack depth.
105
106    It is very important that sizeof(header) agree with malloc
107    alignment chunk size.  The following default should work okay.  */
108
109 #ifndef ALIGN_SIZE
110 #define ALIGN_SIZE      sizeof(double)
111 #endif
112
113 typedef union hdr
114 {
115   char align[ALIGN_SIZE];       /* To force sizeof(header).  */
116   struct
117     {
118       union hdr *next;          /* For chaining headers.  */
119       char *deep;               /* For stack depth measure.  */
120     } h;
121 } header;
122
123 static header *last_alloca_header = NULL;       /* -> last alloca header.  */
124
125 /* Return a pointer to at least SIZE bytes of storage,
126    which will be automatically reclaimed upon exit from
127    the procedure that called alloca.  Originally, this space
128    was supposed to be taken from the current stack frame of the
129    caller, but that method cannot be made to work for some
130    implementations of C, for example under Gould's UTX/32.  */
131
132 pointer
133 alloca (size)
134      unsigned size;
135 {
136   auto char probe;              /* Probes stack depth: */
137   register char *depth = ADDRESS_FUNCTION (probe);
138
139 #if STACK_DIRECTION == 0
140   if (STACK_DIR == 0)           /* Unknown growth direction.  */
141     find_stack_direction ();
142 #endif
143
144   /* Reclaim garbage, defined as all alloca'd storage that
145      was allocated from deeper in the stack than currently. */
146
147   {
148     register header *hp;        /* Traverses linked list.  */
149
150     for (hp = last_alloca_header; hp != NULL;)
151       if ((STACK_DIR > 0 && hp->h.deep > depth)
152           || (STACK_DIR < 0 && hp->h.deep < depth))
153         {
154           register header *np = hp->h.next;
155
156           free ((pointer) hp);  /* Collect garbage.  */
157
158           hp = np;              /* -> next header.  */
159         }
160       else
161         break;                  /* Rest are not deeper.  */
162
163     last_alloca_header = hp;    /* -> last valid storage.  */
164   }
165
166   if (size == 0)
167     return NULL;                /* No allocation required.  */
168
169   /* Allocate combined header + user data storage.  */
170
171   {
172     register pointer new = malloc (sizeof (header) + size);
173     /* Address of header.  */
174
175     ((header *) new)->h.next = last_alloca_header;
176     ((header *) new)->h.deep = depth;
177
178     last_alloca_header = (header *) new;
179
180     /* User storage begins just after header.  */
181
182     return (pointer) ((char *) new + sizeof (header));
183   }
184 }
185
186 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
187
188 #ifdef DEBUG_I00AFUNC
189 #include <stdio.h>
190 #endif
191
192 #ifndef CRAY_STACK
193 #define CRAY_STACK
194 #ifndef CRAY2
195 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
196 struct stack_control_header
197   {
198     long shgrow:32;             /* Number of times stack has grown.  */
199     long shaseg:32;             /* Size of increments to stack.  */
200     long shhwm:32;              /* High water mark of stack.  */
201     long shsize:32;             /* Current size of stack (all segments).  */
202   };
203
204 /* The stack segment linkage control information occurs at
205    the high-address end of a stack segment.  (The stack
206    grows from low addresses to high addresses.)  The initial
207    part of the stack segment linkage control information is
208    0200 (octal) words.  This provides for register storage
209    for the routine which overflows the stack.  */
210
211 struct stack_segment_linkage
212   {
213     long ss[0200];              /* 0200 overflow words.  */
214     long sssize:32;             /* Number of words in this segment.  */
215     long ssbase:32;             /* Offset to stack base.  */
216     long:32;
217     long sspseg:32;             /* Offset to linkage control of previous
218                                    segment of stack.  */
219     long:32;
220     long sstcpt:32;             /* Pointer to task common address block.  */
221     long sscsnm;                /* Private control structure number for
222                                    microtasking.  */
223     long ssusr1;                /* Reserved for user.  */
224     long ssusr2;                /* Reserved for user.  */
225     long sstpid;                /* Process ID for pid based multi-tasking.  */
226     long ssgvup;                /* Pointer to multitasking thread giveup.  */
227     long sscray[7];             /* Reserved for Cray Research.  */
228     long ssa0;
229     long ssa1;
230     long ssa2;
231     long ssa3;
232     long ssa4;
233     long ssa5;
234     long ssa6;
235     long ssa7;
236     long sss0;
237     long sss1;
238     long sss2;
239     long sss3;
240     long sss4;
241     long sss5;
242     long sss6;
243     long sss7;
244   };
245
246 #else /* CRAY2 */
247 /* The following structure defines the vector of words
248    returned by the STKSTAT library routine.  */
249 struct stk_stat
250   {
251     long now;                   /* Current total stack size.  */
252     long maxc;                  /* Amount of contiguous space which would
253                                    be required to satisfy the maximum
254                                    stack demand to date.  */
255     long high_water;            /* Stack high-water mark.  */
256     long overflows;             /* Number of stack overflow ($STKOFEN) calls.  */
257     long hits;                  /* Number of internal buffer hits.  */
258     long extends;               /* Number of block extensions.  */
259     long stko_mallocs;          /* Block allocations by $STKOFEN.  */
260     long underflows;            /* Number of stack underflow calls ($STKRETN).  */
261     long stko_free;             /* Number of deallocations by $STKRETN.  */
262     long stkm_free;             /* Number of deallocations by $STKMRET.  */
263     long segments;              /* Current number of stack segments.  */
264     long maxs;                  /* Maximum number of stack segments so far.  */
265     long pad_size;              /* Stack pad size.  */
266     long current_address;       /* Current stack segment address.  */
267     long current_size;          /* Current stack segment size.  This
268                                    number is actually corrupted by STKSTAT to
269                                    include the fifteen word trailer area.  */
270     long initial_address;       /* Address of initial segment.  */
271     long initial_size;          /* Size of initial segment.  */
272   };
273
274 /* The following structure describes the data structure which trails
275    any stack segment.  I think that the description in 'asdef' is
276    out of date.  I only describe the parts that I am sure about.  */
277
278 struct stk_trailer
279   {
280     long this_address;          /* Address of this block.  */
281     long this_size;             /* Size of this block (does not include
282                                    this trailer).  */
283     long unknown2;
284     long unknown3;
285     long link;                  /* Address of trailer block of previous
286                                    segment.  */
287     long unknown5;
288     long unknown6;
289     long unknown7;
290     long unknown8;
291     long unknown9;
292     long unknown10;
293     long unknown11;
294     long unknown12;
295     long unknown13;
296     long unknown14;
297   };
298
299 #endif /* CRAY2 */
300 #endif /* not CRAY_STACK */
301
302 #ifdef CRAY2
303 /* Determine a "stack measure" for an arbitrary ADDRESS.
304    I doubt that "lint" will like this much. */
305
306 static long
307 i00afunc (address)
308      long *address;
309 {
310   struct stk_stat status;
311   struct stk_trailer *trailer;
312   long *block, size;
313   long result = 0;
314
315   /* We want to iterate through all of the segments.  The first
316      step is to get the stack status structure.  We could do this
317      more quickly and more directly, perhaps, by referencing the
318      $LM00 common block, but I know that this works.  */
319
320   STKSTAT (&status);
321
322   /* Set up the iteration.  */
323
324   trailer = (struct stk_trailer *) (status.current_address
325                                     + status.current_size
326                                     - 15);
327
328   /* There must be at least one stack segment.  Therefore it is
329      a fatal error if "trailer" is null.  */
330
331   if (trailer == 0)
332     abort ();
333
334   /* Discard segments that do not contain our argument address.  */
335
336   while (trailer != 0)
337     {
338       block = (long *) trailer->this_address;
339       size = trailer->this_size;
340       if (block == 0 || size == 0)
341         abort ();
342       trailer = (struct stk_trailer *) trailer->link;
343       if ((block <= address) && (address < (block + size)))
344         break;
345     }
346
347   /* Set the result to the offset in this segment and add the sizes
348      of all predecessor segments.  */
349
350   result = address - block;
351
352   if (trailer == 0)
353     {
354       return result;
355     }
356
357   do
358     {
359       if (trailer->this_size <= 0)
360         abort ();
361       result += trailer->this_size;
362       trailer = (struct stk_trailer *) trailer->link;
363     }
364   while (trailer != 0);
365
366   /* We are done.  Note that if you present a bogus address (one
367      not in any segment), you will get a different number back, formed
368      from subtracting the address of the first block.  This is probably
369      not what you want.  */
370
371   return (result);
372 }
373
374 #else /* not CRAY2 */
375 /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
376    Determine the number of the cell within the stack,
377    given the address of the cell.  The purpose of this
378    routine is to linearize, in some sense, stack addresses
379    for alloca.  */
380
381 static long
382 i00afunc (address)
383      long address;
384 {
385   long stkl = 0;
386
387   long size, pseg, this_segment, stack;
388   long result = 0;
389
390   struct stack_segment_linkage *ssptr;
391
392   /* Register B67 contains the address of the end of the
393      current stack segment.  If you (as a subprogram) store
394      your registers on the stack and find that you are past
395      the contents of B67, you have overflowed the segment.
396
397      B67 also points to the stack segment linkage control
398      area, which is what we are really interested in.  */
399
400   stkl = CRAY_STACKSEG_END ();
401   ssptr = (struct stack_segment_linkage *) stkl;
402
403   /* If one subtracts 'size' from the end of the segment,
404      one has the address of the first word of the segment.
405
406      If this is not the first segment, 'pseg' will be
407      nonzero.  */
408
409   pseg = ssptr->sspseg;
410   size = ssptr->sssize;
411
412   this_segment = stkl - size;
413
414   /* It is possible that calling this routine itself caused
415      a stack overflow.  Discard stack segments which do not
416      contain the target address.  */
417
418   while (!(this_segment <= address && address <= stkl))
419     {
420 #ifdef DEBUG_I00AFUNC
421       fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
422 #endif
423       if (pseg == 0)
424         break;
425       stkl = stkl - pseg;
426       ssptr = (struct stack_segment_linkage *) stkl;
427       size = ssptr->sssize;
428       pseg = ssptr->sspseg;
429       this_segment = stkl - size;
430     }
431
432   result = address - this_segment;
433
434   /* If you subtract pseg from the current end of the stack,
435      you get the address of the previous stack segment's end.
436      This seems a little convoluted to me, but I'll bet you save
437      a cycle somewhere.  */
438
439   while (pseg != 0)
440     {
441 #ifdef DEBUG_I00AFUNC
442       fprintf (stderr, "%011o %011o\n", pseg, size);
443 #endif
444       stkl = stkl - pseg;
445       ssptr = (struct stack_segment_linkage *) stkl;
446       size = ssptr->sssize;
447       pseg = ssptr->sspseg;
448       result += size;
449     }
450   return (result);
451 }
452
453 #endif /* not CRAY2 */
454 #endif /* CRAY */
455
456 #endif /* no alloca */
457 #endif /* not GCC version 2 */