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
8package main
9
10import (
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
35var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
36var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
37
38var 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
50var 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.
56func 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.
80func (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.
110func (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"`}
141func 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.
189func (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.
238func (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.
281func (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.
524func (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.
704func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
705	p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
706}
707
708func (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.
747func (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.
772func (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
783func (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.
799func (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.
826func (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(gofmt(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				gofmt(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.
1026func (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.
1042func (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.
1132func (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.
1198func (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.
1255func (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.
1299func (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.
1333func (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.
1353func (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.
1399func (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.
1418func (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.
1432func (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.
1482func (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.
1574func (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 builtinDefs[r.Name.Go] != "" {
1605				error_(r.Pos(), "no two-result form for C.%s", r.Name.Go)
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.
1684func gofmtPos(n ast.Expr, pos token.Pos) string {
1685	s := gofmt(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.
1703func 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".
1727func (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
1764func gccTmp() string {
1765	return *objDir + "_cgo_.o"
1766}
1767
1768// gccCmd returns the gcc command line to use for compiling
1769// the input.
1770func (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.
1813func (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.
2192func (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.
2202func (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.
2241func 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.
2261type 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
2293var tagGen int
2294var typedef = make(map[string]*Type)
2295var 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.
2299var 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.
2303var anonymousStructTag = make(map[*dwarf.StructType]string)
2304
2305func (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.
2341func 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.
2358func 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".
2370var 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
2385const 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.
2390func (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 "".
2401func (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.
2408func (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.
2415func (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.
2436func (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.
2441func (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
2583		if t.Align = t.Size; t.Align >= c.ptrSize {
2584			t.Align = c.ptrSize
2585		}
2586
2587		switch t.Size {
2588		default:
2589			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
2590		case 1:
2591			t.Go = c.int8
2592		case 2:
2593			t.Go = c.int16
2594		case 4:
2595			t.Go = c.int32
2596		case 8:
2597			t.Go = c.int64
2598		case 16:
2599			t.Go = &ast.ArrayType{
2600				Len: c.intExpr(t.Size),
2601				Elt: c.uint8,
2602			}
2603			// t.Align is the alignment of the Go type.
2604			t.Align = 1
2605		}
2606
2607	case *dwarf.PtrType:
2608		// Clang doesn't emit DW_AT_byte_size for pointer types.
2609		if t.Size != c.ptrSize && t.Size != -1 {
2610			fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
2611		}
2612		t.Size = c.ptrSize
2613		t.Align = c.ptrSize
2614
2615		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
2616			t.Go = c.goVoidPtr
2617			t.C.Set("void*")
2618			dq := dt.Type
2619			for {
2620				if d, ok := dq.(*dwarf.QualType); ok {
2621					t.C.Set(d.Qual + " " + t.C.String())
2622					dq = d.Type
2623				} else {
2624					break
2625				}
2626			}
2627			break
2628		}
2629
2630		// Placeholder initialization; completed in FinishType.
2631		t.Go = &ast.StarExpr{}
2632		t.C.Set("<incomplete>*")
2633		key := dt.Type.String()
2634		if _, ok := c.ptrs[key]; !ok {
2635			c.ptrKeys = append(c.ptrKeys, dt.Type)
2636		}
2637		c.ptrs[key] = append(c.ptrs[key], t)
2638
2639	case *dwarf.QualType:
2640		t1 := c.Type(dt.Type, pos)
2641		t.Size = t1.Size
2642		t.Align = t1.Align
2643		t.Go = t1.Go
2644		if unionWithPointer[t1.Go] {
2645			unionWithPointer[t.Go] = true
2646		}
2647		t.EnumValues = nil
2648		t.Typedef = ""
2649		t.C.Set("%s "+dt.Qual, t1.C)
2650		return t
2651
2652	case *dwarf.StructType:
2653		// Convert to Go struct, being careful about alignment.
2654		// Have to give it a name to simulate C "struct foo" references.
2655		tag := dt.StructName
2656		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
2657			break
2658		}
2659		if tag == "" {
2660			tag = anonymousStructTag[dt]
2661			if tag == "" {
2662				tag = "__" + strconv.Itoa(tagGen)
2663				tagGen++
2664				anonymousStructTag[dt] = tag
2665			}
2666		} else if t.C.Empty() {
2667			t.C.Set(dt.Kind + " " + tag)
2668		}
2669		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
2670		t.Go = name // publish before recursive calls
2671		goIdent[name.Name] = name
2672		if dt.ByteSize < 0 {
2673			// Don't override old type
2674			if _, ok := typedef[name.Name]; ok {
2675				break
2676			}
2677
2678			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
2679			// so execute the basic things that the struct case would do
2680			// other than try to determine a Go representation.
2681			tt := *t
2682			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
2683			// We don't know what the representation of this struct is, so don't let
2684			// anyone allocate one on the Go side. As a side effect of this annotation,
2685			// pointers to this type will not be considered pointers in Go. They won't
2686			// get writebarrier-ed or adjusted during a stack copy. This should handle
2687			// all the cases badPointerTypedef used to handle, but hopefully will
2688			// continue to work going forward without any more need for cgo changes.
2689			tt.Go = c.Ident(incomplete)
2690			typedef[name.Name] = &tt
2691			break
2692		}
2693		switch dt.Kind {
2694		case "class", "union":
2695			t.Go = c.Opaque(t.Size)
2696			if c.dwarfHasPointer(dt, pos) {
2697				unionWithPointer[t.Go] = true
2698			}
2699			if t.C.Empty() {
2700				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
2701			}
2702			t.Align = 1 // TODO: should probably base this on field alignment.
2703			typedef[name.Name] = t
2704		case "struct":
2705			g, csyntax, align := c.Struct(dt, pos)
2706			if t.C.Empty() {
2707				t.C.Set(csyntax)
2708			}
2709			t.Align = align
2710			tt := *t
2711			if tag != "" {
2712				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
2713			}
2714			tt.Go = g
2715			if c.incompleteStructs[tag] {
2716				tt.Go = c.Ident(incomplete)
2717			}
2718			typedef[name.Name] = &tt
2719		}
2720
2721	case *dwarf.TypedefType:
2722		// Record typedef for printing.
2723		if dt.Name == "_GoString_" {
2724			// Special C name for Go string type.
2725			// Knows string layout used by compilers: pointer plus length,
2726			// which rounds up to 2 pointers after alignment.
2727			t.Go = c.string
2728			t.Size = c.ptrSize * 2
2729			t.Align = c.ptrSize
2730			break
2731		}
2732		if dt.Name == "_GoBytes_" {
2733			// Special C name for Go []byte type.
2734			// Knows slice layout used by compilers: pointer, length, cap.
2735			t.Go = c.Ident("[]byte")
2736			t.Size = c.ptrSize + 4 + 4
2737			t.Align = c.ptrSize
2738			break
2739		}
2740		name := c.Ident("_Ctype_" + dt.Name)
2741		goIdent[name.Name] = name
2742		akey := ""
2743		if c.anonymousStructTypedef(dt) {
2744			// only load type recursively for typedefs of anonymous
2745			// structs, see issues 37479 and 37621.
2746			akey = key
2747		}
2748		sub := c.loadType(dt.Type, pos, akey)
2749		if c.badPointerTypedef(dt) {
2750			// Treat this typedef as a uintptr.
2751			s := *sub
2752			s.Go = c.uintptr
2753			s.BadPointer = true
2754			sub = &s
2755			// Make sure we update any previously computed type.
2756			if oldType := typedef[name.Name]; oldType != nil {
2757				oldType.Go = sub.Go
2758				oldType.BadPointer = true
2759			}
2760		}
2761		if c.badVoidPointerTypedef(dt) {
2762			// Treat this typedef as a pointer to a _cgopackage.Incomplete.
2763			s := *sub
2764			s.Go = c.Ident("*" + incomplete)
2765			sub = &s
2766			// Make sure we update any previously computed type.
2767			if oldType := typedef[name.Name]; oldType != nil {
2768				oldType.Go = sub.Go
2769			}
2770		}
2771		// Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
2772		// typedefs that should be marked Incomplete.
2773		if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
2774			if strct, ok := ptr.Type.(*dwarf.StructType); ok {
2775				if c.badStructPointerTypedef(dt.Name, strct) {
2776					c.incompleteStructs[strct.StructName] = true
2777					// Make sure we update any previously computed type.
2778					name := "_Ctype_struct_" + strct.StructName
2779					if oldType := typedef[name]; oldType != nil {
2780						oldType.Go = c.Ident(incomplete)
2781					}
2782				}
2783			}
2784		}
2785		t.Go = name
2786		t.BadPointer = sub.BadPointer
2787		if unionWithPointer[sub.Go] {
2788			unionWithPointer[t.Go] = true
2789		}
2790		t.Size = sub.Size
2791		t.Align = sub.Align
2792		oldType := typedef[name.Name]
2793		if oldType == nil {
2794			tt := *t
2795			tt.Go = sub.Go
2796			tt.BadPointer = sub.BadPointer
2797			typedef[name.Name] = &tt
2798		}
2799
2800		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
2801		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
2802		// with the base type.
2803		// In -godefs mode, do this for all typedefs.
2804		if isStructUnionClass(sub.Go) || *godefs {
2805			t.Go = sub.Go
2806
2807			if isStructUnionClass(sub.Go) {
2808				// Use the typedef name for C code.
2809				typedef[sub.Go.(*ast.Ident).Name].C = t.C
2810			}
2811
2812			// If we've seen this typedef before, and it
2813			// was an anonymous struct/union/class before
2814			// too, use the old definition.
2815			// TODO: it would be safer to only do this if
2816			// we verify that the types are the same.
2817			if oldType != nil && isStructUnionClass(oldType.Go) {
2818				t.Go = oldType.Go
2819			}
2820		}
2821
2822	case *dwarf.UcharType:
2823		if t.Size != 1 {
2824			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
2825		}
2826		t.Go = c.uint8
2827		t.Align = 1
2828
2829	case *dwarf.UintType:
2830		if dt.BitSize > 0 {
2831			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
2832		}
2833
2834		if t.Align = t.Size; t.Align >= c.ptrSize {
2835			t.Align = c.ptrSize
2836		}
2837
2838		switch t.Size {
2839		default:
2840			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
2841		case 1:
2842			t.Go = c.uint8
2843		case 2:
2844			t.Go = c.uint16
2845		case 4:
2846			t.Go = c.uint32
2847		case 8:
2848			t.Go = c.uint64
2849		case 16:
2850			t.Go = &ast.ArrayType{
2851				Len: c.intExpr(t.Size),
2852				Elt: c.uint8,
2853			}
2854			// t.Align is the alignment of the Go type.
2855			t.Align = 1
2856		}
2857
2858	case *dwarf.VoidType:
2859		t.Go = c.goVoid
2860		t.C.Set("void")
2861		t.Align = 1
2862	}
2863
2864	switch dtype.(type) {
2865	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
2866		s := dtype.Common().Name
2867		if s != "" {
2868			if ss, ok := dwarfToName[s]; ok {
2869				s = ss
2870			}
2871			s = strings.Replace(s, " ", "", -1)
2872			name := c.Ident("_Ctype_" + s)
2873			tt := *t
2874			typedef[name.Name] = &tt
2875			if !*godefs {
2876				t.Go = name
2877			}
2878		}
2879	}
2880
2881	if t.Size < 0 {
2882		// Unsized types are [0]byte, unless they're typedefs of other types
2883		// or structs with tags.
2884		// if so, use the name we've already defined.
2885		t.Size = 0
2886		switch dt := dtype.(type) {
2887		case *dwarf.TypedefType:
2888			// ok
2889		case *dwarf.StructType:
2890			if dt.StructName != "" {
2891				break
2892			}
2893			t.Go = c.Opaque(0)
2894		default:
2895			t.Go = c.Opaque(0)
2896		}
2897		if t.C.Empty() {
2898			t.C.Set("void")
2899		}
2900	}
2901
2902	if t.C.Empty() {
2903		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
2904	}
2905
2906	return t
2907}
2908
2909// isStructUnionClass reports whether the type described by the Go syntax x
2910// is a struct, union, or class with a tag.
2911func isStructUnionClass(x ast.Expr) bool {
2912	id, ok := x.(*ast.Ident)
2913	if !ok {
2914		return false
2915	}
2916	name := id.Name
2917	return strings.HasPrefix(name, "_Ctype_struct_") ||
2918		strings.HasPrefix(name, "_Ctype_union_") ||
2919		strings.HasPrefix(name, "_Ctype_class_")
2920}
2921
2922// FuncArg returns a Go type with the same memory layout as
2923// dtype when used as the type of a C function argument.
2924func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
2925	t := c.Type(unqual(dtype), pos)
2926	switch dt := dtype.(type) {
2927	case *dwarf.ArrayType:
2928		// Arrays are passed implicitly as pointers in C.
2929		// In Go, we must be explicit.
2930		tr := &TypeRepr{}
2931		tr.Set("%s*", t.C)
2932		return &Type{
2933			Size:  c.ptrSize,
2934			Align: c.ptrSize,
2935			Go:    &ast.StarExpr{X: t.Go},
2936			C:     tr,
2937		}
2938	case *dwarf.TypedefType:
2939		// C has much more relaxed rules than Go for
2940		// implicit type conversions. When the parameter
2941		// is type T defined as *X, simulate a little of the
2942		// laxness of C by making the argument *X instead of T.
2943		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
2944			// Unless the typedef happens to point to void* since
2945			// Go has special rules around using unsafe.Pointer.
2946			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
2947				break
2948			}
2949			// ...or the typedef is one in which we expect bad pointers.
2950			// It will be a uintptr instead of *X.
2951			if c.baseBadPointerTypedef(dt) {
2952				break
2953			}
2954
2955			t = c.Type(ptr, pos)
2956			if t == nil {
2957				return nil
2958			}
2959
2960			// For a struct/union/class, remember the C spelling,
2961			// in case it has __attribute__((unavailable)).
2962			// See issue 2888.
2963			if isStructUnionClass(t.Go) {
2964				t.Typedef = dt.Name
2965			}
2966		}
2967	}
2968	return t
2969}
2970
2971// FuncType returns the Go type analogous to dtype.
2972// There is no guarantee about matching memory layout.
2973func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
2974	p := make([]*Type, len(dtype.ParamType))
2975	gp := make([]*ast.Field, len(dtype.ParamType))
2976	for i, f := range dtype.ParamType {
2977		// gcc's DWARF generator outputs a single DotDotDotType parameter for
2978		// function pointers that specify no parameters (e.g. void
2979		// (*__cgo_0)()).  Treat this special case as void. This case is
2980		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2981		// legal).
2982		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
2983			p, gp = nil, nil
2984			break
2985		}
2986		p[i] = c.FuncArg(f, pos)
2987		gp[i] = &ast.Field{Type: p[i].Go}
2988	}
2989	var r *Type
2990	var gr []*ast.Field
2991	if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
2992		gr = []*ast.Field{{Type: c.goVoid}}
2993	} else if dtype.ReturnType != nil {
2994		r = c.Type(unqual(dtype.ReturnType), pos)
2995		gr = []*ast.Field{{Type: r.Go}}
2996	}
2997	return &FuncType{
2998		Params: p,
2999		Result: r,
3000		Go: &ast.FuncType{
3001			Params:  &ast.FieldList{List: gp},
3002			Results: &ast.FieldList{List: gr},
3003		},
3004	}
3005}
3006
3007// Identifier
3008func (c *typeConv) Ident(s string) *ast.Ident {
3009	return ast.NewIdent(s)
3010}
3011
3012// Opaque type of n bytes.
3013func (c *typeConv) Opaque(n int64) ast.Expr {
3014	return &ast.ArrayType{
3015		Len: c.intExpr(n),
3016		Elt: c.byte,
3017	}
3018}
3019
3020// Expr for integer n.
3021func (c *typeConv) intExpr(n int64) ast.Expr {
3022	return &ast.BasicLit{
3023		Kind:  token.INT,
3024		Value: strconv.FormatInt(n, 10),
3025	}
3026}
3027
3028// Add padding of given size to fld.
3029func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
3030	n := len(fld)
3031	fld = fld[0 : n+1]
3032	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
3033	sizes = sizes[0 : n+1]
3034	sizes[n] = size
3035	return fld, sizes
3036}
3037
3038// Struct conversion: return Go and (gc) C syntax for type.
3039func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
3040	// Minimum alignment for a struct is 1 byte.
3041	align = 1
3042
3043	var buf strings.Builder
3044	buf.WriteString("struct {")
3045	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
3046	sizes := make([]int64, 0, 2*len(dt.Field)+1)
3047	off := int64(0)
3048
3049	// Rename struct fields that happen to be named Go keywords into
3050	// _{keyword}.  Create a map from C ident -> Go ident. The Go ident will
3051	// be mangled. Any existing identifier that already has the same name on
3052	// the C-side will cause the Go-mangled version to be prefixed with _.
3053	// (e.g. in a struct with fields '_type' and 'type', the latter would be
3054	// rendered as '__type' in Go).
3055	ident := make(map[string]string)
3056	used := make(map[string]bool)
3057	for _, f := range dt.Field {
3058		ident[f.Name] = f.Name
3059		used[f.Name] = true
3060	}
3061
3062	if !*godefs {
3063		for cid, goid := range ident {
3064			if token.Lookup(goid).IsKeyword() {
3065				// Avoid keyword
3066				goid = "_" + goid
3067
3068				// Also avoid existing fields
3069				for _, exist := used[goid]; exist; _, exist = used[goid] {
3070					goid = "_" + goid
3071				}
3072
3073				used[goid] = true
3074				ident[cid] = goid
3075			}
3076		}
3077	}
3078
3079	anon := 0
3080	for _, f := range dt.Field {
3081		name := f.Name
3082		ft := f.Type
3083
3084		// In godefs mode, if this field is a C11
3085		// anonymous union then treat the first field in the
3086		// union as the field in the struct. This handles
3087		// cases like the glibc <sys/resource.h> file; see
3088		// issue 6677.
3089		if *godefs {
3090			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
3091				name = st.Field[0].Name
3092				ident[name] = name
3093				ft = st.Field[0].Type
3094			}
3095		}
3096
3097		// TODO: Handle fields that are anonymous structs by
3098		// promoting the fields of the inner struct.
3099
3100		t := c.Type(ft, pos)
3101		tgo := t.Go
3102		size := t.Size
3103		talign := t.Align
3104		if f.BitOffset > 0 || f.BitSize > 0 {
3105			// The layout of bitfields is implementation defined,
3106			// so we don't know how they correspond to Go fields
3107			// even if they are aligned at byte boundaries.
3108			continue
3109		}
3110
3111		if talign > 0 && f.ByteOffset%talign != 0 {
3112			// Drop misaligned fields, the same way we drop integer bit fields.
3113			// The goal is to make available what can be made available.
3114			// Otherwise one bad and unneeded field in an otherwise okay struct
3115			// makes the whole program not compile. Much of the time these
3116			// structs are in system headers that cannot be corrected.
3117			continue
3118		}
3119
3120		// Round off up to talign, assumed to be a power of 2.
3121		origOff := off
3122		off = (off + talign - 1) &^ (talign - 1)
3123
3124		if f.ByteOffset > off {
3125			fld, sizes = c.pad(fld, sizes, f.ByteOffset-origOff)
3126			off = f.ByteOffset
3127		}
3128		if f.ByteOffset < off {
3129			// Drop a packed field that we can't represent.
3130			continue
3131		}
3132
3133		n := len(fld)
3134		fld = fld[0 : n+1]
3135		if name == "" {
3136			name = fmt.Sprintf("anon%d", anon)
3137			anon++
3138			ident[name] = name
3139		}
3140		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
3141		sizes = sizes[0 : n+1]
3142		sizes[n] = size
3143		off += size
3144		buf.WriteString(t.C.String())
3145		buf.WriteString(" ")
3146		buf.WriteString(name)
3147		buf.WriteString("; ")
3148		if talign > align {
3149			align = talign
3150		}
3151	}
3152	if off < dt.ByteSize {
3153		fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
3154		off = dt.ByteSize
3155	}
3156
3157	// If the last field in a non-zero-sized struct is zero-sized
3158	// the compiler is going to pad it by one (see issue 9401).
3159	// We can't permit that, because then the size of the Go
3160	// struct will not be the same as the size of the C struct.
3161	// Our only option in such a case is to remove the field,
3162	// which means that it cannot be referenced from Go.
3163	for off > 0 && sizes[len(sizes)-1] == 0 {
3164		n := len(sizes)
3165		fld = fld[0 : n-1]
3166		sizes = sizes[0 : n-1]
3167	}
3168
3169	if off != dt.ByteSize {
3170		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
3171	}
3172	buf.WriteString("}")
3173	csyntax = buf.String()
3174
3175	if *godefs {
3176		godefsFields(fld)
3177	}
3178	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
3179	return
3180}
3181
3182// dwarfHasPointer reports whether the DWARF type dt contains a pointer.
3183func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
3184	switch dt := dt.(type) {
3185	default:
3186		fatalf("%s: unexpected type: %s", lineno(pos), dt)
3187		return false
3188
3189	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
3190		*dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
3191		*dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
3192
3193		return false
3194
3195	case *dwarf.ArrayType:
3196		return c.dwarfHasPointer(dt.Type, pos)
3197
3198	case *dwarf.PtrType:
3199		return true
3200
3201	case *dwarf.QualType:
3202		return c.dwarfHasPointer(dt.Type, pos)
3203
3204	case *dwarf.StructType:
3205		for _, f := range dt.Field {
3206			if c.dwarfHasPointer(f.Type, pos) {
3207				return true
3208			}
3209		}
3210		return false
3211
3212	case *dwarf.TypedefType:
3213		if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
3214			return true
3215		}
3216		return c.dwarfHasPointer(dt.Type, pos)
3217	}
3218}
3219
3220func upper(s string) string {
3221	if s == "" {
3222		return ""
3223	}
3224	r, size := utf8.DecodeRuneInString(s)
3225	if r == '_' {
3226		return "X" + s
3227	}
3228	return string(unicode.ToUpper(r)) + s[size:]
3229}
3230
3231// godefsFields rewrites field names for use in Go or C definitions.
3232// It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
3233// converts names to upper case, and rewrites _ into Pad_godefs_n,
3234// so that all fields are exported.
3235func godefsFields(fld []*ast.Field) {
3236	prefix := fieldPrefix(fld)
3237
3238	// Issue 48396: check for duplicate field names.
3239	if prefix != "" {
3240		names := make(map[string]bool)
3241	fldLoop:
3242		for _, f := range fld {
3243			for _, n := range f.Names {
3244				name := n.Name
3245				if name == "_" {
3246					continue
3247				}
3248				if name != prefix {
3249					name = strings.TrimPrefix(n.Name, prefix)
3250				}
3251				name = upper(name)
3252				if names[name] {
3253					// Field name conflict: don't remove prefix.
3254					prefix = ""
3255					break fldLoop
3256				}
3257				names[name] = true
3258			}
3259		}
3260	}
3261
3262	npad := 0
3263	for _, f := range fld {
3264		for _, n := range f.Names {
3265			if n.Name != prefix {
3266				n.Name = strings.TrimPrefix(n.Name, prefix)
3267			}
3268			if n.Name == "_" {
3269				// Use exported name instead.
3270				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
3271				npad++
3272			}
3273			n.Name = upper(n.Name)
3274		}
3275	}
3276}
3277
3278// fieldPrefix returns the prefix that should be removed from all the
3279// field names when generating the C or Go code. For generated
3280// C, we leave the names as is (tv_sec, tv_usec), since that's what
3281// people are used to seeing in C.  For generated Go code, such as
3282// package syscall's data structures, we drop a common prefix
3283// (so sec, usec, which will get turned into Sec, Usec for exporting).
3284func fieldPrefix(fld []*ast.Field) string {
3285	prefix := ""
3286	for _, f := range fld {
3287		for _, n := range f.Names {
3288			// Ignore field names that don't have the prefix we're
3289			// looking for. It is common in C headers to have fields
3290			// named, say, _pad in an otherwise prefixed header.
3291			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
3292			// still want to remove the tv_ prefix.
3293			// The check for "orig_" here handles orig_eax in the
3294			// x86 ptrace register sets, which otherwise have all fields
3295			// with reg_ prefixes.
3296			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
3297				continue
3298			}
3299			i := strings.Index(n.Name, "_")
3300			if i < 0 {
3301				continue
3302			}
3303			if prefix == "" {
3304				prefix = n.Name[:i+1]
3305			} else if prefix != n.Name[:i+1] {
3306				return ""
3307			}
3308		}
3309	}
3310	return prefix
3311}
3312
3313// anonymousStructTypedef reports whether dt is a C typedef for an anonymous
3314// struct.
3315func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
3316	st, ok := dt.Type.(*dwarf.StructType)
3317	return ok && st.StructName == ""
3318}
3319
3320// badPointerTypedef reports whether dt is a C typedef that should not be
3321// considered a pointer in Go. A typedef is bad if C code sometimes stores
3322// non-pointers in this type.
3323// TODO: Currently our best solution is to find these manually and list them as
3324// they come up. A better solution is desired.
3325// Note: DEPRECATED. There is now a better solution. Search for incomplete in this file.
3326func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
3327	if c.badCFType(dt) {
3328		return true
3329	}
3330	if c.badJNI(dt) {
3331		return true
3332	}
3333	if c.badEGLType(dt) {
3334		return true
3335	}
3336	return false
3337}
3338
3339// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
3340func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
3341	// Match the Windows HANDLE type (#42018).
3342	if goos != "windows" || dt.Name != "HANDLE" {
3343		return false
3344	}
3345	// Check that the typedef is "typedef void *<name>".
3346	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
3347		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
3348			return true
3349		}
3350	}
3351	return false
3352}
3353
3354// badStructPointerTypedef is like badVoidPointerTypedef but for structs.
3355func (c *typeConv) badStructPointerTypedef(name string, dt *dwarf.StructType) bool {
3356	// Windows handle types can all potentially contain non-pointers.
3357	// badVoidPointerTypedef handles the "void *" HANDLE type, but other
3358	// handles are defined as
3359	//
3360	// struct <name>__{int unused;}; typedef struct <name>__ *name;
3361	//
3362	// by the DECLARE_HANDLE macro in STRICT mode. The macro is declared in
3363	// the Windows ntdef.h header,
3364	//
3365	// https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntdef.h#L779
3366	if goos != "windows" {
3367		return false
3368	}
3369	if len(dt.Field) != 1 {
3370		return false
3371	}
3372	if dt.StructName != name+"__" {
3373		return false
3374	}
3375	if f := dt.Field[0]; f.Name != "unused" || f.Type.Common().Name != "int" {
3376		return false
3377	}
3378	return true
3379}
3380
3381// baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
3382// as badPointerTypedef reports.
3383func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
3384	for {
3385		if t, ok := dt.Type.(*dwarf.TypedefType); ok {
3386			dt = t
3387			continue
3388		}
3389		break
3390	}
3391	return c.badPointerTypedef(dt)
3392}
3393
3394func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
3395	// The real bad types are CFNumberRef and CFDateRef.
3396	// Sometimes non-pointers are stored in these types.
3397	// CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
3398	// We return true for the other *Ref types just so casting between them is easier.
3399	// We identify the correct set of types as those ending in Ref and for which
3400	// there exists a corresponding GetTypeID function.
3401	// See comment below for details about the bad pointers.
3402	if goos != "darwin" && goos != "ios" {
3403		return false
3404	}
3405	s := dt.Name
3406	if !strings.HasSuffix(s, "Ref") {
3407		return false
3408	}
3409	s = s[:len(s)-3]
3410	if s == "CFType" {
3411		return true
3412	}
3413	if c.getTypeIDs[s] {
3414		return true
3415	}
3416	if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
3417		// Mutable and immutable variants share a type ID.
3418		return true
3419	}
3420	return false
3421}
3422
3423// Comment from Darwin's CFInternal.h
3424/*
3425// Tagged pointer support
3426// Low-bit set means tagged object, next 3 bits (currently)
3427// define the tagged object class, next 4 bits are for type
3428// information for the specific tagged object class.  Thus,
3429// the low byte is for type info, and the rest of a pointer
3430// (32 or 64-bit) is for payload, whatever the tagged class.
3431//
3432// Note that the specific integers used to identify the
3433// specific tagged classes can and will change from release
3434// to release (that's why this stuff is in CF*Internal*.h),
3435// as can the definition of type info vs payload above.
3436//
3437#if __LP64__
3438#define CF_IS_TAGGED_OBJ(PTR)	((uintptr_t)(PTR) & 0x1)
3439#define CF_TAGGED_OBJ_TYPE(PTR)	((uintptr_t)(PTR) & 0xF)
3440#else
3441#define CF_IS_TAGGED_OBJ(PTR)	0
3442#define CF_TAGGED_OBJ_TYPE(PTR)	0
3443#endif
3444
3445enum {
3446    kCFTaggedObjectID_Invalid = 0,
3447    kCFTaggedObjectID_Atom = (0 << 1) + 1,
3448    kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
3449    kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
3450    kCFTaggedObjectID_Integer = (3 << 1) + 1,
3451    kCFTaggedObjectID_DateTS = (4 << 1) + 1,
3452    kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
3453    kCFTaggedObjectID_Date = (6 << 1) + 1,
3454    kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
3455};
3456*/
3457
3458func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
3459	// In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
3460	// property that it is sometimes (always?) a small integer instead of a real pointer.
3461	// Note: although only the android JVMs are bad in this respect, we declare the JNI types
3462	// bad regardless of platform, so the same Go code compiles on both android and non-android.
3463	if parent, ok := jniTypes[dt.Name]; ok {
3464		// Try to make sure we're talking about a JNI type, not just some random user's
3465		// type that happens to use the same name.
3466		// C doesn't have the notion of a package, so it's hard to be certain.
3467
3468		// Walk up to jobject, checking each typedef on the way.
3469		w := dt
3470		for parent != "" {
3471			t, ok := w.Type.(*dwarf.TypedefType)
3472			if !ok || t.Name != parent {
3473				return false
3474			}
3475			w = t
3476			parent, ok = jniTypes[w.Name]
3477			if !ok {
3478				return false
3479			}
3480		}
3481
3482		// Check that the typedef is either:
3483		// 1:
3484		//     	struct _jobject;
3485		//     	typedef struct _jobject *jobject;
3486		// 2: (in NDK16 in C++)
3487		//     	class _jobject {};
3488		//     	typedef _jobject* jobject;
3489		// 3: (in NDK16 in C)
3490		//     	typedef void* jobject;
3491		if ptr, ok := w.Type.(*dwarf.PtrType); ok {
3492			switch v := ptr.Type.(type) {
3493			case *dwarf.VoidType:
3494				return true
3495			case *dwarf.StructType:
3496				if v.StructName == "_jobject" && len(v.Field) == 0 {
3497					switch v.Kind {
3498					case "struct":
3499						if v.Incomplete {
3500							return true
3501						}
3502					case "class":
3503						if !v.Incomplete {
3504							return true
3505						}
3506					}
3507				}
3508			}
3509		}
3510	}
3511	return false
3512}
3513
3514func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool {
3515	if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" {
3516		return false
3517	}
3518	// Check that the typedef is "typedef void *<name>".
3519	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
3520		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
3521			return true
3522		}
3523	}
3524	return false
3525}
3526
3527// jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
3528// they are mapped. The base "jobject" maps to the empty string.
3529var jniTypes = map[string]string{
3530	"jobject":       "",
3531	"jclass":        "jobject",
3532	"jthrowable":    "jobject",
3533	"jstring":       "jobject",
3534	"jarray":        "jobject",
3535	"jbooleanArray": "jarray",
3536	"jbyteArray":    "jarray",
3537	"jcharArray":    "jarray",
3538	"jshortArray":   "jarray",
3539	"jintArray":     "jarray",
3540	"jlongArray":    "jarray",
3541	"jfloatArray":   "jarray",
3542	"jdoubleArray":  "jarray",
3543	"jobjectArray":  "jarray",
3544	"jweak":         "jobject",
3545}
3546