1/* Subroutines needed for unwinding stack frames for exception handling. */ 2/* Compile this one with gcc. */ 3/* Copyright (C) 1997, 1998, 2000 Free Software Foundation, Inc. 4 Contributed by Jason Merrill <jason@cygnus.com>. 5 6This file is part of GNU CC. 7 8GNU CC is free software; you can redistribute it and/or modify 9it under the terms of the GNU General Public License as published by 10the Free Software Foundation; either version 2, or (at your option) 11any later version. 12 13GNU CC is distributed in the hope that it will be useful, 14but WITHOUT ANY WARRANTY; without even the implied warranty of 15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16GNU General Public License for more details. 17 18You should have received a copy of the GNU General Public License 19along with GNU CC; see the file COPYING. If not, write to 20the Free Software Foundation, 59 Temple Place - Suite 330, 21Boston, MA 02111-1307, USA. */ 22 23/* As a special exception, if you link this library with other files, 24 some of which are compiled with GCC, to produce an executable, 25 this library does not by itself cause the resulting executable 26 to be covered by the GNU General Public License. 27 This exception does not however invalidate any other reasons why 28 the executable file might be covered by the GNU General Public License. */ 29 30/* It is incorrect to include config.h here, because this file is being 31 compiled for the target, and hence definitions concerning only the host 32 do not apply. */ 33 34#include "tconfig.h" 35 36/* We disable this when inhibit_libc, so that gcc can still be built without 37 needing header files first. */ 38/* ??? This is not a good solution, since prototypes may be required in 39 some cases for correct code. See also libgcc2.c. */ 40#ifndef inhibit_libc 41/* fixproto guarantees these system headers exist. */ 42#include <stdlib.h> 43#include <unistd.h> 44#endif 45 46#include "defaults.h" 47 48#ifdef DWARF2_UNWIND_INFO 49#include "dwarf2.h" 50#include <stddef.h> 51#include "frame.h" 52#include "gthr.h" 53 54#ifdef __GTHREAD_MUTEX_INIT 55static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; 56#else 57static __gthread_mutex_t object_mutex; 58#endif 59 60/* Don't use `fancy_abort' here even if config.h says to use it. */ 61#ifdef abort 62#undef abort 63#endif 64 65/* Some types used by the DWARF 2 spec. */ 66 67typedef int sword __attribute__ ((mode (SI))); 68typedef unsigned int uword __attribute__ ((mode (SI))); 69typedef unsigned int uaddr __attribute__ ((mode (pointer))); 70typedef int saddr __attribute__ ((mode (pointer))); 71typedef unsigned char ubyte; 72 73/* Terminology: 74 CIE - Common Information Element 75 FDE - Frame Descriptor Element 76 77 There is one per function, and it describes where the function code 78 is located, and what the register lifetimes and stack layout are 79 within the function. 80 81 The data structures are defined in the DWARF specfication, although 82 not in a very readable way (see LITERATURE). 83 84 Every time an exception is thrown, the code needs to locate the FDE 85 for the current function, and starts to look for exception regions 86 from that FDE. This works in a two-level search: 87 a) in a linear search, find the shared image (i.e. DLL) containing 88 the PC 89 b) using the FDE table for that shared object, locate the FDE using 90 binary search (which requires the sorting). */ 91 92/* The first few fields of a CIE. The CIE_id field is 0 for a CIE, 93 to distinguish it from a valid FDE. FDEs are aligned to an addressing 94 unit boundary, but the fields within are unaligned. */ 95 96struct dwarf_cie { 97 uword length; 98 sword CIE_id; 99 ubyte version; 100 char augmentation[0]; 101} __attribute__ ((packed, aligned (__alignof__ (void *)))); 102 103/* The first few fields of an FDE. */ 104 105struct dwarf_fde { 106 uword length; 107 sword CIE_delta; 108 void* pc_begin; 109 uaddr pc_range; 110} __attribute__ ((packed, aligned (__alignof__ (void *)))); 111 112typedef struct dwarf_fde fde; 113 114/* Objects to be searched for frame unwind info. */ 115 116static struct object *objects; 117 118/* The information we care about from a CIE. */ 119 120struct cie_info { 121 char *augmentation; 122 void *eh_ptr; 123 int code_align; 124 int data_align; 125 unsigned ra_regno; 126}; 127 128/* The current unwind state, plus a saved copy for DW_CFA_remember_state. */ 129 130struct frame_state_internal 131{ 132 struct frame_state s; 133 struct frame_state_internal *saved_state; 134}; 135 136/* This is undefined below if we need it to be an actual function. */ 137#define init_object_mutex_once() 138 139#if __GTHREADS 140#ifdef __GTHREAD_MUTEX_INIT_FUNCTION 141 142/* Helper for init_object_mutex_once. */ 143 144static void 145init_object_mutex (void) 146{ 147 __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex); 148} 149 150/* Call this to arrange to initialize the object mutex. */ 151 152#undef init_object_mutex_once 153static void 154init_object_mutex_once (void) 155{ 156 static __gthread_once_t once = __GTHREAD_ONCE_INIT; 157 __gthread_once (&once, init_object_mutex); 158} 159 160#endif /* __GTHREAD_MUTEX_INIT_FUNCTION */ 161#endif /* __GTHREADS */ 162 163/* Decode the unsigned LEB128 constant at BUF into the variable pointed to 164 by R, and return the new value of BUF. */ 165 166static void * 167decode_uleb128 (unsigned char *buf, unsigned *r) 168{ 169 unsigned shift = 0; 170 unsigned result = 0; 171 172 while (1) 173 { 174 unsigned byte = *buf++; 175 result |= (byte & 0x7f) << shift; 176 if ((byte & 0x80) == 0) 177 break; 178 shift += 7; 179 } 180 *r = result; 181 return buf; 182} 183 184/* Decode the signed LEB128 constant at BUF into the variable pointed to 185 by R, and return the new value of BUF. */ 186 187static void * 188decode_sleb128 (unsigned char *buf, int *r) 189{ 190 unsigned shift = 0; 191 unsigned result = 0; 192 unsigned byte; 193 194 while (1) 195 { 196 byte = *buf++; 197 result |= (byte & 0x7f) << shift; 198 shift += 7; 199 if ((byte & 0x80) == 0) 200 break; 201 } 202 if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) 203 result |= - (1 << shift); 204 205 *r = result; 206 return buf; 207} 208 209/* Read unaligned data from the instruction buffer. */ 210 211union unaligned { 212 void *p; 213 unsigned b2 __attribute__ ((mode (HI))); 214 unsigned b4 __attribute__ ((mode (SI))); 215 unsigned b8 __attribute__ ((mode (DI))); 216} __attribute__ ((packed)); 217static inline void * 218read_pointer (void *p) 219{ union unaligned *up = p; return up->p; } 220static inline unsigned 221read_1byte (void *p) 222{ return *(unsigned char *)p; } 223static inline unsigned 224read_2byte (void *p) 225{ union unaligned *up = p; return up->b2; } 226static inline unsigned 227read_4byte (void *p) 228{ union unaligned *up = p; return up->b4; } 229static inline unsigned long 230read_8byte (void *p) 231{ union unaligned *up = p; return up->b8; } 232 233/* Ordering function for FDEs. Functions can't overlap, so we just compare 234 their starting addresses. */ 235 236static inline saddr 237fde_compare (fde *x, fde *y) 238{ 239 return (saddr)x->pc_begin - (saddr)y->pc_begin; 240} 241 242/* Return the address of the FDE after P. */ 243 244static inline fde * 245next_fde (fde *p) 246{ 247 return (fde *)(((char *)p) + p->length + sizeof (p->length)); 248} 249 250/* Sorting an array of FDEs by address. 251 (Ideally we would have the linker sort the FDEs so we don't have to do 252 it at run time. But the linkers are not yet prepared for this.) */ 253 254/* This is a special mix of insertion sort and heap sort, optimized for 255 the data sets that actually occur. They look like 256 101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130. 257 I.e. a linearly increasing sequence (coming from functions in the text 258 section), with additionally a few unordered elements (coming from functions 259 in gnu_linkonce sections) whose values are higher than the values in the 260 surrounding linear sequence (but not necessarily higher than the values 261 at the end of the linear sequence!). 262 The worst-case total run time is O(N) + O(n log (n)), where N is the 263 total number of FDEs and n is the number of erratic ones. */ 264 265typedef struct fde_vector 266{ 267 fde **array; 268 size_t count; 269} fde_vector; 270 271typedef struct fde_accumulator 272{ 273 fde_vector linear; 274 fde_vector erratic; 275} fde_accumulator; 276 277static inline void 278start_fde_sort (fde_accumulator *accu, size_t count) 279{ 280 accu->linear.array = (fde **) malloc (sizeof (fde *) * count); 281 accu->erratic.array = (fde **) malloc (sizeof (fde *) * count); 282 accu->linear.count = 0; 283 accu->erratic.count = 0; 284} 285 286static inline void 287fde_insert (fde_accumulator *accu, fde *this_fde) 288{ 289 accu->linear.array[accu->linear.count++] = this_fde; 290} 291 292/* Split LINEAR into a linear sequence with low values and an erratic 293 sequence with high values, put the linear one (of longest possible 294 length) into LINEAR and the erratic one into ERRATIC. This is O(N). */ 295static inline void 296fde_split (fde_vector *linear, fde_vector *erratic) 297{ 298 size_t count = linear->count; 299 size_t linear_max = (size_t) -1; 300 size_t previous_max[count]; 301 size_t i, j; 302 303 for (i = 0; i < count; i++) 304 { 305 for (j = linear_max; 306 j != (size_t) -1 307 && fde_compare (linear->array[i], linear->array[j]) < 0; 308 j = previous_max[j]) 309 { 310 erratic->array[erratic->count++] = linear->array[j]; 311 linear->array[j] = (fde *) NULL; 312 } 313 previous_max[i] = j; 314 linear_max = i; 315 } 316 317 for (i = 0, j = 0; i < count; i++) 318 if (linear->array[i] != (fde *) NULL) 319 linear->array[j++] = linear->array[i]; 320 linear->count = j; 321} 322 323/* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must 324 use a name that does not conflict. */ 325static inline void 326frame_heapsort (fde_vector *erratic) 327{ 328 /* For a description of this algorithm, see: 329 Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed., 330 p. 60-61. */ 331 fde ** a = erratic->array; 332 /* A portion of the array is called a "heap" if for all i>=0: 333 If i and 2i+1 are valid indices, then a[i] >= a[2i+1]. 334 If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */ 335#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0) 336 size_t n = erratic->count; 337 size_t m = n; 338 size_t i; 339 340 while (m > 0) 341 { 342 /* Invariant: a[m..n-1] is a heap. */ 343 m--; 344 for (i = m; 2*i+1 < n; ) 345 { 346 if (2*i+2 < n 347 && fde_compare (a[2*i+2], a[2*i+1]) > 0 348 && fde_compare (a[2*i+2], a[i]) > 0) 349 { 350 SWAP (a[i], a[2*i+2]); 351 i = 2*i+2; 352 } 353 else if (fde_compare (a[2*i+1], a[i]) > 0) 354 { 355 SWAP (a[i], a[2*i+1]); 356 i = 2*i+1; 357 } 358 else 359 break; 360 } 361 } 362 while (n > 1) 363 { 364 /* Invariant: a[0..n-1] is a heap. */ 365 n--; 366 SWAP (a[0], a[n]); 367 for (i = 0; 2*i+1 < n; ) 368 { 369 if (2*i+2 < n 370 && fde_compare (a[2*i+2], a[2*i+1]) > 0 371 && fde_compare (a[2*i+2], a[i]) > 0) 372 { 373 SWAP (a[i], a[2*i+2]); 374 i = 2*i+2; 375 } 376 else if (fde_compare (a[2*i+1], a[i]) > 0) 377 { 378 SWAP (a[i], a[2*i+1]); 379 i = 2*i+1; 380 } 381 else 382 break; 383 } 384 } 385#undef SWAP 386} 387 388/* Merge V1 and V2, both sorted, and put the result into V1. */ 389static void 390fde_merge (fde_vector *v1, const fde_vector *v2) 391{ 392 size_t i1, i2; 393 fde * fde2; 394 395 i2 = v2->count; 396 if (i2 > 0) 397 { 398 i1 = v1->count; 399 do { 400 i2--; 401 fde2 = v2->array[i2]; 402 while (i1 > 0 && fde_compare (v1->array[i1-1], fde2) > 0) 403 { 404 v1->array[i1+i2] = v1->array[i1-1]; 405 i1--; 406 } 407 v1->array[i1+i2] = fde2; 408 } while (i2 > 0); 409 v1->count += v2->count; 410 } 411} 412 413static fde ** 414end_fde_sort (fde_accumulator *accu, size_t count) 415{ 416 if (accu->linear.count != count) 417 abort (); 418 fde_split (&accu->linear, &accu->erratic); 419 if (accu->linear.count + accu->erratic.count != count) 420 abort (); 421 frame_heapsort (&accu->erratic); 422 fde_merge (&accu->linear, &accu->erratic); 423 free (accu->erratic.array); 424 return accu->linear.array; 425} 426 427static size_t 428count_fdes (fde *this_fde) 429{ 430 size_t count; 431 432 for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde)) 433 { 434 /* Skip CIEs and linked once FDE entries. */ 435 if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) 436 continue; 437 438 ++count; 439 } 440 441 return count; 442} 443 444static void 445add_fdes (fde *this_fde, fde_accumulator *accu, void **beg_ptr, void **end_ptr) 446{ 447 void *pc_begin = *beg_ptr; 448 void *pc_end = *end_ptr; 449 450 for (; this_fde->length != 0; this_fde = next_fde (this_fde)) 451 { 452 /* Skip CIEs and linked once FDE entries. */ 453 if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) 454 continue; 455 456 fde_insert (accu, this_fde); 457 458 if (this_fde->pc_begin < pc_begin) 459 pc_begin = this_fde->pc_begin; 460 if (this_fde->pc_begin + this_fde->pc_range > pc_end) 461 pc_end = this_fde->pc_begin + this_fde->pc_range; 462 } 463 464 *beg_ptr = pc_begin; 465 *end_ptr = pc_end; 466} 467 468/* Set up a sorted array of pointers to FDEs for a loaded object. We 469 count up the entries before allocating the array because it's likely to 470 be faster. */ 471 472static void 473frame_init (struct object* ob) 474{ 475 size_t count; 476 fde_accumulator accu; 477 void *pc_begin, *pc_end; 478 479 if (ob->fde_array) 480 { 481 fde **p = ob->fde_array; 482 for (count = 0; *p; ++p) 483 count += count_fdes (*p); 484 } 485 else 486 count = count_fdes (ob->fde_begin); 487 488 ob->count = count; 489 490 start_fde_sort (&accu, count); 491 pc_begin = (void*)(uaddr)-1; 492 pc_end = 0; 493 494 if (ob->fde_array) 495 { 496 fde **p = ob->fde_array; 497 for (; *p; ++p) 498 add_fdes (*p, &accu, &pc_begin, &pc_end); 499 } 500 else 501 add_fdes (ob->fde_begin, &accu, &pc_begin, &pc_end); 502 503 ob->fde_array = end_fde_sort (&accu, count); 504 ob->pc_begin = pc_begin; 505 ob->pc_end = pc_end; 506} 507 508/* Return a pointer to the FDE for the function containing PC. */ 509 510static fde * 511find_fde (void *pc) 512{ 513 struct object *ob; 514 size_t lo, hi; 515 516 init_object_mutex_once (); 517 __gthread_mutex_lock (&object_mutex); 518 519 for (ob = objects; ob; ob = ob->next) 520 { 521 if (ob->pc_begin == 0) 522 frame_init (ob); 523 if (pc >= ob->pc_begin && pc < ob->pc_end) 524 break; 525 } 526 527 __gthread_mutex_unlock (&object_mutex); 528 529 if (ob == 0) 530 return 0; 531 532 /* Standard binary search algorithm. */ 533 for (lo = 0, hi = ob->count; lo < hi; ) 534 { 535 size_t i = (lo + hi) / 2; 536 fde *f = ob->fde_array[i]; 537 538 if (pc < f->pc_begin) 539 hi = i; 540 else if (pc >= f->pc_begin + f->pc_range) 541 lo = i + 1; 542 else 543 return f; 544 } 545 546 return 0; 547} 548 549static inline struct dwarf_cie * 550get_cie (fde *f) 551{ 552 return ((void *)&f->CIE_delta) - f->CIE_delta; 553} 554 555/* Extract any interesting information from the CIE for the translation 556 unit F belongs to. */ 557 558static void * 559extract_cie_info (fde *f, struct cie_info *c) 560{ 561 void *p; 562 int i; 563 564 c->augmentation = get_cie (f)->augmentation; 565 566 if (strcmp (c->augmentation, "") != 0 567 && strcmp (c->augmentation, "eh") != 0 568 && c->augmentation[0] != 'z') 569 return 0; 570 571 p = c->augmentation + strlen (c->augmentation) + 1; 572 573 if (strcmp (c->augmentation, "eh") == 0) 574 { 575 c->eh_ptr = read_pointer (p); 576 p += sizeof (void *); 577 } 578 else 579 c->eh_ptr = 0; 580 581 p = decode_uleb128 (p, &c->code_align); 582 p = decode_sleb128 (p, &c->data_align); 583 c->ra_regno = *(unsigned char *)p++; 584 585 /* If the augmentation starts with 'z', we now see the length of the 586 augmentation fields. */ 587 if (c->augmentation[0] == 'z') 588 { 589 p = decode_uleb128 (p, &i); 590 p += i; 591 } 592 593 return p; 594} 595 596/* Decode one instruction's worth of DWARF 2 call frame information. 597 Used by __frame_state_for. Takes pointers P to the instruction to 598 decode, STATE to the current register unwind information, INFO to the 599 current CIE information, and PC to the current PC value. Returns a 600 pointer to the next instruction. */ 601 602static void * 603execute_cfa_insn (void *p, struct frame_state_internal *state, 604 struct cie_info *info, void **pc) 605{ 606 unsigned insn = *(unsigned char *)p++; 607 unsigned reg; 608 int offset; 609 610 if (insn & DW_CFA_advance_loc) 611 *pc += ((insn & 0x3f) * info->code_align); 612 else if (insn & DW_CFA_offset) 613 { 614 reg = (insn & 0x3f); 615 p = decode_uleb128 (p, &offset); 616 offset *= info->data_align; 617 state->s.saved[reg] = REG_SAVED_OFFSET; 618 state->s.reg_or_offset[reg] = offset; 619 } 620 else if (insn & DW_CFA_restore) 621 { 622 reg = (insn & 0x3f); 623 state->s.saved[reg] = REG_UNSAVED; 624 } 625 else switch (insn) 626 { 627 case DW_CFA_set_loc: 628 *pc = read_pointer (p); 629 p += sizeof (void *); 630 break; 631 case DW_CFA_advance_loc1: 632 *pc += read_1byte (p); 633 p += 1; 634 break; 635 case DW_CFA_advance_loc2: 636 *pc += read_2byte (p); 637 p += 2; 638 break; 639 case DW_CFA_advance_loc4: 640 *pc += read_4byte (p); 641 p += 4; 642 break; 643 644 case DW_CFA_offset_extended: 645 p = decode_uleb128 (p, ®); 646 p = decode_uleb128 (p, &offset); 647 offset *= info->data_align; 648 state->s.saved[reg] = REG_SAVED_OFFSET; 649 state->s.reg_or_offset[reg] = offset; 650 break; 651 case DW_CFA_restore_extended: 652 p = decode_uleb128 (p, ®); 653 state->s.saved[reg] = REG_UNSAVED; 654 break; 655 656 case DW_CFA_undefined: 657 case DW_CFA_same_value: 658 case DW_CFA_nop: 659 break; 660 661 case DW_CFA_register: 662 { 663 unsigned reg2; 664 p = decode_uleb128 (p, ®); 665 p = decode_uleb128 (p, ®2); 666 state->s.saved[reg] = REG_SAVED_REG; 667 state->s.reg_or_offset[reg] = reg2; 668 } 669 break; 670 671 case DW_CFA_def_cfa: 672 p = decode_uleb128 (p, ®); 673 p = decode_uleb128 (p, &offset); 674 state->s.cfa_reg = reg; 675 state->s.cfa_offset = offset; 676 break; 677 case DW_CFA_def_cfa_register: 678 p = decode_uleb128 (p, ®); 679 state->s.cfa_reg = reg; 680 break; 681 case DW_CFA_def_cfa_offset: 682 p = decode_uleb128 (p, &offset); 683 state->s.cfa_offset = offset; 684 break; 685 686 case DW_CFA_remember_state: 687 { 688 struct frame_state_internal *save = 689 (struct frame_state_internal *) 690 malloc (sizeof (struct frame_state_internal)); 691 memcpy (save, state, sizeof (struct frame_state_internal)); 692 state->saved_state = save; 693 } 694 break; 695 case DW_CFA_restore_state: 696 { 697 struct frame_state_internal *save = state->saved_state; 698 memcpy (state, save, sizeof (struct frame_state_internal)); 699 free (save); 700 } 701 break; 702 703 /* FIXME: Hardcoded for SPARC register window configuration. */ 704 case DW_CFA_GNU_window_save: 705 for (reg = 16; reg < 32; ++reg) 706 { 707 state->s.saved[reg] = REG_SAVED_OFFSET; 708 state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *); 709 } 710 break; 711 712 case DW_CFA_GNU_args_size: 713 p = decode_uleb128 (p, &offset); 714 state->s.args_size = offset; 715 break; 716 717 case DW_CFA_GNU_negative_offset_extended: 718 p = decode_uleb128 (p, ®); 719 p = decode_uleb128 (p, &offset); 720 offset *= info->data_align; 721 state->s.saved[reg] = REG_SAVED_OFFSET; 722 state->s.reg_or_offset[reg] = -offset; 723 break; 724 725 default: 726 abort (); 727 } 728 return p; 729} 730 731/* Called from crtbegin.o to register the unwind info for an object. */ 732 733void 734__register_frame_info (void *begin, struct object *ob) 735{ 736 ob->fde_begin = begin; 737 738 ob->pc_begin = ob->pc_end = 0; 739 ob->fde_array = 0; 740 ob->count = 0; 741 742 init_object_mutex_once (); 743 __gthread_mutex_lock (&object_mutex); 744 745 ob->next = objects; 746 objects = ob; 747 748 __gthread_mutex_unlock (&object_mutex); 749} 750 751void 752__register_frame (void *begin) 753{ 754 struct object *ob = (struct object *) malloc (sizeof (struct object)); 755 __register_frame_info (begin, ob); 756} 757 758/* Similar, but BEGIN is actually a pointer to a table of unwind entries 759 for different translation units. Called from the file generated by 760 collect2. */ 761 762void 763__register_frame_info_table (void *begin, struct object *ob) 764{ 765 ob->fde_begin = begin; 766 ob->fde_array = begin; 767 768 ob->pc_begin = ob->pc_end = 0; 769 ob->count = 0; 770 771 init_object_mutex_once (); 772 __gthread_mutex_lock (&object_mutex); 773 774 ob->next = objects; 775 objects = ob; 776 777 __gthread_mutex_unlock (&object_mutex); 778} 779 780void 781__register_frame_table (void *begin) 782{ 783 struct object *ob = (struct object *) malloc (sizeof (struct object)); 784 __register_frame_info_table (begin, ob); 785} 786 787/* Called from crtbegin.o to deregister the unwind info for an object. */ 788 789void * 790__deregister_frame_info (void *begin) 791{ 792 struct object **p; 793 794 init_object_mutex_once (); 795 __gthread_mutex_lock (&object_mutex); 796 797 p = &objects; 798 while (*p) 799 { 800 if ((*p)->fde_begin == begin) 801 { 802 struct object *ob = *p; 803 *p = (*p)->next; 804 805 /* If we've run init_frame for this object, free the FDE array. */ 806 if (ob->pc_begin) 807 free (ob->fde_array); 808 809 __gthread_mutex_unlock (&object_mutex); 810 return (void *) ob; 811 } 812 p = &((*p)->next); 813 } 814 815 __gthread_mutex_unlock (&object_mutex); 816 abort (); 817} 818 819void 820__deregister_frame (void *begin) 821{ 822 free (__deregister_frame_info (begin)); 823} 824 825/* Called from __throw to find the registers to restore for a given 826 PC_TARGET. The caller should allocate a local variable of `struct 827 frame_state' (declared in frame.h) and pass its address to STATE_IN. */ 828 829struct frame_state * 830__frame_state_for (void *pc_target, struct frame_state *state_in) 831{ 832 fde *f; 833 void *insn, *end, *pc; 834 struct cie_info info; 835 struct frame_state_internal state; 836 837 f = find_fde (pc_target); 838 if (f == 0) 839 return 0; 840 841 insn = extract_cie_info (f, &info); 842 if (insn == 0) 843 return 0; 844 845 memset (&state, 0, sizeof (state)); 846 state.s.retaddr_column = info.ra_regno; 847 state.s.eh_ptr = info.eh_ptr; 848 849 /* First decode all the insns in the CIE. */ 850 end = next_fde ((fde*) get_cie (f)); 851 while (insn < end) 852 insn = execute_cfa_insn (insn, &state, &info, 0); 853 854 insn = ((fde *)f) + 1; 855 856 if (info.augmentation[0] == 'z') 857 { 858 int i; 859 insn = decode_uleb128 (insn, &i); 860 insn += i; 861 } 862 863 /* Then the insns in the FDE up to our target PC. */ 864 end = next_fde (f); 865 pc = f->pc_begin; 866 while (insn < end && pc <= pc_target) 867 insn = execute_cfa_insn (insn, &state, &info, &pc); 868 869 memcpy (state_in, &state.s, sizeof (state.s)); 870 return state_in; 871} 872#endif /* DWARF2_UNWIND_INFO */ 873