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.
5 // Annotate Ref in Prog with C types by parsing gcc debug output.
6 // Conversion of debug output to Go types.
32 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines")
33 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations")
35 var nameToC = map[string]string{
36 "schar": "signed char",
37 "uchar": "unsigned char",
38 "ushort": "unsigned short",
39 "uint": "unsigned int",
40 "ulong": "unsigned long",
41 "longlong": "long long",
42 "ulonglong": "unsigned long long",
43 "complexfloat": "float _Complex",
44 "complexdouble": "double _Complex",
47 // cname returns the C name to use for C.s.
48 // The expansions are listed in nameToC and also
49 // struct_foo becomes "struct foo", and similarly for
51 func cname(s string) string {
52 if t, ok := nameToC[s]; ok {
56 if strings.HasPrefix(s, "struct_") {
57 return "struct " + s[len("struct_"):]
59 if strings.HasPrefix(s, "union_") {
60 return "union " + s[len("union_"):]
62 if strings.HasPrefix(s, "enum_") {
63 return "enum " + s[len("enum_"):]
65 if strings.HasPrefix(s, "sizeof_") {
66 return "sizeof(" + cname(s[len("sizeof_"):]) + ")"
71 // DiscardCgoDirectives processes the import C preamble, and discards
72 // all #cgo CFLAGS and LDFLAGS directives, so they don't make their
73 // way into _cgo_export.h.
74 func (f *File) DiscardCgoDirectives() {
75 linesIn := strings.Split(f.Preamble, "\n")
76 linesOut := make([]string, 0, len(linesIn))
77 for _, line := range linesIn {
78 l := strings.TrimSpace(line)
79 if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
80 linesOut = append(linesOut, line)
82 linesOut = append(linesOut, "")
85 f.Preamble = strings.Join(linesOut, "\n")
88 // addToFlag appends args to flag. All flags are later written out onto the
89 // _cgo_flags file for the build system to use.
90 func (p *Package) addToFlag(flag string, args []string) {
92 // We'll also need these when preprocessing for dwarf information.
93 // However, discard any -g options: we need to be able
94 // to parse the debug info, so stick to what we expect.
95 for _, arg := range args {
96 if !strings.HasPrefix(arg, "-g") {
97 p.GccOptions = append(p.GccOptions, arg)
103 for i, arg := range args {
104 // The go tool will pass us a -I option pointing to objdir;
105 // we don't need to record that for later, as the objdir
106 // will disappear anyhow.
108 // Discard argument in "-I objdir" case.
110 } else if strings.HasPrefix(arg, "-I") && strings.HasPrefix(arg[2:], *objDir) {
111 // This is -Iobjdir. Don't save this argument.
112 } else if arg == "-I" && i+1 < len(args) && strings.HasPrefix(args[i+1], *objDir) {
113 // This is -I objdir. Don't save this argument
117 p.CgoFlags[flag] = append(p.CgoFlags[flag], arg)
122 // splitQuoted splits the string s around each instance of one or more consecutive
123 // white space characters while taking into account quotes and escaping, and
124 // returns an array of substrings of s or an empty list if s contains only white space.
125 // Single quotes and double quotes are recognized to prevent splitting within the
126 // quoted region, and are removed from the resulting substrings. If a quote in s
127 // isn't closed err will be set and r will have the unclosed argument as the
128 // last element. The backslash is used for escaping.
130 // For example, the following string:
132 // `a b:"c d" 'e''f' "g\""`
134 // Would be parsed as:
136 // []string{"a", "b:c d", "ef", `g"`}
138 func splitQuoted(s string) (r []string, err error) {
140 arg := make([]rune, len(s))
145 for _, r := range s {
157 case r == '"' || r == '\'':
161 case unicode.IsSpace(r):
164 args = append(args, string(arg[:i]))
173 args = append(args, string(arg[:i]))
176 err = errors.New("unclosed quote")
178 err = errors.New("unfinished escaping")
183 // Translate rewrites f.AST, the original Go input, to remove
184 // references to the imported package C, replacing them with
185 // references to the equivalent Go types, functions, and variables.
186 func (p *Package) Translate(f *File) {
187 for _, cref := range f.Ref {
188 // Convert C.ulong to C.unsigned long, etc.
189 cref.Name.C = cname(cref.Name.Go)
193 conv.Init(p.PtrSize, p.IntSize)
196 p.typedefs = map[string]bool{}
199 for len(p.typedefs) > numTypedefs {
200 numTypedefs = len(p.typedefs)
201 // Also ask about any typedefs we've seen so far.
202 for _, info := range p.typedefList {
207 f.Name[info.typedef] = n
208 f.NamePos[n] = info.pos
210 needType := p.guessKinds(f)
211 if len(needType) > 0 {
212 p.loadDWARF(f, &conv, needType)
215 // In godefs mode we're OK with the typedefs, which
216 // will presumably also be defined in the file, we
217 // don't want to resolve them to their base types.
223 if p.rewriteCalls(f) {
224 // Add `import _cgo_unsafe "unsafe"` after the package statement.
225 f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"")
230 // loadDefines coerces gcc into spitting out the #defines in use
231 // in the file f and saves relevant renamings in f.Name[name].Define.
232 func (p *Package) loadDefines(f *File) {
234 b.WriteString(builtinProlog)
235 b.WriteString(f.Preamble)
236 stdout := p.gccDefines(b.Bytes())
238 for _, line := range strings.Split(stdout, "\n") {
239 if len(line) < 9 || line[0:7] != "#define" {
243 line = strings.TrimSpace(line[8:])
246 spaceIndex := strings.Index(line, " ")
247 tabIndex := strings.Index(line, "\t")
249 if spaceIndex == -1 && tabIndex == -1 {
251 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
252 key = line[0:spaceIndex]
253 val = strings.TrimSpace(line[spaceIndex:])
255 key = line[0:tabIndex]
256 val = strings.TrimSpace(line[tabIndex:])
259 if key == "__clang__" {
263 if n := f.Name[key]; n != nil {
265 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
272 // guessKinds tricks gcc into revealing the kind of each
273 // name xxx for the references C.xxx in the Go input.
274 // The kind is either a constant, type, or variable.
275 func (p *Package) guessKinds(f *File) []*Name {
276 // Determine kinds for names we already know about,
277 // like #defines or 'struct foo', before bothering with gcc.
278 var names, needType []*Name
279 optional := map[*Name]bool{}
280 for _, key := range nameKeys(f.Name) {
282 // If we've already found this name as a #define
283 // and we can translate it as a constant value, do so.
285 if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil {
287 // Turn decimal into hex, just for consistency
288 // with enum-derived constants. Otherwise
289 // in the cgo -godefs output half the constants
290 // are in hex and half are in whatever the #define used.
291 n.Const = fmt.Sprintf("%#x", i)
292 } else if n.Define[0] == '\'' {
293 if _, err := parser.ParseExpr(n.Define); err == nil {
297 } else if n.Define[0] == '"' {
298 if _, err := parser.ParseExpr(n.Define); err == nil {
309 // If this is a struct, union, or enum type name, no need to guess the kind.
310 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
312 needType = append(needType, n)
316 if goos == "darwin" && strings.HasSuffix(n.C, "Ref") {
317 // For FooRef, find out if FooGetTypeID exists.
318 s := n.C[:len(n.C)-3] + "GetTypeID"
319 n := &Name{Go: s, C: s}
320 names = append(names, n)
324 // Otherwise, we'll need to find out from gcc.
325 names = append(names, n)
328 // Bypass gcc if there's nothing left to find out.
333 // Coerce gcc into telling us whether each name is a type, a value, or undeclared.
334 // For names, find out whether they are integer constants.
335 // We used to look at specific warning or error messages here, but that tied the
336 // behavior too closely to specific versions of the compilers.
337 // Instead, arrange that we can infer what we need from only the presence or absence
338 // of an error on a specific line.
340 // For each name, we generate these lines, where xxx is the index in toSniff plus one.
342 // #line xxx "not-declared"
343 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; }
344 // #line xxx "not-type"
345 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; }
346 // #line xxx "not-int-const"
347 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; }
348 // #line xxx "not-num-const"
349 // void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
350 // #line xxx "not-str-lit"
351 // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
353 // If we see an error at not-declared:xxx, the corresponding name is not declared.
354 // If we see an error at not-type:xxx, the corresponding name is a type.
355 // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
356 // If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
357 // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
359 // The specific input forms are chosen so that they are valid C syntax regardless of
360 // whether name denotes a type or an expression.
363 b.WriteString(builtinProlog)
364 b.WriteString(f.Preamble)
366 for i, n := range names {
367 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
368 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+
369 "#line %d \"not-type\"\n"+
370 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+
371 "#line %d \"not-int-const\"\n"+
372 "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+
373 "#line %d \"not-num-const\"\n"+
374 "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
375 "#line %d \"not-str-lit\"\n"+
376 "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
384 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
385 "int __cgo__1 = __cgo__2;\n")
387 stderr := p.gccErrors(b.Bytes())
389 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
393 sniff := make([]int, len(names))
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
409 isError := strings.Contains(line, ": error:")
410 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
411 if !isError && !isErrorNote {
415 c1 := strings.Index(line, ":")
419 c2 := strings.Index(line[c1+1:], ":")
425 filename := line[:c1]
426 i, _ := strconv.Atoi(line[c1+1 : c2])
428 if i < 0 || i >= len(names) {
430 sawUnmatchedErrors = true
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.
444 sniff[i] |= notDeclared
447 case "not-int-const":
448 sniff[i] |= notIntConst
449 case "not-num-const":
450 sniff[i] |= notNumConst
452 sniff[i] |= notStrLiteral
455 sawUnmatchedErrors = true
460 sawUnmatchedErrors = false
464 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
467 for i, n := range names {
470 if sniff[i]¬Declared != 0 && optional[n] {
471 // Ignore optional undeclared identifiers.
472 // Don't report an error, and skip adding n to the needType array.
475 error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
476 case notStrLiteral | notType:
478 case notIntConst | notStrLiteral | notType:
480 case notIntConst | notNumConst | notType:
482 case notIntConst | notNumConst | notStrLiteral:
484 case notIntConst | notNumConst | notStrLiteral | notType:
487 needType = append(needType, n)
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(f.Preamble))
494 if len(preambleErrors) > 0 {
495 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
498 fatalf("unresolved names")
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.
513 // __typeof__(names[i]) *__cgo__i;
514 // for each entry in names and then dereference the type we
515 // learn for __cgo__i.
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)
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)
534 fmt.Fprintf(&b, "\t0,\n")
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
542 fmt.Fprintf(&b, "\t1\n")
543 fmt.Fprintf(&b, "};\n")
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)
551 fmt.Fprintf(&b, "\t0,\n")
554 fmt.Fprintf(&b, "\t1\n")
555 fmt.Fprintf(&b, "};\n")
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)
565 d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names))
567 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
568 types := make([]dwarf.Type, len(names))
573 fatalf("reading DWARF entry: %s", err)
579 case dwarf.TagVariable:
580 name, _ := e.Val(dwarf.AttrName).(string)
581 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
582 if name == "" || typOff == 0 {
583 if e.Val(dwarf.AttrSpecification) != nil {
584 // Since we are reading all the DWARF,
585 // assume we will see the variable elsewhere.
588 fatalf("malformed DWARF TagVariable entry")
590 if !strings.HasPrefix(name, "__cgo__") {
593 typ, err := d.Type(typOff)
595 fatalf("loading DWARF type: %s", err)
597 t, ok := typ.(*dwarf.PtrType)
599 fatalf("internal error: %s has non-pointer type", name)
601 i, err := strconv.Atoi(name[7:])
603 fatalf("malformed __cgo__ name: %s", name)
606 p.recordTypedefs(t.Type, f.NamePos[names[i]])
608 if e.Tag != dwarf.TagCompileUnit {
613 // Record types and typedef information.
614 for i, n := range names {
615 if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
616 conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
619 for i, n := range names {
624 f, fok := types[i].(*dwarf.FuncType)
625 if n.Kind != "type" && fok {
627 n.FuncType = conv.FuncType(f, pos)
629 n.Type = conv.Type(types[i], pos)
633 if _, ok := types[i].(*dwarf.UintType); ok {
634 n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
636 n.Const = fmt.Sprintf("%#x", ints[i])
640 if i >= len(floats) {
643 switch base(types[i]).(type) {
644 case *dwarf.IntType, *dwarf.UintType:
645 // This has an integer type so it's
646 // not really a floating point
647 // constant. This can happen when the
648 // C compiler complains about using
649 // the value as an integer constant,
650 // but not as a general constant.
651 // Treat this as a variable of the
652 // appropriate type, not a constant,
653 // to get C-style type handling,
654 // avoiding the problem that C permits
655 // uint64(-1) but Go does not.
659 n.Const = fmt.Sprintf("%f", floats[i])
663 n.Const = fmt.Sprintf("%q", strs[i])
671 // recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children.
672 func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) {
673 p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{})
676 func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) {
683 visited[dtype] = true
684 switch dt := dtype.(type) {
685 case *dwarf.TypedefType:
686 if strings.HasPrefix(dt.Name, "__builtin") {
687 // Don't look inside builtin types. There be dragons.
690 if !p.typedefs[dt.Name] {
691 p.typedefs[dt.Name] = true
692 p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos})
693 p.recordTypedefs1(dt.Type, pos, visited)
696 p.recordTypedefs1(dt.Type, pos, visited)
697 case *dwarf.ArrayType:
698 p.recordTypedefs1(dt.Type, pos, visited)
699 case *dwarf.QualType:
700 p.recordTypedefs1(dt.Type, pos, visited)
701 case *dwarf.FuncType:
702 p.recordTypedefs1(dt.ReturnType, pos, visited)
703 for _, a := range dt.ParamType {
704 p.recordTypedefs1(a, pos, visited)
706 case *dwarf.StructType:
707 for _, f := range dt.Field {
708 p.recordTypedefs1(f.Type, pos, visited)
713 // prepareNames finalizes the Kind field of not-type names and sets
714 // the mangled name of all names.
715 func (p *Package) prepareNames(f *File) {
716 for _, n := range f.Name {
717 if n.Kind == "not-type" {
722 n.FuncType = &FuncType{
725 Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}},
734 // mangleName does name mangling to translate names
735 // from the original Go source files to the names
736 // used in the final Go files generated by cgo.
737 func (p *Package) mangleName(n *Name) {
738 // When using gccgo variables have to be
739 // exported so that they become global symbols
740 // that the C code can refer to.
742 if *gccgo && n.IsVar() {
745 n.Mangle = prefix + n.Kind + "_" + n.Go
748 func (f *File) isMangledName(s string) bool {
750 if strings.HasPrefix(s, prefix) {
752 for _, k := range nameKinds {
753 if strings.HasPrefix(t, k+"_") {
761 // rewriteCalls rewrites all calls that pass pointers to check that
762 // they follow the rules for passing pointers between Go and C.
763 // This reports whether the package needs to import unsafe as _cgo_unsafe.
764 func (p *Package) rewriteCalls(f *File) bool {
766 // Walk backward so that in C.f1(C.f2()) we rewrite C.f2 first.
767 for _, call := range f.Calls {
771 start := f.offset(call.Call.Pos())
772 end := f.offset(call.Call.End())
773 str, nu := p.rewriteCall(f, call)
775 f.Edit.Replace(start, end, str)
784 // rewriteCall rewrites one call to add pointer checks.
785 // If any pointer checks are required, we rewrite the call into a
786 // function literal that calls _cgoCheckPointer for each pointer
787 // argument and then calls the original function.
788 // This returns the rewritten call and whether the package needs to
789 // import unsafe as _cgo_unsafe.
790 // If it returns the empty string, the call did not need to be rewritten.
791 func (p *Package) rewriteCall(f *File, call *Call) (string, bool) {
792 // This is a call to C.xxx; set goname to "xxx".
793 // It may have already been mangled by rewriteName.
795 switch fun := call.Call.Fun.(type) {
796 case *ast.SelectorExpr:
797 goname = fun.Sel.Name
799 goname = strings.TrimPrefix(fun.Name, "_C2func_")
800 goname = strings.TrimPrefix(goname, "_Cfunc_")
802 if goname == "" || goname == "malloc" {
805 name := f.Name[goname]
806 if name == nil || name.Kind != "func" {
807 // Probably a type conversion.
811 params := name.FuncType.Params
812 args := call.Call.Args
814 // Avoid a crash if the number of arguments doesn't match
815 // the number of parameters.
816 // This will be caught when the generated file is compiled.
817 if len(args) != len(params) {
822 for i, param := range params {
823 if p.needsPointerCheck(f, param.Go, args[i]) {
832 // We need to rewrite this call.
837 // _cgoCheckPointer(_cgo0, nil)
840 // Using a function literal like this lets us evaluate the
841 // function arguments only once while doing pointer checks.
842 // This is particularly useful when passing additional arguments
843 // to _cgoCheckPointer, as done in checkIndex and checkAddr.
845 // When the function argument is a conversion to unsafe.Pointer,
846 // we unwrap the conversion before checking the pointer,
847 // and then wrap again when calling C.f. This lets us check
848 // the real type of the pointer in some cases. See issue #25941.
850 // When the call to C.f is deferred, we use an additional function
851 // literal to evaluate the arguments at the right time.
852 // defer func() func() {
855 // _cgoCheckPointer(_cgo0, nil)
859 // This works because the defer statement evaluates the first
860 // function literal in order to get the function to call.
863 sb.WriteString("func() ")
865 sb.WriteString("func() ")
872 // Check whether this call expects two results.
873 for _, ref := range f.Ref {
874 if ref.Expr != &call.Call.Fun {
877 if ref.Context == ctxCall2 {
885 // Add the result type, if any.
886 if name.FuncType.Result != nil {
887 rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
888 if rtype != name.FuncType.Result.Go {
891 sb.WriteString(gofmtLine(rtype))
895 // Add the second result type, if any.
897 if name.FuncType.Result == nil {
898 // An explicit void result looks odd but it
899 // seems to be how cgo has worked historically.
900 sb.WriteString("_Ctype_void")
902 sb.WriteString(", error)")
908 // Define _cgoN for each argument value.
909 // Write _cgoCheckPointer calls to sbCheck.
910 var sbCheck bytes.Buffer
911 for i, param := range params {
913 arg, nu := p.mangle(f, &args[i])
918 // Use "var x T = ..." syntax to explicitly convert untyped
919 // constants to the parameter type, to avoid a type mismatch.
920 ptype := p.rewriteUnsafe(param.Go)
922 if !p.needsPointerCheck(f, param.Go, args[i]) || param.BadPointer {
923 if ptype != param.Go {
926 fmt.Fprintf(&sb, "var _cgo%d %s = %s; ", i,
927 gofmtLine(ptype), gofmtPos(arg, origArg.Pos()))
932 if p.checkIndex(&sb, &sbCheck, arg, i) {
937 if p.checkAddr(&sb, &sbCheck, arg, i) {
941 fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
942 fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d, nil); ", i)
946 sb.WriteString("return func() { ")
949 // Write out the calls to _cgoCheckPointer.
950 sb.WriteString(sbCheck.String())
953 sb.WriteString("return ")
956 m, nu := p.mangle(f, &call.Call.Fun)
960 sb.WriteString(gofmtLine(m))
963 for i := range params {
967 fmt.Fprintf(&sb, "_cgo%d", i)
969 sb.WriteString("); ")
979 return sb.String(), needsUnsafe
982 // needsPointerCheck reports whether the type t needs a pointer check.
983 // This is true if t is a pointer and if the value to which it points
984 // might contain a pointer.
985 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
986 // An untyped nil does not need a pointer check, and when
987 // _cgoCheckPointer returns the untyped nil the type assertion we
988 // are going to insert will fail. Easier to just skip nil arguments.
989 // TODO: Note that this fails if nil is shadowed.
990 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
994 return p.hasPointer(f, t, true)
997 // hasPointer is used by needsPointerCheck. If top is true it returns
998 // whether t is or contains a pointer that might point to a pointer.
999 // If top is false it reports whether t is or contains a pointer.
1001 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
1002 switch t := t.(type) {
1003 case *ast.ArrayType:
1008 return p.hasPointer(f, t.Elt, false)
1010 return p.hasPointer(f, t.Elt, top)
1011 case *ast.StructType:
1012 for _, field := range t.Fields.List {
1013 if p.hasPointer(f, field.Type, top) {
1018 case *ast.StarExpr: // Pointer type.
1022 // Check whether this is a pointer to a C union (or class)
1023 // type that contains a pointer.
1024 if unionWithPointer[t.X] {
1027 return p.hasPointer(f, t.X, false)
1028 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
1031 // TODO: Handle types defined within function.
1032 for _, d := range p.Decl {
1033 gd, ok := d.(*ast.GenDecl)
1034 if !ok || gd.Tok != token.TYPE {
1037 for _, spec := range gd.Specs {
1038 ts, ok := spec.(*ast.TypeSpec)
1042 if ts.Name.Name == t.Name {
1043 return p.hasPointer(f, ts.Type, top)
1047 if def := typedef[t.Name]; def != nil {
1048 return p.hasPointer(f, def.Go, top)
1050 if t.Name == "string" {
1053 if t.Name == "error" {
1056 if goTypes[t.Name] != nil {
1059 // We can't figure out the type. Conservative
1060 // approach is to assume it has a pointer.
1062 case *ast.SelectorExpr:
1063 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
1064 // Type defined in a different package.
1065 // Conservative approach is to assume it has a
1070 // Conservative approach: assume pointer.
1073 name := f.Name[t.Sel.Name]
1074 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
1075 return p.hasPointer(f, name.Type.Go, top)
1077 // We can't figure out the type. Conservative
1078 // approach is to assume it has a pointer.
1081 error_(t.Pos(), "could not understand type %s", gofmt(t))
1086 // mangle replaces references to C names in arg with the mangled names,
1087 // rewriting calls when it finds them.
1088 // It removes the corresponding references in f.Ref and f.Calls, so that we
1089 // don't try to do the replacement again in rewriteRef or rewriteCall.
1090 func (p *Package) mangle(f *File, arg *ast.Expr) (ast.Expr, bool) {
1091 needsUnsafe := false
1092 f.walk(arg, ctxExpr, func(f *File, arg interface{}, context astContext) {
1093 px, ok := arg.(*ast.Expr)
1097 sel, ok := (*px).(*ast.SelectorExpr)
1099 if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" {
1103 for _, r := range f.Ref {
1105 *px = p.rewriteName(f, r)
1114 call, ok := (*px).(*ast.CallExpr)
1119 for _, c := range f.Calls {
1120 if !c.Done && c.Call.Lparen == call.Lparen {
1121 cstr, nu := p.rewriteCall(f, c)
1123 // Smuggle the rewritten call through an ident.
1124 *px = ast.NewIdent(cstr)
1133 return *arg, needsUnsafe
1136 // checkIndex checks whether arg has the form &a[i], possibly inside
1137 // type conversions. If so, then in the general case it writes
1139 // _cgoNN := &cgoIndexNN[i] // with type conversions, if any
1140 // to sb, and writes
1141 // _cgoCheckPointer(_cgoNN, _cgoIndexNN)
1142 // to sbCheck, and returns true. If a is a simple variable or field reference,
1144 // _cgoIndexNN := &a
1145 // and dereferences the uses of _cgoIndexNN. Taking the address avoids
1146 // making a copy of an array.
1148 // This tells _cgoCheckPointer to check the complete contents of the
1149 // slice or array being indexed, but no other part of the memory allocation.
1150 func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1151 // Strip type conversions.
1154 c, ok := x.(*ast.CallExpr)
1155 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
1160 u, ok := x.(*ast.UnaryExpr)
1161 if !ok || u.Op != token.AND {
1164 index, ok := u.X.(*ast.IndexExpr)
1171 if p.isVariable(index.X) {
1176 fmt.Fprintf(sb, "_cgoIndex%d := %s%s; ", i, addr, gofmtPos(index.X, index.X.Pos()))
1178 index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i))
1180 index.X = &ast.StarExpr{X: index.X}
1182 fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1185 fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i)
1190 // checkAddr checks whether arg has the form &x, possibly inside type
1191 // conversions. If so, it writes
1193 // _cgoNN := _cgoBaseNN // with type conversions, if any
1194 // to sb, and writes
1195 // _cgoCheckPointer(_cgoBaseNN, true)
1196 // to sbCheck, and returns true. This tells _cgoCheckPointer to check
1197 // just the contents of the pointer being passed, not any other part
1198 // of the memory allocation. This is run after checkIndex, which looks
1199 // for the special case of &a[i], which requires different checks.
1200 func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool {
1201 // Strip type conversions.
1204 c, ok := (*px).(*ast.CallExpr)
1205 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
1210 if u, ok := (*px).(*ast.UnaryExpr); !ok || u.Op != token.AND {
1214 fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
1217 *px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i))
1218 fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
1221 // Use "0 == 0" to do the right thing in the unlikely event
1222 // that "true" is shadowed.
1223 fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgoBase%d, 0 == 0); ", i)
1228 // isType reports whether the expression is definitely a type.
1229 // This is conservative--it returns false for an unknown identifier.
1230 func (p *Package) isType(t ast.Expr) bool {
1231 switch t := t.(type) {
1232 case *ast.SelectorExpr:
1233 id, ok := t.X.(*ast.Ident)
1237 if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
1240 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
1245 // TODO: This ignores shadowing.
1247 case "unsafe.Pointer", "bool", "byte",
1248 "complex64", "complex128",
1250 "float32", "float64",
1251 "int", "int8", "int16", "int32", "int64",
1253 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
1257 if strings.HasPrefix(t.Name, "_Ctype_") {
1260 case *ast.ParenExpr:
1261 return p.isType(t.X)
1263 return p.isType(t.X)
1264 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
1265 *ast.MapType, *ast.ChanType:
1272 // isVariable reports whether x is a variable, possibly with field references.
1273 func (p *Package) isVariable(x ast.Expr) bool {
1274 switch x := x.(type) {
1277 case *ast.SelectorExpr:
1278 return p.isVariable(x.X)
1279 case *ast.IndexExpr:
1285 // rewriteUnsafe returns a version of t with references to unsafe.Pointer
1286 // rewritten to use _cgo_unsafe.Pointer instead.
1287 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
1288 switch t := t.(type) {
1290 // We don't see a SelectorExpr for unsafe.Pointer;
1291 // this is created by code in this file.
1292 if t.Name == "unsafe.Pointer" {
1293 return ast.NewIdent("_cgo_unsafe.Pointer")
1295 case *ast.ArrayType:
1296 t1 := p.rewriteUnsafe(t.Elt)
1302 case *ast.StructType:
1306 for _, f := range t.Fields.List {
1307 ft := p.rewriteUnsafe(f.Type)
1309 fields.List = append(fields.List, f)
1313 fields.List = append(fields.List, &fn)
1322 case *ast.StarExpr: // Pointer type.
1323 x1 := p.rewriteUnsafe(t.X)
1333 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1334 // Go equivalents, now that we have figured out the meaning of all
1335 // the xxx. In *godefs mode, rewriteRef replaces the names
1336 // with full definitions instead of mangled names.
1337 func (p *Package) rewriteRef(f *File) {
1338 // Keep a list of all the functions, to remove the ones
1339 // only used as expressions and avoid generating bridge
1341 functions := make(map[string]bool)
1343 for _, n := range f.Name {
1344 if n.Kind == "func" {
1345 functions[n.Go] = false
1349 // Now that we have all the name types filled in,
1350 // scan through the Refs to identify the ones that
1351 // are trying to do a ,err call. Also check that
1352 // functions are only used in calls.
1353 for _, r := range f.Ref {
1354 if r.Name.IsConst() && r.Name.Const == "" {
1355 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
1358 if r.Name.Kind == "func" {
1360 case ctxCall, ctxCall2:
1361 functions[r.Name.Go] = true
1365 expr := p.rewriteName(f, r)
1368 // Substitute definition for mangled type name.
1369 if id, ok := expr.(*ast.Ident); ok {
1370 if t := typedef[id.Name]; t != nil {
1373 if id.Name == r.Name.Mangle && r.Name.Const != "" {
1374 expr = ast.NewIdent(r.Name.Const)
1379 // Copy position information from old expr into new expr,
1380 // in case expression being replaced is first on line.
1381 // See golang.org/issue/6563.
1382 pos := (*r.Expr).Pos()
1383 if x, ok := expr.(*ast.Ident); ok {
1384 expr = &ast.Ident{NamePos: pos, Name: x.Name}
1387 // Change AST, because some later processing depends on it,
1388 // and also because -godefs mode still prints the AST.
1392 // Record source-level edit for cgo output.
1394 // Prepend a space in case the earlier code ends
1395 // with '/', which would give us a "//" comment.
1396 repl := " " + gofmtPos(expr, old.Pos())
1397 end := fset.Position(old.End())
1398 // Subtract 1 from the column if we are going to
1399 // append a close parenthesis. That will set the
1400 // correct column for the following characters.
1402 if r.Name.Kind != "type" {
1405 if end.Column > sub {
1406 repl = fmt.Sprintf("%s /*line :%d:%d*/", repl, end.Line, end.Column-sub)
1408 if r.Name.Kind != "type" {
1409 repl = "(" + repl + ")"
1411 f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
1415 // Remove functions only used as expressions, so their respective
1416 // bridge functions are not generated.
1417 for name, used := range functions {
1419 delete(f.Name, name)
1424 // rewriteName returns the expression used to rewrite a reference.
1425 func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
1426 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
1428 case ctxCall, ctxCall2:
1429 if r.Name.Kind != "func" {
1430 if r.Name.Kind == "type" {
1432 if r.Name.Type == nil {
1433 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1436 expr = r.Name.Type.Go
1439 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
1442 if r.Context == ctxCall2 {
1443 if r.Name.Go == "_CMalloc" {
1444 error_(r.Pos(), "no two-result form for C.malloc")
1447 // Invent new Name for the two-result function.
1448 n := f.Name["2"+r.Name.Go]
1453 n.Mangle = "_C2func_" + n.Go
1454 f.Name["2"+r.Name.Go] = n
1456 expr = ast.NewIdent(n.Mangle)
1461 switch r.Name.Kind {
1463 if builtinDefs[r.Name.C] != "" {
1464 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
1467 // Function is being used in an expression, to e.g. pass around a C function pointer.
1468 // Create a new Name for this Ref which causes the variable to be declared in Go land.
1469 fpName := "fp_" + r.Name.Go
1470 name := f.Name[fpName]
1476 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
1479 f.Name[fpName] = name
1482 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
1483 // function is defined in out.go and simply returns its argument. See
1485 expr = &ast.CallExpr{
1486 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
1487 Args: []ast.Expr{ast.NewIdent(name.Mangle)},
1490 // Okay - might be new(T)
1491 if r.Name.Type == nil {
1492 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1495 expr = r.Name.Type.Go
1497 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1499 expr = &ast.CallExpr{Fun: expr}
1502 if r.Name.Kind == "var" {
1503 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1505 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
1508 if r.Name.Kind != "type" {
1509 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
1510 } else if r.Name.Type == nil {
1511 // Use of C.enum_x, C.struct_x or C.union_x without C definition.
1512 // GCC won't raise an error when using pointers to such unknown types.
1513 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1515 expr = r.Name.Type.Go
1518 if r.Name.Kind == "func" {
1519 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
1525 // gofmtPos returns the gofmt-formatted string for an AST node,
1526 // with a comment setting the position before the node.
1527 func gofmtPos(n ast.Expr, pos token.Pos) string {
1529 p := fset.Position(pos)
1533 return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s)
1536 // gccBaseCmd returns the start of the compiler command line.
1537 // It uses $CC if set, or else $GCC, or else the compiler recorded
1538 // during the initial build as defaultCC.
1539 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1540 func (p *Package) gccBaseCmd() []string {
1541 // Use $CC if set, since that's what the build uses.
1542 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
1545 // Try $GCC if set, since that's what we used to use.
1546 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
1549 return strings.Fields(defaultCC(goos, goarch))
1552 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1553 func (p *Package) gccMachine() []string {
1556 return []string{"-m64"}
1558 return []string{"-m32"}
1560 return []string{"-marm"} // not thumb
1562 return []string{"-m31"}
1564 return []string{"-m64"}
1565 case "mips64", "mips64le":
1566 return []string{"-mabi=64"}
1567 case "mips", "mipsle":
1568 return []string{"-mabi=32"}
1571 return []string{"-maix64"}
1577 func gccTmp() string {
1578 return *objDir + "_cgo_.o"
1581 // gccCmd returns the gcc command line to use for compiling
1583 func (p *Package) gccCmd() []string {
1584 c := append(p.gccBaseCmd(),
1585 "-w", // no warnings
1586 "-Wno-error", // warnings are not errors
1587 "-o"+gccTmp(), // write object to tmp
1588 "-gdwarf-2", // generate DWARF v2 debugging symbols
1589 "-c", // do not link
1590 "-xc", // input language is C
1595 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1596 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1597 // flag to disable the warning. Yes, really good diagnostics, clang.
1598 "-Wno-unknown-warning-option",
1599 "-Wno-unneeded-internal-declaration",
1600 "-Wno-unused-function",
1601 "-Qunused-arguments",
1602 // Clang embeds prototypes for some builtin functions,
1603 // like malloc and calloc, but all size_t parameters are
1604 // incorrectly typed unsigned long. We work around that
1605 // by disabling the builtin functions (this is safe as
1606 // it won't affect the actual compilation of the C code).
1607 // See: https://golang.org/issue/6506.
1612 c = append(c, p.GccOptions...)
1613 c = append(c, p.gccMachine()...)
1615 c = append(c, "-maix64")
1616 c = append(c, "-mcmodel=large")
1618 c = append(c, "-") //read input from standard input
1622 // gccDebug runs gcc -gdwarf-2 over the C program stdin and
1623 // returns the corresponding DWARF data and, if present, debug data block.
1624 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
1625 runGcc(stdin, p.gccCmd())
1627 isDebugInts := func(s string) bool {
1628 // Some systems use leading _ to denote non-assembly symbols.
1629 return s == "__cgodebug_ints" || s == "___cgodebug_ints"
1631 isDebugFloats := func(s string) bool {
1632 // Some systems use leading _ to denote non-assembly symbols.
1633 return s == "__cgodebug_floats" || s == "___cgodebug_floats"
1635 indexOfDebugStr := func(s string) int {
1636 // Some systems use leading _ to denote non-assembly symbols.
1637 if strings.HasPrefix(s, "___") {
1640 if strings.HasPrefix(s, "__cgodebug_str__") {
1641 if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
1647 indexOfDebugStrlen := func(s string) int {
1648 // Some systems use leading _ to denote non-assembly symbols.
1649 if strings.HasPrefix(s, "___") {
1652 if strings.HasPrefix(s, "__cgodebug_strlen__") {
1653 if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
1660 strs = make([]string, nnames)
1662 strdata := make(map[int]string, nnames)
1663 strlens := make(map[int]int, nnames)
1665 buildStrings := func() {
1666 for n, strlen := range strlens {
1668 if len(data) <= strlen {
1669 fatalf("invalid string literal")
1671 strs[n] = data[:strlen]
1675 if f, err := macho.Open(gccTmp()); err == nil {
1679 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1682 if f.Symtab != nil {
1683 for i := range f.Symtab.Syms {
1684 s := &f.Symtab.Syms[i]
1686 case isDebugInts(s.Name):
1687 // Found it. Now find data section.
1688 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1689 sect := f.Sections[i]
1690 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1691 if sdat, err := sect.Data(); err == nil {
1692 data := sdat[s.Value-sect.Addr:]
1693 ints = make([]int64, len(data)/8)
1694 for i := range ints {
1695 ints[i] = int64(bo.Uint64(data[i*8:]))
1700 case isDebugFloats(s.Name):
1701 // Found it. Now find data section.
1702 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1703 sect := f.Sections[i]
1704 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1705 if sdat, err := sect.Data(); err == nil {
1706 data := sdat[s.Value-sect.Addr:]
1707 floats = make([]float64, len(data)/8)
1708 for i := range floats {
1709 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1715 if n := indexOfDebugStr(s.Name); n != -1 {
1716 // Found it. Now find data section.
1717 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1718 sect := f.Sections[i]
1719 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1720 if sdat, err := sect.Data(); err == nil {
1721 data := sdat[s.Value-sect.Addr:]
1722 strdata[n] = string(data)
1728 if n := indexOfDebugStrlen(s.Name); n != -1 {
1729 // Found it. Now find data section.
1730 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1731 sect := f.Sections[i]
1732 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1733 if sdat, err := sect.Data(); err == nil {
1734 data := sdat[s.Value-sect.Addr:]
1735 strlen := bo.Uint64(data[:8])
1736 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1737 fatalf("string literal too big")
1739 strlens[n] = int(strlen)
1750 return d, ints, floats, strs
1753 if f, err := elf.Open(gccTmp()); err == nil {
1757 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1760 symtab, err := f.Symbols()
1762 for i := range symtab {
1765 case isDebugInts(s.Name):
1766 // Found it. Now find data section.
1767 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1768 sect := f.Sections[i]
1769 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1770 if sdat, err := sect.Data(); err == nil {
1771 data := sdat[s.Value-sect.Addr:]
1772 ints = make([]int64, len(data)/8)
1773 for i := range ints {
1774 ints[i] = int64(bo.Uint64(data[i*8:]))
1779 case isDebugFloats(s.Name):
1780 // Found it. Now find data section.
1781 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1782 sect := f.Sections[i]
1783 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1784 if sdat, err := sect.Data(); err == nil {
1785 data := sdat[s.Value-sect.Addr:]
1786 floats = make([]float64, len(data)/8)
1787 for i := range floats {
1788 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1794 if n := indexOfDebugStr(s.Name); n != -1 {
1795 // Found it. Now find data section.
1796 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1797 sect := f.Sections[i]
1798 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1799 if sdat, err := sect.Data(); err == nil {
1800 data := sdat[s.Value-sect.Addr:]
1801 strdata[n] = string(data)
1807 if n := indexOfDebugStrlen(s.Name); n != -1 {
1808 // Found it. Now find data section.
1809 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1810 sect := f.Sections[i]
1811 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1812 if sdat, err := sect.Data(); err == nil {
1813 data := sdat[s.Value-sect.Addr:]
1814 strlen := bo.Uint64(data[:8])
1815 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1816 fatalf("string literal too big")
1818 strlens[n] = int(strlen)
1829 return d, ints, floats, strs
1832 if f, err := pe.Open(gccTmp()); err == nil {
1836 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1838 bo := binary.LittleEndian
1839 for _, s := range f.Symbols {
1841 case isDebugInts(s.Name):
1842 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1843 sect := f.Sections[i]
1844 if s.Value < sect.Size {
1845 if sdat, err := sect.Data(); err == nil {
1846 data := sdat[s.Value:]
1847 ints = make([]int64, len(data)/8)
1848 for i := range ints {
1849 ints[i] = int64(bo.Uint64(data[i*8:]))
1854 case isDebugFloats(s.Name):
1855 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1856 sect := f.Sections[i]
1857 if s.Value < sect.Size {
1858 if sdat, err := sect.Data(); err == nil {
1859 data := sdat[s.Value:]
1860 floats = make([]float64, len(data)/8)
1861 for i := range floats {
1862 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1868 if n := indexOfDebugStr(s.Name); n != -1 {
1869 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1870 sect := f.Sections[i]
1871 if s.Value < sect.Size {
1872 if sdat, err := sect.Data(); err == nil {
1873 data := sdat[s.Value:]
1874 strdata[n] = string(data)
1880 if n := indexOfDebugStrlen(s.Name); n != -1 {
1881 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1882 sect := f.Sections[i]
1883 if s.Value < sect.Size {
1884 if sdat, err := sect.Data(); err == nil {
1885 data := sdat[s.Value:]
1886 strlen := bo.Uint64(data[:8])
1887 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1888 fatalf("string literal too big")
1890 strlens[n] = int(strlen)
1901 return d, ints, floats, strs
1904 if f, err := xcoff.Open(gccTmp()); err == nil {
1908 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1910 bo := binary.BigEndian
1911 for _, s := range f.Symbols {
1913 case isDebugInts(s.Name):
1914 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1915 sect := f.Sections[i]
1916 if s.Value < sect.Size {
1917 if sdat, err := sect.Data(); err == nil {
1918 data := sdat[s.Value:]
1919 ints = make([]int64, len(data)/8)
1920 for i := range ints {
1921 ints[i] = int64(bo.Uint64(data[i*8:]))
1926 case isDebugFloats(s.Name):
1927 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1928 sect := f.Sections[i]
1929 if s.Value < sect.Size {
1930 if sdat, err := sect.Data(); err == nil {
1931 data := sdat[s.Value:]
1932 floats = make([]float64, len(data)/8)
1933 for i := range floats {
1934 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1940 if n := indexOfDebugStr(s.Name); n != -1 {
1941 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1942 sect := f.Sections[i]
1943 if s.Value < sect.Size {
1944 if sdat, err := sect.Data(); err == nil {
1945 data := sdat[s.Value:]
1946 strdata[n] = string(data)
1952 if n := indexOfDebugStrlen(s.Name); n != -1 {
1953 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1954 sect := f.Sections[i]
1955 if s.Value < sect.Size {
1956 if sdat, err := sect.Data(); err == nil {
1957 data := sdat[s.Value:]
1958 strlen := bo.Uint64(data[:8])
1959 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1960 fatalf("string literal too big")
1962 strlens[n] = int(strlen)
1972 return d, ints, floats, strs
1974 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
1975 panic("not reached")
1978 // gccDefines runs gcc -E -dM -xc - over the C program stdin
1979 // and returns the corresponding standard output, which is the
1980 // #defines that gcc encountered while processing the input
1981 // and its included files.
1982 func (p *Package) gccDefines(stdin []byte) string {
1983 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
1984 base = append(base, p.gccMachine()...)
1985 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
1989 // gccErrors runs gcc over the C program stdin and returns
1990 // the errors that gcc prints. That is, this function expects
1992 func (p *Package) gccErrors(stdin []byte) string {
1993 // TODO(rsc): require failure
1996 // Optimization options can confuse the error messages; remove them.
1997 nargs := make([]string, 0, len(args))
1998 for _, arg := range args {
1999 if !strings.HasPrefix(arg, "-O") {
2000 nargs = append(nargs, arg)
2004 // Force -O0 optimization but keep the trailing "-" at the end.
2005 nargs = append(nargs, "-O0")
2007 nargs[nl-2], nargs[nl-1] = nargs[nl-1], nargs[nl-2]
2010 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
2011 os.Stderr.Write(stdin)
2012 fmt.Fprint(os.Stderr, "EOF\n")
2014 stdout, stderr, _ := run(stdin, nargs)
2016 os.Stderr.Write(stdout)
2017 os.Stderr.Write(stderr)
2019 return string(stderr)
2022 // runGcc runs the gcc command line args with stdin on standard input.
2023 // If the command exits with a non-zero exit status, runGcc prints
2024 // details about what was run and exits.
2025 // Otherwise runGcc returns the data written to standard output and standard error.
2026 // Note that for some of the uses we expect useful data back
2027 // on standard error, but for those uses gcc must still exit 0.
2028 func runGcc(stdin []byte, args []string) (string, string) {
2030 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
2031 os.Stderr.Write(stdin)
2032 fmt.Fprint(os.Stderr, "EOF\n")
2034 stdout, stderr, ok := run(stdin, args)
2036 os.Stderr.Write(stdout)
2037 os.Stderr.Write(stderr)
2040 os.Stderr.Write(stderr)
2043 return string(stdout), string(stderr)
2046 // A typeConv is a translator from dwarf types to Go types
2047 // with equivalent memory layout.
2048 type typeConv struct {
2049 // Cache of already-translated or in-progress types.
2052 // Map from types to incomplete pointers to those types.
2053 ptrs map[string][]*Type
2054 // Keys of ptrs in insertion order (deterministic worklist)
2055 // ptrKeys contains exactly the keys in ptrs.
2056 ptrKeys []dwarf.Type
2058 // Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
2059 getTypeIDs map[string]bool
2061 // Predeclared types.
2063 byte ast.Expr // denotes padding
2064 int8, int16, int32, int64 ast.Expr
2065 uint8, uint16, uint32, uint64, uintptr ast.Expr
2066 float32, float64 ast.Expr
2067 complex64, complex128 ast.Expr
2070 goVoid ast.Expr // _Ctype_void, denotes C's void
2071 goVoidPtr ast.Expr // unsafe.Pointer or *byte
2078 var typedef = make(map[string]*Type)
2079 var goIdent = make(map[string]*ast.Ident)
2081 // unionWithPointer is true for a Go type that represents a C union (or class)
2082 // that may contain a pointer. This is used for cgo pointer checking.
2083 var unionWithPointer = make(map[ast.Expr]bool)
2085 func (c *typeConv) Init(ptrSize, intSize int64) {
2088 c.m = make(map[string]*Type)
2089 c.ptrs = make(map[string][]*Type)
2090 c.getTypeIDs = make(map[string]bool)
2091 c.bool = c.Ident("bool")
2092 c.byte = c.Ident("byte")
2093 c.int8 = c.Ident("int8")
2094 c.int16 = c.Ident("int16")
2095 c.int32 = c.Ident("int32")
2096 c.int64 = c.Ident("int64")
2097 c.uint8 = c.Ident("uint8")
2098 c.uint16 = c.Ident("uint16")
2099 c.uint32 = c.Ident("uint32")
2100 c.uint64 = c.Ident("uint64")
2101 c.uintptr = c.Ident("uintptr")
2102 c.float32 = c.Ident("float32")
2103 c.float64 = c.Ident("float64")
2104 c.complex64 = c.Ident("complex64")
2105 c.complex128 = c.Ident("complex128")
2106 c.void = c.Ident("void")
2107 c.string = c.Ident("string")
2108 c.goVoid = c.Ident("_Ctype_void")
2110 // Normally cgo translates void* to unsafe.Pointer,
2111 // but for historical reasons -godefs uses *byte instead.
2113 c.goVoidPtr = &ast.StarExpr{X: c.byte}
2115 c.goVoidPtr = c.Ident("unsafe.Pointer")
2119 // base strips away qualifiers and typedefs to get the underlying type
2120 func base(dt dwarf.Type) dwarf.Type {
2122 if d, ok := dt.(*dwarf.QualType); ok {
2126 if d, ok := dt.(*dwarf.TypedefType); ok {
2135 // unqual strips away qualifiers from a DWARF type.
2136 // In general we don't care about top-level qualifiers.
2137 func unqual(dt dwarf.Type) dwarf.Type {
2139 if d, ok := dt.(*dwarf.QualType); ok {
2148 // Map from dwarf text names to aliases we use in package "C".
2149 var dwarfToName = map[string]string{
2151 "long unsigned int": "ulong",
2152 "unsigned int": "uint",
2153 "short unsigned int": "ushort",
2154 "unsigned short": "ushort", // Used by Clang; issue 13129.
2155 "short int": "short",
2156 "long long int": "longlong",
2157 "long long unsigned int": "ulonglong",
2158 "signed char": "schar",
2159 "unsigned char": "uchar",
2162 const signedDelta = 64
2164 // String returns the current type representation. Format arguments
2165 // are assembled within this method so that any changes in mutable
2166 // values are taken into account.
2167 func (tr *TypeRepr) String() string {
2168 if len(tr.Repr) == 0 {
2171 if len(tr.FormatArgs) == 0 {
2174 return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
2177 // Empty reports whether the result of String would be "".
2178 func (tr *TypeRepr) Empty() bool {
2179 return len(tr.Repr) == 0
2182 // Set modifies the type representation.
2183 // If fargs are provided, repr is used as a format for fmt.Sprintf.
2184 // Otherwise, repr is used unprocessed as the type representation.
2185 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
2187 tr.FormatArgs = fargs
2190 // FinishType completes any outstanding type mapping work.
2191 // In particular, it resolves incomplete pointer types.
2192 func (c *typeConv) FinishType(pos token.Pos) {
2193 // Completing one pointer type might produce more to complete.
2194 // Keep looping until they're all done.
2195 for len(c.ptrKeys) > 0 {
2196 dtype := c.ptrKeys[0]
2197 dtypeKey := dtype.String()
2198 c.ptrKeys = c.ptrKeys[1:]
2199 ptrs := c.ptrs[dtypeKey]
2200 delete(c.ptrs, dtypeKey)
2202 // Note Type might invalidate c.ptrs[dtypeKey].
2203 t := c.Type(dtype, pos)
2204 for _, ptr := range ptrs {
2205 ptr.Go.(*ast.StarExpr).X = t.Go
2206 ptr.C.Set("%s*", t.C)
2211 // Type returns a *Type with the same memory layout as
2212 // dtype when used as the type of a variable or a struct field.
2213 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
2214 return c.loadType(dtype, pos, "")
2217 // loadType recursively loads the requested dtype and its dependency graph.
2218 func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Type {
2219 // Always recompute bad pointer typedefs, as the set of such
2220 // typedefs changes as we see more types.
2222 if dtt, ok := dtype.(*dwarf.TypedefType); ok && c.badPointerTypedef(dtt) {
2226 // The cache key should be relative to its parent.
2227 // See issue https://golang.org/issue/31891
2228 key := parent + " > " + dtype.String()
2231 if t, ok := c.m[key]; ok {
2233 fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
2240 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
2242 t.C = &TypeRepr{Repr: dtype.Common().Name}
2245 switch dt := dtype.(type) {
2247 fatalf("%s: unexpected type: %s", lineno(pos), dtype)
2249 case *dwarf.AddrType:
2250 if t.Size != c.ptrSize {
2251 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
2256 case *dwarf.ArrayType:
2257 if dt.StrideBitSize > 0 {
2258 // Cannot represent bit-sized elements in Go.
2259 t.Go = c.Opaque(t.Size)
2264 // Indicates flexible array member, which Go doesn't support.
2265 // Translate to zero-length array instead.
2268 sub := c.loadType(dt.Type, pos, key)
2270 t.Go = &ast.ArrayType{
2271 Len: c.intExpr(count),
2274 // Recalculate t.Size now that we know sub.Size.
2275 t.Size = count * sub.Size
2276 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
2278 case *dwarf.BoolType:
2282 case *dwarf.CharType:
2284 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
2289 case *dwarf.EnumType:
2290 if t.Align = t.Size; t.Align >= c.ptrSize {
2293 t.C.Set("enum " + dt.EnumName)
2295 t.EnumValues = make(map[string]int64)
2296 for _, ev := range dt.Val {
2297 t.EnumValues[ev.Name] = ev.Val
2299 signed = signedDelta
2302 switch t.Size + int64(signed) {
2304 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
2313 case 1 + signedDelta:
2315 case 2 + signedDelta:
2317 case 4 + signedDelta:
2319 case 8 + signedDelta:
2323 case *dwarf.FloatType:
2326 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
2332 if t.Align = t.Size; t.Align >= c.ptrSize {
2336 case *dwarf.ComplexType:
2339 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
2345 if t.Align = t.Size / 2; t.Align >= c.ptrSize {
2349 case *dwarf.FuncType:
2350 // No attempt at translation: would enable calls
2351 // directly between worlds, but we need to moderate those.
2355 case *dwarf.IntType:
2357 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
2361 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
2371 t.Go = &ast.ArrayType{
2372 Len: c.intExpr(t.Size),
2376 if t.Align = t.Size; t.Align >= c.ptrSize {
2380 case *dwarf.PtrType:
2381 // Clang doesn't emit DW_AT_byte_size for pointer types.
2382 if t.Size != c.ptrSize && t.Size != -1 {
2383 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
2388 if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
2393 if d, ok := dq.(*dwarf.QualType); ok {
2394 t.C.Set(d.Qual + " " + t.C.String())
2403 // Placeholder initialization; completed in FinishType.
2404 t.Go = &ast.StarExpr{}
2405 t.C.Set("<incomplete>*")
2406 key := dt.Type.String()
2407 if _, ok := c.ptrs[key]; !ok {
2408 c.ptrKeys = append(c.ptrKeys, dt.Type)
2410 c.ptrs[key] = append(c.ptrs[key], t)
2412 case *dwarf.QualType:
2413 t1 := c.loadType(dt.Type, pos, key)
2417 if unionWithPointer[t1.Go] {
2418 unionWithPointer[t.Go] = true
2422 t.C.Set("%s "+dt.Qual, t1.C)
2425 case *dwarf.StructType:
2426 // Convert to Go struct, being careful about alignment.
2427 // Have to give it a name to simulate C "struct foo" references.
2428 tag := dt.StructName
2429 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
2433 tag = "__" + strconv.Itoa(tagGen)
2435 } else if t.C.Empty() {
2436 t.C.Set(dt.Kind + " " + tag)
2438 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
2439 t.Go = name // publish before recursive calls
2440 goIdent[name.Name] = name
2441 if dt.ByteSize < 0 {
2442 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
2443 // so execute the basic things that the struct case would do
2444 // other than try to determine a Go representation.
2446 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
2447 tt.Go = c.Ident("struct{}")
2448 typedef[name.Name] = &tt
2452 case "class", "union":
2453 t.Go = c.Opaque(t.Size)
2454 if c.dwarfHasPointer(dt, pos) {
2455 unionWithPointer[t.Go] = true
2458 t.C.Set("__typeof__(unsigned char[%d])", t.Size)
2460 t.Align = 1 // TODO: should probably base this on field alignment.
2461 typedef[name.Name] = t
2463 g, csyntax, align := c.Struct(dt, pos)
2470 tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
2473 typedef[name.Name] = &tt
2476 case *dwarf.TypedefType:
2477 // Record typedef for printing.
2478 if dt.Name == "_GoString_" {
2479 // Special C name for Go string type.
2480 // Knows string layout used by compilers: pointer plus length,
2481 // which rounds up to 2 pointers after alignment.
2483 t.Size = c.ptrSize * 2
2487 if dt.Name == "_GoBytes_" {
2488 // Special C name for Go []byte type.
2489 // Knows slice layout used by compilers: pointer, length, cap.
2490 t.Go = c.Ident("[]byte")
2491 t.Size = c.ptrSize + 4 + 4
2495 name := c.Ident("_Ctype_" + dt.Name)
2496 goIdent[name.Name] = name
2497 sub := c.loadType(dt.Type, pos, key)
2498 if c.badPointerTypedef(dt) {
2499 // Treat this typedef as a uintptr.
2504 // Make sure we update any previously computed type.
2505 if oldType := typedef[name.Name]; oldType != nil {
2507 oldType.BadPointer = true
2511 t.BadPointer = sub.BadPointer
2512 if unionWithPointer[sub.Go] {
2513 unionWithPointer[t.Go] = true
2517 oldType := typedef[name.Name]
2521 tt.BadPointer = sub.BadPointer
2522 typedef[name.Name] = &tt
2525 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
2526 // use that as the Go form for this typedef too, so that the typedef will be interchangeable
2527 // with the base type.
2528 // In -godefs mode, do this for all typedefs.
2529 if isStructUnionClass(sub.Go) || *godefs {
2532 if isStructUnionClass(sub.Go) {
2533 // Use the typedef name for C code.
2534 typedef[sub.Go.(*ast.Ident).Name].C = t.C
2537 // If we've seen this typedef before, and it
2538 // was an anonymous struct/union/class before
2539 // too, use the old definition.
2540 // TODO: it would be safer to only do this if
2541 // we verify that the types are the same.
2542 if oldType != nil && isStructUnionClass(oldType.Go) {
2547 case *dwarf.UcharType:
2549 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
2554 case *dwarf.UintType:
2556 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
2560 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
2570 t.Go = &ast.ArrayType{
2571 Len: c.intExpr(t.Size),
2575 if t.Align = t.Size; t.Align >= c.ptrSize {
2579 case *dwarf.VoidType:
2585 switch dtype.(type) {
2586 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
2587 s := dtype.Common().Name
2589 if ss, ok := dwarfToName[s]; ok {
2592 s = strings.Replace(s, " ", "", -1)
2593 name := c.Ident("_Ctype_" + s)
2595 typedef[name.Name] = &tt
2603 // Unsized types are [0]byte, unless they're typedefs of other types
2604 // or structs with tags.
2605 // if so, use the name we've already defined.
2607 switch dt := dtype.(type) {
2608 case *dwarf.TypedefType:
2610 case *dwarf.StructType:
2611 if dt.StructName != "" {
2624 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
2630 // isStructUnionClass reports whether the type described by the Go syntax x
2631 // is a struct, union, or class with a tag.
2632 func isStructUnionClass(x ast.Expr) bool {
2633 id, ok := x.(*ast.Ident)
2638 return strings.HasPrefix(name, "_Ctype_struct_") ||
2639 strings.HasPrefix(name, "_Ctype_union_") ||
2640 strings.HasPrefix(name, "_Ctype_class_")
2643 // FuncArg returns a Go type with the same memory layout as
2644 // dtype when used as the type of a C function argument.
2645 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
2646 t := c.Type(unqual(dtype), pos)
2647 switch dt := dtype.(type) {
2648 case *dwarf.ArrayType:
2649 // Arrays are passed implicitly as pointers in C.
2650 // In Go, we must be explicit.
2656 Go: &ast.StarExpr{X: t.Go},
2659 case *dwarf.TypedefType:
2660 // C has much more relaxed rules than Go for
2661 // implicit type conversions. When the parameter
2662 // is type T defined as *X, simulate a little of the
2663 // laxness of C by making the argument *X instead of T.
2664 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
2665 // Unless the typedef happens to point to void* since
2666 // Go has special rules around using unsafe.Pointer.
2667 if _, void := base(ptr.Type).(*dwarf.VoidType); void {
2670 // ...or the typedef is one in which we expect bad pointers.
2671 // It will be a uintptr instead of *X.
2672 if c.baseBadPointerTypedef(dt) {
2676 t = c.Type(ptr, pos)
2681 // For a struct/union/class, remember the C spelling,
2682 // in case it has __attribute__((unavailable)).
2684 if isStructUnionClass(t.Go) {
2692 // FuncType returns the Go type analogous to dtype.
2693 // There is no guarantee about matching memory layout.
2694 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
2695 p := make([]*Type, len(dtype.ParamType))
2696 gp := make([]*ast.Field, len(dtype.ParamType))
2697 for i, f := range dtype.ParamType {
2698 // gcc's DWARF generator outputs a single DotDotDotType parameter for
2699 // function pointers that specify no parameters (e.g. void
2700 // (*__cgo_0)()). Treat this special case as void. This case is
2701 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2703 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
2707 p[i] = c.FuncArg(f, pos)
2708 gp[i] = &ast.Field{Type: p[i].Go}
2712 if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
2713 gr = []*ast.Field{{Type: c.goVoid}}
2714 } else if dtype.ReturnType != nil {
2715 r = c.Type(unqual(dtype.ReturnType), pos)
2716 gr = []*ast.Field{{Type: r.Go}}
2722 Params: &ast.FieldList{List: gp},
2723 Results: &ast.FieldList{List: gr},
2729 func (c *typeConv) Ident(s string) *ast.Ident {
2730 return ast.NewIdent(s)
2733 // Opaque type of n bytes.
2734 func (c *typeConv) Opaque(n int64) ast.Expr {
2735 return &ast.ArrayType{
2741 // Expr for integer n.
2742 func (c *typeConv) intExpr(n int64) ast.Expr {
2743 return &ast.BasicLit{
2745 Value: strconv.FormatInt(n, 10),
2749 // Add padding of given size to fld.
2750 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
2753 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
2754 sizes = sizes[0 : n+1]
2759 // Struct conversion: return Go and (gc) C syntax for type.
2760 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
2761 // Minimum alignment for a struct is 1 byte.
2764 var buf bytes.Buffer
2765 buf.WriteString("struct {")
2766 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
2767 sizes := make([]int64, 0, 2*len(dt.Field)+1)
2770 // Rename struct fields that happen to be named Go keywords into
2771 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will
2772 // be mangled. Any existing identifier that already has the same name on
2773 // the C-side will cause the Go-mangled version to be prefixed with _.
2774 // (e.g. in a struct with fields '_type' and 'type', the latter would be
2775 // rendered as '__type' in Go).
2776 ident := make(map[string]string)
2777 used := make(map[string]bool)
2778 for _, f := range dt.Field {
2779 ident[f.Name] = f.Name
2784 for cid, goid := range ident {
2785 if token.Lookup(goid).IsKeyword() {
2789 // Also avoid existing fields
2790 for _, exist := used[goid]; exist; _, exist = used[goid] {
2801 for _, f := range dt.Field {
2805 // In godefs mode, if this field is a C11
2806 // anonymous union then treat the first field in the
2807 // union as the field in the struct. This handles
2808 // cases like the glibc <sys/resource.h> file; see
2811 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
2812 name = st.Field[0].Name
2814 ft = st.Field[0].Type
2818 // TODO: Handle fields that are anonymous structs by
2819 // promoting the fields of the inner struct.
2821 t := c.Type(ft, pos)
2831 size = f.BitSize / 8
2832 name := tgo.(*ast.Ident).String()
2833 if strings.HasPrefix(name, "int") {
2838 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
2842 if talign > 0 && f.ByteOffset%talign != 0 {
2843 // Drop misaligned fields, the same way we drop integer bit fields.
2844 // The goal is to make available what can be made available.
2845 // Otherwise one bad and unneeded field in an otherwise okay struct
2846 // makes the whole program not compile. Much of the time these
2847 // structs are in system headers that cannot be corrected.
2851 // Round off up to talign, assumed to be a power of 2.
2852 off = (off + talign - 1) &^ (talign - 1)
2854 if f.ByteOffset > off {
2855 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
2858 if f.ByteOffset < off {
2859 // Drop a packed field that we can't represent.
2866 name = fmt.Sprintf("anon%d", anon)
2870 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
2871 sizes = sizes[0 : n+1]
2874 buf.WriteString(t.C.String())
2875 buf.WriteString(" ")
2876 buf.WriteString(name)
2877 buf.WriteString("; ")
2882 if off < dt.ByteSize {
2883 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
2887 // If the last field in a non-zero-sized struct is zero-sized
2888 // the compiler is going to pad it by one (see issue 9401).
2889 // We can't permit that, because then the size of the Go
2890 // struct will not be the same as the size of the C struct.
2891 // Our only option in such a case is to remove the field,
2892 // which means that it cannot be referenced from Go.
2893 for off > 0 && sizes[len(sizes)-1] == 0 {
2896 sizes = sizes[0 : n-1]
2899 if off != dt.ByteSize {
2900 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
2902 buf.WriteString("}")
2903 csyntax = buf.String()
2908 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
2912 // dwarfHasPointer reports whether the DWARF type dt contains a pointer.
2913 func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
2914 switch dt := dt.(type) {
2916 fatalf("%s: unexpected type: %s", lineno(pos), dt)
2919 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
2920 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
2921 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
2925 case *dwarf.ArrayType:
2926 return c.dwarfHasPointer(dt.Type, pos)
2928 case *dwarf.PtrType:
2931 case *dwarf.QualType:
2932 return c.dwarfHasPointer(dt.Type, pos)
2934 case *dwarf.StructType:
2935 for _, f := range dt.Field {
2936 if c.dwarfHasPointer(f.Type, pos) {
2942 case *dwarf.TypedefType:
2943 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
2946 return c.dwarfHasPointer(dt.Type, pos)
2950 func upper(s string) string {
2954 r, size := utf8.DecodeRuneInString(s)
2958 return string(unicode.ToUpper(r)) + s[size:]
2961 // godefsFields rewrites field names for use in Go or C definitions.
2962 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
2963 // converts names to upper case, and rewrites _ into Pad_godefs_n,
2964 // so that all fields are exported.
2965 func godefsFields(fld []*ast.Field) {
2966 prefix := fieldPrefix(fld)
2968 for _, f := range fld {
2969 for _, n := range f.Names {
2970 if n.Name != prefix {
2971 n.Name = strings.TrimPrefix(n.Name, prefix)
2974 // Use exported name instead.
2975 n.Name = "Pad_cgo_" + strconv.Itoa(npad)
2978 n.Name = upper(n.Name)
2983 // fieldPrefix returns the prefix that should be removed from all the
2984 // field names when generating the C or Go code. For generated
2985 // C, we leave the names as is (tv_sec, tv_usec), since that's what
2986 // people are used to seeing in C. For generated Go code, such as
2987 // package syscall's data structures, we drop a common prefix
2988 // (so sec, usec, which will get turned into Sec, Usec for exporting).
2989 func fieldPrefix(fld []*ast.Field) string {
2991 for _, f := range fld {
2992 for _, n := range f.Names {
2993 // Ignore field names that don't have the prefix we're
2994 // looking for. It is common in C headers to have fields
2995 // named, say, _pad in an otherwise prefixed header.
2996 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
2997 // still want to remove the tv_ prefix.
2998 // The check for "orig_" here handles orig_eax in the
2999 // x86 ptrace register sets, which otherwise have all fields
3000 // with reg_ prefixes.
3001 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
3004 i := strings.Index(n.Name, "_")
3009 prefix = n.Name[:i+1]
3010 } else if prefix != n.Name[:i+1] {
3018 // badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
3019 // A typedef is bad if C code sometimes stores non-pointers in this type.
3020 // TODO: Currently our best solution is to find these manually and list them as
3021 // they come up. A better solution is desired.
3022 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
3023 if c.badCFType(dt) {
3029 if c.badEGLDisplay(dt) {
3035 // baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef
3036 // as badPointerTypedef reports.
3037 func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool {
3039 if t, ok := dt.Type.(*dwarf.TypedefType); ok {
3045 return c.badPointerTypedef(dt)
3048 func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
3049 // The real bad types are CFNumberRef and CFDateRef.
3050 // Sometimes non-pointers are stored in these types.
3051 // CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
3052 // We return true for the other *Ref types just so casting between them is easier.
3053 // We identify the correct set of types as those ending in Ref and for which
3054 // there exists a corresponding GetTypeID function.
3055 // See comment below for details about the bad pointers.
3056 if goos != "darwin" {
3060 if !strings.HasSuffix(s, "Ref") {
3067 if c.getTypeIDs[s] {
3070 if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
3071 // Mutable and immutable variants share a type ID.
3077 // Comment from Darwin's CFInternal.h
3079 // Tagged pointer support
3080 // Low-bit set means tagged object, next 3 bits (currently)
3081 // define the tagged object class, next 4 bits are for type
3082 // information for the specific tagged object class. Thus,
3083 // the low byte is for type info, and the rest of a pointer
3084 // (32 or 64-bit) is for payload, whatever the tagged class.
3086 // Note that the specific integers used to identify the
3087 // specific tagged classes can and will change from release
3088 // to release (that's why this stuff is in CF*Internal*.h),
3089 // as can the definition of type info vs payload above.
3092 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1)
3093 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
3095 #define CF_IS_TAGGED_OBJ(PTR) 0
3096 #define CF_TAGGED_OBJ_TYPE(PTR) 0
3100 kCFTaggedObjectID_Invalid = 0,
3101 kCFTaggedObjectID_Atom = (0 << 1) + 1,
3102 kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
3103 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
3104 kCFTaggedObjectID_Integer = (3 << 1) + 1,
3105 kCFTaggedObjectID_DateTS = (4 << 1) + 1,
3106 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
3107 kCFTaggedObjectID_Date = (6 << 1) + 1,
3108 kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
3112 func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
3113 // In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
3114 // property that it is sometimes (always?) a small integer instead of a real pointer.
3115 // Note: although only the android JVMs are bad in this respect, we declare the JNI types
3116 // bad regardless of platform, so the same Go code compiles on both android and non-android.
3117 if parent, ok := jniTypes[dt.Name]; ok {
3118 // Try to make sure we're talking about a JNI type, not just some random user's
3119 // type that happens to use the same name.
3120 // C doesn't have the notion of a package, so it's hard to be certain.
3122 // Walk up to jobject, checking each typedef on the way.
3125 t, ok := w.Type.(*dwarf.TypedefType)
3126 if !ok || t.Name != parent {
3130 parent, ok = jniTypes[w.Name]
3136 // Check that the typedef is either:
3139 // typedef struct _jobject *jobject;
3140 // 2: (in NDK16 in C++)
3141 // class _jobject {};
3142 // typedef _jobject* jobject;
3143 // 3: (in NDK16 in C)
3144 // typedef void* jobject;
3145 if ptr, ok := w.Type.(*dwarf.PtrType); ok {
3146 switch v := ptr.Type.(type) {
3147 case *dwarf.VoidType:
3149 case *dwarf.StructType:
3150 if v.StructName == "_jobject" && len(v.Field) == 0 {
3168 func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool {
3169 if dt.Name != "EGLDisplay" {
3172 // Check that the typedef is "typedef void *EGLDisplay".
3173 if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
3174 if _, ok := ptr.Type.(*dwarf.VoidType); ok {
3181 // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
3182 // they are mapped. The base "jobject" maps to the empty string.
3183 var jniTypes = map[string]string{
3185 "jclass": "jobject",
3186 "jthrowable": "jobject",
3187 "jstring": "jobject",
3188 "jarray": "jobject",
3189 "jbooleanArray": "jarray",
3190 "jbyteArray": "jarray",
3191 "jcharArray": "jarray",
3192 "jshortArray": "jarray",
3193 "jintArray": "jarray",
3194 "jlongArray": "jarray",
3195 "jfloatArray": "jarray",
3196 "jdoubleArray": "jarray",
3197 "jobjectArray": "jarray",