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(`-ffile-prefix-map=([^@]+)=([^@]+)`),
65 re(`-fno-canonical-system-headers`),
66 re(`-f(no-)?eliminate-unused-debug-types`),
67 re(`-f(no-)?exceptions`),
68 re(`-f(no-)?fast-math`),
69 re(`-f(no-)?inline-functions`),
70 re(`-finput-charset=([^@\-].*)`),
71 re(`-f(no-)?fat-lto-objects`),
72 re(`-f(no-)?keep-inline-dllexport`),
73 re(`-f(no-)?lto`),
74 re(`-fmacro-backtrace-limit=(.+)`),
75 re(`-fmessage-length=(.+)`),
76 re(`-f(no-)?modules`),
77 re(`-f(no-)?objc-arc`),
78 re(`-f(no-)?objc-nonfragile-abi`),
79 re(`-f(no-)?objc-legacy-dispatch`),
80 re(`-f(no-)?omit-frame-pointer`),
81 re(`-f(no-)?openmp(-simd)?`),
82 re(`-f(no-)?permissive`),
83 re(`-f(no-)?(pic|PIC|pie|PIE)`),
84 re(`-f(no-)?plt`),
85 re(`-f(no-)?rtti`),
86 re(`-f(no-)?split-stack`),
87 re(`-f(no-)?stack-(.+)`),
88 re(`-f(no-)?strict-aliasing`),
89 re(`-f(un)signed-char`),
90 re(`-f(no-)?use-linker-plugin`),
91 re(`-f(no-)?visibility-inlines-hidden`),
92 re(`-fsanitize=(.+)`),
93 re(`-fsanitize-undefined-strip-path-components=(-)?[0-9]+`),
94 re(`-ftemplate-depth-(.+)`),
95 re(`-ftls-model=(global-dynamic|local-dynamic|initial-exec|local-exec)`),
96 re(`-fvisibility=(.+)`),
97 re(`-g([^@\-].*)?`),
98 re(`-m32`),
99 re(`-m64`),
100 re(`-m(abi|arch|cpu|fpu|simd|tls-dialect|tune)=([^@\-].*)`),
101 re(`-m(no-)?v?aes`),
102 re(`-marm`),
103 re(`-mcmodel=[0-9a-z-]+`),
104 re(`-mfloat-abi=([^@\-].*)`),
105 re(`-m(soft|single|double)-float`),
106 re(`-mfpmath=[0-9a-z,+]*`),
107 re(`-m(no-)?avx[0-9a-z.]*`),
108 re(`-m(no-)?ms-bitfields`),
109 re(`-m(no-)?stack-(.+)`),
110 re(`-mmacosx-(.+)`),
111 re(`-m(no-)?relax`),
112 re(`-m(no-)?strict-align`),
113 re(`-m(no-)?(lsx|lasx|frecipe|div32|lam-bh|lamcas|ld-seq-sa)`),
114 re(`-mios-simulator-version-min=(.+)`),
115 re(`-miphoneos-version-min=(.+)`),
116 re(`-mlarge-data-threshold=[0-9]+`),
117 re(`-mtvos-simulator-version-min=(.+)`),
118 re(`-mtvos-version-min=(.+)`),
119 re(`-mwatchos-simulator-version-min=(.+)`),
120 re(`-mwatchos-version-min=(.+)`),
121 re(`-mnop-fun-dllimport`),
122 re(`-m(no-)?sse[0-9.]*`),
123 re(`-m(no-)?ssse3`),
124 re(`-mthumb(-interwork)?`),
125 re(`-mthreads`),
126 re(`-mwindows`),
127 re(`-no-canonical-prefixes`),
128 re(`--param=ssp-buffer-size=[0-9]*`),
129 re(`-pedantic(-errors)?`),
130 re(`-pipe`),
131 re(`-pthread`),
132 re(`-?-std=([^@\-].*)`),
133 re(`-?-stdlib=([^@\-].*)`),
134 re(`--sysroot=([^@\-].*)`),
135 re(`-w`),
136 re(`-x([^@\-].*)`),
137 re(`-v`),
138 }
139
140 var validCompilerFlagsWithNextArg = []string{
141 "-arch",
142 "-D",
143 "-U",
144 "-I",
145 "-F",
146 "-framework",
147 "-include",
148 "-isysroot",
149 "-isystem",
150 "--sysroot",
151 "-target",
152 "-x",
153 }
154
155 var invalidLinkerFlags = []*lazyregexp.Regexp{
156
157
158 re(`-lto_library`),
159 }
160
161 var validLinkerFlags = []*lazyregexp.Regexp{
162 re(`-F([^@\-].*)`),
163 re(`-l([^@\-].*)`),
164 re(`-L([^@\-].*)`),
165 re(`-O`),
166 re(`-O([^@\-].*)`),
167 re(`-f(no-)?(pic|PIC|pie|PIE)`),
168 re(`-f(no-)?openmp(-simd)?`),
169 re(`-fsanitize=([^@\-].*)`),
170 re(`-flat_namespace`),
171 re(`-g([^@\-].*)?`),
172 re(`-headerpad_max_install_names`),
173 re(`-m(abi|arch|cpu|fpu|simd|tls-dialect|tune)=([^@\-].*)`),
174 re(`-mcmodel=[0-9a-z-]+`),
175 re(`-mfloat-abi=([^@\-].*)`),
176 re(`-m(soft|single|double)-float`),
177 re(`-m(no-)?relax`),
178 re(`-m(no-)?strict-align`),
179 re(`-m(no-)?(lsx|lasx|frecipe|div32|lam-bh|lamcas|ld-seq-sa)`),
180 re(`-mmacosx-(.+)`),
181 re(`-mios-simulator-version-min=(.+)`),
182 re(`-miphoneos-version-min=(.+)`),
183 re(`-mthreads`),
184 re(`-mwindows`),
185 re(`-(pic|PIC|pie|PIE)`),
186 re(`-pthread`),
187 re(`-rdynamic`),
188 re(`-shared`),
189 re(`-?-static([-a-z0-9+]*)`),
190 re(`-?-stdlib=([^@\-].*)`),
191 re(`-v`),
192
193
194
195
196
197
198 re(`-Wl,--(no-)?allow-multiple-definition`),
199 re(`-Wl,--(no-)?allow-shlib-undefined`),
200 re(`-Wl,--(no-)?as-needed`),
201 re(`-Wl,-Bdynamic`),
202 re(`-Wl,-berok`),
203 re(`-Wl,-Bstatic`),
204 re(`-Wl,-Bsymbolic-functions`),
205 re(`-Wl,-O[0-9]+`),
206 re(`-Wl,-d[ny]`),
207 re(`-Wl,--disable-new-dtags`),
208 re(`-Wl,-e[=,][a-zA-Z0-9]+`),
209 re(`-Wl,--enable-new-dtags`),
210 re(`-Wl,--end-group`),
211 re(`-Wl,--(no-)?export-dynamic`),
212 re(`-Wl,-E`),
213 re(`-Wl,-framework,[^,@\-][^,]*`),
214 re(`-Wl,--hash-style=(sysv|gnu|both)`),
215 re(`-Wl,-headerpad_max_install_names`),
216 re(`-Wl,--no-undefined`),
217 re(`-Wl,--pop-state`),
218 re(`-Wl,--push-state`),
219 re(`-Wl,-R,?([^@\-,][^,@]*$)`),
220 re(`-Wl,--just-symbols[=,]([^,@\-][^,@]*)`),
221 re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]*)`),
222 re(`-Wl,-s`),
223 re(`-Wl,-search_paths_first`),
224 re(`-Wl,-sectcreate,([^,@\-][^,]*),([^,@\-][^,]*),([^,@\-][^,]*)`),
225 re(`-Wl,--start-group`),
226 re(`-Wl,-?-static`),
227 re(`-Wl,-?-subsystem,(native|windows|console|posix|xbox)`),
228 re(`-Wl,-syslibroot[=,]([^,@\-][^,]*)`),
229 re(`-Wl,-undefined[=,]([^,@\-][^,]*)`),
230 re(`-Wl,-?-unresolved-symbols=[^,]+`),
231 re(`-Wl,--(no-)?warn-([^,]+)`),
232 re(`-Wl,-?-wrap[=,][^,@\-][^,]*`),
233 re(`-Wl(,-z,(relro|now|(no)?execstack))+`),
234
235 re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so|tbd)`),
236 re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
237 }
238
239 var validLinkerFlagsWithNextArg = []string{
240 "-arch",
241 "-F",
242 "-l",
243 "-L",
244 "-framework",
245 "-isysroot",
246 "--sysroot",
247 "-target",
248 "-Wl,-framework",
249 "-Wl,-rpath",
250 "-Wl,-R",
251 "-Wl,--just-symbols",
252 "-Wl,-undefined",
253 }
254
255 func checkCompilerFlags(name, source string, list []string) error {
256 checkOverrides := true
257 return checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
258 }
259
260 func checkLinkerFlags(name, source string, list []string) error {
261 checkOverrides := true
262 return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
263 }
264
265
266
267
268
269 func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
270 checkOverrides := false
271 if err := checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
272 return err
273 }
274
275
276 for _, fl := range list {
277 if strings.HasPrefix(fl, "-flto") {
278 return fmt.Errorf("flag %q triggers external linking", fl)
279 }
280 }
281 return nil
282 }
283
284 func checkFlags(name, source string, list []string, invalid, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
285
286 var (
287 allow *regexp.Regexp
288 disallow *regexp.Regexp
289 )
290 if checkOverrides {
291 if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
292 r, err := regexp.Compile(env)
293 if err != nil {
294 return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
295 }
296 allow = r
297 }
298 if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
299 r, err := regexp.Compile(env)
300 if err != nil {
301 return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
302 }
303 disallow = r
304 }
305 }
306
307 Args:
308 for i := 0; i < len(list); i++ {
309 arg := list[i]
310 if disallow != nil && disallow.FindString(arg) == arg {
311 goto Bad
312 }
313 if allow != nil && allow.FindString(arg) == arg {
314 continue Args
315 }
316 for _, re := range invalid {
317 if re.FindString(arg) == arg {
318 goto Bad
319 }
320 }
321 for _, re := range valid {
322 if match := re.FindString(arg); match == arg {
323 continue Args
324 } else if strings.HasPrefix(arg, "-Wl,--push-state,") {
325
326
327
328 args := strings.Split(arg, ",")
329 for _, a := range args[1:] {
330 a = "-Wl," + a
331 var found bool
332 for _, re := range valid {
333 if re.FindString(a) == a {
334 found = true
335 break
336 }
337 }
338 if !found {
339 goto Bad
340 }
341 for _, re := range invalid {
342 if re.FindString(a) == a {
343 goto Bad
344 }
345 }
346 }
347 continue Args
348 }
349 }
350 for _, x := range validNext {
351 if arg == x {
352 if i+1 < len(list) && load.SafeArg(list[i+1]) {
353 i++
354 continue Args
355 }
356
357
358 if i+1 < len(list) &&
359 strings.HasPrefix(arg, "-Wl,") &&
360 strings.HasPrefix(list[i+1], "-Wl,") &&
361 load.SafeArg(list[i+1][4:]) &&
362 !strings.Contains(list[i+1][4:], ",") {
363 i++
364 continue Args
365 }
366
367
368 if i+1 < len(list) && arg == "-I" {
369 if (strings.HasPrefix(list[i+1], "=") || strings.HasPrefix(list[i+1], "$SYSROOT")) &&
370 load.SafeArg(list[i+1][1:]) {
371 i++
372 continue Args
373 }
374 }
375
376 if i+1 < len(list) {
377 return fmt.Errorf("invalid flag in %s: %s %s (see https://go.dev/s/invalidflag)", source, arg, list[i+1])
378 }
379 return fmt.Errorf("invalid flag in %s: %s without argument (see https://go.dev/s/invalidflag)", source, arg)
380 }
381 }
382 Bad:
383 return fmt.Errorf("invalid flag in %s: %s (see https://go.dev/s/invalidflag)", source, arg)
384 }
385 return nil
386 }
387
View as plain text