1 /* Wrapper for ar/ranlib/nm to pass the LTO plugin. 2 Copyright (C) 2011-2013 Free Software Foundation, Inc. 3 Contributed by Andi Kleen. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 3, or (at your option) any later 10 version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "libiberty.h" 24 #include "file-find.h" 25 26 #ifndef PERSONALITY 27 #error "Please set personality" 28 #endif 29 30 /* The exec prefix as derived at compile-time from --prefix. */ 31 32 static const char standard_exec_prefix[] = STANDARD_EXEC_PREFIX; 33 34 /* The libexec prefix as derived at compile-time from --prefix. */ 35 36 static const char standard_libexec_prefix[] = STANDARD_LIBEXEC_PREFIX; 37 38 /* The bindir prefix as derived at compile-time from --prefix. */ 39 40 static const char standard_bin_prefix[] = STANDARD_BINDIR_PREFIX; 41 42 /* A relative path to be used in finding the location of tools 43 relative to this program. */ 44 45 static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX; 46 47 /* The exec prefix as relocated from the location of this program. */ 48 49 static const char *self_exec_prefix; 50 51 /* The libexec prefix as relocated from the location of this program. */ 52 53 static const char *self_libexec_prefix; 54 55 /* The tools prefix as relocated from the location of this program. */ 56 57 static const char *self_tooldir_prefix; 58 59 /* The name of the machine that is being targeted. */ 60 61 static const char *const target_machine = DEFAULT_TARGET_MACHINE; 62 63 /* The target version. */ 64 65 static const char *const target_version = DEFAULT_TARGET_VERSION; 66 67 /* The collection of target specific path prefixes. */ 68 69 static struct path_prefix target_path; 70 71 /* The collection path prefixes. */ 72 73 static struct path_prefix path; 74 75 /* The directory separator. */ 76 77 static const char dir_separator[] = { DIR_SEPARATOR, 0 }; 78 79 static void 80 setup_prefixes (const char *exec_path) 81 { 82 const char *self; 83 84 self = getenv ("GCC_EXEC_PREFIX"); 85 if (!self) 86 self = exec_path; 87 else 88 self = concat (self, "gcc-" PERSONALITY, NULL); 89 90 /* Relocate the exec prefix. */ 91 self_exec_prefix = make_relative_prefix (self, 92 standard_bin_prefix, 93 standard_exec_prefix); 94 if (self_exec_prefix == NULL) 95 self_exec_prefix = standard_exec_prefix; 96 97 /* Relocate libexec prefix. */ 98 self_libexec_prefix = make_relative_prefix (self, 99 standard_bin_prefix, 100 standard_libexec_prefix); 101 if (self_libexec_prefix == NULL) 102 self_libexec_prefix = standard_libexec_prefix; 103 104 105 /* Build the relative path to the target-specific tool directory. */ 106 self_tooldir_prefix = concat (tooldir_base_prefix, target_machine, 107 dir_separator, NULL); 108 self_tooldir_prefix = concat (self_exec_prefix, target_machine, 109 dir_separator, target_version, dir_separator, 110 self_tooldir_prefix, NULL); 111 112 /* Add the target-specific tool bin prefix. */ 113 prefix_from_string (concat (self_tooldir_prefix, "bin", NULL), &target_path); 114 115 /* Add the target-specific libexec prefix. */ 116 self_libexec_prefix = concat (self_libexec_prefix, target_machine, 117 dir_separator, target_version, 118 dir_separator, NULL); 119 prefix_from_string (self_libexec_prefix, &target_path); 120 121 /* Add path as a last resort. */ 122 prefix_from_env ("PATH", &path); 123 } 124 125 int 126 main(int ac, char **av) 127 { 128 const char *exe_name; 129 char *plugin; 130 int k, status, err; 131 const char *err_msg; 132 const char **nargv; 133 bool is_ar = !strcmp (PERSONALITY, "ar"); 134 int exit_code = FATAL_EXIT_CODE; 135 136 setup_prefixes (av[0]); 137 138 /* Find the GCC LTO plugin */ 139 plugin = find_a_file (&target_path, LTOPLUGINSONAME, R_OK); 140 if (!plugin) 141 { 142 fprintf (stderr, "%s: Cannot find plugin '%s'\n", av[0], LTOPLUGINSONAME); 143 exit (1); 144 } 145 146 /* Find the wrapped binutils program. */ 147 exe_name = find_a_file (&target_path, PERSONALITY, X_OK); 148 if (!exe_name) 149 { 150 const char *real_exe_name = PERSONALITY; 151 #ifdef CROSS_DIRECTORY_STRUCTURE 152 real_exe_name = concat (target_machine, "-", PERSONALITY, NULL); 153 #endif 154 exe_name = find_a_file (&path, real_exe_name, X_OK); 155 if (!exe_name) 156 { 157 fprintf (stderr, "%s: Cannot find binary '%s'\n", av[0], 158 real_exe_name); 159 exit (1); 160 } 161 } 162 163 /* Create new command line with plugin */ 164 nargv = XCNEWVEC (const char *, ac + 4); 165 nargv[0] = exe_name; 166 nargv[1] = "--plugin"; 167 nargv[2] = plugin; 168 if (is_ar && av[1] && av[1][0] != '-') 169 av[1] = concat("-", av[1], NULL); 170 for (k = 1; k < ac; k++) 171 nargv[2 + k] = av[k]; 172 nargv[2 + k] = NULL; 173 174 /* Run utility */ 175 /* ??? the const is misplaced in pex_one's argv? */ 176 err_msg = pex_one (PEX_LAST|PEX_SEARCH, 177 exe_name, 178 CONST_CAST2 (char * const *, const char **, nargv), 179 concat("gcc-", exe_name, NULL), 180 NULL,NULL, &status, &err); 181 if (err_msg) 182 fprintf(stderr, "Error running %s: %s\n", exe_name, err_msg); 183 else if (status) 184 { 185 if (WIFSIGNALED (status)) 186 { 187 int sig = WTERMSIG (status); 188 fprintf (stderr, "%s terminated with signal %d [%s]%s\n", 189 exe_name, sig, strsignal(sig), 190 WCOREDUMP(status) ? ", core dumped" : ""); 191 } 192 else if (WIFEXITED (status)) 193 exit_code = WEXITSTATUS (status); 194 } 195 else 196 exit_code = SUCCESS_EXIT_CODE; 197 198 return exit_code; 199 } 200