示例#1
0
/* return phase path */
char *
get_phase_dir (phases_t index)
{
#if defined(__linux__) || defined(__APPLE__)
	char *name = phase_info[index].name;

    if (external_gcc != TRUE) {

        /* Construct the path to the internal gcc binaries. */
        if (strcmp(name, "gcc") == 0 || strcmp(name, "g++") == 0) {
            char *root_dir = directory_path(get_executable_dir());
            char *bin_dir = concat_path(root_dir, INTERNAL_GCC_BIN);
            char *gcc_path = concat_path(bin_dir, name);

            if (is_executable(gcc_path)) {
                free(gcc_path);
                return bin_dir;
            }
            free(gcc_path);
            free(bin_dir);
        }
    }
	if (phase_info[index].find_dir_by_path) {
		char cmd[PATH_BUF_LEN];
		char result[PATH_BUF_LEN];

		sprintf(cmd, "dirname \"`which %s`\"", phase_info[index].name);
		if(read_cmd_out(cmd, result) == NULL)
			return phase_info[index].dir;
		return string_copy(result);
	}
#endif
	return phase_info[index].dir;
}
示例#2
0
void
run_phase (phases_t phase, char *name, string_list_t *args)
{
    const char **argv;
    int argc;
    string_item_t *p;
    char *output = NULL;
    char *input = NULL;
    boolean save_stderr = FALSE;
    int fdin, fdout;
    int waitstatus;
    int termsig;
    int num_maps;
    char *rld_path;
    struct stat stat_buf;
    const char* errmsg;
    int errnum;
    char *my_path;
    char *l_path;
    char *l32_path;
    char *nls_path;
    char *env_path;
    char *root_prefix;

#if defined(BUILD_OS_DARWIN)
    int suppress_compiler_path = (phase == P_gas);
#endif /* defined(BUILD_OS_DARWIN) */
    const boolean uses_message_system = 
            (phase == P_f90_fe || phase == P_cppf90_fe);

    if ((phase == P_be || phase == P_ipl) && add_heap_limit) {
        char str[200];

        sprintf(str, "-OPT:hugepage_heap_limit=%d -OPT:hugepage_attr=%d", 
			    heap_limit, hugepage_attr);
        add_string(args, str);
    }
    
    if (show_flag) {
        /* echo the command */
        fprintf(stderr, "%s ", name);
        print_string_list(stderr, args);
    }

    if (!execute_flag) return;

    if (time_flag) init_time();

    /* copy arg_list to argv format that exec wants */
    for (argc = 1, p = args->head; p != NULL; p = p->next) {
        //bug# 581, bug #932, bug #1049
        if (p->name == NULL || p->name[0] == '\0') {
            continue;
        }
        argc++;
    }
    argv = (const char **)malloc((argc + 1) * sizeof(char *));
    if (argv == NULL) {
        error("not enough memory");
        cleanup();
        do_exit(RC_SYSTEM_ERROR);
    }

    argv[0] = name;
    for (argc = 1, p = args->head; p != NULL; p = p->next) {
        //bug# 581, bug #932
        if (p->name == NULL || p->name[0] == '\0') {
            continue;
        }
        /* don't put redirection in arg list */
        if (strcmp(p->name, "<") == 0) {
            /* has input file */
            input = p->next->name;
            break;
        } else if (strcmp(p->name, ">") == 0) {
            /* has output file */
            output = p->next->name;
            break;
        } else if (strcmp(p->name, ">&") == 0) {
            /* has error output file */
            output = p->next->name;
            save_stderr = TRUE;
            break;
        }
        argv[argc++] = p->name;
    }
    argv[argc] = NULL;

    if (show_command_only(name, argv)) {
        return;
    }

    my_path = get_binutils_lib_path();
    rld_path = get_phase_ld_library_path(phase);
    
    if (rld_path != NULL) {
        asprintf(&my_path, "%s:%s", my_path, rld_path);
    }
    
    l_path = l32_path = my_path;
    
    if (ld_library_path) {
        asprintf(&l_path, "%s:%s", my_path, ld_library_path);
    }

    /* if we want memory stats, we have to wait for
       parent to connect to our /proc */
    if (input != NULL) {
    	if ((fdin = open (input, O_RDONLY)) == -1) {
            error ("cannot open input file %s", input);
            cleanup ();
            do_exit (RC_SYSTEM_ERROR);
            /* NOTREACHED */
    	}
    	dup2 (fdin, fileno(stdin));
    }
    if (output != NULL) {
    	if ((fdout = creat (output, 0666)) == -1) {
            error ("cannot create output file %s", output);
            cleanup ();
            do_exit (RC_SYSTEM_ERROR);
            /* NOTREACHED */
    	}
    	if (save_stderr) {
            dup2 (fdout, fileno(stderr));
    	} else {
            dup2 (fdout, fileno(stdout));
    	}
    } 
    
    my_path = get_binutils_lib_path();
    rld_path = get_phase_ld_library_path (phase);
    
    if (rld_path != 0) {
    	asprintf(&my_path, "%s:%s:%s/%s", my_path, rld_path, rld_path, current_target->abi_name);
    }
    
    l_path = l32_path = my_path;
    
    if (ld_library_path)
    	asprintf(&l_path, "%s:%s", my_path, ld_library_path);
    
    if (ld_libraryn32_path)
    	asprintf(&l32_path, "%s:%s", my_path,
    		 ld_libraryn32_path);

#if defined(BUILD_OS_DARWIN)
    /* Darwin static linker uses LD_LIBRARY_PATH, but dynamic
     * linker uses DYLD_LIBRARY_PATH */
    my_putenv("DYLD_LIBRARY_PATH", "%s", l_path);
#else /* defined(BUILD_OS_DARWIN) */
    my_putenv("LD_LIBRARY_PATH", "%s", l_path);
    my_putenv("LD_LIBRARYN32_PATH", "%s", l32_path);
#endif /* defined(BUILD_OS_DARWIN) */
		
    // Set up NLSPATH, for the Fortran front end.
    
    nls_path = getenv("NLSPATH");
    root_prefix = directory_path(get_executable_dir());
    
    if (nls_path) {
        my_putenv("NLSPATH", "%s:%s%s/%%N.cat", nls_path, root_prefix, LIBPATH);
    } else {
        my_putenv("NLSPATH", "%s%s/%%N.cat", root_prefix, LIBPATH);
    }
    
    if (uses_message_system && getenv("ORIG_CMD_NAME") == NULL)
        my_putenv("ORIG_CMD_NAME", "%s", program_name);
    
    if (phase == P_f90_fe) {
        char *root;
        char *modulepath;
        int len;
        char *new_env;
        char *env_name = "FORTRAN_SYSTEM_MODULES=";
        char *env_val = "/usr/lib/f90modules";
        root = getenv("TOOLROOT");
        if (root != NULL) {
            len = strlen(env_val) + strlen(root) +3 + strlen(env_val);
            new_env = alloca(len);
            sprintf(new_env,"%s/%s:%s",root,env_val,env_val);
            env_val = new_env;
        }
        modulepath = string_copy(getenv("FORTRAN_SYSTEM_MODULES"));
        if (modulepath != NULL) {
            /* Append env_val to FORTRAN_SYSTEM_MODULES */
            if (modulepath[strlen(modulepath)-1] == ':') {
                /* Just append env_val */
                len = strlen(modulepath) + strlen(env_val) + 1;
                new_env = alloca(len);
                sprintf(new_env,"%s%s",modulepath,env_val);
            } else {
                /* append :env_val */
                len = strlen(modulepath) + strlen(env_val) + 2;
                new_env = alloca(len);
                sprintf(new_env,"%s:%s",modulepath,env_val);
            }
            env_val = new_env;
        }
        
        my_putenv ("FORTRAN_SYSTEM_MODULES", "%s", env_val);
    }

    /* need to setenv COMPILER_PATH for collect to find ld */
    if (
#ifdef KEY
        // gcc will invoke the cc1 in the COMPILER_PATH directory,
        // which is not what we want when we invoke gcc for
        // preprocessing.  Bug 10164.

#if defined(BUILD_OS_DARWIN)
        /* Driver uses gcc to run assembler. If we set COMPILER_PATH,
         * gcc uses PSC version of cc1, which doesn't accept one of
         * the options (-mmacosx-version-min=10.5.1) which Apple's
         * gcc driver passes to Apple's cc1. Looks like the
         * "is_matching_phase" test might already be trying to fix
         * this, but it's not succeeding.
         */
        !suppress_compiler_path &&
#endif
        !is_matching_phase(get_phase_mask(P_any_cpp), phase) &&
#endif
        1) {
        my_putenv("COMPILER_PATH", "%s", get_phase_dir(P_collect));
    }

    /* Tell IPA where to find the driver. */
    my_putenv("COMPILER_BIN", "%s/" PSC_NAME_PREFIX "cc-"
              PSC_FULL_VERSION, get_executable_dir());

    if (execute(name, argv, input, output, &errmsg, &waitstatus) == -1) {
        error("execute failed: %s", errmsg);
        cleanup();
        do_exit(RC_SYSTEM_ERROR);
    }

    if (time_flag) print_time(name);
    
    if (WIFSTOPPED(waitstatus)) {
        error("STOPPED signal received from %s", name);
        cleanup();
        do_exit(RC_SYSTEM_ERROR);
        /* NOTREACHED */
    } else if (WIFEXITED(waitstatus)) {
        int status = WEXITSTATUS(waitstatus);
        extern int inline_t;
        boolean internal_err = FALSE;
        boolean user_err = FALSE;
        
        if (phase == P_prof) {
            /* Make sure the .cfb files were created before
               changing the STATUS to OKAY */
            if (prof_file != NULL) {
                if (!(stat(fb_file, &stat_buf) != 0 && errno == ENOENT)) {
                    status = RC_OKAY;
                }
            } else {
                internal_error("No count file was specified for a prof run");
                perror(program_name);
            }
        }
    
        if (phase == P_f90_fe && keep_listing) {
            char *cif_file = construct_given_name(drop_path(source_file), 
                                                  "T", TRUE);
    
            if (!(stat(cif_file, &stat_buf) != 0 && errno == ENOENT)) {
                f90_fe_status = status;
            }
            
            f90_fe_name = string_copy(name);
    
            /* Change the status to OKAY so that we can 
             * execute the lister on the cif_file; we will
             * take appropriate action on this status once 
             * the lister has finished executing. See below.
             */
            status = RC_OKAY;
        }
    
        if (phase == P_lister) {
            if (status == RC_OKAY && f90_fe_status != RC_OKAY) {
    
                /* We had encountered an error in the F90_fe phase
                 * but we ignored it so that we could execute the
                 * lister on the cif file; we need to switch the
                 * status to the status we received from F90_fe
                 * and use the name of the F90_fe_phase, so that
                 * we can issue a correct error message.
                 */
    
                status = f90_fe_status;
                name = string_copy(f90_fe_name);
    
                /* Reset f90_fe_status to OKAY for any further
                 * compilations on other source files.
                 */
    
                f90_fe_status = RC_OKAY;
            }
        }
    
        switch (status) {
        case RC_OKAY:
#ifdef KEY
            // If the command line has explicit inline
            // setting, follow it; else follow the
            // front-end request.  Bug 11325.
            if (inline_t != UNDEFINED) {
                run_inline = inline_t;
                break;
            }

#ifdef PATH64_ENABLE_GNU_FRONTEND
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_wgen)) {
              run_inline = FALSE;
            }
#endif // PATH64_ENABLE_GNU_FRONTEND
#ifdef PATH64_ENABLE_PSCLANG
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_psclang)) {
              run_inline = FALSE;
            }
