• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisiónfdd93b8b10a297196af99279086ddc214f3d9bb6 (tree)
Tiempo2003-03-05 14:00:04
AutorAndrew Cagney <cagney@redh...>
CommiterAndrew Cagney

Log Message

2003-03-04 Andrew Cagney <cagney@redhat.com>

* d10v-tdep.c (struct d10v_unwind_cache): Add field "r11_addr",
change type of "next_addr" to LONGEST. Delete member "frameless".
(prologue_find_regs): Parse "st rn, @r11", save r11's offset.
(d10v_frame_unwind_cache): Compute both the frame base and the
previous stack pointer. Store the previous SP's value in the
saved_regs array.
(d10v_frame_id_unwind): Remove commented out code. Check for
circular stack.
(saved_regs_unwinder): When SP_REGNUM, extract the value from the
saved_regs array.
(d10v_unwind_dummy_id): New function.
(d10v_gdbarch_init): Initialize d10v_unwind_dummy_id and
save_dummy_frame_tos.
(struct frame_extra_info): Delete.
(saved_regs_unwind): New function.
(d10v_frame_pop): Update to match current code.
(d10v_frame_register_unwind): Don't unwind LR_REGNUM. Unwind the
PC_REGNUM by returning the saved LR_REGNUM.
* frame.c (get_prev_frame): Store this frame's ID in the next
frame's unwound ID cache.
(deprecated_update_frame_pc_hack): Update the cached value in NEXT
as well.

2003-02-27 Andrew Cagney <cagney@redhat.com>
* frame.c (get_prev_frame): Rewrite the frame ID unwind code to
use unwind_dummy_id when available.
* gdbarch.sh (get_dummy_frame_id): New multi-arch method with
predicate.
* gdbarch.h, gdbarch.c: Regneerate.

Cambiar Resumen

Diferencia incremental

