This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]