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