Source file src/cmd/cgo/gcc.go

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

View as plain text