#endif // PATH64_ENABLE_PSCLANG
            break;
#endif
            if (inline_t == UNDEFINED  && 
                is_matching_phase(get_phase_mask(phase), P_any_fe)) {
#ifdef KEY
                run_inline = FALSE; // bug 11325
#else
                inline_t = FALSE;
#endif
            }
            break;
        
        case RC_NEED_INLINER:
#ifdef KEY      // If the command line has explicit inline
            // setting, follow it; else follow the
            // front-end request.  Bug 11325.
            if (inline_t != UNDEFINED) {
                run_inline = inline_t;
                break;
            }

#ifdef PATH64_ENABLE_GNU_FRONTEND
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_wgen)) {
                run_inline = TRUE;
            }
#endif // PATH64_ENABLE_GNU_FRONTEND
#ifdef PATH64_ENABLE_PSCLANG
            // bug 10215
            if (is_matching_phase(get_phase_mask(phase), P_psclang)) {
              run_inline = TRUE;
            }
#endif // PATH64_ENABLE_PSCLANG
            break;

#endif
            if (inline_t == UNDEFINED && 
                is_matching_phase(get_phase_mask(phase), P_any_fe)) {
#ifdef KEY
                run_inline = TRUE;  // bug 11325
#else
                inline_t = TRUE;
#endif
            }
            /* completed successfully */
            break;
            
        case RC_USER_ERROR:
        case RC_NORECOVER_USER_ERROR:
        case RC_SYSTEM_ERROR:
        case RC_GCC_ERROR:
