return pc;
}
+/* Advance PC across any function entry prologue instructions to reach
+ some "real" code. */
+
CORE_ADDR
-sparc_skip_prologue (CORE_ADDR start_pc, int frameless_p)
+sparc_skip_prologue (CORE_ADDR start_pc)
{
- return examine_prologue (start_pc, frameless_p, NULL, NULL);
+ struct symtab_and_line sal;
+ CORE_ADDR func_start, func_end;
+
+ /* This is the preferred method, find the end of the prologue by
+ using the debugging information. */
+ if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
+ {
+ sal = find_pc_line (func_start, 0);
+
+ if (sal.end < func_end
+ && start_pc <= sal.end)
+ return sal.end;
+ }
+
+ /* Oh well, examine the code by hand. */
+ return examine_prologue (start_pc, 0, NULL, NULL);
}
/* Is the prologue at IP frameless? */
int
sparc_prologue_frameless_p (CORE_ADDR ip)
{
- return ip == sparc_skip_prologue (ip, 1);
+ return ip == examine_prologue (ip, 1, NULL, NULL);
}
/* Check instruction at ADDR to see if it is a branch.
addr = frame1->frame + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE
- (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE);
else if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8)
+ /* NOTE: cagney/2002-05-04: The call to get_prev_frame()
+ is safe/cheap - there will always be a prev frame.
+ This is because frame1 is initialized to frame->next
+ (frame1->prev == frame) and is then advanced towards
+ the innermost (next) frame. */
addr = (get_prev_frame (frame1)->extra_info->bottom
+ (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
+ FRAME_SAVED_I0);
else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8)
+ /* NOTE: cagney/2002-05-04: The call to get_prev_frame()
+ is safe/cheap - there will always be a prev frame.
+ This is because frame1 is initialized to frame->next
+ (frame1->prev == frame) and is then advanced towards
+ the innermost (next) frame. */
addr = (get_prev_frame (frame1)->extra_info->bottom
+ (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
+ FRAME_SAVED_L0);
char *reg_temp;
- reg_temp = alloca (REGISTER_BYTES);
+ reg_temp = alloca (SPARC_INTREG_SIZE * 16);
read_memory (fsr[I0_REGNUM], raw_buffer, 8 * SPARC_INTREG_SIZE);
return 64 * 8 + (regno - 80) * 8;
}
-/* Advance PC across any function entry prologue instructions to reach
- some "real" code. */
-
-static CORE_ADDR
-sparc_gdbarch_skip_prologue (CORE_ADDR ip)
-{
- return examine_prologue (ip, 0, NULL, NULL);
-}
-
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
set_gdbarch_saved_pc_after_call (gdbarch, sparc_saved_pc_after_call);
set_gdbarch_prologue_frameless_p (gdbarch, sparc_prologue_frameless_p);
set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_skip_prologue (gdbarch, sparc_gdbarch_skip_prologue);
+ set_gdbarch_skip_prologue (gdbarch, sparc_skip_prologue);
set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM);
set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
set_gdbarch_call_dummy_address (gdbarch, sparc_call_dummy_address);
set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0x30);
set_gdbarch_call_dummy_length (gdbarch, 0x38);
+
+ /* NOTE: cagney/2002-04-26: Based from info posted by Peter
+ Schauer around Oct '99. Briefly, due to aspects of the SPARC
+ ABI, it isn't possible to use ON_STACK with a strictly
+ compliant compiler.
+
+ Peter Schauer writes ...
+
+ No, any call from GDB to a user function returning a
+ struct/union will fail miserably. Try this:
+
+ *NOINDENT*
+ struct x
+ {
+ int a[4];
+ };
+
+ struct x gx;
+
+ struct x
+ sret ()
+ {
+ return gx;
+ }
+
+ main ()
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ gx.a[i] = i + 1;
+ gx = sret ();
+ }
+ *INDENT*
+
+ Set a breakpoint at the gx = sret () statement, run to it and
+ issue a `print sret()'. It will not succed with your
+ approach, and I doubt that continuing the program will work
+ as well.
+
+ For details of the ABI see the Sparc Architecture Manual. I
+ have Version 8 (Prentice Hall ISBN 0-13-825001-4) and the
+ calling conventions for functions returning aggregate values
+ are explained in Appendix D.3. */
+
set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
set_gdbarch_call_dummy_words (gdbarch, call_dummy_32);
#else