github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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 main
     9  
    10  import (
    11  	"bytes"
    12  	"debug/dwarf"
    13  	"debug/elf"
    14  	"debug/macho"
    15  	"debug/pe"
    16  	"encoding/binary"
    17  	"errors"
    18  	"flag"
    19  	"fmt"
    20  	"go/ast"
    21  	"go/parser"
    22  	"go/token"
    23  	"os"
    24  	"strconv"
    25  	"strings"
    26  	"unicode"
    27  	"unicode/utf8"
    28  )
    29  
    30  var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
    31  var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
    32  
    33  var nameToC = map[string]string{
    34  	"schar":         "signed char",
    35  	"uchar":         "unsigned char",
    36  	"ushort":        "unsigned short",
    37  	"uint":          "unsigned int",
    38  	"ulong":         "unsigned long",
    39  	"longlong":      "long long",
    40  	"ulonglong":     "unsigned long long",
    41  	"complexfloat":  "float complex",
    42  	"complexdouble": "double complex",
    43  }
    44  
    45  // cname returns the C name to use for C.s.
    46  // The expansions are listed in nameToC and also
    47  // struct_foo becomes "struct foo", and similarly for
    48  // union and enum.
    49  func cname(s string) string {
    50  	if t, ok := nameToC[s]; ok {
    51  		return t
    52  	}
    53  
    54  	if strings.HasPrefix(s, "struct_") {
    55  		return "struct " + s[len("struct_"):]
    56  	}
    57  	if strings.HasPrefix(s, "union_") {
    58  		return "union " + s[len("union_"):]
    59  	}
    60  	if strings.HasPrefix(s, "enum_") {
    61  		return "enum " + s[len("enum_"):]
    62  	}
    63  	if strings.HasPrefix(s, "sizeof_") {
    64  		return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
    65  	}
    66  	return s
    67  }
    68  
    69  // DiscardCgoDirectives processes the import C preamble, and discards
    70  // all #cgo CFLAGS and LDFLAGS directives, so they don't make their
    71  // way into _cgo_export.h.
    72  func (f *File) DiscardCgoDirectives() {
    73  	linesIn := strings.Split(f.Preamble, "\n")
    74  	linesOut := make([]string, 0, len(linesIn))
    75  	for _, line := range linesIn {
    76  		l := strings.TrimSpace(line)
    77  		if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
    78  			linesOut = append(linesOut, line)
    79  		} else {
    80  			linesOut = append(linesOut, "")
    81  		}
    82  	}
    83  	f.Preamble = strings.Join(linesOut, "\n")
    84  }
    85  
    86  // addToFlag appends args to flag.  All flags are later written out onto the
    87  // _cgo_flags file for the build system to use.
    88  func (p *Package) addToFlag(flag string, args []string) {
    89  	p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
    90  	if flag == "CFLAGS" {
    91  		// We'll also need these when preprocessing for dwarf information.
    92  		p.GccOptions = append(p.GccOptions, args...)
    93  	}
    94  }
    95  
    96  // splitQuoted splits the string s around each instance of one or more consecutive
    97  // white space characters while taking into account quotes and escaping, and
    98  // returns an array of substrings of s or an empty list if s contains only white space.
    99  // Single quotes and double quotes are recognized to prevent splitting within the
   100  // quoted region, and are removed from the resulting substrings. If a quote in s
   101  // isn't closed err will be set and r will have the unclosed argument as the
   102  // last element.  The backslash is used for escaping.
   103  //
   104  // For example, the following string:
   105  //
   106  //     `a b:"c d" 'e''f'  "g\""`
   107  //
   108  // Would be parsed as:
   109  //
   110  //     []string{"a", "b:c d", "ef", `g"`}
   111  //
   112  func splitQuoted(s string) (r []string, err error) {
   113  	var args []string
   114  	arg := make([]rune, len(s))
   115  	escaped := false
   116  	quoted := false
   117  	quote := '\x00'
   118  	i := 0
   119  	for _, r := range s {
   120  		switch {
   121  		case escaped:
   122  			escaped = false
   123  		case r == '\\':
   124  			escaped = true
   125  			continue
   126  		case quote != 0:
   127  			if r == quote {
   128  				quote = 0
   129  				continue
   130  			}
   131  		case r == '"' || r == '\'':
   132  			quoted = true
   133  			quote = r
   134  			continue
   135  		case unicode.IsSpace(r):
   136  			if quoted || i > 0 {
   137  				quoted = false
   138  				args = append(args, string(arg[:i]))
   139  				i = 0
   140  			}
   141  			continue
   142  		}
   143  		arg[i] = r
   144  		i++
   145  	}
   146  	if quoted || i > 0 {
   147  		args = append(args, string(arg[:i]))
   148  	}
   149  	if quote != 0 {
   150  		err = errors.New("unclosed quote")
   151  	} else if escaped {
   152  		err = errors.New("unfinished escaping")
   153  	}
   154  	return args, err
   155  }
   156  
   157  var safeBytes = []byte(`+-.,/0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz`)
   158  
   159  func safeName(s string) bool {
   160  	if s == "" {
   161  		return false
   162  	}
   163  	for i := 0; i < len(s); i++ {
   164  		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
   165  			return false
   166  		}
   167  	}
   168  	return true
   169  }
   170  
   171  // Translate rewrites f.AST, the original Go input, to remove
   172  // references to the imported package C, replacing them with
   173  // references to the equivalent Go types, functions, and variables.
   174  func (p *Package) Translate(f *File) {
   175  	for _, cref := range f.Ref {
   176  		// Convert C.ulong to C.unsigned long, etc.
   177  		cref.Name.C = cname(cref.Name.Go)
   178  	}
   179  	p.loadDefines(f)
   180  	needType := p.guessKinds(f)
   181  	if len(needType) > 0 {
   182  		p.loadDWARF(f, needType)
   183  	}
   184  	p.rewriteRef(f)
   185  }
   186  
   187  // loadDefines coerces gcc into spitting out the #defines in use
   188  // in the file f and saves relevant renamings in f.Name[name].Define.
   189  func (p *Package) loadDefines(f *File) {
   190  	var b bytes.Buffer
   191  	b.WriteString(f.Preamble)
   192  	b.WriteString(builtinProlog)
   193  	stdout := p.gccDefines(b.Bytes())
   194  
   195  	for _, line := range strings.Split(stdout, "\n") {
   196  		if len(line) < 9 || line[0:7] != "#define" {
   197  			continue
   198  		}
   199  
   200  		line = strings.TrimSpace(line[8:])
   201  
   202  		var key, val string
   203  		spaceIndex := strings.Index(line, " ")
   204  		tabIndex := strings.Index(line, "\t")
   205  
   206  		if spaceIndex == -1 && tabIndex == -1 {
   207  			continue
   208  		} else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
   209  			key = line[0:spaceIndex]
   210  			val = strings.TrimSpace(line[spaceIndex:])
   211  		} else {
   212  			key = line[0:tabIndex]
   213  			val = strings.TrimSpace(line[tabIndex:])
   214  		}
   215  
   216  		if n := f.Name[key]; n != nil {
   217  			if *debugDefine {
   218  				fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
   219  			}
   220  			n.Define = val
   221  		}
   222  	}
   223  }
   224  
   225  // guessKinds tricks gcc into revealing the kind of each
   226  // name xxx for the references C.xxx in the Go input.
   227  // The kind is either a constant, type, or variable.
   228  func (p *Package) guessKinds(f *File) []*Name {
   229  	// Determine kinds for names we already know about,
   230  	// like #defines or 'struct foo', before bothering with gcc.
   231  	var names, needType []*Name
   232  	for _, n := range f.Name {
   233  		// If we've already found this name as a #define
   234  		// and we can translate it as a constant value, do so.
   235  		if n.Define != "" {
   236  			isConst := false
   237  			if _, err := strconv.Atoi(n.Define); err == nil {
   238  				isConst = true
   239  			} else if n.Define[0] == '"' || n.Define[0] == '\'' {
   240  				if _, err := parser.ParseExpr(n.Define); err == nil {
   241  					isConst = true
   242  				}
   243  			}
   244  			if isConst {
   245  				n.Kind = "const"
   246  				// Turn decimal into hex, just for consistency
   247  				// with enum-derived constants.  Otherwise
   248  				// in the cgo -godefs output half the constants
   249  				// are in hex and half are in whatever the #define used.
   250  				i, err := strconv.ParseInt(n.Define, 0, 64)
   251  				if err == nil {
   252  					n.Const = fmt.Sprintf("%#x", i)
   253  				} else {
   254  					n.Const = n.Define
   255  				}
   256  				continue
   257  			}
   258  
   259  			if isName(n.Define) {
   260  				n.C = n.Define
   261  			}
   262  		}
   263  
   264  		needType = append(needType, n)
   265  
   266  		// If this is a struct, union, or enum type name, no need to guess the kind.
   267  		if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
   268  			n.Kind = "type"
   269  			continue
   270  		}
   271  
   272  		// Otherwise, we'll need to find out from gcc.
   273  		names = append(names, n)
   274  	}
   275  
   276  	// Bypass gcc if there's nothing left to find out.
   277  	if len(names) == 0 {
   278  		return needType
   279  	}
   280  
   281  	// Coerce gcc into telling us whether each name is a type, a value, or undeclared.
   282  	// For names, find out whether they are integer constants.
   283  	// We used to look at specific warning or error messages here, but that tied the
   284  	// behavior too closely to specific versions of the compilers.
   285  	// Instead, arrange that we can infer what we need from only the presence or absence
   286  	// of an error on a specific line.
   287  	//
   288  	// For each name, we generate these lines, where xxx is the index in toSniff plus one.
   289  	//
   290  	//	#line xxx "not-declared"
   291  	//	void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; }
   292  	//	#line xxx "not-type"
   293  	//	void __cgo_f_xxx_2(void) { name *__cgo_undefined__; }
   294  	//	#line xxx "not-const"
   295  	//	void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; }
   296  	//
   297  	// If we see an error at not-declared:xxx, the corresponding name is not declared.
   298  	// If we see an error at not-type:xxx, the corresponding name is a type.
   299  	// If we see an error at not-const:xxx, the corresponding name is not an integer constant.
   300  	// If we see no errors, we assume the name is an expression but not a constant
   301  	// (so a variable or a function).
   302  	//
   303  	// The specific input forms are chosen so that they are valid C syntax regardless of
   304  	// whether name denotes a type or an expression.
   305  
   306  	var b bytes.Buffer
   307  	b.WriteString(f.Preamble)
   308  	b.WriteString(builtinProlog)
   309  
   310  	for i, n := range names {
   311  		fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
   312  			"void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+
   313  			"#line %d \"not-type\"\n"+
   314  			"void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+
   315  			"#line %d \"not-const\"\n"+
   316  			"void __cgo_f_%d_3(void) { enum { __cgo__undefined__ = (%s)*1 }; }\n",
   317  			i+1, i+1, n.C,
   318  			i+1, i+1, n.C,
   319  			i+1, i+1, n.C)
   320  	}
   321  	fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
   322  		"int __cgo__1 = __cgo__2;\n")
   323  
   324  	stderr := p.gccErrors(b.Bytes())
   325  	if stderr == "" {
   326  		fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
   327  	}
   328  
   329  	completed := false
   330  	sniff := make([]int, len(names))
   331  	const (
   332  		notType = 1 << iota
   333  		notConst
   334  	)
   335  	for _, line := range strings.Split(stderr, "\n") {
   336  		if !strings.Contains(line, ": error:") {
   337  			// we only care about errors.
   338  			// we tried to turn off warnings on the command line, but one never knows.
   339  			continue
   340  		}
   341  
   342  		c1 := strings.Index(line, ":")
   343  		if c1 < 0 {
   344  			continue
   345  		}
   346  		c2 := strings.Index(line[c1+1:], ":")
   347  		if c2 < 0 {
   348  			continue
   349  		}
   350  		c2 += c1 + 1
   351  
   352  		filename := line[:c1]
   353  		i, _ := strconv.Atoi(line[c1+1 : c2])
   354  		i--
   355  		if i < 0 || i >= len(names) {
   356  			continue
   357  		}
   358  
   359  		switch filename {
   360  		case "completed":
   361  			// Strictly speaking, there is no guarantee that seeing the error at completed:1
   362  			// (at the end of the file) means we've seen all the errors from earlier in the file,
   363  			// but usually it does. Certainly if we don't see the completed:1 error, we did
   364  			// not get all the errors we expected.
   365  			completed = true
   366  
   367  		case "not-declared":
   368  			error_(token.NoPos, "%s", strings.TrimSpace(line[c2+1:]))
   369  		case "not-type":
   370  			sniff[i] |= notType
   371  		case "not-const":
   372  			sniff[i] |= notConst
   373  		}
   374  	}
   375  
   376  	if !completed {
   377  		fatalf("%s did not produce error at completed:1\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
   378  	}
   379  
   380  	for i, n := range names {
   381  		switch sniff[i] {
   382  		case 0:
   383  			error_(token.NoPos, "could not determine kind of name for C.%s", fixGo(n.Go))
   384  		case notType:
   385  			n.Kind = "const"
   386  		case notConst:
   387  			n.Kind = "type"
   388  		case notConst | notType:
   389  			n.Kind = "not-type"
   390  		}
   391  	}
   392  	if nerrors > 0 {
   393  		fatalf("unresolved names")
   394  	}
   395  
   396  	needType = append(needType, names...)
   397  	return needType
   398  }
   399  
   400  // loadDWARF parses the DWARF debug information generated
   401  // by gcc to learn the details of the constants, variables, and types
   402  // being referred to as C.xxx.
   403  func (p *Package) loadDWARF(f *File, names []*Name) {
   404  	// Extract the types from the DWARF section of an object
   405  	// from a well-formed C program.  Gcc only generates DWARF info
   406  	// for symbols in the object file, so it is not enough to print the
   407  	// preamble and hope the symbols we care about will be there.
   408  	// Instead, emit
   409  	//	__typeof__(names[i]) *__cgo__i;
   410  	// for each entry in names and then dereference the type we
   411  	// learn for __cgo__i.
   412  	var b bytes.Buffer
   413  	b.WriteString(f.Preamble)
   414  	b.WriteString(builtinProlog)
   415  	for i, n := range names {
   416  		fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
   417  		if n.Kind == "const" {
   418  			fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
   419  		}
   420  	}
   421  
   422  	// Apple's LLVM-based gcc does not include the enumeration
   423  	// names and values in its DWARF debug output.  In case we're
   424  	// using such a gcc, create a data block initialized with the values.
   425  	// We can read them out of the object file.
   426  	fmt.Fprintf(&b, "long long __cgodebug_data[] = {\n")
   427  	for _, n := range names {
   428  		if n.Kind == "const" {
   429  			fmt.Fprintf(&b, "\t%s,\n", n.C)
   430  		} else {
   431  			fmt.Fprintf(&b, "\t0,\n")
   432  		}
   433  	}
   434  	// for the last entry, we can not use 0, otherwise
   435  	// in case all __cgodebug_data is zero initialized,
   436  	// LLVM-based gcc will place the it in the __DATA.__common
   437  	// zero-filled section (our debug/macho doesn't support
   438  	// this)
   439  	fmt.Fprintf(&b, "\t1\n")
   440  	fmt.Fprintf(&b, "};\n")
   441  
   442  	d, bo, debugData := p.gccDebug(b.Bytes())
   443  	enumVal := make([]int64, len(debugData)/8)
   444  	for i := range enumVal {
   445  		enumVal[i] = int64(bo.Uint64(debugData[i*8:]))
   446  	}
   447  
   448  	// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
   449  	types := make([]dwarf.Type, len(names))
   450  	enums := make([]dwarf.Offset, len(names))
   451  	nameToIndex := make(map[*Name]int)
   452  	for i, n := range names {
   453  		nameToIndex[n] = i
   454  	}
   455  	nameToRef := make(map[*Name]*Ref)
   456  	for _, ref := range f.Ref {
   457  		nameToRef[ref.Name] = ref
   458  	}
   459  	r := d.Reader()
   460  	for {
   461  		e, err := r.Next()
   462  		if err != nil {
   463  			fatalf("reading DWARF entry: %s", err)
   464  		}
   465  		if e == nil {
   466  			break
   467  		}
   468  		switch e.Tag {
   469  		case dwarf.TagEnumerationType:
   470  			offset := e.Offset
   471  			for {
   472  				e, err := r.Next()
   473  				if err != nil {
   474  					fatalf("reading DWARF entry: %s", err)
   475  				}
   476  				if e.Tag == 0 {
   477  					break
   478  				}
   479  				if e.Tag == dwarf.TagEnumerator {
   480  					entryName := e.Val(dwarf.AttrName).(string)
   481  					if strings.HasPrefix(entryName, "__cgo_enum__") {
   482  						n, _ := strconv.Atoi(entryName[len("__cgo_enum__"):])
   483  						if 0 <= n && n < len(names) {
   484  							enums[n] = offset
   485  						}
   486  					}
   487  				}
   488  			}
   489  		case dwarf.TagVariable:
   490  			name, _ := e.Val(dwarf.AttrName).(string)
   491  			typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
   492  			if name == "" || typOff == 0 {
   493  				fatalf("malformed DWARF TagVariable entry")
   494  			}
   495  			if !strings.HasPrefix(name, "__cgo__") {
   496  				break
   497  			}
   498  			typ, err := d.Type(typOff)
   499  			if err != nil {
   500  				fatalf("loading DWARF type: %s", err)
   501  			}
   502  			t, ok := typ.(*dwarf.PtrType)
   503  			if !ok || t == nil {
   504  				fatalf("internal error: %s has non-pointer type", name)
   505  			}
   506  			i, err := strconv.Atoi(name[7:])
   507  			if err != nil {
   508  				fatalf("malformed __cgo__ name: %s", name)
   509  			}
   510  			if enums[i] != 0 {
   511  				t, err := d.Type(enums[i])
   512  				if err != nil {
   513  					fatalf("loading DWARF type: %s", err)
   514  				}
   515  				types[i] = t
   516  			} else {
   517  				types[i] = t.Type
   518  			}
   519  		}
   520  		if e.Tag != dwarf.TagCompileUnit {
   521  			r.SkipChildren()
   522  		}
   523  	}
   524  
   525  	// Record types and typedef information.
   526  	var conv typeConv
   527  	conv.Init(p.PtrSize, p.IntSize)
   528  	for i, n := range names {
   529  		if types[i] == nil {
   530  			continue
   531  		}
   532  		pos := token.NoPos
   533  		if ref, ok := nameToRef[n]; ok {
   534  			pos = ref.Pos()
   535  		}
   536  		f, fok := types[i].(*dwarf.FuncType)
   537  		if n.Kind != "type" && fok {
   538  			n.Kind = "func"
   539  			n.FuncType = conv.FuncType(f, pos)
   540  		} else {
   541  			n.Type = conv.Type(types[i], pos)
   542  			if enums[i] != 0 && n.Type.EnumValues != nil {
   543  				k := fmt.Sprintf("__cgo_enum__%d", i)
   544  				n.Kind = "const"
   545  				n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k])
   546  				// Remove injected enum to ensure the value will deep-compare
   547  				// equally in future loads of the same constant.
   548  				delete(n.Type.EnumValues, k)
   549  			}
   550  			// Prefer debug data over DWARF debug output, if we have it.
   551  			if n.Kind == "const" && i < len(enumVal) {
   552  				n.Const = fmt.Sprintf("%#x", enumVal[i])
   553  			}
   554  		}
   555  	}
   556  
   557  }
   558  
   559  // mangleName does name mangling to translate names
   560  // from the original Go source files to the names
   561  // used in the final Go files generated by cgo.
   562  func (p *Package) mangleName(n *Name) {
   563  	// When using gccgo variables have to be
   564  	// exported so that they become global symbols
   565  	// that the C code can refer to.
   566  	prefix := "_C"
   567  	if *gccgo && n.IsVar() {
   568  		prefix = "C"
   569  	}
   570  	n.Mangle = prefix + n.Kind + "_" + n.Go
   571  }
   572  
   573  // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
   574  // Go equivalents, now that we have figured out the meaning of all
   575  // the xxx.  In *godefs or *cdefs mode, rewriteRef replaces the names
   576  // with full definitions instead of mangled names.
   577  func (p *Package) rewriteRef(f *File) {
   578  	// Keep a list of all the functions, to remove the ones
   579  	// only used as expressions and avoid generating bridge
   580  	// code for them.
   581  	functions := make(map[string]bool)
   582  
   583  	// Assign mangled names.
   584  	for _, n := range f.Name {
   585  		if n.Kind == "not-type" {
   586  			n.Kind = "var"
   587  		}
   588  		if n.Mangle == "" {
   589  			p.mangleName(n)
   590  		}
   591  		if n.Kind == "func" {
   592  			functions[n.Go] = false
   593  		}
   594  	}
   595  
   596  	// Now that we have all the name types filled in,
   597  	// scan through the Refs to identify the ones that
   598  	// are trying to do a ,err call.  Also check that
   599  	// functions are only used in calls.
   600  	for _, r := range f.Ref {
   601  		if r.Name.Kind == "const" && r.Name.Const == "" {
   602  			error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
   603  		}
   604  		var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
   605  		switch r.Context {
   606  		case "call", "call2":
   607  			if r.Name.Kind != "func" {
   608  				if r.Name.Kind == "type" {
   609  					r.Context = "type"
   610  					expr = r.Name.Type.Go
   611  					break
   612  				}
   613  				error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
   614  				break
   615  			}
   616  			functions[r.Name.Go] = true
   617  			if r.Context == "call2" {
   618  				if r.Name.Go == "_CMalloc" {
   619  					error_(r.Pos(), "no two-result form for C.malloc")
   620  					break
   621  				}
   622  				// Invent new Name for the two-result function.
   623  				n := f.Name["2"+r.Name.Go]
   624  				if n == nil {
   625  					n = new(Name)
   626  					*n = *r.Name
   627  					n.AddError = true
   628  					n.Mangle = "_C2func_" + n.Go
   629  					f.Name["2"+r.Name.Go] = n
   630  				}
   631  				expr = ast.NewIdent(n.Mangle)
   632  				r.Name = n
   633  				break
   634  			}
   635  		case "expr":
   636  			if r.Name.Kind == "func" {
   637  				// Function is being used in an expression, to e.g. pass around a C function pointer.
   638  				// Create a new Name for this Ref which causes the variable to be declared in Go land.
   639  				fpName := "fp_" + r.Name.Go
   640  				name := f.Name[fpName]
   641  				if name == nil {
   642  					name = &Name{
   643  						Go:   fpName,
   644  						C:    r.Name.C,
   645  						Kind: "fpvar",
   646  						Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
   647  					}
   648  					p.mangleName(name)
   649  					f.Name[fpName] = name
   650  				}
   651  				r.Name = name
   652  				expr = ast.NewIdent(name.Mangle)
   653  			} else if r.Name.Kind == "type" {
   654  				// Okay - might be new(T)
   655  				expr = r.Name.Type.Go
   656  			} else if r.Name.Kind == "var" {
   657  				expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
   658  			}
   659  
   660  		case "type":
   661  			if r.Name.Kind != "type" {
   662  				error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
   663  			} else if r.Name.Type == nil {
   664  				// Use of C.enum_x, C.struct_x or C.union_x without C definition.
   665  				// GCC won't raise an error when using pointers to such unknown types.
   666  				error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
   667  			} else {
   668  				expr = r.Name.Type.Go
   669  			}
   670  		default:
   671  			if r.Name.Kind == "func" {
   672  				error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
   673  			}
   674  		}
   675  		if *godefs || *cdefs {
   676  			// Substitute definition for mangled type name.
   677  			if id, ok := expr.(*ast.Ident); ok {
   678  				if t := typedef[id.Name]; t != nil {
   679  					expr = t.Go
   680  				}
   681  				if id.Name == r.Name.Mangle && r.Name.Const != "" {
   682  					expr = ast.NewIdent(r.Name.Const)
   683  				}
   684  			}
   685  		}
   686  
   687  		// Copy position information from old expr into new expr,
   688  		// in case expression being replaced is first on line.
   689  		// See golang.org/issue/6563.
   690  		pos := (*r.Expr).Pos()
   691  		switch x := expr.(type) {
   692  		case *ast.Ident:
   693  			expr = &ast.Ident{NamePos: pos, Name: x.Name}
   694  		}
   695  
   696  		*r.Expr = expr
   697  	}
   698  
   699  	// Remove functions only used as expressions, so their respective
   700  	// bridge functions are not generated.
   701  	for name, used := range functions {
   702  		if !used {
   703  			delete(f.Name, name)
   704  		}
   705  	}
   706  }
   707  
   708  // gccBaseCmd returns the start of the compiler command line.
   709  // It uses $CC if set, or else $GCC, or else the compiler recorded
   710  // during the initial build as defaultCC.
   711  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
   712  func (p *Package) gccBaseCmd() []string {
   713  	// Use $CC if set, since that's what the build uses.
   714  	if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
   715  		return ret
   716  	}
   717  	// Try $GCC if set, since that's what we used to use.
   718  	if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
   719  		return ret
   720  	}
   721  	return strings.Fields(defaultCC)
   722  }
   723  
   724  // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
   725  func (p *Package) gccMachine() []string {
   726  	switch goarch {
   727  	case "amd64":
   728  		return []string{"-m64"}
   729  	case "386":
   730  		return []string{"-m32"}
   731  	case "arm":
   732  		return []string{"-marm"} // not thumb
   733  	}
   734  	return nil
   735  }
   736  
   737  func gccTmp() string {
   738  	return *objDir + "_cgo_.o"
   739  }
   740  
   741  // gccCmd returns the gcc command line to use for compiling
   742  // the input.
   743  func (p *Package) gccCmd() []string {
   744  	c := append(p.gccBaseCmd(),
   745  		"-w",          // no warnings
   746  		"-Wno-error",  // warnings are not errors
   747  		"-o"+gccTmp(), // write object to tmp
   748  		"-gdwarf-2",   // generate DWARF v2 debugging symbols
   749  		"-c",          // do not link
   750  		"-xc",         // input language is C
   751  	)
   752  	if strings.Contains(c[0], "clang") {
   753  		c = append(c,
   754  			"-ferror-limit=0",
   755  			// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
   756  			// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
   757  			// flag to disable the warning. Yes, really good diagnostics, clang.
   758  			"-Wno-unknown-warning-option",
   759  			"-Wno-unneeded-internal-declaration",
   760  			"-Wno-unused-function",
   761  			"-Qunused-arguments",
   762  			// Clang embeds prototypes for some builtin functions,
   763  			// like malloc and calloc, but all size_t parameters are
   764  			// incorrectly typed unsigned long. We work around that
   765  			// by disabling the builtin functions (this is safe as
   766  			// it won't affect the actual compilation of the C code).
   767  			// See: http://golang.org/issue/6506.
   768  			"-fno-builtin",
   769  		)
   770  	}
   771  
   772  	c = append(c, p.GccOptions...)
   773  	c = append(c, p.gccMachine()...)
   774  	c = append(c, "-") //read input from standard input
   775  	return c
   776  }
   777  
   778  // gccDebug runs gcc -gdwarf-2 over the C program stdin and
   779  // returns the corresponding DWARF data and, if present, debug data block.
   780  func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) {
   781  	runGcc(stdin, p.gccCmd())
   782  
   783  	isDebugData := func(s string) bool {
   784  		// Some systems use leading _ to denote non-assembly symbols.
   785  		return s == "__cgodebug_data" || s == "___cgodebug_data"
   786  	}
   787  
   788  	if f, err := macho.Open(gccTmp()); err == nil {
   789  		defer f.Close()
   790  		d, err := f.DWARF()
   791  		if err != nil {
   792  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
   793  		}
   794  		var data []byte
   795  		if f.Symtab != nil {
   796  			for i := range f.Symtab.Syms {
   797  				s := &f.Symtab.Syms[i]
   798  				if isDebugData(s.Name) {
   799  					// Found it.  Now find data section.
   800  					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
   801  						sect := f.Sections[i]
   802  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
   803  							if sdat, err := sect.Data(); err == nil {
   804  								data = sdat[s.Value-sect.Addr:]
   805  							}
   806  						}
   807  					}
   808  				}
   809  			}
   810  		}
   811  		return d, f.ByteOrder, data
   812  	}
   813  
   814  	if f, err := elf.Open(gccTmp()); err == nil {
   815  		defer f.Close()
   816  		d, err := f.DWARF()
   817  		if err != nil {
   818  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
   819  		}
   820  		var data []byte
   821  		symtab, err := f.Symbols()
   822  		if err == nil {
   823  			for i := range symtab {
   824  				s := &symtab[i]
   825  				if isDebugData(s.Name) {
   826  					// Found it.  Now find data section.
   827  					if i := int(s.Section); 0 <= i && i < len(f.Sections) {
   828  						sect := f.Sections[i]
   829  						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
   830  							if sdat, err := sect.Data(); err == nil {
   831  								data = sdat[s.Value-sect.Addr:]
   832  							}
   833  						}
   834  					}
   835  				}
   836  			}
   837  		}
   838  		return d, f.ByteOrder, data
   839  	}
   840  
   841  	if f, err := pe.Open(gccTmp()); err == nil {
   842  		defer f.Close()
   843  		d, err := f.DWARF()
   844  		if err != nil {
   845  			fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
   846  		}
   847  		var data []byte
   848  		for _, s := range f.Symbols {
   849  			if isDebugData(s.Name) {
   850  				if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
   851  					sect := f.Sections[i]
   852  					if s.Value < sect.Size {
   853  						if sdat, err := sect.Data(); err == nil {
   854  							data = sdat[s.Value:]
   855  						}
   856  					}
   857  				}
   858  			}
   859  		}
   860  		return d, binary.LittleEndian, data
   861  	}
   862  
   863  	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp())
   864  	panic("not reached")
   865  }
   866  
   867  // gccDefines runs gcc -E -dM -xc - over the C program stdin
   868  // and returns the corresponding standard output, which is the
   869  // #defines that gcc encountered while processing the input
   870  // and its included files.
   871  func (p *Package) gccDefines(stdin []byte) string {
   872  	base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
   873  	base = append(base, p.gccMachine()...)
   874  	stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
   875  	return stdout
   876  }
   877  
   878  // gccErrors runs gcc over the C program stdin and returns
   879  // the errors that gcc prints.  That is, this function expects
   880  // gcc to fail.
   881  func (p *Package) gccErrors(stdin []byte) string {
   882  	// TODO(rsc): require failure
   883  	args := p.gccCmd()
   884  
   885  	if *debugGcc {
   886  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
   887  		os.Stderr.Write(stdin)
   888  		fmt.Fprint(os.Stderr, "EOF\n")
   889  	}
   890  	stdout, stderr, _ := run(stdin, args)
   891  	if *debugGcc {
   892  		os.Stderr.Write(stdout)
   893  		os.Stderr.Write(stderr)
   894  	}
   895  	return string(stderr)
   896  }
   897  
   898  // runGcc runs the gcc command line args with stdin on standard input.
   899  // If the command exits with a non-zero exit status, runGcc prints
   900  // details about what was run and exits.
   901  // Otherwise runGcc returns the data written to standard output and standard error.
   902  // Note that for some of the uses we expect useful data back
   903  // on standard error, but for those uses gcc must still exit 0.
   904  func runGcc(stdin []byte, args []string) (string, string) {
   905  	if *debugGcc {
   906  		fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
   907  		os.Stderr.Write(stdin)
   908  		fmt.Fprint(os.Stderr, "EOF\n")
   909  	}
   910  	stdout, stderr, ok := run(stdin, args)
   911  	if *debugGcc {
   912  		os.Stderr.Write(stdout)
   913  		os.Stderr.Write(stderr)
   914  	}
   915  	if !ok {
   916  		os.Stderr.Write(stderr)
   917  		os.Exit(2)
   918  	}
   919  	return string(stdout), string(stderr)
   920  }
   921  
   922  // A typeConv is a translator from dwarf types to Go types
   923  // with equivalent memory layout.
   924  type typeConv struct {
   925  	// Cache of already-translated or in-progress types.
   926  	m       map[dwarf.Type]*Type
   927  	typedef map[string]ast.Expr
   928  
   929  	// Predeclared types.
   930  	bool                                   ast.Expr
   931  	byte                                   ast.Expr // denotes padding
   932  	int8, int16, int32, int64              ast.Expr
   933  	uint8, uint16, uint32, uint64, uintptr ast.Expr
   934  	float32, float64                       ast.Expr
   935  	complex64, complex128                  ast.Expr
   936  	void                                   ast.Expr
   937  	unsafePointer                          ast.Expr
   938  	string                                 ast.Expr
   939  	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
   940  
   941  	ptrSize int64
   942  	intSize int64
   943  }
   944  
   945  var tagGen int
   946  var typedef = make(map[string]*Type)
   947  var goIdent = make(map[string]*ast.Ident)
   948  
   949  func (c *typeConv) Init(ptrSize, intSize int64) {
   950  	c.ptrSize = ptrSize
   951  	c.intSize = intSize
   952  	c.m = make(map[dwarf.Type]*Type)
   953  	c.bool = c.Ident("bool")
   954  	c.byte = c.Ident("byte")
   955  	c.int8 = c.Ident("int8")
   956  	c.int16 = c.Ident("int16")
   957  	c.int32 = c.Ident("int32")
   958  	c.int64 = c.Ident("int64")
   959  	c.uint8 = c.Ident("uint8")
   960  	c.uint16 = c.Ident("uint16")
   961  	c.uint32 = c.Ident("uint32")
   962  	c.uint64 = c.Ident("uint64")
   963  	c.uintptr = c.Ident("uintptr")
   964  	c.float32 = c.Ident("float32")
   965  	c.float64 = c.Ident("float64")
   966  	c.complex64 = c.Ident("complex64")
   967  	c.complex128 = c.Ident("complex128")
   968  	c.unsafePointer = c.Ident("unsafe.Pointer")
   969  	c.void = c.Ident("void")
   970  	c.string = c.Ident("string")
   971  	c.goVoid = c.Ident("_Ctype_void")
   972  }
   973  
   974  // base strips away qualifiers and typedefs to get the underlying type
   975  func base(dt dwarf.Type) dwarf.Type {
   976  	for {
   977  		if d, ok := dt.(*dwarf.QualType); ok {
   978  			dt = d.Type
   979  			continue
   980  		}
   981  		if d, ok := dt.(*dwarf.TypedefType); ok {
   982  			dt = d.Type
   983  			continue
   984  		}
   985  		break
   986  	}
   987  	return dt
   988  }
   989  
   990  // Map from dwarf text names to aliases we use in package "C".
   991  var dwarfToName = map[string]string{
   992  	"long int":               "long",
   993  	"long unsigned int":      "ulong",
   994  	"unsigned int":           "uint",
   995  	"short unsigned int":     "ushort",
   996  	"short int":              "short",
   997  	"long long int":          "longlong",
   998  	"long long unsigned int": "ulonglong",
   999  	"signed char":            "schar",
  1000  	"float complex":          "complexfloat",
  1001  	"double complex":         "complexdouble",
  1002  }
  1003  
  1004  const signedDelta = 64
  1005  
  1006  // String returns the current type representation.  Format arguments
  1007  // are assembled within this method so that any changes in mutable
  1008  // values are taken into account.
  1009  func (tr *TypeRepr) String() string {
  1010  	if len(tr.Repr) == 0 {
  1011  		return ""
  1012  	}
  1013  	if len(tr.FormatArgs) == 0 {
  1014  		return tr.Repr
  1015  	}
  1016  	return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
  1017  }
  1018  
  1019  // Empty returns true if the result of String would be "".
  1020  func (tr *TypeRepr) Empty() bool {
  1021  	return len(tr.Repr) == 0
  1022  }
  1023  
  1024  // Set modifies the type representation.
  1025  // If fargs are provided, repr is used as a format for fmt.Sprintf.
  1026  // Otherwise, repr is used unprocessed as the type representation.
  1027  func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
  1028  	tr.Repr = repr
  1029  	tr.FormatArgs = fargs
  1030  }
  1031  
  1032  // Type returns a *Type with the same memory layout as
  1033  // dtype when used as the type of a variable or a struct field.
  1034  func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
  1035  	if t, ok := c.m[dtype]; ok {
  1036  		if t.Go == nil {
  1037  			fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
  1038  		}
  1039  		return t
  1040  	}
  1041  
  1042  	// clang won't generate DW_AT_byte_size for pointer types,
  1043  	// so we have to fix it here.
  1044  	if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 {
  1045  		dt.ByteSize = c.ptrSize
  1046  	}
  1047  
  1048  	t := new(Type)
  1049  	t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
  1050  	t.Align = -1
  1051  	t.C = &TypeRepr{Repr: dtype.Common().Name}
  1052  	c.m[dtype] = t
  1053  
  1054  	switch dt := dtype.(type) {
  1055  	default:
  1056  		fatalf("%s: unexpected type: %s", lineno(pos), dtype)
  1057  
  1058  	case *dwarf.AddrType:
  1059  		if t.Size != c.ptrSize {
  1060  			fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
  1061  		}
  1062  		t.Go = c.uintptr
  1063  		t.Align = t.Size
  1064  
  1065  	case *dwarf.ArrayType:
  1066  		if dt.StrideBitSize > 0 {
  1067  			// Cannot represent bit-sized elements in Go.
  1068  			t.Go = c.Opaque(t.Size)
  1069  			break
  1070  		}
  1071  		gt := &ast.ArrayType{
  1072  			Len: c.intExpr(dt.Count),
  1073  		}
  1074  		t.Go = gt // publish before recursive call
  1075  		sub := c.Type(dt.Type, pos)
  1076  		t.Align = sub.Align
  1077  		gt.Elt = sub.Go
  1078  		t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
  1079  
  1080  	case *dwarf.BoolType:
  1081  		t.Go = c.bool
  1082  		t.Align = 1
  1083  
  1084  	case *dwarf.CharType:
  1085  		if t.Size != 1 {
  1086  			fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
  1087  		}
  1088  		t.Go = c.int8
  1089  		t.Align = 1
  1090  
  1091  	case *dwarf.EnumType:
  1092  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1093  			t.Align = c.ptrSize
  1094  		}
  1095  		t.C.Set("enum " + dt.EnumName)
  1096  		signed := 0
  1097  		t.EnumValues = make(map[string]int64)
  1098  		for _, ev := range dt.Val {
  1099  			t.EnumValues[ev.Name] = ev.Val
  1100  			if ev.Val < 0 {
  1101  				signed = signedDelta
  1102  			}
  1103  		}
  1104  		switch t.Size + int64(signed) {
  1105  		default:
  1106  			fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
  1107  		case 1:
  1108  			t.Go = c.uint8
  1109  		case 2:
  1110  			t.Go = c.uint16
  1111  		case 4:
  1112  			t.Go = c.uint32
  1113  		case 8:
  1114  			t.Go = c.uint64
  1115  		case 1 + signedDelta:
  1116  			t.Go = c.int8
  1117  		case 2 + signedDelta:
  1118  			t.Go = c.int16
  1119  		case 4 + signedDelta:
  1120  			t.Go = c.int32
  1121  		case 8 + signedDelta:
  1122  			t.Go = c.int64
  1123  		}
  1124  
  1125  	case *dwarf.FloatType:
  1126  		switch t.Size {
  1127  		default:
  1128  			fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
  1129  		case 4:
  1130  			t.Go = c.float32
  1131  		case 8:
  1132  			t.Go = c.float64
  1133  		}
  1134  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1135  			t.Align = c.ptrSize
  1136  		}
  1137  
  1138  	case *dwarf.ComplexType:
  1139  		switch t.Size {
  1140  		default:
  1141  			fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
  1142  		case 8:
  1143  			t.Go = c.complex64
  1144  		case 16:
  1145  			t.Go = c.complex128
  1146  		}
  1147  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1148  			t.Align = c.ptrSize
  1149  		}
  1150  
  1151  	case *dwarf.FuncType:
  1152  		// No attempt at translation: would enable calls
  1153  		// directly between worlds, but we need to moderate those.
  1154  		t.Go = c.uintptr
  1155  		t.Align = c.ptrSize
  1156  
  1157  	case *dwarf.IntType:
  1158  		if dt.BitSize > 0 {
  1159  			fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
  1160  		}
  1161  		switch t.Size {
  1162  		default:
  1163  			fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
  1164  		case 1:
  1165  			t.Go = c.int8
  1166  		case 2:
  1167  			t.Go = c.int16
  1168  		case 4:
  1169  			t.Go = c.int32
  1170  		case 8:
  1171  			t.Go = c.int64
  1172  		}
  1173  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1174  			t.Align = c.ptrSize
  1175  		}
  1176  
  1177  	case *dwarf.PtrType:
  1178  		t.Align = c.ptrSize
  1179  
  1180  		// Translate void* as unsafe.Pointer
  1181  		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
  1182  			t.Go = c.unsafePointer
  1183  			t.C.Set("void*")
  1184  			break
  1185  		}
  1186  
  1187  		gt := &ast.StarExpr{}
  1188  		t.Go = gt // publish before recursive call
  1189  		sub := c.Type(dt.Type, pos)
  1190  		gt.X = sub.Go
  1191  		t.C.Set("%s*", sub.C)
  1192  
  1193  	case *dwarf.QualType:
  1194  		// Ignore qualifier.
  1195  		t = c.Type(dt.Type, pos)
  1196  		c.m[dtype] = t
  1197  		return t
  1198  
  1199  	case *dwarf.StructType:
  1200  		// Convert to Go struct, being careful about alignment.
  1201  		// Have to give it a name to simulate C "struct foo" references.
  1202  		tag := dt.StructName
  1203  		if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
  1204  			break
  1205  		}
  1206  		if tag == "" {
  1207  			tag = "__" + strconv.Itoa(tagGen)
  1208  			tagGen++
  1209  		} else if t.C.Empty() {
  1210  			t.C.Set(dt.Kind + " " + tag)
  1211  		}
  1212  		name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
  1213  		t.Go = name // publish before recursive calls
  1214  		goIdent[name.Name] = name
  1215  		if dt.ByteSize < 0 {
  1216  			// Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
  1217  			// so execute the basic things that the struct case would do
  1218  			// other than try to determine a Go representation.
  1219  			tt := *t
  1220  			tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
  1221  			tt.Go = c.Ident("struct{}")
  1222  			typedef[name.Name] = &tt
  1223  			break
  1224  		}
  1225  		switch dt.Kind {
  1226  		case "class", "union":
  1227  			t.Go = c.Opaque(t.Size)
  1228  			if t.C.Empty() {
  1229  				t.C.Set("__typeof__(unsigned char[%d])", t.Size)
  1230  			}
  1231  			t.Align = 1 // TODO: should probably base this on field alignment.
  1232  			typedef[name.Name] = t
  1233  		case "struct":
  1234  			g, csyntax, align := c.Struct(dt, pos)
  1235  			if t.C.Empty() {
  1236  				t.C.Set(csyntax)
  1237  			}
  1238  			t.Align = align
  1239  			tt := *t
  1240  			if tag != "" {
  1241  				tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
  1242  			}
  1243  			tt.Go = g
  1244  			typedef[name.Name] = &tt
  1245  		}
  1246  
  1247  	case *dwarf.TypedefType:
  1248  		// Record typedef for printing.
  1249  		if dt.Name == "_GoString_" {
  1250  			// Special C name for Go string type.
  1251  			// Knows string layout used by compilers: pointer plus length,
  1252  			// which rounds up to 2 pointers after alignment.
  1253  			t.Go = c.string
  1254  			t.Size = c.ptrSize * 2
  1255  			t.Align = c.ptrSize
  1256  			break
  1257  		}
  1258  		if dt.Name == "_GoBytes_" {
  1259  			// Special C name for Go []byte type.
  1260  			// Knows slice layout used by compilers: pointer, length, cap.
  1261  			t.Go = c.Ident("[]byte")
  1262  			t.Size = c.ptrSize + 4 + 4
  1263  			t.Align = c.ptrSize
  1264  			break
  1265  		}
  1266  		name := c.Ident("_Ctype_" + dt.Name)
  1267  		goIdent[name.Name] = name
  1268  		t.Go = name // publish before recursive call
  1269  		sub := c.Type(dt.Type, pos)
  1270  		t.Size = sub.Size
  1271  		t.Align = sub.Align
  1272  		oldType := typedef[name.Name]
  1273  		if oldType == nil {
  1274  			tt := *t
  1275  			tt.Go = sub.Go
  1276  			typedef[name.Name] = &tt
  1277  		}
  1278  
  1279  		// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
  1280  		// use that as the Go form for this typedef too, so that the typedef will be interchangeable
  1281  		// with the base type.
  1282  		// In -godefs and -cdefs mode, do this for all typedefs.
  1283  		if isStructUnionClass(sub.Go) || *godefs || *cdefs {
  1284  			t.Go = sub.Go
  1285  
  1286  			if isStructUnionClass(sub.Go) {
  1287  				// Use the typedef name for C code.
  1288  				typedef[sub.Go.(*ast.Ident).Name].C = t.C
  1289  			}
  1290  
  1291  			// If we've seen this typedef before, and it
  1292  			// was an anonymous struct/union/class before
  1293  			// too, use the old definition.
  1294  			// TODO: it would be safer to only do this if
  1295  			// we verify that the types are the same.
  1296  			if oldType != nil && isStructUnionClass(oldType.Go) {
  1297  				t.Go = oldType.Go
  1298  			}
  1299  		}
  1300  
  1301  	case *dwarf.UcharType:
  1302  		if t.Size != 1 {
  1303  			fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
  1304  		}
  1305  		t.Go = c.uint8
  1306  		t.Align = 1
  1307  
  1308  	case *dwarf.UintType:
  1309  		if dt.BitSize > 0 {
  1310  			fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
  1311  		}
  1312  		switch t.Size {
  1313  		default:
  1314  			fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
  1315  		case 1:
  1316  			t.Go = c.uint8
  1317  		case 2:
  1318  			t.Go = c.uint16
  1319  		case 4:
  1320  			t.Go = c.uint32
  1321  		case 8:
  1322  			t.Go = c.uint64
  1323  		}
  1324  		if t.Align = t.Size; t.Align >= c.ptrSize {
  1325  			t.Align = c.ptrSize
  1326  		}
  1327  
  1328  	case *dwarf.VoidType:
  1329  		t.Go = c.goVoid
  1330  		t.C.Set("void")
  1331  		t.Align = 1
  1332  	}
  1333  
  1334  	switch dtype.(type) {
  1335  	case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
  1336  		s := dtype.Common().Name
  1337  		if s != "" {
  1338  			if ss, ok := dwarfToName[s]; ok {
  1339  				s = ss
  1340  			}
  1341  			s = strings.Join(strings.Split(s, " "), "") // strip spaces
  1342  			name := c.Ident("_Ctype_" + s)
  1343  			tt := *t
  1344  			typedef[name.Name] = &tt
  1345  			if !*godefs && !*cdefs {
  1346  				t.Go = name
  1347  			}
  1348  		}
  1349  	}
  1350  
  1351  	if t.Size <= 0 {
  1352  		// Clang does not record the size of a pointer in its DWARF entry,
  1353  		// so if dtype is an array, the call to dtype.Size at the top of the function
  1354  		// computed the size as the array length * 0 = 0.
  1355  		// The type switch called Type (this function) recursively on the pointer
  1356  		// entry, and the code near the top of the function updated the size to
  1357  		// be correct, so calling dtype.Size again will produce the correct value.
  1358  		t.Size = dtype.Size()
  1359  		if t.Size < 0 {
  1360  			// Unsized types are [0]byte, unless they're typedefs of other types
  1361  			// or structs with tags.
  1362  			// if so, use the name we've already defined.
  1363  			t.Size = 0
  1364  			switch dt := dtype.(type) {
  1365  			case *dwarf.TypedefType:
  1366  				// ok
  1367  			case *dwarf.StructType:
  1368  				if dt.StructName != "" {
  1369  					break
  1370  				}
  1371  				t.Go = c.Opaque(0)
  1372  			default:
  1373  				t.Go = c.Opaque(0)
  1374  			}
  1375  			if t.C.Empty() {
  1376  				t.C.Set("void")
  1377  			}
  1378  			return t
  1379  		}
  1380  	}
  1381  
  1382  	if t.C.Empty() {
  1383  		fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
  1384  	}
  1385  
  1386  	return t
  1387  }
  1388  
  1389  // isStructUnionClass reports whether the type described by the Go syntax x
  1390  // is a struct, union, or class with a tag.
  1391  func isStructUnionClass(x ast.Expr) bool {
  1392  	id, ok := x.(*ast.Ident)
  1393  	if !ok {
  1394  		return false
  1395  	}
  1396  	name := id.Name
  1397  	return strings.HasPrefix(name, "_Ctype_struct_") ||
  1398  		strings.HasPrefix(name, "_Ctype_union_") ||
  1399  		strings.HasPrefix(name, "_Ctype_class_")
  1400  }
  1401  
  1402  // FuncArg returns a Go type with the same memory layout as
  1403  // dtype when used as the type of a C function argument.
  1404  func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
  1405  	t := c.Type(dtype, pos)
  1406  	switch dt := dtype.(type) {
  1407  	case *dwarf.ArrayType:
  1408  		// Arrays are passed implicitly as pointers in C.
  1409  		// In Go, we must be explicit.
  1410  		tr := &TypeRepr{}
  1411  		tr.Set("%s*", t.C)
  1412  		return &Type{
  1413  			Size:  c.ptrSize,
  1414  			Align: c.ptrSize,
  1415  			Go:    &ast.StarExpr{X: t.Go},
  1416  			C:     tr,
  1417  		}
  1418  	case *dwarf.TypedefType:
  1419  		// C has much more relaxed rules than Go for
  1420  		// implicit type conversions.  When the parameter
  1421  		// is type T defined as *X, simulate a little of the
  1422  		// laxness of C by making the argument *X instead of T.
  1423  		if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
  1424  			// Unless the typedef happens to point to void* since
  1425  			// Go has special rules around using unsafe.Pointer.
  1426  			if _, void := base(ptr.Type).(*dwarf.VoidType); void {
  1427  				break
  1428  			}
  1429  
  1430  			t = c.Type(ptr, pos)
  1431  			if t == nil {
  1432  				return nil
  1433  			}
  1434  
  1435  			// Remember the C spelling, in case the struct
  1436  			// has __attribute__((unavailable)) on it.  See issue 2888.
  1437  			t.Typedef = dt.Name
  1438  		}
  1439  	}
  1440  	return t
  1441  }
  1442  
  1443  // FuncType returns the Go type analogous to dtype.
  1444  // There is no guarantee about matching memory layout.
  1445  func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
  1446  	p := make([]*Type, len(dtype.ParamType))
  1447  	gp := make([]*ast.Field, len(dtype.ParamType))
  1448  	for i, f := range dtype.ParamType {
  1449  		// gcc's DWARF generator outputs a single DotDotDotType parameter for
  1450  		// function pointers that specify no parameters (e.g. void
  1451  		// (*__cgo_0)()).  Treat this special case as void.  This case is
  1452  		// invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
  1453  		// legal).
  1454  		if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
  1455  			p, gp = nil, nil
  1456  			break
  1457  		}
  1458  		p[i] = c.FuncArg(f, pos)
  1459  		gp[i] = &ast.Field{Type: p[i].Go}
  1460  	}
  1461  	var r *Type
  1462  	var gr []*ast.Field
  1463  	if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok {
  1464  		gr = []*ast.Field{{Type: c.goVoid}}
  1465  	} else if dtype.ReturnType != nil {
  1466  		r = c.Type(dtype.ReturnType, pos)
  1467  		gr = []*ast.Field{{Type: r.Go}}
  1468  	}
  1469  	return &FuncType{
  1470  		Params: p,
  1471  		Result: r,
  1472  		Go: &ast.FuncType{
  1473  			Params:  &ast.FieldList{List: gp},
  1474  			Results: &ast.FieldList{List: gr},
  1475  		},
  1476  	}
  1477  }
  1478  
  1479  // Identifier
  1480  func (c *typeConv) Ident(s string) *ast.Ident {
  1481  	return ast.NewIdent(s)
  1482  }
  1483  
  1484  // Opaque type of n bytes.
  1485  func (c *typeConv) Opaque(n int64) ast.Expr {
  1486  	return &ast.ArrayType{
  1487  		Len: c.intExpr(n),
  1488  		Elt: c.byte,
  1489  	}
  1490  }
  1491  
  1492  // Expr for integer n.
  1493  func (c *typeConv) intExpr(n int64) ast.Expr {
  1494  	return &ast.BasicLit{
  1495  		Kind:  token.INT,
  1496  		Value: strconv.FormatInt(n, 10),
  1497  	}
  1498  }
  1499  
  1500  // Add padding of given size to fld.
  1501  func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
  1502  	n := len(fld)
  1503  	fld = fld[0 : n+1]
  1504  	fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
  1505  	return fld
  1506  }
  1507  
  1508  // Struct conversion: return Go and (6g) C syntax for type.
  1509  func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
  1510  	var buf bytes.Buffer
  1511  	buf.WriteString("struct {")
  1512  	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
  1513  	off := int64(0)
  1514  
  1515  	// Rename struct fields that happen to be named Go keywords into
  1516  	// _{keyword}.  Create a map from C ident -> Go ident.  The Go ident will
  1517  	// be mangled.  Any existing identifier that already has the same name on
  1518  	// the C-side will cause the Go-mangled version to be prefixed with _.
  1519  	// (e.g. in a struct with fields '_type' and 'type', the latter would be
  1520  	// rendered as '__type' in Go).
  1521  	ident := make(map[string]string)
  1522  	used := make(map[string]bool)
  1523  	for _, f := range dt.Field {
  1524  		ident[f.Name] = f.Name
  1525  		used[f.Name] = true
  1526  	}
  1527  
  1528  	if !*godefs && !*cdefs {
  1529  		for cid, goid := range ident {
  1530  			if token.Lookup(goid).IsKeyword() {
  1531  				// Avoid keyword
  1532  				goid = "_" + goid
  1533  
  1534  				// Also avoid existing fields
  1535  				for _, exist := used[goid]; exist; _, exist = used[goid] {
  1536  					goid = "_" + goid
  1537  				}
  1538  
  1539  				used[goid] = true
  1540  				ident[cid] = goid
  1541  			}
  1542  		}
  1543  	}
  1544  
  1545  	anon := 0
  1546  	for _, f := range dt.Field {
  1547  		if f.ByteOffset > off {
  1548  			fld = c.pad(fld, f.ByteOffset-off)
  1549  			off = f.ByteOffset
  1550  		}
  1551  		t := c.Type(f.Type, pos)
  1552  		tgo := t.Go
  1553  		size := t.Size
  1554  		talign := t.Align
  1555  		if f.BitSize > 0 {
  1556  			if f.BitSize%8 != 0 {
  1557  				continue
  1558  			}
  1559  			size = f.BitSize / 8
  1560  			name := tgo.(*ast.Ident).String()
  1561  			if strings.HasPrefix(name, "int") {
  1562  				name = "int"
  1563  			} else {
  1564  				name = "uint"
  1565  			}
  1566  			tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
  1567  			talign = size
  1568  		}
  1569  
  1570  		if talign > 0 && f.ByteOffset%talign != 0 {
  1571  			// Drop misaligned fields, the same way we drop integer bit fields.
  1572  			// The goal is to make available what can be made available.
  1573  			// Otherwise one bad and unneeded field in an otherwise okay struct
  1574  			// makes the whole program not compile. Much of the time these
  1575  			// structs are in system headers that cannot be corrected.
  1576  			continue
  1577  		}
  1578  		n := len(fld)
  1579  		fld = fld[0 : n+1]
  1580  		name := f.Name
  1581  		if name == "" {
  1582  			name = fmt.Sprintf("anon%d", anon)
  1583  			anon++
  1584  			ident[name] = name
  1585  		}
  1586  		fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
  1587  		off += size
  1588  		buf.WriteString(t.C.String())
  1589  		buf.WriteString(" ")
  1590  		buf.WriteString(name)
  1591  		buf.WriteString("; ")
  1592  		if talign > align {
  1593  			align = talign
  1594  		}
  1595  	}
  1596  	if off < dt.ByteSize {
  1597  		fld = c.pad(fld, dt.ByteSize-off)
  1598  		off = dt.ByteSize
  1599  	}
  1600  	if off != dt.ByteSize {
  1601  		fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
  1602  	}
  1603  	buf.WriteString("}")
  1604  	csyntax = buf.String()
  1605  
  1606  	if *godefs || *cdefs {
  1607  		godefsFields(fld)
  1608  	}
  1609  	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
  1610  	return
  1611  }
  1612  
  1613  func upper(s string) string {
  1614  	if s == "" {
  1615  		return ""
  1616  	}
  1617  	r, size := utf8.DecodeRuneInString(s)
  1618  	if r == '_' {
  1619  		return "X" + s
  1620  	}
  1621  	return string(unicode.ToUpper(r)) + s[size:]
  1622  }
  1623  
  1624  // godefsFields rewrites field names for use in Go or C definitions.
  1625  // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
  1626  // converts names to upper case, and rewrites _ into Pad_godefs_n,
  1627  // so that all fields are exported.
  1628  func godefsFields(fld []*ast.Field) {
  1629  	prefix := fieldPrefix(fld)
  1630  	npad := 0
  1631  	for _, f := range fld {
  1632  		for _, n := range f.Names {
  1633  			if n.Name != prefix {
  1634  				n.Name = strings.TrimPrefix(n.Name, prefix)
  1635  			}
  1636  			if n.Name == "_" {
  1637  				// Use exported name instead.
  1638  				n.Name = "Pad_cgo_" + strconv.Itoa(npad)
  1639  				npad++
  1640  			}
  1641  			if !*cdefs {
  1642  				n.Name = upper(n.Name)
  1643  			}
  1644  		}
  1645  		p := &f.Type
  1646  		t := *p
  1647  		if star, ok := t.(*ast.StarExpr); ok {
  1648  			star = &ast.StarExpr{X: star.X}
  1649  			*p = star
  1650  			p = &star.X
  1651  			t = *p
  1652  		}
  1653  		if id, ok := t.(*ast.Ident); ok {
  1654  			if id.Name == "unsafe.Pointer" {
  1655  				*p = ast.NewIdent("*byte")
  1656  			}
  1657  		}
  1658  	}
  1659  }
  1660  
  1661  // fieldPrefix returns the prefix that should be removed from all the
  1662  // field names when generating the C or Go code.  For generated
  1663  // C, we leave the names as is (tv_sec, tv_usec), since that's what
  1664  // people are used to seeing in C.  For generated Go code, such as
  1665  // package syscall's data structures, we drop a common prefix
  1666  // (so sec, usec, which will get turned into Sec, Usec for exporting).
  1667  func fieldPrefix(fld []*ast.Field) string {
  1668  	if *cdefs {
  1669  		return ""
  1670  	}
  1671  	prefix := ""
  1672  	for _, f := range fld {
  1673  		for _, n := range f.Names {
  1674  			// Ignore field names that don't have the prefix we're
  1675  			// looking for.  It is common in C headers to have fields
  1676  			// named, say, _pad in an otherwise prefixed header.
  1677  			// If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
  1678  			// still want to remove the tv_ prefix.
  1679  			// The check for "orig_" here handles orig_eax in the
  1680  			// x86 ptrace register sets, which otherwise have all fields
  1681  			// with reg_ prefixes.
  1682  			if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
  1683  				continue
  1684  			}
  1685  			i := strings.Index(n.Name, "_")
  1686  			if i < 0 {
  1687  				continue
  1688  			}
  1689  			if prefix == "" {
  1690  				prefix = n.Name[:i+1]
  1691  			} else if prefix != n.Name[:i+1] {
  1692  				return ""
  1693  			}
  1694  		}
  1695  	}
  1696  	return prefix
  1697  }