GNU Binutils with patches for OS216
Revisión | f4ab3f81e8643c5b4c865df463f0cba56062ba96 (tree) |
---|---|
Tiempo | 2003-03-07 04:21:30 |
Autor | Andrew Cagney <cagney@redh...> |
Commiter | Andrew Cagney |
2003-03-06 Andrew Cagney <cagney@redhat.com>
* gdbarch.sh (gdbarch_unwind_pc): New method.
* gdbarch.h, gdbarch.c: Regenerate.
* frame.c (frame_pc_unwind): Rewrite. Prefer gdbarch_unwind_pc,
but use read_pc and FRAME_SAVED_PC as fall backs.
(frame_saved_regs_pc_unwind): Delete function.
(trad_frame_unwinder): Update.
* frame-unwind.h (frame_unwind_pc_ftype): Delete declaration.
(struct frame_unwind): Update.
* dummy-frame.c (dummy_frame_pc_unwind): Delete function.
(dummy_frame_unwind): Update.
* sentinel-frame.c (sentinel_frame_pc_unwind): Delete function.
(sentinel_frame_unwinder): Update.
* d10v-tdep.c (d10v_frame_pc_unwind): Delete function.
(d10v_frame_unwind): Update.
(d10v_unwind_pc): New function.
(d10v_gdbarch_init): Set unwind_pc.
2003-03-05 Andrew Cagney <cagney@redhat.com>
* dummy-frame.c (dummy_frame_id_unwind): Abort if called.
(cached_find_dummy_frame): Add hack to obtain this thread's id
without calling id unwind.
* frame.h: Merge with mainline.
* d10v-tdep.c: Merge with mainline.
* frame.c: Merge with mainline.
@@ -1,3 +1,31 @@ | ||
1 | +2003-03-06 Andrew Cagney <cagney@redhat.com> | |
2 | + | |
3 | + * gdbarch.sh (gdbarch_unwind_pc): New method. | |
4 | + * gdbarch.h, gdbarch.c: Regenerate. | |
5 | + * frame.c (frame_pc_unwind): Rewrite. Prefer gdbarch_unwind_pc, | |
6 | + but use read_pc and FRAME_SAVED_PC as fall backs. | |
7 | + (frame_saved_regs_pc_unwind): Delete function. | |
8 | + (trad_frame_unwinder): Update. | |
9 | + * frame-unwind.h (frame_unwind_pc_ftype): Delete declaration. | |
10 | + (struct frame_unwind): Update. | |
11 | + * dummy-frame.c (dummy_frame_pc_unwind): Delete function. | |
12 | + (dummy_frame_unwind): Update. | |
13 | + * sentinel-frame.c (sentinel_frame_pc_unwind): Delete function. | |
14 | + (sentinel_frame_unwinder): Update. | |
15 | + * d10v-tdep.c (d10v_frame_pc_unwind): Delete function. | |
16 | + (d10v_frame_unwind): Update. | |
17 | + (d10v_unwind_pc): New function. | |
18 | + (d10v_gdbarch_init): Set unwind_pc. | |
19 | + | |
20 | +2003-03-05 Andrew Cagney <cagney@redhat.com> | |
21 | + | |
22 | + * dummy-frame.c (dummy_frame_id_unwind): Abort if called. | |
23 | + (cached_find_dummy_frame): Add hack to obtain this thread's id | |
24 | + without calling id unwind. | |
25 | + * frame.h: Merge with mainline. | |
26 | + * d10v-tdep.c: Merge with mainline. | |
27 | + * frame.c: Merge with mainline. | |
28 | + | |
1 | 29 | 2003-03-04 Andrew Cagney <cagney@redhat.com> |
2 | 30 | |
3 | 31 | * d10v-tdep.c (struct d10v_unwind_cache): Add field "r11_addr", |
@@ -616,8 +616,11 @@ struct d10v_unwind_cache | ||
616 | 616 | CORE_ADDR base; |
617 | 617 | int size; |
618 | 618 | CORE_ADDR *saved_regs; |
619 | - LONGEST next_addr; | |
620 | - LONGEST r11_addr; | |
619 | + /* How far the SP and r11 (FP) have been offset from the start of | |
620 | + the stack frame (as defined by the previous frame's stack | |
621 | + pointer). */ | |
622 | + LONGEST sp_offset; | |
623 | + LONGEST r11_offset; | |
621 | 624 | int uses_frame; |
622 | 625 | void **regs; |
623 | 626 | }; |
@@ -632,8 +635,8 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
632 | 635 | if ((op & 0x7E1F) == 0x6C1F) |
633 | 636 | { |
634 | 637 | n = (op & 0x1E0) >> 5; |
635 | - info->next_addr -= 2; | |
636 | - info->saved_regs[n] = info->next_addr; | |
638 | + info->sp_offset -= 2; | |
639 | + info->saved_regs[n] = info->sp_offset; | |
637 | 640 | return 1; |
638 | 641 | } |
639 | 642 |
@@ -641,9 +644,9 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
641 | 644 | else if ((op & 0x7E3F) == 0x6E1F) |
642 | 645 | { |
643 | 646 | n = (op & 0x1E0) >> 5; |
644 | - info->next_addr -= 4; | |
645 | - info->saved_regs[n] = info->next_addr; | |
646 | - info->saved_regs[n + 1] = info->next_addr + 2; | |
647 | + info->sp_offset -= 4; | |
648 | + info->saved_regs[n] = info->sp_offset; | |
649 | + info->saved_regs[n + 1] = info->sp_offset + 2; | |
647 | 650 | return 1; |
648 | 651 | } |
649 | 652 |
@@ -653,7 +656,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
653 | 656 | n = (op & 0x1E) >> 1; |
654 | 657 | if (n == 0) |
655 | 658 | n = 16; |
656 | - info->next_addr -= n; | |
659 | + info->sp_offset -= n; | |
657 | 660 | return 1; |
658 | 661 | } |
659 | 662 |
@@ -661,7 +664,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
661 | 664 | if (op == 0x417E) |
662 | 665 | { |
663 | 666 | info->uses_frame = 1; |
664 | - info->r11_addr = info->next_addr; | |
667 | + info->r11_offset = info->sp_offset; | |
665 | 668 | return 1; |
666 | 669 | } |
667 | 670 |
@@ -669,7 +672,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
669 | 672 | if ((op & 0x7E1F) == 0x6816) |
670 | 673 | { |
671 | 674 | n = (op & 0x1E0) >> 5; |
672 | - info->saved_regs[n] = info->r11_addr; | |
675 | + info->saved_regs[n] = info->r11_offset; | |
673 | 676 | return 1; |
674 | 677 | } |
675 | 678 |
@@ -681,7 +684,7 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
681 | 684 | if ((op & 0x7E1F) == 0x681E) |
682 | 685 | { |
683 | 686 | n = (op & 0x1E0) >> 5; |
684 | - info->saved_regs[n] = info->next_addr; | |
687 | + info->saved_regs[n] = info->sp_offset; | |
685 | 688 | return 1; |
686 | 689 | } |
687 | 690 |
@@ -689,8 +692,8 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, | ||
689 | 692 | if ((op & 0x7E3F) == 0x3A1E) |
690 | 693 | { |
691 | 694 | n = (op & 0x1E0) >> 5; |
692 | - info->saved_regs[n] = info->next_addr; | |
693 | - info->saved_regs[n + 1] = info->next_addr + 2; | |
695 | + info->saved_regs[n] = info->sp_offset; | |
696 | + info->saved_regs[n + 1] = info->sp_offset + 2; | |
694 | 697 | return 1; |
695 | 698 | } |
696 | 699 |
@@ -708,8 +711,8 @@ d10v_frame_unwind_cache (struct frame_info *next_frame, | ||
708 | 711 | void **this_cache) |
709 | 712 | { |
710 | 713 | CORE_ADDR pc; |
711 | - ULONGEST sp; | |
712 | - ULONGEST base; | |
714 | + ULONGEST prev_sp; | |
715 | + ULONGEST this_base; | |
713 | 716 | unsigned long op; |
714 | 717 | unsigned short op1, op2; |
715 | 718 | int i; |
@@ -724,7 +727,7 @@ d10v_frame_unwind_cache (struct frame_info *next_frame, | ||
724 | 727 | |
725 | 728 | info->size = 0; |
726 | 729 | |
727 | - info->next_addr = 0; | |
730 | + info->sp_offset = 0; | |
728 | 731 | |
729 | 732 | pc = get_pc_function_start (frame_pc_unwind (next_frame)); |
730 | 733 |
@@ -739,22 +742,22 @@ d10v_frame_unwind_cache (struct frame_info *next_frame, | ||
739 | 742 | { |
740 | 743 | /* add3 sp,sp,n */ |
741 | 744 | short n = op & 0xFFFF; |
742 | - info->next_addr += n; | |
745 | + info->sp_offset += n; | |
743 | 746 | } |
744 | 747 | else if ((op & 0x3F0F0000) == 0x340F0000) |
745 | 748 | { |
746 | 749 | /* st rn, @(offset,sp) */ |
747 | 750 | short offset = op & 0xFFFF; |
748 | 751 | short n = (op >> 20) & 0xF; |
749 | - info->saved_regs[n] = info->next_addr + offset; | |
752 | + info->saved_regs[n] = info->sp_offset + offset; | |
750 | 753 | } |
751 | 754 | else if ((op & 0x3F1F0000) == 0x350F0000) |
752 | 755 | { |
753 | 756 | /* st2w rn, @(offset,sp) */ |
754 | 757 | short offset = op & 0xFFFF; |
755 | 758 | short n = (op >> 20) & 0xF; |
756 | - info->saved_regs[n] = info->next_addr + offset; | |
757 | - info->saved_regs[n + 1] = info->next_addr + offset + 2; | |
759 | + info->saved_regs[n] = info->sp_offset + offset; | |
760 | + info->saved_regs[n + 1] = info->sp_offset + offset + 2; | |
758 | 761 | } |
759 | 762 | else |
760 | 763 | break; |
@@ -779,52 +782,50 @@ d10v_frame_unwind_cache (struct frame_info *next_frame, | ||
779 | 782 | pc += 4; |
780 | 783 | } |
781 | 784 | |
782 | - info->size = -info->next_addr; | |
785 | + info->size = -info->sp_offset; | |
783 | 786 | |
784 | - /* Compute the frame's base. */ | |
787 | + /* Compute the frame's base, and the previous frame's SP. */ | |
785 | 788 | if (info->uses_frame) |
786 | 789 | { |
787 | - /* The SP was moved into the FP. This indicates that a new | |
788 | - frame was created. Get THIS frame's FP value by unwinding it | |
789 | - from the next frame. */ | |
790 | - frame_unwind_unsigned_register (next_frame, FP_REGNUM, &base); | |
790 | + /* The SP was moved to the FP. This indicates that a new frame | |
791 | + was created. Get THIS frame's FP value by unwinding it from | |
792 | + the next frame. */ | |
793 | + frame_unwind_unsigned_register (next_frame, FP_REGNUM, &this_base); | |
791 | 794 | /* The FP points at the last saved register. Adjust the FP back |
792 | 795 | to before the first saved register giving the SP. */ |
793 | - sp = base + info->size; | |
796 | + prev_sp = this_base + info->size; | |
794 | 797 | } |
795 | 798 | else if (info->saved_regs[SP_REGNUM]) |
796 | 799 | { |
797 | 800 | /* The SP was saved (which is very unusual), the frame base is |
798 | 801 | just the PREV's frame's TOP-OF-STACK. */ |
799 | - base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM], | |
800 | - register_size (current_gdbarch, | |
801 | - SP_REGNUM)); | |
802 | - sp = base; | |
802 | + this_base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM], | |
803 | + register_size (current_gdbarch, | |
804 | + SP_REGNUM)); | |
805 | + prev_sp = this_base; | |
803 | 806 | } |
804 | 807 | else |
805 | 808 | { |
806 | 809 | /* Assume that the FP is this frame's SP but with that pushed |
807 | 810 | stack space added back. */ |
808 | - frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base); | |
809 | - sp = base + info->size; | |
811 | + frame_unwind_unsigned_register (next_frame, SP_REGNUM, &this_base); | |
812 | + prev_sp = this_base + info->size; | |
810 | 813 | } |
811 | 814 | |
812 | - info->base = d10v_make_daddr (base); | |
813 | - sp = d10v_make_daddr (sp); | |
815 | + info->base = d10v_make_daddr (this_base); | |
816 | + prev_sp = d10v_make_daddr (prev_sp); | |
814 | 817 | |
815 | 818 | /* Adjust all the saved registers so that they contain addresses and |
816 | 819 | not offsets. */ |
817 | 820 | for (i = 0; i < NUM_REGS - 1; i++) |
818 | - { | |
819 | - if (info->saved_regs[i]) | |
820 | - { | |
821 | - info->saved_regs[i] = (sp + info->saved_regs[i]); | |
822 | - } | |
823 | - } | |
821 | + if (info->saved_regs[i]) | |
822 | + { | |
823 | + info->saved_regs[i] = (prev_sp + info->saved_regs[i]); | |
824 | + } | |
824 | 825 | |
825 | 826 | /* The SP_REGNUM is special. Instead of the address of the SP, the |
826 | 827 | previous frame's SP value is saved. */ |
827 | - info->saved_regs[SP_REGNUM] = sp; | |
828 | + info->saved_regs[SP_REGNUM] = prev_sp; | |
828 | 829 | |
829 | 830 | return info; |
830 | 831 | } |
@@ -1432,22 +1433,12 @@ display_trace (int low, int high) | ||
1432 | 1433 | } |
1433 | 1434 | } |
1434 | 1435 | |
1435 | - | |
1436 | 1436 | static CORE_ADDR |
1437 | -d10v_frame_pc_unwind (struct frame_info *next_frame, | |
1438 | - void **this_cache) | |
1437 | +d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) | |
1439 | 1438 | { |
1440 | - /* FIXME: This shouldn't be needed. Instead single per-architecture | |
1441 | - method should be called for all frames. */ | |
1442 | - CORE_ADDR lr; | |
1443 | - struct d10v_unwind_cache *info | |
1444 | - = d10v_frame_unwind_cache (next_frame, this_cache); | |
1445 | - void *buffer = alloca (max_register_size (current_gdbarch)); | |
1446 | - saved_regs_unwind (next_frame, info->saved_regs, LR_REGNUM, buffer); | |
1447 | - lr = extract_unsigned_integer (buffer, register_size (current_gdbarch, | |
1448 | - LR_REGNUM)); | |
1449 | - return d10v_make_iaddr (lr); | |
1450 | - | |
1439 | + ULONGEST pc; | |
1440 | + frame_unwind_unsigned_register (next_frame, PC_REGNUM, &pc); | |
1441 | + return d10v_make_iaddr (pc); | |
1451 | 1442 | } |
1452 | 1443 | |
1453 | 1444 | /* Given the next frame, determine the address of this function's |
@@ -1587,18 +1578,6 @@ d10v_frame_register_unwind (struct frame_info *next_frame, | ||
1587 | 1578 | lvalp, addrp, realnump, bufferp); |
1588 | 1579 | } |
1589 | 1580 | |
1590 | - | |
1591 | -static struct frame_id | |
1592 | -d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) | |
1593 | -{ | |
1594 | - ULONGEST base; | |
1595 | - struct frame_id id; | |
1596 | - id.pc = frame_pc_unwind (next_frame); | |
1597 | - frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base); | |
1598 | - id.base = d10v_make_daddr (base); | |
1599 | - return id; | |
1600 | -} | |
1601 | - | |
1602 | 1581 | static void |
1603 | 1582 | d10v_frame_pop (struct frame_info *next_frame, void **this_cache, |
1604 | 1583 | struct regcache *regcache) |
@@ -1635,7 +1614,6 @@ d10v_frame_pop (struct frame_info *next_frame, void **this_cache, | ||
1635 | 1614 | |
1636 | 1615 | static struct frame_unwind d10v_frame_unwind = { |
1637 | 1616 | d10v_frame_pop, |
1638 | - d10v_frame_pc_unwind, | |
1639 | 1617 | d10v_frame_id_unwind, |
1640 | 1618 | d10v_frame_register_unwind |
1641 | 1619 | }; |
@@ -1646,6 +1624,22 @@ d10v_frame_p (CORE_ADDR pc) | ||
1646 | 1624 | return &d10v_frame_unwind; |
1647 | 1625 | } |
1648 | 1626 | |
1627 | +/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that | |
1628 | + dummy frame. The frame ID's base needs to match the TOS value | |
1629 | + saved by save_dummy_frame_tos(), and the PC match the dummy frame's | |
1630 | + breakpoint. */ | |
1631 | + | |
1632 | +static struct frame_id | |
1633 | +d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) | |
1634 | +{ | |
1635 | + ULONGEST base; | |
1636 | + struct frame_id id; | |
1637 | + id.pc = frame_pc_unwind (next_frame); | |
1638 | + frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base); | |
1639 | + id.base = d10v_make_daddr (base); | |
1640 | + return id; | |
1641 | +} | |
1642 | + | |
1649 | 1643 | static gdbarch_init_ftype d10v_gdbarch_init; |
1650 | 1644 | |
1651 | 1645 | static struct gdbarch * |
@@ -1782,9 +1776,14 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | ||
1782 | 1776 | set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info); |
1783 | 1777 | |
1784 | 1778 | frame_unwind_append_predicate (gdbarch, d10v_frame_p); |
1779 | + | |
1780 | + /* Methods for saving / extracting a dummy frame's ID. */ | |
1785 | 1781 | set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id); |
1786 | 1782 | set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); |
1787 | 1783 | |
1784 | + /* Return the unwound PC value. */ | |
1785 | + set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc); | |
1786 | + | |
1788 | 1787 | return gdbarch; |
1789 | 1788 | } |
1790 | 1789 |
@@ -108,8 +108,13 @@ struct dummy_frame * | ||
108 | 108 | cached_find_dummy_frame (struct frame_info *next_frame, void **this_cache) |
109 | 109 | { |
110 | 110 | if ((*this_cache) == NULL) |
111 | - (*this_cache) = find_dummy_frame (frame_pc_unwind (next_frame), | |
112 | - frame_id_unwind (next_frame).base); | |
111 | + { | |
112 | + /* FIXME: hack to find the frame ID of this frame. Need to do | |
113 | + this better. */ | |
114 | + gdb_assert (next_frame->prev != NULL); | |
115 | + (*this_cache) = find_dummy_frame (frame_pc_unwind (next_frame), | |
116 | + next_frame->prev->frame); | |
117 | + } | |
113 | 118 | return (*this_cache); |
114 | 119 | } |
115 | 120 |
@@ -371,23 +376,6 @@ dummy_frame_register_unwind (struct frame_info *next_frame, void **this_cache, | ||
371 | 376 | } |
372 | 377 | } |
373 | 378 | |
374 | -/* Assuming that FRAME is a dummy, return the resume address for the | |
375 | - previous frame. */ | |
376 | - | |
377 | -static CORE_ADDR | |
378 | -dummy_frame_pc_unwind (struct frame_info *next_frame, | |
379 | - void **this_cache) | |
380 | -{ | |
381 | - struct dummy_frame *dummy = cached_find_dummy_frame (next_frame, this_cache); | |
382 | - /* Oops! In a dummy-frame but can't find the stack dummy. Pretend | |
383 | - that the frame doesn't unwind. Should this function instead | |
384 | - return a has-no-caller indication? */ | |
385 | - if (dummy == NULL) | |
386 | - return 0; | |
387 | - return dummy->pc; | |
388 | -} | |
389 | - | |
390 | - | |
391 | 379 | /* Assuming that FRAME is a dummy, return the ID of the calling frame |
392 | 380 | (the frame that the dummy has the saved state of). */ |
393 | 381 |
@@ -396,6 +384,7 @@ dummy_frame_id_unwind (struct frame_info *next_frame, | ||
396 | 384 | void **this_cache, |
397 | 385 | struct frame_id *this_id) |
398 | 386 | { |
387 | +#if 0 | |
399 | 388 | struct dummy_frame *dummy = cached_find_dummy_frame (next_frame, this_cache); |
400 | 389 | /* Oops! In a dummy-frame but can't find the stack dummy. Pretend |
401 | 390 | that the frame doesn't unwind. Should this function instead |
@@ -404,12 +393,19 @@ dummy_frame_id_unwind (struct frame_info *next_frame, | ||
404 | 393 | (*this_id) = null_frame_id; |
405 | 394 | else |
406 | 395 | (*this_id) = dummy->id; |
396 | +#else | |
397 | + /* FIXME - with all the frames shuffled by one, it becomes possible | |
398 | + to move the dummy frame unwind code to here. This is because, | |
399 | + unlike the mainline, this function is called when determining the | |
400 | + ID of the dummy, and not the ID of the dummy's caller. For the | |
401 | + moment, this function is never called. */ | |
402 | + internal_error (__FILE__, __LINE__, "dummy_frame_pc_unwind called"); | |
403 | +#endif | |
407 | 404 | } |
408 | 405 | |
409 | 406 | static struct frame_unwind dummy_frame_unwind = |
410 | 407 | { |
411 | 408 | dummy_frame_pop, |
412 | - dummy_frame_pc_unwind, | |
413 | 409 | dummy_frame_id_unwind, |
414 | 410 | dummy_frame_register_unwind |
415 | 411 | }; |
@@ -104,26 +104,6 @@ typedef void (frame_unwind_reg_ftype) (struct frame_info *next_frame, | ||
104 | 104 | |
105 | 105 | /* Assuming the frame chain: (outer) prev <-> this <-> next (inner); |
106 | 106 | use the NEXT frame, and its register unwind method, to unwind THIS |
107 | - frame's PC, returning the value of PC (the return address) in PREV | |
108 | - frame. | |
109 | - | |
110 | - Traditionally, THIS frame's PC was unwound by examining THIS | |
111 | - frame's function prolog and identifying where (in a register or on | |
112 | - the stack) that return address was saved. | |
113 | - | |
114 | - Please note that this per-frame method may be superseeded by an | |
115 | - architecture specific method that determines the unwound PC (aka | |
116 | - return address) using just the register unwind methods. | |
117 | - | |
118 | - THIS_CACHE can be used to share any prologue analysis data with the | |
119 | - other unwind methods. Memory for that cache should be allocated | |
120 | - using frame_obstack_zalloc(). */ | |
121 | - | |
122 | -typedef CORE_ADDR (frame_unwind_pc_ftype) (struct frame_info *next_frame, | |
123 | - void **this_cache); | |
124 | - | |
125 | -/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); | |
126 | - use the NEXT frame, and its register unwind method, to unwind THIS | |
127 | 107 | frame's entire stack, writing PREV's frames register values into |
128 | 108 | REGCACHE. |
129 | 109 |
@@ -151,7 +131,6 @@ struct frame_unwind | ||
151 | 131 | /* Should an attribute indicating the frame's address-in-block go |
152 | 132 | here? */ |
153 | 133 | frame_unwind_pop_ftype *pop; |
154 | - frame_unwind_pc_ftype *pc; | |
155 | 134 | frame_unwind_id_ftype *id; |
156 | 135 | frame_unwind_reg_ftype *reg; |
157 | 136 | }; |
@@ -135,27 +135,54 @@ frame_find_by_id (struct frame_id id) | ||
135 | 135 | } |
136 | 136 | |
137 | 137 | CORE_ADDR |
138 | -frame_pc_unwind (struct frame_info *this_frame) | |
138 | +frame_pc_unwind (struct frame_info *next_frame) | |
139 | 139 | { |
140 | - if (!this_frame->pc_unwind_cache_p) | |
140 | + if (!next_frame->pc_unwind_cache_p) | |
141 | 141 | { |
142 | - this_frame->pc_unwind_cache | |
143 | - = this_frame->unwind->pc (this_frame->next, &this_frame->unwind_cache); | |
144 | - this_frame->pc_unwind_cache_p = 1; | |
145 | - } | |
146 | - return this_frame->pc_unwind_cache; | |
147 | -} | |
148 | - | |
149 | -struct frame_id | |
150 | -frame_id_unwind (struct frame_info *this_frame) | |
151 | -{ | |
152 | - if (!this_frame->id_unwind_cache_p) | |
153 | - { | |
154 | - this_frame->unwind->id (this_frame->next, &this_frame->unwind_cache, | |
155 | - &this_frame->id_unwind_cache); | |
156 | - this_frame->id_unwind_cache_p = 1; | |
142 | + CORE_ADDR pc; | |
143 | + if (gdbarch_unwind_pc_p (current_gdbarch)) | |
144 | + { | |
145 | + /* The right way. The `pure' way. The one true way. This | |
146 | + method depends solely on the register-unwind code to | |
147 | + determine the value of registers in THIS frame, and hence | |
148 | + the value of this frame's PC (resume address). A typical | |
149 | + implementation is no more than: | |
150 | + | |
151 | + frame_unwind_register (next_frame, ISA_PC_REGNUM, buf); | |
152 | + return extract_address (buf, size of ISA_PC_REGNUM); | |
153 | + | |
154 | + Note: this method is very heavily dependent on a correct | |
155 | + register-unwind implementation, it pays to fix that | |
156 | + method first; this method is frame type agnostic, since | |
157 | + it only deals with register values, it works with any | |
158 | + frame. This is all in stark contrast to the old | |
159 | + FRAME_SAVED_PC which would try to directly handle all the | |
160 | + different ways that a PC could be unwound. */ | |
161 | + pc = gdbarch_unwind_pc (current_gdbarch, next_frame); | |
162 | + } | |
163 | + else if (next_frame->level < 0) | |
164 | + { | |
165 | + /* FIXME: cagney/2003-03-06: Old code and and a sentinel | |
166 | + frame. Do like was always done. Fetch the PC's value | |
167 | + direct from the global registers array (via read_pc). | |
168 | + This assumes that this frame belongs to the current | |
169 | + global register cache. The assumption is dangerous. */ | |
170 | + pc = read_pc (); | |
171 | + } | |
172 | + else if (FRAME_SAVED_PC_P ()) | |
173 | + { | |
174 | + /* FIXME: cagney/2003-03-06: Old code, but not a sentinel | |
175 | + frame. Do like was always done. Note that this method, | |
176 | + unlike unwind_pc(), tries to handle all the different | |
177 | + frame cases directly. It fails. */ | |
178 | + pc = FRAME_SAVED_PC (next_frame); | |
179 | + } | |
180 | + else | |
181 | + internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method"); | |
182 | + next_frame->pc_unwind_cache = pc; | |
183 | + next_frame->pc_unwind_cache_p = 1; | |
157 | 184 | } |
158 | - return this_frame->id_unwind_cache; | |
185 | + return next_frame->pc_unwind_cache; | |
159 | 186 | } |
160 | 187 | |
161 | 188 | void |
@@ -682,13 +709,6 @@ frame_saved_regs_register_unwind (struct frame_info *frame, void **cache, | ||
682 | 709 | bufferp); |
683 | 710 | } |
684 | 711 | |
685 | -static CORE_ADDR | |
686 | -frame_saved_regs_pc_unwind (struct frame_info *frame, void **cache) | |
687 | -{ | |
688 | - gdb_assert (FRAME_SAVED_PC_P ()); | |
689 | - return FRAME_SAVED_PC (frame); | |
690 | -} | |
691 | - | |
692 | 712 | static void |
693 | 713 | frame_saved_regs_id_unwind (struct frame_info *next_frame, void **cache, |
694 | 714 | struct frame_id *id) |
@@ -760,7 +780,6 @@ frame_saved_regs_pop (struct frame_info *fi, void **cache, | ||
760 | 780 | |
761 | 781 | const struct frame_unwind trad_frame_unwinder = { |
762 | 782 | frame_saved_regs_pop, |
763 | - frame_saved_regs_pc_unwind, | |
764 | 783 | frame_saved_regs_id_unwind, |
765 | 784 | frame_saved_regs_register_unwind |
766 | 785 | }; |
@@ -1346,83 +1365,87 @@ get_prev_frame (struct frame_info *next_frame) | ||
1346 | 1365 | prev_frame->pc); |
1347 | 1366 | |
1348 | 1367 | /* Find the prev's frame's ID. */ |
1349 | - { | |
1350 | - switch (prev_frame->type) | |
1351 | - { | |
1352 | - case DUMMY_FRAME: | |
1353 | - /* A dummy doesn't have anything resembling either a sane | |
1354 | - frame or PC. The PC is sitting in the entry code and the | |
1355 | - stack, which has nothing to do with that entry address, is | |
1356 | - a down right mess. Trying to use the standard frame ID | |
1357 | - unwind code to get the previous frame ID is just asking for | |
1358 | - trouble. */ | |
1359 | - if (gdbarch_unwind_dummy_id_p (current_gdbarch)) | |
1360 | - { | |
1361 | - /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS, | |
1362 | - previously saved the dummy ID that is being obtained | |
1363 | - here. Things only work if the two match. */ | |
1364 | - gdb_assert (SAVE_DUMMY_FRAME_TOS_P ()); | |
1365 | - /* Use an architecture specific method to extract the | |
1366 | - prev's dummy ID from the next frame. Note that this | |
1367 | - method typically uses frame_register_unwind to obtain | |
1368 | - register values needed to determine the dummy ID. */ | |
1369 | - next_frame->id_unwind_cache = | |
1370 | - gdbarch_unwind_dummy_id (current_gdbarch, next_frame); | |
1371 | - } | |
1372 | - else if (next_frame->level == 0) | |
1373 | - { | |
1374 | - /* We're `unwinding' the sentinel frame. Just fake up the | |
1375 | - ID the same way that the traditional hacks did it. */ | |
1376 | - next_frame->id_unwind_cache.pc = read_pc (); | |
1377 | - next_frame->id_unwind_cache.pc = read_fp (); | |
1378 | - } | |
1379 | - else | |
1380 | - { | |
1381 | - /* Outch! We're not on the innermost frame yet we're | |
1382 | - trying to unwind to a dummy. The architecture must | |
1383 | - provide the unwind_dummy_id() method. */ | |
1384 | - internal_error (__FILE__, __LINE__, | |
1368 | + switch (prev_frame->type) | |
1369 | + { | |
1370 | + case DUMMY_FRAME: | |
1371 | + /* When unwinding a normal frame, the stack structure is | |
1372 | + determined by analyzing the frame's function's code (be it | |
1373 | + using brute force prologue analysis, or the dwarf2 CFI). In | |
1374 | + the case of a dummy frame, that simply isn't possible. The | |
1375 | + The PC is either the program entry point, or some random | |
1376 | + address on the stack. Trying to use that PC to apply | |
1377 | + standard frame ID unwind techniques is just asking for | |
1378 | + trouble. */ | |
1379 | + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) | |
1380 | + { | |
1381 | + /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS, | |
1382 | + previously saved the dummy frame's ID. Things only work | |
1383 | + if the two return the same value. */ | |
1384 | + gdb_assert (SAVE_DUMMY_FRAME_TOS_P ()); | |
1385 | + /* Use an architecture specific method to extract the prev's | |
1386 | + dummy ID from the next frame. Note that this method uses | |
1387 | + frame_register_unwind to obtain the register values | |
1388 | + needed to determine the dummy frame's ID. */ | |
1389 | + prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch, | |
1390 | + next_frame); | |
1391 | + } | |
1392 | + else if (next_frame->level < 0) | |
1393 | + { | |
1394 | + /* We're unwinding a sentinel frame, the PC of which is | |
1395 | + pointing at a stack dummy. Fake up the dummy frame's ID | |
1396 | + using the same sequence as is found a traditional | |
1397 | + unwinder. Once all architectures supply the | |
1398 | + unwind_dummy_id method, this code can go away. */ | |
1399 | + prev_frame->id.base = read_fp (); | |
1400 | + prev_frame->id.pc = read_pc (); | |
1401 | + } | |
1402 | + else | |
1403 | + { | |
1404 | + /* Outch! We're not on the innermost frame yet we're trying | |
1405 | + to unwind to a dummy. The architecture must provide the | |
1406 | + unwind_dummy_id() method. Abandon the unwind process but | |
1407 | + only after first warning the user. */ | |
1408 | + internal_warning (__FILE__, __LINE__, | |
1385 | 1409 | "Missing unwind_dummy_id architecture method"); |
1386 | - } | |
1387 | - break; | |
1388 | - case NORMAL_FRAME: | |
1389 | - case SIGTRAMP_FRAME: | |
1390 | - prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache, | |
1391 | - &next_frame->id_unwind_cache); | |
1392 | - /* Check that the unwound ID is valid. */ | |
1393 | - if (!frame_id_p (next_frame->id_unwind_cache)) | |
1394 | - { | |
1395 | - if (frame_debug) | |
1396 | - fprintf_unfiltered (gdb_stdlog, | |
1397 | - "Outermost frame - unwound frame ID invalid\n"); | |
1398 | - return NULL; | |
1399 | - } | |
1400 | - /* Check that the new frame isn't inner to (younger, below, | |
1401 | - next) the old frame. If that happens the frame unwind is | |
1402 | - going backwards. */ | |
1403 | - /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since | |
1404 | - that doesn't have a valid frame ID. Should instead set the | |
1405 | - sentinel frame's frame ID to a `sentinel'. Leave it until | |
1406 | - after the switch to storing the frame ID, instead of the | |
1407 | - frame base, in the frame object. */ | |
1408 | - if (next_frame->level >= 0 | |
1409 | - && frame_id_inner (next_frame->id_unwind_cache, | |
1410 | - get_frame_id (next_frame))) | |
1411 | - error ("Unwound frame inner-to selected frame (corrupt stack?)"); | |
1412 | - /* Note that, due to frameless functions, the stronger test of | |
1413 | - the new frame being outer to the old frame can't be used - | |
1414 | - frameless functions differ by only their PC value. */ | |
1415 | - break; | |
1416 | - default: | |
1417 | - internal_error (__FILE__, __LINE__, "bad switch"); | |
1418 | - } | |
1419 | - /* FIXME: cagney/2002-12-18: Instead of this hack, the frame ID | |
1420 | - should be directly stored in the `struct frame_info'. | |
1421 | - Unfortunatly, GDB isn't quite ready for this, need to get HP/UX | |
1422 | - multi-arch and make 'struct frame_info' opaque. */ | |
1423 | - next_frame->id_unwind_cache_p = 1; | |
1424 | - prev_frame->frame = next_frame->id_unwind_cache.base; | |
1425 | - } | |
1410 | + return NULL; | |
1411 | + } | |
1412 | + break; | |
1413 | + case NORMAL_FRAME: | |
1414 | + case SIGTRAMP_FRAME: | |
1415 | + prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache, | |
1416 | + &prev_frame->id); | |
1417 | + /* Check that the unwound ID is valid. */ | |
1418 | + if (!frame_id_p (prev_frame->id)) | |
1419 | + { | |
1420 | + if (frame_debug) | |
1421 | + fprintf_unfiltered (gdb_stdlog, | |
1422 | + "Outermost frame - unwound frame ID invalid\n"); | |
1423 | + return NULL; | |
1424 | + } | |
1425 | + /* Check that the new frame isn't inner to (younger, below, | |
1426 | + next) the old frame. If that happens the frame unwind is | |
1427 | + going backwards. */ | |
1428 | + /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since | |
1429 | + that doesn't have a valid frame ID. Should instead set the | |
1430 | + sentinel frame's frame ID to a `sentinel'. Leave it until | |
1431 | + after the switch to storing the frame ID, instead of the | |
1432 | + frame base, in the frame object. */ | |
1433 | + if (next_frame->level >= 0 | |
1434 | + && frame_id_inner (prev_frame->id, get_frame_id (next_frame))) | |
1435 | + error ("Unwound frame inner-to selected frame (corrupt stack?)"); | |
1436 | + /* Note that, due to frameless functions, the stronger test of | |
1437 | + the new frame being outer to the old frame can't be used - | |
1438 | + frameless functions differ by only their PC value. */ | |
1439 | + break; | |
1440 | + default: | |
1441 | + internal_error (__FILE__, __LINE__, "bad switch"); | |
1442 | + } | |
1443 | + | |
1444 | + /* FIXME: cagney/2002-12-18: Instead of this hack, should only store | |
1445 | + the frame ID in PREV_FRAME. Unfortunatly, some architectures | |
1446 | + (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at | |
1447 | + the "struct frame_info" object directly. */ | |
1448 | + prev_frame->frame = prev_frame->id.base; | |
1426 | 1449 | |
1427 | 1450 | /* Link it in. */ |
1428 | 1451 | next_frame->prev = prev_frame; |
@@ -1557,11 +1580,11 @@ void | ||
1557 | 1580 | deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc) |
1558 | 1581 | { |
1559 | 1582 | /* See comment in "frame.h". */ |
1560 | - gdb_assert (frame->next != NULL); | |
1561 | - /* Fix up this PC's value. */ | |
1562 | 1583 | frame->pc = pc; |
1563 | - /* While we're at it, also update the cache, in NEXT, that also | |
1564 | - contains that value. */ | |
1584 | + /* While we're at it, update this frame's cached PC value, found in | |
1585 | + the next frame. Oh, for the day when "struct frame_info" is | |
1586 | + opaque and this hack on hack can go. */ | |
1587 | + gdb_assert (frame->next != NULL); | |
1565 | 1588 | frame->next->pc_unwind_cache = pc; |
1566 | 1589 | frame->next->pc_unwind_cache_p = 1; |
1567 | 1590 | } |
@@ -310,10 +310,6 @@ extern const char *frame_map_regnum_to_name (int regnum); | ||
310 | 310 | |
311 | 311 | extern CORE_ADDR frame_pc_unwind (struct frame_info *frame); |
312 | 312 | |
313 | -/* Unwind the frame ID. Return an ID that uniquely identifies the | |
314 | - caller's frame. */ | |
315 | -extern struct frame_id frame_id_unwind (struct frame_info *frame); | |
316 | - | |
317 | 313 | /* Discard the specified frame. Restoring the registers to the state |
318 | 314 | of the caller. */ |
319 | 315 | extern void frame_pop (struct frame_info *frame); |
@@ -412,9 +408,9 @@ struct frame_info | ||
412 | 408 | int pc_unwind_cache_p; |
413 | 409 | CORE_ADDR pc_unwind_cache; |
414 | 410 | |
415 | - /* Cached copy of the previous frame's ID. */ | |
416 | - int id_unwind_cache_p; | |
417 | - struct frame_id id_unwind_cache; | |
411 | + /* This frame's ID. Note that the frame's ID, base and PC contain | |
412 | + redundant information. */ | |
413 | + struct frame_id id; | |
418 | 414 | |
419 | 415 | /* Pointers to the next (down, inner, younger) and previous (up, |
420 | 416 | outer, older) frame_info's in the frame cache. */ |
@@ -242,6 +242,7 @@ struct gdbarch | ||
242 | 242 | gdbarch_frame_chain_ftype *frame_chain; |
243 | 243 | gdbarch_frame_chain_valid_ftype *frame_chain_valid; |
244 | 244 | gdbarch_frame_saved_pc_ftype *frame_saved_pc; |
245 | + gdbarch_unwind_pc_ftype *unwind_pc; | |
245 | 246 | gdbarch_frame_args_address_ftype *frame_args_address; |
246 | 247 | gdbarch_frame_locals_address_ftype *frame_locals_address; |
247 | 248 | gdbarch_saved_pc_after_call_ftype *saved_pc_after_call; |
@@ -433,6 +434,7 @@ struct gdbarch startup_gdbarch = | ||
433 | 434 | 0, |
434 | 435 | 0, |
435 | 436 | 0, |
437 | + 0, | |
436 | 438 | generic_in_function_epilogue_p, |
437 | 439 | construct_inferior_arguments, |
438 | 440 | 0, |
@@ -759,6 +761,7 @@ verify_gdbarch (struct gdbarch *gdbarch) | ||
759 | 761 | /* Skip verify of frame_chain, has predicate */ |
760 | 762 | /* Skip verify of frame_chain_valid, has predicate */ |
761 | 763 | /* Skip verify of frame_saved_pc, has predicate */ |
764 | + /* Skip verify of unwind_pc, has predicate */ | |
762 | 765 | /* Skip verify of frame_args_address, invalid_p == 0 */ |
763 | 766 | /* Skip verify of frame_locals_address, invalid_p == 0 */ |
764 | 767 | if ((GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) |
@@ -2578,6 +2581,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) | ||
2578 | 2581 | fprintf_unfiltered (file, |
2579 | 2582 | "gdbarch_dump: unwind_dummy_id = 0x%08lx\n", |
2580 | 2583 | (long) current_gdbarch->unwind_dummy_id); |
2584 | + if (GDB_MULTI_ARCH) | |
2585 | + fprintf_unfiltered (file, | |
2586 | + "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n", | |
2587 | + gdbarch_unwind_pc_p (current_gdbarch)); | |
2588 | + if (GDB_MULTI_ARCH) | |
2589 | + fprintf_unfiltered (file, | |
2590 | + "gdbarch_dump: unwind_pc = 0x%08lx\n", | |
2591 | + (long) current_gdbarch->unwind_pc); | |
2581 | 2592 | #ifdef USE_STRUCT_CONVENTION |
2582 | 2593 | fprintf_unfiltered (file, |
2583 | 2594 | "gdbarch_dump: %s # %s\n", |
@@ -4845,6 +4856,32 @@ set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch, | ||
4845 | 4856 | gdbarch->frame_saved_pc = frame_saved_pc; |
4846 | 4857 | } |
4847 | 4858 | |
4859 | +int | |
4860 | +gdbarch_unwind_pc_p (struct gdbarch *gdbarch) | |
4861 | +{ | |
4862 | + gdb_assert (gdbarch != NULL); | |
4863 | + return gdbarch->unwind_pc != 0; | |
4864 | +} | |
4865 | + | |
4866 | +CORE_ADDR | |
4867 | +gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) | |
4868 | +{ | |
4869 | + gdb_assert (gdbarch != NULL); | |
4870 | + if (gdbarch->unwind_pc == 0) | |
4871 | + internal_error (__FILE__, __LINE__, | |
4872 | + "gdbarch: gdbarch_unwind_pc invalid"); | |
4873 | + if (gdbarch_debug >= 2) | |
4874 | + fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_pc called\n"); | |
4875 | + return gdbarch->unwind_pc (gdbarch, next_frame); | |
4876 | +} | |
4877 | + | |
4878 | +void | |
4879 | +set_gdbarch_unwind_pc (struct gdbarch *gdbarch, | |
4880 | + gdbarch_unwind_pc_ftype unwind_pc) | |
4881 | +{ | |
4882 | + gdbarch->unwind_pc = unwind_pc; | |
4883 | +} | |
4884 | + | |
4848 | 4885 | CORE_ADDR |
4849 | 4886 | gdbarch_frame_args_address (struct gdbarch *gdbarch, struct frame_info *fi) |
4850 | 4887 | { |
@@ -2230,6 +2230,8 @@ extern void set_gdbarch_frame_chain_valid (struct gdbarch *gdbarch, gdbarch_fram | ||
2230 | 2230 | #endif |
2231 | 2231 | #endif |
2232 | 2232 | |
2233 | +/* NOTE: FRAME_SAVED_PC is replaced by UNWIND_PC */ | |
2234 | + | |
2233 | 2235 | #if defined (FRAME_SAVED_PC) |
2234 | 2236 | /* Legacy for systems yet to multi-arch FRAME_SAVED_PC */ |
2235 | 2237 | #if !defined (FRAME_SAVED_PC_P) |
@@ -2267,6 +2269,12 @@ extern void set_gdbarch_frame_saved_pc (struct gdbarch *gdbarch, gdbarch_frame_s | ||
2267 | 2269 | #endif |
2268 | 2270 | #endif |
2269 | 2271 | |
2272 | +extern int gdbarch_unwind_pc_p (struct gdbarch *gdbarch); | |
2273 | + | |
2274 | +typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame); | |
2275 | +extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame); | |
2276 | +extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc); | |
2277 | + | |
2270 | 2278 | /* Default (function) for non- multi-arch platforms. */ |
2271 | 2279 | #if (!GDB_MULTI_ARCH) && !defined (FRAME_ARGS_ADDRESS) |
2272 | 2280 | #define FRAME_ARGS_ADDRESS(fi) (get_frame_base (fi)) |
@@ -591,7 +591,9 @@ v:2:FRAME_ARGS_SKIP:CORE_ADDR:frame_args_skip::::0:-1 | ||
591 | 591 | f:2:FRAMELESS_FUNCTION_INVOCATION:int:frameless_function_invocation:struct frame_info *fi:fi:::generic_frameless_function_invocation_not::0 |
592 | 592 | F:2:FRAME_CHAIN:CORE_ADDR:frame_chain:struct frame_info *frame:frame::0:0 |
593 | 593 | F:2:FRAME_CHAIN_VALID:int:frame_chain_valid:CORE_ADDR chain, struct frame_info *thisframe:chain, thisframe::0:0 |
594 | +# NOTE: FRAME_SAVED_PC is replaced by UNWIND_PC | |
594 | 595 | F:2:FRAME_SAVED_PC:CORE_ADDR:frame_saved_pc:struct frame_info *fi:fi::0:0 |
596 | +M::UNWIND_PC:CORE_ADDR:unwind_pc:struct frame_info *next_frame:next_frame: | |
595 | 597 | f:2:FRAME_ARGS_ADDRESS:CORE_ADDR:frame_args_address:struct frame_info *fi:fi::0:get_frame_base::0 |
596 | 598 | f:2:FRAME_LOCALS_ADDRESS:CORE_ADDR:frame_locals_address:struct frame_info *fi:fi::0:get_frame_base::0 |
597 | 599 | f:2:SAVED_PC_AFTER_CALL:CORE_ADDR:saved_pc_after_call:struct frame_info *frame:frame::0:0 |
@@ -76,17 +76,6 @@ sentinel_frame_register_unwind (struct frame_info *next_frame, | ||
76 | 76 | } |
77 | 77 | } |
78 | 78 | |
79 | -CORE_ADDR | |
80 | -sentinel_frame_pc_unwind (struct frame_info *next_frame, | |
81 | - void **this_cache) | |
82 | -{ | |
83 | - /* FIXME: cagney/2003-01-08: This should be using a per-architecture | |
84 | - method that doesn't suffer from DECR_PC_AFTER_BREAK problems. | |
85 | - Such a method would take unwind_cache, regcache and stop reason | |
86 | - parameters. */ | |
87 | - return read_pc (); | |
88 | -} | |
89 | - | |
90 | 79 | void |
91 | 80 | sentinel_frame_id_unwind (struct frame_info *next_frame, |
92 | 81 | void **this_cache, |
@@ -106,7 +95,6 @@ sentinel_frame_pop (struct frame_info *next_frame, | ||
106 | 95 | const struct frame_unwind sentinel_frame_unwinder = |
107 | 96 | { |
108 | 97 | sentinel_frame_pop, |
109 | - sentinel_frame_pc_unwind, | |
110 | 98 | sentinel_frame_id_unwind, |
111 | 99 | sentinel_frame_register_unwind |
112 | 100 | }; |