Undefined behaviour code used in sysdeps/unix/sysv/linux/x86_64/makecontext.c

Godmar Back godmar@gmail.com
Mon May 21 11:39:00 GMT 2018


On Mon, May 21, 2018 at 12:32 AM, Remus Clearwater
<remus.clearwater@gmail.com> wrote:
> https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/makecontext.c;h=0d0802bf431326f7fcfe03d49df0c8ee7f4fdaab;hb=HEAD#l71
>
>   51 void
>   52 __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
>   53 {
>   54   extern void __start_context (void) attribute_hidden;
>   55   greg_t *sp;
>   56   unsigned int idx_uc_link;
>   57   va_list ap;
>   58   int i;
>   59
>   60   /* Generate room on stack for parameter if needed and uc_link.  */
>   61   sp = (greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp
>   62                    + ucp->uc_stack.ss_size);
>   63   sp -= (argc > 6 ? argc - 6 : 0) + 1;
>   64   /* Align stack and make space for trampoline address.  */
>   65   sp = (greg_t *) ((((uintptr_t) sp) & -16L) - 8);
>   66
>   67   idx_uc_link = (argc > 6 ? argc - 6 : 0) + 1;
>   68
>   69   /* Setup context ucp.  */
>   70   /* Address to jump to.  */
>
>   71   ucp->uc_mcontext.gregs[REG_RIP] = (uintptr_t) func;
>
> As far as I know cast a function pointer to ordinary integer type or
> void*/char* is undefined behaviour in C specification.
>

My reading is that it is implementation-defined, not undefined.

Looking at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf it says:

"Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior is
undefined. The result need not be in the range of values of any
integer type."

and moreover: "The mapping functions for converting a pointer to an
integer or an integer to a pointer are intended to be consistent with
the addressing structure of the execution environment."



More information about the Libc-help mailing list