6

I was interested in what exactly setjmp does at least in x86_64 linux, so I searched through glibc's source code, but I cannot really find where the register saving is done. Could you explain what is going on here?

setjmp.h

extern int _setjmp (struct __jmp_buf_tag __env[1]) __THROWNL;
#define setjmp(env)     _setjmp (env)

bsd-_setjmp.c

int
_setjmp (jmp_buf env)
{
  return __sigsetjmp (env, 0);
}

libc_hidden_def (_setjmp)

setjmp.c

int
__libc_sigsetjmp (jmp_buf env, int savemask)
{
  __sigjmp_save (env, savemask);
  __set_errno (ENOSYS);
  return 0;
}

weak_alias (__libc_sigsetjmp, __sigsetjmp)
stub_warning (__sigsetjmp)

sigjmp.c

int
__sigjmp_save (sigjmp_buf env, int savemask)
{
  env[0].__mask_was_saved = (savemask &&
                             __sigprocmask (SIG_BLOCK, (sigset_t *) NULL,
                                            &env[0].__saved_mask) == 0);
  return 0;
}
  • 2
    I think it's written in assembly in one of the platform specific directories. Have you tried single-stepping with a debeugger through the glibc and observing what source files you hit? – fuz Aug 03 '15 at 10:19
  • It might be done internally within the compiler. – Barmar Aug 03 '15 at 10:34
  • 2
    The x86_64 source can be [found here](https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/setjmp.S;h=774aaf1e8d9c918162a88cb1141fe4737969c4af;hb=HEAD). It's written in assembly. If you move "up" a directory, you can find the source for other platforms too. – P.P Aug 03 '15 at 10:57

1 Answers1

5

setjmp is a macro which calls _setjmp. For the x86_64 architecture, it's defined in ../sysdeps/x86_64/bsd-_setjmp.S. _setjmp will then call __sigsetjmp, defined in ../sysdeps/x86_64/setjmp.S; this function is strictly platform dependent and needs to be implemented in assembly.

edmz
  • 8,220
  • 2
  • 26
  • 45