Ejemplo n.º 1
0
static int realmode(unsigned nthreads)
{
int	listensock;
struct	cthreadinfo *threads;
struct	dupinfo di;

	listensock=lf_init("filters/dupfilter-mode",
		ALLFILTERSOCKETDIR "/dupfilter",
		ALLFILTERSOCKETDIR "/.dupfilter",
		FILTERSOCKETDIR "/dupfilter",
		FILTERSOCKETDIR "/.dupfilter");

	if (listensock < 0)
		return (1);

	threads=cthread_init(nthreads, sizeof(struct dupinfo),
		(void (*)(void *))&hashclient_wrapper,
		(void (*)(void *))&checkclient);
	if (!threads)
	{
		perror("cthread_init");
		return (1);
	}

	lf_init_completed(listensock);

	for (;;)
	{
		if ((di.fd=lf_accept(listensock)) < 0)	break;

		di.cancelfunc= &realcancel;

		if ( cthread_go(threads,
			(void (*)(void *, void *))&initdupinfo, &di))
		{
			perror("cthread_go");
			break;
		}
	}
	cthread_wait(threads);
	return (0);
}
Ejemplo n.º 2
0
/*
 * _dyld_init() is the start off point for the dynamic link editor.  It is
 * called before any part of an executable program runs.  This is done either
 * in the executable runtime startoff or by the kernel as a result of an exec(2)
 * system call (which goes through __dyld_start to get here).
 *
 * This routine causes the dynamic shared libraries an executable uses to be
 * mapped, sets up the executable and the libraries to call the dynamic link
 * editor when a lazy reference to a symbol is first used, resolves all non-lazy
 * symbol references needed to start running the program and then returns to
 * the executable program to start up the program.
 */
