github.com/bir3/gocompiler@v0.3.205/src/cmd/cgo/gcc.go (about)

     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 cgo
     9  
    10  import (
    11  	"bytes"
    12  	"debug/dwarf"
    13  	"debug/elf"
    14  	"debug/macho"
    15  	"debug/pe"
    16  	"encoding/binary"
    17  	"errors"
    18  	"github.com/bir3/gocompiler/src/cmd/cgo/flag"
    19  	"fmt"
    20  	"github.com/bir3/gocompiler/src/go/ast"
    21  	"github.com/bir3/gocompiler/src/go/parser"
    22  	"github.com/bir3/gocompiler/src/go/token"
    23  	"github.com/bir3/gocompiler/src/internal/xcoff"
    24  	"math"
    25  	"os"
    26  	"os/exec"
    27  	"strconv"
    28  	"strings"
    29  	"unicode"
    30  	"unicode/utf8"
    31  
    32  	"github.com/bir3/gocompiler/src/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 {
   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  		fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
   961  		fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d, nil); ", i)
   962  	}
   963  
   964  	if call.Deferred {
   965  		sb.WriteString("return func() { ")
   966  	}
   967  
   968  	// Write out the calls to _cgoCheckPointer.
   969  	sb.WriteString(sbCheck.String())
   970  
   971  	if result {
   972  		sb.WriteString("return ")
   973  	}
   974  
   975  	m, nu := p.mangle(f, &call.Call.Fun, false)
   976  	if nu {
   977  		needsUnsafe = true
   978  	}
   979  	sb.WriteString(gofmtPos(m, end))
   980  
   981  	sb.WriteString("(")
   982  	for i := range params {
   983  		if i > 0 {
   984  			sb.WriteString(", ")
   985  		}
   986  		fmt.Fprintf(&sb, "_cgo%d", i)
   987  	}
   988  	sb.WriteString("); ")
   989  	if call.Deferred {
   990  		sb.WriteString("}")
   991  	}
   992  	sb.WriteString("}")
   993  	if call.Deferred {
   994  		sb.WriteString("()")
   995  	}
   996  	sb.WriteString("()")
   997  
   998  	return sb.String(), needsUnsafe
   999  }
  1000  
  1001  // needsPointerCheck reports whether the type t needs a pointer check.
  1002  // This is true if t is a pointer and if the value to which it points
  1003  // might contain a pointer.
  1004  func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
  1005  	// An untyped nil does not need a pointer check, and when
  1006  	// _cgoCheckPointer returns the untyped nil the type assertion we
  1007  	// are going to insert will fail.  Easier to just skip nil arguments.
  1008  	// TODO: Note that this fails if nil is shadowed.
  1009  	if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
  1010  		return false
  1011  	}
  1012  
  1013  	return p.hasPointer(f, t, true)
  1014  }
  1015  
  1016  // hasPointer is used by needsPointerCheck. If top is true it returns
  1017  // whether t is or contains a pointer that might point to a pointer.
  1018  // If top is false it reports whether t is or contains a pointer.
  1019  // f may be nil.
  1020  func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
  1021  	switch t := t.(type) {
  1022  	case *ast.ArrayType:
  1023  		if t.Len == nil {
  1024  			if !top {
  1025  				return true
  1026  			}
  1027  			return p.hasPointer(f, t.Elt, false)
  1028  		}
  1029  		return p.hasPointer(f, t.Elt, top)
  1030  	case *ast.StructType:
  1031  		for _, field := range t.Fields.List {
  1032  			if p.hasPointer(f, field.Type, top) {
  1033  				return true
  1034  			}
  1035  		}
  1036  		return false
  1037  	case *ast.StarExpr: // Pointer type.
  1038  		if !top {
  1039  			return true
  1040  		}
  1041  		// Check whether this is a pointer to a C union (or class)
  1042  		// type that contains a pointer.
  1043  		if unionWithPointer[t.X] {
  1044  			return true
  1045  		}
  1046  		return p.hasPointer(f, t.X, false)
  1047  	case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
  1048  		return true
  1049  	case *ast.Ident:
  1050  		// TODO: Handle types defined within function.
  1051  		for _, d := range p.Decl {
  1052  			gd, ok := d.(*ast.GenDecl)
  1053  			if !ok || gd.Tok != token.TYPE {
  1054  				continue
  1055  			}
  1056  			for _, spec := range gd.Specs {
  1057  				ts, ok := spec.(*ast.TypeSpec)
  1058  				if !ok {
  1059  					continue
  1060  				}
  1061  				if ts.Name.Name == t.Name {
  1062  					return p.hasPointer(f, ts.Type, top)
  1063  				}
  1064  			}
  1065  		}
  1066  		if def := typedef[t.Name]; def != nil {
  1067  			return p.hasPointer(f, def.Go, top)
  1068  		}
  1069  		if t.Name == "string" {
  1070  			return !top
  1071  		}
  1072  		if t.Name == "error" {
  1073  			return true
  1074  		}
  1075  		if goTypes[t.Name] != nil {
  1076  			return false
  1077  		}
  1078  		// We can't figure out the type. Conservative
  1079  		// approach is to assume it has a pointer.
  1080  		return true
  1081  	case *ast.SelectorExpr:
  1082  		if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
  1083  			// Type defined in a different package.
  1084  			// Conservative approach is to assume it has a
  1085  			// pointer.
  1086  			return true
  1087  		}
  1088  		if f == nil {
  1089  			// Conservative approach: assume pointer.
  1090  			return true
  1091  		}
  1092  		name := f.Name[t.Sel.Name]
  1093  		if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
  1094  			return p.hasPointer(f, name.Type.Go, top)
  1095  		}
  1096  		// We can't figure out the type. Conservative
  1097  		// approach is to assume it has a pointer.
  1098  		return true
  1099  	default:
  1100  		error_(t.Pos(), "could not understand type %s", gofmt(t))
  1101  		return true
  1102  	}
  1103  }
  1104  
  1105  // mangle replaces references to C names in arg with the mangled names,
  1106  // rewriting calls when it finds them.
  1107  // It removes the corresponding references in f.Ref and f.Calls, so that we
  1108  // don't try to do the replacement again in rewriteRef or rewriteCall.
  1109  // If addPosition is true, add position info to the idents of C names in arg.
  1110  func (p *Package) mangle(f *File, arg *ast.Expr, addPosition bool) (ast.Expr, bool) {
  1111  	needsUnsafe := false
  1112  	f.walk(arg, ctxExpr, func(f *File, arg interface{}, context astContext) {
  1113  		px, ok := arg.(*ast.Expr)
  1114  		if !ok {
  1115  			return
  1116  		}
  1117  		sel, ok := (*px).(*ast.SelectorExpr)
  1118  		if ok {
  1119  			if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" {
  1120  				return
  1121  			}
  1122  
  1123  			for _, r := range f.Ref {
  1124  				if r.Expr == px {
  1125  					*px = p.rewriteName(f, r, addPosition)
  1126  					r.Done = true
  1127  					break
  1128  				}
  1129  			}
  1130  
  1131  			return
  1132  		}
  1133  
  1134  		call, ok := (*px).(*ast.CallExpr)
  1135  		if !ok {
  1136  			return
  1137  		}
  1138  
  1139  		for _, c := range f.Calls {
  1140  			if !c.Done && c.Call.Lparen == call.Lparen {
  1141  				cstr, nu := p.rewriteCall(f, c)
  1142  				if cstr != "" {
  1143  					// Smuggle the rewritten call through an ident.
  1144  					*px = ast.NewIdent(cstr)
  1145  					if nu {
  1146  						needsUnsafe = true
  1147  					}
  1148  					c.Done = true
  1149  				}
  1150  			}
  1151  		}
  1152  	})
  1153  	return *arg, needsUnsafe
  1154  }
  1155  
  1156  // checkIndex checks whether arg has the form &a[i], possibly inside
  1157  // type conversions. If so, then in the general case it writes
  1158  //
  1159  //	_cgoIndexNN := a
  1160  //	_cgoNN := &cgoIndexNN[i] // with type conversions, if any
  1161  //
  1162  // to sb, and writes
  1163  //
  1164  //	_cgoCheckPointer(_cgoNN, _cgoIndexNN)
  1165  //
  1166  // to sbCheck, and returns true. If a is a simple variable or field reference,
  1167  // it writes
  1168  //
  1169  //	_cgoIndexNN := &a
  1170  //
  1171  // and dereferences the uses of _cgoIndexNN. Taking the address avoids
  1172  // making a copy of an array.
  1173  //
  1174  // This tells _cgoCheckPointer to check the complete contents of the
  1175  // slice or array being indexed, but no other part of the memory allocation.
  1176  func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
  1177  	// Strip type conversions.
  1178  	x := arg
  1179  	for {
  1180  		c, ok := x.(*ast.CallExpr)
  1181  		if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
  1182  			break
  1183  		}
  1184  		x = c.Args[0]
  1185  	}
  1186  	u, ok := x.(*ast.UnaryExpr)
  1187  	if !ok || u.Op != token.AND {
  1188  		return false
  1189  	}
  1190  	index, ok := u.X.(*ast.IndexExpr)
  1191  	if !ok {
  1192  		return false
  1193  	}
  1194  
  1195  	addr := ""
  1196  	deref := ""
  1197  	if p.isVariable(index.X) {
  1198  		addr = "&"
  1199  		deref = "*"
  1200  	}
  1201  
  1202  	fmt.Fprintf(sb, "_cgoIndex%d := %s%s; ", i, addr, gofmtPos(index.X, index.X.Pos()))
  1203  	origX := index.X
  1204  	index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i))
  1205  	if deref == "*" {
  1206  		index.X = &ast.StarExpr{X: index.X}
  1207  	}
  1208  	fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
  1209  	index.X = origX
  1210  
  1211  	fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i)
  1212  
  1213  	return true
  1214  }
  1215  
  1216  // checkAddr checks whether arg has the form &x, possibly inside type
  1217  // conversions. If so, it writes
  1218  //
  1219  //	_cgoBaseNN := &x
  1220  //	_cgoNN := _cgoBaseNN // with type conversions, if any
  1221  //
  1222  // to sb, and writes
  1223  //
  1224  //	_cgoCheckPointer(_cgoBaseNN, true)
  1225  //
  1226  // to sbCheck, and returns true. This tells _cgoCheckPointer to check
  1227  // just the contents of the pointer being passed, not any other part
  1228  // of the memory allocation. This is run after checkIndex, which looks
  1229  // for the special case of &a[i], which requires different checks.
  1230  func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
  1231  	// Strip type conversions.
  1232  	px := &arg
  1233  	for {
  1234  		c, ok := (*px).(*ast.CallExpr)
  1235  		if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
  1236  			break
  1237  		}
  1238  		px = &c.Args[0]
  1239  	}
  1240  	if u, ok := (*px).(*ast.UnaryExpr); !ok || u.Op != token.AND {
  1241  		return false
  1242  	}
  1243  
  1244  	fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
  1245  
  1246  	origX := *px
  1247  	*px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i))
  1248  	fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
  1249  	*px = origX
  1250  
  1251  	// Use "0 == 0" to do the right thing in the unlikely event
  1252  	// that "true" is shadowed.
  1253  	fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgoBase%d, 0 == 0); ", i)
  1254  
  1255  	return true
  1256  }
  1257  
  1258  // isType reports whether the expression is definitely a type.
  1259  // This is conservative--it returns false for an unknown identifier.
  1260  func (p *Package) isType(t ast.Expr) bool {
  1261  	switch t := t.(type) {
  1262  	case *ast.SelectorExpr:
  1263  		id, ok := t.X.(*ast.Ident)
  1264  		if !ok {
  1265  			return false
  1266  		}
  1267  		if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
  1268  			return true
  1269  		}
  1270  		if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
  1271  			return true
  1272  		}
  1273  		return false
  1274  	case *ast.Ident:
  1275  		// TODO: This ignores shadowing.
  1276  		switch t.Name {
  1277  		case "unsafe.Pointer", "bool", "byte",
  1278  			"complex64", "complex128",
  1279  			"error",
  1280  			"float32", "float64",
  1281  			"int", "int8", "int16", "int32", "int64",
  1282  			"rune", "string",
  1283  			"uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
  1284  
  1285  			return true
  1286  		}
  1287  		if strings.HasPrefix(t.Name, "_Ctype_") {
  1288  			return true
  1289  		}
  1290  	case *ast.ParenExpr:
  1291  		return p.isType(t.X)
  1292  	case *ast.StarExpr:
  1293  		return p.isType(t.X)
  1294  	case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
  1295  		*ast.MapType, *ast.ChanType:
  1296  
  1297  		return true
  1298  	}
  1299  	return false
  1300  }
  1301  
  1302  // isVariable reports whether x is a variable, possibly with field references.
  1303  func (p *Package) isVariable(x ast.Expr) bool {
  1304  	switch x := x.(type) {
  1305  	case *ast.Ident:
  1306  		return true
  1307  	case *ast.SelectorExpr:
  1308  		return p.isVariable(x.X)
  1309  	case *ast.IndexExpr:
  1310  		return true
  1311  	}
  1312  	return false
  1313  }
  1314  
  1315  // rewriteUnsafe returns a version of t with references to unsafe.Pointer
  1316  // rewritten to use _cgo_unsafe.Pointer instead.
  1317  func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
  1318  	switch t := t.(type) {
  1319  	case *ast.Ident:
  1320  		// We don't see a SelectorExpr for unsafe.Pointer;
  1321  		// this is created by code in this file.
  1322  		if t.Name == "unsafe.Pointer" {
  1323  			return ast.NewIdent("_cgo_unsafe.Pointer")
  1324  		}
  1325  	case *ast.ArrayType:
  1326  		t1 := p.rewriteUnsafe(t.Elt)
  1327  		if t1 != t.Elt {
  1328  			r := *t
  1329  			r.Elt = t1
  1330  			return &r
  1331  		}
  1332  	case *ast.StructType:
  1333  		changed := false
  1334  		fields := *t.Fields
  1335  		fields.List = nil
  1336  		for _, f := range t.Fields.List {
  1337  			ft := p.rewriteUnsafe(f.Type)
  1338  			if ft == f.Type {
  1339  				fields.List = append(fields.List, f)
  1340  			} else {
  1341  				fn := *f
  1342  				fn.Type = ft
  1343  				fields.List = append(fields.List, &fn)
  1344  				changed = true
  1345  			}
  1346  		}
  1347  		if changed {
  1348  			r := *t
  1349  			r.Fields = &fields
  1350  			return &r
  1351  		}
  1352  	case *ast.StarExpr: // Pointer type.
  1353  		x1 := p.rewriteUnsafe(t.X)
  1354  		if x1 != t.X {
  1355  			r := *t
  1356  			r.X = x1
  1357  			return &r
  1358  		}
  1359  	}
  1360  	return t
  1361  }
  1362  
  1363  // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
  1364  // Go equivalents, now that we have figured out the meaning of all
  1365  // the xxx. In *godefs mode, rewriteRef replaces the names
  1366  // with full definitions instead of mangled names.
  1367  func (p *Package) rewriteRef(f *File) {
  1368  	// Keep a list of all the functions, to remove the ones
  1369  	// only used as expressions and avoid generating bridge
  1370  	// code for them.
  1371  	functions := make(map[string]bool)
  1372  
  1373  	for _, n := range f.Name {
  1374  		if n.Kind == "func" {
  1375  			functions[n.Go] = false
  1376  		}
  1377  	}
  1378  
  1379  	// Now that we have all the name types filled in,
  1380  	// scan through the Refs to identify the ones that
  1381  	// are trying to do a ,err call. Also check that
  1382  	// functions are only used in calls.
  1383  	for _, r := range f.Ref {
  1384  		if r.Name.IsConst() && r.Name.Const == "" {
  1385  			error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
  1386  		}
  1387  
  1388  		if r.Name.Kind == "func" {
  1389  			switch r.Context {
  1390  			case ctxCall, ctxCall2:
  1391  				functions[r.Name.Go] = true
  1392  			}
  1393  		}
  1394  
  1395  		expr := p.rewriteName(f, r, false)
  1396  
  1397  		if *godefs {
  1398  			// Substitute definition for mangled type name.
  1399  			if r.Name.Type != nil && r.Name.Kind == "type" {
  1400  				expr = r.Name.Type.Go
  1401  			}
  1402  			if id, ok := expr.(*ast.Ident); ok {
  1403  				if t := typedef[id.Name]; t != nil {
  1404  					expr = t.Go
  1405  				}
  1406  				if id.Name == r.Name.Mangle && r.Name.Const != "" {
  1407  					expr = ast.NewIdent(r.Name.Const)
  1408  				}
  1409  			}
  1410  		}
  1411  
  1412  		// Copy position information from old expr into new expr,
  1413  		// in case expression being replaced is first on line.
  1414  		// See golang.org/issue/6563.
  1415  		pos := (*r.Expr).Pos()
  1416  		if x, ok := expr.(*ast.Ident); ok {
  1417  			expr = &ast.Ident{NamePos: pos, Name: x.Name}
  1418  		}
  1419  
  1420  		// Change AST, because some later processing depends on it,
  1421  		// and also because -godefs mode still prints the AST.
  1422  		old := *r.Expr
  1423  		*r.Expr = expr
  1424  
  1425  		// Record source-level edit for cgo output.
  1426  		if !r.Done {
  1427  			// Prepend a space in case the earlier code ends
  1428  			// with '/', which would give us a "//" comment.
  1429  			repl := " " + gofmtPos(expr, old.Pos())
  1430  			end := fset.Position(old.End())
  1431  			// Subtract 1 from the column if we are going to
  1432  			// append a close parenthesis. That will set the
  1433  			// correct column for the following characters.
  1434  			sub := 0
  1435  			if r.Name.Kind != "type" {
  1436  				sub = 1
  1437  			}
  1438  			if end.Column > sub {
  1439  				repl = fmt.Sprintf("%s /*line :%d:%d*/", repl, end.Line, end.Column-sub)
  1440  			}
  1441  			if r.Name.Kind != "type" {
  1442  				repl = "(" + repl + ")"
  1443  			}
  1444  			f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
  1445  		}
  1446  	}
  1447  
  1448  	// Remove functions only used as expressions, so their respective
  1449  	// bridge functions are not generated.
  1450  	for name, used := range functions {
  1451  		if !used {
  1452  			delete(f.Name, name)
  1453  		}
  1454  	}
  1455  }
  1456  
  1457  // rewriteName returns the expression used to rewrite a reference.
  1458  // If addPosition is true, add position info in the ident name.
  1459  func (p *Package) rewriteName(f *File, r *Ref, addPosition bool) ast.Expr {
  1460  	getNewIdent := ast.NewIdent
  1461  	if addPosition {
  1462  		getNewIdent = func(newName string) *ast.Ident {
  1463  			mangledIdent := ast.NewIdent(newName)
  1464  			if len(newName) == len(r.Name.Go) {
  1465  				return mangledIdent
  1466  			}
  1467  			p := fset.Position((*r.Expr).End())
  1468  			if p.Column == 0 {
  1469  				return mangledIdent
  1470  			}
  1471  			return ast.NewIdent(fmt.Sprintf("%s /*line :%d:%d*/", newName, p.Line, p.Column))
  1472  		}
  1473  	}
  1474  	var expr ast.Expr = getNewIdent(r.Name.Mangle) // default
  1475  	switch r.Context {
  1476  	case ctxCall, ctxCall2:
  1477  		if r.Name.Kind != "func" {
  1478  			if r.Name.Kind == "type" {
  1479  				r.Context = ctxType
  1480  				if r.Name.Type == nil {
  1481  					error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
  1482  				}
  1483  				break
  1484  			}
  1485  			error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
  1486  			break
  1487  		}
  1488  		if r.Context == ctxCall2 {
  1489  			if r.Name.Go == "_CMalloc" {
  1490  				error_(r.Pos(), "no two-result form for C.malloc")
  1491  				break
  1492  			}
  1493  			// Invent new Name for the two-result function.
  1494  			n := f.Name["2"+r.Name.Go]
  1495  			if n == nil {
  1496  				n = new(Name)
  1497  				*n = *r.Name
  1498  				n.AddError = true
  1499  				n.Mangle = "_C2func_" + n.Go
  1500  				f.Name["2"+r.Name.Go] = n
  1501  			}
  1502  			expr = getNewIdent(n.Mangle)
  1503  			r.Name = n
  1504  			break
  1505  		}
  1506  	case ctxExpr:
  1507  		switch r.Name.Kind {
  1508  		case "func":
  1509  			if builtinDefs[r.Name.C] != "" {
  1510  				error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
  1511  			}
  1512  
  1513  			// Function is being used in an expression, to e.g. pass around a C function pointer.
  1514  			// Create a new Name for this Ref which causes the variable to be declared in Go land.
  1515  			fpName := "fp_" + r.Name.Go
  1516  			name := f.Name[fpName]
  1517  			if name == nil {
  1518  				name = &Name{
  1519  					Go:   fpName,
  1520  					C:    r.Name.C,
  1521  					Kind: "fpvar",
  1522  					Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
  1523  				}
  1524  				p.mangleName(name)
  1525  				f.Name[fpName] = name
  1526  			}
  1527  			r.Name = name
  1528  			// Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
  1529  			// function is defined in out.go and simply returns its argument. See
  1530  			// issue 7757.
  1531  			expr = &ast.CallExpr{
  1532  				Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
  1533  				Args: []ast.Expr{getNewIdent(name.Mangle)},
  1534  			}
  1535  		case "type":
  1536  			// Okay - might be new(T), T(x), Generic[T], etc.
  1537  			if r.Name.Type == nil {
  1538  				error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
  1539  			}
  1540  		case "var":
  1541  			expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
  1542  		case "macro":
  1543  			expr = &ast.CallExpr{Fun: expr}
  1544  		}
  1545  	case ctxSelector:
  1546  		if r.Name.Kind == "var" {
  1547  			expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
  1548  		} else {
  1549  			error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
  1550  		}
  1551  	case ctxType:
  1552  		if r.Name.Kind != "type" {
  1553  			error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
  1554  		} else if r.Name.Type == nil {
  1555  			// Use of C.enum_x, C.struct_x or C.union_x without C definition.
  1556  			// GCC won't raise an error when using pointers to such unknown types.
  1557  			error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
  1558  		}
  1559  	default:
  1560  		if r.Name.Kind == "func" {
  1561  			error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
  1562  		}
  1563  	}
  1564  	return expr
  1565  }
  1566  
  1567  // gofmtPos returns the gofmt-formatted string for an AST node,
  1568  // with a comment setting the position before the node.
  1569  func gofmtPos(n ast.Expr, pos token.Pos) string {
  1570  	s := gofmtLine(n)
  1571  	p := fset.Position(pos)
  1572  	if p.Column == 0 {
  1573  		return s
  1574  	}
  1575  	return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s)
  1576  }
  1577  
  1578  // checkGCCBaseCmd returns the start of the compiler command line.
  1579  // It uses $CC if set, or else $GCC, or else the compiler recorded
  1580  // during the initial build as defaultCC.
  1581  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  1582  //
  1583  // The compiler command line is split into arguments on whitespace. Quotes
  1584  // are understood, so arguments may contain whitespace.
  1585  //
  1586  // checkGCCBaseCmd confirms that the compiler exists in PATH, returning
  1587  // an error if it does not.
  1588  func checkGCCBaseCmd() ([]string, error) {
  1589  	// Use $CC if set, since that's what the build uses.
  1590  	value := os.Getenv("CC")
  1591  	if value == "" {
  1592  		// Try $GCC if set, since that's what we used to use.
  1593  		value = os.Getenv("GCC")
  1594  	}
  1595  	if value == "" {
  1596  		value = defaultCC(goos, goarch)
  1597  	}
  1598  	args, err := quoted.Split(value)
  1599  	if err != nil {
  1600  		return nil, err
  1601  	}
  1602  	if len(args) == 0 {
  1603  		return nil, errors.New("CC not set and no default found")
  1604  	}
  1605  	if _, err := exec.LookPath(args[0]); err != nil {
  1606  		return nil, fmt.Errorf("C compiler %q not found: %v", args[0], err)
  1607  	}
  1608  	return args[:len(args):len(args)], nil
  1609  }
  1610  
  1611  // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
  1612  func (p *Package) gccMachine() []string {
  1613  	switch goarch {
  1614  	case "amd64":
  1615  		if goos == "darwin" {
  1616  			return []string{"-arch", "x86_64", "-m64"}
  1617  		}
  1618  		return []string{"-m64"}
  1619  	case "arm64":
  1620  		if goos == "darwin" {
  1621  			return []string{"-arch", "arm64"}
  1622  		}
  1623  	case "386":
  1624  		return []string{"-m32"}
  1625  	case "arm":
  1626  		return []string{"-marm"} // not thumb
  1627  	case "s390":
  1628  		return []string{"-m31"}
  1629  	case "s390x":
  1630  		return []string{"-m64"}
  1631  	case "mips64", "mips64le":
  1632  		if gomips64 == "hardfloat" {
  1633  			return []string{"-mabi=64", "-mhard-float"}
  1634  		} else if gomips64 == "softfloat" {
  1635  			return []string{"-mabi=64", "-msoft-float"}
  1636  		}
  1637  	case "mips", "mipsle":
  1638  		if gomips == "hardfloat" {
  1639  			return []string{"-mabi=32", "-mfp32", "-mhard-float", "-mno-odd-spreg"}
  1640  		} else if gomips == "softfloat" {
  1641  			return []string{"-mabi=32", "-msoft-float"}
  1642  		}
  1643  	case "loong64":
  1644  		return []string{"-mabi=lp64d"}
  1645  	}
  1646  	return nil
  1647  }
  1648  
  1649  func gccTmp() string {
  1650  	return *objDir + "_cgo_.o"
  1651  }
  1652  
  1653  // gccCmd returns the gcc command line to use for compiling
  1654  // the input.
  1655  func (p *Package) gccCmd() []string {
  1656  	c := append(gccBaseCmd,
  1657  		"-w",          // no warnings
  1658  		"-Wno-error",  // warnings are not errors
  1659  		"-o"+gccTmp(), // write object to tmp
  1660  		"-gdwarf-2",   // generate DWARF v2 debugging symbols
  1661  		"-c",          // do not link
  1662  		"-xc",         // input language is C
  1663  	)
  1664  	if p.GccIsClang {
  1665  		c = append(c,
  1666  			"-ferror-limit=0",
  1667  			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
  1668  			// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
  1669  			// flag to disable the warning. Yes, really good diagnostics, clang.
  1670  			"-Wno-unknown-warning-option",
  1671  			"-Wno-unneeded-internal-declaration",
  1672  			"-Wno-unused-function",
  1673  			"-Qunused-arguments",
  1674  			// Clang embeds prototypes for some builtin functions,
  1675  			// like malloc and calloc, but all size_t parameters are
  1676  			// incorrectly typed unsigned long. We work around that
  1677  			// by disabling the builtin functions (this is safe as
  1678  			// it won't affect the actual compilation of the C code).
  1679  			// See: https://golang.org/issue/6506.
  1680  			"-fno-builtin",
  1681  		)
  1682  	}
  1683  
  1684  	c = append(c, p.GccOptions...)
  1685  	c = append(c, p.gccMachine()...)
  1686  	if goos == "aix" {
  1687  		c = append(c, "-maix64")
  1688  		c = append(c, "-mcmodel=large")
  1689  	}
  1690  	// disable LTO so we get an object whose symbols we can read
  1691  	c = append(c, "-fno-lto")
  1692  	c = append(c, "-") //read input from standard input
  1693  	return c
  1694  }
  1695  
  1696  // gccDebug runs gcc -gdwarf-2 over the C program stdin and
  1697  // returns the corresponding DWARF data and, if present, debug data block.
  1698  func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
  1699  	runGcc(stdin, p.gccCmd())
  1700  
  1701  	isDebugInts := func(s string) bool {
  1702  		// Some systems use leading _ to denote non-assembly symbols.
  1703  		return s == "__cgodebug_ints" || s == "___cgodebug_ints"
  1704  	}
  1705  	isDebugFloats := func(s string) bool {
  1706  		// Some systems use leading _ to denote non-assembly symbols.
  1707  		return s == "__cgodebug_floats" || s == "___cgodebug_floats"
  1708  	}
  1709  	indexOfDebugStr := func(s string) int {
  1710  		// Some systems use leading _ to denote non-assembly symbols.
  1711  		if strings.HasPrefix(s, "___") {
  1712  			s = s[1:]
  1713  		}
  1714  		if strings.HasPrefix(s, "__cgodebug_str__") {
  1715  			if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
  1716  				return n
  1717  			}
  1718  		}
  1719  		return -1
  1720  	}
  1721  	indexOfDebugStrlen := func(s string) int {
  1722  		// Some systems use leading _ to denote non-assembly symbols.
  1723  		if strings.HasPrefix(s, "___") {
  1724  			s = s[1:]
  1725  		}
  1726  		if strings.HasPrefix(s, "__cgodebug_strlen__") {
  1727  			if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
  1728  				return n
  1729  			}
  1730  		}
  1731  		return -1
  1732  	}
  1733  
  1734  	strs = make([]string, nnames)
  1735  
  1736  	strdata := make(map[int]string, nnames)
  1737  	strlens := make(map[int]int, nnames)
  1738  
  1739  	buildStrings := func() {
  1740  		for n, strlen := range strlens {
  1741  			data := strdata[n]
  1742  			if len(data) <= strlen {
  1743  				fatalf("invalid string literal")
  1744  			}
  1745  			strs[n] = data[:strlen]
  1746  		}
  1747  	}
  1748  
  1749  	if f, err := macho.Open(gccTmp()); err == nil {
  1750  		defer f.Close()
  1751  		d, err := f.DWARF()
  1752  		if err != nil {
  1753  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  1754  		}
  1755  		bo := f.ByteOrder
  1756  		if f.Symtab != nil {
  1757  			for i := range f.Symtab.Syms {
  1758  				s := &f.Symtab.Syms[i]
  1759  				switch {
  1760  				case isDebugInts(s.Name):
  1761  					// Found it. Now find data section.
  1762  					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1763  						sect := f.Sections[i]
  1764  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1765  							if sdat, err := sect.Data(); err == nil {
  1766  								data := sdat[s.Value-sect.Addr:]
  1767  								ints = make([]int64, len(data)/8)
  1768  								for i := range ints {
  1769  									ints[i] = int64(bo.Uint64(data[i*8:]))
  1770  								}
  1771  							}
  1772  						}
  1773  					}
  1774  				case isDebugFloats(s.Name):
  1775  					// Found it. Now find data section.
  1776  					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1777  						sect := f.Sections[i]
  1778  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1779  							if sdat, err := sect.Data(); err == nil {
  1780  								data := sdat[s.Value-sect.Addr:]
  1781  								floats = make([]float64, len(data)/8)
  1782  								for i := range floats {
  1783  									floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
  1784  								}
  1785  							}
  1786  						}
  1787  					}
  1788  				default:
  1789  					if n := indexOfDebugStr(s.Name); n != -1 {
  1790  						// Found it. Now find data section.
  1791  						if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1792  							sect := f.Sections[i]
  1793  							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1794  								if sdat, err := sect.Data(); err == nil {
  1795  									data := sdat[s.Value-sect.Addr:]
  1796  									strdata[n] = string(data)
  1797  								}
  1798  							}
  1799  						}
  1800  						break
  1801  					}
  1802  					if n := indexOfDebugStrlen(s.Name); n != -1 {
  1803  						// Found it. Now find data section.
  1804  						if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
  1805  							sect := f.Sections[i]
  1806  							if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
  1807  								if sdat, err := sect.Data(); err == nil {
  1808  									data := sdat[s.Value-sect.Addr:]
  1809  									strlen := bo.Uint64(data[:8])
  1810  									if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  1811  										fatalf("string literal too big")
  1812  									}
  1813  									strlens[n] = int(strlen)
  1814  								}
  1815  							}
  1816  						}
  1817  						break
  1818  					}
  1819  				}
  1820  			}
  1821  
  1822  			buildStrings()
  1823  		}
  1824  		return d, ints, floats, strs
  1825  	}
  1826  
  1827  	if f, err := elf.Open(gccTmp()); err == nil {
  1828  		defer f.Close()
  1829  		d, err := f.DWARF()
  1830  		if err != nil {
  1831  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  1832  		}
  1833  		bo := f.ByteOrder
  1834  		symtab, err := f.Symbols()
  1835  		if err == nil {
  1836  			// Check for use of -fsanitize=hwaddress (issue 53285).
  1837  			removeTag := func(v uint64) uint64 { return v }
  1838  			if goarch == "arm64" {
  1839  				for i := range symtab {
  1840  					if symtab[i].Name == "__hwasan_init" {
  1841  						// -fsanitize=hwaddress on ARM
  1842  						// uses the upper byte of a
  1843  						// memory address as a hardware
  1844  						// tag. Remove it so that
  1845  						// we can find the associated
  1846  						// data.
  1847  						removeTag = func(v uint64) uint64 { return v &^ (0xff << (64 - 8)) }
  1848  						break
  1849  					}
  1850  				}
  1851  			}
  1852  
  1853  			for i := range symtab {
  1854  				s := &symtab[i]
  1855  				switch {
  1856  				case isDebugInts(s.Name):
  1857  					// Found it. Now find data section.
  1858  					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1859  						sect := f.Sections[i]
  1860  						val := removeTag(s.Value)
  1861  						if sect.Addr <= val && val < sect.Addr+sect.Size {
  1862  							if sdat, err := sect.Data(); err == nil {
  1863  								data := sdat[val-sect.Addr:]
  1864  								ints = make([]int64, len(data)/8)
  1865  								for i := range ints {
  1866  									ints[i] = int64(bo.Uint64(data[i*8:]))
  1867  								}
  1868  							}
  1869  						}
  1870  					}
  1871  				case isDebugFloats(s.Name):
  1872  					// Found it. Now find data section.
  1873  					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1874  						sect := f.Sections[i]
  1875  						val := removeTag(s.Value)
  1876  						if sect.Addr <= val && val < sect.Addr+sect.Size {
  1877  							if sdat, err := sect.Data(); err == nil {
  1878  								data := sdat[val-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.Section); 0 <= i && i < len(f.Sections) {
  1890  							sect := f.Sections[i]
  1891  							val := removeTag(s.Value)
  1892  							if sect.Addr <= val && val < sect.Addr+sect.Size {
  1893  								if sdat, err := sect.Data(); err == nil {
  1894  									data := sdat[val-sect.Addr:]
  1895  									strdata[n] = string(data)
  1896  								}
  1897  							}
  1898  						}
  1899  						break
  1900  					}
  1901  					if n := indexOfDebugStrlen(s.Name); n != -1 {
  1902  						// Found it. Now find data section.
  1903  						if i := int(s.Section); 0 <= i && i < len(f.Sections) {
  1904  							sect := f.Sections[i]
  1905  							val := removeTag(s.Value)
  1906  							if sect.Addr <= val && val < sect.Addr+sect.Size {
  1907  								if sdat, err := sect.Data(); err == nil {
  1908  									data := sdat[val-sect.Addr:]
  1909  									strlen := bo.Uint64(data[:8])
  1910  									if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  1911  										fatalf("string literal too big")
  1912  									}
  1913  									strlens[n] = int(strlen)
  1914  								}
  1915  							}
  1916  						}
  1917  						break
  1918  					}
  1919  				}
  1920  			}
  1921  
  1922  			buildStrings()
  1923  		}
  1924  		return d, ints, floats, strs
  1925  	}
  1926  
  1927  	if f, err := pe.Open(gccTmp()); err == nil {
  1928  		defer f.Close()
  1929  		d, err := f.DWARF()
  1930  		if err != nil {
  1931  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  1932  		}
  1933  		bo := binary.LittleEndian
  1934  		for _, s := range f.Symbols {
  1935  			switch {
  1936  			case isDebugInts(s.Name):
  1937  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1938  					sect := f.Sections[i]
  1939  					if s.Value < sect.Size {
  1940  						if sdat, err := sect.Data(); err == nil {
  1941  							data := sdat[s.Value:]
  1942  							ints = make([]int64, len(data)/8)
  1943  							for i := range ints {
  1944  								ints[i] = int64(bo.Uint64(data[i*8:]))
  1945  							}
  1946  						}
  1947  					}
  1948  				}
  1949  			case isDebugFloats(s.Name):
  1950  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1951  					sect := f.Sections[i]
  1952  					if s.Value < sect.Size {
  1953  						if sdat, err := sect.Data(); err == nil {
  1954  							data := sdat[s.Value:]
  1955  							floats = make([]float64, len(data)/8)
  1956  							for i := range floats {
  1957  								floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
  1958  							}
  1959  						}
  1960  					}
  1961  				}
  1962  			default:
  1963  				if n := indexOfDebugStr(s.Name); n != -1 {
  1964  					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1965  						sect := f.Sections[i]
  1966  						if s.Value < sect.Size {
  1967  							if sdat, err := sect.Data(); err == nil {
  1968  								data := sdat[s.Value:]
  1969  								strdata[n] = string(data)
  1970  							}
  1971  						}
  1972  					}
  1973  					break
  1974  				}
  1975  				if n := indexOfDebugStrlen(s.Name); n != -1 {
  1976  					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  1977  						sect := f.Sections[i]
  1978  						if s.Value < sect.Size {
  1979  							if sdat, err := sect.Data(); err == nil {
  1980  								data := sdat[s.Value:]
  1981  								strlen := bo.Uint64(data[:8])
  1982  								if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  1983  									fatalf("string literal too big")
  1984  								}
  1985  								strlens[n] = int(strlen)
  1986  							}
  1987  						}
  1988  					}
  1989  					break
  1990  				}
  1991  			}
  1992  		}
  1993  
  1994  		buildStrings()
  1995  
  1996  		return d, ints, floats, strs
  1997  	}
  1998  
  1999  	if f, err := xcoff.Open(gccTmp()); err == nil {
  2000  		defer f.Close()
  2001  		d, err := f.DWARF()
  2002  		if err != nil {
  2003  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
  2004  		}
  2005  		bo := binary.BigEndian
  2006  		for _, s := range f.Symbols {
  2007  			switch {
  2008  			case isDebugInts(s.Name):
  2009  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  2010  					sect := f.Sections[i]
  2011  					if s.Value < sect.Size {
  2012  						if sdat, err := sect.Data(); err == nil {
  2013  							data := sdat[s.Value:]
  2014  							ints = make([]int64, len(data)/8)
  2015  							for i := range ints {
  2016  								ints[i] = int64(bo.Uint64(data[i*8:]))
  2017  							}
  2018  						}
  2019  					}
  2020  				}
  2021  			case isDebugFloats(s.Name):
  2022  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  2023  					sect := f.Sections[i]
  2024  					if s.Value < sect.Size {
  2025  						if sdat, err := sect.Data(); err == nil {
  2026  							data := sdat[s.Value:]
  2027  							floats = make([]float64, len(data)/8)
  2028  							for i := range floats {
  2029  								floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
  2030  							}
  2031  						}
  2032  					}
  2033  				}
  2034  			default:
  2035  				if n := indexOfDebugStr(s.Name); n != -1 {
  2036  					if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
  2037  						sect := f.Sections[i]
  2038  						if s.Value < sect.Size {
  2039  							if sdat, err := sect.Data(); err == nil {
  2040  								data := sdat[s.Value:]
  2041  								strdata[n] = string(data)
  2042  							}
  2043  						}
  2044  					}
  2045  					break
  2046  				}
  2047  				if n := indexOfDebugStrlen(s.Name); n != -1 {
  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  								strlen := bo.Uint64(data[:8])
  2054  								if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
  2055  									fatalf("string literal too big")
  2056  								}
  2057  								strlens[n] = int(strlen)
  2058  							}
  2059  						}
  2060  					}
  2061  					break
  2062  				}
  2063  			}
  2064  		}
  2065  
  2066  		buildStrings()
  2067  		return d, ints, floats, strs
  2068  	}
  2069  	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
  2070  	panic("not reached")
  2071  }
  2072  
  2073  // gccDefines runs gcc -E -dM -xc - over the C program stdin
  2074  // and returns the corresponding standard output, which is the
  2075  // #defines that gcc encountered while processing the input
  2076  // and its included files.
  2077  func (p *Package) gccDefines(stdin []byte) string {
  2078  	base := append(gccBaseCmd, "-E", "-dM", "-xc")
  2079  	base = append(base, p.gccMachine()...)
  2080  	stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
  2081  	return stdout
  2082  }
  2083  
  2084  // gccErrors runs gcc over the C program stdin and returns
  2085  // the errors that gcc prints. That is, this function expects
  2086  // gcc to fail.
  2087  func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string {
  2088  	// TODO(rsc): require failure
  2089  	args := p.gccCmd()
  2090  
  2091  	// Optimization options can confuse the error messages; remove them.
  2092  	nargs := make([]string, 0, len(args)+len(extraArgs))
  2093  	for _, arg := range args {
  2094  		if !strings.HasPrefix(arg, "-O") {
  2095  			nargs = append(nargs, arg)
  2096  		}
  2097  	}
  2098  
  2099  	// Force -O0 optimization and append extra arguments, but keep the
  2100  	// trailing "-" at the end.
  2101  	li := len(nargs) - 1
  2102  	last := nargs[li]
  2103  	nargs[li] = "-O0"
  2104  	nargs = append(nargs, extraArgs...)
  2105  	nargs = append(nargs, last)
  2106  
  2107  	if *debugGcc {
  2108  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
  2109  		os.Stderr.Write(stdin)
  2110  		fmt.Fprint(os.Stderr, "EOF\n")
  2111  	}
  2112  	stdout, stderr, _ := run(stdin, nargs)
  2113  	if *debugGcc {
  2114  		os.Stderr.Write(stdout)
  2115  		os.Stderr.Write(stderr)
  2116  	}
  2117  	return string(stderr)
  2118  }
  2119  
  2120  // runGcc runs the gcc command line args with stdin on standard input.
  2121  // If the command exits with a non-zero exit status, runGcc prints
  2122  // details about what was run and exits.
  2123  // Otherwise runGcc returns the data written to standard output and standard error.
  2124  // Note that for some of the uses we expect useful data back
  2125  // on standard error, but for those uses gcc must still exit 0.
  2126  func runGcc(stdin []byte, args []string) (string, string) {
  2127  	if *debugGcc {
  2128  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
  2129  		os.Stderr.Write(stdin)
  2130  		fmt.Fprint(os.Stderr, "EOF\n")
  2131  	}
  2132  	stdout, stderr, ok := run(stdin, args)
  2133  	if *debugGcc {
  2134  		os.Stderr.Write(stdout)
  2135  		os.Stderr.Write(stderr)
  2136  	}
  2137  	if !ok {
  2138  		os.Stderr.Write(stderr)
  2139  		os.Exit(2)
  2140  	}
  2141  	return string(stdout), string(stderr)
  2142  }
  2143  
  2144  // A typeConv is a translator from dwarf types to Go types
  2145  // with equivalent memory layout.
  2146  type typeConv struct {
  2147  	// Cache of already-translated or in-progress types.
  2148  	m map[string]*Type
  2149  
  2150  	// Map from types to incomplete pointers to those types.
  2151  	ptrs map[string][]*Type
  2152  	// Keys of ptrs in insertion order (deterministic worklist)
  2153  	// ptrKeys contains exactly the keys in ptrs.
  2154  	ptrKeys []dwarf.Type
  2155  
  2156  	// Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
  2157  	getTypeIDs map[string]bool
  2158  
  2159  	// incompleteStructs contains C structs that should be marked Incomplete.
  2160  	incompleteStructs map[string]bool
  2161  
  2162  	// Predeclared types.
  2163  	bool                                   ast.Expr
  2164  	byte                                   ast.Expr // denotes padding
  2165  	int8, int16, int32, int64              ast.Expr
  2166  	uint8, uint16, uint32, uint64, uintptr ast.Expr
  2167  	float32, float64                       ast.Expr
  2168  	complex64, complex128                  ast.Expr
  2169  	void                                   ast.Expr
  2170  	string                                 ast.Expr
  2171  	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
  2172  	goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
  2173  
  2174  	ptrSize int64
  2175  	intSize int64
  2176  }
  2177  
  2178  var tagGen int
  2179  var typedef = make(map[string]*Type)
  2180  var goIdent = make(map[string]*ast.Ident)
  2181  
  2182  // unionWithPointer is true for a Go type that represents a C union (or class)
  2183  // that may contain a pointer. This is used for cgo pointer checking.
  2184  var unionWithPointer = make(map[ast.Expr]bool)
  2185  
  2186  // anonymousStructTag provides a consistent tag for an anonymous struct.
  2187  // The same dwarf.StructType pointer will always get the same tag.
  2188  var anonymousStructTag = make(map[*dwarf.StructType]string)
  2189  
  2190  func (c *typeConv) Init(ptrSize, intSize int64) {
  2191  	c.ptrSize = ptrSize
  2192  	c.intSize = intSize
  2193  	c.m = make(map[string]*Type)
  2194  	c.ptrs = make(map[string][]*Type)
  2195  	c.getTypeIDs = make(map[string]bool)
  2196  	c.incompleteStructs = make(map[string]bool)
  2197  	c.bool = c.Ident("bool")
  2198  	c.byte = c.Ident("byte")
  2199  	c.int8 = c.Ident("int8")
  2200  	c.int16 = c.Ident("int16")
  2201  	c.int32 = c.Ident("int32")
  2202  	c.int64 = c.Ident("int64")
  2203  	c.uint8 = c.Ident("uint8")
  2204  	c.uint16 = c.Ident("uint16")
  2205  	c.uint32 = c.Ident("uint32")
  2206  	c.uint64 = c.Ident("uint64")
  2207  	c.uintptr = c.Ident("uintptr")
  2208  	c.float32 = c.Ident("float32")
  2209  	c.float64 = c.Ident("float64")
  2210  	c.complex64 = c.Ident("complex64")
  2211  	c.complex128 = c.Ident("complex128")
  2212  	c.void = c.Ident("void")
  2213  	c.string = c.Ident("string")
  2214  	c.goVoid = c.Ident("_Ctype_void")
  2215  
  2216  	// Normally cgo translates void* to unsafe.Pointer,
  2217  	// but for historical reasons -godefs uses *byte instead.
  2218  	if *godefs {
  2219  		c.goVoidPtr = &ast.StarExpr{X: c.byte}
  2220  	} else {
  2221  		c.goVoidPtr = c.Ident("unsafe.Pointer")
  2222  	}
  2223  }
  2224  
  2225  // base strips away qualifiers and typedefs to get the underlying type.
  2226  func base(dt dwarf.Type) dwarf.Type {
  2227  	for {
  2228  		if d, ok := dt.(*dwarf.QualType); ok {
  2229  			dt = d.Type
  2230  			continue
  2231  		}
  2232  		if d, ok := dt.(*dwarf.TypedefType); ok {
  2233  			dt = d.Type
  2234  			continue
  2235  		}
  2236  		break
  2237  	}
  2238  	return dt
  2239  }
  2240  
  2241  // unqual strips away qualifiers from a DWARF type.
  2242  // In general we don't care about top-level qualifiers.
  2243  func unqual(dt dwarf.Type) dwarf.Type {
  2244  	for {
  2245  		if d, ok := dt.(*dwarf.QualType); ok {
  2246  			dt = d.Type
  2247  		} else {
  2248  			break
  2249  		}
  2250  	}
  2251  	return dt
  2252  }
  2253  
  2254  // Map from dwarf text names to aliases we use in package "C".
  2255  var dwarfToName = map[string]string{
  2256  	"long int":               "long",
  2257  	"long unsigned int":      "ulong",
  2258  	"unsigned int":           "uint",
  2259  	"short unsigned int":     "ushort",
  2260  	"unsigned short":         "ushort", // Used by Clang; issue 13129.
  2261  	"short int":              "short",
  2262  	"long long int":          "longlong",
  2263  	"long long unsigned int": "ulonglong",
  2264  	"signed char":            "schar",
  2265  	"unsigned char":          "uchar",
  2266  	"unsigned long":          "ulong",     // Used by Clang 14; issue 53013.
  2267  	"unsigned long long":     "ulonglong", // Used by Clang 14; issue 53013.
  2268  }
  2269  
  2270  const signedDelta = 64
  2271  
  2272  // String returns the current type representation. Format arguments
  2273  // are assembled within this method so that any changes in mutable
  2274  // values are taken into account.
  2275  func (tr *TypeRepr) String() string {
  2276  	if len(tr.Repr) == 0 {
  2277  		return ""
  2278  	}
  2279  	if len(tr.FormatArgs) == 0 {
  2280  		return tr.Repr
  2281  	}
  2282  	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
  2283  }
  2284  
  2285  // Empty reports whether the result of String would be "".
  2286  func (tr *TypeRepr) Empty() bool {
  2287  	return len(tr.Repr) == 0
  2288  }
  2289  
  2290  // Set modifies the type representation.
  2291  // If fargs are provided, repr is used as a format for fmt.Sprintf.
  2292  // Otherwise, repr is used unprocessed as the type representation.
  2293  func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
  2294  	tr.Repr = repr
  2295  	tr.FormatArgs = fargs
  2296  }
  2297  
  2298  // FinishType completes any outstanding type mapping work.
  2299  // In particular, it resolves incomplete pointer types.
  2300  func (c *typeConv) FinishType(pos token.Pos) {
  2301  	// Completing one pointer type might produce more to complete.
  2302  	// Keep looping until they're all done.
  2303  	for len(c.ptrKeys) > 0 {
  2304  		dtype := c.ptrKeys[0]
  2305  		dtypeKey := dtype.String()
  2306  		c.ptrKeys = c.ptrKeys[1:]
  2307  		ptrs := c.ptrs[dtypeKey]
  2308  		delete(c.ptrs, dtypeKey)
  2309  
  2310  		// Note Type might invalidate c.ptrs[dtypeKey].
  2311  		t := c.Type(dtype, pos)
  2312  		for _, ptr := range ptrs {
  2313  			ptr.Go.(*ast.StarExpr).X = t.Go
  2314  			ptr.C.Set("%s*", t.C)
  2315  		}
  2316  	}
  2317  }
  2318  
  2319  // Type returns a *Type with the same memory layout as
  2320  // dtype when used as the type of a variable or a struct field.
  2321  func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
  2322  	return c.loadType(dtype, pos, "")
  2323  }
  2324  
  2325  // loadType recursively loads the requested dtype and its dependency graph.
  2326  func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Type {
  2327  	// Always recompute bad pointer typedefs, as the set of such
  2328  	// typedefs changes as we see more types.
  2329  	checkCache := true
  2330  	if dtt, ok := dtype.(*dwarf.TypedefType); ok && c.badPointerTypedef(dtt) {
  2331  		checkCache = false
  2332  	}
  2333  
  2334  	// The cache key should be relative to its parent.
  2335  	// See issue https://golang.org/issue/31891
  2336  	key := parent + " > " + dtype.String()
  2337  
  2338  	if checkCache {
  2339  		if t, ok := c.m[key]; ok {
  2340  			if t.Go == nil {
  2341  				fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
  2342  			}
  2343  			return t
  2344  		}
  2345  	}
  2346  
  2347  	t := new(Type)
  2348  	t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
  2349  	t.Align = -1
  2350  	t.C = &TypeRepr{Repr: dtype.Common().Name}
  2351  	c.m[key] = t
  2352  
  2353  	switch dt := dtype.(type) {
  2354  	default:
  2355  		fatalf("%s: unexpected type: %s", lineno(pos), dtype)
  2356  
  2357  	case *dwarf.AddrType:
  2358  		if t.Size != c.ptrSize {
  2359  			fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
  2360  		}
  2361  		t.Go = c.uintptr
  2362  		t.Align = t.Size
  2363  
  2364  	case *dwarf.ArrayType:
  2365  		if dt.StrideBitSize > 0 {
  2366  			// Cannot represent bit-sized elements in Go.
  2367  			t.Go = c.Opaque(t.Size)
  2368  			break
  2369  		}
  2370  		count := dt.Count
  2371  		if count == -1 {
  2372  			// Indicates flexible array member, which Go doesn't support.
  2373  			// Translate to zero-length array instead.
  2374  			count = 0
  2375  		}
  2376  		sub := c.Type(dt.Type, pos)
  2377  		t.Align = sub.Align
  2378  		t.Go = &ast.ArrayType{
  2379  			Len: c.intExpr(count),
  2380  			Elt: sub.Go,
  2381  		}
  2382  		// Recalculate t.Size now that we know sub.Size.
  2383  		t.Size = count * sub.Size
  2384  		t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
  2385  
  2386  	case *dwarf.BoolType:
  2387  		t.Go = c.bool
  2388  		t.Align = 1
  2389  
  2390  	case *dwarf.CharType:
  2391  		if t.Size != 1 {
  2392  			fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
  2393  		}
  2394  		t.Go = c.int8
  2395  		t.Align = 1
  2396  
  2397  	case *dwarf.EnumType:
  2398  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2399  			t.Align = c.ptrSize
  2400  		}
  2401  		t.C.Set("enum " + dt.EnumName)
  2402  		signed := 0
  2403  		t.EnumValues = make(map[string]int64)
  2404  		for _, ev := range dt.Val {
  2405  			t.EnumValues[ev.Name] = ev.Val
  2406  			if ev.Val < 0 {
  2407  				signed = signedDelta
  2408  			}
  2409  		}
  2410  		switch t.Size + int64(signed) {
  2411  		default:
  2412  			fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
  2413  		case 1:
  2414  			t.Go = c.uint8
  2415  		case 2:
  2416  			t.Go = c.uint16
  2417  		case 4:
  2418  			t.Go = c.uint32
  2419  		case 8:
  2420  			t.Go = c.uint64
  2421  		case 1 + signedDelta:
  2422  			t.Go = c.int8
  2423  		case 2 + signedDelta:
  2424  			t.Go = c.int16
  2425  		case 4 + signedDelta:
  2426  			t.Go = c.int32
  2427  		case 8 + signedDelta:
  2428  			t.Go = c.int64
  2429  		}
  2430  
  2431  	case *dwarf.FloatType:
  2432  		switch t.Size {
  2433  		default:
  2434  			fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
  2435  		case 4:
  2436  			t.Go = c.float32
  2437  		case 8:
  2438  			t.Go = c.float64
  2439  		}
  2440  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2441  			t.Align = c.ptrSize
  2442  		}
  2443  
  2444  	case *dwarf.ComplexType:
  2445  		switch t.Size {
  2446  		default:
  2447  			fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
  2448  		case 8:
  2449  			t.Go = c.complex64
  2450  		case 16:
  2451  			t.Go = c.complex128
  2452  		}
  2453  		if t.Align = t.Size / 2; t.Align >= c.ptrSize {
  2454  			t.Align = c.ptrSize
  2455  		}
  2456  
  2457  	case *dwarf.FuncType:
  2458  		// No attempt at translation: would enable calls
  2459  		// directly between worlds, but we need to moderate those.
  2460  		t.Go = c.uintptr
  2461  		t.Align = c.ptrSize
  2462  
  2463  	case *dwarf.IntType:
  2464  		if dt.BitSize > 0 {
  2465  			fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
  2466  		}
  2467  		switch t.Size {
  2468  		default:
  2469  			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
  2470  		case 1:
  2471  			t.Go = c.int8
  2472  		case 2:
  2473  			t.Go = c.int16
  2474  		case 4:
  2475  			t.Go = c.int32
  2476  		case 8:
  2477  			t.Go = c.int64
  2478  		case 16:
  2479  			t.Go = &ast.ArrayType{
  2480  				Len: c.intExpr(t.Size),
  2481  				Elt: c.uint8,
  2482  			}
  2483  		}
  2484  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2485  			t.Align = c.ptrSize
  2486  		}
  2487  
  2488  	case *dwarf.PtrType:
  2489  		// Clang doesn't emit DW_AT_byte_size for pointer types.
  2490  		if t.Size != c.ptrSize && t.Size != -1 {
  2491  			fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
  2492  		}
  2493  		t.Size = c.ptrSize
  2494  		t.Align = c.ptrSize
  2495  
  2496  		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
  2497  			t.Go = c.goVoidPtr
  2498  			t.C.Set("void*")
  2499  			dq := dt.Type
  2500  			for {
  2501  				if d, ok := dq.(*dwarf.QualType); ok {
  2502  					t.C.Set(d.Qual + " " + t.C.String())
  2503  					dq = d.Type
  2504  				} else {
  2505  					break
  2506  				}
  2507  			}
  2508  			break
  2509  		}
  2510  
  2511  		// Placeholder initialization; completed in FinishType.
  2512  		t.Go = &ast.StarExpr{}
  2513  		t.C.Set("<incomplete>*")
  2514  		key := dt.Type.String()
  2515  		if _, ok := c.ptrs[key]; !ok {
  2516  			c.ptrKeys = append(c.ptrKeys, dt.Type)
  2517  		}
  2518  		c.ptrs[key] = append(c.ptrs[key], t)
  2519  
  2520  	case *dwarf.QualType:
  2521  		t1 := c.Type(dt.Type, pos)
  2522  		t.Size = t1.Size
  2523  		t.Align = t1.Align
  2524  		t.Go = t1.Go
  2525  		if unionWithPointer[t1.Go] {
  2526  			unionWithPointer[t.Go] = true
  2527  		}
  2528  		t.EnumValues = nil
  2529  		t.Typedef = ""
  2530  		t.C.Set("%s "+dt.Qual, t1.C)
  2531  		return t
  2532  
  2533  	case *dwarf.StructType:
  2534  		// Convert to Go struct, being careful about alignment.
  2535  		// Have to give it a name to simulate C "struct foo" references.
  2536  		tag := dt.StructName
  2537  		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
  2538  			break
  2539  		}
  2540  		if tag == "" {
  2541  			tag = anonymousStructTag[dt]
  2542  			if tag == "" {
  2543  				tag = "__" + strconv.Itoa(tagGen)
  2544  				tagGen++
  2545  				anonymousStructTag[dt] = tag
  2546  			}
  2547  		} else if t.C.Empty() {
  2548  			t.C.Set(dt.Kind + " " + tag)
  2549  		}
  2550  		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
  2551  		t.Go = name // publish before recursive calls
  2552  		goIdent[name.Name] = name
  2553  		if dt.ByteSize < 0 {
  2554  			// Don't override old type
  2555  			if _, ok := typedef[name.Name]; ok {
  2556  				break
  2557  			}
  2558  
  2559  			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
  2560  			// so execute the basic things that the struct case would do
  2561  			// other than try to determine a Go representation.
  2562  			tt := *t
  2563  			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
  2564  			// We don't know what the representation of this struct is, so don't let
  2565  			// anyone allocate one on the Go side. As a side effect of this annotation,
  2566  			// pointers to this type will not be considered pointers in Go. They won't
  2567  			// get writebarrier-ed or adjusted during a stack copy. This should handle
  2568  			// all the cases badPointerTypedef used to handle, but hopefully will
  2569  			// continue to work going forward without any more need for cgo changes.
  2570  			tt.Go = c.Ident(incomplete)
  2571  			typedef[name.Name] = &tt
  2572  			break
  2573  		}
  2574  		switch dt.Kind {
  2575  		case "class", "union":
  2576  			t.Go = c.Opaque(t.Size)
  2577  			if c.dwarfHasPointer(dt, pos) {
  2578  				unionWithPointer[t.Go] = true
  2579  			}
  2580  			if t.C.Empty() {
  2581  				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
  2582  			}
  2583  			t.Align = 1 // TODO: should probably base this on field alignment.
  2584  			typedef[name.Name] = t
  2585  		case "struct":
  2586  			g, csyntax, align := c.Struct(dt, pos)
  2587  			if t.C.Empty() {
  2588  				t.C.Set(csyntax)
  2589  			}
  2590  			t.Align = align
  2591  			tt := *t
  2592  			if tag != "" {
  2593  				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
  2594  			}
  2595  			tt.Go = g
  2596  			if c.incompleteStructs[tag] {
  2597  				tt.Go = c.Ident(incomplete)
  2598  			}
  2599  			typedef[name.Name] = &tt
  2600  		}
  2601  
  2602  	case *dwarf.TypedefType:
  2603  		// Record typedef for printing.
  2604  		if dt.Name == "_GoString_" {
  2605  			// Special C name for Go string type.
  2606  			// Knows string layout used by compilers: pointer plus length,
  2607  			// which rounds up to 2 pointers after alignment.
  2608  			t.Go = c.string
  2609  			t.Size = c.ptrSize * 2
  2610  			t.Align = c.ptrSize
  2611  			break
  2612  		}
  2613  		if dt.Name == "_GoBytes_" {
  2614  			// Special C name for Go []byte type.
  2615  			// Knows slice layout used by compilers: pointer, length, cap.
  2616  			t.Go = c.Ident("[]byte")
  2617  			t.Size = c.ptrSize + 4 + 4
  2618  			t.Align = c.ptrSize
  2619  			break
  2620  		}
  2621  		name := c.Ident("_Ctype_" + dt.Name)
  2622  		goIdent[name.Name] = name
  2623  		akey := ""
  2624  		if c.anonymousStructTypedef(dt) {
  2625  			// only load type recursively for typedefs of anonymous
  2626  			// structs, see issues 37479 and 37621.
  2627  			akey = key
  2628  		}
  2629  		sub := c.loadType(dt.Type, pos, akey)
  2630  		if c.badPointerTypedef(dt) {
  2631  			// Treat this typedef as a uintptr.
  2632  			s := *sub
  2633  			s.Go = c.uintptr
  2634  			s.BadPointer = true
  2635  			sub = &s
  2636  			// Make sure we update any previously computed type.
  2637  			if oldType := typedef[name.Name]; oldType != nil {
  2638  				oldType.Go = sub.Go
  2639  				oldType.BadPointer = true
  2640  			}
  2641  		}
  2642  		if c.badVoidPointerTypedef(dt) {
  2643  			// Treat this typedef as a pointer to a _cgopackage.Incomplete.
  2644  			s := *sub
  2645  			s.Go = c.Ident("*" + incomplete)
  2646  			sub = &s
  2647  			// Make sure we update any previously computed type.
  2648  			if oldType := typedef[name.Name]; oldType != nil {
  2649  				oldType.Go = sub.Go
  2650  			}
  2651  		}
  2652  		// Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
  2653  		// typedefs that should be marked Incomplete.
  2654  		if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
  2655  			if strct, ok := ptr.Type.(*dwarf.StructType); ok {
  2656  				if c.badStructPointerTypedef(dt.Name, strct) {
  2657  					c.incompleteStructs[strct.StructName] = true
  2658  					// Make sure we update any previously computed type.
  2659  					name := "_Ctype_struct_" + strct.StructName
  2660  					if oldType := typedef[name]; oldType != nil {
  2661  						oldType.Go = c.Ident(incomplete)
  2662  					}
  2663  				}
  2664  			}
  2665  		}
  2666  		t.Go = name
  2667  		t.BadPointer = sub.BadPointer
  2668  		if unionWithPointer[sub.Go] {
  2669  			unionWithPointer[t.Go] = true
  2670  		}
  2671  		t.Size = sub.Size
  2672  		t.Align = sub.Align
  2673  		oldType := typedef[name.Name]
  2674  		if oldType == nil {
  2675  			tt := *t
  2676  			tt.Go = sub.Go
  2677  			tt.BadPointer = sub.BadPointer
  2678  			typedef[name.Name] = &tt
  2679  		}
  2680  
  2681  		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
  2682  		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
  2683  		// with the base type.
  2684  		// In -godefs mode, do this for all typedefs.
  2685  		if isStructUnionClass(sub.Go) || *godefs {
  2686  			t.Go = sub.Go
  2687  
  2688  			if isStructUnionClass(sub.Go) {
  2689  				// Use the typedef name for C code.
  2690  				typedef[sub.Go.(*ast.Ident).Name].C = t.C
  2691  			}
  2692  
  2693  			// If we've seen this typedef before, and it
  2694  			// was an anonymous struct/union/class before
  2695  			// too, use the old definition.
  2696  			// TODO: it would be safer to only do this if
  2697  			// we verify that the types are the same.
  2698  			if oldType != nil && isStructUnionClass(oldType.Go) {
  2699  				t.Go = oldType.Go
  2700  			}
  2701  		}
  2702  
  2703  	case *dwarf.UcharType:
  2704  		if t.Size != 1 {
  2705  			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
  2706  		}
  2707  		t.Go = c.uint8
  2708  		t.Align = 1
  2709  
  2710  	case *dwarf.UintType:
  2711  		if dt.BitSize > 0 {
  2712  			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
  2713  		}
  2714  		switch t.Size {
  2715  		default:
  2716  			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
  2717  		case 1:
  2718  			t.Go = c.uint8
  2719  		case 2:
  2720  			t.Go = c.uint16
  2721  		case 4:
  2722  			t.Go = c.uint32
  2723  		case 8:
  2724  			t.Go = c.uint64
  2725  		case 16:
  2726  			t.Go = &ast.ArrayType{
  2727  				Len: c.intExpr(t.Size),
  2728  				Elt: c.uint8,
  2729  			}
  2730  		}
  2731  		if t.Align = t.Size; t.Align >= c.ptrSize {
  2732  			t.Align = c.ptrSize
  2733  		}
  2734  
  2735  	case *dwarf.VoidType:
  2736  		t.Go = c.goVoid
  2737  		t.C.Set("void")
  2738  		t.Align = 1
  2739  	}
  2740  
  2741  	switch dtype.(type) {
  2742  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
  2743  		s := dtype.Common().Name
  2744  		if s != "" {
  2745  			if ss, ok := dwarfToName[s]; ok {
  2746  				s = ss
  2747  			}
  2748  			s = strings.Replace(s, " ", "", -1)
  2749  			name := c.Ident("_Ctype_" + s)
  2750  			tt := *t
  2751  			typedef[name.Name] = &tt
  2752  			if !*godefs {
  2753  				t.Go = name
  2754  			}
  2755  		}
  2756  	}
  2757  
  2758  	if t.Size < 0 {
  2759  		// Unsized types are [0]byte, unless they're typedefs of other types
  2760  		// or structs with tags.
  2761  		// if so, use the name we've already defined.
  2762  		t.Size = 0
  2763  		switch dt := dtype.(type) {
  2764  		case *dwarf.TypedefType:
  2765  			// ok
  2766  		case *dwarf.StructType:
  2767  			if dt.StructName != "" {
  2768  				break
  2769  			}
  2770  			t.Go = c.Opaque(0)
  2771  		default:
  2772  			t.Go = c.Opaque(0)
  2773  		}
  2774  		if t.C.Empty() {
  2775  			t.C.Set("void")
  2776  		}
  2777  	}
  2778  
  2779  	if t.C.Empty() {
  2780  		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
  2781  	}
  2782  
  2783  	return t
  2784  }
  2785  
  2786  // isStructUnionClass reports whether the type described by the Go syntax x
  2787  // is a struct, union, or class with a tag.
  2788  func isStructUnionClass(x ast.Expr) bool {
  2789  	id, ok := x.(*ast.Ident)
  2790  	if !ok {
  2791  		return false
  2792  	}
  2793  	name := id.Name
  2794  	return strings.HasPrefix(name, "_Ctype_struct_") ||
  2795  		strings.HasPrefix(name, "_Ctype_union_") ||
  2796  		strings.HasPrefix(name, "_Ctype_class_")
  2797  }
  2798  
  2799  // FuncArg returns a Go type with the same memory layout as
  2800  // dtype when used as the type of a C function argument.
  2801  func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
  2802  	t := c.Type(unqual(dtype), pos)
  2803  	switch dt := dtype.(type) {
  2804  	case *dwarf.ArrayType:
  2805  		// Arrays are passed implicitly as pointers in C.
  2806  		// In Go, we must be explicit.
  2807  		tr := &TypeRepr{}
  2808  		tr.Set("%s*", t.C)
  2809  		return &Type{
  2810  			Size:  c.ptrSize,
  2811  			Align: c.ptrSize,
  2812  			Go:    &ast.StarExpr{X: t.Go},
  2813  			C:     tr,
  2814  		}
  2815  	case *dwarf.TypedefType:
  2816  		// C has much more relaxed rules than Go for
  2817  		// implicit type conversions. When the parameter
  2818  		// is type T defined as *X, simulate a little of the
  2819  		// laxness of C by making the argument *X instead of T.
  2820  		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
  2821  			// Unless the typedef happens to point to void* since
  2822  			// Go has special rules around using unsafe.Pointer.
  2823  			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
  2824  				break
  2825  			}
  2826  			// ...or the typedef is one in which we expect bad pointers.
  2827  			// It will be a uintptr instead of *X.
  2828  			if c.baseBadPointerTypedef(dt) {
  2829  				break
  2830  			}
  2831  
  2832  			t = c.Type(ptr, pos)
  2833  			if t == nil {
  2834  				return nil
  2835  			}
  2836  
  2837  			// For a struct/union/class, remember the C spelling,
  2838  			// in case it has __attribute__((unavailable)).
  2839  			// See issue 2888.
  2840  			if isStructUnionClass(t.Go) {
  2841  				t.Typedef = dt.Name
  2842  			}
  2843  		}
  2844  	}
  2845  	return t
  2846  }
  2847  
  2848  // FuncType returns the Go type analogous to dtype.
  2849  // There is no guarantee about matching memory layout.
  2850  func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
  2851  	p := make([]*Type, len(dtype.ParamType))
  2852  	gp := make([]*ast.Field, len(dtype.ParamType))
  2853  	for i, f := range dtype.ParamType {
  2854  		// gcc's DWARF generator outputs a single DotDotDotType parameter for
  2855  		// function pointers that specify no parameters (e.g. void
  2856  		// (*__cgo_0)()).  Treat this special case as void. This case is
  2857  		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
  2858  		// legal).
  2859  		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
  2860  			p, gp = nil, nil
  2861  			break
  2862  		}
  2863  		p[i] = c.FuncArg(f, pos)
  2864  		gp[i] = &ast.Field{Type: p[i].Go}
  2865  	}
  2866  	var r *Type
  2867  	var gr []*ast.Field
  2868  	if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
  2869  		gr = []*ast.Field{{Type: c.goVoid}}
  2870  	} else if dtype.ReturnType != nil {
  2871  		r = c.Type(unqual(dtype.ReturnType), pos)
  2872  		gr = []*ast.Field{{Type: r.Go}}
  2873  	}
  2874  	return &FuncType{
  2875  		Params: p,
  2876  		Result: r,
  2877  		Go: &ast.FuncType{
  2878  			Params:  &ast.FieldList{List: gp},
  2879  			Results: &ast.FieldList{List: gr},
  2880  		},
  2881  	}
  2882  }
  2883  
  2884  // Identifier
  2885  func (c *typeConv) Ident(s string) *ast.Ident {
  2886  	return ast.NewIdent(s)
  2887  }
  2888  
  2889  // Opaque type of n bytes.
  2890  func (c *typeConv) Opaque(n int64) ast.Expr {
  2891  	return &ast.ArrayType{
  2892  		Len: c.intExpr(n),
  2893  		Elt: c.byte,
  2894  	}
  2895  }
  2896  
  2897  // Expr for integer n.
  2898  func (c *typeConv) intExpr(n int64) ast.Expr {
  2899  	return &ast.BasicLit{
  2900  		Kind:  token.INT,
  2901  		Value: strconv.FormatInt(n, 10),
  2902  	}
  2903  }
  2904  
  2905  // Add padding of given size to fld.
  2906  func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
  2907  	n := len(fld)
  2908  	fld = fld[0 : n+1]
  2909  	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
  2910  	sizes = sizes[0 : n+1]
  2911  	sizes[n] = size
  2912  	return fld, sizes
  2913  }
  2914  
  2915  // Struct conversion: return Go and (gc) C syntax for type.
  2916  func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
  2917  	// Minimum alignment for a struct is 1 byte.
  2918  	align = 1
  2919  
  2920  	var buf strings.Builder
  2921  	buf.WriteString("struct {")
  2922  	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
  2923  	sizes := make([]int64, 0, 2*len(dt.Field)+1)
  2924  	off := int64(0)
  2925  
  2926  	// Rename struct fields that happen to be named Go keywords into
  2927  	// _{keyword}.  Create a map from C ident -> Go ident. The Go ident will
  2928  	// be mangled. Any existing identifier that already has the same name on
  2929  	// the C-side will cause the Go-mangled version to be prefixed with _.
  2930  	// (e.g. in a struct with fields '_type' and 'type', the latter would be
  2931  	// rendered as '__type' in Go).
  2932  	ident := make(map[string]string)
  2933  	used := make(map[string]bool)
  2934  	for _, f := range dt.Field {
  2935  		ident[f.Name] = f.Name
  2936  		used[f.Name] = true
  2937  	}
  2938  
  2939  	if !*godefs {
  2940  		for cid, goid := range ident {
  2941  			if token.Lookup(goid).IsKeyword() {
  2942  				// Avoid keyword
  2943  				goid = "_" + goid
  2944  
  2945  				// Also avoid existing fields
  2946  				for _, exist := used[goid]; exist; _, exist = used[goid] {
  2947  					goid = "_" + goid
  2948  				}
  2949  
  2950  				used[goid] = true
  2951  				ident[cid] = goid
  2952  			}
  2953  		}
  2954  	}
  2955  
  2956  	anon := 0
  2957  	for _, f := range dt.Field {
  2958  		name := f.Name
  2959  		ft := f.Type
  2960  
  2961  		// In godefs mode, if this field is a C11
  2962  		// anonymous union then treat the first field in the
  2963  		// union as the field in the struct. This handles
  2964  		// cases like the glibc <sys/resource.h> file; see
  2965  		// issue 6677.
  2966  		if *godefs {
  2967  			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
  2968  				name = st.Field[0].Name
  2969  				ident[name] = name
  2970  				ft = st.Field[0].Type
  2971  			}
  2972  		}
  2973  
  2974  		// TODO: Handle fields that are anonymous structs by
  2975  		// promoting the fields of the inner struct.
  2976  
  2977  		t := c.Type(ft, pos)
  2978  		tgo := t.Go
  2979  		size := t.Size
  2980  		talign := t.Align
  2981  		if f.BitOffset > 0 || f.BitSize > 0 {
  2982  			// The layout of bitfields is implementation defined,
  2983  			// so we don't know how they correspond to Go fields
  2984  			// even if they are aligned at byte boundaries.
  2985  			continue
  2986  		}
  2987  
  2988  		if talign > 0 && f.ByteOffset%talign != 0 {
  2989  			// Drop misaligned fields, the same way we drop integer bit fields.
  2990  			// The goal is to make available what can be made available.
  2991  			// Otherwise one bad and unneeded field in an otherwise okay struct
  2992  			// makes the whole program not compile. Much of the time these
  2993  			// structs are in system headers that cannot be corrected.
  2994  			continue
  2995  		}
  2996  
  2997  		// Round off up to talign, assumed to be a power of 2.
  2998  		off = (off + talign - 1) &^ (talign - 1)
  2999  
  3000  		if f.ByteOffset > off {
  3001  			fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
  3002  			off = f.ByteOffset
  3003  		}
  3004  		if f.ByteOffset < off {
  3005  			// Drop a packed field that we can't represent.
  3006  			continue
  3007  		}
  3008  
  3009  		n := len(fld)
  3010  		fld = fld[0 : n+1]
  3011  		if name == "" {
  3012  			name = fmt.Sprintf("anon%d", anon)
  3013  			anon++
  3014  			ident[name] = name
  3015  		}
  3016  		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
  3017  		sizes = sizes[0 : n+1]
  3018  		sizes[n] = size
  3019  		off += size
  3020  		buf.WriteString(t.C.String())
  3021  		buf.WriteString(" ")
  3022  		buf.WriteString(name)
  3023  		buf.WriteString("; ")
  3024  		if talign > align {
  3025  			align = talign
  3026  		}
  3027  	}
  3028  	if off < dt.ByteSize {
  3029  		fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
  3030  		off = dt.ByteSize
  3031  	}
  3032  
  3033  	// If the last field in a non-zero-sized struct is zero-sized
  3034  	// the compiler is going to pad it by one (see issue 9401).
  3035  	// We can't permit that, because then the size of the Go
  3036  	// struct will not be the same as the size of the C struct.
  3037  	// Our only option in such a case is to remove the field,
  3038  	// which means that it cannot be referenced from Go.
  3039  	for off > 0 && sizes[len(sizes)-1] == 0 {
  3040  		n := len(sizes)
  3041  		fld = fld[0 : n-1]
  3042  		sizes = sizes[0 : n-1]
  3043  	}
  3044  
  3045  	if off != dt.ByteSize {
  3046  		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
  3047  	}
  3048  	buf.WriteString("}")
  3049  	csyntax = buf.String()
  3050  
  3051  	if *godefs {
  3052  		godefsFields(fld)
  3053  	}
  3054  	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
  3055  	return
  3056  }
  3057  
  3058  // dwarfHasPointer reports whether the DWARF type dt contains a pointer.
  3059  func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
  3060  	switch dt := dt.(type) {
  3061  	default:
  3062  		fatalf("%s: unexpected type: %s", lineno(pos), dt)
  3063  		return false
  3064  
  3065  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
  3066  		*dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
  3067  		*dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
  3068  
  3069  		return false
  3070  
  3071  	case *dwarf.ArrayType:
  3072  		return c.dwarfHasPointer(dt.Type, pos)
  3073  
  3074  	case *dwarf.PtrType:
  3075  		return true
  3076  
  3077  	case *dwarf.QualType:
  3078  		return c.dwarfHasPointer(dt.Type, pos)
  3079  
  3080  	case *dwarf.StructType:
  3081  		for _, f := range dt.Field {
  3082  			if c.dwarfHasPointer(f.Type, pos) {
  3083  				return true
  3084  			}
  3085  		}
  3086  		return false
  3087  
  3088  	case *dwarf.TypedefType:
  3089  		if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
  3090  			return true
  3091  		}
  3092  		return c.dwarfHasPointer(dt.Type, pos)
  3093  	}
  3094  }
  3095  
  3096  func upper(s string) string {
  3097  	if s == "" {
  3098  		return ""
  3099  	}
  3100  	r, size := utf8.DecodeRuneInString(s)
  3101  	if r == '_' {
  3102  		return "X" + s
  3103  	}
  3104  	return string(unicode.ToUpper(r)) + s[size:]
  3105  }
  3106  
  3107  // godefsFields rewrites field names for use in Go or C definitions.
  3108  // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
  3109  // converts names to upper case, and rewrites _ into Pad_godefs_n,
  3110  // so that all fields are exported.
  3111  func godefsFields(fld []*ast.Field) {
  3112  	prefix := fieldPrefix(fld)
  3113  
  3114  	// Issue 48396: check for duplicate field names.
  3115  	if prefix != "" {
  3116  		names := make(map[string]bool)
  3117  	fldLoop:
  3118  		for _, f := range fld {
  3119  			for _, n := range f.Names {
  3120  				name := n.Name
  3121  				if name == "_" {
  3122  					continue
  3123  				}
  3124  				if name != prefix {
  3125  					name = strings.TrimPrefix(n.Name, prefix)
  3126  				}
  3127  				name = upper(name)
  3128  				if names[name] {
  3129  					// Field name conflict: don't remove prefix.
  3130  					prefix = ""
  3131  					break fldLoop
  3132  				}
  3133  				names[name] = true
  3134  			}
  3135  		}
  3136  	}
  3137  
  3138  	npad := 0
  3139  	for _, f := range fld {
  3140  		for _, n := range f.Names {
  3141  			if n.Name != prefix {
  3142  				n.Name = strings.TrimPrefix(n.Name, prefix)
  3143  			}
  3144  			if n.Name == "_" {
  3145  				// Use exported name instead.
  3146  				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
  3147  				npad++
  3148  			}
  3149  			n.Name = upper(n.Name)
  3150  		}
  3151  	}
  3152  }
  3153  
  3154  // fieldPrefix returns the prefix that should be removed from all the
  3155  // field names when generating the C or Go code. For generated
  3156  // C, we leave the names as is (tv_sec, tv_usec), since that's what
  3157  // people are used to seeing in C.  For generated Go code, such as
  3158  // package syscall's data structures, we drop a common prefix
  3159  // (so sec, usec, which will get turned into Sec, Usec for exporting).
  3160  func fieldPrefix(fld []*ast.Field) string {
  3161  	prefix := ""
  3162  	for _, f := range fld {
  3163  		for _, n := range f.Names {
  3164  			// Ignore field names that don't have the prefix we're
  3165  			// looking for. It is common in C headers to have fields
  3166  			// named, say, _pad in an otherwise prefixed header.
  3167  			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
  3168  			// still want to remove the tv_ prefix.
  3169  			// The check for "orig_" here handles orig_eax in the
  3170  			// x86 ptrace register sets, which otherwise have all fields
  3171  			// with reg_ prefixes.
  3172  			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
  3173  				continue
  3174  			}
  3175  			i := strings.Index(n.Name, "_")
  3176  			if i < 0 {
  3177  				continue
  3178  			}
  3179  			if prefix == "" {
  3180  				prefix = n.Name[:i+1]
  3181  			} else if prefix != n.Name[:i+1] {
  3182  				return ""
  3183  			}
  3184  		}
  3185  	}
  3186  	return prefix
  3187  }
  3188  
  3189  // anonymousStructTypedef reports whether dt is a C typedef for an anonymous
  3190  // struct.
  3191  func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
  3192  	st, ok := dt.Type.(*dwarf.StructType)
  3193  	return ok && st.StructName == ""
  3194  }
  3195  
  3196  // badPointerTypedef reports whether dt is a C typedef that should not be
  3197  // considered a pointer in Go. A typedef is bad if C code sometimes stores
  3198  // non-pointers in this type.
  3199  // TODO: Currently our best solution is to find these manually and list them as
  3200  // they come up. A better solution is desired.
  3201  // Note: DEPRECATED. There is now a better solution. Search for incomplete in this file.
  3202  func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
  3203  	if c.badCFType(dt) {
  3204  		return true
  3205  	}
  3206  	if c.badJNI(dt) {
  3207  		return true
  3208  	}
  3209  	if c.badEGLType(dt) {
  3210  		return true
  3211  	}
  3212  	return false
  3213  }
  3214  
  3215  // badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
  3216  func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
  3217  	// Match the Windows HANDLE type (#42018).
  3218  	if goos != "windows" || dt.Name != "HANDLE" {
  3219  		return false
  3220  	}
  3221  	// Check that the typedef is "typedef void *<name>".
  3222  	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
  3223  		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
  3224  			return true
  3225  		}
  3226  	}
  3227  	return false
  3228  }
  3229  
  3230  // badStructPointerTypedef is like badVoidPointerTypedefs but for structs.
  3231  func (c *typeConv) badStructPointerTypedef(name string, dt *dwarf.StructType) bool {
  3232  	// Windows handle types can all potentially contain non-pointers.
  3233  	// badVoidPointerTypedef handles the "void *" HANDLE type, but other
  3234  	// handles are defined as
  3235  	//
  3236  	// struct <name>__{int unused;}; typedef struct <name>__ *name;
  3237  	//
  3238  	// by the DECLARE_HANDLE macro in STRICT mode. The macro is declared in
  3239  	// the Windows ntdef.h header,
  3240  	//
  3241  	// https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntdef.h#L779
  3242  	if goos != "windows" {
  3243  		return false
  3244  	}
  3245  	if len(dt.Field) != 1 {
  3246  		return false
  3247  	}
  3248  	if dt.StructName != name+"__" {
  3249  		return false
  3250  	}
  3251  	if f := dt.Field[0]; f.Name != "unused" || f.Type.Common().Name != "int" {
  3252  		return false
  3253  	}
  3254  	return true
  3255  }
  3256  
  3257  // baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
  3258  // as badPointerTypedef reports.
  3259  func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
  3260  	for {
  3261  		if t, ok := dt.Type.(*dwarf.TypedefType); ok {
  3262  			dt = t
  3263  			continue
  3264  		}
  3265  		break
  3266  	}
  3267  	return c.badPointerTypedef(dt)
  3268  }
  3269  
  3270  func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
  3271  	// The real bad types are CFNumberRef and CFDateRef.
  3272  	// Sometimes non-pointers are stored in these types.
  3273  	// CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
  3274  	// We return true for the other *Ref types just so casting between them is easier.
  3275  	// We identify the correct set of types as those ending in Ref and for which
  3276  	// there exists a corresponding GetTypeID function.
  3277  	// See comment below for details about the bad pointers.
  3278  	if goos != "darwin" && goos != "ios" {
  3279  		return false
  3280  	}
  3281  	s := dt.Name
  3282  	if !strings.HasSuffix(s, "Ref") {
  3283  		return false
  3284  	}
  3285  	s = s[:len(s)-3]
  3286  	if s == "CFType" {
  3287  		return true
  3288  	}
  3289  	if c.getTypeIDs[s] {
  3290  		return true
  3291  	}
  3292  	if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
  3293  		// Mutable and immutable variants share a type ID.
  3294  		return true
  3295  	}
  3296  	return false
  3297  }
  3298  
  3299  // Comment from Darwin's CFInternal.h
  3300  /*
  3301  // Tagged pointer support
  3302  // Low-bit set means tagged object, next 3 bits (currently)
  3303  // define the tagged object class, next 4 bits are for type
  3304  // information for the specific tagged object class.  Thus,
  3305  // the low byte is for type info, and the rest of a pointer
  3306  // (32 or 64-bit) is for payload, whatever the tagged class.
  3307  //
  3308  // Note that the specific integers used to identify the
  3309  // specific tagged classes can and will change from release
  3310  // to release (that's why this stuff is in CF*Internal*.h),
  3311  // as can the definition of type info vs payload above.
  3312  //
  3313  #if __LP64__
  3314  #define CF_IS_TAGGED_OBJ(PTR)	((uintptr_t)(PTR) & 0x1)
  3315  #define CF_TAGGED_OBJ_TYPE(PTR)	((uintptr_t)(PTR) & 0xF)
  3316  #else
  3317  #define CF_IS_TAGGED_OBJ(PTR)	0
  3318  #define CF_TAGGED_OBJ_TYPE(PTR)	0
  3319  #endif
  3320  
  3321  enum {
  3322      kCFTaggedObjectID_Invalid = 0,
  3323      kCFTaggedObjectID_Atom = (0 << 1) + 1,
  3324      kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
  3325      kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
  3326      kCFTaggedObjectID_Integer = (3 << 1) + 1,
  3327      kCFTaggedObjectID_DateTS = (4 << 1) + 1,
  3328      kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
  3329      kCFTaggedObjectID_Date = (6 << 1) + 1,
  3330      kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
  3331  };
  3332  */
  3333  
  3334  func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
  3335  	// In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
  3336  	// property that it is sometimes (always?) a small integer instead of a real pointer.
  3337  	// Note: although only the android JVMs are bad in this respect, we declare the JNI types
  3338  	// bad regardless of platform, so the same Go code compiles on both android and non-android.
  3339  	if parent, ok := jniTypes[dt.Name]; ok {
  3340  		// Try to make sure we're talking about a JNI type, not just some random user's
  3341  		// type that happens to use the same name.
  3342  		// C doesn't have the notion of a package, so it's hard to be certain.
  3343  
  3344  		// Walk up to jobject, checking each typedef on the way.
  3345  		w := dt
  3346  		for parent != "" {
  3347  			t, ok := w.Type.(*dwarf.TypedefType)
  3348  			if !ok || t.Name != parent {
  3349  				return false
  3350  			}
  3351  			w = t
  3352  			parent, ok = jniTypes[w.Name]
  3353  			if !ok {
  3354  				return false
  3355  			}
  3356  		}
  3357  
  3358  		// Check that the typedef is either:
  3359  		// 1:
  3360  		//     	struct _jobject;
  3361  		//     	typedef struct _jobject *jobject;
  3362  		// 2: (in NDK16 in C++)
  3363  		//     	class _jobject {};
  3364  		//     	typedef _jobject* jobject;
  3365  		// 3: (in NDK16 in C)
  3366  		//     	typedef void* jobject;
  3367  		if ptr, ok := w.Type.(*dwarf.PtrType); ok {
  3368  			switch v := ptr.Type.(type) {
  3369  			case *dwarf.VoidType:
  3370  				return true
  3371  			case *dwarf.StructType:
  3372  				if v.StructName == "_jobject" && len(v.Field) == 0 {
  3373  					switch v.Kind {
  3374  					case "struct":
  3375  						if v.Incomplete {
  3376  							return true
  3377  						}
  3378  					case "class":
  3379  						if !v.Incomplete {
  3380  							return true
  3381  						}
  3382  					}
  3383  				}
  3384  			}
  3385  		}
  3386  	}
  3387  	return false
  3388  }
  3389  
  3390  func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool {
  3391  	if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" {
  3392  		return false
  3393  	}
  3394  	// Check that the typedef is "typedef void *<name>".
  3395  	if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
  3396  		if _, ok := ptr.Type.(*dwarf.VoidType); ok {
  3397  			return true
  3398  		}
  3399  	}
  3400  	return false
  3401  }
  3402  
  3403  // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
  3404  // they are mapped. The base "jobject" maps to the empty string.
  3405  var jniTypes = map[string]string{
  3406  	"jobject":       "",
  3407  	"jclass":        "jobject",
  3408  	"jthrowable":    "jobject",
  3409  	"jstring":       "jobject",
  3410  	"jarray":        "jobject",
  3411  	"jbooleanArray": "jarray",
  3412  	"jbyteArray":    "jarray",
  3413  	"jcharArray":    "jarray",
  3414  	"jshortArray":   "jarray",
  3415  	"jintArray":     "jarray",
  3416  	"jlongArray":    "jarray",
  3417  	"jfloatArray":   "jarray",
  3418  	"jdoubleArray":  "jarray",
  3419  	"jobjectArray":  "jarray",
  3420  	"jweak":         "jobject",
  3421  }