]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/cgo/gcc.go
cmd/cgo: disable #cgo noescape/nocallback until Go 1.23
[gostls13.git] / src / cmd / cgo / gcc.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Annotate Ref in Prog with C types by parsing gcc debug output.
6 // Conversion of debug output to Go types.
7
8 package main
9
10 import (
11         "bytes"
12         "debug/dwarf"
13         "debug/elf"
14         "debug/macho"
15         "debug/pe"
16         "encoding/binary"
17         "errors"
18         "flag"
19         "fmt"
20         "go/ast"
21         "go/parser"
22         "go/token"
23         "internal/xcoff"
24         "math"
25         "os"
26         "os/exec"
27         "strconv"
28         "strings"
29         "unicode"
30         "unicode/utf8"
31
32         "cmd/internal/quoted"
33 )
34
35 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
36 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
37
38 var nameToC = map[string]string{
39         "schar":         "signed char",
40         "uchar":         "unsigned char",
41         "ushort":        "unsigned short",
42         "uint":          "unsigned int",
43         "ulong":         "unsigned long",
44         "longlong":      "long long",
45         "ulonglong":     "unsigned long long",
46         "complexfloat":  "float _Complex",
47         "complexdouble": "double _Complex",
48 }
49
50 var incomplete = "_cgopackage.Incomplete"
51
52 // cname returns the C name to use for C.s.
53 // The expansions are listed in nameToC and also
54 // struct_foo becomes "struct foo", and similarly for
55 // union and enum.
56 func cname(s string) string {
57         if t, ok := nameToC[s]; ok {
58                 return t
59         }
60
61         if strings.HasPrefix(s, "struct_") {
62                 return "struct " + s[len("struct_"):]
63         }
64         if strings.HasPrefix(s, "union_") {
65                 return "union " + s[len("union_"):]
66         }
67         if strings.HasPrefix(s, "enum_") {
68                 return "enum " + s[len("enum_"):]
69         }
70         if strings.HasPrefix(s, "sizeof_") {
71                 return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
72         }
73         return s
74 }
75
76 // ProcessCgoDirectives processes the import C preamble:
77 //  1. discards all #cgo CFLAGS, LDFLAGS, nocallback and noescape directives,
78 //     so they don't make their way into _cgo_export.h.
79 //  2. parse the nocallback and noescape directives.
80 func (f *File) ProcessCgoDirectives() {
81         linesIn := strings.Split(f.Preamble, "\n")
82         linesOut := make([]string, 0, len(linesIn))
83         f.NoCallbacks = make(map[string]bool)
84         f.NoEscapes = make(map[string]bool)
85         for _, line := range linesIn {
86                 l := strings.TrimSpace(line)
87                 if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
88                         linesOut = append(linesOut, line)
89                 } else {
90                         linesOut = append(linesOut, "")
91
92                         // #cgo (nocallback|noescape) <function name>
93                         if fields := strings.Fields(l); len(fields) == 3 {
94                                 directive := fields[1]
95                                 funcName := fields[2]
96                                 if directive == "nocallback" {
97                                         fatalf("#cgo nocallback disabled until Go 1.23")
98                                         f.NoCallbacks[funcName] = true
99                                 } else if directive == "noescape" {
100                                         fatalf("#cgo noescape disabled until Go 1.23")
101                                         f.NoEscapes[funcName] = true
102                                 }
103                         }
104                 }
105         }
106         f.Preamble = strings.Join(linesOut, "\n")
107 }
108
109 // addToFlag appends args to flag.
110 func (p *Package) addToFlag(flag string, args []string) {
111         if flag == "CFLAGS" {
112                 // We'll also need these when preprocessing for dwarf information.
113                 // However, discard any -g options: we need to be able
114                 // to parse the debug info, so stick to what we expect.
115                 for _, arg := range args {
116                         if !strings.HasPrefix(arg, "-g") {
117                                 p.GccOptions = append(p.GccOptions, arg)
118                         }
119                 }
120         }
121         if flag == "LDFLAGS" {
122                 p.LdFlags = append(p.LdFlags, args...)
123         }
124 }
125
126 // splitQuoted splits the string s around each instance of one or more consecutive
127 // white space characters while taking into account quotes and escaping, and
128 // returns an array of substrings of s or an empty list if s contains only white space.
129 // Single quotes and double quotes are recognized to prevent splitting within the
130 // quoted region, and are removed from the resulting substrings. If a quote in s
131 // isn't closed err will be set and r will have the unclosed argument as the
132 // last element. The backslash is used for escaping.
133 //
134 // For example, the following string:
135 //
136 //      `a b:"c d" 'e''f'  "g\""`
137 //
138 // Would be parsed as:
139 //
140 //      []string{"a", "b:c d", "ef", `g"`}
141 func splitQuoted(s string) (r []string, err error) {
142         var args []string
143         arg := make([]rune, len(s))
144         escaped := false
145         quoted := false
146         quote := '\x00'
147         i := 0
148         for _, r := range s {
149                 switch {
150                 case escaped:
151                         escaped = false
152                 case r == '\\':
153                         escaped = true
154                         continue
155                 case quote != 0:
156                         if r == quote {
157                                 quote = 0
158                                 continue
159                         }
160                 case r == '"' || r == '\'':
161                         quoted = true
162                         quote = r
163                         continue
164                 case unicode.IsSpace(r):
165                         if quoted || i > 0 {
166                                 quoted = false
167                                 args = append(args, string(arg[:i]))
168                                 i = 0
169                         }
170                         continue
171                 }
172                 arg[i] = r
173                 i++
174         }
175         if quoted || i > 0 {
176                 args = append(args, string(arg[:i]))
177         }
178         if quote != 0 {
179                 err = errors.New("unclosed quote")
180         } else if escaped {
181                 err = errors.New("unfinished escaping")
182         }
183         return args, err
184 }
185
186 // Translate rewrites f.AST, the original Go input, to remove
187 // references to the imported package C, replacing them with
188 // references to the equivalent Go types, functions, and variables.
189 func (p *Package) Translate(f *File) {
190         for _, cref := range f.Ref {
191                 // Convert C.ulong to C.unsigned long, etc.
192                 cref.Name.C = cname(cref.Name.Go)
193         }
194
195         var conv typeConv
196         conv.Init(p.PtrSize, p.IntSize)
197
198         p.loadDefines(f)
199         p.typedefs = map[string]bool{}
200         p.typedefList = nil
201         numTypedefs := -1
202         for len(p.typedefs) > numTypedefs {
203                 numTypedefs = len(p.typedefs)
204                 // Also ask about any typedefs we've seen so far.
205                 for _, info := range p.typedefList {
206                         if f.Name[info.typedef] != nil {
207                                 continue
208                         }
209                         n := &Name{
210                                 Go: info.typedef,
211                                 C:  info.typedef,
212                         }
213                         f.Name[info.typedef] = n
214                         f.NamePos[n] = info.pos
215                 }
216                 needType := p.guessKinds(f)
217                 if len(needType) > 0 {
218                         p.loadDWARF(f, &conv, needType)
219                 }
220
221                 // In godefs mode we're OK with the typedefs, which
222                 // will presumably also be defined in the file, we
223                 // don't want to resolve them to their base types.
224                 if *godefs {
225                         break
226                 }
227         }
228         p.prepareNames(f)
229         if p.rewriteCalls(f) {
230                 // Add `import _cgo_unsafe "unsafe"` after the package statement.
231                 f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"")
232         }
233         p.rewriteRef(f)
234 }
235
236 // loadDefines coerces gcc into spitting out the #defines in use
237 // in the file f and saves relevant renamings in f.Name[name].Define.
238 func (p *Package) loadDefines(f *File) {
239         var b bytes.Buffer
240         b.WriteString(builtinProlog)
241         b.WriteString(f.Preamble)
242         stdout := p.gccDefines(b.Bytes())
243
244         for _, line := range strings.Split(stdout, "\n") {
245                 if len(line) < 9 || line[0:7] != "#define" {
246                         continue
247                 }
248
249                 line = strings.TrimSpace(line[8:])
250
251                 var key, val string
252                 spaceIndex := strings.Index(line, " ")
253                 tabIndex := strings.Index(line, "\t")
254
255                 if spaceIndex == -1 && tabIndex == -1 {
256                         continue
257                 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
258                         key = line[0:spaceIndex]
259                         val = strings.TrimSpace(line[spaceIndex:])
260                 } else {
261                         key = line[0:tabIndex]
262                         val = strings.TrimSpace(line[tabIndex:])
263                 }
264
265                 if key == "__clang__" {
266                         p.GccIsClang = true
267                 }
268
269                 if n := f.Name[key]; n != nil {
270                         if *debugDefine {
271                                 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
272                         }
273                         n.Define = val
274                 }
275         }
276 }
277
278 // guessKinds tricks gcc into revealing the kind of each
279 // name xxx for the references C.xxx in the Go input.
280 // The kind is either a constant, type, or variable.
281 func (p *Package) guessKinds(f *File) []*Name {
282         // Determine kinds for names we already know about,
283         // like #defines or 'struct foo', before bothering with gcc.
284         var names, needType []*Name
285         optional := map[*Name]bool{}
286         for _, key := range nameKeys(f.Name) {
287                 n := f.Name[key]
288                 // If we've already found this name as a #define
289                 // and we can translate it as a constant value, do so.
290                 if n.Define != "" {
291                         if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil {
292                                 n.Kind = "iconst"
293                                 // Turn decimal into hex, just for consistency
294                                 // with enum-derived constants. Otherwise
295                                 // in the cgo -godefs output half the constants
296                                 // are in hex and half are in whatever the #define used.
297                                 n.Const = fmt.Sprintf("%#x", i)
298                         } else if n.Define[0] == '\'' {
299                                 if _, err := parser.ParseExpr(n.Define); err == nil {
300                                         n.Kind = "iconst"
301                                         n.Const = n.Define
302                                 }
303                         } else if n.Define[0] == '"' {
304                                 if _, err := parser.ParseExpr(n.Define); err == nil {
305                                         n.Kind = "sconst"
306                                         n.Const = n.Define
307                                 }
308                         }
309
310                         if n.IsConst() {
311                                 continue
312                         }
313                 }
314
315                 // If this is a struct, union, or enum type name, no need to guess the kind.
316                 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
317                         n.Kind = "type"
318                         needType = append(needType, n)
319                         continue
320                 }
321
322                 if (goos == "darwin" || goos == "ios") && strings.HasSuffix(n.C, "Ref") {
323                         // For FooRef, find out if FooGetTypeID exists.
324                         s := n.C[:len(n.C)-3] + "GetTypeID"
325                         n := &Name{Go: s, C: s}
326                         names = append(names, n)
327                         optional[n] = true
328                 }
329
330                 // Otherwise, we'll need to find out from gcc.
331                 names = append(names, n)
332         }
333
334         // Bypass gcc if there's nothing left to find out.
335         if len(names) == 0 {
336                 return needType
337         }
338
339         // Coerce gcc into telling us whether each name is a type, a value, or undeclared.
340         // For names, find out whether they are integer constants.
341         // We used to look at specific warning or error messages here, but that tied the
342         // behavior too closely to specific versions of the compilers.
343         // Instead, arrange that we can infer what we need from only the presence or absence
344         // of an error on a specific line.
345         //
346         // For each name, we generate these lines, where xxx is the index in toSniff plus one.
347         //
348         //      #line xxx "not-declared"
349         //      void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; }
350         //      #line xxx "not-type"
351         //      void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; }
352         //      #line xxx "not-int-const"
353         //      void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; }
354         //      #line xxx "not-num-const"
355         //      void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
356         //      #line xxx "not-str-lit"
357         //      void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
358         //
359         // If we see an error at not-declared:xxx, the corresponding name is not declared.
360         // If we see an error at not-type:xxx, the corresponding name is not a type.
361         // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
362         // If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
363         // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
364         //
365         // The specific input forms are chosen so that they are valid C syntax regardless of
366         // whether name denotes a type or an expression.
367
368         var b bytes.Buffer
369         b.WriteString(builtinProlog)
370         b.WriteString(f.Preamble)
371
372         for i, n := range names {
373                 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
374                         "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+
375                         "#line %d \"not-type\"\n"+
376                         "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+
377                         "#line %d \"not-int-const\"\n"+
378                         "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+
379                         "#line %d \"not-num-const\"\n"+
380                         "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
381                         "#line %d \"not-str-lit\"\n"+
382                         "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
383                         i+1, i+1, n.C,
384                         i+1, i+1, n.C,
385                         i+1, i+1, n.C,
386                         i+1, i+1, n.C,
387                         i+1, i+1, n.C,
388                 )
389         }
390         fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
391                 "int __cgo__1 = __cgo__2;\n")
392
393         // We need to parse the output from this gcc command, so ensure that it
394         // doesn't have any ANSI escape sequences in it. (TERM=dumb is
395         // insufficient; if the user specifies CGO_CFLAGS=-fdiagnostics-color,
396         // GCC will ignore TERM, and GCC can also be configured at compile-time
397         // to ignore TERM.)
398         stderr := p.gccErrors(b.Bytes(), "-fdiagnostics-color=never")
399         if strings.Contains(stderr, "unrecognized command line option") {
400                 // We're using an old version of GCC that doesn't understand
401                 // -fdiagnostics-color. Those versions can't print color anyway,
402                 // so just rerun without that option.
403                 stderr = p.gccErrors(b.Bytes())
404         }
405         if stderr == "" {
406                 fatalf("%s produced no output\non input:\n%s", gccBaseCmd[0], b.Bytes())
407         }
408
409         completed := false
410         sniff := make([]int, len(names))
411         const (
412                 notType = 1 << iota
413                 notIntConst
414                 notNumConst
415                 notStrLiteral
416                 notDeclared
417         )
418         sawUnmatchedErrors := false
419         for _, line := range strings.Split(stderr, "\n") {
420                 // Ignore warnings and random comments, with one
421                 // exception: newer GCC versions will sometimes emit
422                 // an error on a macro #define with a note referring
423                 // to where the expansion occurs. We care about where
424                 // the expansion occurs, so in that case treat the note
425                 // as an error.
426                 isError := strings.Contains(line, ": error:")
427                 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
428                 if !isError && !isErrorNote {
429                         continue
430                 }
431
432                 c1 := strings.Index(line, ":")
433                 if c1 < 0 {
434                         continue
435                 }
436                 c2 := strings.Index(line[c1+1:], ":")
437                 if c2 < 0 {
438                         continue
439                 }
440                 c2 += c1 + 1
441
442                 filename := line[:c1]
443                 i, _ := strconv.Atoi(line[c1+1 : c2])
444                 i--
445                 if i < 0 || i >= len(names) {
446                         if isError {
447                                 sawUnmatchedErrors = true
448                         }
449                         continue
450                 }
451
452                 switch filename {
453                 case "completed":
454                         // Strictly speaking, there is no guarantee that seeing the error at completed:1
455                         // (at the end of the file) means we've seen all the errors from earlier in the file,
456                         // but usually it does. Certainly if we don't see the completed:1 error, we did
457                         // not get all the errors we expected.
458                         completed = true
459
460                 case "not-declared":
461                         sniff[i] |= notDeclared
462                 case "not-type":
463                         sniff[i] |= notType
464                 case "not-int-const":
465                         sniff[i] |= notIntConst
466                 case "not-num-const":
467                         sniff[i] |= notNumConst
468                 case "not-str-lit":
469                         sniff[i] |= notStrLiteral
470                 default:
471                         if isError {
472                                 sawUnmatchedErrors = true
473                         }
474                         continue
475                 }
476
477                 sawUnmatchedErrors = false
478         }
479
480         if !completed {
481                 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", gccBaseCmd[0], b.Bytes(), stderr)
482         }
483
484         for i, n := range names {
485                 switch sniff[i] {
486                 default:
487                         if sniff[i]&notDeclared != 0 && optional[n] {
488                                 // Ignore optional undeclared identifiers.
489                                 // Don't report an error, and skip adding n to the needType array.
490                                 continue
491                         }
492                         error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
493                 case notStrLiteral | notType:
494                         n.Kind = "iconst"
495                 case notIntConst | notStrLiteral | notType:
496                         n.Kind = "fconst"
497                 case notIntConst | notNumConst | notType:
498                         n.Kind = "sconst"
499                 case notIntConst | notNumConst | notStrLiteral:
500                         n.Kind = "type"
501                 case notIntConst | notNumConst | notStrLiteral | notType:
502                         n.Kind = "not-type"
503                 }
504                 needType = append(needType, n)
505         }
506         if nerrors > 0 {
507                 // Check if compiling the preamble by itself causes any errors,
508                 // because the messages we've printed out so far aren't helpful
509                 // to users debugging preamble mistakes. See issue 8442.
510                 preambleErrors := p.gccErrors([]byte(builtinProlog + f.Preamble))
511                 if len(preambleErrors) > 0 {
512                         error_(token.NoPos, "\n%s errors for preamble:\n%s", gccBaseCmd[0], preambleErrors)
513                 }
514
515                 fatalf("unresolved names")
516         }
517
518         return needType
519 }
520
521 // loadDWARF parses the DWARF debug information generated
522 // by gcc to learn the details of the constants, variables, and types
523 // being referred to as C.xxx.
524 func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) {
525         // Extract the types from the DWARF section of an object
526         // from a well-formed C program. Gcc only generates DWARF info
527         // for symbols in the object file, so it is not enough to print the
528         // preamble and hope the symbols we care about will be there.
529         // Instead, emit
530         //      __typeof__(names[i]) *__cgo__i;
531         // for each entry in names and then dereference the type we
532         // learn for __cgo__i.
533         var b bytes.Buffer
534         b.WriteString(builtinProlog)
535         b.WriteString(f.Preamble)
536         b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
537         for i, n := range names {
538                 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
539                 if n.Kind == "iconst" {
540                         fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
541                 }
542         }
543
544         // We create a data block initialized with the values,
545         // so we can read them out of the object file.
546         fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
547         for _, n := range names {
548                 if n.Kind == "iconst" {
549                         fmt.Fprintf(&b, "\t%s,\n", n.C)
550                 } else {
551                         fmt.Fprintf(&b, "\t0,\n")
552                 }
553         }
554         // for the last entry, we cannot use 0, otherwise
555         // in case all __cgodebug_data is zero initialized,
556         // LLVM-based gcc will place the it in the __DATA.__common
557         // zero-filled section (our debug/macho doesn't support
558         // this)
559         fmt.Fprintf(&b, "\t1\n")
560         fmt.Fprintf(&b, "};\n")
561
562         // do the same work for floats.
563         fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n")
564         for _, n := range names {
565                 if n.Kind == "fconst" {
566                         fmt.Fprintf(&b, "\t%s,\n", n.C)
567                 } else {
568                         fmt.Fprintf(&b, "\t0,\n")
569                 }
570         }
571         fmt.Fprintf(&b, "\t1\n")
572         fmt.Fprintf(&b, "};\n")
573
574         // do the same work for strings.
575         for i, n := range names {
576                 if n.Kind == "sconst" {
577                         fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C)
578                         fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C)
579                 }
580         }
581
582         d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names))
583
584         // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
585         types := make([]dwarf.Type, len(names))
586         r := d.Reader()
587         for {
588                 e, err := r.Next()
589                 if err != nil {
590                         fatalf("reading DWARF entry: %s", err)
591                 }
592                 if e == nil {
593                         break
594                 }
595                 switch e.Tag {
596                 case dwarf.TagVariable:
597                         name, _ := e.Val(dwarf.AttrName).(string)
598                         // As of https://reviews.llvm.org/D123534, clang
599                         // now emits DW_TAG_variable DIEs that have
600                         // no name (so as to be able to describe the
601                         // type and source locations of constant strings)
602                         // like the second arg in the call below:
603                         //
604                         //     myfunction(42, "foo")
605                         //
606                         // If a var has no name we won't see attempts to
607                         // refer to it via "C.<name>", so skip these vars
608                         //
609                         // See issue 53000 for more context.
610                         if name == "" {
611                                 break
612                         }
613                         typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
614                         if typOff == 0 {
615                                 if e.Val(dwarf.AttrSpecification) != nil {
616                                         // Since we are reading all the DWARF,
617                                         // assume we will see the variable elsewhere.
618                                         break
619                                 }
620                                 fatalf("malformed DWARF TagVariable entry")
621                         }
622                         if !strings.HasPrefix(name, "__cgo__") {
623                                 break
624                         }
625                         typ, err := d.Type(typOff)
626                         if err != nil {
627                                 fatalf("loading DWARF type: %s", err)
628                         }
629                         t, ok := typ.(*dwarf.PtrType)
630                         if !ok || t == nil {
631                                 fatalf("internal error: %s has non-pointer type", name)
632                         }
633                         i, err := strconv.Atoi(name[7:])
634                         if err != nil {
635                                 fatalf("malformed __cgo__ name: %s", name)
636                         }
637                         types[i] = t.Type
638                         p.recordTypedefs(t.Type, f.NamePos[names[i]])
639                 }
640                 if e.Tag != dwarf.TagCompileUnit {
641                         r.SkipChildren()
642                 }
643         }
644
645         // Record types and typedef information.
646         for i, n := range names {
647                 if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
648                         conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
649                 }
650         }
651         for i, n := range names {
652                 if types[i] == nil {
653                         continue
654                 }
655                 pos := f.NamePos[n]
656                 f, fok := types[i].(*dwarf.FuncType)
657                 if n.Kind != "type" && fok {
658                         n.Kind = "func"
659                         n.FuncType = conv.FuncType(f, pos)
660                 } else {
661                         n.Type = conv.Type(types[i], pos)
662                         switch n.Kind {
663                         case "iconst":
664                                 if i < len(ints) {
665                                         if _, ok := types[i].(*dwarf.UintType); ok {
666                                                 n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
667                                         } else {
668                                                 n.Const = fmt.Sprintf("%#x", ints[i])
669                                         }
670                                 }
671                         case "fconst":
672                                 if i >= len(floats) {
673                                         break
674                                 }
675                                 switch base(types[i]).(type) {
676                                 case *dwarf.IntType, *dwarf.UintType:
677                                         // This has an integer type so it's
678                                         // not really a floating point
679                                         // constant. This can happen when the
680                                         // C compiler complains about using
681                                         // the value as an integer constant,
682                                         // but not as a general constant.
683                                         // Treat this as a variable of the
684                                         // appropriate type, not a constant,
685                                         // to get C-style type handling,
686                                         // avoiding the problem that C permits
687                                         // uint64(-1) but Go does not.
688                                         // See issue 26066.
689                                         n.Kind = "var"
690                                 default:
691                                         n.Const = fmt.Sprintf("%f", floats[i])
692                                 }
693                         case "sconst":
694                                 if i < len(strs) {
695                                         n.Const = fmt.Sprintf("%q", strs[i])
696                                 }
697                         }
698                 }
699                 conv.FinishType(pos)
700         }
701 }
702
703 // recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
704 func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
705         p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
706 }
707
708 func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
709         if dtype == nil {
710                 return
711         }
712         if visited[dtype] {
713                 return
714         }
715         visited[dtype] = true
716         switch dt := dtype.(type) {
717         case *dwarf.TypedefType:
718                 if strings.HasPrefix(dt.Name, "__builtin") {
719                         // Don't look inside builtin types. There be dragons.
720                         return
721                 }
722                 if !p.typedefs[dt.Name] {
723                         p.typedefs[dt.Name] = true
724                         p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
725                         p.recordTypedefs1(dt.Type, pos, visited)
726                 }
727         case *dwarf.PtrType:
728                 p.recordTypedefs1(dt.Type, pos, visited)
729         case *dwarf.ArrayType:
730                 p.recordTypedefs1(dt.Type, pos, visited)
731         case *dwarf.QualType:
732                 p.recordTypedefs1(dt.Type, pos, visited)
733         case *dwarf.FuncType:
734                 p.recordTypedefs1(dt.ReturnType, pos, visited)
735                 for _, a := range dt.ParamType {
736                         p.recordTypedefs1(a, pos, visited)
737                 }
738         case *dwarf.StructType:
739                 for _, f := range dt.Field {
740                         p.recordTypedefs1(f.Type, pos, visited)
741                 }
742         }
743 }
744
745 // prepareNames finalizes the Kind field of not-type names and sets
746 // the mangled name of all names.
747 func (p *Package) prepareNames(f *File) {
748         for _, n := range f.Name {
749                 if n.Kind == "not-type" {
750                         if n.Define == "" {
751                                 n.Kind = "var"
752                         } else {
753                                 n.Kind = "macro"
754                                 n.FuncType = &FuncType{
755                                         Result: n.Type,
756                                         Go: &ast.FuncType{
757                                                 Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}},
758                                         },
759                                 }
760                         }
761                 }
762                 p.mangleName(n)
763                 if n.Kind == "type" && typedef[n.Mangle] == nil {
764                         typedef[n.Mangle] = n.Type
765                 }
766         }
767 }
768
769 // mangleName does name mangling to translate names
770 // from the original Go source files to the names
771 // used in the final Go files generated by cgo.
772 func (p *Package) mangleName(n *Name) {
773         // When using gccgo variables have to be
774         // exported so that they become global symbols
775         // that the C code can refer to.
776         prefix := "_C"
777         if *gccgo && n.IsVar() {
778                 prefix = "C"
779         }
780         n.Mangle = prefix + n.Kind + "_" + n.Go
781 }
782
783 func (f *File) isMangledName(s string) bool {
784         prefix := "_C"
785         if strings.HasPrefix(s, prefix) {
786                 t := s[len(prefix):]
787                 for _, k := range nameKinds {
788                         if strings.HasPrefix(t, k+"_") {
789                                 return true
790                         }
791                 }
792         }
793         return false
794 }
795
796 // rewriteCalls rewrites all calls that pass pointers to check that
797 // they follow the rules for passing pointers between Go and C.
798 // This reports whether the package needs to import unsafe as _cgo_unsafe.
799 func (p *Package) rewriteCalls(f *File) bool {
800         needsUnsafe := false
801         // Walk backward so that in C.f1(C.f2()) we rewrite C.f2 first.
802         for _, call := range f.Calls {
803                 if call.Done {
804                         continue
805                 }
806                 start := f.offset(call.Call.Pos())
807                 end := f.offset(call.Call.End())
808                 str, nu := p.rewriteCall(f, call)
809                 if str != "" {
810                         f.Edit.Replace(start, end, str)
811                         if nu {
812                                 needsUnsafe = true
813                         }
814                 }
815         }
816         return needsUnsafe
817 }
818
819 // rewriteCall rewrites one call to add pointer checks.
820 // If any pointer checks are required, we rewrite the call into a
821 // function literal that calls _cgoCheckPointer for each pointer
822 // argument and then calls the original function.
823 // This returns the rewritten call and whether the package needs to
824 // import unsafe as _cgo_unsafe.
825 // If it returns the empty string, the call did not need to be rewritten.
826 func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
827         // This is a call to C.xxx; set goname to "xxx".
828         // It may have already been mangled by rewriteName.
829         var goname string
830         switch fun := call.Call.Fun.(type) {
831         case *ast.SelectorExpr:
832                 goname = fun.Sel.Name
833         case *ast.Ident:
834                 goname = strings.TrimPrefix(fun.Name, "_C2func_")
835                 goname = strings.TrimPrefix(goname, "_Cfunc_")
836         }
837         if goname == "" || goname == "malloc" {
838                 return "", false
839         }
840         name := f.Name[goname]
841         if name == nil || name.Kind != "func" {
842                 // Probably a type conversion.
843                 return "", false
844         }
845
846         params := name.FuncType.Params
847         args := call.Call.Args
848         end := call.Call.End()
849
850         // Avoid a crash if the number of arguments doesn't match
851         // the number of parameters.
852         // This will be caught when the generated file is compiled.
853         if len(args) != len(params) {
854                 return "", false
855         }
856
857         any := false
858         for i, param := range params {
859                 if p.needsPointerCheck(f, param.Go, args[i]) {
860                         any = true
861                         break
862                 }
863         }
864         if !any {
865                 return "", false
866         }
867
868         // We need to rewrite this call.
869         //
870         // Rewrite C.f(p) to
871         //    func() {
872         //            _cgo0 := p
873         //            _cgoCheckPointer(_cgo0, nil)
874         //            C.f(_cgo0)
875         //    }()
876         // Using a function literal like this lets us evaluate the
877         // function arguments only once while doing pointer checks.
878         // This is particularly useful when passing additional arguments
879         // to _cgoCheckPointer, as done in checkIndex and checkAddr.
880         //
881         // When the function argument is a conversion to unsafe.Pointer,
882         // we unwrap the conversion before checking the pointer,
883         // and then wrap again when calling C.f. This lets us check
884         // the real type of the pointer in some cases. See issue #25941.
885         //
886         // When the call to C.f is deferred, we use an additional function
887         // literal to evaluate the arguments at the right time.
888         //    defer func() func() {
889         //            _cgo0 := p
890         //            return func() {
891         //                    _cgoCheckPointer(_cgo0, nil)
892         //                    C.f(_cgo0)
893         //            }
894         //    }()()
895         // This works because the defer statement evaluates the first
896         // function literal in order to get the function to call.
897
898         var sb bytes.Buffer
899         sb.WriteString("func() ")
900         if call.Deferred {
901                 sb.WriteString("func() ")
902         }
903
904         needsUnsafe := false
905         result := false
906         twoResults := false
907         if !call.Deferred {
908                 // Check whether this call expects two results.
909                 for _, ref := range f.Ref {
910                         if ref.Expr != &call.Call.Fun {
911                                 continue
912                         }
913                         if ref.Context == ctxCall2 {
914                                 sb.WriteString("(")
915                                 result = true
916                                 twoResults = true
917                         }
918                         break
919                 }
920
921                 // Add the result type, if any.
922                 if name.FuncType.Result != nil {
923                         rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
924                         if rtype != name.FuncType.Result.Go {
925                                 needsUnsafe = true
926                         }
927                         sb.WriteString(gofmtLine(rtype))
928                         result = true
929                 }
930
931                 // Add the second result type, if any.
932                 if twoResults {
933                         if name.FuncType.Result == nil {
934                                 // An explicit void result looks odd but it
935                                 // seems to be how cgo has worked historically.
936                                 sb.WriteString("_Ctype_void")
937                         }
938                         sb.WriteString(", error)")
939                 }
940         }
941
942         sb.WriteString("{ ")
943
944         // Define _cgoN for each argument value.
945         // Write _cgoCheckPointer calls to sbCheck.
946         var sbCheck bytes.Buffer
947         for i, param := range params {
948                 origArg := args[i]
949                 arg, nu := p.mangle(f, &args[i], true)
950                 if nu {
951                         needsUnsafe = true
952                 }
953
954                 // Use "var x T = ..." syntax to explicitly convert untyped
955                 // constants to the parameter type, to avoid a type mismatch.
956                 ptype := p.rewriteUnsafe(param.Go)
957
958                 if !p.needsPointerCheck(f, param.Go, args[i]) || param.BadPointer || p.checkUnsafeStringData(args[i]) {
959                         if ptype != param.Go {
960                                 needsUnsafe = true
961                         }
962                         fmt.Fprintf(&sb, "var _cgo%d %s = %s; ", i,
963                                 gofmtLine(ptype), gofmtPos(arg, origArg.Pos()))
964                         continue
965                 }
966
967                 // Check for &a[i].
968                 if p.checkIndex(&sb, &sbCheck, arg, i) {
969                         continue
970                 }
971
972                 // Check for &x.
973                 if p.checkAddr(&sb, &sbCheck, arg, i) {
974                         continue
975                 }
976
977                 // Check for a[:].
978                 if p.checkSlice(&sb, &sbCheck, arg, i) {
979                         continue
980                 }
981
982                 fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
983                 fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d, nil); ", i)
984         }
985
986         if call.Deferred {
987                 sb.WriteString("return func() { ")
988         }
989
990         // Write out the calls to _cgoCheckPointer.
991         sb.WriteString(sbCheck.String())
992
993         if result {
994                 sb.WriteString("return ")
995         }
996
997         m, nu := p.mangle(f, &call.Call.Fun, false)
998         if nu {
999                 needsUnsafe = true
1000         }
1001         sb.WriteString(gofmtPos(m, end))
1002
1003         sb.WriteString("(")
1004         for i := range params {
1005                 if i > 0 {
1006                         sb.WriteString(", ")
1007                 }
1008                 fmt.Fprintf(&sb, "_cgo%d", i)
1009         }
1010         sb.WriteString("); ")
1011         if call.Deferred {
1012                 sb.WriteString("}")
1013         }
1014         sb.WriteString("}")
1015         if call.Deferred {
1016                 sb.WriteString("()")
1017         }
1018         sb.WriteString("()")
1019
1020         return sb.String(), needsUnsafe
1021 }
1022
1023 // needsPointerCheck reports whether the type t needs a pointer check.
1024 // This is true if t is a pointer and if the value to which it points
1025 // might contain a pointer.
1026 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
1027         // An untyped nil does not need a pointer check, and when
1028         // _cgoCheckPointer returns the untyped nil the type assertion we
1029         // are going to insert will fail.  Easier to just skip nil arguments.
1030         // TODO: Note that this fails if nil is shadowed.
1031         if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
1032                 return false
1033         }
1034
1035         return p.hasPointer(f, t, true)
1036 }
1037
1038 // hasPointer is used by needsPointerCheck. If top is true it returns
1039 // whether t is or contains a pointer that might point to a pointer.
1040 // If top is false it reports whether t is or contains a pointer.
1041 // f may be nil.
1042 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
1043         switch t := t.(type) {
1044         case *ast.ArrayType:
1045                 if t.Len == nil {
1046                         if !top {
1047                                 return true
1048                         }
1049                         return p.hasPointer(f, t.Elt, false)
1050                 }
1051                 return p.hasPointer(f, t.Elt, top)
1052         case *ast.StructType:
1053                 for _, field := range t.Fields.List {
1054                         if p.hasPointer(f, field.Type, top) {
1055                                 return true
1056                         }
1057                 }
1058                 return false
1059         case *ast.StarExpr: // Pointer type.
1060                 if !top {
1061                         return true
1062                 }
1063                 // Check whether this is a pointer to a C union (or class)
1064                 // type that contains a pointer.
1065                 if unionWithPointer[t.X] {
1066                         return true
1067                 }
1068                 return p.hasPointer(f, t.X, false)
1069         case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
1070                 return true
1071         case *ast.Ident:
1072                 // TODO: Handle types defined within function.
1073                 for _, d := range p.Decl {
1074                         gd, ok := d.(*ast.GenDecl)
1075                         if !ok || gd.Tok != token.TYPE {
1076                                 continue
1077                         }
1078                         for _, spec := range gd.Specs {
1079                                 ts, ok := spec.(*ast.TypeSpec)
1080                                 if !ok {
1081                                         continue
1082                                 }
1083                                 if ts.Name.Name == t.Name {
1084                                         return p.hasPointer(f, ts.Type, top)
1085                                 }
1086                         }
1087                 }
1088                 if def := typedef[t.Name]; def != nil {
1089                         return p.hasPointer(f, def.Go, top)
1090                 }
1091                 if t.Name == "string" {
1092                         return !top
1093                 }
1094                 if t.Name == "error" {
1095                         return true
1096                 }
1097                 if goTypes[t.Name] != nil {
1098                         return false
1099                 }
1100                 // We can't figure out the type. Conservative
1101                 // approach is to assume it has a pointer.
1102                 return true
1103         case *ast.SelectorExpr:
1104                 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
1105                         // Type defined in a different package.
1106                         // Conservative approach is to assume it has a
1107                         // pointer.
1108                         return true
1109                 }
1110                 if f == nil {
1111                         // Conservative approach: assume pointer.
1112                         return true
1113                 }
1114                 name := f.Name[t.Sel.Name]
1115                 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
1116                         return p.hasPointer(f, name.Type.Go, top)
1117                 }
1118                 // We can't figure out the type. Conservative
1119                 // approach is to assume it has a pointer.
1120                 return true
1121         default:
1122                 error_(t.Pos(), "could not understand type %s", gofmt(t))
1123                 return true
1124         }
1125 }
1126
1127 // mangle replaces references to C names in arg with the mangled names,
1128 // rewriting calls when it finds them.
1129 // It removes the corresponding references in f.Ref and f.Calls, so that we
1130 // don't try to do the replacement again in rewriteRef or rewriteCall.
1131 // If addPosition is true, add position info to the idents of C names in arg.
1132 func (p *Package) mangle(f *File, arg *ast.Expr, addPosition bool) (ast.Expr, bool) {
1133         needsUnsafe := false
1134         f.walk(arg, ctxExpr, func(f *File, arg interface{}, context astContext) {
1135                 px, ok := arg.(*ast.Expr)
1136                 if !ok {
1137                         return
1138                 }
1139                 sel, ok := (*px).(*ast.SelectorExpr)
1140                 if ok {
1141                         if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" {
1142                                 return
1143                         }
1144
1145                         for _, r := range f.Ref {
1146                                 if r.Expr == px {
1147                                         *px = p.rewriteName(f, r, addPosition)
1148                                         r.Done = true
1149                                         break
1150                                 }
1151                         }
1152
1153                         return
1154                 }
1155
1156                 call, ok := (*px).(*ast.CallExpr)
1157                 if !ok {
1158                         return
1159                 }
1160
1161                 for _, c := range f.Calls {
1162                         if !c.Done && c.Call.Lparen == call.Lparen {
1163                                 cstr, nu := p.rewriteCall(f, c)
1164                                 if cstr != "" {
1165                                         // Smuggle the rewritten call through an ident.
1166                                         *px = ast.NewIdent(cstr)
1167                                         if nu {
1168                                                 needsUnsafe = true
1169                                         }
1170                                         c.Done = true
1171                                 }
1172                         }
1173                 }
1174         })
1175         return *arg, needsUnsafe
1176 }
1177
1178 // checkIndex checks whether arg has the form &a[i], possibly inside
1179 // type conversions. If so, then in the general case it writes
1180 //
1181 //      _cgoIndexNN := a
1182 //      _cgoNN := &cgoIndexNN[i] // with type conversions, if any
1183 //
1184 // to sb, and writes
1185 //
1186 //      _cgoCheckPointer(_cgoNN, _cgoIndexNN)
1187 //
1188 // to sbCheck, and returns true. If a is a simple variable or field reference,
1189 // it writes
1190 //
1191 //      _cgoIndexNN := &a
1192 //
1193 // and dereferences the uses of _cgoIndexNN. Taking the address avoids
1194 // making a copy of an array.
1195 //
1196 // This tells _cgoCheckPointer to check the complete contents of the
1197 // slice or array being indexed, but no other part of the memory allocation.
1198 func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1199         // Strip type conversions.
1200         x := arg
1201         for {
1202                 c, ok := x.(*ast.CallExpr)
1203                 if !ok || len(c.Args) != 1 {
1204                         break
1205                 }
1206                 if !p.isType(c.Fun) && !p.isUnsafeData(c.Fun, false) {
1207                         break
1208                 }
1209                 x = c.Args[0]
1210         }
1211         u, ok := x.(*ast.UnaryExpr)
1212         if !ok || u.Op != token.AND {
1213                 return false
1214         }
1215         index, ok := u.X.(*ast.IndexExpr)
1216         if !ok {
1217                 return false
1218         }
1219
1220         addr := ""
1221         deref := ""
1222         if p.isVariable(index.X) {
1223                 addr = "&"
1224                 deref = "*"
1225         }
1226
1227         fmt.Fprintf(sb, "_cgoIndex%d := %s%s; ", i, addr, gofmtPos(index.X, index.X.Pos()))
1228         origX := index.X
1229         index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i))
1230         if deref == "*" {
1231                 index.X = &ast.StarExpr{X: index.X}
1232         }
1233         fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1234         index.X = origX
1235
1236         fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i)
1237
1238         return true
1239 }
1240
1241 // checkAddr checks whether arg has the form &x, possibly inside type
1242 // conversions. If so, it writes
1243 //
1244 //      _cgoBaseNN := &x
1245 //      _cgoNN := _cgoBaseNN // with type conversions, if any
1246 //
1247 // to sb, and writes
1248 //
1249 //      _cgoCheckPointer(_cgoBaseNN, true)
1250 //
1251 // to sbCheck, and returns true. This tells _cgoCheckPointer to check
1252 // just the contents of the pointer being passed, not any other part
1253 // of the memory allocation. This is run after checkIndex, which looks
1254 // for the special case of &a[i], which requires different checks.
1255 func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1256         // Strip type conversions.
1257         px := &arg
1258         for {
1259                 c, ok := (*px).(*ast.CallExpr)
1260                 if !ok || len(c.Args) != 1 {
1261                         break
1262                 }
1263                 if !p.isType(c.Fun) && !p.isUnsafeData(c.Fun, false) {
1264                         break
1265                 }
1266                 px = &c.Args[0]
1267         }
1268         if u, ok := (*px).(*ast.UnaryExpr); !ok || u.Op != token.AND {
1269                 return false
1270         }
1271
1272         fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
1273
1274         origX := *px
1275         *px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i))
1276         fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1277         *px = origX
1278
1279         // Use "0 == 0" to do the right thing in the unlikely event
1280         // that "true" is shadowed.
1281         fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgoBase%d, 0 == 0); ", i)
1282
1283         return true
1284 }
1285
1286 // checkSlice checks whether arg has the form x[i:j], possibly inside
1287 // type conversions. If so, it writes
1288 //
1289 //      _cgoSliceNN := x[i:j]
1290 //      _cgoNN := _cgoSliceNN // with type conversions, if any
1291 //
1292 // to sb, and writes
1293 //
1294 //      _cgoCheckPointer(_cgoSliceNN, true)
1295 //
1296 // to sbCheck, and returns true. This tells _cgoCheckPointer to check
1297 // just the contents of the slice being passed, not any other part
1298 // of the memory allocation.
1299 func (p *Package) checkSlice(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1300         // Strip type conversions.
1301         px := &arg
1302         for {
1303                 c, ok := (*px).(*ast.CallExpr)
1304                 if !ok || len(c.Args) != 1 {
1305                         break
1306                 }
1307                 if !p.isType(c.Fun) && !p.isUnsafeData(c.Fun, false) {
1308                         break
1309                 }
1310                 px = &c.Args[0]
1311         }
1312         if _, ok := (*px).(*ast.SliceExpr); !ok {
1313                 return false
1314         }
1315
1316         fmt.Fprintf(sb, "_cgoSlice%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
1317
1318         origX := *px
1319         *px = ast.NewIdent(fmt.Sprintf("_cgoSlice%d", i))
1320         fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1321         *px = origX
1322
1323         // Use 0 == 0 to do the right thing in the unlikely event
1324         // that "true" is shadowed.
1325         fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgoSlice%d, 0 == 0); ", i)
1326
1327         return true
1328 }
1329
1330 // checkUnsafeStringData checks for a call to unsafe.StringData.
1331 // The result of that call can't contain a pointer so there is
1332 // no need to call _cgoCheckPointer.
1333 func (p *Package) checkUnsafeStringData(arg ast.Expr) bool {
1334         x := arg
1335         for {
1336                 c, ok := x.(*ast.CallExpr)
1337                 if !ok || len(c.Args) != 1 {
1338                         break
1339                 }
1340                 if p.isUnsafeData(c.Fun, true) {
1341                         return true
1342                 }
1343                 if !p.isType(c.Fun) {
1344                         break
1345                 }
1346                 x = c.Args[0]
1347         }
1348         return false
1349 }
1350
1351 // isType reports whether the expression is definitely a type.
1352 // This is conservative--it returns false for an unknown identifier.
1353 func (p *Package) isType(t ast.Expr) bool {
1354         switch t := t.(type) {
1355         case *ast.SelectorExpr:
1356                 id, ok := t.X.(*ast.Ident)
1357                 if !ok {
1358                         return false
1359                 }
1360                 if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
1361                         return true
1362                 }
1363                 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
1364                         return true
1365                 }
1366                 return false
1367         case *ast.Ident:
1368                 // TODO: This ignores shadowing.
1369                 switch t.Name {
1370                 case "unsafe.Pointer", "bool", "byte",
1371                         "complex64", "complex128",
1372                         "error",
1373                         "float32", "float64",
1374                         "int", "int8", "int16", "int32", "int64",
1375                         "rune", "string",
1376                         "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
1377
1378                         return true
1379                 }
1380                 if strings.HasPrefix(t.Name, "_Ctype_") {
1381                         return true
1382                 }
1383         case *ast.ParenExpr:
1384                 return p.isType(t.X)
1385         case *ast.StarExpr:
1386                 return p.isType(t.X)
1387         case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
1388                 *ast.MapType, *ast.ChanType:
1389
1390                 return true
1391         }
1392         return false
1393 }
1394
1395 // isUnsafeData reports whether the expression is unsafe.StringData
1396 // or unsafe.SliceData. We can ignore these when checking for pointers
1397 // because they don't change whether or not their argument contains
1398 // any Go pointers. If onlyStringData is true we only check for StringData.
1399 func (p *Package) isUnsafeData(x ast.Expr, onlyStringData bool) bool {
1400         st, ok := x.(*ast.SelectorExpr)
1401         if !ok {
1402                 return false
1403         }
1404         id, ok := st.X.(*ast.Ident)
1405         if !ok {
1406                 return false
1407         }
1408         if id.Name != "unsafe" {
1409                 return false
1410         }
1411         if !onlyStringData && st.Sel.Name == "SliceData" {
1412                 return true
1413         }
1414         return st.Sel.Name == "StringData"
1415 }
1416
1417 // isVariable reports whether x is a variable, possibly with field references.
1418 func (p *Package) isVariable(x ast.Expr) bool {
1419         switch x := x.(type) {
1420         case *ast.Ident:
1421                 return true
1422         case *ast.SelectorExpr:
1423                 return p.isVariable(x.X)
1424         case *ast.IndexExpr:
1425                 return true
1426         }
1427         return false
1428 }
1429
1430 // rewriteUnsafe returns a version of t with references to unsafe.Pointer
1431 // rewritten to use _cgo_unsafe.Pointer instead.
1432 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
1433         switch t := t.(type) {
1434         case *ast.Ident:
1435                 // We don't see a SelectorExpr for unsafe.Pointer;
1436                 // this is created by code in this file.
1437                 if t.Name == "unsafe.Pointer" {
1438                         return ast.NewIdent("_cgo_unsafe.Pointer")
1439                 }
1440         case *ast.ArrayType:
1441                 t1 := p.rewriteUnsafe(t.Elt)
1442                 if t1 != t.Elt {
1443                         r := *t
1444                         r.Elt = t1
1445                         return &r
1446                 }
1447         case *ast.StructType:
1448                 changed := false
1449                 fields := *t.Fields
1450                 fields.List = nil
1451                 for _, f := range t.Fields.List {
1452                         ft := p.rewriteUnsafe(f.Type)
1453                         if ft == f.Type {
1454                                 fields.List = append(fields.List, f)
1455                         } else {
1456                                 fn := *f
1457                                 fn.Type = ft
1458                                 fields.List = append(fields.List, &fn)
1459                                 changed = true
1460                         }
1461                 }
1462                 if changed {
1463                         r := *t
1464                         r.Fields = &fields
1465                         return &r
1466                 }
1467         case *ast.StarExpr: // Pointer type.
1468                 x1 := p.rewriteUnsafe(t.X)
1469                 if x1 != t.X {
1470                         r := *t
1471                         r.X = x1
1472                         return &r
1473                 }
1474         }
1475         return t
1476 }
1477
1478 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1479 // Go equivalents, now that we have figured out the meaning of all
1480 // the xxx. In *godefs mode, rewriteRef replaces the names
1481 // with full definitions instead of mangled names.
1482 func (p *Package) rewriteRef(f *File) {
1483         // Keep a list of all the functions, to remove the ones
1484         // only used as expressions and avoid generating bridge
1485         // code for them.
1486         functions := make(map[string]bool)
1487
1488         for _, n := range f.Name {
1489                 if n.Kind == "func" {
1490                         functions[n.Go] = false
1491                 }
1492         }
1493
1494         // Now that we have all the name types filled in,
1495         // scan through the Refs to identify the ones that
1496         // are trying to do a ,err call. Also check that
1497         // functions are only used in calls.
1498         for _, r := range f.Ref {
1499                 if r.Name.IsConst() && r.Name.Const == "" {
1500                         error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
1501                 }
1502
1503                 if r.Name.Kind == "func" {
1504                         switch r.Context {
1505                         case ctxCall, ctxCall2:
1506                                 functions[r.Name.Go] = true
1507                         }
1508                 }
1509
1510                 expr := p.rewriteName(f, r, false)
1511
1512                 if *godefs {
1513                         // Substitute definition for mangled type name.
1514                         if r.Name.Type != nil && r.Name.Kind == "type" {
1515                                 expr = r.Name.Type.Go
1516                         }
1517                         if id, ok := expr.(*ast.Ident); ok {
1518                                 if t := typedef[id.Name]; t != nil {
1519                                         expr = t.Go
1520                                 }
1521                                 if id.Name == r.Name.Mangle && r.Name.Const != "" {
1522                                         expr = ast.NewIdent(r.Name.Const)
1523                                 }
1524                         }
1525                 }
1526
1527                 // Copy position information from old expr into new expr,
1528                 // in case expression being replaced is first on line.
1529                 // See golang.org/issue/6563.
1530                 pos := (*r.Expr).Pos()
1531                 if x, ok := expr.(*ast.Ident); ok {
1532                         expr = &ast.Ident{NamePos: pos, Name: x.Name}
1533                 }
1534
1535                 // Change AST, because some later processing depends on it,
1536                 // and also because -godefs mode still prints the AST.
1537                 old := *r.Expr
1538                 *r.Expr = expr
1539
1540                 // Record source-level edit for cgo output.
1541                 if !r.Done {
1542                         // Prepend a space in case the earlier code ends
1543                         // with '/', which would give us a "//" comment.
1544                         repl := " " + gofmtPos(expr, old.Pos())
1545                         end := fset.Position(old.End())
1546                         // Subtract 1 from the column if we are going to
1547                         // append a close parenthesis. That will set the
1548                         // correct column for the following characters.
1549                         sub := 0
1550                         if r.Name.Kind != "type" {
1551                                 sub = 1
1552                         }
1553                         if end.Column > sub {
1554                                 repl = fmt.Sprintf("%s /*line :%d:%d*/", repl, end.Line, end.Column-sub)
1555                         }
1556                         if r.Name.Kind != "type" {
1557                                 repl = "(" + repl + ")"
1558                         }
1559                         f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
1560                 }
1561         }
1562
1563         // Remove functions only used as expressions, so their respective
1564         // bridge functions are not generated.
1565         for name, used := range functions {
1566                 if !used {
1567                         delete(f.Name, name)
1568                 }
1569         }
1570 }
1571
1572 // rewriteName returns the expression used to rewrite a reference.
1573 // If addPosition is true, add position info in the ident name.
1574 func (p *Package) rewriteName(f *File, r *Ref, addPosition bool) ast.Expr {
1575         getNewIdent := ast.NewIdent
1576         if addPosition {
1577                 getNewIdent = func(newName string) *ast.Ident {
1578                         mangledIdent := ast.NewIdent(newName)
1579                         if len(newName) == len(r.Name.Go) {
1580                                 return mangledIdent
1581                         }
1582                         p := fset.Position((*r.Expr).End())
1583                         if p.Column == 0 {
1584                                 return mangledIdent
1585                         }
1586                         return ast.NewIdent(fmt.Sprintf("%s /*line :%d:%d*/", newName, p.Line, p.Column))
1587                 }
1588         }
1589         var expr ast.Expr = getNewIdent(r.Name.Mangle) // default
1590         switch r.Context {
1591         case ctxCall, ctxCall2:
1592                 if r.Name.Kind != "func" {
1593                         if r.Name.Kind == "type" {
1594                                 r.Context = ctxType
1595                                 if r.Name.Type == nil {
1596                                         error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1597                                 }
1598                                 break
1599                         }
1600                         error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
1601                         break
1602                 }
1603                 if r.Context == ctxCall2 {
1604                         if r.Name.Go == "_CMalloc" {
1605                                 error_(r.Pos(), "no two-result form for C.malloc")
1606                                 break
1607                         }
1608                         // Invent new Name for the two-result function.
1609                         n := f.Name["2"+r.Name.Go]
1610                         if n == nil {
1611                                 n = new(Name)
1612                                 *n = *r.Name
1613                                 n.AddError = true
1614                                 n.Mangle = "_C2func_" + n.Go
1615                                 f.Name["2"+r.Name.Go] = n
1616                         }
1617                         expr = getNewIdent(n.Mangle)
1618                         r.Name = n
1619                         break
1620                 }
1621         case ctxExpr:
1622                 switch r.Name.Kind {
1623                 case "func":
1624                         if builtinDefs[r.Name.C] != "" {
1625                                 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
1626                         }
1627
1628                         // Function is being used in an expression, to e.g. pass around a C function pointer.
1629                         // Create a new Name for this Ref which causes the variable to be declared in Go land.
1630                         fpName := "fp_" + r.Name.Go
1631                         name := f.Name[fpName]
1632                         if name == nil {
1633                                 name = &Name{
1634                                         Go:   fpName,
1635                                         C:    r.Name.C,
1636                                         Kind: "fpvar",
1637                                         Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
1638                                 }
1639                                 p.mangleName(name)
1640                                 f.Name[fpName] = name
1641                         }
1642                         r.Name = name
1643                         // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
1644                         // function is defined in out.go and simply returns its argument. See
1645                         // issue 7757.
1646                         expr = &ast.CallExpr{
1647                                 Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
1648                                 Args: []ast.Expr{getNewIdent(name.Mangle)},
1649                         }
1650                 case "type":
1651                         // Okay - might be new(T), T(x), Generic[T], etc.
1652                         if r.Name.Type == nil {
1653                                 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1654                         }
1655                 case "var":
1656                         expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1657                 case "macro":
1658                         expr = &ast.CallExpr{Fun: expr}
1659                 }
1660         case ctxSelector:
1661                 if r.Name.Kind == "var" {
1662                         expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1663                 } else {
1664                         error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
1665                 }
1666         case ctxType:
1667                 if r.Name.Kind != "type" {
1668                         error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
1669                 } else if r.Name.Type == nil {
1670                         // Use of C.enum_x, C.struct_x or C.union_x without C definition.
1671                         // GCC won't raise an error when using pointers to such unknown types.
1672                         error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1673                 }
1674         default:
1675                 if r.Name.Kind == "func" {
1676                         error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
1677                 }
1678         }
1679         return expr
1680 }
1681
1682 // gofmtPos returns the gofmt-formatted string for an AST node,
1683 // with a comment setting the position before the node.
1684 func gofmtPos(n ast.Expr, pos token.Pos) string {
1685         s := gofmtLine(n)
1686         p := fset.Position(pos)
1687         if p.Column == 0 {
1688                 return s
1689         }
1690         return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s)
1691 }
1692
1693 // checkGCCBaseCmd returns the start of the compiler command line.
1694 // It uses $CC if set, or else $GCC, or else the compiler recorded
1695 // during the initial build as defaultCC.
1696 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1697 //
1698 // The compiler command line is split into arguments on whitespace. Quotes
1699 // are understood, so arguments may contain whitespace.
1700 //
1701 // checkGCCBaseCmd confirms that the compiler exists in PATH, returning
1702 // an error if it does not.
1703 func checkGCCBaseCmd() ([]string, error) {
1704         // Use $CC if set, since that's what the build uses.
1705         value := os.Getenv("CC")
1706         if value == "" {
1707                 // Try $GCC if set, since that's what we used to use.
1708                 value = os.Getenv("GCC")
1709         }
1710         if value == "" {
1711                 value = defaultCC(goos, goarch)
1712         }
1713         args, err := quoted.Split(value)
1714         if err != nil {
1715                 return nil, err
1716         }
1717         if len(args) == 0 {
1718                 return nil, errors.New("CC not set and no default found")
1719         }
1720         if _, err := exec.LookPath(args[0]); err != nil {
1721                 return nil, fmt.Errorf("C compiler %q not found: %v", args[0], err)
1722         }
1723         return args[:len(args):len(args)], nil
1724 }
1725
1726 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1727 func (p *Package) gccMachine() []string {
1728         switch goarch {
1729         case "amd64":
1730                 if goos == "darwin" {
1731                         return []string{"-arch", "x86_64", "-m64"}
1732                 }
1733                 return []string{"-m64"}
1734         case "arm64":
1735                 if goos == "darwin" {
1736                         return []string{"-arch", "arm64"}
1737                 }
1738         case "386":
1739                 return []string{"-m32"}
1740         case "arm":
1741                 return []string{"-marm"} // not thumb
1742         case "s390":
1743                 return []string{"-m31"}
1744         case "s390x":
1745                 return []string{"-m64"}
1746         case "mips64", "mips64le":
1747                 if gomips64 == "hardfloat" {
1748                         return []string{"-mabi=64", "-mhard-float"}
1749                 } else if gomips64 == "softfloat" {
1750                         return []string{"-mabi=64", "-msoft-float"}
1751                 }
1752         case "mips", "mipsle":
1753                 if gomips == "hardfloat" {
1754                         return []string{"-mabi=32", "-mfp32", "-mhard-float", "-mno-odd-spreg"}
1755                 } else if gomips == "softfloat" {
1756                         return []string{"-mabi=32", "-msoft-float"}
1757                 }
1758         case "loong64":
1759                 return []string{"-mabi=lp64d"}
1760         }
1761         return nil
1762 }
1763
1764 func gccTmp() string {
1765         return *objDir + "_cgo_.o"
1766 }
1767
1768 // gccCmd returns the gcc command line to use for compiling
1769 // the input.
1770 func (p *Package) gccCmd() []string {
1771         c := append(gccBaseCmd,
1772                 "-w",          // no warnings
1773                 "-Wno-error",  // warnings are not errors
1774                 "-o"+gccTmp(), // write object to tmp
1775                 "-gdwarf-2",   // generate DWARF v2 debugging symbols
1776                 "-c",          // do not link
1777                 "-xc",         // input language is C
1778         )
1779         if p.GccIsClang {
1780                 c = append(c,
1781                         "-ferror-limit=0",
1782                         // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1783                         // doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1784                         // flag to disable the warning. Yes, really good diagnostics, clang.
1785                         "-Wno-unknown-warning-option",
1786                         "-Wno-unneeded-internal-declaration",
1787                         "-Wno-unused-function",
1788                         "-Qunused-arguments",
1789                         // Clang embeds prototypes for some builtin functions,
1790                         // like malloc and calloc, but all size_t parameters are
1791                         // incorrectly typed unsigned long. We work around that
1792                         // by disabling the builtin functions (this is safe as
1793                         // it won't affect the actual compilation of the C code).
1794                         // See: https://golang.org/issue/6506.
1795                         "-fno-builtin",
1796                 )
1797         }
1798
1799         c = append(c, p.GccOptions...)
1800         c = append(c, p.gccMachine()...)
1801         if goos == "aix" {
1802                 c = append(c, "-maix64")
1803                 c = append(c, "-mcmodel=large")
1804         }
1805         // disable LTO so we get an object whose symbols we can read
1806         c = append(c, "-fno-lto")
1807         c = append(c, "-") //read input from standard input
1808         return c
1809 }
1810
1811 // gccDebug runs gcc -gdwarf-2 over the C program stdin and
1812 // returns the corresponding DWARF data and, if present, debug data block.
1813 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
1814         runGcc(stdin, p.gccCmd())
1815
1816         isDebugInts := func(s string) bool {
1817                 // Some systems use leading _ to denote non-assembly symbols.
1818                 return s == "__cgodebug_ints" || s == "___cgodebug_ints"
1819         }
1820         isDebugFloats := func(s string) bool {
1821                 // Some systems use leading _ to denote non-assembly symbols.
1822                 return s == "__cgodebug_floats" || s == "___cgodebug_floats"
1823         }
1824         indexOfDebugStr := func(s string) int {
1825                 // Some systems use leading _ to denote non-assembly symbols.
1826                 if strings.HasPrefix(s, "___") {
1827                         s = s[1:]
1828                 }
1829                 if strings.HasPrefix(s, "__cgodebug_str__") {
1830                         if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
1831                                 return n
1832                         }
1833                 }
1834                 return -1
1835         }
1836         indexOfDebugStrlen := func(s string) int {
1837                 // Some systems use leading _ to denote non-assembly symbols.
1838                 if strings.HasPrefix(s, "___") {
1839                         s = s[1:]
1840                 }
1841                 if strings.HasPrefix(s, "__cgodebug_strlen__") {
1842                         if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
1843                                 return n
1844                         }
1845                 }
1846                 return -1
1847         }
1848
1849         strs = make([]string, nnames)
1850
1851         strdata := make(map[int]string, nnames)
1852         strlens := make(map[int]int, nnames)
1853
1854         buildStrings := func() {
1855                 for n, strlen := range strlens {
1856                         data := strdata[n]
1857                         if len(data) <= strlen {
1858                                 fatalf("invalid string literal")
1859                         }
1860                         strs[n] = data[:strlen]
1861                 }
1862         }
1863
1864         if f, err := macho.Open(gccTmp()); err == nil {
1865                 defer f.Close()
1866                 d, err := f.DWARF()
1867                 if err != nil {
1868                         fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1869                 }
1870                 bo := f.ByteOrder
1871                 if f.Symtab != nil {
1872                         for i := range f.Symtab.Syms {
1873                                 s := &f.Symtab.Syms[i]
1874                                 switch {
1875                                 case isDebugInts(s.Name):
1876                                         // Found it. Now find data section.
1877                                         if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1878                                                 sect := f.Sections[i]
1879                                                 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1880                                                         if sdat, err := sect.Data(); err == nil {
1881                                                                 data := sdat[s.Value-sect.Addr:]
1882                                                                 ints = make([]int64, len(data)/8)
1883                                                                 for i := range ints {
1884                                                                         ints[i] = int64(bo.Uint64(data[i*8:]))
1885                                                                 }
1886                                                         }
1887                                                 }
1888                                         }
1889                                 case isDebugFloats(s.Name):
1890                                         // Found it. Now find data section.
1891                                         if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1892                                                 sect := f.Sections[i]
1893                                                 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1894                                                         if sdat, err := sect.Data(); err == nil {
1895                                                                 data := sdat[s.Value-sect.Addr:]
1896                                                                 floats = make([]float64, len(data)/8)
1897                                                                 for i := range floats {
1898                                                                         floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1899                                                                 }
1900                                                         }
1901                                                 }
1902                                         }
1903                                 default:
1904                                         if n := indexOfDebugStr(s.Name); n != -1 {
1905                                                 // Found it. Now find data section.
1906                                                 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1907                                                         sect := f.Sections[i]
1908                                                         if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1909                                                                 if sdat, err := sect.Data(); err == nil {
1910                                                                         data := sdat[s.Value-sect.Addr:]
1911                                                                         strdata[n] = string(data)
1912                                                                 }
1913                                                         }
1914                                                 }
1915                                                 break
1916                                         }
1917                                         if n := indexOfDebugStrlen(s.Name); n != -1 {
1918                                                 // Found it. Now find data section.
1919                                                 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1920                                                         sect := f.Sections[i]
1921                                                         if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1922                                                                 if sdat, err := sect.Data(); err == nil {
1923                                                                         data := sdat[s.Value-sect.Addr:]
1924                                                                         strlen := bo.Uint64(data[:8])
1925                                                                         if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1926                                                                                 fatalf("string literal too big")
1927                                                                         }
1928                                                                         strlens[n] = int(strlen)
1929                                                                 }
1930                                                         }
1931                                                 }
1932                                                 break
1933                                         }
1934                                 }
1935                         }
1936
1937                         buildStrings()
1938                 }
1939                 return d, ints, floats, strs
1940         }
1941
1942         if f, err := elf.Open(gccTmp()); err == nil {
1943                 defer f.Close()
1944                 d, err := f.DWARF()
1945                 if err != nil {
1946                         fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1947                 }
1948                 bo := f.ByteOrder
1949                 symtab, err := f.Symbols()
1950                 if err == nil {
1951                         // Check for use of -fsanitize=hwaddress (issue 53285).
1952                         removeTag := func(v uint64) uint64 { return v }
1953                         if goarch == "arm64" {
1954                                 for i := range symtab {
1955                                         if symtab[i].Name == "__hwasan_init" {
1956                                                 // -fsanitize=hwaddress on ARM
1957                                                 // uses the upper byte of a
1958                                                 // memory address as a hardware
1959                                                 // tag. Remove it so that
1960                                                 // we can find the associated
1961                                                 // data.
1962                                                 removeTag = func(v uint64) uint64 { return v &^ (0xff << (64 - 8)) }
1963                                                 break
1964                                         }
1965                                 }
1966                         }
1967
1968                         for i := range symtab {
1969                                 s := &symtab[i]
1970                                 switch {
1971                                 case isDebugInts(s.Name):
1972                                         // Found it. Now find data section.
1973                                         if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1974                                                 sect := f.Sections[i]
1975                                                 val := removeTag(s.Value)
1976                                                 if sect.Addr <= val && val < sect.Addr+sect.Size {
1977                                                         if sdat, err := sect.Data(); err == nil {
1978                                                                 data := sdat[val-sect.Addr:]
1979                                                                 ints = make([]int64, len(data)/8)
1980                                                                 for i := range ints {
1981                                                                         ints[i] = int64(bo.Uint64(data[i*8:]))
1982                                                                 }
1983                                                         }
1984                                                 }
1985                                         }
1986                                 case isDebugFloats(s.Name):
1987                                         // Found it. Now find data section.
1988                                         if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1989                                                 sect := f.Sections[i]
1990                                                 val := removeTag(s.Value)
1991                                                 if sect.Addr <= val && val < sect.Addr+sect.Size {
1992                                                         if sdat, err := sect.Data(); err == nil {
1993                                                                 data := sdat[val-sect.Addr:]
1994                                                                 floats = make([]float64, len(data)/8)
1995                                                                 for i := range floats {
1996                                                                         floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1997                                                                 }
1998                                                         }
1999                                                 }
2000                                         }
2001                                 default:
2002                                         if n := indexOfDebugStr(s.Name); n != -1 {
2003                                                 // Found it. Now find data section.
2004                                                 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
2005                                                         sect := f.Sections[i]
2006                                                         val := removeTag(s.Value)
2007                                                         if sect.Addr <= val && val < sect.Addr+sect.Size {
2008                                                                 if sdat, err := sect.Data(); err == nil {
2009                                                                         data := sdat[val-sect.Addr:]
2010                                                                         strdata[n] = string(data)
2011                                                                 }
2012                                                         }
2013                                                 }
2014                                                 break
2015                                         }
2016                                         if n := indexOfDebugStrlen(s.Name); n != -1 {
2017                                                 // Found it. Now find data section.
2018                                                 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
2019                                                         sect := f.Sections[i]
2020                                                         val := removeTag(s.Value)
2021                                                         if sect.Addr <= val && val < sect.Addr+sect.Size {
2022                                                                 if sdat, err := sect.Data(); err == nil {
2023                                                                         data := sdat[val-sect.Addr:]
2024                                                                         strlen := bo.Uint64(data[:8])
2025                                                                         if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
2026                                                                                 fatalf("string literal too big")
2027                                                                         }
2028                                                                         strlens[n] = int(strlen)
2029                                                                 }
2030                                                         }
2031                                                 }
2032                                                 break
2033                                         }
2034                                 }
2035                         }
2036
2037                         buildStrings()
2038                 }
2039                 return d, ints, floats, strs
2040         }
2041
2042         if f, err := pe.Open(gccTmp()); err == nil {
2043                 defer f.Close()
2044                 d, err := f.DWARF()
2045                 if err != nil {
2046                         fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
2047                 }
2048                 bo := binary.LittleEndian
2049                 for _, s := range f.Symbols {
2050                         switch {
2051                         case isDebugInts(s.Name):
2052                                 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2053                                         sect := f.Sections[i]
2054                                         if s.Value < sect.Size {
2055                                                 if sdat, err := sect.Data(); err == nil {
2056                                                         data := sdat[s.Value:]
2057                                                         ints = make([]int64, len(data)/8)
2058                                                         for i := range ints {
2059                                                                 ints[i] = int64(bo.Uint64(data[i*8:]))
2060                                                         }
2061                                                 }
2062                                         }
2063                                 }
2064                         case isDebugFloats(s.Name):
2065                                 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2066                                         sect := f.Sections[i]
2067                                         if s.Value < sect.Size {
2068                                                 if sdat, err := sect.Data(); err == nil {
2069                                                         data := sdat[s.Value:]
2070                                                         floats = make([]float64, len(data)/8)
2071                                                         for i := range floats {
2072                                                                 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
2073                                                         }
2074                                                 }
2075                                         }
2076                                 }
2077                         default:
2078                                 if n := indexOfDebugStr(s.Name); n != -1 {
2079                                         if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2080                                                 sect := f.Sections[i]
2081                                                 if s.Value < sect.Size {
2082                                                         if sdat, err := sect.Data(); err == nil {
2083                                                                 data := sdat[s.Value:]
2084                                                                 strdata[n] = string(data)
2085                                                         }
2086                                                 }
2087                                         }
2088                                         break
2089                                 }
2090                                 if n := indexOfDebugStrlen(s.Name); n != -1 {
2091                                         if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2092                                                 sect := f.Sections[i]
2093                                                 if s.Value < sect.Size {
2094                                                         if sdat, err := sect.Data(); err == nil {
2095                                                                 data := sdat[s.Value:]
2096                                                                 strlen := bo.Uint64(data[:8])
2097                                                                 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
2098                                                                         fatalf("string literal too big")
2099                                                                 }
2100                                                                 strlens[n] = int(strlen)
2101                                                         }
2102                                                 }
2103                                         }
2104                                         break
2105                                 }
2106                         }
2107                 }
2108
2109                 buildStrings()
2110
2111                 return d, ints, floats, strs
2112         }
2113
2114         if f, err := xcoff.Open(gccTmp()); err == nil {
2115                 defer f.Close()
2116                 d, err := f.DWARF()
2117                 if err != nil {
2118                         fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
2119                 }
2120                 bo := binary.BigEndian
2121                 for _, s := range f.Symbols {
2122                         switch {
2123                         case isDebugInts(s.Name):
2124                                 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2125                                         sect := f.Sections[i]
2126                                         if s.Value < sect.Size {
2127                                                 if sdat, err := sect.Data(); err == nil {
2128                                                         data := sdat[s.Value:]
2129                                                         ints = make([]int64, len(data)/8)
2130                                                         for i := range ints {
2131                                                                 ints[i] = int64(bo.Uint64(data[i*8:]))
2132                                                         }
2133                                                 }
2134                                         }
2135                                 }
2136                         case isDebugFloats(s.Name):
2137                                 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2138                                         sect := f.Sections[i]
2139                                         if s.Value < sect.Size {
2140                                                 if sdat, err := sect.Data(); err == nil {
2141                                                         data := sdat[s.Value:]
2142                                                         floats = make([]float64, len(data)/8)
2143                                                         for i := range floats {
2144                                                                 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
2145                                                         }
2146                                                 }
2147                                         }
2148                                 }
2149                         default:
2150                                 if n := indexOfDebugStr(s.Name); n != -1 {
2151                                         if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2152                                                 sect := f.Sections[i]
2153                                                 if s.Value < sect.Size {
2154                                                         if sdat, err := sect.Data(); err == nil {
2155                                                                 data := sdat[s.Value:]
2156                                                                 strdata[n] = string(data)
2157                                                         }
2158                                                 }
2159                                         }
2160                                         break
2161                                 }
2162                                 if n := indexOfDebugStrlen(s.Name); n != -1 {
2163                                         if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
2164                                                 sect := f.Sections[i]
2165                                                 if s.Value < sect.Size {
2166                                                         if sdat, err := sect.Data(); err == nil {
2167                                                                 data := sdat[s.Value:]
2168                                                                 strlen := bo.Uint64(data[:8])
2169                                                                 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
2170                                                                         fatalf("string literal too big")
2171                                                                 }
2172                                                                 strlens[n] = int(strlen)
2173                                                         }
2174                                                 }
2175                                         }
2176                                         break
2177                                 }
2178                         }
2179                 }
2180
2181                 buildStrings()
2182                 return d, ints, floats, strs
2183         }
2184         fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
2185         panic("not reached")
2186 }
2187
2188 // gccDefines runs gcc -E -dM -xc - over the C program stdin
2189 // and returns the corresponding standard output, which is the
2190 // #defines that gcc encountered while processing the input
2191 // and its included files.
2192 func (p *Package) gccDefines(stdin []byte) string {
2193         base := append(gccBaseCmd, "-E", "-dM", "-xc")
2194         base = append(base, p.gccMachine()...)
2195         stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
2196         return stdout
2197 }
2198
2199 // gccErrors runs gcc over the C program stdin and returns
2200 // the errors that gcc prints. That is, this function expects
2201 // gcc to fail.
2202 func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string {
2203         // TODO(rsc): require failure
2204         args := p.gccCmd()
2205
2206         // Optimization options can confuse the error messages; remove them.
2207         nargs := make([]string, 0, len(args)+len(extraArgs))
2208         for _, arg := range args {
2209                 if !strings.HasPrefix(arg, "-O") {
2210                         nargs = append(nargs, arg)
2211                 }
2212         }
2213
2214         // Force -O0 optimization and append extra arguments, but keep the
2215         // trailing "-" at the end.
2216         li := len(nargs) - 1
2217         last := nargs[li]
2218         nargs[li] = "-O0"
2219         nargs = append(nargs, extraArgs...)
2220         nargs = append(nargs, last)
2221
2222         if *debugGcc {
2223                 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
2224                 os.Stderr.Write(stdin)
2225                 fmt.Fprint(os.Stderr, "EOF\n")
2226         }
2227         stdout, stderr, _ := run(stdin, nargs)
2228         if *debugGcc {
2229                 os.Stderr.Write(stdout)
2230                 os.Stderr.Write(stderr)
2231         }
2232         return string(stderr)
2233 }
2234
2235 // runGcc runs the gcc command line args with stdin on standard input.
2236 // If the command exits with a non-zero exit status, runGcc prints
2237 // details about what was run and exits.
2238 // Otherwise runGcc returns the data written to standard output and standard error.
2239 // Note that for some of the uses we expect useful data back
2240 // on standard error, but for those uses gcc must still exit 0.
2241 func runGcc(stdin []byte, args []string) (string, string) {
2242         if *debugGcc {
2243                 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
2244                 os.Stderr.Write(stdin)
2245                 fmt.Fprint(os.Stderr, "EOF\n")
2246         }
2247         stdout, stderr, ok := run(stdin, args)
2248         if *debugGcc {
2249                 os.Stderr.Write(stdout)
2250                 os.Stderr.Write(stderr)
2251         }
2252         if !ok {
2253                 os.Stderr.Write(stderr)
2254                 os.Exit(2)
2255         }
2256         return string(stdout), string(stderr)
2257 }
2258
2259 // A typeConv is a translator from dwarf types to Go types
2260 // with equivalent memory layout.
2261 type typeConv struct {
2262         // Cache of already-translated or in-progress types.
2263         m map[string]*Type
2264
2265         // Map from types to incomplete pointers to those types.
2266         ptrs map[string][]*Type
2267         // Keys of ptrs in insertion order (deterministic worklist)
2268         // ptrKeys contains exactly the keys in ptrs.
2269         ptrKeys []dwarf.Type
2270
2271         // Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
2272         getTypeIDs map[string]bool
2273
2274         // incompleteStructs contains C structs that should be marked Incomplete.
2275         incompleteStructs map[string]bool
2276
2277         // Predeclared types.
2278         bool                                   ast.Expr
2279         byte                                   ast.Expr // denotes padding
2280         int8, int16, int32, int64              ast.Expr
2281         uint8, uint16, uint32, uint64, uintptr ast.Expr
2282         float32, float64                       ast.Expr
2283         complex64, complex128                  ast.Expr
2284         void                                   ast.Expr
2285         string                                 ast.Expr
2286         goVoid                                 ast.Expr // _Ctype_void, denotes C's void
2287         goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
2288
2289         ptrSize int64
2290         intSize int64
2291 }
2292
2293 var tagGen int
2294 var typedef = make(map[string]*Type)
2295 var goIdent = make(map[string]*ast.Ident)
2296
2297 // unionWithPointer is true for a Go type that represents a C union (or class)
2298 // that may contain a pointer. This is used for cgo pointer checking.
2299 var unionWithPointer = make(map[ast.Expr]bool)
2300
2301 // anonymousStructTag provides a consistent tag for an anonymous struct.
2302 // The same dwarf.StructType pointer will always get the same tag.
2303 var anonymousStructTag = make(map[*dwarf.StructType]string)
2304
2305 func (c *typeConv) Init(ptrSize, intSize int64) {
2306         c.ptrSize = ptrSize
2307         c.intSize = intSize
2308         c.m = make(map[string]*Type)
2309         c.ptrs = make(map[string][]*Type)
2310         c.getTypeIDs = make(map[string]bool)
2311         c.incompleteStructs = make(map[string]bool)
2312         c.bool = c.Ident("bool")
2313         c.byte = c.Ident("byte")
2314         c.int8 = c.Ident("int8")
2315         c.int16 = c.Ident("int16")
2316         c.int32 = c.Ident("int32")
2317         c.int64 = c.Ident("int64")
2318         c.uint8 = c.Ident("uint8")
2319         c.uint16 = c.Ident("uint16")
2320         c.uint32 = c.Ident("uint32")
2321         c.uint64 = c.Ident("uint64")
2322         c.uintptr = c.Ident("uintptr")
2323         c.float32 = c.Ident("float32")
2324         c.float64 = c.Ident("float64")
2325         c.complex64 = c.Ident("complex64")
2326         c.complex128 = c.Ident("complex128")
2327         c.void = c.Ident("void")
2328         c.string = c.Ident("string")
2329         c.goVoid = c.Ident("_Ctype_void")
2330
2331         // Normally cgo translates void* to unsafe.Pointer,
2332         // but for historical reasons -godefs uses *byte instead.
2333         if *godefs {
2334                 c.goVoidPtr = &ast.StarExpr{X: c.byte}
2335         } else {
2336                 c.goVoidPtr = c.Ident("unsafe.Pointer")
2337         }
2338 }
2339
2340 // base strips away qualifiers and typedefs to get the underlying type.
2341 func base(dt dwarf.Type) dwarf.Type {
2342         for {
2343                 if d, ok := dt.(*dwarf.QualType); ok {
2344                         dt = d.Type
2345                         continue
2346                 }
2347                 if d, ok := dt.(*dwarf.TypedefType); ok {
2348                         dt = d.Type
2349                         continue
2350                 }
2351                 break
2352         }
2353         return dt
2354 }
2355
2356 // unqual strips away qualifiers from a DWARF type.
2357 // In general we don't care about top-level qualifiers.
2358 func unqual(dt dwarf.Type) dwarf.Type {
2359         for {
2360                 if d, ok := dt.(*dwarf.QualType); ok {
2361                         dt = d.Type
2362                 } else {
2363                         break
2364                 }
2365         }
2366         return dt
2367 }
2368
2369 // Map from dwarf text names to aliases we use in package "C".
2370 var dwarfToName = map[string]string{
2371         "long int":               "long",
2372         "long unsigned int":      "ulong",
2373         "unsigned int":           "uint",
2374         "short unsigned int":     "ushort",
2375         "unsigned short":         "ushort", // Used by Clang; issue 13129.
2376         "short int":              "short",
2377         "long long int":          "longlong",
2378         "long long unsigned int": "ulonglong",
2379         "signed char":            "schar",
2380         "unsigned char":          "uchar",
2381         "unsigned long":          "ulong",     // Used by Clang 14; issue 53013.
2382         "unsigned long long":     "ulonglong", // Used by Clang 14; issue 53013.
2383 }
2384
2385 const signedDelta = 64
2386
2387 // String returns the current type representation. Format arguments
2388 // are assembled within this method so that any changes in mutable
2389 // values are taken into account.
2390 func (tr *TypeRepr) String() string {
2391         if len(tr.Repr) == 0 {
2392                 return ""
2393         }
2394         if len(tr.FormatArgs) == 0 {
2395                 return tr.Repr
2396         }
2397         return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
2398 }
2399
2400 // Empty reports whether the result of String would be "".
2401 func (tr *TypeRepr) Empty() bool {
2402         return len(tr.Repr) == 0
2403 }
2404
2405 // Set modifies the type representation.
2406 // If fargs are provided, repr is used as a format for fmt.Sprintf.
2407 // Otherwise, repr is used unprocessed as the type representation.
2408 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
2409         tr.Repr = repr
2410         tr.FormatArgs = fargs
2411 }
2412
2413 // FinishType completes any outstanding type mapping work.
2414 // In particular, it resolves incomplete pointer types.
2415 func (c *typeConv) FinishType(pos token.Pos) {
2416         // Completing one pointer type might produce more to complete.
2417         // Keep looping until they're all done.
2418         for len(c.ptrKeys) > 0 {
2419                 dtype := c.ptrKeys[0]
2420                 dtypeKey := dtype.String()
2421                 c.ptrKeys = c.ptrKeys[1:]
2422                 ptrs := c.ptrs[dtypeKey]
2423                 delete(c.ptrs, dtypeKey)
2424
2425                 // Note Type might invalidate c.ptrs[dtypeKey].
2426                 t := c.Type(dtype, pos)
2427                 for _, ptr := range ptrs {
2428                         ptr.Go.(*ast.StarExpr).X = t.Go
2429                         ptr.C.Set("%s*", t.C)
2430                 }
2431         }
2432 }
2433
2434 // Type returns a *Type with the same memory layout as
2435 // dtype when used as the type of a variable or a struct field.
2436 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
2437         return c.loadType(dtype, pos, "")
2438 }
2439
2440 // loadType recursively loads the requested dtype and its dependency graph.
2441 func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Type {
2442         // Always recompute bad pointer typedefs, as the set of such
2443         // typedefs changes as we see more types.
2444         checkCache := true
2445         if dtt, ok := dtype.(*dwarf.TypedefType); ok && c.badPointerTypedef(dtt) {
2446                 checkCache = false
2447         }
2448
2449         // The cache key should be relative to its parent.
2450         // See issue https://golang.org/issue/31891
2451         key := parent + " > " + dtype.String()
2452
2453         if checkCache {
2454                 if t, ok := c.m[key]; ok {
2455                         if t.Go == nil {
2456                                 fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
2457                         }
2458                         return t
2459                 }
2460         }
2461
2462         t := new(Type)
2463         t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
2464         t.Align = -1
2465         t.C = &TypeRepr{Repr: dtype.Common().Name}
2466         c.m[key] = t
2467
2468         switch dt := dtype.(type) {
2469         default:
2470                 fatalf("%s: unexpected type: %s", lineno(pos), dtype)
2471
2472         case *dwarf.AddrType:
2473                 if t.Size != c.ptrSize {
2474                         fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
2475                 }
2476                 t.Go = c.uintptr
2477                 t.Align = t.Size
2478
2479         case *dwarf.ArrayType:
2480                 if dt.StrideBitSize > 0 {
2481                         // Cannot represent bit-sized elements in Go.
2482                         t.Go = c.Opaque(t.Size)
2483                         break
2484                 }
2485                 count := dt.Count
2486                 if count == -1 {
2487                         // Indicates flexible array member, which Go doesn't support.
2488                         // Translate to zero-length array instead.
2489                         count = 0
2490                 }
2491                 sub := c.Type(dt.Type, pos)
2492                 t.Align = sub.Align
2493                 t.Go = &ast.ArrayType{
2494                         Len: c.intExpr(count),
2495                         Elt: sub.Go,
2496                 }
2497                 // Recalculate t.Size now that we know sub.Size.
2498                 t.Size = count * sub.Size
2499                 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
2500
2501         case *dwarf.BoolType:
2502                 t.Go = c.bool
2503                 t.Align = 1
2504
2505         case *dwarf.CharType:
2506                 if t.Size != 1 {
2507                         fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
2508                 }
2509                 t.Go = c.int8
2510                 t.Align = 1
2511
2512         case *dwarf.EnumType:
2513                 if t.Align = t.Size; t.Align >= c.ptrSize {
2514                         t.Align = c.ptrSize
2515                 }
2516                 t.C.Set("enum " + dt.EnumName)
2517                 signed := 0
2518                 t.EnumValues = make(map[string]int64)
2519                 for _, ev := range dt.Val {
2520                         t.EnumValues[ev.Name] = ev.Val
2521                         if ev.Val < 0 {
2522                                 signed = signedDelta
2523                         }
2524                 }
2525                 switch t.Size + int64(signed) {
2526                 default:
2527                         fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
2528                 case 1:
2529                         t.Go = c.uint8
2530                 case 2:
2531                         t.Go = c.uint16
2532                 case 4:
2533                         t.Go = c.uint32
2534                 case 8:
2535                         t.Go = c.uint64
2536                 case 1 + signedDelta:
2537                         t.Go = c.int8
2538                 case 2 + signedDelta:
2539                         t.Go = c.int16
2540                 case 4 + signedDelta:
2541                         t.Go = c.int32
2542                 case 8 + signedDelta:
2543                         t.Go = c.int64
2544                 }
2545
2546         case *dwarf.FloatType:
2547                 switch t.Size {
2548                 default:
2549                         fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
2550                 case 4:
2551                         t.Go = c.float32
2552                 case 8:
2553                         t.Go = c.float64
2554                 }
2555                 if t.Align = t.Size; t.Align >= c.ptrSize {
2556                         t.Align = c.ptrSize
2557                 }
2558
2559         case *dwarf.ComplexType:
2560                 switch t.Size {
2561                 default:
2562                         fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
2563                 case 8:
2564                         t.Go = c.complex64
2565                 case 16:
2566                         t.Go = c.complex128
2567                 }
2568                 if t.Align = t.Size / 2; t.Align >= c.ptrSize {
2569                         t.Align = c.ptrSize
2570                 }
2571
2572         case *dwarf.FuncType:
2573                 // No attempt at translation: would enable calls
2574                 // directly between worlds, but we need to moderate those.
2575                 t.Go = c.uintptr
2576                 t.Align = c.ptrSize
2577
2578         case *dwarf.IntType:
2579                 if dt.BitSize > 0 {
2580                         fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
2581                 }
2582                 switch t.Size {
2583                 default:
2584                         fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
2585                 case 1:
2586                         t.Go = c.int8
2587                 case 2:
2588                         t.Go = c.int16
2589                 case 4:
2590                         t.Go = c.int32
2591                 case 8:
2592                         t.Go = c.int64
2593                 case 16:
2594                         t.Go = &ast.ArrayType{
2595                                 Len: c.intExpr(t.Size),
2596                                 Elt: c.uint8,
2597                         }
2598                 }
2599                 if t.Align = t.Size; t.Align >= c.ptrSize {
2600                         t.Align = c.ptrSize
2601                 }
2602
2603         case *dwarf.PtrType:
2604                 // Clang doesn't emit DW_AT_byte_size for pointer types.
2605                 if t.Size != c.ptrSize && t.Size != -1 {
2606                         fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
2607                 }
2608                 t.Size = c.ptrSize
2609                 t.Align = c.ptrSize
2610
2611                 if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
2612                         t.Go = c.goVoidPtr
2613                         t.C.Set("void*")
2614                         dq := dt.Type
2615                         for {
2616                                 if d, ok := dq.(*dwarf.QualType); ok {
2617                                         t.C.Set(d.Qual + " " + t.C.String())
2618                                         dq = d.Type
2619                                 } else {
2620                                         break
2621                                 }
2622                         }
2623                         break
2624                 }
2625
2626                 // Placeholder initialization; completed in FinishType.
2627                 t.Go = &ast.StarExpr{}
2628                 t.C.Set("<incomplete>*")
2629                 key := dt.Type.String()
2630                 if _, ok := c.ptrs[key]; !ok {
2631                         c.ptrKeys = append(c.ptrKeys, dt.Type)
2632                 }
2633                 c.ptrs[key] = append(c.ptrs[key], t)
2634
2635         case *dwarf.QualType:
2636                 t1 := c.Type(dt.Type, pos)
2637                 t.Size = t1.Size
2638                 t.Align = t1.Align
2639                 t.Go = t1.Go
2640                 if unionWithPointer[t1.Go] {
2641                         unionWithPointer[t.Go] = true
2642                 }
2643                 t.EnumValues = nil
2644                 t.Typedef = ""
2645                 t.C.Set("%s "+dt.Qual, t1.C)
2646                 return t
2647
2648         case *dwarf.StructType:
2649                 // Convert to Go struct, being careful about alignment.
2650                 // Have to give it a name to simulate C "struct foo" references.
2651                 tag := dt.StructName
2652                 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
2653                         break
2654                 }
2655                 if tag == "" {
2656                         tag = anonymousStructTag[dt]
2657                         if tag == "" {
2658                                 tag = "__" + strconv.Itoa(tagGen)
2659                                 tagGen++
2660                                 anonymousStructTag[dt] = tag
2661                         }
2662                 } else if t.C.Empty() {
2663                         t.C.Set(dt.Kind + " " + tag)
2664                 }
2665                 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
2666                 t.Go = name // publish before recursive calls
2667                 goIdent[name.Name] = name
2668                 if dt.ByteSize < 0 {
2669                         // Don't override old type
2670                         if _, ok := typedef[name.Name]; ok {
2671                                 break
2672                         }
2673
2674                         // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
2675                         // so execute the basic things that the struct case would do
2676                         // other than try to determine a Go representation.
2677                         tt := *t
2678                         tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
2679                         // We don't know what the representation of this struct is, so don't let
2680                         // anyone allocate one on the Go side. As a side effect of this annotation,
2681                         // pointers to this type will not be considered pointers in Go. They won't
2682                         // get writebarrier-ed or adjusted during a stack copy. This should handle
2683                         // all the cases badPointerTypedef used to handle, but hopefully will
2684                         // continue to work going forward without any more need for cgo changes.
2685                         tt.Go = c.Ident(incomplete)
2686                         typedef[name.Name] = &tt
2687                         break
2688                 }
2689                 switch dt.Kind {
2690                 case "class", "union":
2691                         t.Go = c.Opaque(t.Size)
2692                         if c.dwarfHasPointer(dt, pos) {
2693                                 unionWithPointer[t.Go] = true
2694                         }
2695                         if t.C.Empty() {
2696                                 t.C.Set("__typeof__(unsigned char[%d])", t.Size)
2697                         }
2698                         t.Align = 1 // TODO: should probably base this on field alignment.
2699                         typedef[name.Name] = t
2700                 case "struct":
2701                         g, csyntax, align := c.Struct(dt, pos)
2702                         if t.C.Empty() {
2703                                 t.C.Set(csyntax)
2704                         }
2705                         t.Align = align
2706                         tt := *t
2707                         if tag != "" {
2708                                 tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
2709                         }
2710                         tt.Go = g
2711                         if c.incompleteStructs[tag] {
2712                                 tt.Go = c.Ident(incomplete)
2713                         }
2714                         typedef[name.Name] = &tt
2715                 }
2716
2717         case *dwarf.TypedefType:
2718                 // Record typedef for printing.
2719                 if dt.Name == "_GoString_" {
2720                         // Special C name for Go string type.
2721                         // Knows string layout used by compilers: pointer plus length,
2722                         // which rounds up to 2 pointers after alignment.
2723                         t.Go = c.string
2724                         t.Size = c.ptrSize * 2
2725                         t.Align = c.ptrSize
2726                         break
2727                 }
2728                 if dt.Name == "_GoBytes_" {
2729                         // Special C name for Go []byte type.
2730                         // Knows slice layout used by compilers: pointer, length, cap.
2731                         t.Go = c.Ident("[]byte")
2732                         t.Size = c.ptrSize + 4 + 4
2733                         t.Align = c.ptrSize
2734                         break
2735                 }
2736                 name := c.Ident("_Ctype_" + dt.Name)
2737                 goIdent[name.Name] = name
2738                 akey := ""
2739                 if c.anonymousStructTypedef(dt) {
2740                         // only load type recursively for typedefs of anonymous
2741                         // structs, see issues 37479 and 37621.
2742                         akey = key
2743                 }
2744                 sub := c.loadType(dt.Type, pos, akey)
2745                 if c.badPointerTypedef(dt) {
2746                         // Treat this typedef as a uintptr.
2747                         s := *sub
2748                         s.Go = c.uintptr
2749                         s.BadPointer = true
2750                         sub = &s
2751                         // Make sure we update any previously computed type.
2752                         if oldType := typedef[name.Name]; oldType != nil {
2753                                 oldType.Go = sub.Go
2754                                 oldType.BadPointer = true
2755                         }
2756                 }
2757                 if c.badVoidPointerTypedef(dt) {
2758                         // Treat this typedef as a pointer to a _cgopackage.Incomplete.
2759                         s := *sub
2760                         s.Go = c.Ident("*" + incomplete)
2761                         sub = &s
2762                         // Make sure we update any previously computed type.
2763                         if oldType := typedef[name.Name]; oldType != nil {
2764                                 oldType.Go = sub.Go
2765                         }
2766                 }
2767                 // Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
2768                 // typedefs that should be marked Incomplete.
2769                 if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
2770                         if strct, ok := ptr.Type.(*dwarf.StructType); ok {
2771                                 if c.badStructPointerTypedef(dt.Name, strct) {
2772                                         c.incompleteStructs[strct.StructName] = true
2773                                         // Make sure we update any previously computed type.
2774                                         name := "_Ctype_struct_" + strct.StructName
2775                                         if oldType := typedef[name]; oldType != nil {
2776                                                 oldType.Go = c.Ident(incomplete)
2777                                         }
2778                                 }
2779                         }
2780                 }
2781                 t.Go = name
2782                 t.BadPointer = sub.BadPointer
2783                 if unionWithPointer[sub.Go] {
2784                         unionWithPointer[t.Go] = true
2785                 }
2786                 t.Size = sub.Size
2787                 t.Align = sub.Align
2788                 oldType := typedef[name.Name]
2789                 if oldType == nil {
2790                         tt := *t
2791                         tt.Go = sub.Go
2792                         tt.BadPointer = sub.BadPointer
2793                         typedef[name.Name] = &tt
2794                 }
2795
2796                 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
2797                 // use that as the Go form for this typedef too, so that the typedef will be interchangeable
2798                 // with the base type.
2799                 // In -godefs mode, do this for all typedefs.
2800                 if isStructUnionClass(sub.Go) || *godefs {
2801                         t.Go = sub.Go
2802
2803                         if isStructUnionClass(sub.Go) {
2804                                 // Use the typedef name for C code.
2805                                 typedef[sub.Go.(*ast.Ident).Name].C = t.C
2806                         }
2807
2808                         // If we've seen this typedef before, and it
2809                         // was an anonymous struct/union/class before
2810                         // too, use the old definition.
2811                         // TODO: it would be safer to only do this if
2812                         // we verify that the types are the same.
2813                         if oldType != nil && isStructUnionClass(oldType.Go) {
2814                                 t.Go = oldType.Go
2815                         }
2816                 }
2817
2818         case *dwarf.UcharType:
2819                 if t.Size != 1 {
2820                         fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
2821                 }
2822                 t.Go = c.uint8
2823                 t.Align = 1
2824
2825         case *dwarf.UintType:
2826                 if dt.BitSize > 0 {
2827                         fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
2828                 }
2829                 switch t.Size {
2830                 default:
2831                         fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
2832                 case 1:
2833                         t.Go = c.uint8
2834                 case 2:
2835                         t.Go = c.uint16
2836                 case 4:
2837                         t.Go = c.uint32
2838                 case 8:
2839                         t.Go = c.uint64
2840                 case 16:
2841                         t.Go = &ast.ArrayType{
2842                                 Len: c.intExpr(t.Size),
2843                                 Elt: c.uint8,
2844                         }
2845                 }
2846                 if t.Align = t.Size; t.Align >= c.ptrSize {
2847                         t.Align = c.ptrSize
2848                 }
2849
2850         case *dwarf.VoidType:
2851                 t.Go = c.goVoid
2852                 t.C.Set("void")
2853                 t.Align = 1
2854         }
2855
2856         switch dtype.(type) {
2857         case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
2858                 s := dtype.Common().Name
2859                 if s != "" {
2860                         if ss, ok := dwarfToName[s]; ok {
2861                                 s = ss
2862                         }
2863                         s = strings.Replace(s, " ", "", -1)
2864                         name := c.Ident("_Ctype_" + s)
2865                         tt := *t
2866                         typedef[name.Name] = &tt
2867                         if !*godefs {
2868                                 t.Go = name
2869                         }
2870                 }
2871         }
2872
2873         if t.Size < 0 {
2874                 // Unsized types are [0]byte, unless they're typedefs of other types
2875                 // or structs with tags.
2876                 // if so, use the name we've already defined.
2877                 t.Size = 0
2878                 switch dt := dtype.(type) {
2879                 case *dwarf.TypedefType:
2880                         // ok
2881                 case *dwarf.StructType:
2882                         if dt.StructName != "" {
2883                                 break
2884                         }
2885                         t.Go = c.Opaque(0)
2886                 default:
2887                         t.Go = c.Opaque(0)
2888                 }
2889                 if t.C.Empty() {
2890                         t.C.Set("void")
2891                 }
2892         }
2893
2894         if t.C.Empty() {
2895                 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
2896         }
2897
2898         return t
2899 }
2900
2901 // isStructUnionClass reports whether the type described by the Go syntax x
2902 // is a struct, union, or class with a tag.
2903 func isStructUnionClass(x ast.Expr) bool {
2904         id, ok := x.(*ast.Ident)
2905         if !ok {
2906                 return false
2907         }
2908         name := id.Name
2909         return strings.HasPrefix(name, "_Ctype_struct_") ||
2910                 strings.HasPrefix(name, "_Ctype_union_") ||
2911                 strings.HasPrefix(name, "_Ctype_class_")
2912 }
2913
2914 // FuncArg returns a Go type with the same memory layout as
2915 // dtype when used as the type of a C function argument.
2916 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
2917         t := c.Type(unqual(dtype), pos)
2918         switch dt := dtype.(type) {
2919         case *dwarf.ArrayType:
2920                 // Arrays are passed implicitly as pointers in C.
2921                 // In Go, we must be explicit.
2922                 tr := &TypeRepr{}
2923                 tr.Set("%s*", t.C)
2924                 return &Type{
2925                         Size:  c.ptrSize,
2926                         Align: c.ptrSize,
2927                         Go:    &ast.StarExpr{X: t.Go},
2928                         C:     tr,
2929                 }
2930         case *dwarf.TypedefType:
2931                 // C has much more relaxed rules than Go for
2932                 // implicit type conversions. When the parameter
2933                 // is type T defined as *X, simulate a little of the
2934                 // laxness of C by making the argument *X instead of T.
2935                 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
2936                         // Unless the typedef happens to point to void* since
2937                         // Go has special rules around using unsafe.Pointer.
2938                         if _, void := base(ptr.Type).(*dwarf.VoidType); void {
2939                                 break
2940                         }
2941                         // ...or the typedef is one in which we expect bad pointers.
2942                         // It will be a uintptr instead of *X.
2943                         if c.baseBadPointerTypedef(dt) {
2944                                 break
2945                         }
2946
2947                         t = c.Type(ptr, pos)
2948                         if t == nil {
2949                                 return nil
2950                         }
2951
2952                         // For a struct/union/class, remember the C spelling,
2953                         // in case it has __attribute__((unavailable)).
2954                         // See issue 2888.
2955                         if isStructUnionClass(t.Go) {
2956                                 t.Typedef = dt.Name
2957                         }
2958                 }
2959         }
2960         return t
2961 }
2962
2963 // FuncType returns the Go type analogous to dtype.
2964 // There is no guarantee about matching memory layout.
2965 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
2966         p := make([]*Type, len(dtype.ParamType))
2967         gp := make([]*ast.Field, len(dtype.ParamType))
2968         for i, f := range dtype.ParamType {
2969                 // gcc's DWARF generator outputs a single DotDotDotType parameter for
2970                 // function pointers that specify no parameters (e.g. void
2971                 // (*__cgo_0)()).  Treat this special case as void. This case is
2972                 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2973                 // legal).
2974                 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
2975                         p, gp = nil, nil
2976                         break
2977                 }
2978                 p[i] = c.FuncArg(f, pos)
2979                 gp[i] = &ast.Field{Type: p[i].Go}
2980         }
2981         var r *Type
2982         var gr []*ast.Field
2983         if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
2984                 gr = []*ast.Field{{Type: c.goVoid}}
2985         } else if dtype.ReturnType != nil {
2986                 r = c.Type(unqual(dtype.ReturnType), pos)
2987                 gr = []*ast.Field{{Type: r.Go}}
2988         }
2989         return &FuncType{
2990                 Params: p,
2991                 Result: r,
2992                 Go: &ast.FuncType{
2993                         Params:  &ast.FieldList{List: gp},
2994                         Results: &ast.FieldList{List: gr},
2995                 },
2996         }
2997 }
2998
2999 // Identifier
3000 func (c *typeConv) Ident(s string) *ast.Ident {
3001         return ast.NewIdent(s)
3002 }
3003
3004 // Opaque type of n bytes.
3005 func (c *typeConv) Opaque(n int64) ast.Expr {
3006         return &ast.ArrayType{
3007                 Len: c.intExpr(n),
3008                 Elt: c.byte,
3009         }
3010 }
3011
3012 // Expr for integer n.
3013 func (c *typeConv) intExpr(n int64) ast.Expr {
3014         return &ast.BasicLit{
3015                 Kind:  token.INT,
3016                 Value: strconv.FormatInt(n, 10),
3017         }
3018 }
3019
3020 // Add padding of given size to fld.
3021 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
3022         n := len(fld)
3023         fld = fld[0 : n+1]
3024         fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
3025         sizes = sizes[0 : n+1]
3026         sizes[n] = size
3027         return fld, sizes
3028 }
3029
3030 // Struct conversion: return Go and (gc) C syntax for type.
3031 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
3032         // Minimum alignment for a struct is 1 byte.
3033         align = 1
3034
3035         var buf strings.Builder
3036         buf.WriteString("struct {")
3037         fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
3038         sizes := make([]int64, 0, 2*len(dt.Field)+1)
3039         off := int64(0)
3040
3041         // Rename struct fields that happen to be named Go keywords into
3042         // _{keyword}.  Create a map from C ident -> Go ident. The Go ident will
3043         // be mangled. Any existing identifier that already has the same name on
3044         // the C-side will cause the Go-mangled version to be prefixed with _.
3045         // (e.g. in a struct with fields '_type' and 'type', the latter would be
3046         // rendered as '__type' in Go).
3047         ident := make(map[string]string)
3048         used := make(map[string]bool)
3049         for _, f := range dt.Field {
3050                 ident[f.Name] = f.Name
3051                 used[f.Name] = true
3052         }
3053
3054         if !*godefs {
3055                 for cid, goid := range ident {
3056                         if token.Lookup(goid).IsKeyword() {
3057                                 // Avoid keyword
3058                                 goid = "_" + goid
3059
3060                                 // Also avoid existing fields
3061                                 for _, exist := used[goid]; exist; _, exist = used[goid] {
3062                                         goid = "_" + goid
3063                                 }
3064
3065                                 used[goid] = true
3066                                 ident[cid] = goid
3067                         }
3068                 }
3069         }
3070
3071         anon := 0
3072         for _, f := range dt.Field {
3073                 name := f.Name
3074                 ft := f.Type
3075
3076                 // In godefs mode, if this field is a C11
3077                 // anonymous union then treat the first field in the
3078                 // union as the field in the struct. This handles
3079                 // cases like the glibc <sys/resource.h> file; see
3080                 // issue 6677.
3081                 if *godefs {
3082                         if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
3083                                 name = st.Field[0].Name
3084                                 ident[name] = name
3085                                 ft = st.Field[0].Type
3086                         }
3087                 }
3088
3089                 // TODO: Handle fields that are anonymous structs by
3090                 // promoting the fields of the inner struct.
3091
3092                 t := c.Type(ft, pos)
3093                 tgo := t.Go
3094                 size := t.Size
3095                 talign := t.Align
3096                 if f.BitOffset > 0 || f.BitSize > 0 {
3097                         // The layout of bitfields is implementation defined,
3098                         // so we don't know how they correspond to Go fields
3099                         // even if they are aligned at byte boundaries.
3100                         continue
3101                 }
3102
3103                 if talign > 0 && f.ByteOffset%talign != 0 {
3104                         // Drop misaligned fields, the same way we drop integer bit fields.
3105                         // The goal is to make available what can be made available.
3106                         // Otherwise one bad and unneeded field in an otherwise okay struct
3107                         // makes the whole program not compile. Much of the time these
3108                         // structs are in system headers that cannot be corrected.
3109                         continue
3110                 }
3111
3112                 // Round off up to talign, assumed to be a power of 2.
3113                 off = (off + talign - 1) &^ (talign - 1)
3114
3115                 if f.ByteOffset > off {
3116                         fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
3117                         off = f.ByteOffset
3118                 }
3119                 if f.ByteOffset < off {
3120                         // Drop a packed field that we can't represent.
3121                         continue
3122                 }
3123
3124                 n := len(fld)
3125                 fld = fld[0 : n+1]
3126                 if name == "" {
3127                         name = fmt.Sprintf("anon%d", anon)
3128                         anon++
3129                         ident[name] = name
3130                 }
3131                 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
3132                 sizes = sizes[0 : n+1]
3133                 sizes[n] = size
3134                 off += size
3135                 buf.WriteString(t.C.String())
3136                 buf.WriteString(" ")
3137                 buf.WriteString(name)
3138                 buf.WriteString("; ")
3139                 if talign > align {
3140                         align = talign
3141                 }
3142         }
3143         if off < dt.ByteSize {
3144                 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
3145                 off = dt.ByteSize
3146         }
3147
3148         // If the last field in a non-zero-sized struct is zero-sized
3149         // the compiler is going to pad it by one (see issue 9401).
3150         // We can't permit that, because then the size of the Go
3151         // struct will not be the same as the size of the C struct.
3152         // Our only option in such a case is to remove the field,
3153         // which means that it cannot be referenced from Go.
3154         for off > 0 && sizes[len(sizes)-1] == 0 {
3155                 n := len(sizes)
3156                 fld = fld[0 : n-1]
3157                 sizes = sizes[0 : n-1]
3158         }
3159
3160         if off != dt.ByteSize {
3161                 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
3162         }
3163         buf.WriteString("}")
3164         csyntax = buf.String()
3165
3166         if *godefs {
3167                 godefsFields(fld)
3168         }
3169         expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
3170         return
3171 }
3172
3173 // dwarfHasPointer reports whether the DWARF type dt contains a pointer.
3174 func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
3175         switch dt := dt.(type) {
3176         default:
3177                 fatalf("%s: unexpected type: %s", lineno(pos), dt)
3178                 return false
3179
3180         case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
3181                 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
3182                 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
3183
3184                 return false
3185
3186         case *dwarf.ArrayType:
3187                 return c.dwarfHasPointer(dt.Type, pos)
3188
3189         case *dwarf.PtrType:
3190                 return true
3191
3192         case *dwarf.QualType:
3193                 return c.dwarfHasPointer(dt.Type, pos)
3194
3195         case *dwarf.StructType:
3196                 for _, f := range dt.Field {
3197                         if c.dwarfHasPointer(f.Type, pos) {
3198                                 return true
3199                         }
3200                 }
3201                 return false
3202
3203         case *dwarf.TypedefType:
3204                 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
3205                         return true
3206                 }
3207                 return c.dwarfHasPointer(dt.Type, pos)
3208         }
3209 }
3210
3211 func upper(s string) string {
3212         if s == "" {
3213                 return ""
3214         }
3215         r, size := utf8.DecodeRuneInString(s)
3216         if r == '_' {
3217                 return "X" + s
3218         }
3219         return string(unicode.ToUpper(r)) + s[size:]
3220 }
3221
3222 // godefsFields rewrites field names for use in Go or C definitions.
3223 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
3224 // converts names to upper case, and rewrites _ into Pad_godefs_n,
3225 // so that all fields are exported.
3226 func godefsFields(fld []*ast.Field) {
3227         prefix := fieldPrefix(fld)
3228
3229         // Issue 48396: check for duplicate field names.
3230         if prefix != "" {
3231                 names := make(map[string]bool)
3232         fldLoop:
3233                 for _, f := range fld {
3234                         for _, n := range f.Names {
3235                                 name := n.Name
3236                                 if name == "_" {
3237                                         continue
3238                                 }
3239                                 if name != prefix {
3240                                         name = strings.TrimPrefix(n.Name, prefix)
3241                                 }
3242                                 name = upper(name)
3243                                 if names[name] {
3244                                         // Field name conflict: don't remove prefix.
3245                                         prefix = ""
3246                                         break fldLoop
3247                                 }
3248                                 names[name] = true
3249                         }
3250                 }
3251         }
3252
3253         npad := 0
3254         for _, f := range fld {
3255                 for _, n := range f.Names {
3256                         if n.Name != prefix {
3257                                 n.Name = strings.TrimPrefix(n.Name, prefix)
3258                         }
3259                         if n.Name == "_" {
3260                                 // Use exported name instead.
3261                                 n.Name = "Pad_cgo_" + strconv.Itoa(npad)
3262                                 npad++
3263                         }
3264                         n.Name = upper(n.Name)
3265                 }
3266         }
3267 }
3268
3269 // fieldPrefix returns the prefix that should be removed from all the
3270 // field names when generating the C or Go code. For generated
3271 // C, we leave the names as is (tv_sec, tv_usec), since that's what
3272 // people are used to seeing in C.  For generated Go code, such as
3273 // package syscall's data structures, we drop a common prefix
3274 // (so sec, usec, which will get turned into Sec, Usec for exporting).
3275 func fieldPrefix(fld []*ast.Field) string {
3276         prefix := ""
3277         for _, f := range fld {
3278                 for _, n := range f.Names {
3279                         // Ignore field names that don't have the prefix we're
3280                         // looking for. It is common in C headers to have fields
3281                         // named, say, _pad in an otherwise prefixed header.
3282                         // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
3283                         // still want to remove the tv_ prefix.
3284                         // The check for "orig_" here handles orig_eax in the
3285                         // x86 ptrace register sets, which otherwise have all fields
3286                         // with reg_ prefixes.
3287                         if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
3288                                 continue
3289                         }
3290                         i := strings.Index(n.Name, "_")
3291                         if i < 0 {
3292                                 continue
3293                         }
3294                         if prefix == "" {
3295                                 prefix = n.Name[:i+1]
3296                         } else if prefix != n.Name[:i+1] {
3297                                 return ""
3298                         }
3299                 }
3300         }
3301         return prefix
3302 }
3303
3304 // anonymousStructTypedef reports whether dt is a C typedef for an anonymous
3305 // struct.
3306 func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
3307         st, ok := dt.Type.(*dwarf.StructType)
3308         return ok && st.StructName == ""
3309 }
3310
3311 // badPointerTypedef reports whether dt is a C typedef that should not be
3312 // considered a pointer in Go. A typedef is bad if C code sometimes stores
3313 // non-pointers in this type.
3314 // TODO: Currently our best solution is to find these manually and list them as
3315 // they come up. A better solution is desired.
3316 // Note: DEPRECATED. There is now a better solution. Search for incomplete in this file.
3317 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
3318         if c.badCFType(dt) {
3319                 return true
3320         }
3321         if c.badJNI(dt) {
3322                 return true
3323         }
3324         if c.badEGLType(dt) {
3325                 return true
3326         }
3327         return false
3328 }
3329
3330 // badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
3331 func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
3332         // Match the Windows HANDLE type (#42018).
3333         if goos != "windows" || dt.Name != "HANDLE" {
3334                 return false
3335         }
3336         // Check that the typedef is "typedef void *<name>".
3337         if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
3338                 if _, ok := ptr.Type.(*dwarf.VoidType); ok {
3339                         return true
3340                 }
3341         }
3342         return false
3343 }
3344
3345 // badStructPointerTypedef is like badVoidPointerTypedef but for structs.
3346 func (c *typeConv) badStructPointerTypedef(name string, dt *dwarf.StructType) bool {
3347         // Windows handle types can all potentially contain non-pointers.
3348         // badVoidPointerTypedef handles the "void *" HANDLE type, but other
3349         // handles are defined as
3350         //
3351         // struct <name>__{int unused;}; typedef struct <name>__ *name;
3352         //
3353         // by the DECLARE_HANDLE macro in STRICT mode. The macro is declared in
3354         // the Windows ntdef.h header,
3355         //
3356         // https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntdef.h#L779
3357         if goos != "windows" {
3358                 return false
3359         }
3360         if len(dt.Field) != 1 {
3361                 return false
3362         }
3363         if dt.StructName != name+"__" {
3364                 return false
3365         }
3366         if f := dt.Field[0]; f.Name != "unused" || f.Type.Common().Name != "int" {
3367                 return false
3368         }
3369         return true
3370 }
3371
3372 // baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
3373 // as badPointerTypedef reports.
3374 func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
3375         for {
3376                 if t, ok := dt.Type.(*dwarf.TypedefType); ok {
3377                         dt = t
3378                         continue
3379                 }
3380                 break
3381         }
3382         return c.badPointerTypedef(dt)
3383 }
3384
3385 func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
3386         // The real bad types are CFNumberRef and CFDateRef.
3387         // Sometimes non-pointers are stored in these types.
3388         // CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
3389         // We return true for the other *Ref types just so casting between them is easier.
3390         // We identify the correct set of types as those ending in Ref and for which
3391         // there exists a corresponding GetTypeID function.
3392         // See comment below for details about the bad pointers.
3393         if goos != "darwin" && goos != "ios" {
3394                 return false
3395         }
3396         s := dt.Name
3397         if !strings.HasSuffix(s, "Ref") {
3398                 return false
3399         }
3400         s = s[:len(s)-3]
3401         if s == "CFType" {
3402                 return true
3403         }
3404         if c.getTypeIDs[s] {
3405                 return true
3406         }
3407         if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
3408                 // Mutable and immutable variants share a type ID.
3409                 return true
3410         }
3411         return false
3412 }
3413
3414 // Comment from Darwin's CFInternal.h
3415 /*
3416 // Tagged pointer support
3417 // Low-bit set means tagged object, next 3 bits (currently)
3418 // define the tagged object class, next 4 bits are for type
3419 // information for the specific tagged object class.  Thus,
3420 // the low byte is for type info, and the rest of a pointer
3421 // (32 or 64-bit) is for payload, whatever the tagged class.
3422 //
3423 // Note that the specific integers used to identify the
3424 // specific tagged classes can and will change from release
3425 // to release (that's why this stuff is in CF*Internal*.h),
3426 // as can the definition of type info vs payload above.
3427 //
3428 #if __LP64__
3429 #define CF_IS_TAGGED_OBJ(PTR)   ((uintptr_t)(PTR) & 0x1)
3430 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
3431 #else
3432 #define CF_IS_TAGGED_OBJ(PTR)   0
3433 #define CF_TAGGED_OBJ_TYPE(PTR) 0
3434 #endif
3435
3436 enum {
3437     kCFTaggedObjectID_Invalid = 0,
3438     kCFTaggedObjectID_Atom = (0 << 1) + 1,
3439     kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
3440     kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
3441     kCFTaggedObjectID_Integer = (3 << 1) + 1,
3442     kCFTaggedObjectID_DateTS = (4 << 1) + 1,
3443     kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
3444     kCFTaggedObjectID_Date = (6 << 1) + 1,
3445     kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
3446 };
3447 */
3448
3449 func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
3450         // In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
3451         // property that it is sometimes (always?) a small integer instead of a real pointer.
3452         // Note: although only the android JVMs are bad in this respect, we declare the JNI types
3453         // bad regardless of platform, so the same Go code compiles on both android and non-android.
3454         if parent, ok := jniTypes[dt.Name]; ok {
3455                 // Try to make sure we're talking about a JNI type, not just some random user's
3456                 // type that happens to use the same name.
3457                 // C doesn't have the notion of a package, so it's hard to be certain.
3458
3459                 // Walk up to jobject, checking each typedef on the way.
3460                 w := dt
3461                 for parent != "" {
3462                         t, ok := w.Type.(*dwarf.TypedefType)
3463                         if !ok || t.Name != parent {
3464                                 return false
3465                         }
3466                         w = t
3467                         parent, ok = jniTypes[w.Name]
3468                         if !ok {
3469                                 return false
3470                         }
3471                 }
3472
3473                 // Check that the typedef is either:
3474                 // 1:
3475                 //      struct _jobject;
3476                 //      typedef struct _jobject *jobject;
3477                 // 2: (in NDK16 in C++)
3478                 //      class _jobject {};
3479                 //      typedef _jobject* jobject;
3480                 // 3: (in NDK16 in C)
3481                 //      typedef void* jobject;
3482                 if ptr, ok := w.Type.(*dwarf.PtrType); ok {
3483                         switch v := ptr.Type.(type) {
3484                         case *dwarf.VoidType:
3485                                 return true
3486                         case *dwarf.StructType:
3487                                 if v.StructName == "_jobject" && len(v.Field) == 0 {
3488                                         switch v.Kind {
3489                                         case "struct":
3490                                                 if v.Incomplete {
3491                                                         return true
3492                                                 }
3493                                         case "class":
3494                                                 if !v.Incomplete {
3495                                                         return true
3496                                                 }
3497                                         }
3498                                 }
3499                         }
3500                 }
3501         }
3502         return false
3503 }
3504
3505 func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool {
3506         if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" {
3507                 return false
3508         }
3509         // Check that the typedef is "typedef void *<name>".
3510         if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
3511                 if _, ok := ptr.Type.(*dwarf.VoidType); ok {
3512                         return true
3513                 }
3514         }
3515         return false
3516 }
3517
3518 // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
3519 // they are mapped. The base "jobject" maps to the empty string.
3520 var jniTypes = map[string]string{
3521         "jobject":       "",
3522         "jclass":        "jobject",
3523         "jthrowable":    "jobject",
3524         "jstring":       "jobject",
3525         "jarray":        "jobject",
3526         "jbooleanArray": "jarray",
3527         "jbyteArray":    "jarray",
3528         "jcharArray":    "jarray",
3529         "jshortArray":   "jarray",
3530         "jintArray":     "jarray",
3531         "jlongArray":    "jarray",
3532         "jfloatArray":   "jarray",
3533         "jdoubleArray":  "jarray",
3534         "jobjectArray":  "jarray",
3535         "jweak":         "jobject",
3536 }