Blame arch/nt64/src/crt_glue.c

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