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

View as plain text