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

View as plain text