This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: [rfc] ``pc'' -> resume_addr?
>> I think the name ``pc'' brings with it a certain amount of baggage.
>> When reading a piece of code, it isn't clear if the hardware ``pc''
>> (possibly needing adjustment) or the program's resume address is being used.
>
>
> When are they not the same?
I'm not sure. I'm also not the only one :-) cf:
/* Are we in a call dummy? The code below which allows DECR_PC_AFTER_BREAK
below is for infrun.c, which may give the macro a pc without that
subtracted out. */
int
pc_in_call_dummy_before_text_end (CORE_ADDR pc, CORE_ADDR sp,
CORE_ADDR frame_address)
{
return ((pc) >= text_end - CALL_DUMMY_LENGTH
&& (pc) <= text_end + DECR_PC_AFTER_BREAK);
}
In reading the code, I never know if I've got a ``pc'' or a ``pc''. If
I print the value and it isn't as expected, I'm left wondering if I
should adjust it, or that something somewhere else forgot to adjust it.
>> On an x86, and m68k, for instance, the hardware PC may or may not need
>> to be adjusted (decr_pc_after_break()) before it becomes a frame->pc.
>
>
> Yeah -- but this is done almost immediately after the target stops.
> Past that point, the hardware pc _is_ equal to the address at which
> execution will resume. Before that point, we haven't really built
> or used very many of these objects called 'pc' or 'something->pc'.
> Have we?
Ok, I think I've figured out how this ``works'':
- target stops
- infrun has an initial look round. If it doesn't think the read_pc()
value is interesting, it resumes the target. Thing is, I can't detect
any write_pc() for this case - as best as I can tell it resumes the
target without adjusting the PC.
- Otherwise infrun calls bpstat_stop_status() and that will eventually call:
write_pc(read_pc()-decr);
and patch up that PC value. Ulgh!
- finally the block/frame is created. This calls read_pc() and gets
the ``fixed'' pc.
I don't know if this can really be called ``immediatly after'' the
target stops. infrun.c, for instance, can call functions (such as
pc_in_call_dummy) with either [PC] or [PC]-DECR_PC_AFTER_BREAK.
I think even more troubling (and something I didn't realize) is that the
meaning of read_pc() its self changes as you step through the code:
read_pc() != read_pc().
>> Within the frame, the ``pc'' designates ``resume'' address of the
>> function. Knowing this is important when understanding why some of the
>> frame code does:
>>
>> if (frame->next != NULL)
>> return frame->pc - 1;
>> else
>> return frame->pc;
>
>
> Uggh. Where does THAT code come from? ;-)
blockframe.c:get_frame_block() (it is lightly different). The code is
wierd but correct.
>> Remember, when making an inferior function call, GDB does not set the
>> PC. Rather it sets the resume/continue address using the debug info.
>> For instance, on the sparc, it sets:
>>
>> [PC] = resume_addr;
>> [NPC] = resume_addr + 4;
>>
>> This behavour is very different to what the user is trying to achieve if
>> they enter:
>>
>> (gdb) jump *foo *bar
>>
>> On a sparc, that would execute:
>>
>> *foo
>> *bar
>> *(bar + 4)
>> *(bar + 8)
>
>
> Whoa, you lost me. The "jump" command only accepts one argument.
> What does "jump *foo *bar" mean?
Sorry, I'm wrong. I thought that was implemented but (fortunatly) it
isn't. The semantics would be: [PC] = '*foo'. [NPC] = '*bar'.
--
I guess there are several things here:
frame->pc
this is the resume address (always?)
read_pc()
thanks to decr_pc_after_break, this
isn't defined.
decr_pc_after_break
the real villian
enjoy,
Andrew