Re: __darwin_i386_exception_state, cr2 and faultvaddr
Re: __darwin_i386_exception_state, cr2 and faultvaddr
- Subject: Re: __darwin_i386_exception_state, cr2 and faultvaddr
- From: Terry Lambert <email@hidden>
- Date: Thu, 22 Jan 2009 02:06:47 -0800
On Jan 19, 2009, at 2:51 PM, Joel Reymont wrote:
On Jan 19, 2009, at 10:35 PM, Terry Lambert wrote:
The GP2 does not get the faulting address on i385 if it is in the
64 bit hole. Otherwise it is the faulting address.
What is GP2?
Is this the EIP in the saved registers or the faultvaddr?
I need to get hold of the return EIP, I think, i.e. the address I
will be going back to.
There are five types of memory faults that result in an exception.
The first type is a memory fault for a a page which is mapped; these
include trying to write to a page which is mapped read-only or read/
execute. The second type is attempting to execute in a page that
isn't marked executable. The third is attempting to read a page which
is not marked readable. The fourth is attempting to read/write/
execute a page which simply isn't mapped. The final type is
attempting to access for any reason a page which is in the
architectural address space hole which is the difference between the
architected 64 bit address space and the implemented 48 bit address
space on current CPUs.
This last one turns into a General Protection Fault, and it's a
different once than the others in that it is impossible to get back
the address resulting in the fault because the bits are simply not
available from the processor at the time the fault occurs. The only
way you're getting those bits back is if you do instruction stream
emulation by knowing where you should have been executing at the time
of the failure, and emulate it to the point of saying "yes this is the
emulated faulting address".
The other types of exception that you end up with are divided into
data access exceptions (which translate out as SIGBUS and SIGSEGV) or
an instruction access exception (which mostly translates into a
SIGILL, unless you've used floating point).
Assuming you didn't general protection yourself, by the time this gets
to your signal handler, half of the information has been lost,
however, since we cache the si_addr value at exception time, and based
on the exception type, we have to pick whether it means the address of
the faulting instruction (which it will be, for a SIGILL or SIGFPE),
or the address of the faulting memory reference (which it will be for
a SIGSEGV pr SIGBUS).
So basically, you are going to lose the information you want when
using signals to do this sort of thing, even if you do manage to cast
the third argument out of a void * (which it is) and dig it out of the
right out of several ucontext_t structures which might be being used
(depending on the architecture and the age of the binary).
Don't expect siginfo to not change. Unless you are a debugger, and
rev every time week rev the os, expect your code to break. A call
to getthreadstate is a better bet.
Do you mean getcontext (man ucontext)?
According to the sigaction manpage, the handler has this interface
void handler(int, siginfo_t *info, ucontext_t *uap);
It says that in the example. In the definition section, it's
considered a void *, meaning "no user serviceable parts inside".
This lets us change it if we need to, with the only thing being
damaged by a change being gdb itself, since no one else is actually
supposed to be looking at it.
If you want to file a documentation bug vs. the BSD kernel component,
I can get the example part of the man change pages to make sure it
says "void *" there, too.
so the user context (thread state?) is given.
What am I missing?
There are actually a bunch of different ucontext formats. The
ucontext format will generally be changed (or it's ID changed) when we
release a new set of tools or a new version of the OS, or a new
platform (which happens to require it). How to decode it is based on
its ID, and that's subject to change.
For example, the uc_mcontext field is a structure pointer or literal
inlined data, depending. The context can be 32 bit, 64 bit, or both
(which was needed to support 64 bit leaf functions on PPC64 code
called from PPC32 code).
There's really a lot of tricky, ugly stuff that happens in there, and
you can't depend on it (you can only depend on us to update the tools
we ship at the same time we ship the OS, if we've updated the OS
between one release and the next).
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden