This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

Support setjmp in x86-64 psABI with AVX-512


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


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