#ifdef KEY
        case RC_RTL_MISSING_ERROR: /* bug 14054 */
#endif
            user_err = TRUE;
            break;

        case RC_OVERFLOW_ERROR:
            if (!ran_twice && phase == P_be) {
                /* try recompiling with larger limits */
                ran_twice = TRUE;
                add_string(args, "-TENV:long_eh_offsets");
                add_string(args, "-TENV:large_stack");
                run_phase(phase, name, args);
                return;
            }
            internal_err = TRUE;
            break;
#ifdef KEY
        case RC_GCC_INTERNAL_ERROR:
#endif
        case RC_INTERNAL_ERROR:
            internal_err = TRUE;
            break;

        default:
            internal_err = TRUE;
            break;
        } 

        if (internal_err) {
            if (phase == P_ld ||
                phase == P_ldplus ||
#ifdef KEY
                phase == P_gas ||           // bug 4846
                phase == P_f_coco ||        // bug 9058
#ifdef PATH64_ENABLE_PSCLANG
                phase == P_psclang_cpp ||
                phase == P_psclang ||
#endif // PATH64_ENABLE_PSCLANG
                status == RC_GCC_INTERNAL_ERROR ||  //bug 9637
#endif // KEY
#ifdef PATH64_ENABLE_GNU_FRONTEND
                phase == P_spin_cc1 ||
                phase == P_spin_cc1plus ||
                phase == P_gcpp ||
                phase == P_gcpp_plus ||
#endif // PATH64_ENABLE_GNU_FRONTEND
                TRUE) {

                if (phase == P_gas ||
                    status == RC_GCC_INTERNAL_ERROR) {
                	internal_error_occurred = 1;
                }
                log_error("%s returned non-zero status %d", name, status);
                nomsg_error(status);
            } else {
                internal_error("%s returned non-zero status %d", name, status);
            }
        }
        else if (user_err) {
            /* assume phase will print diagnostics */
            if (phase == P_c_gfe || phase == P_cplus_gfe
#ifdef PATH64_ENABLE_GNU_FRONTEND
#ifdef KEY
                || phase == P_wgen
                || phase == P_spin_cc1
                || phase == P_spin_cc1plus
#endif // KEY
#endif // PATH64_ENABLE_GNU_FRONTEND
               ) {
                nomsg_error(RC_INTERNAL_ERROR);
            }
            else if (!show_flag || save_stderr) {
                nomsg_error(RC_USER_ERROR);
            } else {
                error("%s returned non-zero status %d", name, status);
            }
        }
        ran_twice = FALSE;
        return;

    } else if(WIFSIGNALED(waitstatus)) {
        termsig = WTERMSIG(waitstatus);
        switch (termsig) {
#ifdef SIGHUP
        case SIGHUP:
#endif
        case SIGINT:
#ifdef SIGQUIT
        case SIGQUIT:
#endif
#ifdef SIGKILL
        case SIGKILL:
#endif
        case SIGTERM:
            error("%s died due to signal %d", name, termsig);
            break;
        default:
            internal_error("%s died due to signal %d", name, termsig);
            break;
        }

        if(waitstatus & WCOREFLAG) {
            error("core dumped");
        }

#ifdef SIGKILL
        if (termsig == SIGKILL) {
            error("Probably caused by running out of swap space -- check %s", LOGFILE);
        }
#endif

        cleanup();
        do_exit(RC_SYSTEM_ERROR);
    } else {
        /* cannot happen, I think! */
        internal_error("driver exec'ing is confused");
        return;
    }
}
示例#3
0
void obtain_license (char *exedir, int argc, char *argv[]) {
    int pipes[2] ;
    int pid ;
    char exename[MAXPATHLEN] ;
    char language[10] ;
    struct stat st ;
    int i ;
    char *l ;
    char *prodname;

    const char *errortext = "Unable to obtain subscription.  The PathScale compiler cannot run without a subscription.\nPlease see http://www.pathscale.com/subscription/1.1/msgs.html for details.\n" ;
   
#ifdef TARG_MIPS
    if (!strcmp(target_cpu, "mips5kf") ||
	!strcmp(target_cpu, "twc9a")) {
      return;
    } else {
      warning("Unexpected target_cpu \"%s\" requires subscription.",
	      target_cpu ? target_cpu : "(NULL)");
    }
#endif
#ifdef NO_LICENSE_CHECK 
    return;
#endif

    l = getenv ("PATHSCALE_SUBSCRIPTION_CLIENT") ;
    if (l == NULL) {
        snprintf (exename, sizeof(exename), "%s/subclient", exedir) ;
        if (subverbose) {
            fprintf (stderr, "Subscription client: looking for %s\n", exename) ;
        }
        if (stat (exename, &st) != 0) {
            snprintf (exename, sizeof(exename), "%s/subclient",
		      get_phase_dir(P_be)) ;
            if (subverbose) {
                fprintf (stderr, "Subscription client: looking for %s\n", exename) ;
            }
            if (stat (exename, &st) != 0) {
                fprintf (stderr, "%s", errortext) ;
                do_exit (1); 
            }
        }
    } else {
        strcpy (exename, l) ;
        if (subverbose) {
            fprintf (stderr, "Subscription client: looking for %s\n", exename) ;
        }
        if (stat (exename, &st) != 0) {
            fprintf (stderr, "%s", errortext) ;
            do_exit (1); 
        }
    }

    subflags[0] = '\0' ;
    for (i = 1 ; i < argc ; i++) {
        if (argv[i][0] == '-') {
            switch (argv[i][1]) {
            case 'o':		// don't pass these as they might contain sensitive stuff
            case 'I':
            case 'L':
            case 'D':
            case 'U':
                break ;
            case 'W':
                if (strncmp (argv[i], "-Wl", 3) == 0) {
                }
                goto addflag ;
            case 'T':
                if (strncmp (argv[i], "-TENV:ipa_ident", 15) == 0) {
                    break ;
                }
                // fall through
            default:
            addflag:
                strcat (subflags, argv[i]) ;
                strcat (subflags, " ") ;
                break ;
            }
        }
    }

    switch (invoked_lang) {
    case L_f77:
        strcpy (language, "FORTRAN77") ;
	break;
    case L_f90:
        strcpy (language, "FORTRAN90") ;
	break;
    case L_cc:
        strcpy (language, "C") ;
	break;
    case L_CC:
        strcpy (language, "CC") ;
	break;
    }

    {
      // bug 12667
      char *dir = get_executable_dir();
      prodname = "Compiler";
      if (dir != NULL) {
	char *basedir = directory_path(dir);
	char *ndir = concat_strings(basedir, "/lib/" PSC_FULL_VERSION "/cray");
	if (file_exists(ndir)) {
	  prodname = "Compiler_XTS";
	}
      }
    }

    pid = fork() ;
    if (pid == 0) {		// child
        const char *argvec[8] ;

        argvec[0] = exename ;
        argvec[1] = prodname;		// bug 12667
        argvec[2] = language ;
        argvec[3] = PSC_BUILD_DATE ;
        argvec[4] = subflags ;
        argvec[5] = PSC_FULL_VERSION ;
        argvec[6] = NULL ;
        if (subverbose) {
            argvec[6] = "--v" ;
            argvec[7] = NULL ;
        }
        execv (exename, (char*const*)argvec) ;
        fprintf (stderr, "%s", errortext) ;
        do_exit (6) ;
    } else {
        int statloc ;
        waitpid (pid, &statloc, 0) ;

        // if we were not able to get a license due to missing subclient executable, tell caller
        if (WIFEXITED(statloc)) {
            if (WEXITSTATUS (statloc) == 6) {		// no subclient program?
                do_exit (1) ;
            } else if (WEXITSTATUS (statloc) == 7) {	// hard stop?
                fprintf (stderr, "Compilation terminated\n") ;
                do_exit (1) ;
            } else if (WEXITSTATUS (statloc) != 0) {            // license client failed, can't rely on output
                fprintf (stderr, "Subscription client exited with error status\n") ;
                do_exit (1) ;
            }
        } else {
	  fprintf (stderr, "Subscription client error\n") ;	// bug 9164
	  do_exit(1);
        }

    }
}