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(`-ftemplate-depth-(.+)`),
94 re(`-fvisibility=(.+)`),
95 re(`-g([^@\-].*)?`),
96 re(`-m32`),
97 re(`-m64`),
98 re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`),
99 re(`-m(no-)?v?aes`),
100 re(`-marm`),
101 re(`-m(no-)?avx[0-9a-z]*`),
102 re(`-mfloat-abi=([^@\-].*)`),
103 re(`-mfpmath=[0-9a-z,+]*`),
104 re(`-m(no-)?avx[0-9a-z.]*`),
105 re(`-m(no-)?ms-bitfields`),
106 re(`-m(no-)?stack-(.+)`),
107 re(`-mmacosx-(.+)`),
108 re(`-mios-simulator-version-min=(.+)`),
109 re(`-miphoneos-version-min=(.+)`),
110 re(`-mtvos-simulator-version-min=(.+)`),
111 re(`-mtvos-version-min=(.+)`),
112 re(`-mwatchos-simulator-version-min=(.+)`),
113 re(`-mwatchos-version-min=(.+)`),
114 re(`-mnop-fun-dllimport`),
115 re(`-m(no-)?sse[0-9.]*`),
116 re(`-m(no-)?ssse3`),
117 re(`-mthumb(-interwork)?`),
118 re(`-mthreads`),
119 re(`-mwindows`),
120 re(`-no-canonical-prefixes`),
121 re(`--param=ssp-buffer-size=[0-9]*`),
122 re(`-pedantic(-errors)?`),
123 re(`-pipe`),
124 re(`-pthread`),
125 re(`-?-std=([^@\-].*)`),
126 re(`-?-stdlib=([^@\-].*)`),
127 re(`--sysroot=([^@\-].*)`),
128 re(`-w`),
129 re(`-x([^@\-].*)`),
130 re(`-v`),
131 }
132
133 var validCompilerFlagsWithNextArg = []string{
134 "-arch",
135 "-D",
136 "-U",
137 "-I",
138 "-F",
139 "-framework",
140 "-include",
141 "-isysroot",
142 "-isystem",
143 "--sysroot",
144 "-target",
145 "-x",
146 }
147
148 var invalidLinkerFlags = []*lazyregexp.Regexp{
149
150
151 re(`-lto_library`),
152 }
153
154 var validLinkerFlags = []*lazyregexp.Regexp{
155 re(`-F([^@\-].*)`),
156 re(`-l([^@\-].*)`),
157 re(`-L([^@\-].*)`),
158 re(`-O`),
159 re(`-O([^@\-].*)`),
160 re(`-f(no-)?(pic|PIC|pie|PIE)`),
161 re(`-f(no-)?openmp(-simd)?`),
162 re(`-fsanitize=([^@\-].*)`),
163 re(`-flat_namespace`),
164 re(`-g([^@\-].*)?`),
165 re(`-headerpad_max_install_names`),
166 re(`-m(abi|arch|cpu|fpu|tune)=([^@\-].*)`),
167 re(`-mfloat-abi=([^@\-].*)`),
168 re(`-mmacosx-(.+)`),
169 re(`-mios-simulator-version-min=(.+)`),
170 re(`-miphoneos-version-min=(.+)`),
171 re(`-mthreads`),
172 re(`-mwindows`),
173 re(`-(pic|PIC|pie|PIE)`),
174 re(`-pthread`),
175 re(`-rdynamic`),
176 re(`-shared`),
177 re(`-?-static([-a-z0-9+]*)`),
178 re(`-?-stdlib=([^@\-].*)`),
179 re(`-v`),
180
181
182
183
184
185
186 re(`-Wl,--(no-)?allow-multiple-definition`),
187 re(`-Wl,--(no-)?allow-shlib-undefined`),
188 re(`-Wl,--(no-)?as-needed`),
189 re(`-Wl,-Bdynamic`),
190 re(`-Wl,-berok`),
191 re(`-Wl,-Bstatic`),
192 re(`-Wl,-Bsymbolic-functions`),
193 re(`-Wl,-O[0-9]+`),
194 re(`-Wl,-d[ny]`),
195 re(`-Wl,--disable-new-dtags`),
196 re(`-Wl,-e[=,][a-zA-Z0-9]+`),
197 re(`-Wl,--enable-new-dtags`),
198 re(`-Wl,--end-group`),
199 re(`-Wl,--(no-)?export-dynamic`),
200 re(`-Wl,-E`),
201 re(`-Wl,-framework,[^,@\-][^,]+`),
202 re(`-Wl,--hash-style=(sysv|gnu|both)`),
203 re(`-Wl,-headerpad_max_install_names`),
204 re(`-Wl,--no-undefined`),
205 re(`-Wl,-R,?([^@\-,][^,@]*$)`),
206 re(`-Wl,--just-symbols[=,]([^,@\-][^,@]+)`),
207 re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]+)`),
208 re(`-Wl,-s`),
209 re(`-Wl,-search_paths_first`),
210 re(`-Wl,-sectcreate,([^,@\-][^,]+),([^,@\-][^,]+),([^,@\-][^,]+)`),
211 re(`-Wl,--start-group`),
212 re(`-Wl,-?-static`),
213 re(`-Wl,-?-subsystem,(native|windows|console|posix|xbox)`),
214 re(`-Wl,-syslibroot[=,]([^,@\-][^,]+)`),
215 re(`-Wl,-undefined[=,]([^,@\-][^,]+)`),
216 re(`-Wl,-?-unresolved-symbols=[^,]+`),
217 re(`-Wl,--(no-)?warn-([^,]+)`),
218 re(`-Wl,-?-wrap[=,][^,@\-][^,]*`),
219 re(`-Wl,-z,(no)?execstack`),
220 re(`-Wl,-z,relro`),
221
222 re(`[a-zA-Z0-9_/].*\.(a|o|obj|dll|dylib|so|tbd)`),
223 re(`\./.*\.(a|o|obj|dll|dylib|so|tbd)`),
224 }
225
226 var validLinkerFlagsWithNextArg = []string{
227 "-arch",
228 "-F",
229 "-l",
230 "-L",
231 "-framework",
232 "-isysroot",
233 "--sysroot",
234 "-target",
235 "-Wl,-framework",
236 "-Wl,-rpath",
237 "-Wl,-R",
238 "-Wl,--just-symbols",
239 "-Wl,-undefined",
240 }
241
242 func checkCompilerFlags(name, source string, list []string) error {
243 checkOverrides := true
244 return checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides)
245 }
246
247 func checkLinkerFlags(name, source string, list []string) error {
248 checkOverrides := true
249 return checkFlags(name, source, list, invalidLinkerFlags, validLinkerFlags, validLinkerFlagsWithNextArg, checkOverrides)
250 }
251
252
253
254
255
256 func checkCompilerFlagsForInternalLink(name, source string, list []string) error {
257 checkOverrides := false
258 if err := checkFlags(name, source, list, nil, validCompilerFlags, validCompilerFlagsWithNextArg, checkOverrides); err != nil {
259 return err
260 }
261
262
263 for _, fl := range list {
264 if strings.HasPrefix(fl, "-flto") {
265 return fmt.Errorf("flag %q triggers external linking", fl)
266 }
267 }
268 return nil
269 }
270
271 func checkFlags(name, source string, list []string, invalid, valid []*lazyregexp.Regexp, validNext []string, checkOverrides bool) error {
272
273 var (
274 allow *regexp.Regexp
275 disallow *regexp.Regexp
276 )
277 if checkOverrides {
278 if env := cfg.Getenv("CGO_" + name + "_ALLOW"); env != "" {
279 r, err := regexp.Compile(env)
280 if err != nil {
281 return fmt.Errorf("parsing $CGO_%s_ALLOW: %v", name, err)
282 }
283 allow = r
284 }
285 if env := cfg.Getenv("CGO_" + name + "_DISALLOW"); env != "" {
286 r, err := regexp.Compile(env)
287 if err != nil {
288 return fmt.Errorf("parsing $CGO_%s_DISALLOW: %v", name, err)
289 }
290 disallow = r
291 }
292 }
293
294 Args:
295 for i := 0; i < len(list); i++ {
296 arg := list[i]
297 if disallow != nil && disallow.FindString(arg) == arg {
298 goto Bad
299 }
300 if allow != nil && allow.FindString(arg) == arg {
301 continue Args
302 }
303 for _, re := range invalid {
304 if re.FindString(arg) == arg {
305 goto Bad
306 }
307 }
308 for _, re := range valid {
309 if re.FindString(arg) == arg {
310 continue Args
311 }
312 }
313 for _, x := range validNext {
314 if arg == x {
315 if i+1 < len(list) && load.SafeArg(list[i+1]) {
316 i++
317 continue Args
318 }
319
320
321 if i+1 < len(list) &&
322 strings.HasPrefix(arg, "-Wl,") &&
323 strings.HasPrefix(list[i+1], "-Wl,") &&
324 load.SafeArg(list[i+1][4:]) &&
325 !strings.Contains(list[i+1][4:], ",") {
326 i++
327 continue Args
328 }
329
330
331 if i+1 < len(list) && arg == "-I" {
332 if (strings.HasPrefix(list[i+1], "=") || strings.HasPrefix(list[i+1], "$SYSROOT")) &&
333 load.SafeArg(list[i+1][1:]) {
334 i++
335 continue Args
336 }
337 }
338
339 if i+1 < len(list) {
340 return fmt.Errorf("invalid flag in %s: %s %s (see https://golang.org/s/invalidflag)", source, arg, list[i+1])
341 }
342 return fmt.Errorf("invalid flag in %s: %s without argument (see https://golang.org/s/invalidflag)", source, arg)
343 }
344 }
345 Bad:
346 return fmt.Errorf("invalid flag in %s: %s", source, arg)
347 }
348 return nil
349 }
350
View as plain text