This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Support setjmp in x86-64 psABI with AVX-512
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: Rich Felker <dalias at aerifal dot cx>
- Cc: GNU C Library <libc-alpha at sourceware dot org>, GCC Development <gcc at gcc dot gnu dot org>, Binutils <binutils at sourceware dot org>
- Date: Sat, 27 Jul 2013 20:27:07 +0200
- Subject: Support setjmp in x86-64 psABI with AVX-512
- References: <CAMe9rOrvMxSLj3LcYBs71tVdw6C0vJFKD2HxvnoHc13UamftwA at mail dot gmail dot com> <ddab98c2-bb3b-4d02-b403-e7d5690cfe00 at email dot android dot com> <CAMe9rOpxErCVtE-PDZ3Yb9mL+4E+XQ-are9Df4YBbEioj+MmZA at mail dot gmail dot com> <b9c5d467-834a-4b57-b48c-ac4bb450c9e5 at email dot android dot com> <20130725030655 dot GL14138 at laptop dot redhat dot com> <20130725065538 dot GA18427 at domone dot kolej dot mff dot cuni dot cz> <20130725165053 dot GJ4284 at brightrain dot aerifal dot cx> <20130727154405 dot GA25725 at domone dot kolej dot mff dot cuni dot cz> <20130727161257 dot GY4284 at brightrain dot aerifal dot cx>
On Sat, Jul 27, 2013 at 12:12:57PM -0400, Rich Felker wrote:
> On Sat, Jul 27, 2013 at 05:44:05PM +0200, OndÅej BÃlka wrote:
> > On Thu, Jul 25, 2013 at 12:50:53PM -0400, Rich Felker wrote:
> > > On Thu, Jul 25, 2013 at 08:55:38AM +0200, OndÅej BÃlka wrote:
> > > You can't add call-saved registers without breaking the ABI, because
> > > they need to be saved in the jmp_buf, which does not have space for
> > > them.
> > >
> > Well you can. Use versioning, structure will not change and layout for
> > old setjmp/longjmp is unchanged. For new setjmp we set jump address to
> > jmp_buf address to distinguish it from first case. Then for each thread
> > we keep a stack with extra space needed to save additional registers.
> > When setjmp/longjmp is called we prune frames from exited functions.
>
> This required unbounded storage which does not exist. From a practical
> standpoint you would either have to reserve a huge amount of storage
> (e.g. double the allocated thread stack size and use half of it as
> reserved space for jmp_buf) or make the calling program crash when the
Standard trick mmap and double.
> small, reasonable amount of reserved space is exhausted. The latter is
> highly unacceptable since the main purpose (IMO:) of jmp_buf is to
> work around bad library code that can't handle resource exhaustion by
> replacing its 'xmalloc' type functions with ones that longjmp to a
> thread-local jmp_buf set by the caller (e.g. this is the only way to
> use glib robustly).
>
Well what I wrote is to work around pathologic cases.
With versioning and changing size of structure I could do trick with
distinguishing by pointing to itself and it would mostly work.
It would break when function that uses setjmp obtains jmp_buf by
parameter from other unit.
To avoid it we need allocate some extra space. Most programs would have
number of jmp_buf instances limited so not deallocating extra would not
cause problem. To violate that limit you need to have variation to these:
int rec(..){
jmp_buf x;
setjmp(x);
...
rec(x);
}
while (cond){
jmp_buf *x= malloc(...);
setjmp(x);
...
free(x);
}
> By the way, I do have another horrible idea for how you could do it.
Next idea would be hack gcc to mark all variables volatile in functions
with setjmp.
> glibc's jmp_buf is actually a sigjmp_buf and contains 120 wasted bytes
> of sigset_t for nonexistant HURD signals. So you could store a few
> registers after the actually-used part of the sigset_t.
>
> > > Also, unless you add them at the same time the registers are added to
> > > the machine (so there's no existing code using those registers),
> > > you'll have ABI problems like this: function using the new call-saved
> > > registers calls qsort, which calls application code, which assumes the
> > > registers are call-clobbered and clobbers them; after qsort returns,
> > > the original caller's state is gone.
> > >
> > What are you talking about? Do you mean that user wrongly marked qsort
> > as a function that does not clobber arguments?
>
> OK, you're obviously thinking of some kind of special way of tagging
> individual functions as preserving new registers, rather than whole
> object or shared library files, in which case it's plausible that you
> can make this part work.
>
> Rich