Blame arch/nt32/src/crt_glue.c

296178
#include <unistd.h>
296178
#include <pthread.h>
296178
#include "atomic.h"
296178
#include "syscall.h"
296178
#include "psxglue.h"
296178
#include "pthread_impl.h"
296178
296178
extern struct __ldso_vtbl *	__ldso_vtbl;
296178
extern struct __psx_vtbl *	__psx_vtbl;
296178
296178
typedef int __app_main();
296178
typedef int __pthread_surrogate_routine(struct pthread *);
296178
296178
extern int _init(void);
296178
static int __pthread_surrogate_init(struct pthread * self);
296178
296178
extern int __libc_start_main(
296178
	void *	main,
296178
	int	argc,
296178
	char **	argv);
296178
296178
void __libc_entry_routine(
296178
	__app_main *		__main,
296178
	__psx_init_routine *	__psx_init,
296178
	int			options)
296178
{
296178
	int			argc;
296178
	char **			argv;
296178
	char **			envp;
296178
	struct __psx_context	ctx;
296178
296178
	/* ctx init */
296178
	ctx.size		= sizeof(ctx);
296178
	ctx.options		= options;
296178
	ctx.pthread_create_fn	= pthread_create;
296178
	ctx.pthread_surrogate_fn= __pthread_surrogate_init;
296178
296178
	/* __psx_init must succeed... */
296178
	if (__psx_init(&argc,&argv,&envp,&ctx))
296178
		a_crash();
296178
296178
	/* ...and conform */
296178
	else if (envp != argv + (argc + 1))
296178
		a_crash();
296178
296178
	/* dso init routines */
296178
	_init();
296178
296178
	/* write once */
296178
	__syscall_vtbl	= (unsigned long **)ctx.sys_vtbl;
296178
	__ldso_vtbl	= ctx.ldso_vtbl;
296178
	__psx_vtbl	= ctx.psx_vtbl;
296178
	__teb_sys_idx	= ctx.teb_sys_idx;
296178
	__teb_libc_idx	= ctx.teb_libc_idx;
296178
296178
	/* enter libc */
296178
	__libc_start_main(__main,argc,argv);
296178
296178
	/* guard */
296178
	a_crash();
296178
}
296178
296178
static int __pthread_surrogate_init(struct pthread * self)
296178
{
296178
	/**
296178
	 * invoked by psxscl upon creation of a surrogate libc
296178
	 * thread, which in turn may only call pthread_create();
296178
	 *
296178
	 * the purpose of this mecahnism is to support a scenario
296178
	 * where a third-party library creates a non-posix thread
296178
	 * which then calls, be it directly or via a callback
296178
	 * function, a libc api that depends on a valid
296178
	 * pthread_self.
296178
	 *
296178
	 * self: a pointer to an already zero'ed memory page
296178
	 *
296178
	 * struct pthread relevant members:
296178
	 * --------------------------------
296178
	 * cancel (already zero)
296178
	 * canary (already zero)
296178
	 *
296178
	 * pthread_create() reference:
296178
	 * 1a47ed15eebf96d0c8d5de4aea54108bc8cc3f53
296178
	**/
296178
296178
	return 0;
296178
}