--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,37 @@
11 2003-03-04 Andrew Cagney <cagney@redhat.com>
22
3+ * d10v-tdep.c (struct d10v_unwind_cache): Add field "r11_addr",
4+ change type of "next_addr" to LONGEST. Delete member "frameless".
5+ (prologue_find_regs): Parse "st rn, @r11", save r11's offset.
6+ (d10v_frame_unwind_cache): Compute both the frame base and the
7+ previous stack pointer. Store the previous SP's value in the
8+ saved_regs array.
9+ (d10v_frame_id_unwind): Remove commented out code. Check for
10+ circular stack.
11+ (saved_regs_unwinder): When SP_REGNUM, extract the value from the
12+ saved_regs array.
13+ (d10v_unwind_dummy_id): New function.
14+ (d10v_gdbarch_init): Initialize d10v_unwind_dummy_id and
15+ save_dummy_frame_tos.
16+ (struct frame_extra_info): Delete.
17+ (saved_regs_unwind): New function.
18+ (d10v_frame_pop): Update to match current code.
19+ (d10v_frame_register_unwind): Don't unwind LR_REGNUM. Unwind the
20+ PC_REGNUM by returning the saved LR_REGNUM.
21+ * frame.c (get_prev_frame): Store this frame's ID in the next
22+ frame's unwound ID cache.
23+ (deprecated_update_frame_pc_hack): Update the cached value in NEXT
24+ as well.
25+
26+ 2003-02-27 Andrew Cagney <cagney@redhat.com>
27+ * frame.c (get_prev_frame): Rewrite the frame ID unwind code to
28+ use unwind_dummy_id when available.
29+ * gdbarch.sh (get_dummy_frame_id): New multi-arch method with
30+ predicate.
31+ * gdbarch.h, gdbarch.c: Regneerate.
32+
33+2003-03-04 Andrew Cagney <cagney@redhat.com>
34+
335 * d10v-tdep.c (d10v_frame_unwind_cache): Update to work with
436 NEXT_FRAME and THIS_CACHE.
537 (d10v_frame_pc_unwind): Ditto.
--- a/gdb/d10v-tdep.c
+++ b/gdb/d10v-tdep.c
@@ -45,20 +45,9 @@
4545
4646 #include "gdb_assert.h"
4747
48-static void d10v_frame_register_unwind (struct frame_info *next_frame,
49- void **this_cache,
50- int prev_regnum, int *optimizedp,
51- enum lval_type *lvalp,
52- CORE_ADDR *addrp,
53- int *realnump, void *bufferp);
54-
55-
56-struct frame_extra_info
57- {
58- CORE_ADDR return_pc;
59- int frameless;
60- int size;
61- };
48+static void saved_regs_unwind (struct frame_info *next_frame,
49+ CORE_ADDR *saved_regs, int prev_regnum,
50+ void *bufferp);
6251
6352 struct gdbarch_tdep
6453 {
@@ -625,10 +614,10 @@ d10v_skip_prologue (CORE_ADDR pc)
625614 struct d10v_unwind_cache
626615 {
627616 CORE_ADDR base;
628- int frameless;
629617 int size;
630618 CORE_ADDR *saved_regs;
631- CORE_ADDR next_addr;
619+ LONGEST next_addr;
620+ LONGEST r11_addr;
632621 int uses_frame;
633622 void **regs;
634623 };
@@ -672,6 +661,15 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op,
672661 if (op == 0x417E)
673662 {
674663 info->uses_frame = 1;
664+ info->r11_addr = info->next_addr;
665+ return 1;
666+ }
667+
668+ /* st rn, @r11 */
669+ if ((op & 0x7E1F) == 0x6816)
670+ {
671+ n = (op & 0x1E0) >> 5;
672+ info->saved_regs[n] = info->r11_addr;
675673 return 1;
676674 }
677675
@@ -724,7 +722,6 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
724722 (*this_cache) = info;
725723 info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS);
726724
727- info->frameless = 0;
728725 info->size = 0;
729726
730727 info->next_addr = 0;
@@ -784,40 +781,51 @@ d10v_frame_unwind_cache (struct frame_info *next_frame,
784781
785782 info->size = -info->next_addr;
786783
787- /* Start out with the frame's stack top. */
788- frame_unwind_unsigned_register (next_frame, SP_REGNUM, &sp);
789- sp = d10v_make_daddr (sp);
790-
791- for (i = 0; i < NUM_REGS - 1; i++)
792- if (info->saved_regs[i])
793- {
794- info->saved_regs[i] = sp - (info->next_addr - info->saved_regs[i]);
795- }
796-
797784 /* Compute the frame's base. */
798- if (info->saved_regs[FP_REGNUM])
785+ if (info->uses_frame)
799786 {
800- /* The FP was saved, which means that the current FP is live.
801- Unwind its value from the NEXT frame. */
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. */
802790 frame_unwind_unsigned_register (next_frame, FP_REGNUM, &base);
791+ /* The FP points at the last saved register. Adjust the FP back
792+ to before the first saved register giving the SP. */
793+ sp = base + info->size;
803794 }
804795 else if (info->saved_regs[SP_REGNUM])
805796 {
806- /* The SP was saved (this is very unusual), the frame base is
797+ /* The SP was saved (which is very unusual), the frame base is
807798 just the PREV's frame's TOP-OF-STACK. */
808799 base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM],
809800 register_size (current_gdbarch,
810801 SP_REGNUM));
811- info->frameless = 1;
802+ sp = base;
812803 }
813804 else
814805 {
815806 /* Assume that the FP is this frame's SP but with that pushed
816807 stack space added back. */
817808 frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
818- base += info->size;
809+ sp = base + info->size;
819810 }
811+
820812 info->base = d10v_make_daddr (base);
813+ sp = d10v_make_daddr (sp);
814+
815+ /* Adjust all the saved registers so that they contain addresses and
816+ not offsets. */
817+ 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+ }
824+
825+ /* The SP_REGNUM is special. Instead of the address of the SP, the
826+ previous frame's SP value is saved. */
827+ info->saved_regs[SP_REGNUM] = sp;
828+
821829 return info;
822830 }
823831
@@ -1429,17 +1437,13 @@ static CORE_ADDR
14291437 d10v_frame_pc_unwind (struct frame_info *next_frame,
14301438 void **this_cache)
14311439 {
1432- /* FIXME: This shouldn't be needed. Instead a per-architecture
1433- method should be called. */
1434- int optimized;
1435- enum lval_type lval;
1436- CORE_ADDR addr;
1437- int realnum;
1438- ULONGEST lr;
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);
14391445 void *buffer = alloca (max_register_size (current_gdbarch));
1440- d10v_frame_register_unwind (next_frame, this_cache, LR_REGNUM,
1441- &optimized, &lval, &addr, &realnum,
1442- buffer);
1446+ saved_regs_unwind (next_frame, info->saved_regs, LR_REGNUM, buffer);
14431447 lr = extract_unsigned_integer (buffer, register_size (current_gdbarch,
14441448 LR_REGNUM));
14451449 return d10v_make_iaddr (lr);
@@ -1472,26 +1476,24 @@ d10v_frame_id_unwind (struct frame_info *next_frame,
14721476 return;
14731477 }
14741478
1475-#if 0
1476- if (!info->saved_regs[FP_REGNUM])
1477- {
1478- if (!info->saved_regs[SP_REGNUM]
1479- || info->saved_regs[SP_REGNUM] == STACK_START)
1480- return;
1481-
1482- this_id->base = info->saved_regs[SP_REGNUM];
1483- this_id->pc = info->return_pc;
1484- }
1479+ /* Hopefully the prologue analysis either correctly determined the
1480+ frame's base (which is the SP from the previous frame), or set
1481+ that base to "NULL". */
1482+ base = info->base;
1483+ if (base == STACK_START || base == 0)
1484+ return;
14851485
1486- addr = read_memory_unsigned_integer (info->saved_regs[FP_REGNUM],
1487- register_size (current_gdbarch, FP_REGNUM));
1488- if (addr == 0)
1486+ /* Check that we're not going round in circles on the same frame ID.
1487+ Be careful to avoid applying the test to sentinel frames (which
1488+ do go round in circles). Can't use ID_EQ as that doesn't yet
1489+ compare PC values. */
1490+ if (frame_relative_level (next_frame) >= 0
1491+ && get_frame_type (next_frame) != DUMMY_FRAME
1492+ && get_frame_id (next_frame).pc == pc
1493+ && get_frame_id (next_frame).base == base)
14891494 return;
1490-#endif
14911495
1492- /* Hopefully the prolog analysis has correctly determined the
1493- frame's base. */
1494- this_id->base = info->base;
1496+ this_id->base = base;
14951497 this_id->pc = pc;
14961498 }
14971499
@@ -1504,15 +1506,30 @@ saved_regs_unwinder (struct frame_info *next_frame,
15041506 {
15051507 if (saved_regs[prev_regnum] != 0)
15061508 {
1507- *optimizedp = 0;
1508- *lvalp = lval_memory;
1509- *addrp = saved_regs[prev_regnum];
1510- *realnump = -1;
1511- if (bufferp != NULL)
1509+ if (prev_regnum == SP_REGNUM)
1510+ {
1511+ /* SP register treated specially. */
1512+ *optimizedp = 0;
1513+ *lvalp = not_lval;
1514+ *addrp = 0;
1515+ *realnump = -1;
1516+ if (bufferp != NULL)
1517+ store_address (bufferp,
1518+ register_size (current_gdbarch, SP_REGNUM),
1519+ saved_regs[SP_REGNUM]);
1520+ }
1521+ else
15121522 {
1513- /* Read the value in from memory. */
1514- read_memory (saved_regs[prev_regnum], bufferp,
1515- register_size (current_gdbarch, prev_regnum));
1523+ *optimizedp = 0;
1524+ *lvalp = lval_memory;
1525+ *addrp = saved_regs[prev_regnum];
1526+ *realnump = -1;
1527+ if (bufferp != NULL)
1528+ {
1529+ /* Read the value in from memory. */
1530+ read_memory (saved_regs[prev_regnum], bufferp,
1531+ register_size (current_gdbarch, prev_regnum));
1532+ }
15161533 }
15171534 return;
15181535 }
@@ -1525,6 +1542,20 @@ saved_regs_unwinder (struct frame_info *next_frame,
15251542 realnump, bufferp);
15261543 }
15271544
1545+/* Wrapper so that local code can unwind register values. */
1546+
1547+static void
1548+saved_regs_unwind (struct frame_info *next_frame, CORE_ADDR *saved_regs,
1549+ int prev_regnum, void *bufferp)
1550+{
1551+ int optimized;
1552+ enum lval_type lval;
1553+ CORE_ADDR addr;
1554+ int realnum;
1555+ saved_regs_unwinder (next_frame, saved_regs, prev_regnum,
1556+ &optimized, &lval, &addr, &realnum, bufferp);
1557+}
1558+
15281559
15291560 static void
15301561 d10v_frame_register_unwind (struct frame_info *next_frame,
@@ -1535,44 +1566,67 @@ d10v_frame_register_unwind (struct frame_info *next_frame,
15351566 {
15361567 struct d10v_unwind_cache *info
15371568 = d10v_frame_unwind_cache (next_frame, this_cache);
1538- if (prev_regnum == PC_REGNUM)
1539- prev_regnum = LR_REGNUM;
1540- saved_regs_unwinder (next_frame, info->saved_regs, prev_regnum, optimizedp,
1541- lvalp, addrp, realnump, bufferp);
1569+ if (prev_regnum == LR_REGNUM)
1570+ /* Unwinding the LR isn't possible. It's value is trashed by the
1571+ call instruction. Mark the value as optimized away. */
1572+ {
1573+ *optimizedp = 1;
1574+ *lvalp = lval_register;
1575+ *addrp = 0;
1576+ *realnump = LR_REGNUM;
1577+ if (bufferp != NULL)
1578+ memset (bufferp, 0, register_size (current_gdbarch, LR_REGNUM));
1579+ }
1580+ else if (prev_regnum == PC_REGNUM)
1581+ /* The caller's PC is saved in LR_REGNUM. Find/return the
1582+ LR_REGNUM. */
1583+ saved_regs_unwinder (next_frame, info->saved_regs, LR_REGNUM, optimizedp,
1584+ lvalp, addrp, realnump, bufferp);
1585+ else
1586+ saved_regs_unwinder (next_frame, info->saved_regs, prev_regnum, optimizedp,
1587+ lvalp, addrp, realnump, bufferp);
15421588 }
15431589
15441590
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+
15451602 static void
1546-d10v_frame_pop (struct frame_info *fi, void **unwind_cache,
1603+d10v_frame_pop (struct frame_info *next_frame, void **this_cache,
15471604 struct regcache *regcache)
15481605 {
1549- struct d10v_unwind_cache *info = d10v_frame_unwind_cache (fi, unwind_cache);
1606+ struct d10v_unwind_cache *info
1607+ = d10v_frame_unwind_cache (next_frame, this_cache);
15501608 CORE_ADDR fp;
15511609 int regnum;
15521610 char raw_buffer[8];
15531611
1554- fp = get_frame_base (fi);
1555-
15561612 /* now update the current registers with the old values */
15571613 for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++)
15581614 {
1559- frame_unwind_register (fi, regnum, raw_buffer);
1615+ saved_regs_unwind (next_frame, info->saved_regs, regnum, raw_buffer);
15601616 regcache_cooked_write (regcache, regnum, raw_buffer);
15611617 }
15621618 for (regnum = 0; regnum < SP_REGNUM; regnum++)
15631619 {
1564- frame_unwind_register (fi, regnum, raw_buffer);
1620+ saved_regs_unwind (next_frame, info->saved_regs, regnum, raw_buffer);
15651621 regcache_cooked_write (regcache, regnum, raw_buffer);
15661622 }
1567- frame_unwind_register (fi, PSW_REGNUM, raw_buffer);
1623+ saved_regs_unwind (next_frame, info->saved_regs, PSW_REGNUM, raw_buffer);
15681624 regcache_cooked_write (regcache, PSW_REGNUM, raw_buffer);
15691625
1570- frame_unwind_register (fi, LR_REGNUM, raw_buffer);
1626+ saved_regs_unwind (next_frame, info->saved_regs, LR_REGNUM, raw_buffer);
15711627 regcache_cooked_write (regcache, PC_REGNUM, raw_buffer);
15721628
1573- store_unsigned_integer (raw_buffer,
1574- register_size (current_gdbarch, SP_REGNUM),
1575- fp + info->size);
1629+ saved_regs_unwind (next_frame, info->saved_regs, SP_REGNUM, raw_buffer);
15761630 regcache_cooked_write (regcache, SP_REGNUM, raw_buffer);
15771631
15781632 target_store_registers (-1);
@@ -1728,6 +1782,8 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
17281782 set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
17291783
17301784 frame_unwind_append_predicate (gdbarch, d10v_frame_p);
1785+ set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
1786+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
17311787
17321788 return gdbarch;
17331789 }
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,10 @@
1+2003-03-04 Andrew Cagney <cagney@redhat.com>
2+
3+ 2003-02-27 Andrew Cagney <cagney@redhat.com>
4+ * gdbint.texinfo (Target Architecture Definition): Document
5+ unwind_dummy_id. Cross reference unwind_dummy_id and
6+ SAVE_DUMMY_FRAME_TOS.
7+
18 2003-03-02 Daniel Jacobowitz <drow@mvista.com>
29
310 * Makefile.in (distclean): Remove config.log.
--- a/gdb/doc/gdbint.texinfo
+++ b/gdb/doc/gdbint.texinfo
@@ -3691,10 +3691,11 @@ rather than directly.
36913691
36923692 @item SAVE_DUMMY_FRAME_TOS (@var{sp})
36933693 @findex SAVE_DUMMY_FRAME_TOS
3694-Used in @samp{call_function_by_hand} to notify the target dependent code
3695-of the top-of-stack value that will be passed to the the inferior code.
3696-This is the value of the @code{SP} after both the dummy frame and space
3697-for parameters/results have been allocated on the stack.
3694+@anchor{SAVE_DUMMY_FRAME_TOS} Used in @samp{call_function_by_hand} to
3695+notify the target dependent code of the top-of-stack value that will be
3696+passed to the the inferior code. This is the value of the @code{SP}
3697+after both the dummy frame and space for parameters/results have been
3698+allocated on the stack. @xref{unwind_dummy_id}.
36983699
36993700 @item SDB_REG_TO_REGNUM
37003701 @findex SDB_REG_TO_REGNUM
@@ -3878,6 +3879,14 @@ Libraries, ,Opcodes}). @var{info} is a structure (of type
38783879 @code{disassemble_info}) defined in @file{include/dis-asm.h} used to
38793880 pass information to the instruction decoding routine.
38803881
3882+@item struct frame_id unwind_dummy_id (struct frame_info *@var{frame})
3883+@findex unwind_dummy_id
3884+@anchor{unwind_dummy_id} Given @var{frame} return a @code{struct
3885+frame_id} that uniquely identifies an inferior function call's dummy
3886+frame. The value returned must match the dummy frame stack value
3887+previously saved using @code{SAVE_DUMMY_FRAME_TOS}.
3888+@xref{SAVE_DUMMY_FRAME_TOS}.
3889+
38813890 @item USE_STRUCT_CONVENTION (@var{gcc_p}, @var{type})
38823891 @findex USE_STRUCT_CONVENTION
38833892 If defined, this must be an expression that is nonzero if a value of the
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1345,39 +1345,83 @@ get_prev_frame (struct frame_info *next_frame)
13451345 prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
13461346 prev_frame->pc);
13471347
1348- /* FIXME: cagney/2003-01-13: A dummy frame doesn't need to unwind
1349- the frame ID because the frame ID comes from the previous frame.
1350- The other frames do though. True? */
1348+ /* Find the prev's frame's ID. */
13511349 {
1352- /* FIXME: cagney/2002-12-18: Instead of this hack, should just
1353- save the frame ID directly. */
1354- struct frame_id id;
1355- prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache, &id);
1356- /* Check that the unwound ID is valid. As of 2003-02-24 the
1357- x86-64 was returning an invalid frame ID when trying to do an
1358- unwind a sentinel frame that belonged to a frame dummy. */
1359- if (!frame_id_p (id))
1350+ switch (prev_frame->type)
13601351 {
1361- if (frame_debug)
1362- fprintf_unfiltered (gdb_stdlog,
1363- "Outermost frame - unwound frame ID invalid\n");
1364- return NULL;
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__,
1385+ "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");
13651418 }
1366- /* Check that the new frame isn't inner to (younger, below, next)
1367- the old frame. If that happens the frame unwind is going
1368- backwards. */
1369- /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since that
1370- doesn't have a valid frame ID. Should instead set the sentinel
1371- frame's frame ID to a `sentinel'. Leave it until after the
1372- switch to storing the frame ID, instead of the frame base, in
1373- the frame object. */
1374- if (next_frame->level >= 0
1375- && frame_id_inner (id, get_frame_id (next_frame)))
1376- error ("Unwound frame inner-to selected frame (corrupt stack?)");
1377- /* Note that, due to frameless functions, the stronger test of the
1378- new frame being outer to the old frame can't be used -
1379- frameless functions differ by only their PC value. */
1380- prev_frame->frame = id.base;
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;
13811425 }
13821426
13831427 /* Link it in. */
@@ -1514,7 +1558,12 @@ deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
15141558 {
15151559 /* See comment in "frame.h". */
15161560 gdb_assert (frame->next != NULL);
1561+ /* Fix up this PC's value. */
15171562 frame->pc = pc;
1563+ /* While we're at it, also update the cache, in NEXT, that also
1564+ contains that value. */
1565+ frame->next->pc_unwind_cache = pc;
1566+ frame->next->pc_unwind_cache_p = 1;
15181567 }
15191568
15201569 void
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -251,6 +251,7 @@ struct gdbarch
251251 int extra_stack_alignment_needed;
252252 gdbarch_reg_struct_has_addr_ftype *reg_struct_has_addr;
253253 gdbarch_save_dummy_frame_tos_ftype *save_dummy_frame_tos;
254+ gdbarch_unwind_dummy_id_ftype *unwind_dummy_id;
254255 int parm_boundary;
255256 const struct floatformat * float_format;
256257 const struct floatformat * double_format;
@@ -431,6 +432,7 @@ struct gdbarch startup_gdbarch =
431432 0,
432433 0,
433434 0,
435+ 0,
434436 generic_in_function_epilogue_p,
435437 construct_inferior_arguments,
436438 0,
@@ -770,6 +772,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
770772 /* Skip verify of extra_stack_alignment_needed, invalid_p == 0 */
771773 /* Skip verify of reg_struct_has_addr, has predicate */
772774 /* Skip verify of save_dummy_frame_tos, has predicate */
775+ /* Skip verify of unwind_dummy_id, has predicate */
773776 if (gdbarch->float_format == 0)
774777 gdbarch->float_format = default_float_format (gdbarch);
775778 if (gdbarch->double_format == 0)
@@ -2567,6 +2570,14 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
25672570 (long) current_gdbarch->write_sp
25682571 /*TARGET_WRITE_SP ()*/);
25692572 #endif
2573+ if (GDB_MULTI_ARCH)
2574+ fprintf_unfiltered (file,
2575+ "gdbarch_dump: gdbarch_unwind_dummy_id_p() = %d\n",
2576+ gdbarch_unwind_dummy_id_p (current_gdbarch));
2577+ if (GDB_MULTI_ARCH)
2578+ fprintf_unfiltered (file,
2579+ "gdbarch_dump: unwind_dummy_id = 0x%08lx\n",
2580+ (long) current_gdbarch->unwind_dummy_id);
25702581 #ifdef USE_STRUCT_CONVENTION
25712582 fprintf_unfiltered (file,
25722583 "gdbarch_dump: %s # %s\n",
@@ -5032,6 +5043,32 @@ set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch,
50325043 }
50335044
50345045 int
5046+gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch)
5047+{
5048+ gdb_assert (gdbarch != NULL);
5049+ return gdbarch->unwind_dummy_id != 0;
5050+}
5051+
5052+struct frame_id
5053+gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info)
5054+{
5055+ gdb_assert (gdbarch != NULL);
5056+ if (gdbarch->unwind_dummy_id == 0)
5057+ internal_error (__FILE__, __LINE__,
5058+ "gdbarch: gdbarch_unwind_dummy_id invalid");
5059+ if (gdbarch_debug >= 2)
5060+ fprintf_unfiltered (gdb_stdlog, "gdbarch_unwind_dummy_id called\n");
5061+ return gdbarch->unwind_dummy_id (gdbarch, info);
5062+}
5063+
5064+void
5065+set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch,
5066+ gdbarch_unwind_dummy_id_ftype unwind_dummy_id)
5067+{
5068+ gdbarch->unwind_dummy_id = unwind_dummy_id;
5069+}
5070+
5071+int
50355072 gdbarch_parm_boundary (struct gdbarch *gdbarch)
50365073 {
50375074 gdb_assert (gdbarch != NULL);
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -2458,6 +2458,12 @@ extern void set_gdbarch_save_dummy_frame_tos (struct gdbarch *gdbarch, gdbarch_s
24582458 #endif
24592459 #endif
24602460
2461+extern int gdbarch_unwind_dummy_id_p (struct gdbarch *gdbarch);
2462+
2463+typedef struct frame_id (gdbarch_unwind_dummy_id_ftype) (struct gdbarch *gdbarch, struct frame_info *info);
2464+extern struct frame_id gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *info);
2465+extern void set_gdbarch_unwind_dummy_id (struct gdbarch *gdbarch, gdbarch_unwind_dummy_id_ftype *unwind_dummy_id);
2466+
24612467 extern int gdbarch_parm_boundary (struct gdbarch *gdbarch);
24622468 extern void set_gdbarch_parm_boundary (struct gdbarch *gdbarch, int parm_boundary);
24632469 #if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (PARM_BOUNDARY)
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -602,6 +602,7 @@ M:::CORE_ADDR:frame_align:CORE_ADDR address:address
602602 v:2:EXTRA_STACK_ALIGNMENT_NEEDED:int:extra_stack_alignment_needed::::0:1::0:::
603603 F:2:REG_STRUCT_HAS_ADDR:int:reg_struct_has_addr:int gcc_p, struct type *type:gcc_p, type::0:0
604604 F:2:SAVE_DUMMY_FRAME_TOS:void:save_dummy_frame_tos:CORE_ADDR sp:sp::0:0
605+M::UNWIND_DUMMY_ID:struct frame_id:unwind_dummy_id:struct frame_info *info:info::0:0
605606 v:2:PARM_BOUNDARY:int:parm_boundary
606607 #
607608 v:2:TARGET_FLOAT_FORMAT:const struct floatformat *:float_format::::::default_float_format (gdbarch)::%s:(TARGET_FLOAT_FORMAT)->name