sudo: don't use hardening flags on host tools
[buildroot-gz.git] / toolchain / toolchain-external / ext-toolchain-wrapper.c
blob8db4ac4214d0d320275e12481ddb8b9a33f9420a
1 /**
2 * Buildroot wrapper for external toolchains. This simply executes the real
3 * toolchain with a number of arguments (sysroot/arch/..) hardcoded,
4 * to ensure the external toolchain uses the correct configuration.
5 * The hardcoded path arguments are defined relative to the actual location
6 * of the binary.
8 * (C) 2011 Peter Korsgaard <jacmet@sunsite.dk>
9 * (C) 2011 Daniel Nyström <daniel.nystrom@timeterminal.se>
10 * (C) 2012 Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
11 * (C) 2013 Spenser Gilliland <spenser@gillilanding.com>
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
18 #include <stdio.h>
19 #include <string.h>
20 #include <limits.h>
21 #include <unistd.h>
22 #include <stdlib.h>
24 static char path[PATH_MAX];
25 static char sysroot[PATH_MAX];
27 /**
28 * GCC errors out with certain combinations of arguments (examples are
29 * -mfloat-abi={hard|soft} and -m{little|big}-endian), so we have to ensure
30 * that we only pass the predefined one to the real compiler if the inverse
31 * option isn't in the argument list.
32 * This specifies the worst case number of extra arguments we might pass
33 * Currently, we have:
34 * -mfloat-abi=
35 * -march=
36 * -mtune=
37 * -mcpu=
39 #define EXCLUSIVE_ARGS 4
41 static char *predef_args[] = {
42 path,
43 "--sysroot", sysroot,
44 #ifdef BR_ABI
45 "-mabi=" BR_ABI,
46 #endif
47 #ifdef BR_FPU
48 "-mfpu=" BR_FPU,
49 #endif
50 #ifdef BR_SOFTFLOAT
51 "-msoft-float",
52 #endif /* BR_SOFTFLOAT */
53 #ifdef BR_MODE
54 "-m" BR_MODE,
55 #endif
56 #ifdef BR_64
57 "-m64",
58 #endif
59 #ifdef BR_BINFMT_FLAT
60 "-Wl,-elf2flt",
61 #endif
62 #ifdef BR_MIPS_TARGET_LITTLE_ENDIAN
63 "-EL",
64 #endif
65 #ifdef BR_MIPS_TARGET_BIG_ENDIAN
66 "-EB",
67 #endif
68 #ifdef BR_ADDITIONAL_CFLAGS
69 BR_ADDITIONAL_CFLAGS
70 #endif
73 int main(int argc, char **argv)
75 char **args, **cur;
76 char *relbasedir, *absbasedir;
77 char *progpath = argv[0];
78 char *basename;
79 char *env_debug;
80 int ret, i, count = 0, debug;
82 /* Calculate the relative paths */
83 basename = strrchr(progpath, '/');
84 if (basename) {
85 *basename = '\0';
86 basename++;
87 relbasedir = malloc(strlen(progpath) + 7);
88 if (relbasedir == NULL) {
89 perror(__FILE__ ": malloc");
90 return 2;
92 sprintf(relbasedir, "%s/../..", argv[0]);
93 absbasedir = realpath(relbasedir, NULL);
94 } else {
95 basename = progpath;
96 absbasedir = malloc(PATH_MAX + 1);
97 ret = readlink("/proc/self/exe", absbasedir, PATH_MAX);
98 if (ret < 0) {
99 perror(__FILE__ ": readlink");
100 return 2;
102 absbasedir[ret] = '\0';
103 for (i = ret; i > 0; i--) {
104 if (absbasedir[i] == '/') {
105 absbasedir[i] = '\0';
106 if (++count == 3)
107 break;
111 if (absbasedir == NULL) {
112 perror(__FILE__ ": realpath");
113 return 2;
116 /* Fill in the relative paths */
117 #ifdef BR_CROSS_PATH_REL
118 ret = snprintf(path, sizeof(path), "%s/" BR_CROSS_PATH_REL "/%s", absbasedir, basename);
119 #else /* BR_CROSS_PATH_ABS */
120 ret = snprintf(path, sizeof(path), BR_CROSS_PATH_ABS "/%s", basename);
121 #endif
122 if (ret >= sizeof(path)) {
123 perror(__FILE__ ": overflow");
124 return 3;
126 ret = snprintf(sysroot, sizeof(sysroot), "%s/" BR_SYSROOT, absbasedir);
127 if (ret >= sizeof(sysroot)) {
128 perror(__FILE__ ": overflow");
129 return 3;
132 cur = args = malloc(sizeof(predef_args) +
133 (sizeof(char *) * (argc + EXCLUSIVE_ARGS)));
134 if (args == NULL) {
135 perror(__FILE__ ": malloc");
136 return 2;
139 /* start with predefined args */
140 memcpy(cur, predef_args, sizeof(predef_args));
141 cur += sizeof(predef_args) / sizeof(predef_args[0]);
143 #ifdef BR_FLOAT_ABI
144 /* add float abi if not overridden in args */
145 for (i = 1; i < argc; i++) {
146 if (!strncmp(argv[i], "-mfloat-abi=", strlen("-mfloat-abi=")) ||
147 !strcmp(argv[i], "-msoft-float") ||
148 !strcmp(argv[i], "-mhard-float"))
149 break;
152 if (i == argc)
153 *cur++ = "-mfloat-abi=" BR_FLOAT_ABI;
154 #endif
156 #if defined(BR_ARCH) || \
157 defined(BR_TUNE) || \
158 defined(BR_CPU)
159 /* Add our -march/cpu/tune/abi flags, but only if none are
160 * already specified on the commandline
162 for (i = 1; i < argc; i++) {
163 if (!strncmp(argv[i], "-march=", strlen("-march=")) ||
164 !strncmp(argv[i], "-mtune=", strlen("-mtune=")) ||
165 !strncmp(argv[i], "-mcpu=", strlen("-mcpu=" )))
166 break;
168 if (i == argc) {
169 #ifdef BR_ARCH
170 *cur++ = "-march=" BR_ARCH;
171 #endif
172 #ifdef BR_TUNE
173 *cur++ = "-mtune=" BR_TUNE;
174 #endif
175 #ifdef BR_CPU
176 *cur++ = "-mcpu=" BR_CPU;
177 #endif
179 #endif /* ARCH || TUNE || CPU */
181 /* append forward args */
182 memcpy(cur, &argv[1], sizeof(char *) * (argc - 1));
183 cur += argc - 1;
185 /* finish with NULL termination */
186 *cur = NULL;
188 /* Debug the wrapper to see actual arguments passed to
189 * the compiler:
190 * unset, empty, or 0: do not trace
191 * set to 1 : trace all arguments on a single line
192 * set to 2 : trace one argument per line
194 if ((env_debug = getenv("BR2_DEBUG_WRAPPER"))) {
195 debug = atoi(env_debug);
196 if (debug > 0) {
197 fprintf(stderr, "Toolchain wrapper executing:");
198 for (i = 0; args[i]; i++)
199 fprintf(stderr, "%s'%s'",
200 (debug == 2) ? "\n " : " ", args[i]);
201 fprintf(stderr, "\n");
205 if (execv(path, args))
206 perror(path);
208 free(args);
210 return 2;