1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package work
31
32 import (
33 "fmt"
34 "internal/lazyregexp"
35 "regexp"
36 "strings"
37
38 "cmd/go/internal/cfg"
39 "cmd/go/internal/load"
40 )
41
42 var re = lazyregexp.New
43
44 var validCompilerFlags = []*lazyregexp.Regexp{
45 re(`-D([A-Za-z_][A-Za-z0-9_]*)(=[^@\-]*)?`),
46 re(`-U([A-Za-z_][A-Za-z0-9_]*)`),
47 re(`-F([^@\-].*)`),
48 re(`-I([^@\-].*)`),
49 re(`-O`),
50 re(`-O([^@\-].*)`),
51 re(`-W`),
52 re(`-W([^@,]+)`),
53 re(`-Wa,-mbig-obj`),
54 re(`-Wp,-D([A-Za-z_][A-Za-z0-9_]*)(=[^@,\-]*)?`),
55 re(`-Wp,-U([A-Za-z_][A-Za-z0-9_]*)`),
56 re(`-ansi`),
57 re(`-f(no-)?asynchronous-unwind-tables`),
58 re(`-f(no-)?blocks`),
59 re(`-f(no-)builtin-[a-zA-Z0-9_]*`),
60 re(`-f(no-)?common`),
61 re(`-f(no-)?constant-cfstrings`),
62 re(`-fdebug-prefix-map=([^@]+)=([^@]+)`),
63 re(`-fdiagnostics-show-note-include-stack`),
64 re(`-fexcess-precision=([A-Za-z0-9_]+)`),
65 re(`-ffile-prefix-map=([^@]+)=([^@]+)`),
66 re(`-fno-canonical-system-headers`),
67 re(`-f(no-)?eliminate-unused-debug-types`),
68 re(`-f(no-)?exceptions`),
69 re(`-f(no-)?fast-math`),
70 re(`-f(no-)?inline-functions`),
71 re(`-finput-charset=([^@\-].*)`),
72 re(`-f(no-)?fat-lto-objects`),
73 re(`-f(no-)?keep-inline-dllexport`),
74 re(`-f(no-)?lto`),
75 re(`-fmacro-backtrace-limit=(.+)`),
76 re(`-fmessage-length=(.+)`),
77 re(`-f(no-)?modules`),
78 re(`-f(no-)?objc-arc`),
79 re(`-f(no-)?objc-nonfragile-abi`),
80 re(`-f(no-)?objc-legacy-dispatch`),
81 re(`-f(no-)?omit-frame-pointer`),
82 re(`-f(no-)?openmp(-simd)?`),
83 re(`-f(no-)?permissive`),
84 re(`-f(no-)?(pic|PIC|pie|PIE)`),
85 re(`-f(no-)?plt`),
86 re(`-f(no-)?rtti`),
87 re(`-f(no-)?split-stack`),
88 re(`-f(no-)?stack-(.+)`),
89 re(`-f(no-)?strict-aliasing`),
90 re(`-f(un)signed-char`),
91 re(`-f(no-)?use-linker-plugin`),
92 re(`-f(no-)?visibility-inlines-hidden`),
93 re(`-fsanitize=(.+)`),
94 re(`-fsanitize-undefined-strip-path-components=(-)?[0-9]+`),
95 re(`-ftemplate-depth-(.+)`),
96 re(`-ftls-model=(global-dynamic|local-dynamic|initial-exec|local-exec)`),
97 re(`-fvisibility=(.+)`),
98 re(`-g([^@\-].*)?`),
99 re(`-m32`),
100 re(`-m64`),
101 re(`-m(abi|arch|cpu|fpu|simd|tls-dialect|tune)=([^@\-].*)`),
102 re(`-m(no-)?v?aes`),
103 re(`-marm`),
104 re(`-mcmodel=[0-9a-z-]+`),
105 re(`-mfloat-abi=([^@\-].*)`),
106 re(`-m(soft|single|double)-float`),
107 re(`-mfpmath=[0-9a-z,+]*`),
108 re(`-m(no-)?avx[0-9a-z.]*`),
109 re(`-m(no-)?ms-bitfields`),
110 re(`-m(no-)?stack-(.+)`),
111 re(`-mmacosx-(.+)`),
112 re(`-m(no-)?relax`),
113 re(`-m(no-)?strict-align`),
114 re(`-m(no-)?(lsx|lasx|frecipe|div32|lam-bh|lamcas|ld-seq-sa)`),
115 re(`-mios-simulator-version-min=(.+)`),
116 re(`-miphoneos-version-min=(.+)`),
117 re(`-mlarge-data-threshold=[0-9]+`),
118 re(`-mtvos-simulator-version-min=(.+)`),
119 re(`-mtvos-version-min=(.+)`),
120 re(`-mwatchos-simulator-version-min=(.+)`),
121 re(`-mwatchos-version-min=(.+)`),
122 re(`-mnop-fun-dllimport`),
123 re(`-m(no-)?sse[0-9.]*`),
124 re(`-m(no-)?ssse3`),
125 re(`-mthumb(-interwork)?`),
126 re(`-mthreads`),
127 re(`-mwindows`),
128 re(`-no-canonical-prefixes`),
129 re(`--param=ssp-buffer-size=[0-9]*`),
130 re(`-pedantic(-errors)?`),
131 re(`-pipe`),
132 re(`-pthread`),
133 re(`--static`),
134 re(`-?-std=([^@\-].*)`),
135 re(`-?-stdlib=([^@\-].*)`),
136 re(`--sysroot=([^@\-].*)`),
137 re(`-w`),
138 re(`-x([^@\-].*)`),
139 re(`-v`),
140 }
141
142 var validCompilerFlagsWithNextArg = []string{
143 "-arch",
144 "-D",
145 "-U",
146 "-I",
147 "-F",
148 "-framework",
149 "-include",
150 "-isysroot",
151 "-isystem",
152 "--sysroot",
153 "-target",
154 "-x",
155 }
156
157 var invalidLinkerFlags = []*lazyregexp.Regexp{
158
159
160 re(`-lto_library`),
161 }
162
163 var validLinkerFlags = []*lazyregexp.Regexp{
164 re(`-F([^@\-].*)`),
165 re(`-l([^@\-].*)`),
166 re(`-L([^@\-].*)`),
167 re(`-O`),
168 re(`-O([^@\-].*)`),
169 re(`-f(no-)?(pic|PIC|pie|PIE)`),
170 re(`-f(no-)?openmp(-simd)?`),
171 re(`-fsanitize=([^@\-].*)`),
172 re(`-flat_namespace`),
173 re(`-g([^@\-].*)?`),
174 re(`-headerpad_max_install_names`),
175 re(`-m(abi|arch|cpu|fpu|simd|tls-dialect|tune)=([^@\-].*)`),
176 re(`-mcmodel=[0-9a-z-]+`),
177 re(`-mfloat-abi=([^@\-].*)`),
178 re(`-m(soft|single|double)-float`),
179 re(`-m(no-)?relax`),
180 re(`-m(no-)?strict-align`),
181 re(`-m(no-)?(lsx|lasx|frecipe|div32|lam-bh|lamcas|ld-seq-sa)`),
182 re(`-mmacosx-(.+)`),
183 re(`-mios-simulator-version-min=(.+)`),
184 re(`-miphoneos-version-min=(.+)`),
185 re(`-mthreads`),
186 re(`-mwindows`),
187 re(`-(pic|PIC|pie|PIE)`),
188 re(`-pthread`),
189 re(`-rdynamic`),
190 re(`-shared`),
191 re(`-?-static([-a-z0-9+]*)`),
192 re(`-?-stdlib=([^@\-].*)`),
193 re(`-v`),
194
195
196
197
198
199
200 re(`-Wl,--(no-)?allow-multiple-definition`),
201 re(`-Wl,--(no-)?allow-shlib-undefined`),
202 re(`-Wl,--(no-)?as-needed`),
203 re(`-Wl,-Bdynamic`),
204 re(`-Wl,-berok`),
205 re(`-Wl,-Bstatic`),
206 re(`-Wl,-Bsymbolic-functions`),
207 re(`-Wl,-O[0-9]+`),
208 re(`-Wl,-d[ny]`),
209 re(`-Wl,--disable-new-dtags`),
210 re(`-Wl,-e[=,][a-zA-Z0-9]+`),
211 re(`-Wl,--enable-new-dtags`),
212 re(`-Wl,--end-group`),
213 re(`-Wl,--(no-)?export-dynamic`),
214 re(`-Wl,-E`),
215 re(`-Wl,-framework,[^,@\-][^,]*`),
216 re(`-Wl,--hash-style=(sysv|gnu|both)`),
217 re(`-Wl,-headerpad_max_install_names`),
218 re(`-Wl,--no-undefined`),
219 re(`-Wl,--pop-state`),
220 re(`-Wl,--push-state`),
221 re(`-Wl,-R,?([^@\-,][^,@]*$)`),
222 re(`-Wl,--just-symbols[=,]([^,@\-][^,@]*)`),
223 re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]*)`),
224 re(`-Wl,-s`),
225 re(`-Wl,-search_paths_first`),
226 re(`-Wl,-sectcreate,([^,@\-][^,]*),([^,@\-][^,]*),([^,@\-][^,]*)`),
227 re(`-Wl,--start-group`),
228 re(`-Wl,-?-static`),
229 re(`-Wl,-?-subsystem,(native|windows|console|posix|xbox)`),
230 re(`-Wl,-syslibroot[=,]([^,@\-][^,]*)`),
231 re(`-Wl,-undefined[=,]([^,@\-][^,]*)`),
232 re(`-Wl,-?-unresolved-symbols=[^,]+`),
233 re(`-Wl,--(no-)?warn-([^,]+)`),
234 re(`-Wl,-?-wrap[=,][^,@\-][^,]*`),
235 re(`-Wl(,-z,(relro|now|(no)?execstack))+`),
236
237 re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so|tbd)`),
238 re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
239 }
240
241 var validLinkerFlagsWithNextArg = []string{
242 "-arch",
243 "-F",
244 "-l",
245 "-L",
246 "-framework",
247 "-isysroot",
248 "--sysroot",
249 "-target",
250 "-Wl,-framework",
251 "-Wl,-rpath",
252 "-Wl,-R",
253 "-Wl,--just-symbols",
254 "-Wl,-undefined",
255 }
256
257 var validPkgConfigFlags = []*lazyregexp.Regexp{
258 re(`--atleast-pkgconfig-version=\d+\.\d+\.\d+`),
259 re(`--atleast-version=\d+\.\d+\.\d+`),
260 re(`--cflags-only-I`),
261 re(`--cflags`),
262 re(`--define-prefix`),
263 re(`--define-variable=[A-Za-z_][A-Za-z0-9_]*=[^@\-]*`),
264 re(`--digraph`),
265 re(`--dont-define-prefix`),
266 re(`--dont-relocate-paths`),
267 re(`--dump-personality`),
268 re(`--env-only`),
269 re(`--errors-to-stdout`),
270 re(`--exact-version=\d+\.\d+\.\d+`),
271 re(`--exists`),
272 re(`--fragment-filter=[A-Za-z_][a-zA-Z0-9_]*`),
273 re(`--ignore-conflicts`),
274 re(`--internal-cflags`),
275 re(`--keep-system-cflags`),
276 re(`--keep-system-libs`),
277 re(`--libs-only-l`),
278 re(`--libs-only-L`),
279 re(`--libs`),
280 re(`--list-all`),
281 re(`--list-package-names`),
282 re(`--max-version=\d+\.\d+\.\d+`),
283 re(`--maximum-traverse-depth=[0-9]+`),
284 re(`--modversion`),
285 re(`--msvc-syntax`),
286 re(`--no-cache`),
287 re(`--no-provides`),
288 re(`--no-uninstalled`),
289 re(`--path`),
290 re(`--personality=(triplet|filename)`),
291 re(`--prefix-variable=[A-Za-z_][a-zA-Z0-9_]*`),
292 re(`--print-errors`),
293 re(`--print-provides`),
294 re(`--print-requires-private`),
295 re(`--print-requires`),
296 re(`--print-variables`),
297 re(`--pure`),
298 re(`--shared`),
299 re(`--short-errors`),
300 re(`--silence-errors`),
301 re(`--simulate`),
302 re(`--static`),
303 re(`--uninstalled`),
304 re(`--validate`),
305 re(`--variable=[A-Za-z_][a-zA-Z0-9_]*`),
306 re(`--with-path=[^@\-].*`),
307 }
308
309 func checkCompilerFlags(name, source string, list []string) error {
310 checkOverrides := true
311 return checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
312 }
313
314 func checkLinkerFlags(name, source string, list []string) error {
315 checkOverrides := true
316 return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
317 }
318
319 func checkPkgConfigFlags(name, source string, list []string) error {
320 checkOverrides := false
321 return checkFlags(name, source, list, nil, validPkgConfigFlags, nil, checkOverrides)
322 }
323
324
325
326
327
328 func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
329 checkOverrides := false
330 if err := checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
331 return err
332 }
333
334
335
336
337 for _, fl := range list {
338 if strings.HasPrefix(fl, "-flto") {
339 return fmt.Errorf("flag %q triggers external linking", fl)
340 }
341 if fl == "-static" || fl == "--static" {
342 return fmt.Errorf("flag %q triggers external linking", fl)
343 }
344 }
345 return nil
346 }
347
348
349
350 func checkLinkerFlagsForInternalLink(name, source string, list []string) error {
351 checkOverrides := false
352 if err := checkFlags(name, source, list, nil, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides); err != nil {
353 return err
354 }
355
356
357 for _, fl := range list {
358 if fl == "-static" || fl == "--static" ||
359 fl == "-Wl,-static" || fl == "-Wl,--static" ||
360 fl == "-Wl,-Bstatic" {
361 return fmt.Errorf("flag %q triggers external linking", fl)
362 }
363 }
364 return nil
365 }
366
367 func checkFlags(name, source string, list []string, invalid, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
368
369 var (
370 allow *regexp.Regexp
371 disallow *regexp.Regexp
372 )
373 if checkOverrides {
374 if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
375 r, err := regexp.Compile(env)
376 if err != nil {
377 return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
378 }
379 allow = r
380 }
381 if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
382 r, err := regexp.Compile(env)
383 if err != nil {
384 return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
385 }
386 disallow = r
387 }
388 }
389
390 Args:
391 for i := 0; i < len(list); i++ {
392 arg := list[i]
393 if disallow != nil && disallow.FindString(arg) == arg {
394 goto Bad
395 }
396 if allow != nil && allow.FindString(arg) == arg {
397 continue Args
398 }
399 for _, re := range invalid {
400 if re.FindString(arg) == arg {
401 goto Bad
402 }
403 }
404 for _, re := range valid {
405 if match := re.FindString(arg); match == arg {
406 continue Args
407 } else if strings.HasPrefix(arg, "-Wl,--push-state,") {
408
409
410
411 args := strings.Split(arg, ",")
412 for _, a := range args[1:] {
413 a = "-Wl," + a
414 var found bool
415 for _, re := range valid {
416 if re.FindString(a) == a {
417 found = true
418 break
419 }
420 }
421 if !found {
422 goto Bad
423 }
424 for _, re := range invalid {
425 if re.FindString(a) == a {
426 goto Bad
427 }
428 }
429 }
430 continue Args
431 }
432 }
433 for _, x := range validNext {
434 if arg == x {
435 if i+1 < len(list) && load.SafeArg(list[i+1]) {
436 i++
437 continue Args
438 }
439
440
441 if i+1 < len(list) &&
442 strings.HasPrefix(arg, "-Wl,") &&
443 strings.HasPrefix(list[i+1], "-Wl,") &&
444 load.SafeArg(list[i+1][4:]) &&
445 !strings.Contains(list[i+1][4:], ",") {
446 i++
447 continue Args
448 }
449
450
451 if i+1 < len(list) && arg == "-I" {
452 if (strings.HasPrefix(list[i+1], "=") || strings.HasPrefix(list[i+1], "$SYSROOT")) &&
453 load.SafeArg(list[i+1][1:]) {
454 i++
455 continue Args
456 }
457 }
458
459 if i+1 < len(list) {
460 return fmt.Errorf("invalid flag in %s: %s %s (see https://go.dev/s/invalidflag)", source, arg, list[i+1])
461 }
462 return fmt.Errorf("invalid flag in %s: %s without argument (see https://go.dev/s/invalidflag)", source, arg)
463 }
464 }
465 Bad:
466 return fmt.Errorf("invalid flag in %s: %s (see https://go.dev/s/invalidflag)", source, arg)
467 }
468 return nil
469 }
470
View as plain text