This is the mail archive of the gdb-patches@sourceware.org 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: [RFA 1/2] mips: Switch inferior function calls to ON_STACK method.


Joel

> >  Thanks for this work -- can you give me a reference to some background 
> > information as to why exactly we want to remove the AT_SYMBOL method?
> 
> I do not have a specific reference. Only the fact that it's always
> been a method that we wanted to deprecate and then remove support for...

 OK, fair enough.  I'll see if I can find anything relevant myself to feed 
my curiosity.

> I think that we will be fine, because the code is not actually inserting
> the breakpoint, merely reserving the room for it on the stack. Later
> on, the target layer then inserts the breakpoint for us, using the
> appropriate method. If you're connected to a board via JTAG, it should
> do the right thing.

 Indeed, I realised that shortly after posting my reply.  I got tricked 
into thinking this is needed for a reason, but I think it's really not.  
I think it is safe to assume a MIPS software breakpoint will always fit in 
a single machine instruction, so it should be enough to reserve space for 
two 32-bit instructions just as in the snippet I proposed -- one for the 
place to put the breakpoint at and the other for the delay slot avoidance.

> >  I can address all these microMIPS issues if you like as I'm likely
> >  more familiar with that stuff,
> 
> I'd feel more comfortable if you did. I think I understand a little
> better what you mean by microMIPS, although I thought it was what
> the code called mips16. But I realize now that it's something
> different, because IIRC you can switch between mips16 and mips32
> by simply using odd addresses (or not).

 Well, the microMIPS instruction set is a new encoding of all the existing 
MIPS instructions, with some new instructions added.  It is intended to be 
source-compatible with the existing MIPS software, up to handwritten 
assembly (in the macro mode).

 Overall there are four categories of instructions in the microMIPS set:

* newly-added 16-bit instructions,

* newly-added 32-bit instructions,

* reencoded 32-bit instructions,

* newly-added 48-bit instructions.

 Most of 16-bit instructions are shortened forms of frequently used 
instructions that already existed in the original MIPS instruction set.  
Some are genuinely new operations (e.g. MOVEP, move a pair of registers).  
Also most of 16-bit instructions have equivalent 32-bit encodings that 
have a wider range of their immediate argument and/or can address more 
registers.

 There isn't much to say about newly-added 32-bit instructions -- in most 
cases they are widened forms of some 16-bit instructions, though again, 
there are some unique exception (ADDIUPC, add immediate to PC, comes to my 
mind).

 All the reencoded 32-bit instructions already existed in the original 
MIPS instruction set.  Some particularily infrequently used have the range 
of their immediate argument narrowed compared to the original (e.g. DADDI, 
double-word add with overflow detection).  The use of an auxiliary 
register is required to use an immediate outside the range as is with 
values outside the signed 16-bit range in the original MIPS instruction 
set.  GAS handles this peculiarity transparently in the macro mode.

 One 48-bit instruction has been defined, LI32, to load a 32-bit immediate 
into a register with a single instruction.  It's a part of the 64-bit 
architecture spec, you won't get it on 32-bit processors.

 We don't have to care about MIPS16 support here because any processor 
that supports the MIPS16 instruction set will also support the standard 
MIPS set.  This is not going to be true for microMIPS support.

 And for the record, the ISA bit is used for microMIPS code just as it is 
for MIPS16 execution, by using odd addresses you switch the processor into 
"the other" mode, whichever of MIPS16 or microMIPS one it supports.  
However for pure-microMIPS processors the ISA bit is hardwired to 1 -- all 
code addresses are always odd.

 Coincidentally all-zeroes is a 32-bit NOP instruction both in the 
standard MIPS and the microMIPS mode -- there's a 16-bit encoding of NOP 
in the microMIPS mode naturally as well.

> > > @@ -6906,10 +6936,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
> > >  
> > >    /* MIPS version of CALL_DUMMY.  */
> > >  
> > > -  /* NOTE: cagney/2003-08-05: Eventually call dummy location will be
> > > -     replaced by a command, and all targets will default to on stack
> > > -     (regardless of the stack's execute status).  */
> > > -  set_gdbarch_call_dummy_location (gdbarch, AT_SYMBOL);
> > > +  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
> > > +  set_gdbarch_push_dummy_code (gdbarch, mips_push_dummy_code);
> > >    set_gdbarch_frame_align (gdbarch, mips_frame_align);
> > >  
> > >    set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
> > 
> >  So what if the stack pages are indeed not executable (their page entries 
> > have the XI aka Execute Inhibit bit set)?
> 
> The only time when we are executing an instruction on the stack is
> when the function being called returns and hits the breakpoint.
> IIRC, there has been some testing done against this situation,
> and things just worked. I suspect that we get a trap, and that trap
> correctly gets interpreted. I can see ourselves receiving a signal
> instead, but I think this can also be correctly interpreted. Maybe
> we'll have to make some adjustement to GDB's core, but I'd rather
> fix that if I have a way to reproduce and therefore test...

 Understood, but I'd be happier if the comment you're removing or a 
similar stayed in place.  If by trap you mean SIGTRAP, then I think this 
is not going to be the case.

 For the record: if the XI bit is set and execution is attempted, then the 
Execute-Inhibit exception is triggered.  Depending on how the processor 
has been configured, this will map either to the TLBL exception, just as 
with any TLB fault on an instruction fetch, or a newly-defined exception 
(see below).  This will probably be translated to SIGSEGV by any OS; any 
bare-iron application may not be as flexible, but certainly will handle it 
somehow if it set XI in the first place.

 The Execute-Inhibit exception certainly has a precedence over software 
breakpoints (both BREAK and SDBBP) because the respective instruction has 
to execute for the breakpoint exception to trigger.  However hardware 
instruction breakpoints, both EJTAG and CP0 Watch register ones, do take 
precedence over Execute-Inhibit.

 The XI feature itself is a moderately new addition to the MIPS 
architecture, originally introduced with the SmartMIPS ASE (a security 
enhancement intended for smart cards, I'm told) and with revision #3 
merged into the base architecture.  There is a corresponding RI feature, 
intended to read-protect pages holding code.

 The Execute-Inhibit and Read-Inhibit exceptions are new codes (20 and 19, 
respectively) added to the CP0 Cause register with the merge of the 
feature into the base architecture (they were not defined for the original 
SmartMIPS ASE), so there is little if any existing practice as to how they 
are handled by OSes, my SIGSEGV assumption above is how I would handle it 
myself.  Upstream Linux kernel does not handle the new codes for once, but 
does handle the XI bit itself in some configurations.  I don't think I 
have access to any hardware I could test it with though.

 I know that some architectures have supported such fine-grained access to 
virtual memory for quite a while now, so I would have assumed we have got 
it sorted out already somehow in a generic way.

  Maciej


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