提交 ea343364 编写于 作者: R Rich Felker

match glibc/lsb cancellation abi on i386

glibc made the ridiculous choice to use pass-by-register calling
convention for these functions, which is impossible to duplicate
directly on non-gcc compilers. instead, we use ugly asm to wrap and
convert the calling convention. presumably this works with every
compiler anyone could potentially want to use.
上级 92b52b70
......@@ -4,3 +4,22 @@ struct __ptcb {
struct __ptcb *__next;
void *__ptrs[3];
};
static inline void __pthread_register_cancel_2(struct __ptcb *__cb)
{
__asm__ __volatile__( "call __pthread_register_cancel" : : "a"(__cb) );
}
static inline void __pthread_unregister_cancel_2(struct __ptcb *__cb)
{
__asm__ __volatile__( "call __pthread_unregister_cancel" : : "a"(__cb) );
}
static inline void __pthread_unwind_next_2(struct __ptcb *__cb)
{
__asm__ __volatile__( "call __pthread_unwind_next" : : "a"(__cb) );
}
#define __pthread_register_cancel __pthread_register_cancel_2
#define __pthread_unregister_cancel __pthread_unregister_cancel_2
#define __pthread_unwind_next __pthread_unwind_next_2
......@@ -181,9 +181,11 @@ int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
#include <bits/pthread.h>
int __setjmp(void *);
#ifndef __pthread_register_cancel
void __pthread_register_cancel(struct __ptcb *);
void __pthread_unregister_cancel(struct __ptcb *);
void __pthread_unwind_next(struct __ptcb *);
#endif
#define pthread_cleanup_push(f, x) \
do { struct __ptcb __cb; void (*__f)(void *) = (f); void *__x = (x); \
......
#include "pthread_impl.h"
#ifdef __pthread_register_cancel
#undef __pthread_register_cancel
#undef __pthread_unregister_cancel
#define __pthread_register_cancel __pthread_register_cancel_3
#define __pthread_unregister_cancel __pthread_unregister_cancel_3
#endif
void __pthread_register_cancel(struct __ptcb *cb)
{
struct pthread *self = pthread_self();
......
.text
.global __pthread_register_cancel
.type __pthread_register_cancel,%function
__pthread_register_cancel:
pushl %eax
call __pthread_register_cancel_3
popl %eax
ret
.global __pthread_unregister_cancel
.type __pthread_unregister_cancel,%function
__pthread_unregister_cancel:
pushl %eax
call __pthread_unregister_cancel_3
popl %eax
ret
.text
.global __pthread_unwind_next
.type __pthread_unwind_next,%function
__pthread_unwind_next:
pushl %eax
call __pthread_unwind_next_3
popl %eax
ret
#include "pthread_impl.h"
#ifdef __pthread_unwind_next
#undef __pthread_unwind_next
#define __pthread_unwind_next __pthread_unwind_next_3
#endif
void __pthread_unwind_next(struct __ptcb *cb)
{
int i, j, not_finished;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册