Change all files that I own to use the official DragonFly Project
[dragonfly.git] / contrib / gcc / libgcc2.c
1 /* More subroutines needed by GCC output code on some machines.  */
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 /* $FreeBSD: src/contrib/gcc/libgcc2.c,v 1.4 1999/10/27 09:45:47 obrien Exp $ */
30 /* $DragonFly: src/contrib/gcc/Attic/libgcc2.c,v 1.3 2003/12/10 22:25:04 dillon Exp $ */
31
32 /* It is incorrect to include config.h here, because this file is being
33    compiled for the target, and hence definitions concerning only the host
34    do not apply.  */
35
36 #include "tconfig.h"
37
38 /* We disable this when inhibit_libc, so that gcc can still be built without
39    needing header files first.  */
40 /* ??? This is not a good solution, since prototypes may be required in
41    some cases for correct code.  See also frame.c.  */
42 #ifndef inhibit_libc
43 /* fixproto guarantees these system headers exist. */
44 #include <stdlib.h>
45 #include <unistd.h>
46 #endif
47
48 #include "machmode.h"
49 #include "defaults.h" 
50 #ifndef L_trampoline
51 #include <stddef.h>
52 #endif
53
54 /* Don't use `fancy_abort' here even if config.h says to use it.  */
55 #ifdef abort
56 #undef abort
57 #endif
58
59 #if (SUPPORTS_WEAK == 1) && (defined (ASM_OUTPUT_DEF) || defined (ASM_OUTPUT_WEAK_ALIAS))
60 #define WEAK_ALIAS
61 #endif
62
63 /* In a cross-compilation situation, default to inhibiting compilation
64    of routines that use libc.  */
65
66 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
67 #define inhibit_libc
68 #endif
69
70 /* Permit the tm.h file to select the endianness to use just for this
71    file.  This is used when the endianness is determined when the
72    compiler is run.  */
73
74 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
75 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
76 #endif
77
78 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
79 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
80 #endif
81
82 /* In the first part of this file, we are interfacing to calls generated
83    by the compiler itself.  These calls pass values into these routines
84    which have very specific modes (rather than very specific types), and
85    these compiler-generated calls also expect any return values to have
86    very specific modes (rather than very specific types).  Thus, we need
87    to avoid using regular C language type names in this part of the file
88    because the sizes for those types can be configured to be anything.
89    Instead we use the following special type names.  */
90
91 typedef unsigned int UQItype    __attribute__ ((mode (QI)));
92 typedef          int SItype     __attribute__ ((mode (SI)));
93 typedef unsigned int USItype    __attribute__ ((mode (SI)));
94 typedef          int DItype     __attribute__ ((mode (DI)));
95 typedef unsigned int UDItype    __attribute__ ((mode (DI)));
96
97 typedef         float SFtype    __attribute__ ((mode (SF)));
98 typedef         float DFtype    __attribute__ ((mode (DF)));
99
100 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
101 typedef         float XFtype    __attribute__ ((mode (XF)));
102 #endif
103 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
104 typedef         float TFtype    __attribute__ ((mode (TF)));
105 #endif
106
107 typedef int word_type __attribute__ ((mode (__word__)));
108
109 /* Make sure that we don't accidentally use any normal C language built-in
110    type names in the first part of this file.  Instead we want to use *only*
111    the type names defined above.  The following macro definitions insure
112    that if we *do* accidentally use some normal C language built-in type name,
113    we will get a syntax error.  */
114
115 #define char bogus_type
116 #define short bogus_type
117 #define int bogus_type
118 #define long bogus_type
119 #define unsigned bogus_type
120 #define float bogus_type
121 #define double bogus_type
122
123 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
124
125 /* DIstructs are pairs of SItype values in the order determined by
126    LIBGCC2_WORDS_BIG_ENDIAN.  */
127
128 #if LIBGCC2_WORDS_BIG_ENDIAN
129   struct DIstruct {SItype high, low;};
130 #else
131   struct DIstruct {SItype low, high;};
132 #endif
133
134 /* We need this union to unpack/pack DImode values, since we don't have
135    any arithmetic yet.  Incoming DImode parameters are stored into the
136    `ll' field, and the unpacked result is read from the struct `s'.  */
137
138 typedef union
139 {
140   struct DIstruct s;
141   DItype ll;
142 } DIunion;
143
144 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
145      || defined (L_divdi3) || defined (L_udivdi3) \
146      || defined (L_moddi3) || defined (L_umoddi3))
147
148 #include "longlong.h"
149
150 #endif /* udiv or mul */
151
152 extern DItype __fixunssfdi (SFtype a);
153 extern DItype __fixunsdfdi (DFtype a);
154 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
155 extern DItype __fixunsxfdi (XFtype a);
156 #endif
157 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
158 extern DItype __fixunstfdi (TFtype a);
159 #endif
160 \f
161 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
162 #if defined (L_divdi3) || defined (L_moddi3)
163 static inline
164 #endif
165 DItype
166 __negdi2 (DItype u)
167 {
168   DIunion w;
169   DIunion uu;
170
171   uu.ll = u;
172
173   w.s.low = -uu.s.low;
174   w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
175
176   return w.ll;
177 }
178 #endif
179 \f
180 /* Unless shift functions are defined whith full ANSI prototypes,
181    parameter b will be promoted to int if word_type is smaller than an int.  */
182 #ifdef L_lshrdi3
183 DItype
184 __lshrdi3 (DItype u, word_type b)
185 {
186   DIunion w;
187   word_type bm;
188   DIunion uu;
189
190   if (b == 0)
191     return u;
192
193   uu.ll = u;
194
195   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
196   if (bm <= 0)
197     {
198       w.s.high = 0;
199       w.s.low = (USItype)uu.s.high >> -bm;
200     }
201   else
202     {
203       USItype carries = (USItype)uu.s.high << bm;
204       w.s.high = (USItype)uu.s.high >> b;
205       w.s.low = ((USItype)uu.s.low >> b) | carries;
206     }
207
208   return w.ll;
209 }
210 #endif
211
212 #ifdef L_ashldi3
213 DItype
214 __ashldi3 (DItype u, word_type b)
215 {
216   DIunion w;
217   word_type bm;
218   DIunion uu;
219
220   if (b == 0)
221     return u;
222
223   uu.ll = u;
224
225   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
226   if (bm <= 0)
227     {
228       w.s.low = 0;
229       w.s.high = (USItype)uu.s.low << -bm;
230     }
231   else
232     {
233       USItype carries = (USItype)uu.s.low >> bm;
234       w.s.low = (USItype)uu.s.low << b;
235       w.s.high = ((USItype)uu.s.high << b) | carries;
236     }
237
238   return w.ll;
239 }
240 #endif
241
242 #ifdef L_ashrdi3
243 DItype
244 __ashrdi3 (DItype u, word_type b)
245 {
246   DIunion w;
247   word_type bm;
248   DIunion uu;
249
250   if (b == 0)
251     return u;
252
253   uu.ll = u;
254
255   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
256   if (bm <= 0)
257     {
258       /* w.s.high = 1..1 or 0..0 */
259       w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
260       w.s.low = uu.s.high >> -bm;
261     }
262   else
263     {
264       USItype carries = (USItype)uu.s.high << bm;
265       w.s.high = uu.s.high >> b;
266       w.s.low = ((USItype)uu.s.low >> b) | carries;
267     }
268
269   return w.ll;
270 }
271 #endif
272 \f
273 #ifdef L_ffsdi2
274 DItype
275 __ffsdi2 (DItype u)
276 {
277   DIunion uu, w;
278   uu.ll = u;
279   w.s.high = 0;
280   w.s.low = ffs (uu.s.low);
281   if (w.s.low != 0)
282     return w.ll;
283   w.s.low = ffs (uu.s.high);
284   if (w.s.low != 0)
285     {
286       w.s.low += BITS_PER_UNIT * sizeof (SItype);
287       return w.ll;
288     }
289   return w.ll;
290 }
291 #endif
292 \f
293 #ifdef L_muldi3
294 DItype
295 __muldi3 (DItype u, DItype v)
296 {
297   DIunion w;
298   DIunion uu, vv;
299
300   uu.ll = u,
301   vv.ll = v;
302
303   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
304   w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
305                + (USItype) uu.s.high * (USItype) vv.s.low);
306
307   return w.ll;
308 }
309 #endif
310 \f
311 #ifdef L_udiv_w_sdiv
312 #if defined (sdiv_qrnnd)
313 USItype
314 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
315 {
316   USItype q, r;
317   USItype c0, c1, b1;
318
319   if ((SItype) d >= 0)
320     {
321       if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
322         {
323           /* dividend, divisor, and quotient are nonnegative */
324           sdiv_qrnnd (q, r, a1, a0, d);
325         }
326       else
327         {
328           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
329           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
330           /* Divide (c1*2^32 + c0) by d */
331           sdiv_qrnnd (q, r, c1, c0, d);
332           /* Add 2^31 to quotient */
333           q += (USItype) 1 << (SI_TYPE_SIZE - 1);
334         }
335     }
336   else
337     {
338       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
339       c1 = a1 >> 1;                     /* A/2 */
340       c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
341
342       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
343         {
344           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
345
346           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
347           if ((d & 1) != 0)
348             {
349               if (r >= q)
350                 r = r - q;
351               else if (q - r <= d)
352                 {
353                   r = r - q + d;
354                   q--;
355                 }
356               else
357                 {
358                   r = r - q + 2*d;
359                   q -= 2;
360                 }
361             }
362         }
363       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
364         {
365           c1 = (b1 - 1) - c1;
366           c0 = ~c0;                     /* logical NOT */
367
368           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
369
370           q = ~q;                       /* (A/2)/b1 */
371           r = (b1 - 1) - r;
372
373           r = 2*r + (a0 & 1);           /* A/(2*b1) */
374
375           if ((d & 1) != 0)
376             {
377               if (r >= q)
378                 r = r - q;
379               else if (q - r <= d)
380                 {
381                   r = r - q + d;
382                   q--;
383                 }
384               else
385                 {
386                   r = r - q + 2*d;
387                   q -= 2;
388                 }
389             }
390         }
391       else                              /* Implies c1 = b1 */
392         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
393           if (a0 >= -d)
394             {
395               q = -1;
396               r = a0 + d;
397             }
398           else
399             {
400               q = -2;
401               r = a0 + 2*d;
402             }
403         }
404     }
405
406   *rp = r;
407   return q;
408 }
409 #else
410 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
411 USItype
412 __udiv_w_sdiv (USItype *rp __attribute__ ((__unused__)),
413                USItype a1 __attribute__ ((__unused__)),
414                USItype a0 __attribute__ ((__unused__)),
415                USItype d __attribute__ ((__unused__)))
416 {
417   return 0;
418 }
419 #endif
420 #endif
421 \f
422 #if (defined (L_udivdi3) || defined (L_divdi3) || \
423      defined (L_umoddi3) || defined (L_moddi3))
424 #define L_udivmoddi4
425 #endif
426
427 #ifdef L_udivmoddi4
428 static const UQItype __clz_tab[] =
429 {
430   0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
431   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
432   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
433   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
434   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
435   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
436   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
437   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
438 };
439
440 #if (defined (L_udivdi3) || defined (L_divdi3) || \
441      defined (L_umoddi3) || defined (L_moddi3))
442 static inline
443 #endif
444 UDItype
445 __udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
446 {
447   DIunion ww;
448   DIunion nn, dd;
449   DIunion rr;
450   USItype d0, d1, n0, n1, n2;
451   USItype q0, q1;
452   USItype b, bm;
453
454   nn.ll = n;
455   dd.ll = d;
456
457   d0 = dd.s.low;
458   d1 = dd.s.high;
459   n0 = nn.s.low;
460   n1 = nn.s.high;
461
462 #if !UDIV_NEEDS_NORMALIZATION
463   if (d1 == 0)
464     {
465       if (d0 > n1)
466         {
467           /* 0q = nn / 0D */
468
469           udiv_qrnnd (q0, n0, n1, n0, d0);
470           q1 = 0;
471
472           /* Remainder in n0.  */
473         }
474       else
475         {
476           /* qq = NN / 0d */
477
478           if (d0 == 0)
479             d0 = 1 / d0;        /* Divide intentionally by zero.  */
480
481           udiv_qrnnd (q1, n1, 0, n1, d0);
482           udiv_qrnnd (q0, n0, n1, n0, d0);
483
484           /* Remainder in n0.  */
485         }
486
487       if (rp != 0)
488         {
489           rr.s.low = n0;
490           rr.s.high = 0;
491           *rp = rr.ll;
492         }
493     }
494
495 #else /* UDIV_NEEDS_NORMALIZATION */
496
497   if (d1 == 0)
498     {
499       if (d0 > n1)
500         {
501           /* 0q = nn / 0D */
502
503           count_leading_zeros (bm, d0);
504
505           if (bm != 0)
506             {
507               /* Normalize, i.e. make the most significant bit of the
508                  denominator set.  */
509
510               d0 = d0 << bm;
511               n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
512               n0 = n0 << bm;
513             }
514
515           udiv_qrnnd (q0, n0, n1, n0, d0);
516           q1 = 0;
517
518           /* Remainder in n0 >> bm.  */
519         }
520       else
521         {
522           /* qq = NN / 0d */
523
524           if (d0 == 0)
525             d0 = 1 / d0;        /* Divide intentionally by zero.  */
526
527           count_leading_zeros (bm, d0);
528
529           if (bm == 0)
530             {
531               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
532                  conclude (the most significant bit of n1 is set) /\ (the
533                  leading quotient digit q1 = 1).
534
535                  This special case is necessary, not an optimization.
536                  (Shifts counts of SI_TYPE_SIZE are undefined.)  */
537
538               n1 -= d0;
539               q1 = 1;
540             }
541           else
542             {
543               /* Normalize.  */
544
545               b = SI_TYPE_SIZE - bm;
546
547               d0 = d0 << bm;
548               n2 = n1 >> b;
549               n1 = (n1 << bm) | (n0 >> b);
550               n0 = n0 << bm;
551
552               udiv_qrnnd (q1, n1, n2, n1, d0);
553             }
554
555           /* n1 != d0...  */
556
557           udiv_qrnnd (q0, n0, n1, n0, d0);
558
559           /* Remainder in n0 >> bm.  */
560         }
561
562       if (rp != 0)
563         {
564           rr.s.low = n0 >> bm;
565           rr.s.high = 0;
566           *rp = rr.ll;
567         }
568     }
569 #endif /* UDIV_NEEDS_NORMALIZATION */
570
571   else
572     {
573       if (d1 > n1)
574         {
575           /* 00 = nn / DD */
576
577           q0 = 0;
578           q1 = 0;
579
580           /* Remainder in n1n0.  */
581           if (rp != 0)
582             {
583               rr.s.low = n0;
584               rr.s.high = n1;
585               *rp = rr.ll;
586             }
587         }
588       else
589         {
590           /* 0q = NN / dd */
591
592           count_leading_zeros (bm, d1);
593           if (bm == 0)
594             {
595               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
596                  conclude (the most significant bit of n1 is set) /\ (the
597                  quotient digit q0 = 0 or 1).
598
599                  This special case is necessary, not an optimization.  */
600
601               /* The condition on the next line takes advantage of that
602                  n1 >= d1 (true due to program flow).  */
603               if (n1 > d1 || n0 >= d0)
604                 {
605                   q0 = 1;
606                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
607                 }
608               else
609                 q0 = 0;
610
611               q1 = 0;
612
613               if (rp != 0)
614                 {
615                   rr.s.low = n0;
616                   rr.s.high = n1;
617                   *rp = rr.ll;
618                 }
619             }
620           else
621             {
622               USItype m1, m0;
623               /* Normalize.  */
624
625               b = SI_TYPE_SIZE - bm;
626
627               d1 = (d1 << bm) | (d0 >> b);
628               d0 = d0 << bm;
629               n2 = n1 >> b;
630               n1 = (n1 << bm) | (n0 >> b);
631               n0 = n0 << bm;
632
633               udiv_qrnnd (q0, n1, n2, n1, d1);
634               umul_ppmm (m1, m0, q0, d0);
635
636               if (m1 > n1 || (m1 == n1 && m0 > n0))
637                 {
638                   q0--;
639                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
640                 }
641
642               q1 = 0;
643
644               /* Remainder in (n1n0 - m1m0) >> bm.  */
645               if (rp != 0)
646                 {
647                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
648                   rr.s.low = (n1 << b) | (n0 >> bm);
649                   rr.s.high = n1 >> bm;
650                   *rp = rr.ll;
651                 }
652             }
653         }
654     }
655
656   ww.s.low = q0;
657   ww.s.high = q1;
658   return ww.ll;
659 }
660 #endif
661
662 #ifdef L_divdi3
663 UDItype __udivmoddi4 ();
664
665 DItype
666 __divdi3 (DItype u, DItype v)
667 {
668   word_type c = 0;
669   DIunion uu, vv;
670   DItype w;
671
672   uu.ll = u;
673   vv.ll = v;
674
675   if (uu.s.high < 0)
676     c = ~c,
677     uu.ll = __negdi2 (uu.ll);
678   if (vv.s.high < 0)
679     c = ~c,
680     vv.ll = __negdi2 (vv.ll);
681
682   w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
683   if (c)
684     w = __negdi2 (w);
685
686   return w;
687 }
688 #endif
689
690 #ifdef L_moddi3
691 UDItype __udivmoddi4 ();
692 DItype
693 __moddi3 (DItype u, DItype v)
694 {
695   word_type c = 0;
696   DIunion uu, vv;
697   DItype w;
698
699   uu.ll = u;
700   vv.ll = v;
701
702   if (uu.s.high < 0)
703     c = ~c,
704     uu.ll = __negdi2 (uu.ll);
705   if (vv.s.high < 0)
706     vv.ll = __negdi2 (vv.ll);
707
708   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
709   if (c)
710     w = __negdi2 (w);
711
712   return w;
713 }
714 #endif
715
716 #ifdef L_umoddi3
717 UDItype __udivmoddi4 ();
718 UDItype
719 __umoddi3 (UDItype u, UDItype v)
720 {
721   UDItype w;
722
723   (void) __udivmoddi4 (u, v, &w);
724
725   return w;
726 }
727 #endif
728
729 #ifdef L_udivdi3
730 UDItype __udivmoddi4 ();
731 UDItype
732 __udivdi3 (UDItype n, UDItype d)
733 {
734   return __udivmoddi4 (n, d, (UDItype *) 0);
735 }
736 #endif
737 \f
738 #ifdef L_cmpdi2
739 word_type
740 __cmpdi2 (DItype a, DItype b)
741 {
742   DIunion au, bu;
743
744   au.ll = a, bu.ll = b;
745
746   if (au.s.high < bu.s.high)
747     return 0;
748   else if (au.s.high > bu.s.high)
749     return 2;
750   if ((USItype) au.s.low < (USItype) bu.s.low)
751     return 0;
752   else if ((USItype) au.s.low > (USItype) bu.s.low)
753     return 2;
754   return 1;
755 }
756 #endif
757
758 #ifdef L_ucmpdi2
759 word_type
760 __ucmpdi2 (DItype a, DItype b)
761 {
762   DIunion au, bu;
763
764   au.ll = a, bu.ll = b;
765
766   if ((USItype) au.s.high < (USItype) bu.s.high)
767     return 0;
768   else if ((USItype) au.s.high > (USItype) bu.s.high)
769     return 2;
770   if ((USItype) au.s.low < (USItype) bu.s.low)
771     return 0;
772   else if ((USItype) au.s.low > (USItype) bu.s.low)
773     return 2;
774   return 1;
775 }
776 #endif
777 \f
778 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
779 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
780 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
781
782 DItype
783 __fixunstfdi (TFtype a)
784 {
785   TFtype b;
786   UDItype v;
787
788   if (a < 0)
789     return 0;
790
791   /* Compute high word of result, as a flonum.  */
792   b = (a / HIGH_WORD_COEFF);
793   /* Convert that to fixed (but not to DItype!),
794      and shift it into the high word.  */
795   v = (USItype) b;
796   v <<= WORD_SIZE;
797   /* Remove high part from the TFtype, leaving the low part as flonum.  */
798   a -= (TFtype)v;
799   /* Convert that to fixed (but not to DItype!) and add it in.
800      Sometimes A comes out negative.  This is significant, since
801      A has more bits than a long int does.  */
802   if (a < 0)
803     v -= (USItype) (- a);
804   else
805     v += (USItype) a;
806   return v;
807 }
808 #endif
809
810 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
811 DItype
812 __fixtfdi (TFtype a)
813 {
814   if (a < 0)
815     return - __fixunstfdi (-a);
816   return __fixunstfdi (a);
817 }
818 #endif
819
820 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
821 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
822 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
823
824 DItype
825 __fixunsxfdi (XFtype a)
826 {
827   XFtype b;
828   UDItype v;
829
830   if (a < 0)
831     return 0;
832
833   /* Compute high word of result, as a flonum.  */
834   b = (a / HIGH_WORD_COEFF);
835   /* Convert that to fixed (but not to DItype!),
836      and shift it into the high word.  */
837   v = (USItype) b;
838   v <<= WORD_SIZE;
839   /* Remove high part from the XFtype, leaving the low part as flonum.  */
840   a -= (XFtype)v;
841   /* Convert that to fixed (but not to DItype!) and add it in.
842      Sometimes A comes out negative.  This is significant, since
843      A has more bits than a long int does.  */
844   if (a < 0)
845     v -= (USItype) (- a);
846   else
847     v += (USItype) a;
848   return v;
849 }
850 #endif
851
852 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
853 DItype
854 __fixxfdi (XFtype a)
855 {
856   if (a < 0)
857     return - __fixunsxfdi (-a);
858   return __fixunsxfdi (a);
859 }
860 #endif
861
862 #ifdef L_fixunsdfdi
863 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
864 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
865
866 DItype
867 __fixunsdfdi (DFtype a)
868 {
869   DFtype b;
870   UDItype v;
871
872   if (a < 0)
873     return 0;
874
875   /* Compute high word of result, as a flonum.  */
876   b = (a / HIGH_WORD_COEFF);
877   /* Convert that to fixed (but not to DItype!),
878      and shift it into the high word.  */
879   v = (USItype) b;
880   v <<= WORD_SIZE;
881   /* Remove high part from the DFtype, leaving the low part as flonum.  */
882   a -= (DFtype)v;
883   /* Convert that to fixed (but not to DItype!) and add it in.
884      Sometimes A comes out negative.  This is significant, since
885      A has more bits than a long int does.  */
886   if (a < 0)
887     v -= (USItype) (- a);
888   else
889     v += (USItype) a;
890   return v;
891 }
892 #endif
893
894 #ifdef L_fixdfdi
895 DItype
896 __fixdfdi (DFtype a)
897 {
898   if (a < 0)
899     return - __fixunsdfdi (-a);
900   return __fixunsdfdi (a);
901 }
902 #endif
903
904 #ifdef L_fixunssfdi
905 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
906 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
907
908 DItype
909 __fixunssfdi (SFtype original_a)
910 {
911   /* Convert the SFtype to a DFtype, because that is surely not going
912      to lose any bits.  Some day someone else can write a faster version
913      that avoids converting to DFtype, and verify it really works right.  */
914   DFtype a = original_a;
915   DFtype b;
916   UDItype v;
917
918   if (a < 0)
919     return 0;
920
921   /* Compute high word of result, as a flonum.  */
922   b = (a / HIGH_WORD_COEFF);
923   /* Convert that to fixed (but not to DItype!),
924      and shift it into the high word.  */
925   v = (USItype) b;
926   v <<= WORD_SIZE;
927   /* Remove high part from the DFtype, leaving the low part as flonum.  */
928   a -= (DFtype)v;
929   /* Convert that to fixed (but not to DItype!) and add it in.
930      Sometimes A comes out negative.  This is significant, since
931      A has more bits than a long int does.  */
932   if (a < 0)
933     v -= (USItype) (- a);
934   else
935     v += (USItype) a;
936   return v;
937 }
938 #endif
939
940 #ifdef L_fixsfdi
941 DItype
942 __fixsfdi (SFtype a)
943 {
944   if (a < 0)
945     return - __fixunssfdi (-a);
946   return __fixunssfdi (a);
947 }
948 #endif
949
950 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
951 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
952 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
953 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
954
955 XFtype
956 __floatdixf (DItype u)
957 {
958   XFtype d;
959
960   d = (SItype) (u >> WORD_SIZE);
961   d *= HIGH_HALFWORD_COEFF;
962   d *= HIGH_HALFWORD_COEFF;
963   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
964
965   return d;
966 }
967 #endif
968
969 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
970 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
971 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
972 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
973
974 TFtype
975 __floatditf (DItype u)
976 {
977   TFtype d;
978
979   d = (SItype) (u >> WORD_SIZE);
980   d *= HIGH_HALFWORD_COEFF;
981   d *= HIGH_HALFWORD_COEFF;
982   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
983
984   return d;
985 }
986 #endif
987
988 #ifdef L_floatdidf
989 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
990 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
991 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
992
993 DFtype
994 __floatdidf (DItype u)
995 {
996   DFtype d;
997
998   d = (SItype) (u >> WORD_SIZE);
999   d *= HIGH_HALFWORD_COEFF;
1000   d *= HIGH_HALFWORD_COEFF;
1001   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1002
1003   return d;
1004 }
1005 #endif
1006
1007 #ifdef L_floatdisf
1008 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1009 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1010 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1011 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1012
1013 /* Define codes for all the float formats that we know of.  Note
1014    that this is copied from real.h.  */
1015    
1016 #define UNKNOWN_FLOAT_FORMAT 0
1017 #define IEEE_FLOAT_FORMAT 1
1018 #define VAX_FLOAT_FORMAT 2
1019 #define IBM_FLOAT_FORMAT 3
1020
1021 /* Default to IEEE float if not specified.  Nearly all machines use it.  */
1022 #ifndef HOST_FLOAT_FORMAT
1023 #define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1024 #endif
1025
1026 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1027 #define DF_SIZE 53
1028 #define SF_SIZE 24
1029 #endif
1030
1031 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1032 #define DF_SIZE 56
1033 #define SF_SIZE 24
1034 #endif
1035
1036 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1037 #define DF_SIZE 56
1038 #define SF_SIZE 24
1039 #endif
1040
1041 SFtype
1042 __floatdisf (DItype u)
1043 {
1044   /* Do the calculation in DFmode
1045      so that we don't lose any of the precision of the high word
1046      while multiplying it.  */
1047   DFtype f;
1048
1049   /* Protect against double-rounding error.
1050      Represent any low-order bits, that might be truncated in DFmode,
1051      by a bit that won't be lost.  The bit can go in anywhere below the
1052      rounding position of the SFmode.  A fixed mask and bit position
1053      handles all usual configurations.  It doesn't handle the case
1054      of 128-bit DImode, however.  */
1055   if (DF_SIZE < DI_SIZE
1056       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1057     {
1058 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1059       if (! (- ((DItype) 1 << DF_SIZE) < u
1060              && u < ((DItype) 1 << DF_SIZE)))
1061         {
1062           if ((USItype) u & (REP_BIT - 1))
1063             u |= REP_BIT;
1064         }
1065     }
1066   f = (SItype) (u >> WORD_SIZE);
1067   f *= HIGH_HALFWORD_COEFF;
1068   f *= HIGH_HALFWORD_COEFF;
1069   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1070
1071   return (SFtype) f;
1072 }
1073 #endif
1074
1075 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1076 /* Reenable the normal types, in case limits.h needs them.  */
1077 #undef char
1078 #undef short
1079 #undef int
1080 #undef long
1081 #undef unsigned
1082 #undef float
1083 #undef double
1084 #undef MIN
1085 #undef MAX
1086 #include <limits.h>
1087
1088 USItype
1089 __fixunsxfsi (XFtype a)
1090 {
1091   if (a >= - (DFtype) LONG_MIN)
1092     return (SItype) (a + LONG_MIN) - LONG_MIN;
1093   return (SItype) a;
1094 }
1095 #endif
1096
1097 #ifdef L_fixunsdfsi
1098 /* Reenable the normal types, in case limits.h needs them.  */
1099 #undef char
1100 #undef short
1101 #undef int
1102 #undef long
1103 #undef unsigned
1104 #undef float
1105 #undef double
1106 #undef MIN
1107 #undef MAX
1108 #include <limits.h>
1109
1110 USItype
1111 __fixunsdfsi (DFtype a)
1112 {
1113   if (a >= - (DFtype) LONG_MIN)
1114     return (SItype) (a + LONG_MIN) - LONG_MIN;
1115   return (SItype) a;
1116 }
1117 #endif
1118
1119 #ifdef L_fixunssfsi
1120 /* Reenable the normal types, in case limits.h needs them.  */
1121 #undef char
1122 #undef short
1123 #undef int
1124 #undef long
1125 #undef unsigned
1126 #undef float
1127 #undef double
1128 #undef MIN
1129 #undef MAX
1130 #include <limits.h>
1131
1132 USItype
1133 __fixunssfsi (SFtype a)
1134 {
1135   if (a >= - (SFtype) LONG_MIN)
1136     return (SItype) (a + LONG_MIN) - LONG_MIN;
1137   return (SItype) a;
1138 }
1139 #endif
1140 \f
1141 /* From here on down, the routines use normal data types.  */
1142
1143 #define SItype bogus_type
1144 #define USItype bogus_type
1145 #define DItype bogus_type
1146 #define UDItype bogus_type
1147 #define SFtype bogus_type
1148 #define DFtype bogus_type
1149
1150 #undef char
1151 #undef short
1152 #undef int
1153 #undef long
1154 #undef unsigned
1155 #undef float
1156 #undef double
1157 \f
1158 #ifdef L__gcc_bcmp
1159
1160 /* Like bcmp except the sign is meaningful.
1161    Result is negative if S1 is less than S2,
1162    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1163
1164 int
1165 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1166 {
1167   while (size > 0)
1168     {
1169       unsigned char c1 = *s1++, c2 = *s2++;
1170       if (c1 != c2)
1171         return c1 - c2;
1172       size--;
1173     }
1174   return 0;
1175 }
1176
1177 #endif
1178 \f\f
1179 #ifdef L__dummy
1180 void
1181 __dummy () {}
1182 #endif
1183
1184 #ifdef L_varargs
1185 #ifdef __i860__
1186 #if defined(__svr4__) || defined(__alliant__)
1187         asm ("  .text");
1188         asm ("  .align  4");
1189
1190 /* The Alliant needs the added underscore.  */
1191         asm (".globl    __builtin_saveregs");
1192 asm ("__builtin_saveregs:");
1193         asm (".globl    ___builtin_saveregs");
1194 asm ("___builtin_saveregs:");
1195
1196         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1197         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1198                                            area and also for a new va_list
1199                                            structure */
1200         /* Save all argument registers in the arg reg save area.  The
1201            arg reg save area must have the following layout (according
1202            to the svr4 ABI):
1203
1204                 struct {
1205                   union  {
1206                     float freg[8];
1207                     double dreg[4];
1208                   } float_regs;
1209                   long  ireg[12];
1210                 };
1211         */
1212
1213         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1214         asm ("  fst.q   %f12,16(%sp)"); 
1215
1216         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1217         asm ("  st.l    %r17,36(%sp)"); 
1218         asm ("  st.l    %r18,40(%sp)");
1219         asm ("  st.l    %r19,44(%sp)");
1220         asm ("  st.l    %r20,48(%sp)");
1221         asm ("  st.l    %r21,52(%sp)");
1222         asm ("  st.l    %r22,56(%sp)");
1223         asm ("  st.l    %r23,60(%sp)");
1224         asm ("  st.l    %r24,64(%sp)");
1225         asm ("  st.l    %r25,68(%sp)");
1226         asm ("  st.l    %r26,72(%sp)");
1227         asm ("  st.l    %r27,76(%sp)");
1228
1229         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1230                                            va_list structure.  Put in into
1231                                            r16 so that it will be returned
1232                                            to the caller.  */
1233
1234         /* Initialize all fields of the new va_list structure.  This
1235            structure looks like:
1236
1237                 typedef struct {
1238                     unsigned long       ireg_used;
1239                     unsigned long       freg_used;
1240                     long                *reg_base;
1241                     long                *mem_ptr;
1242                 } va_list;
1243         */
1244
1245         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1246         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1247         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1248         asm ("  bri     %r1");          /* delayed return */
1249         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1250
1251 #else /* not __svr4__ */
1252 #if defined(__PARAGON__)
1253         /*
1254          *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1255          *      and we stand a better chance of hooking into libraries
1256          *      compiled by PGI.  [andyp@ssd.intel.com]
1257          */
1258         asm ("  .text");
1259         asm ("  .align  4");
1260         asm (".globl    __builtin_saveregs");
1261 asm ("__builtin_saveregs:");
1262         asm (".globl    ___builtin_saveregs");
1263 asm ("___builtin_saveregs:");
1264
1265         asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1266         asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1267                                            area and also for a new va_list
1268                                            structure */
1269         /* Save all argument registers in the arg reg save area.  The
1270            arg reg save area must have the following layout (according
1271            to the svr4 ABI):
1272
1273                 struct {
1274                   union  {
1275                     float freg[8];
1276                     double dreg[4];
1277                   } float_regs;
1278                   long  ireg[12];
1279                 };
1280         */
1281
1282         asm ("  fst.q   f8,  0(sp)");
1283         asm ("  fst.q   f12,16(sp)"); 
1284         asm ("  st.l    r16,32(sp)");
1285         asm ("  st.l    r17,36(sp)"); 
1286         asm ("  st.l    r18,40(sp)");
1287         asm ("  st.l    r19,44(sp)");
1288         asm ("  st.l    r20,48(sp)");
1289         asm ("  st.l    r21,52(sp)");
1290         asm ("  st.l    r22,56(sp)");
1291         asm ("  st.l    r23,60(sp)");
1292         asm ("  st.l    r24,64(sp)");
1293         asm ("  st.l    r25,68(sp)");
1294         asm ("  st.l    r26,72(sp)");
1295         asm ("  st.l    r27,76(sp)");
1296
1297         asm ("  adds    80,sp,r16");  /* compute the address of the new
1298                                            va_list structure.  Put in into
1299                                            r16 so that it will be returned
1300                                            to the caller.  */
1301
1302         /* Initialize all fields of the new va_list structure.  This
1303            structure looks like:
1304
1305                 typedef struct {
1306                     unsigned long       ireg_used;
1307                     unsigned long       freg_used;
1308                     long                *reg_base;
1309                     long                *mem_ptr;
1310                 } va_list;
1311         */
1312
1313         asm ("  st.l    r0, 0(r16)"); /* nfixed */
1314         asm ("  st.l    r0, 4(r16)"); /* nfloating */
1315         asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1316         asm ("  bri     r1");           /* delayed return */
1317         asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1318 #else /* not __PARAGON__ */
1319         asm ("  .text");
1320         asm ("  .align  4");
1321
1322         asm (".globl    ___builtin_saveregs");
1323         asm ("___builtin_saveregs:");
1324         asm ("  mov     sp,r30");
1325         asm ("  andnot  0x0f,sp,sp");
1326         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1327
1328 /* Fill in the __va_struct.  */
1329         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1330         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1331         asm ("  st.l    r18, 8(sp)");
1332         asm ("  st.l    r19,12(sp)");
1333         asm ("  st.l    r20,16(sp)");
1334         asm ("  st.l    r21,20(sp)");
1335         asm ("  st.l    r22,24(sp)");
1336         asm ("  st.l    r23,28(sp)");
1337         asm ("  st.l    r24,32(sp)");
1338         asm ("  st.l    r25,36(sp)");
1339         asm ("  st.l    r26,40(sp)");
1340         asm ("  st.l    r27,44(sp)");
1341
1342         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1343         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1344
1345 /* Fill in the __va_ctl.  */
1346         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1347         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1348         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1349         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1350
1351         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1352         asm ("  bri     r1");
1353         asm ("  mov     r30,sp");
1354                                 /* recover stack and pass address to start 
1355                                    of data.  */
1356 #endif /* not __PARAGON__ */
1357 #endif /* not __svr4__ */
1358 #else /* not __i860__ */
1359 #ifdef __sparc__
1360         asm (".global __builtin_saveregs");
1361         asm ("__builtin_saveregs:");
1362         asm (".global ___builtin_saveregs");
1363         asm ("___builtin_saveregs:");
1364 #ifdef NEED_PROC_COMMAND
1365         asm (".proc 020");
1366 #endif
1367         asm ("st %i0,[%fp+68]");
1368         asm ("st %i1,[%fp+72]");
1369         asm ("st %i2,[%fp+76]");
1370         asm ("st %i3,[%fp+80]");
1371         asm ("st %i4,[%fp+84]");
1372         asm ("retl");
1373         asm ("st %i5,[%fp+88]");
1374 #ifdef NEED_TYPE_COMMAND
1375         asm (".type __builtin_saveregs,#function");
1376         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1377 #endif
1378 #else /* not __sparc__ */
1379 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1380
1381   asm ("        .text");
1382 #ifdef __mips16
1383   asm ("        .set nomips16");
1384 #endif
1385   asm ("        .ent __builtin_saveregs");
1386   asm ("        .globl __builtin_saveregs");
1387   asm ("__builtin_saveregs:");
1388   asm ("        sw      $4,0($30)");
1389   asm ("        sw      $5,4($30)");
1390   asm ("        sw      $6,8($30)");
1391   asm ("        sw      $7,12($30)");
1392   asm ("        j       $31");
1393   asm ("        .end __builtin_saveregs");
1394 #else /* not __mips__, etc.  */
1395
1396 void *
1397 __builtin_saveregs ()
1398 {
1399   abort ();
1400 }
1401
1402 #endif /* not __mips__ */
1403 #endif /* not __sparc__ */
1404 #endif /* not __i860__ */
1405 #endif
1406 \f
1407 #ifdef L_eprintf
1408 #ifndef inhibit_libc
1409
1410 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1411 #include <stdio.h>
1412 /* This is used by the `assert' macro.  */
1413 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1414   __attribute__ ((__noreturn__));
1415
1416 void
1417 __eprintf (const char *string, const char *expression,
1418            unsigned int line, const char *filename)
1419 {
1420   fprintf (stderr, string, expression, line, filename);
1421   fflush (stderr);
1422   abort ();
1423 }
1424
1425 #endif
1426 #endif
1427
1428 #ifdef L_bb
1429
1430 /* Structure emitted by -a  */
1431 struct bb
1432 {
1433   long zero_word;
1434   const char *filename;
1435   long *counts;
1436   long ncounts;
1437   struct bb *next;
1438   const unsigned long *addresses;
1439
1440   /* Older GCC's did not emit these fields.  */
1441   long nwords;
1442   const char **functions;
1443   const long *line_nums;
1444   const char **filenames;
1445   char *flags;
1446 };
1447
1448 #ifdef BLOCK_PROFILER_CODE
1449 BLOCK_PROFILER_CODE
1450 #else
1451 #ifndef inhibit_libc
1452
1453 /* Simple minded basic block profiling output dumper for
1454    systems that don't provide tcov support.  At present,
1455    it requires atexit and stdio.  */
1456
1457 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1458 #include <stdio.h>
1459 char *ctime ();
1460
1461 #include "gbl-ctors.h"
1462 #include "gcov-io.h"
1463 #include <string.h>
1464
1465 static struct bb *bb_head;
1466
1467 /* Return the number of digits needed to print a value */
1468 /* __inline__ */ static int num_digits (long value, int base)
1469 {
1470   int minus = (value < 0 && base != 16);
1471   unsigned long v = (minus) ? -value : value;
1472   int ret = minus;
1473
1474   do
1475     {
1476       v /= base;
1477       ret++;
1478     }
1479   while (v);
1480
1481   return ret;
1482 }
1483
1484 void
1485 __bb_exit_func (void)
1486 {
1487   FILE *da_file, *file;
1488   long time_value;
1489   int i;
1490
1491   if (bb_head == 0)
1492     return;
1493
1494   i = strlen (bb_head->filename) - 3;
1495
1496   if (!strcmp (bb_head->filename+i, ".da"))
1497     {
1498       /* Must be -fprofile-arcs not -a.
1499          Dump data in a form that gcov expects.  */
1500
1501       struct bb *ptr;
1502
1503       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1504         {
1505           /* If the file exists, and the number of counts in it is the same,
1506              then merge them in.  */
1507              
1508           if ((da_file = fopen (ptr->filename, "r")) != 0)
1509             {
1510               long n_counts = 0;
1511               
1512               if (__read_long (&n_counts, da_file, 8) != 0)
1513                 {
1514                   fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1515                            ptr->filename);
1516                   continue;
1517                 }
1518
1519               if (n_counts == ptr->ncounts)
1520                 {
1521                   int i;
1522
1523                   for (i = 0; i < n_counts; i++)
1524                     {
1525                       long v = 0;
1526
1527                       if (__read_long (&v, da_file, 8) != 0)
1528                         {
1529                           fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1530                                    ptr->filename);
1531                           break;
1532                         }
1533                       ptr->counts[i] += v;
1534                     }
1535                 }
1536
1537               if (fclose (da_file) == EOF)
1538                 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1539                          ptr->filename);
1540             }
1541           if ((da_file = fopen (ptr->filename, "w")) == 0)
1542             {
1543               fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1544                        ptr->filename);
1545               continue;
1546             }
1547
1548           /* ??? Should first write a header to the file.  Preferably, a 4 byte
1549              magic number, 4 bytes containing the time the program was
1550              compiled, 4 bytes containing the last modification time of the
1551              source file, and 4 bytes indicating the compiler options used.
1552
1553              That way we can easily verify that the proper source/executable/
1554              data file combination is being used from gcov.  */
1555
1556           if (__write_long (ptr->ncounts, da_file, 8) != 0)
1557             {
1558               
1559               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1560                        ptr->filename);
1561             }
1562           else
1563             {
1564               int j;
1565               long *count_ptr = ptr->counts;
1566               int ret = 0;
1567               for (j = ptr->ncounts; j > 0; j--)
1568                 {
1569                   if (__write_long (*count_ptr, da_file, 8) != 0)
1570                     {
1571                       ret=1;
1572                       break;
1573                     }
1574                   count_ptr++;
1575                 }
1576               if (ret)
1577                 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1578                          ptr->filename);
1579             }
1580           
1581           if (fclose (da_file) == EOF)
1582             fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1583                      ptr->filename);
1584         }
1585
1586       return;
1587     }
1588
1589   /* Must be basic block profiling.  Emit a human readable output file.  */
1590
1591   file = fopen ("bb.out", "a");
1592
1593   if (!file)
1594     perror ("bb.out");
1595
1596   else
1597     {
1598       struct bb *ptr;
1599
1600       /* This is somewhat type incorrect, but it avoids worrying about
1601          exactly where time.h is included from.  It should be ok unless
1602          a void * differs from other pointer formats, or if sizeof (long)
1603          is < sizeof (time_t).  It would be nice if we could assume the
1604          use of rationale standards here.  */
1605
1606       time ((void *) &time_value);
1607       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1608
1609       /* We check the length field explicitly in order to allow compatibility
1610          with older GCC's which did not provide it.  */
1611
1612       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1613         {
1614           int i;
1615           int func_p    = (ptr->nwords >= sizeof (struct bb)
1616                            && ptr->nwords <= 1000
1617                            && ptr->functions);
1618           int line_p    = (func_p && ptr->line_nums);
1619           int file_p    = (func_p && ptr->filenames);
1620           int addr_p    = (ptr->addresses != 0);
1621           long ncounts  = ptr->ncounts;
1622           long cnt_max  = 0;
1623           long line_max = 0;
1624           long addr_max = 0;
1625           int file_len  = 0;
1626           int func_len  = 0;
1627           int blk_len   = num_digits (ncounts, 10);
1628           int cnt_len;
1629           int line_len;
1630           int addr_len;
1631
1632           fprintf (file, "File %s, %ld basic blocks \n\n",
1633                    ptr->filename, ncounts);
1634
1635           /* Get max values for each field.  */
1636           for (i = 0; i < ncounts; i++)
1637             {
1638               const char *p;
1639               int len;
1640
1641               if (cnt_max < ptr->counts[i])
1642                 cnt_max = ptr->counts[i];
1643
1644               if (addr_p && addr_max < ptr->addresses[i])
1645                 addr_max = ptr->addresses[i];
1646
1647               if (line_p && line_max < ptr->line_nums[i])
1648                 line_max = ptr->line_nums[i];
1649
1650               if (func_p)
1651                 {
1652                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1653                   len = strlen (p);
1654                   if (func_len < len)
1655                     func_len = len;
1656                 }
1657
1658               if (file_p)
1659                 {
1660                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1661                   len = strlen (p);
1662                   if (file_len < len)
1663                     file_len = len;
1664                 }
1665             }
1666
1667           addr_len = num_digits (addr_max, 16);
1668           cnt_len  = num_digits (cnt_max, 10);
1669           line_len = num_digits (line_max, 10);
1670
1671           /* Now print out the basic block information.  */
1672           for (i = 0; i < ncounts; i++)
1673             {
1674               fprintf (file,
1675                        "    Block #%*d: executed %*ld time(s)",
1676                        blk_len, i+1,
1677                        cnt_len, ptr->counts[i]);
1678
1679               if (addr_p)
1680                 fprintf (file, " address= 0x%.*lx", addr_len,
1681                          ptr->addresses[i]);
1682
1683               if (func_p)
1684                 fprintf (file, " function= %-*s", func_len,
1685                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1686
1687               if (line_p)
1688                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1689
1690               if (file_p)
1691                 fprintf (file, " file= %s",
1692                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1693
1694               fprintf (file, "\n");
1695             }
1696
1697           fprintf (file, "\n");
1698           fflush (file);
1699         }
1700
1701       fprintf (file, "\n\n");
1702       fclose (file);
1703     }
1704 }
1705
1706 void
1707 __bb_init_func (struct bb *blocks)
1708 {
1709   /* User is supposed to check whether the first word is non-0,
1710      but just in case....  */
1711
1712   if (blocks->zero_word)
1713     return;
1714
1715 #ifdef ON_EXIT
1716   /* Initialize destructor.  */
1717   if (!bb_head)
1718     ON_EXIT (__bb_exit_func, 0);
1719 #endif
1720
1721   /* Set up linked list.  */
1722   blocks->zero_word = 1;
1723   blocks->next = bb_head;
1724   bb_head = blocks;
1725 }
1726
1727 #ifndef MACHINE_STATE_SAVE
1728 #define MACHINE_STATE_SAVE(ID)
1729 #endif
1730 #ifndef MACHINE_STATE_RESTORE
1731 #define MACHINE_STATE_RESTORE(ID)
1732 #endif
1733
1734 /* Number of buckets in hashtable of basic block addresses.  */
1735
1736 #define BB_BUCKETS 311
1737
1738 /* Maximum length of string in file bb.in.  */
1739
1740 #define BBINBUFSIZE 500
1741
1742 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1743    "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
1744
1745 #define BBINBUFSIZESTR "499"
1746
1747 struct bb_edge
1748 {
1749   struct bb_edge *next;
1750   unsigned long src_addr;
1751   unsigned long dst_addr;
1752   unsigned long count;
1753 };
1754
1755 enum bb_func_mode
1756 {
1757   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1758 };
1759
1760 struct bb_func
1761 {
1762   struct bb_func *next;
1763   char *funcname;
1764   char *filename;
1765   enum bb_func_mode mode;
1766 };
1767
1768 /* This is the connection to the outside world.
1769    The BLOCK_PROFILER macro must set __bb.blocks
1770    and __bb.blockno.  */
1771
1772 struct {
1773   unsigned long blockno;
1774   struct bb *blocks;
1775 } __bb;
1776
1777 /* Vars to store addrs of source and destination basic blocks 
1778    of a jump.  */
1779
1780 static unsigned long bb_src = 0;
1781 static unsigned long bb_dst = 0;
1782
1783 static FILE *bb_tracefile = (FILE *) 0;
1784 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1785 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1786 static unsigned long bb_callcount = 0;
1787 static int bb_mode = 0;
1788
1789 static unsigned long *bb_stack = (unsigned long *) 0;
1790 static size_t bb_stacksize = 0;
1791
1792 static int reported = 0;
1793
1794 /* Trace modes:
1795 Always             :   Print execution frequencies of basic blocks
1796                        to file bb.out.
1797 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1798 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1799 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1800 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1801 */
1802
1803 #ifdef HAVE_POPEN
1804
1805 /*#include <sys/types.h>*/
1806 #include <sys/stat.h>
1807 /*#include <malloc.h>*/
1808
1809 /* Commands executed by gopen.  */
1810
1811 #define GOPENDECOMPRESS "gzip -cd "
1812 #define GOPENCOMPRESS "gzip -c >"
1813
1814 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1815    If it does not compile, simply replace gopen by fopen and delete
1816    '.gz' from any first parameter to gopen.  */
1817
1818 static FILE *
1819 gopen (char *fn, char *mode)
1820 {
1821   int use_gzip;
1822   char *p;
1823
1824   if (mode[1])
1825     return (FILE *) 0;
1826
1827   if (mode[0] != 'r' && mode[0] != 'w') 
1828     return (FILE *) 0;
1829
1830   p = fn + strlen (fn)-1;
1831   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1832               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1833
1834   if (use_gzip)
1835     {
1836       if (mode[0]=='r')
1837         {
1838           FILE *f;
1839           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1840                                      + sizeof (GOPENDECOMPRESS));
1841           strcpy (s, GOPENDECOMPRESS);
1842           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1843           f = popen (s, mode);
1844           free (s);
1845           return f;
1846         }
1847
1848       else
1849         {
1850           FILE *f;
1851           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1852                                      + sizeof (GOPENCOMPRESS));
1853           strcpy (s, GOPENCOMPRESS);
1854           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1855           if (!(f = popen (s, mode)))
1856             f = fopen (s, mode);
1857           free (s);
1858           return f;
1859         }
1860     }
1861
1862   else
1863     return fopen (fn, mode);
1864 }
1865
1866 static int
1867 gclose (FILE *f)
1868 {
1869   struct stat buf;
1870
1871   if (f != 0)
1872     {
1873       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1874         return pclose (f);
1875
1876       return fclose (f);
1877     }
1878   return 0;
1879 }
1880
1881 #endif /* HAVE_POPEN */
1882
1883 /* Called once per program.  */
1884
1885 static void
1886 __bb_exit_trace_func ()
1887 {
1888   FILE *file = fopen ("bb.out", "a");
1889   struct bb_func *f;
1890   struct bb *b;
1891         
1892   if (!file)
1893     perror ("bb.out");
1894
1895   if (bb_mode & 1)
1896     {
1897       if (!bb_tracefile)
1898         perror ("bbtrace");
1899       else
1900 #ifdef HAVE_POPEN
1901         gclose (bb_tracefile);
1902 #else
1903         fclose (bb_tracefile);
1904 #endif /* HAVE_POPEN */
1905     }
1906
1907   /* Check functions in `bb.in'.  */
1908
1909   if (file)
1910     {
1911       long time_value;
1912       const struct bb_func *p;
1913       int printed_something = 0;
1914       struct bb *ptr;
1915       long blk;
1916
1917       /* This is somewhat type incorrect.  */
1918       time ((void *) &time_value);
1919
1920       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1921         {
1922           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1923             {
1924               if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
1925                 continue;
1926               for (blk = 0; blk < ptr->ncounts; blk++)
1927                 {
1928                   if (!strcmp (p->funcname, ptr->functions[blk]))
1929                     goto found;
1930                 }
1931             }
1932   
1933           if (!printed_something)
1934             {
1935               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1936               printed_something = 1;
1937             }
1938
1939           fprintf (file, "\tFunction %s", p->funcname);
1940           if (p->filename)
1941               fprintf (file, " of file %s", p->filename);
1942           fprintf (file, "\n" );
1943   
1944 found:        ;
1945         }
1946
1947       if (printed_something)
1948        fprintf (file, "\n");
1949
1950     }
1951
1952   if (bb_mode & 2)
1953     {
1954       if (!bb_hashbuckets)
1955         {
1956           if (!reported)
1957             {
1958               fprintf (stderr, "Profiler: out of memory\n");
1959               reported = 1;
1960             }
1961           return;
1962         }
1963     
1964       else if (file)
1965         {
1966           long time_value;
1967           int i;
1968           unsigned long addr_max = 0;
1969           unsigned long cnt_max  = 0;
1970           int cnt_len;
1971           int addr_len;
1972     
1973           /* This is somewhat type incorrect, but it avoids worrying about
1974              exactly where time.h is included from.  It should be ok unless
1975              a void * differs from other pointer formats, or if sizeof (long)
1976              is < sizeof (time_t).  It would be nice if we could assume the
1977              use of rationale standards here.  */
1978     
1979           time ((void *) &time_value);
1980           fprintf (file, "Basic block jump tracing");
1981
1982           switch (bb_mode & 12)
1983             {
1984               case 0:
1985                 fprintf (file, " (with call)");
1986               break;
1987
1988               case 4:
1989                 /* Print nothing.  */
1990               break;
1991
1992               case 8:
1993                 fprintf (file, " (with call & ret)");
1994               break;
1995
1996               case 12:
1997                 fprintf (file, " (with ret)");
1998               break;
1999             }
2000
2001           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2002     
2003           for (i = 0; i < BB_BUCKETS; i++)
2004             {
2005                struct bb_edge *bucket = bb_hashbuckets[i];
2006                for ( ; bucket; bucket = bucket->next )
2007                  {
2008                    if (addr_max < bucket->src_addr) 
2009                      addr_max = bucket->src_addr;
2010                    if (addr_max < bucket->dst_addr) 
2011                      addr_max = bucket->dst_addr;
2012                    if (cnt_max < bucket->count) 
2013                      cnt_max = bucket->count;
2014                  }
2015             }
2016           addr_len = num_digits (addr_max, 16);
2017           cnt_len  = num_digits (cnt_max, 10);
2018     
2019           for ( i = 0; i < BB_BUCKETS; i++)
2020             {
2021                struct bb_edge *bucket = bb_hashbuckets[i];
2022                for ( ; bucket; bucket = bucket->next )
2023                  {
2024                    fprintf (file, "Jump from block 0x%.*lx to "
2025                                   "block 0x%.*lx executed %*lu time(s)\n", 
2026                             addr_len, bucket->src_addr, 
2027                             addr_len, bucket->dst_addr, 
2028                             cnt_len, bucket->count);
2029                  }
2030             }
2031   
2032           fprintf (file, "\n");
2033
2034         }
2035     }
2036
2037    if (file)
2038      fclose (file);
2039
2040    /* Free allocated memory.  */
2041
2042    f = bb_func_head;
2043    while (f)
2044      {
2045        struct bb_func *old = f;
2046
2047        f = f->next;
2048        if (old->funcname) free (old->funcname);
2049        if (old->filename) free (old->filename);
2050        free (old);
2051      }
2052
2053    if (bb_stack)
2054      free (bb_stack);
2055
2056    if (bb_hashbuckets)
2057      {
2058        int i;
2059
2060        for (i = 0; i < BB_BUCKETS; i++)
2061          {
2062            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2063
2064            while (bucket)
2065              {
2066                old = bucket;
2067                bucket = bucket->next;
2068                free (old);
2069              }
2070          }
2071        free (bb_hashbuckets);
2072      }
2073
2074    for (b = bb_head; b; b = b->next)
2075      if (b->flags) free (b->flags);
2076 }
2077
2078 /* Called once per program.  */
2079
2080 static void
2081 __bb_init_prg ()
2082 {
2083
2084   FILE *file;
2085   char buf[BBINBUFSIZE];
2086   const char *p;
2087   const char *pos;
2088   enum bb_func_mode m;
2089
2090 #ifdef ON_EXIT
2091   /* Initialize destructor.  */
2092   ON_EXIT (__bb_exit_func, 0);
2093 #endif
2094
2095   if (!(file = fopen ("bb.in", "r")))
2096     return;
2097
2098   while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2099     {
2100       p = buf;
2101       if (*p == '-') 
2102         { 
2103           m = TRACE_OFF; 
2104           p++; 
2105         }
2106       else 
2107         { 
2108           m = TRACE_ON; 
2109         }
2110       if (!strcmp (p, "__bb_trace__"))
2111         bb_mode |= 1;
2112       else if (!strcmp (p, "__bb_jumps__"))
2113         bb_mode |= 2;
2114       else if (!strcmp (p, "__bb_hidecall__"))
2115         bb_mode |= 4;
2116       else if (!strcmp (p, "__bb_showret__"))
2117         bb_mode |= 8;
2118       else 
2119         {
2120           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2121           if (f)
2122             {
2123               unsigned long l;
2124               f->next = bb_func_head;
2125               if ((pos = strchr (p, ':')))
2126                 {
2127                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2128                     continue;
2129                   strcpy (f->funcname, pos+1);
2130                   l = pos-p;
2131                   if ((f->filename = (char *) malloc (l+1)))
2132                     {
2133                       strncpy (f->filename, p, l);
2134                       f->filename[l] = '\0';
2135                     }
2136                   else
2137                     f->filename = (char *) 0;
2138                 }
2139               else
2140                 {
2141                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2142                     continue;
2143                   strcpy (f->funcname, p);
2144                   f->filename = (char *) 0;
2145                 }
2146               f->mode = m;
2147               bb_func_head = f;
2148             }
2149          }
2150     }
2151   fclose (file);
2152
2153 #ifdef HAVE_POPEN 
2154
2155   if (bb_mode & 1)
2156       bb_tracefile = gopen ("bbtrace.gz", "w");
2157
2158 #else
2159
2160   if (bb_mode & 1)
2161       bb_tracefile = fopen ("bbtrace", "w");
2162
2163 #endif /* HAVE_POPEN */
2164
2165   if (bb_mode & 2)
2166     {
2167       bb_hashbuckets = (struct bb_edge **) 
2168                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2169       if (bb_hashbuckets)
2170         memset (bb_hashbuckets, 0, BB_BUCKETS * sizeof (struct bb_edge *));
2171     }
2172
2173   if (bb_mode & 12)
2174     {
2175       bb_stacksize = 10;
2176       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2177     }
2178
2179 #ifdef ON_EXIT
2180       /* Initialize destructor.  */
2181       ON_EXIT (__bb_exit_trace_func, 0);
2182 #endif
2183
2184 }
2185
2186 /* Called upon entering a basic block.  */
2187
2188 void
2189 __bb_trace_func ()
2190 {
2191   struct bb_edge *bucket;
2192
2193   MACHINE_STATE_SAVE("1")
2194
2195   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2196     goto skip;
2197
2198   bb_dst = __bb.blocks->addresses[__bb.blockno];
2199   __bb.blocks->counts[__bb.blockno]++;
2200
2201   if (bb_tracefile)
2202     {
2203       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2204     }
2205
2206   if (bb_hashbuckets)
2207     {
2208       struct bb_edge **startbucket, **oldnext;
2209
2210       oldnext = startbucket
2211         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2212       bucket = *startbucket;
2213
2214       for (bucket = *startbucket; bucket; 
2215            oldnext = &(bucket->next), bucket = *oldnext)
2216         {
2217           if (bucket->src_addr == bb_src
2218               && bucket->dst_addr == bb_dst)
2219             {
2220               bucket->count++;
2221               *oldnext = bucket->next;
2222               bucket->next = *startbucket;
2223               *startbucket = bucket;
2224               goto ret;
2225             }
2226         }
2227
2228       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2229
2230       if (!bucket)
2231         {
2232           if (!reported)
2233             {
2234               fprintf (stderr, "Profiler: out of memory\n");
2235               reported = 1;
2236             }
2237         }
2238
2239       else
2240         {
2241           bucket->src_addr = bb_src;
2242           bucket->dst_addr = bb_dst;
2243           bucket->next = *startbucket;
2244           *startbucket = bucket;
2245           bucket->count = 1;
2246         }
2247     }
2248
2249 ret:
2250   bb_src = bb_dst;
2251
2252 skip:
2253   ;
2254
2255   MACHINE_STATE_RESTORE("1")
2256
2257 }
2258
2259 /* Called when returning from a function and `__bb_showret__' is set.  */
2260
2261 static void
2262 __bb_trace_func_ret ()
2263 {
2264   struct bb_edge *bucket;
2265
2266   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2267     goto skip;
2268
2269   if (bb_hashbuckets)
2270     {
2271       struct bb_edge **startbucket, **oldnext;
2272
2273       oldnext = startbucket
2274         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2275       bucket = *startbucket;
2276
2277       for (bucket = *startbucket; bucket; 
2278            oldnext = &(bucket->next), bucket = *oldnext)
2279         {
2280           if (bucket->src_addr == bb_dst
2281                && bucket->dst_addr == bb_src)
2282             {
2283               bucket->count++;
2284               *oldnext = bucket->next;
2285               bucket->next = *startbucket;
2286               *startbucket = bucket;
2287               goto ret;
2288             }
2289         }
2290
2291       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2292
2293       if (!bucket)
2294         {
2295           if (!reported)
2296             {
2297               fprintf (stderr, "Profiler: out of memory\n");
2298               reported = 1;
2299             }
2300         }
2301
2302       else
2303         {
2304           bucket->src_addr = bb_dst;
2305           bucket->dst_addr = bb_src;
2306           bucket->next = *startbucket;
2307           *startbucket = bucket;
2308           bucket->count = 1;
2309         }
2310     }
2311
2312 ret:
2313   bb_dst = bb_src;
2314
2315 skip:
2316   ;
2317
2318 }
2319
2320 /* Called upon entering the first function of a file.  */
2321
2322 static void
2323 __bb_init_file (struct bb *blocks)
2324 {
2325
2326   const struct bb_func *p;
2327   long blk, ncounts = blocks->ncounts;
2328   const char **functions = blocks->functions;
2329
2330   /* Set up linked list.  */
2331   blocks->zero_word = 1;
2332   blocks->next = bb_head;
2333   bb_head = blocks;
2334
2335   blocks->flags = 0;
2336   if (!bb_func_head
2337       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2338     return;
2339
2340   for (blk = 0; blk < ncounts; blk++)
2341     blocks->flags[blk] = 0;
2342
2343   for (blk = 0; blk < ncounts; blk++)
2344     {
2345       for (p = bb_func_head; p; p = p->next)
2346         {
2347           if (!strcmp (p->funcname, functions[blk])
2348               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2349             {
2350               blocks->flags[blk] |= p->mode;
2351             }
2352         }
2353     }
2354
2355 }
2356
2357 /* Called when exiting from a function.  */
2358
2359 void
2360 __bb_trace_ret ()
2361 {
2362
2363   MACHINE_STATE_SAVE("2")
2364
2365   if (bb_callcount)
2366     {
2367       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2368         {
2369           bb_src = bb_stack[bb_callcount];
2370           if (bb_mode & 8)
2371             __bb_trace_func_ret ();
2372         }
2373
2374       bb_callcount -= 1;
2375     }
2376
2377   MACHINE_STATE_RESTORE("2")
2378
2379 }
2380
2381 /* Called when entering a function.  */
2382
2383 void
2384 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2385 {
2386   static int trace_init = 0;
2387
2388   MACHINE_STATE_SAVE("3")
2389
2390   if (!blocks->zero_word)
2391     { 
2392       if (!trace_init)
2393         { 
2394           trace_init = 1;
2395           __bb_init_prg ();
2396         }
2397       __bb_init_file (blocks);
2398     }
2399
2400   if (bb_callcount)
2401     {
2402
2403       bb_callcount += 1;
2404
2405       if (bb_mode & 12)
2406         {
2407           if (bb_callcount >= bb_stacksize)
2408             {
2409               size_t newsize = bb_callcount + 100;
2410
2411               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2412               if (! bb_stack)
2413                 {
2414                   if (!reported)
2415                     {
2416                       fprintf (stderr, "Profiler: out of memory\n");
2417                       reported = 1;
2418                     }
2419                   bb_stacksize = 0;
2420                   goto stack_overflow;
2421                 }
2422               bb_stacksize = newsize;
2423             }
2424           bb_stack[bb_callcount] = bb_src;
2425
2426           if (bb_mode & 4)
2427             bb_src = 0;
2428
2429         }
2430
2431 stack_overflow:;
2432
2433     }
2434
2435   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2436     {
2437       bb_callcount = 1;
2438       bb_src = 0;
2439
2440       if (bb_stack)
2441           bb_stack[bb_callcount] = bb_src;
2442     }
2443
2444   MACHINE_STATE_RESTORE("3")
2445 }
2446
2447 #endif /* not inhibit_libc */
2448 #endif /* not BLOCK_PROFILER_CODE */
2449 #endif /* L_bb */
2450 \f
2451 #ifdef L_shtab
2452 unsigned int __shtab[] = {
2453     0x00000001, 0x00000002, 0x00000004, 0x00000008,
2454     0x00000010, 0x00000020, 0x00000040, 0x00000080,
2455     0x00000100, 0x00000200, 0x00000400, 0x00000800,
2456     0x00001000, 0x00002000, 0x00004000, 0x00008000,
2457     0x00010000, 0x00020000, 0x00040000, 0x00080000,
2458     0x00100000, 0x00200000, 0x00400000, 0x00800000,
2459     0x01000000, 0x02000000, 0x04000000, 0x08000000,
2460     0x10000000, 0x20000000, 0x40000000, 0x80000000
2461   };
2462 #endif
2463 \f
2464 #ifdef L_clear_cache
2465 /* Clear part of an instruction cache.  */
2466
2467 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2468
2469 void
2470 __clear_cache (char *beg, char *end)
2471 {
2472 #ifdef CLEAR_INSN_CACHE 
2473   CLEAR_INSN_CACHE (beg, end);
2474 #else
2475 #ifdef INSN_CACHE_SIZE
2476   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2477   static int initialized;
2478   int offset;
2479   void *start_addr
2480   void *end_addr;
2481   typedef (*function_ptr) ();
2482
2483 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2484   /* It's cheaper to clear the whole cache.
2485      Put in a series of jump instructions so that calling the beginning
2486      of the cache will clear the whole thing.  */
2487
2488   if (! initialized)
2489     {
2490       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2491                  & -INSN_CACHE_LINE_WIDTH);
2492       int end_ptr = ptr + INSN_CACHE_SIZE;
2493
2494       while (ptr < end_ptr)
2495         {
2496           *(INSTRUCTION_TYPE *)ptr
2497             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2498           ptr += INSN_CACHE_LINE_WIDTH;
2499         }
2500       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2501
2502       initialized = 1;
2503     }
2504
2505   /* Call the beginning of the sequence.  */
2506   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2507                     & -INSN_CACHE_LINE_WIDTH))
2508    ());
2509
2510 #else /* Cache is large.  */
2511
2512   if (! initialized)
2513     {
2514       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2515                  & -INSN_CACHE_LINE_WIDTH);
2516
2517       while (ptr < (int) array + sizeof array)
2518         {
2519           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2520           ptr += INSN_CACHE_LINE_WIDTH;
2521         }
2522
2523       initialized = 1;
2524     }
2525
2526   /* Find the location in array that occupies the same cache line as BEG.  */
2527
2528   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2529   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2530                  & -INSN_CACHE_PLANE_SIZE)
2531                 + offset);
2532
2533   /* Compute the cache alignment of the place to stop clearing.  */
2534 #if 0  /* This is not needed for gcc's purposes.  */
2535   /* If the block to clear is bigger than a cache plane,
2536      we clear the entire cache, and OFFSET is already correct.  */ 
2537   if (end < beg + INSN_CACHE_PLANE_SIZE)
2538 #endif
2539     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2540                & -INSN_CACHE_LINE_WIDTH)
2541               & (INSN_CACHE_PLANE_SIZE - 1));
2542
2543 #if INSN_CACHE_DEPTH > 1
2544   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2545   if (end_addr <= start_addr)
2546     end_addr += INSN_CACHE_PLANE_SIZE;
2547
2548   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2549     {
2550       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2551       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2552
2553       while (addr != stop)
2554         {
2555           /* Call the return instruction at ADDR.  */
2556           ((function_ptr) addr) ();
2557
2558           addr += INSN_CACHE_LINE_WIDTH;
2559         }
2560     }
2561 #else /* just one plane */
2562   do
2563     {
2564       /* Call the return instruction at START_ADDR.  */
2565       ((function_ptr) start_addr) ();
2566
2567       start_addr += INSN_CACHE_LINE_WIDTH;
2568     }
2569   while ((start_addr % INSN_CACHE_SIZE) != offset);
2570 #endif /* just one plane */
2571 #endif /* Cache is large */
2572 #endif /* Cache exists */
2573 #endif /* CLEAR_INSN_CACHE */
2574 }
2575
2576 #endif /* L_clear_cache */
2577 \f
2578 #ifdef L_trampoline
2579
2580 /* Jump to a trampoline, loading the static chain address.  */
2581
2582 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2583
2584 long getpagesize()
2585 {
2586 #ifdef _ALPHA_
2587   return 8192;
2588 #else
2589   return 4096;
2590 #endif
2591 }
2592
2593 #ifdef i386
2594 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2595 #endif
2596
2597 int
2598 mprotect (char *addr, int len, int prot)
2599 {
2600   int np, op;
2601
2602   if (prot == 7)
2603     np = 0x40;
2604   else if (prot == 5)
2605     np = 0x20;
2606   else if (prot == 4)
2607     np = 0x10;
2608   else if (prot == 3)
2609     np = 0x04;
2610   else if (prot == 1)
2611     np = 0x02;
2612   else if (prot == 0)
2613     np = 0x01;
2614
2615   if (VirtualProtect (addr, len, np, &op))
2616     return 0;
2617   else
2618     return -1;
2619 }
2620
2621 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2622
2623 #ifdef TRANSFER_FROM_TRAMPOLINE 
2624 TRANSFER_FROM_TRAMPOLINE 
2625 #endif
2626
2627 #if defined (NeXT) && defined (__MACH__)
2628
2629 /* Make stack executable so we can call trampolines on stack.
2630    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2631 #ifdef NeXTStep21
2632  #include <mach.h>
2633 #else
2634  #include <mach/mach.h>
2635 #endif
2636
2637 void
2638 __enable_execute_stack (char *addr)
2639 {
2640   kern_return_t r;
2641   char *eaddr = addr + TRAMPOLINE_SIZE;
2642   vm_address_t a = (vm_address_t) addr;
2643
2644   /* turn on execute access on stack */
2645   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2646   if (r != KERN_SUCCESS)
2647     {
2648       mach_error("vm_protect VM_PROT_ALL", r);
2649       exit(1);
2650     }
2651
2652   /* We inline the i-cache invalidation for speed */
2653
2654 #ifdef CLEAR_INSN_CACHE
2655   CLEAR_INSN_CACHE (addr, eaddr);
2656 #else
2657   __clear_cache ((int) addr, (int) eaddr);
2658 #endif
2659
2660
2661 #endif /* defined (NeXT) && defined (__MACH__) */
2662
2663 #ifdef __convex__
2664
2665 /* Make stack executable so we can call trampolines on stack.
2666    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2667
2668 #include <sys/mman.h>
2669 #include <sys/vmparam.h>
2670 #include <machine/machparam.h>
2671
2672 void
2673 __enable_execute_stack ()
2674 {
2675   int fp;
2676   static unsigned lowest = USRSTACK;
2677   unsigned current = (unsigned) &fp & -NBPG;
2678
2679   if (lowest > current)
2680     {
2681       unsigned len = lowest - current;
2682       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2683       lowest = current;
2684     }
2685
2686   /* Clear instruction cache in case an old trampoline is in it.  */
2687   asm ("pich");
2688 }
2689 #endif /* __convex__ */
2690
2691 #ifdef __sysV88__
2692
2693 /* Modified from the convex -code above.  */
2694
2695 #include <sys/param.h>
2696 #include <errno.h>
2697 #include <sys/m88kbcs.h>
2698
2699 void
2700 __enable_execute_stack ()
2701 {
2702   int save_errno;
2703   static unsigned long lowest = USRSTACK;
2704   unsigned long current = (unsigned long) &save_errno & -NBPC;
2705   
2706   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2707      address is seen as 'negative'. That is the case with the stack.   */
2708
2709   save_errno=errno;
2710   if (lowest > current)
2711     {
2712       unsigned len=lowest-current;
2713       memctl(current,len,MCT_TEXT);
2714       lowest = current;
2715     }
2716   else
2717     memctl(current,NBPC,MCT_TEXT);
2718   errno=save_errno;
2719 }
2720
2721 #endif /* __sysV88__ */
2722
2723 #ifdef __sysV68__
2724
2725 #include <sys/signal.h>
2726 #include <errno.h>
2727
2728 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2729    so define it here, because we need it in __clear_insn_cache below */
2730 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2731    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2732
2733 #ifdef MCT_TEXT
2734 asm("\n\
2735         global memctl\n\
2736 memctl:\n\
2737         movq &75,%d0\n\
2738         trap &0\n\
2739         bcc.b noerror\n\
2740         jmp cerror%\n\
2741 noerror:\n\
2742         movq &0,%d0\n\
2743         rts");
2744 #endif
2745
2746 /* Clear instruction cache so we can call trampolines on stack.
2747    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2748
2749 void
2750 __clear_insn_cache ()
2751 {
2752 #ifdef MCT_TEXT
2753   int save_errno;
2754
2755   /* Preserve errno, because users would be surprised to have
2756   errno changing without explicitly calling any system-call. */
2757   save_errno = errno;
2758
2759   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2760      No need to use an address derived from _start or %sp, as 0 works also. */
2761   memctl(0, 4096, MCT_TEXT);
2762   errno = save_errno;
2763 #endif
2764 }
2765
2766 #endif /* __sysV68__ */
2767
2768 #ifdef __pyr__
2769
2770 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2771 #include <stdio.h>
2772 #include <sys/mman.h>
2773 #include <sys/types.h>
2774 #include <sys/param.h>
2775 #include <sys/vmmac.h>
2776
2777 /* Modified from the convex -code above.
2778    mremap promises to clear the i-cache.  */
2779
2780 void
2781 __enable_execute_stack ()
2782 {
2783   int fp;
2784   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2785                 PROT_READ|PROT_WRITE|PROT_EXEC))
2786     {
2787       perror ("mprotect in __enable_execute_stack");
2788       fflush (stderr);
2789       abort ();
2790     }
2791 }
2792 #endif /* __pyr__ */
2793
2794 #if defined (sony_news) && defined (SYSTYPE_BSD)
2795
2796 #include <stdio.h>
2797 #include <sys/types.h>
2798 #include <sys/param.h>
2799 #include <syscall.h>
2800 #include <machine/sysnews.h>
2801
2802 /* cacheflush function for NEWS-OS 4.2.
2803    This function is called from trampoline-initialize code
2804    defined in config/mips/mips.h.  */
2805
2806 void
2807 cacheflush (char *beg, int size, int flag)
2808 {
2809   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2810     {
2811       perror ("cache_flush");
2812       fflush (stderr);
2813       abort ();
2814     }
2815 }
2816
2817 #endif /* sony_news */
2818 #endif /* L_trampoline */
2819 \f
2820 #ifndef __CYGWIN__
2821 #ifdef L__main
2822
2823 #include "gbl-ctors.h"
2824 /* Some systems use __main in a way incompatible with its use in gcc, in these
2825    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2826    give the same symbol without quotes for an alternative entry point.  You
2827    must define both, or neither.  */
2828 #ifndef NAME__MAIN
2829 #define NAME__MAIN "__main"
2830 #define SYMBOL__MAIN __main
2831 #endif
2832
2833 #ifdef INIT_SECTION_ASM_OP
2834 #undef HAS_INIT_SECTION
2835 #define HAS_INIT_SECTION
2836 #endif
2837
2838 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2839 /* Run all the global destructors on exit from the program.  */
2840
2841 void
2842 __do_global_dtors ()
2843 {
2844 #ifdef DO_GLOBAL_DTORS_BODY
2845   DO_GLOBAL_DTORS_BODY;
2846 #else
2847   static func_ptr *p = __DTOR_LIST__ + 1;
2848   while (*p)
2849     {
2850       p++;
2851       (*(p-1)) ();
2852     }
2853 #endif
2854 }
2855 #endif
2856
2857 #ifndef HAS_INIT_SECTION
2858 /* Run all the global constructors on entry to the program.  */
2859
2860 #ifndef ON_EXIT
2861 #define ON_EXIT(a, b)
2862 #else
2863 /* Make sure the exit routine is pulled in to define the globals as
2864    bss symbols, just in case the linker does not automatically pull
2865    bss definitions from the library.  */
2866
2867 extern int _exit_dummy_decl;
2868 int *_exit_dummy_ref = &_exit_dummy_decl;
2869 #endif /* ON_EXIT */
2870
2871 void
2872 __do_global_ctors ()
2873 {
2874   DO_GLOBAL_CTORS_BODY;
2875   ON_EXIT (__do_global_dtors, 0);
2876 }
2877 #endif /* no HAS_INIT_SECTION */
2878
2879 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2880 /* Subroutine called automatically by `main'.
2881    Compiling a global function named `main'
2882    produces an automatic call to this function at the beginning.
2883
2884    For many systems, this routine calls __do_global_ctors.
2885    For systems which support a .init section we use the .init section
2886    to run __do_global_ctors, so we need not do anything here.  */
2887
2888 void
2889 SYMBOL__MAIN ()
2890 {
2891   /* Support recursive calls to `main': run initializers just once.  */
2892   static int initialized;
2893   if (! initialized)
2894     {
2895       initialized = 1;
2896       __do_global_ctors ();
2897     }
2898 }
2899 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2900
2901 #endif /* L__main */
2902 #endif /* __CYGWIN__ */
2903 \f
2904 #ifdef L_ctors
2905
2906 #include "gbl-ctors.h"
2907
2908 /* Provide default definitions for the lists of constructors and
2909    destructors, so that we don't get linker errors.  These symbols are
2910    intentionally bss symbols, so that gld and/or collect will provide
2911    the right values.  */
2912
2913 /* We declare the lists here with two elements each,
2914    so that they are valid empty lists if no other definition is loaded.
2915
2916    If we are using the old "set" extensions to have the gnu linker
2917    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2918    must be in the bss/common section.
2919
2920    Long term no port should use those extensions.  But many still do.  */
2921 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2922 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2923 func_ptr __CTOR_LIST__[2] = {0, 0};
2924 func_ptr __DTOR_LIST__[2] = {0, 0};
2925 #else
2926 func_ptr __CTOR_LIST__[2];
2927 func_ptr __DTOR_LIST__[2];
2928 #endif
2929 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2930 #endif /* L_ctors */
2931 \f
2932 #ifdef L_exit
2933
2934 #include "gbl-ctors.h"
2935
2936 #ifdef NEED_ATEXIT
2937 # ifdef ON_EXIT
2938 #  undef ON_EXIT
2939 # endif
2940 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2941 #endif
2942
2943 #ifndef ON_EXIT
2944
2945 #ifdef NEED_ATEXIT
2946 # include <errno.h>
2947
2948 static func_ptr *atexit_chain = 0;
2949 static long atexit_chain_length = 0;
2950 static volatile long last_atexit_chain_slot = -1;
2951
2952 int atexit (func_ptr func)
2953 {
2954   if (++last_atexit_chain_slot == atexit_chain_length)
2955     {
2956       atexit_chain_length += 32;
2957       if (atexit_chain)
2958         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2959                                              * sizeof (func_ptr));
2960       else
2961         atexit_chain = (func_ptr *) malloc (atexit_chain_length
2962                                             * sizeof (func_ptr));
2963       if (! atexit_chain)
2964         {
2965           atexit_chain_length = 0;
2966           last_atexit_chain_slot = -1;
2967           errno = ENOMEM;
2968           return (-1);
2969         }
2970     }
2971   atexit_chain[last_atexit_chain_slot] = func;
2972   return (0);
2973 }
2974 #endif /* NEED_ATEXIT */
2975
2976 /* If we have no known way of registering our own __do_global_dtors
2977    routine so that it will be invoked at program exit time, then we
2978    have to define our own exit routine which will get this to happen.  */
2979
2980 extern void __do_global_dtors ();
2981 extern void __bb_exit_func ();
2982 extern void _cleanup ();
2983 extern void _exit () __attribute__ ((noreturn));
2984
2985 void 
2986 exit (int status)
2987 {
2988 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2989 #ifdef NEED_ATEXIT
2990   if (atexit_chain)
2991     {
2992       for ( ; last_atexit_chain_slot-- >= 0; )
2993         {
2994           (*atexit_chain[last_atexit_chain_slot + 1]) ();
2995           atexit_chain[last_atexit_chain_slot + 1] = 0;
2996         }
2997       free (atexit_chain);
2998       atexit_chain = 0;
2999     }
3000 #else /* No NEED_ATEXIT */
3001   __do_global_dtors ();
3002 #endif /* No NEED_ATEXIT */
3003 #endif /* !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF) */
3004 /* In gbl-ctors.h, ON_EXIT is defined if HAVE_ATEXIT is defined.  In
3005    __bb_init_func and _bb_init_prg, __bb_exit_func is registered with
3006    ON_EXIT if ON_EXIT is defined.  Thus we must not call __bb_exit_func here
3007    if HAVE_ATEXIT is defined. */
3008 #ifndef HAVE_ATEXIT
3009 #ifndef inhibit_libc
3010   __bb_exit_func ();
3011 #endif
3012 #endif /* !HAVE_ATEXIT */
3013 #ifdef EXIT_BODY
3014   EXIT_BODY;
3015 #else
3016   _cleanup ();
3017 #endif
3018   _exit (status);
3019 }
3020
3021 #else /* ON_EXIT defined */
3022 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
3023
3024 # ifndef HAVE_ATEXIT
3025 /* Provide a fake for atexit() using ON_EXIT.  */
3026 int atexit (func_ptr func)
3027 {
3028   return ON_EXIT (func, NULL);
3029 }
3030 # endif /* HAVE_ATEXIT */
3031 #endif /* ON_EXIT defined */
3032
3033 #endif /* L_exit */
3034 \f
3035 #ifdef L_eh
3036
3037 #include "gthr.h"
3038
3039 /* Shared exception handling support routines.  */
3040
3041 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3042
3043 void
3044 __default_terminate ()
3045 {
3046   abort ();
3047 }
3048
3049 void (*__terminate_func)() = __default_terminate;
3050
3051 void
3052 __terminate ()
3053 {
3054   (*__terminate_func)();
3055 }
3056
3057 void *
3058 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3059 {
3060 #if 0
3061  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3062          catch_type, throw_type);
3063 #endif
3064  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3065    return obj;
3066  return 0;
3067 }
3068
3069 void
3070 __empty ()
3071 {
3072 }
3073 \f
3074
3075 /* Include definitions of EH context and table layout */
3076
3077 #include "eh-common.h"
3078 #ifndef inhibit_libc
3079 #include <stdio.h>
3080 #endif
3081
3082 /* Allocate and return a new EH context structure. */
3083
3084 extern void __throw ();
3085
3086 static void *
3087 new_eh_context ()
3088 {
3089   struct eh_full_context {
3090     struct eh_context c;
3091     void *top_elt[2];
3092   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3093
3094   if (! ehfc)
3095     __terminate ();
3096
3097   memset (ehfc, 0, sizeof *ehfc);
3098
3099   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3100
3101   /* This should optimize out entirely.  This should always be true,
3102      but just in case it ever isn't, don't allow bogus code to be
3103      generated.  */
3104
3105   if ((void*)(&ehfc->c) != (void*)ehfc)
3106     __terminate ();
3107
3108   return &ehfc->c;
3109 }
3110
3111 #if __GTHREADS
3112 static __gthread_key_t eh_context_key;
3113
3114 /* Destructor for struct eh_context. */
3115 static void
3116 eh_context_free (void *ptr)
3117 {
3118   __gthread_key_dtor (eh_context_key, ptr);
3119   if (ptr)
3120     free (ptr);
3121 }
3122 #endif
3123
3124 /* Pointer to function to return EH context. */
3125
3126 static struct eh_context *eh_context_initialize ();
3127 static struct eh_context *eh_context_static ();
3128 #if __GTHREADS
3129 static struct eh_context *eh_context_specific ();
3130 #endif
3131
3132 static struct eh_context *(*get_eh_context) () = &eh_context_initialize;
3133
3134 /* Routine to get EH context.
3135    This one will simply call the function pointer. */
3136
3137 void *
3138 __get_eh_context ()
3139 {
3140   return (void *) (*get_eh_context) ();
3141 }
3142
3143 /* Get and set the language specific info pointer. */
3144
3145 void **
3146 __get_eh_info ()
3147 {
3148   struct eh_context *eh = (*get_eh_context) ();
3149   return &eh->info;
3150 }
3151 \f
3152 #if __GTHREADS
3153 static void
3154 eh_threads_initialize ()
3155 {
3156   /* Try to create the key.  If it fails, revert to static method,
3157      otherwise start using thread specific EH contexts. */
3158   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3159     get_eh_context = &eh_context_specific;
3160   else
3161     get_eh_context = &eh_context_static;
3162 }
3163 #endif /* no __GTHREADS */
3164
3165 /* Initialize EH context.
3166    This will be called only once, since we change GET_EH_CONTEXT
3167    pointer to another routine. */
3168
3169 static struct eh_context *
3170 eh_context_initialize ()
3171 {
3172 #if __GTHREADS
3173
3174   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3175   /* Make sure that get_eh_context does not point to us anymore.
3176      Some systems have dummy thread routines in their libc that
3177      return a success (Solaris 2.6 for example). */
3178   if (__gthread_once (&once, eh_threads_initialize) != 0
3179       || get_eh_context == &eh_context_initialize)
3180     {
3181       /* Use static version of EH context. */
3182       get_eh_context = &eh_context_static;
3183     }
3184
3185 #else /* no __GTHREADS */
3186
3187   /* Use static version of EH context. */
3188   get_eh_context = &eh_context_static;
3189
3190 #endif /* no __GTHREADS */
3191
3192   return (*get_eh_context) ();
3193 }
3194
3195 /* Return a static EH context. */
3196
3197 static struct eh_context *
3198 eh_context_static ()
3199 {
3200   static struct eh_context eh;
3201   static int initialized;
3202   static void *top_elt[2];
3203
3204   if (! initialized)
3205     {
3206       initialized = 1;
3207       memset (&eh, 0, sizeof eh);
3208       eh.dynamic_handler_chain = top_elt;
3209     }
3210   return &eh;
3211 }
3212
3213 #if __GTHREADS
3214 /* Return a thread specific EH context. */
3215
3216 static struct eh_context *
3217 eh_context_specific ()
3218 {
3219   struct eh_context *eh;
3220   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3221   if (! eh)
3222     {
3223       eh = new_eh_context ();
3224       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3225         __terminate ();
3226     }
3227
3228   return eh;
3229 }
3230 #endif __GTHREADS
3231 \f
3232 /* Support routines for setjmp/longjmp exception handling.  */
3233
3234 /* Calls to __sjthrow are generated by the compiler when an exception
3235    is raised when using the setjmp/longjmp exception handling codegen
3236    method.  */
3237
3238 #ifdef DONT_USE_BUILTIN_SETJMP
3239 extern void longjmp (void *, int);
3240 #endif
3241
3242 /* Routine to get the head of the current thread's dynamic handler chain
3243    use for exception handling. */
3244
3245 void ***
3246 __get_dynamic_handler_chain ()
3247 {
3248   struct eh_context *eh = (*get_eh_context) ();
3249   return &eh->dynamic_handler_chain;
3250 }
3251
3252 /* This is used to throw an exception when the setjmp/longjmp codegen
3253    method is used for exception handling.
3254
3255    We call __terminate if there are no handlers left.  Otherwise we run the
3256    cleanup actions off the dynamic cleanup stack, and pop the top of the
3257    dynamic handler chain, and use longjmp to transfer back to the associated
3258    handler.  */
3259
3260 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3261
3262 void
3263 __sjthrow ()
3264 {
3265   struct eh_context *eh = (*get_eh_context) ();
3266   void ***dhc = &eh->dynamic_handler_chain;
3267   void *jmpbuf;
3268   void (*func)(void *, int);
3269   void *arg;
3270   void ***cleanup;
3271
3272   /* The cleanup chain is one word into the buffer.  Get the cleanup
3273      chain.  */
3274   cleanup = (void***)&(*dhc)[1];
3275
3276   /* If there are any cleanups in the chain, run them now.  */
3277   if (cleanup[0])
3278     {
3279       double store[200];
3280       void **buf = (void**)store;
3281       buf[1] = 0;
3282       buf[0] = (*dhc);
3283
3284       /* try { */
3285 #ifdef DONT_USE_BUILTIN_SETJMP
3286       if (! setjmp (&buf[2]))
3287 #else
3288       if (! __builtin_setjmp (&buf[2]))
3289 #endif
3290         {
3291           *dhc = buf;
3292           while (cleanup[0])
3293             {
3294               func = (void(*)(void*, int))cleanup[0][1];
3295               arg = (void*)cleanup[0][2];
3296
3297               /* Update this before running the cleanup.  */
3298               cleanup[0] = (void **)cleanup[0][0];
3299
3300               (*func)(arg, 2);
3301             }
3302           *dhc = buf[0];
3303         }
3304       /* catch (...) */
3305       else
3306         {
3307           __terminate ();
3308         }
3309     }
3310   
3311   /* We must call terminate if we try and rethrow an exception, when
3312      there is no exception currently active and when there are no
3313      handlers left.  */
3314   if (! eh->info || (*dhc)[0] == 0)
3315     __terminate ();
3316     
3317   /* Find the jmpbuf associated with the top element of the dynamic
3318      handler chain.  The jumpbuf starts two words into the buffer.  */
3319   jmpbuf = &(*dhc)[2];
3320
3321   /* Then we pop the top element off the dynamic handler chain.  */
3322   *dhc = (void**)(*dhc)[0];
3323
3324   /* And then we jump to the handler.  */
3325
3326 #ifdef DONT_USE_BUILTIN_SETJMP
3327   longjmp (jmpbuf, 1);
3328 #else
3329   __builtin_longjmp (jmpbuf, 1);
3330 #endif
3331 }
3332
3333 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3334    handler, then pop the handler off the dynamic handler stack, and
3335    then throw.  This is used to skip the first handler, and transfer
3336    control to the next handler in the dynamic handler stack.  */
3337
3338 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3339
3340 void
3341 __sjpopnthrow ()
3342 {
3343   struct eh_context *eh = (*get_eh_context) ();
3344   void ***dhc = &eh->dynamic_handler_chain;
3345   void (*func)(void *, int);
3346   void *arg;
3347   void ***cleanup;
3348
3349   /* The cleanup chain is one word into the buffer.  Get the cleanup
3350      chain.  */
3351   cleanup = (void***)&(*dhc)[1];
3352
3353   /* If there are any cleanups in the chain, run them now.  */
3354   if (cleanup[0])
3355     {
3356       double store[200];
3357       void **buf = (void**)store;
3358       buf[1] = 0;
3359       buf[0] = (*dhc);
3360
3361       /* try { */
3362 #ifdef DONT_USE_BUILTIN_SETJMP
3363       if (! setjmp (&buf[2]))
3364 #else
3365       if (! __builtin_setjmp (&buf[2]))
3366 #endif
3367         {
3368           *dhc = buf;
3369           while (cleanup[0])
3370             {
3371               func = (void(*)(void*, int))cleanup[0][1];
3372               arg = (void*)cleanup[0][2];
3373
3374               /* Update this before running the cleanup.  */
3375               cleanup[0] = (void **)cleanup[0][0];
3376
3377               (*func)(arg, 2);
3378             }
3379           *dhc = buf[0];
3380         }
3381       /* catch (...) */
3382       else
3383         {
3384           __terminate ();
3385         }
3386     }
3387
3388   /* Then we pop the top element off the dynamic handler chain.  */
3389   *dhc = (void**)(*dhc)[0];
3390
3391   __sjthrow ();
3392 }
3393 \f
3394 /* Support code for all exception region-based exception handling.  */
3395
3396 int
3397 __eh_rtime_match (void *rtime)
3398 {
3399   void *info;
3400   __eh_matcher matcher;
3401   void *ret;
3402
3403   info = *(__get_eh_info ());
3404   matcher = ((__eh_info *)info)->match_function;
3405   if (! matcher)
3406     {
3407 #ifndef inhibit_libc
3408       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3409 #endif
3410       return 0;
3411     }
3412   ret = (*matcher) (info, rtime, (void *)0);
3413   return (ret != NULL);
3414 }
3415
3416 /* This value identifies the place from which an exception is being
3417    thrown.  */
3418
3419 #ifdef EH_TABLE_LOOKUP
3420
3421 EH_TABLE_LOOKUP
3422
3423 #else
3424
3425 #ifdef DWARF2_UNWIND_INFO
3426
3427
3428 /* Return the table version of an exception descriptor */
3429
3430 short 
3431 __get_eh_table_version (exception_descriptor *table) 
3432 {
3433   return table->lang.version;
3434 }
3435
3436 /* Return the originating table language of an exception descriptor */
3437
3438 short 
3439 __get_eh_table_language (exception_descriptor *table)
3440 {
3441   return table->lang.language;
3442 }
3443
3444 /* This routine takes a PC and a pointer to the exception region TABLE for
3445    its translation unit, and returns the address of the exception handler
3446    associated with the closest exception table handler entry associated
3447    with that PC, or 0 if there are no table entries the PC fits in.
3448
3449    In the advent of a tie, we have to give the last entry, as it represents
3450    an inner block.  */
3451
3452 static void *
3453 old_find_exception_handler (void *pc, old_exception_table *table)
3454 {
3455   if (table)
3456     {
3457       int pos;
3458       int best = -1;
3459
3460       /* We can't do a binary search because the table isn't guaranteed
3461          to be sorted from function to function.  */
3462       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3463         {
3464           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3465             {
3466               /* This can apply.  Make sure it is at least as small as
3467                  the previous best.  */
3468               if (best == -1 || (table[pos].end_region <= table[best].end_region
3469                         && table[pos].start_region >= table[best].start_region))
3470                 best = pos;
3471             }
3472           /* But it is sorted by starting PC within a function.  */
3473           else if (best >= 0 && table[pos].start_region > pc)
3474             break;
3475         }
3476       if (best != -1)
3477         return table[best].exception_handler;
3478     }
3479
3480   return (void *) 0;
3481 }
3482
3483 /* find_exception_handler finds the correct handler, if there is one, to
3484    handle an exception.
3485    returns a pointer to the handler which controlled should be transferred
3486    to, or NULL if there is nothing left.
3487    Parameters:
3488    PC - pc where the exception originates. If this is a rethrow, 
3489         then this starts out as a pointer to the exception table
3490         entry we wish to rethrow out of.
3491    TABLE - exception table for the current module.
3492    EH_INFO - eh info pointer for this exception.
3493    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3494    CLEANUP - returned flag indicating whether this is a cleanup handler.
3495 */
3496 static void *
3497 find_exception_handler (void *pc, exception_descriptor *table, 
3498                         __eh_info *eh_info, int rethrow, int *cleanup)
3499 {
3500
3501   void *retval = NULL;
3502   *cleanup = 1;
3503   if (table)
3504     {
3505       int pos = 0;
3506       /* The new model assumed the table is sorted inner-most out so the
3507          first region we find which matches is the correct one */
3508
3509       exception_table *tab = &(table->table[0]);
3510
3511       /* Subtract 1 from the PC to avoid hitting the next region */
3512       if (rethrow) 
3513         {
3514           /* pc is actually the region table entry to rethrow out of */
3515           pos = ((exception_table *) pc) - tab;
3516           pc = ((exception_table *) pc)->end_region - 1;
3517
3518           /* The label is always on the LAST handler entry for a region, 
3519              so we know the next entry is a different region, even if the
3520              addresses are the same. Make sure its not end of table tho. */
3521           if (tab[pos].start_region != (void *) -1)
3522             pos++;
3523         }
3524       else
3525         pc--;
3526       
3527       /* We can't do a binary search because the table is in inner-most
3528          to outermost address ranges within functions */
3529       for ( ; tab[pos].start_region != (void *) -1; pos++)
3530         { 
3531           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3532             {
3533               if (tab[pos].match_info)
3534                 {
3535                   __eh_matcher matcher = eh_info->match_function;
3536                   /* match info but no matcher is NOT a match */
3537                   if (matcher) 
3538                     {
3539                       void *ret = (*matcher)((void *) eh_info, 
3540                                              tab[pos].match_info, table);
3541                       if (ret) 
3542                         {
3543                           if (retval == NULL)
3544                             retval = tab[pos].exception_handler;
3545                           *cleanup = 0;
3546                           break;
3547                         }
3548                     }
3549                 }
3550               else
3551                 {
3552                   if (retval == NULL)
3553                     retval = tab[pos].exception_handler;
3554                 }
3555             }
3556         }
3557     }
3558   return retval;
3559 }
3560 #endif /* DWARF2_UNWIND_INFO */
3561 #endif /* EH_TABLE_LOOKUP */
3562 \f
3563 #ifdef DWARF2_UNWIND_INFO
3564 /* Support code for exception handling using static unwind information.  */
3565
3566 #include "frame.h"
3567
3568 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3569    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3570    avoid a warning about casting between int and pointer of different
3571    sizes.  */
3572
3573 typedef int ptr_type __attribute__ ((mode (pointer)));
3574
3575 #ifdef INCOMING_REGNO
3576 /* Is the saved value for register REG in frame UDATA stored in a register
3577    window in the previous frame?  */
3578
3579 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3580    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3581    compiled functions won't work with the frame-unwind stuff here.  
3582    Perhaps the entireity of in_reg_window should be conditional on having
3583    seen a DW_CFA_GNU_window_save?  */
3584 #define target_flags 0
3585
3586 static int
3587 in_reg_window (int reg, frame_state *udata)
3588 {
3589   if (udata->saved[reg] == REG_SAVED_REG)
3590     return INCOMING_REGNO (reg) == reg;
3591   if (udata->saved[reg] != REG_SAVED_OFFSET)
3592     return 0;
3593
3594 #ifdef STACK_GROWS_DOWNWARD
3595   return udata->reg_or_offset[reg] > 0;
3596 #else
3597   return udata->reg_or_offset[reg] < 0;
3598 #endif
3599 }
3600 #else
3601 static inline int in_reg_window (int reg, frame_state *udata) { return 0; }
3602 #endif /* INCOMING_REGNO */
3603
3604 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3605    frame called by UDATA or 0.  */
3606
3607 static word_type *
3608 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3609 {
3610   while (udata->saved[reg] == REG_SAVED_REG)
3611     {
3612       reg = udata->reg_or_offset[reg];
3613       if (in_reg_window (reg, udata))
3614         {
3615           udata = sub_udata;
3616           sub_udata = NULL;
3617         }
3618     }
3619   if (udata->saved[reg] == REG_SAVED_OFFSET)
3620     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3621   else
3622     abort ();
3623 }
3624
3625 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3626    frame called by UDATA or 0.  */
3627
3628 static inline void *
3629 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3630 {
3631   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3632 }
3633
3634 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3635
3636 static inline void
3637 put_reg (unsigned reg, void *val, frame_state *udata)
3638 {
3639   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3640 }
3641
3642 /* Copy the saved value for register REG from frame UDATA to frame
3643    TARGET_UDATA.  Unlike the previous two functions, this can handle
3644    registers that are not one word large.  */
3645
3646 static void
3647 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3648 {
3649   word_type *preg = get_reg_addr (reg, udata, NULL);
3650   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3651
3652   memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg));
3653 }
3654
3655 /* Retrieve the return address for frame UDATA.  */
3656
3657 static inline void *
3658 get_return_addr (frame_state *udata, frame_state *sub_udata)
3659 {
3660   return __builtin_extract_return_addr
3661     (get_reg (udata->retaddr_column, udata, sub_udata));
3662 }
3663
3664 /* Overwrite the return address for frame UDATA with VAL.  */
3665
3666 static inline void
3667 put_return_addr (void *val, frame_state *udata)
3668 {
3669   val = __builtin_frob_return_addr (val);
3670   put_reg (udata->retaddr_column, val, udata);
3671 }
3672
3673 /* Given the current frame UDATA and its return address PC, return the
3674    information about the calling frame in CALLER_UDATA.  */
3675
3676 static void *
3677 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3678 {
3679   caller_udata = __frame_state_for (pc, caller_udata);
3680   if (! caller_udata)
3681     return 0;
3682
3683   /* Now go back to our caller's stack frame.  If our caller's CFA register
3684      was saved in our stack frame, restore it; otherwise, assume the CFA
3685      register is SP and restore it to our CFA value.  */
3686   if (udata->saved[caller_udata->cfa_reg])
3687     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3688   else
3689     caller_udata->cfa = udata->cfa;
3690   caller_udata->cfa += caller_udata->cfa_offset;
3691
3692   return caller_udata;
3693 }
3694
3695 /* Hook to call before __terminate if only cleanup handlers remain. */
3696 void 
3697 __unwinding_cleanup ()
3698 {
3699 }
3700
3701 /* throw_helper performs some of the common grunt work for a throw. This
3702    routine is called by throw and rethrows. This is pretty much split 
3703    out from the old __throw routine. An addition has been added which allows
3704    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3705    but cleanups remaining. This allows a debugger to examine the state
3706    at which the throw was executed, before any cleanups, rather than
3707    at the terminate point after the stack has been unwound.
3708
3709    EH is the current eh_context structure.
3710    PC is the address of the call to __throw.
3711    MY_UDATA is the unwind information for __throw.
3712    OFFSET_P is where we return the SP adjustment offset.  */
3713
3714 static void *
3715 throw_helper (eh, pc, my_udata, offset_p)
3716      struct eh_context *eh;
3717      void *pc;
3718      frame_state *my_udata;
3719      long *offset_p;
3720 {
3721   frame_state ustruct2, *udata = &ustruct2;
3722   frame_state ustruct;
3723   frame_state *sub_udata = &ustruct;
3724   void *saved_pc = pc;
3725   void *handler;
3726   void *handler_p;
3727   void *pc_p;
3728   frame_state saved_ustruct;
3729   int new_eh_model;
3730   int cleanup = 0;
3731   int only_cleanup = 0;
3732   int rethrow = 0;
3733   int saved_state = 0;
3734   long args_size;
3735   __eh_info *eh_info = (__eh_info *)eh->info;
3736
3737   /* Do we find a handler based on a re-throw PC? */
3738   if (eh->table_index != (void *) 0)
3739     rethrow = 1;
3740
3741   memcpy (udata, my_udata, sizeof (*udata));
3742
3743   handler = (void *) 0;
3744   for (;;)
3745     { 
3746       frame_state *p = udata;
3747       udata = next_stack_level (pc, udata, sub_udata);
3748       sub_udata = p;
3749
3750       /* If we couldn't find the next frame, we lose.  */
3751       if (! udata)
3752         break;
3753
3754       if (udata->eh_ptr == NULL)
3755         new_eh_model = 0;
3756       else
3757         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3758                                           runtime_id_field == NEW_EH_RUNTIME);
3759
3760       if (rethrow) 
3761         {
3762           rethrow = 0;
3763           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3764                                           eh_info, 1, &cleanup);
3765           eh->table_index = (void *)0;
3766         }
3767       else
3768         if (new_eh_model)
3769           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3770                                             0, &cleanup);
3771         else
3772           handler = old_find_exception_handler (pc, udata->eh_ptr);
3773
3774       /* If we found one, we can stop searching, if its not a cleanup. 
3775          for cleanups, we save the state, and keep looking. This allows
3776          us to call a debug hook if there are nothing but cleanups left. */
3777       if (handler)
3778         {
3779           if (cleanup)
3780             {
3781               if (!saved_state)
3782                 {
3783                   saved_ustruct = *udata;
3784                   handler_p = handler;
3785                   pc_p = pc;
3786                   saved_state = 1;
3787                   only_cleanup = 1;
3788                 }
3789             }
3790           else
3791             {
3792               only_cleanup = 0;
3793               break;
3794             }
3795         }
3796
3797       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3798          hitting the beginning of the next region.  */
3799       pc = get_return_addr (udata, sub_udata) - 1;
3800     }
3801
3802   if (saved_state) 
3803     {
3804       udata = &saved_ustruct;
3805       handler = handler_p;
3806       pc = pc_p;
3807       if (only_cleanup)
3808         __unwinding_cleanup ();
3809     }
3810
3811   /* If we haven't found a handler by now, this is an unhandled
3812      exception.  */
3813   if (! handler) 
3814     __terminate();
3815
3816   eh->handler_label = handler;
3817
3818   args_size = udata->args_size;
3819
3820   if (pc == saved_pc)
3821     /* We found a handler in the throw context, no need to unwind.  */
3822     udata = my_udata;
3823   else
3824     {
3825       int i;
3826
3827       /* Unwind all the frames between this one and the handler by copying
3828          their saved register values into our register save slots.  */
3829
3830       /* Remember the PC where we found the handler.  */
3831       void *handler_pc = pc;
3832
3833       /* Start from the throw context again.  */
3834       pc = saved_pc;
3835       memcpy (udata, my_udata, sizeof (*udata));
3836
3837       while (pc != handler_pc)
3838         {
3839           frame_state *p = udata;
3840           udata = next_stack_level (pc, udata, sub_udata);
3841           sub_udata = p;
3842
3843           for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3844             if (i != udata->retaddr_column && udata->saved[i])
3845               {
3846                 /* If you modify the saved value of the return address
3847                    register on the SPARC, you modify the return address for
3848                    your caller's frame.  Don't do that here, as it will
3849                    confuse get_return_addr.  */
3850                 if (in_reg_window (i, udata)
3851                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3852                     && udata->reg_or_offset[udata->retaddr_column] == i)
3853                   continue;
3854                 copy_reg (i, udata, my_udata);
3855               }
3856
3857           pc = get_return_addr (udata, sub_udata) - 1;
3858         }
3859
3860       /* But we do need to update the saved return address register from
3861          the last frame we unwind, or the handler frame will have the wrong
3862          return address.  */
3863       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3864         {
3865           i = udata->reg_or_offset[udata->retaddr_column];
3866           if (in_reg_window (i, udata))
3867             copy_reg (i, udata, my_udata);
3868         }
3869     }
3870   /* udata now refers to the frame called by the handler frame.  */
3871
3872   /* We adjust SP by the difference between __throw's CFA and the CFA for
3873      the frame called by the handler frame, because those CFAs correspond
3874      to the SP values at the two call sites.  We need to further adjust by
3875      the args_size of the handler frame itself to get the handler frame's
3876      SP from before the args were pushed for that call.  */
3877 #ifdef STACK_GROWS_DOWNWARD
3878   *offset_p = udata->cfa - my_udata->cfa + args_size;
3879 #else
3880   *offset_p = my_udata->cfa - udata->cfa - args_size;
3881 #endif
3882                        
3883   return handler;
3884 }
3885
3886
3887 /* We first search for an exception handler, and if we don't find
3888    it, we call __terminate on the current stack frame so that we may
3889    use the debugger to walk the stack and understand why no handler
3890    was found.
3891
3892    If we find one, then we unwind the frames down to the one that
3893    has the handler and transfer control into the handler.  */
3894
3895 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
3896
3897 void
3898 __throw ()
3899 {
3900   struct eh_context *eh = (*get_eh_context) ();
3901   void *pc, *handler;
3902   long offset;
3903
3904   /* XXX maybe make my_ustruct static so we don't have to look it up for
3905      each throw.  */
3906   frame_state my_ustruct, *my_udata = &my_ustruct;
3907
3908   /* This is required for C++ semantics.  We must call terminate if we
3909      try and rethrow an exception, when there is no exception currently
3910      active.  */
3911   if (! eh->info)
3912     __terminate ();
3913     
3914   /* Start at our stack frame.  */
3915 label:
3916   my_udata = __frame_state_for (&&label, my_udata);
3917   if (! my_udata)
3918     __terminate ();
3919
3920   /* We need to get the value from the CFA register. */
3921   my_udata->cfa = __builtin_dwarf_cfa ();
3922
3923   /* Do any necessary initialization to access arbitrary stack frames.
3924      On the SPARC, this means flushing the register windows.  */
3925   __builtin_unwind_init ();
3926
3927   /* Now reset pc to the right throw point.  */
3928   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3929
3930   handler = throw_helper (eh, pc, my_udata, &offset);
3931
3932   /* Now go!  */
3933
3934   __builtin_eh_return ((void *)eh, offset, handler);
3935
3936   /* Epilogue:  restore the handler frame's register values and return
3937      to the stub.  */
3938 }
3939
3940 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
3941
3942 void
3943 __rethrow (index)
3944      void *index;
3945 {
3946   struct eh_context *eh = (*get_eh_context) ();
3947   void *pc, *handler;
3948   long offset;
3949
3950   /* XXX maybe make my_ustruct static so we don't have to look it up for
3951      each throw.  */
3952   frame_state my_ustruct, *my_udata = &my_ustruct;
3953
3954   /* This is required for C++ semantics.  We must call terminate if we
3955      try and rethrow an exception, when there is no exception currently
3956      active.  */
3957   if (! eh->info)
3958     __terminate ();
3959
3960   /* This is the table index we want to rethrow from. The value of
3961      the END_REGION label is used for the PC of the throw, and the
3962      search begins with the next table entry. */
3963   eh->table_index = index;
3964     
3965   /* Start at our stack frame.  */
3966 label:
3967   my_udata = __frame_state_for (&&label, my_udata);
3968   if (! my_udata)
3969     __terminate ();
3970
3971   /* We need to get the value from the CFA register. */
3972   my_udata->cfa = __builtin_dwarf_cfa ();
3973
3974   /* Do any necessary initialization to access arbitrary stack frames.
3975      On the SPARC, this means flushing the register windows.  */
3976   __builtin_unwind_init ();
3977
3978   /* Now reset pc to the right throw point.  */
3979   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3980
3981   handler = throw_helper (eh, pc, my_udata, &offset);
3982
3983   /* Now go!  */
3984
3985   __builtin_eh_return ((void *)eh, offset, handler);
3986
3987   /* Epilogue:  restore the handler frame's register values and return
3988      to the stub.  */
3989 }
3990 #endif /* DWARF2_UNWIND_INFO */
3991
3992 #endif /* L_eh */
3993 \f
3994 #ifdef L_pure
3995 #ifndef inhibit_libc
3996 /* This gets us __GNU_LIBRARY__.  */
3997 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
3998 #include <stdio.h>
3999
4000 #ifdef __GNU_LIBRARY__
4001   /* Avoid forcing the library's meaning of `write' on the user program
4002      by using the "internal" name (for use within the library)  */
4003 #define write(fd, buf, n)       __write((fd), (buf), (n))
4004 #endif
4005 #endif /* inhibit_libc */
4006
4007 #define MESSAGE "pure virtual method called\n"
4008
4009 void
4010 __pure_virtual ()
4011 {
4012 #ifndef inhibit_libc
4013   write (2, MESSAGE, sizeof (MESSAGE) - 1);
4014 #endif
4015   __terminate ();
4016 }
4017 #endif
4018 \f
4019 #ifdef L_stack_smash_handler
4020 #include <stdio.h>
4021 #include <string.h>
4022 #include <fcntl.h>
4023 #include <unistd.h>
4024
4025 #ifdef _POSIX_SOURCE
4026 #include <signal.h>
4027 #endif
4028
4029 #if defined(HAVE_SYSLOG)
4030 #include <sys/types.h>
4031 #include <sys/socket.h>
4032 #include <sys/un.h>
4033
4034 #include <sys/syslog.h>
4035 #ifndef _PATH_LOG
4036 #define _PATH_LOG "/dev/log"
4037 #endif
4038 #endif
4039
4040 long __guard[8] = {0,0,0,0,0,0,0,0};
4041 static void __guard_setup (void) __attribute__ ((constructor)) ;
4042 static void __guard_setup (void)
4043 {
4044   int fd;
4045   if (__guard[0]!=0) return;
4046   fd = open ("/dev/urandom", 0);
4047   if (fd != -1) {
4048     ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
4049     close (fd) ;
4050     if (size == sizeof(__guard)) return;
4051   }
4052   /* If a random generator can't be used, the protector switches the guard
4053      to the "terminator canary" */
4054   ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
4055   ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
4056 }
4057 void __stack_smash_handler (char func[], int damaged ATTRIBUTE_UNUSED)
4058 {
4059 #if defined (__GNU_LIBRARY__)
4060   extern char * __progname;
4061 #endif
4062   const char message[] = ": stack smashing attack in function ";
4063   int bufsz = 256, len;
4064   char buf[bufsz];
4065 #if defined(HAVE_SYSLOG)
4066   int LogFile;
4067   struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
4068 #endif
4069 #ifdef _POSIX_SOURCE
4070   {
4071     sigset_t mask;
4072     sigfillset(&mask);
4073     sigdelset(&mask, SIGABRT);  /* Block all signal handlers */
4074     sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
4075   }
4076 #endif
4077
4078   strcpy(buf, "<2>"); len=3;    /* send LOG_CRIT */
4079 #if defined (__GNU_LIBRARY__)
4080   strncat(buf, __progname, bufsz-len-1); len = strlen(buf);
4081 #endif
4082   if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);}
4083   if (bufsz>len) {strncat(buf, func, bufsz-len-1); len = strlen(buf);}
4084
4085   /* print error message */
4086   write (STDERR_FILENO, buf+3, len-3);
4087 #if defined(HAVE_SYSLOG)
4088   if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) {
4089
4090     /*
4091      * Send "found" message to the "/dev/log" path
4092      */
4093     SyslogAddr.sun_family = AF_UNIX;
4094     (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
4095                   sizeof(SyslogAddr.sun_path) - 1);
4096     SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0';
4097     sendto(LogFile, buf, len, 0, (struct sockaddr *)&SyslogAddr,
4098            sizeof(SyslogAddr));
4099   }
4100 #endif
4101
4102 #ifdef _POSIX_SOURCE
4103   { /* Make sure the default handler is associated with SIGABRT */
4104     struct sigaction sa;
4105     
4106     memset(&sa, 0, sizeof(struct sigaction));
4107     sigfillset(&sa.sa_mask);    /* Block all signals */
4108     sa.sa_flags = 0;
4109     sa.sa_handler = SIG_DFL;
4110     sigaction(SIGABRT, &sa, NULL);
4111     (void)kill(getpid(), SIGABRT);
4112   }
4113 #endif
4114   _exit(127);
4115 }
4116 #endif
4117 \f
4118 #ifdef L_stack_smash_handler
4119 #include <stdio.h>
4120 #include <string.h>
4121 #include <fcntl.h>
4122 #include <unistd.h>
4123
4124 #ifdef _POSIX_SOURCE
4125 #include <signal.h>
4126 #endif
4127
4128 #if defined(HAVE_SYSLOG)
4129 #include <sys/types.h>
4130 #include <sys/socket.h>
4131 #include <sys/un.h>
4132
4133 #include <sys/syslog.h>
4134 #ifndef _PATH_LOG
4135 #define _PATH_LOG "/dev/log"
4136 #endif
4137 #endif
4138
4139 long __guard[8] = {0,0,0,0,0,0,0,0};
4140 static void __guard_setup (void) __attribute__ ((constructor)) ;
4141 static void __guard_setup (void)
4142 {
4143   int fd;
4144   if (__guard[0]!=0) return;
4145   fd = open ("/dev/urandom", 0);
4146   if (fd != -1) {
4147     ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
4148     close (fd) ;
4149     if (size == sizeof(__guard)) return;
4150   }
4151   /* If a random generator can't be used, the protector switches the guard
4152      to the "terminator canary" */
4153   ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
4154   ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
4155 }
4156 void __stack_smash_handler (char func[], int damaged ATTRIBUTE_UNUSED)
4157 {
4158 #if defined (__GNU_LIBRARY__)
4159   extern char * __progname;
4160 #endif
4161   const char message[] = ": stack smashing attack in function ";
4162   int bufsz = 256, len;
4163   char buf[bufsz];
4164 #if defined(HAVE_SYSLOG)
4165   int LogFile;
4166   struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
4167 #endif
4168 #ifdef _POSIX_SOURCE
4169   {
4170     sigset_t mask;
4171     sigfillset(&mask);
4172     sigdelset(&mask, SIGABRT);  /* Block all signal handlers */
4173     sigprocmask(SIG_BLOCK, &mask, NULL); /* except SIGABRT */
4174   }
4175 #endif
4176
4177   strcpy(buf, "<2>"); len=3;    /* send LOG_CRIT */
4178 #if defined (__GNU_LIBRARY__)
4179   strncat(buf, __progname, bufsz-len-1); len = strlen(buf);
4180 #endif
4181   if (bufsz>len) {strncat(buf, message, bufsz-len-1); len = strlen(buf);}
4182   if (bufsz>len) strncat(buf, func, bufsz-len-1);
4183
4184   /* print error message */
4185   write (STDERR_FILENO, buf+3, len-3);
4186 #if defined(HAVE_SYSLOG)
4187   if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) != -1) {
4188
4189     /*
4190      * Send "found" message to the "/dev/log" path
4191      */
4192     SyslogAddr.sun_family = AF_UNIX;
4193     (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
4194                   sizeof(SyslogAddr.sun_path) - 1);
4195     SyslogAddr.sun_path[sizeof(SyslogAddr.sun_path) - 1] = '\0';
4196     sendto(LogFile, buf, strlen(buf), 0, (struct sockaddr *)&SyslogAddr,
4197            sizeof(SyslogAddr));
4198   }
4199 #endif
4200
4201 #ifdef _POSIX_SOURCE
4202   { /* Make sure the default handler is associated with SIGABRT */
4203     struct sigaction sa;
4204     
4205     memset(&sa, 0, sizeof(struct sigaction));
4206     sigfillset(&sa.sa_mask);    /* Block all signals */
4207     sa.sa_flags = 0;
4208     sa.sa_handler = SIG_DFL;
4209     sigaction(SIGABRT, &sa, NULL);
4210     (void)kill(getpid(), SIGABRT);
4211   }
4212 #endif
4213   _exit(127);
4214 }
4215 #endif