unsigned long
_dyld_init(
struct mach_header *mh,
unsigned long argc,
char **argv,
char **envp)
{
    unsigned int count;
    kern_return_t r;
    unsigned long entry_point;
    mach_port_t my_mach_host_self;
#ifndef __MACH30__
    struct section *s;
#endif
#ifdef MALLOC_DEBUG
    extern void cthread_init(void);

	cthread_init();
#endif
	
	/* set lock for dyld data structures */
	set_lock();

	/*
	 * Get the cputype and cpusubtype of the machine we're running on.
	 */
	count = HOST_BASIC_INFO_COUNT;
	my_mach_host_self = mach_host_self();
	if((r = host_info(my_mach_host_self, HOST_BASIC_INFO, (host_info_t)
			  (&host_basic_info), &count)) != KERN_SUCCESS){
	    mach_port_deallocate(mach_task_self(), my_mach_host_self);
	    mach_error(r, "can't get host basic info");
	}
	mach_port_deallocate(mach_task_self(), my_mach_host_self);
#if defined(__GONZO_BUNSEN_BEAKER__) && defined(__ppc__)
	if(host_basic_info.cpu_type == CPU_TYPE_POWERPC &&
	   (host_basic_info.cpu_subtype == CPU_SUBTYPE_POWERPC_7400 ||
	    host_basic_info.cpu_subtype == CPU_SUBTYPE_POWERPC_7450 ||
	    host_basic_info.cpu_subtype == CPU_SUBTYPE_POWERPC_970))
	    processor_has_vec = TRUE;
#endif

	/*
	 * Pickup the environment variables for the dynamic link editor.
	 */
	pickup_environment_variables(envp);
	
	/*
	 * Make initial trace entry if requested.
	 */
	DYLD_TRACE_INIT_START(0);

	/*
	 * Create the executable's path from the exec_path and the current
	 * working directory (if needed).  If we did not pick up the exec_path
	 * (we are running with an old kernel) use argv[0] if has a slash in it
	 * as it is a path relative to the current working directory.  Of course
	 * argv[0] may not have anything to do with the filename being executed
	 * in all cases but it is likely to be right.
	 */
	if(exec_path != NULL)
	    create_executables_path(exec_path);
	else if(strchr(argv[0], '/') != NULL)
	    create_executables_path(argv[0]);
	if(dyld_executable_path_debug == TRUE)
	    printf("executables_path = %s\n",
		   executables_path == NULL ? "NULL" : executables_path);

#ifdef DYLD_PROFILING
	s = (struct section *) getsectbynamefromheader(
	    &_mh_dylinker_header, SEG_TEXT, SECT_TEXT);
	monstartup((char *)(s->addr + dyld_image_vmaddr_slide),
		   (char *)(s->addr + dyld_image_vmaddr_slide + s->size));
#endif

#ifndef __MACH30__
	/*
	 * See if the profile server for shared pcsample buffers exists.
	 * Then if so try to setup a pcsample buffer for dyld itself.
	 */
	profile_server = profile_server_exists();
	if(profile_server == TRUE){
	    s = (struct section *) getsectbynamefromheader(
		&_mh_dylinker_header, SEG_TEXT, SECT_TEXT);
	    shared_pcsample_buffer("/usr/lib/dyld", s, dyld_image_vmaddr_slide);
	}
#endif /* __MACH30__ */

	/*
	 * Start off by loading the executable image as the first object image
	 * that make up the program.  This in turn will load the dynamic shared
	 * libraries the executable uses and the libraries those libraries use
	 * to the list of library images that make up the program.
	 */
	if((mh->flags & MH_FORCE_FLAT) != 0 ||
	   dyld_force_flat_namespace == TRUE)
	    force_flat_namespace = TRUE;
	if((mh->flags & MH_NOFIXPREBINDING) == MH_NOFIXPREBINDING)
	    dyld_no_fix_prebinding = TRUE;
	executable_prebound = (mh->flags & MH_PREBOUND) == MH_PREBOUND;
	load_executable_image(argv[0], mh, &entry_point);

	/*
	 * If the prebinding set is still set then try to setup this program to
	 * use the prebound state in it's images.  If any of these fail then
	 * undo any prebinding and bind as usual.
	 */
	if((mh->flags & MH_PREBOUND) != MH_PREBOUND){
	    /*
	     * The executable is not prebound but if the libraries are setup
	     * for prebinding and the executable when built had no undefined
	     * symbols then try to use the prebound libraries.  This is for
	     * the flat namespace case (and only some sub cases, see the
	     * comments in try_to_use_prebound_libraries()).  If this fails
	     * then the two-level namespace cases are handled by the routine
	     * find_twolevel_prebound_lib_subtrees() which is called below.
	     */
	    if(prebinding == TRUE){
		if((mh->flags & MH_NOUNDEFS) == MH_NOUNDEFS){
		    try_to_use_prebound_libraries();
		}
		else{
		    if(dyld_prebind_debug != 0)
			print("dyld: %s: prebinding disabled because "
			       "executable not marked with MH_NOUNDEFS\n",
				argv[0]);
		    prebinding = FALSE;
		}
	    }
	}
	else if(prebinding == TRUE){
	    set_images_to_prebound();
	}
	if(prebinding == FALSE){
	    /*
	     * The program was not fully prebound but if we are not forcing
	     * flat namespace semantics we can still use any sub trees of
	     * libraries that are all two-level namespace and prebound.
	     */
	    if(force_flat_namespace == FALSE)
		find_twolevel_prebound_lib_subtrees();

	    /*
	     * First undo any images that were prebound.
	     */
	    undo_prebound_images(FALSE);

	    /*
	     * Build the initial list of non-lazy symbol references based on the
	     * executable.
	     */
	    if((mh->flags & MH_BINDATLOAD) != 0 || dyld_bind_at_launch == TRUE)
		executable_bind_at_load = TRUE;
	    setup_initial_undefined_list(FALSE);

	    /*
	     * With the undefined list set up link in the needed modules.
	     */
	    link_in_need_modules(FALSE, FALSE, NULL);
	}
	else{
	    if(dyld_prebind_debug != 0){
		if((mh->flags & MH_PREBOUND) != MH_PREBOUND)
		    print("dyld: %s: prebinding enabled using only prebound "
			   "libraries\n", argv[0]);
		else
		    print("dyld: %s: prebinding enabled\n", argv[0]);
	    }
	}
	/*
	 * Now with the program about to be launched set
	 * all_twolevel_modules_prebound to TRUE if all libraries are two-level,
	 * prebound and all modules in them are linked.
	 */
	set_all_twolevel_modules_prebound();
	launched = TRUE;

	/*
	 * If DYLD_EBADEXEC_ONLY is set then print a message as the program
	 * will launch.
	 */
	if(dyld_ebadexec_only == TRUE){
	    error("executable: %s will be launched (DYLD_EBADEXEC_ONLY set, "
		"program not started)", argv[0]);
	    link_edit_error(DYLD_FILE_ACCESS, EBADEXEC, argv[0]);
	}
	
	if(dyld_print_libraries_post_launch == TRUE)
	    dyld_print_libraries = TRUE;

	/* release lock for dyld data structures */
	release_lock();
	
	DYLD_TRACE_INIT_END(0);

	/*
	 * Return the address of the executable's entry point which is used if
	 * this routine was called from __dyld_start.  Otherwise this was called
	 * from the runtime startoff of the executable and this return value is
	 * ignored.
	 */
	return(entry_point);
}