libgo: update to Go1.10rc2
[official-gcc.git] / libgo / go / cmd / cgo / gcc.go
blob534fba17eb4bbfe5155d0f7ae212c13dff2f7a7c
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.
8 package main
10 import (
11 "bytes"
12 "debug/dwarf"
13 "debug/elf"
14 "debug/macho"
15 "debug/pe"
16 "debug/xcoff"
17 "encoding/binary"
18 "errors"
19 "flag"
20 "fmt"
21 "go/ast"
22 "go/parser"
23 "go/token"
24 "math"
25 "os"
26 "strconv"
27 "strings"
28 "unicode"
29 "unicode/utf8"
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
50 // union and enum.
51 func cname(s string) string {
52 if t, ok := nameToC[s]; ok {
53 return t
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_"):]) + ")"
68 return s
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)
81 } else {
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) {
91 if flag == "CFLAGS" {
92 // We'll need these when preprocessing for dwarf information.
93 p.GccOptions = append(p.GccOptions, args...)
96 skip := false
97 for i, arg := range args {
98 // The go tool will pass us a -I option pointing to objdir;
99 // we don't need to record that for later, as the objdir
100 // will disappear anyhow.
101 if skip {
102 // Discard argument in "-I objdir" case.
103 skip = false
104 } else if strings.HasPrefix(arg, "-I") && strings.HasPrefix(arg[2:], *objDir) {
105 // This is -Iobjdir. Don't save this argument.
106 } else if arg == "-I" && i+1 < len(args) && strings.HasPrefix(args[i+1], *objDir) {
107 // This is -I objdir. Don't save this argument
108 // or the next one.
109 skip = true
110 } else {
111 p.CgoFlags[flag] = append(p.CgoFlags[flag], arg)
116 // splitQuoted splits the string s around each instance of one or more consecutive
117 // white space characters while taking into account quotes and escaping, and
118 // returns an array of substrings of s or an empty list if s contains only white space.
119 // Single quotes and double quotes are recognized to prevent splitting within the
120 // quoted region, and are removed from the resulting substrings. If a quote in s
121 // isn't closed err will be set and r will have the unclosed argument as the
122 // last element. The backslash is used for escaping.
124 // For example, the following string:
126 // `a b:"c d" 'e''f' "g\""`
128 // Would be parsed as:
130 // []string{"a", "b:c d", "ef", `g"`}
132 func splitQuoted(s string) (r []string, err error) {
133 var args []string
134 arg := make([]rune, len(s))
135 escaped := false
136 quoted := false
137 quote := '\x00'
138 i := 0
139 for _, r := range s {
140 switch {
141 case escaped:
142 escaped = false
143 case r == '\\':
144 escaped = true
145 continue
146 case quote != 0:
147 if r == quote {
148 quote = 0
149 continue
151 case r == '"' || r == '\'':
152 quoted = true
153 quote = r
154 continue
155 case unicode.IsSpace(r):
156 if quoted || i > 0 {
157 quoted = false
158 args = append(args, string(arg[:i]))
159 i = 0
161 continue
163 arg[i] = r
166 if quoted || i > 0 {
167 args = append(args, string(arg[:i]))
169 if quote != 0 {
170 err = errors.New("unclosed quote")
171 } else if escaped {
172 err = errors.New("unfinished escaping")
174 return args, err
177 // Translate rewrites f.AST, the original Go input, to remove
178 // references to the imported package C, replacing them with
179 // references to the equivalent Go types, functions, and variables.
180 func (p *Package) Translate(f *File) {
181 for _, cref := range f.Ref {
182 // Convert C.ulong to C.unsigned long, etc.
183 cref.Name.C = cname(cref.Name.Go)
185 p.loadDefines(f)
186 needType := p.guessKinds(f)
187 if len(needType) > 0 {
188 p.loadDWARF(f, needType)
190 if p.rewriteCalls(f) {
191 // Add `import _cgo_unsafe "unsafe"` after the package statement.
192 f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"")
194 p.rewriteRef(f)
197 // loadDefines coerces gcc into spitting out the #defines in use
198 // in the file f and saves relevant renamings in f.Name[name].Define.
199 func (p *Package) loadDefines(f *File) {
200 var b bytes.Buffer
201 b.WriteString(builtinProlog)
202 b.WriteString(f.Preamble)
203 stdout := p.gccDefines(b.Bytes())
205 for _, line := range strings.Split(stdout, "\n") {
206 if len(line) < 9 || line[0:7] != "#define" {
207 continue
210 line = strings.TrimSpace(line[8:])
212 var key, val string
213 spaceIndex := strings.Index(line, " ")
214 tabIndex := strings.Index(line, "\t")
216 if spaceIndex == -1 && tabIndex == -1 {
217 continue
218 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) {
219 key = line[0:spaceIndex]
220 val = strings.TrimSpace(line[spaceIndex:])
221 } else {
222 key = line[0:tabIndex]
223 val = strings.TrimSpace(line[tabIndex:])
226 if key == "__clang__" {
227 p.GccIsClang = true
230 if n := f.Name[key]; n != nil {
231 if *debugDefine {
232 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
234 n.Define = val
239 // guessKinds tricks gcc into revealing the kind of each
240 // name xxx for the references C.xxx in the Go input.
241 // The kind is either a constant, type, or variable.
242 func (p *Package) guessKinds(f *File) []*Name {
243 // Determine kinds for names we already know about,
244 // like #defines or 'struct foo', before bothering with gcc.
245 var names, needType []*Name
246 optional := map[*Name]bool{}
247 for _, key := range nameKeys(f.Name) {
248 n := f.Name[key]
249 // If we've already found this name as a #define
250 // and we can translate it as a constant value, do so.
251 if n.Define != "" {
252 if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil {
253 n.Kind = "iconst"
254 // Turn decimal into hex, just for consistency
255 // with enum-derived constants. Otherwise
256 // in the cgo -godefs output half the constants
257 // are in hex and half are in whatever the #define used.
258 n.Const = fmt.Sprintf("%#x", i)
259 } else if n.Define[0] == '\'' {
260 if _, err := parser.ParseExpr(n.Define); err == nil {
261 n.Kind = "iconst"
262 n.Const = n.Define
264 } else if n.Define[0] == '"' {
265 if _, err := parser.ParseExpr(n.Define); err == nil {
266 n.Kind = "sconst"
267 n.Const = n.Define
271 if n.IsConst() {
272 continue
276 // If this is a struct, union, or enum type name, no need to guess the kind.
277 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") {
278 n.Kind = "type"
279 needType = append(needType, n)
280 continue
283 if goos == "darwin" && strings.HasSuffix(n.C, "Ref") {
284 // For FooRef, find out if FooGetTypeID exists.
285 s := n.C[:len(n.C)-3] + "GetTypeID"
286 n := &Name{Go: s, C: s}
287 names = append(names, n)
288 optional[n] = true
291 // Otherwise, we'll need to find out from gcc.
292 names = append(names, n)
295 // Bypass gcc if there's nothing left to find out.
296 if len(names) == 0 {
297 return needType
300 // Coerce gcc into telling us whether each name is a type, a value, or undeclared.
301 // For names, find out whether they are integer constants.
302 // We used to look at specific warning or error messages here, but that tied the
303 // behavior too closely to specific versions of the compilers.
304 // Instead, arrange that we can infer what we need from only the presence or absence
305 // of an error on a specific line.
307 // For each name, we generate these lines, where xxx is the index in toSniff plus one.
309 // #line xxx "not-declared"
310 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; }
311 // #line xxx "not-type"
312 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; }
313 // #line xxx "not-int-const"
314 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; }
315 // #line xxx "not-num-const"
316 // void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); }
317 // #line xxx "not-str-lit"
318 // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); }
320 // If we see an error at not-declared:xxx, the corresponding name is not declared.
321 // If we see an error at not-type:xxx, the corresponding name is a type.
322 // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant.
323 // If we see an error at not-num-const:xxx, the corresponding name is not a number constant.
324 // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal.
326 // The specific input forms are chosen so that they are valid C syntax regardless of
327 // whether name denotes a type or an expression.
329 var b bytes.Buffer
330 b.WriteString(builtinProlog)
331 b.WriteString(f.Preamble)
333 for i, n := range names {
334 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+
335 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+
336 "#line %d \"not-type\"\n"+
337 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+
338 "#line %d \"not-int-const\"\n"+
339 "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+
340 "#line %d \"not-num-const\"\n"+
341 "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+
342 "#line %d \"not-str-lit\"\n"+
343 "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n",
344 i+1, i+1, n.C,
345 i+1, i+1, n.C,
346 i+1, i+1, n.C,
347 i+1, i+1, n.C,
348 i+1, i+1, n.C,
351 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+
352 "int __cgo__1 = __cgo__2;\n")
354 stderr := p.gccErrors(b.Bytes())
355 if stderr == "" {
356 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
359 completed := false
360 sniff := make([]int, len(names))
361 const (
362 notType = 1 << iota
363 notIntConst
364 notNumConst
365 notStrLiteral
366 notDeclared
368 sawUnmatchedErrors := false
369 for _, line := range strings.Split(stderr, "\n") {
370 // Ignore warnings and random comments, with one
371 // exception: newer GCC versions will sometimes emit
372 // an error on a macro #define with a note referring
373 // to where the expansion occurs. We care about where
374 // the expansion occurs, so in that case treat the note
375 // as an error.
376 isError := strings.Contains(line, ": error:")
377 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors
378 if !isError && !isErrorNote {
379 continue
382 c1 := strings.Index(line, ":")
383 if c1 < 0 {
384 continue
386 c2 := strings.Index(line[c1+1:], ":")
387 if c2 < 0 {
388 continue
390 c2 += c1 + 1
392 filename := line[:c1]
393 i, _ := strconv.Atoi(line[c1+1 : c2])
395 if i < 0 || i >= len(names) {
396 if isError {
397 sawUnmatchedErrors = true
399 continue
402 switch filename {
403 case "completed":
404 // Strictly speaking, there is no guarantee that seeing the error at completed:1
405 // (at the end of the file) means we've seen all the errors from earlier in the file,
406 // but usually it does. Certainly if we don't see the completed:1 error, we did
407 // not get all the errors we expected.
408 completed = true
410 case "not-declared":
411 sniff[i] |= notDeclared
412 case "not-type":
413 sniff[i] |= notType
414 case "not-int-const":
415 sniff[i] |= notIntConst
416 case "not-num-const":
417 sniff[i] |= notNumConst
418 case "not-str-lit":
419 sniff[i] |= notStrLiteral
420 default:
421 if isError {
422 sawUnmatchedErrors = true
424 continue
427 sawUnmatchedErrors = false
430 if !completed {
431 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
434 for i, n := range names {
435 switch sniff[i] {
436 default:
437 if sniff[i]&notDeclared != 0 && optional[n] {
438 // Ignore optional undeclared identifiers.
439 // Don't report an error, and skip adding n to the needType array.
440 continue
442 error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
443 case notStrLiteral | notType:
444 n.Kind = "iconst"
445 case notIntConst | notStrLiteral | notType:
446 n.Kind = "fconst"
447 case notIntConst | notNumConst | notType:
448 n.Kind = "sconst"
449 case notIntConst | notNumConst | notStrLiteral:
450 n.Kind = "type"
451 case notIntConst | notNumConst | notStrLiteral | notType:
452 n.Kind = "not-type"
454 needType = append(needType, n)
456 if nerrors > 0 {
457 // Check if compiling the preamble by itself causes any errors,
458 // because the messages we've printed out so far aren't helpful
459 // to users debugging preamble mistakes. See issue 8442.
460 preambleErrors := p.gccErrors([]byte(f.Preamble))
461 if len(preambleErrors) > 0 {
462 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
465 fatalf("unresolved names")
468 return needType
471 // loadDWARF parses the DWARF debug information generated
472 // by gcc to learn the details of the constants, variables, and types
473 // being referred to as C.xxx.
474 func (p *Package) loadDWARF(f *File, names []*Name) {
475 // Extract the types from the DWARF section of an object
476 // from a well-formed C program. Gcc only generates DWARF info
477 // for symbols in the object file, so it is not enough to print the
478 // preamble and hope the symbols we care about will be there.
479 // Instead, emit
480 // __typeof__(names[i]) *__cgo__i;
481 // for each entry in names and then dereference the type we
482 // learn for __cgo__i.
483 var b bytes.Buffer
484 b.WriteString(builtinProlog)
485 b.WriteString(f.Preamble)
486 b.WriteString("#line 1 \"cgo-dwarf-inference\"\n")
487 for i, n := range names {
488 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i)
489 if n.Kind == "iconst" {
490 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C)
494 // We create a data block initialized with the values,
495 // so we can read them out of the object file.
496 fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n")
497 for _, n := range names {
498 if n.Kind == "iconst" {
499 fmt.Fprintf(&b, "\t%s,\n", n.C)
500 } else {
501 fmt.Fprintf(&b, "\t0,\n")
504 // for the last entry, we cannot use 0, otherwise
505 // in case all __cgodebug_data is zero initialized,
506 // LLVM-based gcc will place the it in the __DATA.__common
507 // zero-filled section (our debug/macho doesn't support
508 // this)
509 fmt.Fprintf(&b, "\t1\n")
510 fmt.Fprintf(&b, "};\n")
512 // do the same work for floats.
513 fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n")
514 for _, n := range names {
515 if n.Kind == "fconst" {
516 fmt.Fprintf(&b, "\t%s,\n", n.C)
517 } else {
518 fmt.Fprintf(&b, "\t0,\n")
521 fmt.Fprintf(&b, "\t1\n")
522 fmt.Fprintf(&b, "};\n")
524 // do the same work for strings.
525 for i, n := range names {
526 if n.Kind == "sconst" {
527 fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C)
528 fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C)
532 d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names))
534 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
535 types := make([]dwarf.Type, len(names))
536 r := d.Reader()
537 for {
538 e, err := r.Next()
539 if err != nil {
540 fatalf("reading DWARF entry: %s", err)
542 if e == nil {
543 break
545 switch e.Tag {
546 case dwarf.TagVariable:
547 name, _ := e.Val(dwarf.AttrName).(string)
548 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset)
549 if name == "" || typOff == 0 {
550 if e.Val(dwarf.AttrSpecification) != nil {
551 // Since we are reading all the DWARF,
552 // assume we will see the variable elsewhere.
553 break
555 fatalf("malformed DWARF TagVariable entry")
557 if !strings.HasPrefix(name, "__cgo__") {
558 break
560 typ, err := d.Type(typOff)
561 if err != nil {
562 fatalf("loading DWARF type: %s", err)
564 t, ok := typ.(*dwarf.PtrType)
565 if !ok || t == nil {
566 fatalf("internal error: %s has non-pointer type", name)
568 i, err := strconv.Atoi(name[7:])
569 if err != nil {
570 fatalf("malformed __cgo__ name: %s", name)
572 types[i] = t.Type
574 if e.Tag != dwarf.TagCompileUnit {
575 r.SkipChildren()
579 // Record types and typedef information.
580 var conv typeConv
581 conv.Init(p.PtrSize, p.IntSize)
582 for i, n := range names {
583 if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" {
584 conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true
587 for i, n := range names {
588 if types[i] == nil {
589 continue
591 pos := f.NamePos[n]
592 f, fok := types[i].(*dwarf.FuncType)
593 if n.Kind != "type" && fok {
594 n.Kind = "func"
595 n.FuncType = conv.FuncType(f, pos)
596 } else {
597 n.Type = conv.Type(types[i], pos)
598 switch n.Kind {
599 case "iconst":
600 if i < len(ints) {
601 if _, ok := types[i].(*dwarf.UintType); ok {
602 n.Const = fmt.Sprintf("%#x", uint64(ints[i]))
603 } else {
604 n.Const = fmt.Sprintf("%#x", ints[i])
607 case "fconst":
608 if i < len(floats) {
609 n.Const = fmt.Sprintf("%f", floats[i])
611 case "sconst":
612 if i < len(strs) {
613 n.Const = fmt.Sprintf("%q", strs[i])
617 conv.FinishType(pos)
621 // mangleName does name mangling to translate names
622 // from the original Go source files to the names
623 // used in the final Go files generated by cgo.
624 func (p *Package) mangleName(n *Name) {
625 // When using gccgo variables have to be
626 // exported so that they become global symbols
627 // that the C code can refer to.
628 prefix := "_C"
629 if *gccgo && n.IsVar() {
630 prefix = "C"
632 n.Mangle = prefix + n.Kind + "_" + n.Go
635 // rewriteCalls rewrites all calls that pass pointers to check that
636 // they follow the rules for passing pointers between Go and C.
637 // This returns whether the package needs to import unsafe as _cgo_unsafe.
638 func (p *Package) rewriteCalls(f *File) bool {
639 needsUnsafe := false
640 for _, call := range f.Calls {
641 // This is a call to C.xxx; set goname to "xxx".
642 goname := call.Call.Fun.(*ast.SelectorExpr).Sel.Name
643 if goname == "malloc" {
644 continue
646 name := f.Name[goname]
647 if name.Kind != "func" {
648 // Probably a type conversion.
649 continue
651 if p.rewriteCall(f, call, name) {
652 needsUnsafe = true
655 return needsUnsafe
658 // rewriteCall rewrites one call to add pointer checks.
659 // If any pointer checks are required, we rewrite the call into a
660 // function literal that calls _cgoCheckPointer for each pointer
661 // argument and then calls the original function.
662 // This returns whether the package needs to import unsafe as _cgo_unsafe.
663 func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool {
664 // Avoid a crash if the number of arguments is
665 // less than the number of parameters.
666 // This will be caught when the generated file is compiled.
667 if len(call.Call.Args) < len(name.FuncType.Params) {
668 return false
671 any := false
672 for i, param := range name.FuncType.Params {
673 if p.needsPointerCheck(f, param.Go, call.Call.Args[i]) {
674 any = true
675 break
678 if !any {
679 return false
682 // We need to rewrite this call.
684 // We are going to rewrite C.f(p) to
685 // func (_cgo0 ptype) {
686 // _cgoCheckPointer(_cgo0)
687 // C.f(_cgo0)
688 // }(p)
689 // Using a function literal like this lets us do correct
690 // argument type checking, and works correctly if the call is
691 // deferred.
692 needsUnsafe := false
693 params := make([]*ast.Field, len(name.FuncType.Params))
694 nargs := make([]ast.Expr, len(name.FuncType.Params))
695 var stmts []ast.Stmt
696 for i, param := range name.FuncType.Params {
697 // params is going to become the parameters of the
698 // function literal.
699 // nargs is going to become the list of arguments made
700 // by the call within the function literal.
701 // nparam is the parameter of the function literal that
702 // corresponds to param.
704 origArg := call.Call.Args[i]
705 nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i))
706 nargs[i] = nparam
708 // The Go version of the C type might use unsafe.Pointer,
709 // but the file might not import unsafe.
710 // Rewrite the Go type if necessary to use _cgo_unsafe.
711 ptype := p.rewriteUnsafe(param.Go)
712 if ptype != param.Go {
713 needsUnsafe = true
716 params[i] = &ast.Field{
717 Names: []*ast.Ident{nparam},
718 Type: ptype,
721 if !p.needsPointerCheck(f, param.Go, origArg) {
722 continue
725 // Run the cgo pointer checks on nparam.
727 // Change the function literal to call the real function
728 // with the parameter passed through _cgoCheckPointer.
729 c := &ast.CallExpr{
730 Fun: ast.NewIdent("_cgoCheckPointer"),
731 Args: []ast.Expr{
732 nparam,
736 // Add optional additional arguments for an address
737 // expression.
738 c.Args = p.checkAddrArgs(f, c.Args, origArg)
740 stmt := &ast.ExprStmt{
741 X: c,
743 stmts = append(stmts, stmt)
746 const cgoMarker = "__cgo__###__marker__"
747 fcall := &ast.CallExpr{
748 Fun: ast.NewIdent(cgoMarker),
749 Args: nargs,
751 ftype := &ast.FuncType{
752 Params: &ast.FieldList{
753 List: params,
756 if name.FuncType.Result != nil {
757 rtype := p.rewriteUnsafe(name.FuncType.Result.Go)
758 if rtype != name.FuncType.Result.Go {
759 needsUnsafe = true
761 ftype.Results = &ast.FieldList{
762 List: []*ast.Field{
763 &ast.Field{
764 Type: rtype,
770 // If this call expects two results, we have to
771 // adjust the results of the function we generated.
772 for _, ref := range f.Ref {
773 if ref.Expr == &call.Call.Fun && ref.Context == ctxCall2 {
774 if ftype.Results == nil {
775 // An explicit void argument
776 // looks odd but it seems to
777 // be how cgo has worked historically.
778 ftype.Results = &ast.FieldList{
779 List: []*ast.Field{
780 &ast.Field{
781 Type: ast.NewIdent("_Ctype_void"),
786 ftype.Results.List = append(ftype.Results.List,
787 &ast.Field{
788 Type: ast.NewIdent("error"),
793 var fbody ast.Stmt
794 if ftype.Results == nil {
795 fbody = &ast.ExprStmt{
796 X: fcall,
798 } else {
799 fbody = &ast.ReturnStmt{
800 Results: []ast.Expr{fcall},
803 lit := &ast.FuncLit{
804 Type: ftype,
805 Body: &ast.BlockStmt{
806 List: append(stmts, fbody),
809 text := strings.Replace(gofmt(lit), "\n", ";", -1)
810 repl := strings.Split(text, cgoMarker)
811 f.Edit.Insert(f.offset(call.Call.Fun.Pos()), repl[0])
812 f.Edit.Insert(f.offset(call.Call.Fun.End()), repl[1])
814 return needsUnsafe
817 // needsPointerCheck returns whether the type t needs a pointer check.
818 // This is true if t is a pointer and if the value to which it points
819 // might contain a pointer.
820 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool {
821 // An untyped nil does not need a pointer check, and when
822 // _cgoCheckPointer returns the untyped nil the type assertion we
823 // are going to insert will fail. Easier to just skip nil arguments.
824 // TODO: Note that this fails if nil is shadowed.
825 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" {
826 return false
829 return p.hasPointer(f, t, true)
832 // hasPointer is used by needsPointerCheck. If top is true it returns
833 // whether t is or contains a pointer that might point to a pointer.
834 // If top is false it returns whether t is or contains a pointer.
835 // f may be nil.
836 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool {
837 switch t := t.(type) {
838 case *ast.ArrayType:
839 if t.Len == nil {
840 if !top {
841 return true
843 return p.hasPointer(f, t.Elt, false)
845 return p.hasPointer(f, t.Elt, top)
846 case *ast.StructType:
847 for _, field := range t.Fields.List {
848 if p.hasPointer(f, field.Type, top) {
849 return true
852 return false
853 case *ast.StarExpr: // Pointer type.
854 if !top {
855 return true
857 // Check whether this is a pointer to a C union (or class)
858 // type that contains a pointer.
859 if unionWithPointer[t.X] {
860 return true
862 return p.hasPointer(f, t.X, false)
863 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
864 return true
865 case *ast.Ident:
866 // TODO: Handle types defined within function.
867 for _, d := range p.Decl {
868 gd, ok := d.(*ast.GenDecl)
869 if !ok || gd.Tok != token.TYPE {
870 continue
872 for _, spec := range gd.Specs {
873 ts, ok := spec.(*ast.TypeSpec)
874 if !ok {
875 continue
877 if ts.Name.Name == t.Name {
878 return p.hasPointer(f, ts.Type, top)
882 if def := typedef[t.Name]; def != nil {
883 return p.hasPointer(f, def.Go, top)
885 if t.Name == "string" {
886 return !top
888 if t.Name == "error" {
889 return true
891 if goTypes[t.Name] != nil {
892 return false
894 // We can't figure out the type. Conservative
895 // approach is to assume it has a pointer.
896 return true
897 case *ast.SelectorExpr:
898 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" {
899 // Type defined in a different package.
900 // Conservative approach is to assume it has a
901 // pointer.
902 return true
904 if f == nil {
905 // Conservative approach: assume pointer.
906 return true
908 name := f.Name[t.Sel.Name]
909 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil {
910 return p.hasPointer(f, name.Type.Go, top)
912 // We can't figure out the type. Conservative
913 // approach is to assume it has a pointer.
914 return true
915 default:
916 error_(t.Pos(), "could not understand type %s", gofmt(t))
917 return true
921 // checkAddrArgs tries to add arguments to the call of
922 // _cgoCheckPointer when the argument is an address expression. We
923 // pass true to mean that the argument is an address operation of
924 // something other than a slice index, which means that it's only
925 // necessary to check the specific element pointed to, not the entire
926 // object. This is for &s.f, where f is a field in a struct. We can
927 // pass a slice or array, meaning that we should check the entire
928 // slice or array but need not check any other part of the object.
929 // This is for &s.a[i], where we need to check all of a. However, we
930 // only pass the slice or array if we can refer to it without side
931 // effects.
932 func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr {
933 // Strip type conversions.
934 for {
935 c, ok := x.(*ast.CallExpr)
936 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) {
937 break
939 x = c.Args[0]
941 u, ok := x.(*ast.UnaryExpr)
942 if !ok || u.Op != token.AND {
943 return args
945 index, ok := u.X.(*ast.IndexExpr)
946 if !ok {
947 // This is the address of something that is not an
948 // index expression. We only need to examine the
949 // single value to which it points.
950 // TODO: what if true is shadowed?
951 return append(args, ast.NewIdent("true"))
953 if !p.hasSideEffects(f, index.X) {
954 // Examine the entire slice.
955 return append(args, index.X)
957 // Treat the pointer as unknown.
958 return args
961 // hasSideEffects returns whether the expression x has any side
962 // effects. x is an expression, not a statement, so the only side
963 // effect is a function call.
964 func (p *Package) hasSideEffects(f *File, x ast.Expr) bool {
965 found := false
966 f.walk(x, ctxExpr,
967 func(f *File, x interface{}, context astContext) {
968 switch x.(type) {
969 case *ast.CallExpr:
970 found = true
973 return found
976 // isType returns whether the expression is definitely a type.
977 // This is conservative--it returns false for an unknown identifier.
978 func (p *Package) isType(t ast.Expr) bool {
979 switch t := t.(type) {
980 case *ast.SelectorExpr:
981 id, ok := t.X.(*ast.Ident)
982 if !ok {
983 return false
985 if id.Name == "unsafe" && t.Sel.Name == "Pointer" {
986 return true
988 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil {
989 return true
991 return false
992 case *ast.Ident:
993 // TODO: This ignores shadowing.
994 switch t.Name {
995 case "unsafe.Pointer", "bool", "byte",
996 "complex64", "complex128",
997 "error",
998 "float32", "float64",
999 "int", "int8", "int16", "int32", "int64",
1000 "rune", "string",
1001 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
1003 return true
1005 case *ast.StarExpr:
1006 return p.isType(t.X)
1007 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType,
1008 *ast.MapType, *ast.ChanType:
1010 return true
1012 return false
1015 // rewriteUnsafe returns a version of t with references to unsafe.Pointer
1016 // rewritten to use _cgo_unsafe.Pointer instead.
1017 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr {
1018 switch t := t.(type) {
1019 case *ast.Ident:
1020 // We don't see a SelectorExpr for unsafe.Pointer;
1021 // this is created by code in this file.
1022 if t.Name == "unsafe.Pointer" {
1023 return ast.NewIdent("_cgo_unsafe.Pointer")
1025 case *ast.ArrayType:
1026 t1 := p.rewriteUnsafe(t.Elt)
1027 if t1 != t.Elt {
1028 r := *t
1029 r.Elt = t1
1030 return &r
1032 case *ast.StructType:
1033 changed := false
1034 fields := *t.Fields
1035 fields.List = nil
1036 for _, f := range t.Fields.List {
1037 ft := p.rewriteUnsafe(f.Type)
1038 if ft == f.Type {
1039 fields.List = append(fields.List, f)
1040 } else {
1041 fn := *f
1042 fn.Type = ft
1043 fields.List = append(fields.List, &fn)
1044 changed = true
1047 if changed {
1048 r := *t
1049 r.Fields = &fields
1050 return &r
1052 case *ast.StarExpr: // Pointer type.
1053 x1 := p.rewriteUnsafe(t.X)
1054 if x1 != t.X {
1055 r := *t
1056 r.X = x1
1057 return &r
1060 return t
1063 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the
1064 // Go equivalents, now that we have figured out the meaning of all
1065 // the xxx. In *godefs mode, rewriteRef replaces the names
1066 // with full definitions instead of mangled names.
1067 func (p *Package) rewriteRef(f *File) {
1068 // Keep a list of all the functions, to remove the ones
1069 // only used as expressions and avoid generating bridge
1070 // code for them.
1071 functions := make(map[string]bool)
1073 // Assign mangled names.
1074 for _, n := range f.Name {
1075 if n.Kind == "not-type" {
1076 if n.Define == "" {
1077 n.Kind = "var"
1078 } else {
1079 n.Kind = "macro"
1080 n.FuncType = &FuncType{
1081 Result: n.Type,
1082 Go: &ast.FuncType{
1083 Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}},
1088 if n.Mangle == "" {
1089 p.mangleName(n)
1091 if n.Kind == "func" {
1092 functions[n.Go] = false
1096 // Now that we have all the name types filled in,
1097 // scan through the Refs to identify the ones that
1098 // are trying to do a ,err call. Also check that
1099 // functions are only used in calls.
1100 for _, r := range f.Ref {
1101 if r.Name.IsConst() && r.Name.Const == "" {
1102 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
1104 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
1105 switch r.Context {
1106 case ctxCall, ctxCall2:
1107 if r.Name.Kind != "func" {
1108 if r.Name.Kind == "type" {
1109 r.Context = ctxType
1110 if r.Name.Type == nil {
1111 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1112 break
1114 expr = r.Name.Type.Go
1115 break
1117 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
1118 break
1120 functions[r.Name.Go] = true
1121 if r.Context == ctxCall2 {
1122 if r.Name.Go == "_CMalloc" {
1123 error_(r.Pos(), "no two-result form for C.malloc")
1124 break
1126 // Invent new Name for the two-result function.
1127 n := f.Name["2"+r.Name.Go]
1128 if n == nil {
1129 n = new(Name)
1130 *n = *r.Name
1131 n.AddError = true
1132 n.Mangle = "_C2func_" + n.Go
1133 f.Name["2"+r.Name.Go] = n
1135 expr = ast.NewIdent(n.Mangle)
1136 r.Name = n
1137 break
1139 case ctxExpr:
1140 switch r.Name.Kind {
1141 case "func":
1142 if builtinDefs[r.Name.C] != "" {
1143 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C))
1146 // Function is being used in an expression, to e.g. pass around a C function pointer.
1147 // Create a new Name for this Ref which causes the variable to be declared in Go land.
1148 fpName := "fp_" + r.Name.Go
1149 name := f.Name[fpName]
1150 if name == nil {
1151 name = &Name{
1152 Go: fpName,
1153 C: r.Name.C,
1154 Kind: "fpvar",
1155 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")},
1157 p.mangleName(name)
1158 f.Name[fpName] = name
1160 r.Name = name
1161 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr
1162 // function is defined in out.go and simply returns its argument. See
1163 // issue 7757.
1164 expr = &ast.CallExpr{
1165 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
1166 Args: []ast.Expr{ast.NewIdent(name.Mangle)},
1168 case "type":
1169 // Okay - might be new(T)
1170 if r.Name.Type == nil {
1171 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1172 break
1174 expr = r.Name.Type.Go
1175 case "var":
1176 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1177 case "macro":
1178 expr = &ast.CallExpr{Fun: expr}
1180 case ctxSelector:
1181 if r.Name.Kind == "var" {
1182 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
1183 } else {
1184 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go))
1186 case ctxType:
1187 if r.Name.Kind != "type" {
1188 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
1189 } else if r.Name.Type == nil {
1190 // Use of C.enum_x, C.struct_x or C.union_x without C definition.
1191 // GCC won't raise an error when using pointers to such unknown types.
1192 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C)
1193 } else {
1194 expr = r.Name.Type.Go
1196 default:
1197 if r.Name.Kind == "func" {
1198 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
1202 if *godefs {
1203 // Substitute definition for mangled type name.
1204 if id, ok := expr.(*ast.Ident); ok {
1205 if t := typedef[id.Name]; t != nil {
1206 expr = t.Go
1208 if id.Name == r.Name.Mangle && r.Name.Const != "" {
1209 expr = ast.NewIdent(r.Name.Const)
1214 // Copy position information from old expr into new expr,
1215 // in case expression being replaced is first on line.
1216 // See golang.org/issue/6563.
1217 pos := (*r.Expr).Pos()
1218 switch x := expr.(type) {
1219 case *ast.Ident:
1220 expr = &ast.Ident{NamePos: pos, Name: x.Name}
1223 // Change AST, because some later processing depends on it,
1224 // and also because -godefs mode still prints the AST.
1225 old := *r.Expr
1226 *r.Expr = expr
1228 // Record source-level edit for cgo output.
1229 repl := gofmt(expr)
1230 if r.Name.Kind != "type" {
1231 repl = "(" + repl + ")"
1233 f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
1236 // Remove functions only used as expressions, so their respective
1237 // bridge functions are not generated.
1238 for name, used := range functions {
1239 if !used {
1240 delete(f.Name, name)
1245 // gccBaseCmd returns the start of the compiler command line.
1246 // It uses $CC if set, or else $GCC, or else the compiler recorded
1247 // during the initial build as defaultCC.
1248 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
1249 func (p *Package) gccBaseCmd() []string {
1250 // Use $CC if set, since that's what the build uses.
1251 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 {
1252 return ret
1254 // Try $GCC if set, since that's what we used to use.
1255 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 {
1256 return ret
1258 return strings.Fields(defaultCC(goos, goarch))
1261 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm".
1262 func (p *Package) gccMachine() []string {
1263 switch goarch {
1264 case "amd64":
1265 return []string{"-m64"}
1266 case "386":
1267 return []string{"-m32"}
1268 case "arm":
1269 return []string{"-marm"} // not thumb
1270 case "s390":
1271 return []string{"-m31"}
1272 case "s390x":
1273 return []string{"-m64"}
1274 case "mips64", "mips64le":
1275 return []string{"-mabi=64"}
1276 case "mips", "mipsle":
1277 return []string{"-mabi=32"}
1278 case "ppc64":
1279 if goos == "aix" {
1280 return []string{"-maix64"}
1283 return nil
1286 func gccTmp() string {
1287 return *objDir + "_cgo_.o"
1290 // gccCmd returns the gcc command line to use for compiling
1291 // the input.
1292 func (p *Package) gccCmd() []string {
1293 c := append(p.gccBaseCmd(),
1294 "-w", // no warnings
1295 "-Wno-error", // warnings are not errors
1296 "-o"+gccTmp(), // write object to tmp
1297 "-gdwarf-2", // generate DWARF v2 debugging symbols
1298 "-c", // do not link
1299 "-xc", // input language is C
1301 if p.GccIsClang {
1302 c = append(c,
1303 "-ferror-limit=0",
1304 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
1305 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another
1306 // flag to disable the warning. Yes, really good diagnostics, clang.
1307 "-Wno-unknown-warning-option",
1308 "-Wno-unneeded-internal-declaration",
1309 "-Wno-unused-function",
1310 "-Qunused-arguments",
1311 // Clang embeds prototypes for some builtin functions,
1312 // like malloc and calloc, but all size_t parameters are
1313 // incorrectly typed unsigned long. We work around that
1314 // by disabling the builtin functions (this is safe as
1315 // it won't affect the actual compilation of the C code).
1316 // See: https://golang.org/issue/6506.
1317 "-fno-builtin",
1321 c = append(c, p.GccOptions...)
1322 c = append(c, p.gccMachine()...)
1323 c = append(c, "-") //read input from standard input
1324 return c
1327 // gccDebug runs gcc -gdwarf-2 over the C program stdin and
1328 // returns the corresponding DWARF data and, if present, debug data block.
1329 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) {
1330 runGcc(stdin, p.gccCmd())
1332 isDebugInts := func(s string) bool {
1333 // Some systems use leading _ to denote non-assembly symbols.
1334 return s == "__cgodebug_ints" || s == "___cgodebug_ints"
1336 isDebugFloats := func(s string) bool {
1337 // Some systems use leading _ to denote non-assembly symbols.
1338 return s == "__cgodebug_floats" || s == "___cgodebug_floats"
1340 indexOfDebugStr := func(s string) int {
1341 // Some systems use leading _ to denote non-assembly symbols.
1342 if strings.HasPrefix(s, "___") {
1343 s = s[1:]
1345 if strings.HasPrefix(s, "__cgodebug_str__") {
1346 if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil {
1347 return n
1350 return -1
1352 indexOfDebugStrlen := func(s string) int {
1353 // Some systems use leading _ to denote non-assembly symbols.
1354 if strings.HasPrefix(s, "___") {
1355 s = s[1:]
1357 if strings.HasPrefix(s, "__cgodebug_strlen__") {
1358 if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil {
1359 return n
1362 return -1
1365 strs = make([]string, nnames)
1367 strdata := make(map[int]string, nnames)
1368 strlens := make(map[int]int, nnames)
1370 buildStrings := func() {
1371 for n, strlen := range strlens {
1372 data := strdata[n]
1373 if len(data) <= strlen {
1374 fatalf("invalid string literal")
1376 strs[n] = string(data[:strlen])
1380 if f, err := macho.Open(gccTmp()); err == nil {
1381 defer f.Close()
1382 d, err := f.DWARF()
1383 if err != nil {
1384 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1386 bo := f.ByteOrder
1387 if f.Symtab != nil {
1388 for i := range f.Symtab.Syms {
1389 s := &f.Symtab.Syms[i]
1390 switch {
1391 case isDebugInts(s.Name):
1392 // Found it. Now find data section.
1393 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1394 sect := f.Sections[i]
1395 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1396 if sdat, err := sect.Data(); err == nil {
1397 data := sdat[s.Value-sect.Addr:]
1398 ints = make([]int64, len(data)/8)
1399 for i := range ints {
1400 ints[i] = int64(bo.Uint64(data[i*8:]))
1405 case isDebugFloats(s.Name):
1406 // Found it. Now find data section.
1407 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1408 sect := f.Sections[i]
1409 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1410 if sdat, err := sect.Data(); err == nil {
1411 data := sdat[s.Value-sect.Addr:]
1412 floats = make([]float64, len(data)/8)
1413 for i := range floats {
1414 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1419 default:
1420 if n := indexOfDebugStr(s.Name); n != -1 {
1421 // Found it. Now find data section.
1422 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1423 sect := f.Sections[i]
1424 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1425 if sdat, err := sect.Data(); err == nil {
1426 data := sdat[s.Value-sect.Addr:]
1427 strdata[n] = string(data)
1431 break
1433 if n := indexOfDebugStrlen(s.Name); n != -1 {
1434 // Found it. Now find data section.
1435 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
1436 sect := f.Sections[i]
1437 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1438 if sdat, err := sect.Data(); err == nil {
1439 data := sdat[s.Value-sect.Addr:]
1440 strlen := bo.Uint64(data[:8])
1441 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1442 fatalf("string literal too big")
1444 strlens[n] = int(strlen)
1448 break
1453 buildStrings()
1455 return d, ints, floats, strs
1458 if f, err := elf.Open(gccTmp()); err == nil {
1459 defer f.Close()
1460 d, err := f.DWARF()
1461 if err != nil {
1462 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1464 bo := f.ByteOrder
1465 symtab, err := f.Symbols()
1466 if err == nil {
1467 for i := range symtab {
1468 s := &symtab[i]
1469 switch {
1470 case isDebugInts(s.Name):
1471 // Found it. Now find data section.
1472 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1473 sect := f.Sections[i]
1474 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1475 if sdat, err := sect.Data(); err == nil {
1476 data := sdat[s.Value-sect.Addr:]
1477 ints = make([]int64, len(data)/8)
1478 for i := range ints {
1479 ints[i] = int64(bo.Uint64(data[i*8:]))
1484 case isDebugFloats(s.Name):
1485 // Found it. Now find data section.
1486 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1487 sect := f.Sections[i]
1488 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1489 if sdat, err := sect.Data(); err == nil {
1490 data := sdat[s.Value-sect.Addr:]
1491 floats = make([]float64, len(data)/8)
1492 for i := range floats {
1493 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1498 default:
1499 if n := indexOfDebugStr(s.Name); n != -1 {
1500 // Found it. Now find data section.
1501 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1502 sect := f.Sections[i]
1503 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1504 if sdat, err := sect.Data(); err == nil {
1505 data := sdat[s.Value-sect.Addr:]
1506 strdata[n] = string(data)
1510 break
1512 if n := indexOfDebugStrlen(s.Name); n != -1 {
1513 // Found it. Now find data section.
1514 if i := int(s.Section); 0 <= i && i < len(f.Sections) {
1515 sect := f.Sections[i]
1516 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
1517 if sdat, err := sect.Data(); err == nil {
1518 data := sdat[s.Value-sect.Addr:]
1519 strlen := bo.Uint64(data[:8])
1520 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1521 fatalf("string literal too big")
1523 strlens[n] = int(strlen)
1527 break
1532 buildStrings()
1534 return d, ints, floats, strs
1537 if f, err := pe.Open(gccTmp()); err == nil {
1538 defer f.Close()
1539 d, err := f.DWARF()
1540 if err != nil {
1541 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1543 bo := binary.LittleEndian
1544 for _, s := range f.Symbols {
1545 switch {
1546 case isDebugInts(s.Name):
1547 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1548 sect := f.Sections[i]
1549 if s.Value < sect.Size {
1550 if sdat, err := sect.Data(); err == nil {
1551 data := sdat[s.Value:]
1552 ints = make([]int64, len(data)/8)
1553 for i := range ints {
1554 ints[i] = int64(bo.Uint64(data[i*8:]))
1559 case isDebugFloats(s.Name):
1560 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1561 sect := f.Sections[i]
1562 if s.Value < sect.Size {
1563 if sdat, err := sect.Data(); err == nil {
1564 data := sdat[s.Value:]
1565 floats = make([]float64, len(data)/8)
1566 for i := range floats {
1567 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1572 default:
1573 if n := indexOfDebugStr(s.Name); n != -1 {
1574 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1575 sect := f.Sections[i]
1576 if s.Value < sect.Size {
1577 if sdat, err := sect.Data(); err == nil {
1578 data := sdat[s.Value:]
1579 strdata[n] = string(data)
1583 break
1585 if n := indexOfDebugStrlen(s.Name); n != -1 {
1586 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1587 sect := f.Sections[i]
1588 if s.Value < sect.Size {
1589 if sdat, err := sect.Data(); err == nil {
1590 data := sdat[s.Value:]
1591 strlen := bo.Uint64(data[:8])
1592 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1593 fatalf("string literal too big")
1595 strlens[n] = int(strlen)
1599 break
1604 buildStrings()
1606 return d, ints, floats, strs
1609 if f, err := xcoff.Open(gccTmp()); err == nil {
1610 defer f.Close()
1611 d, err := f.DWARF()
1612 if err != nil {
1613 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err)
1615 bo := binary.BigEndian
1616 for _, s := range f.Symbols {
1617 switch {
1618 case isDebugInts(s.Name):
1619 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1620 sect := f.Sections[i]
1621 if s.Value < sect.Size {
1622 if sdat, err := sect.Data(); err == nil {
1623 data := sdat[s.Value:]
1624 ints = make([]int64, len(data)/8)
1625 for i := range ints {
1626 ints[i] = int64(bo.Uint64(data[i*8:]))
1631 case isDebugFloats(s.Name):
1632 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1633 sect := f.Sections[i]
1634 if s.Value < sect.Size {
1635 if sdat, err := sect.Data(); err == nil {
1636 data := sdat[s.Value:]
1637 floats = make([]float64, len(data)/8)
1638 for i := range floats {
1639 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:]))
1644 default:
1645 if n := indexOfDebugStr(s.Name); n != -1 {
1646 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1647 sect := f.Sections[i]
1648 if s.Value < sect.Size {
1649 if sdat, err := sect.Data(); err == nil {
1650 data := sdat[s.Value:]
1651 strdata[n] = string(data)
1655 break
1657 if n := indexOfDebugStrlen(s.Name); n != -1 {
1658 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) {
1659 sect := f.Sections[i]
1660 if s.Value < sect.Size {
1661 if sdat, err := sect.Data(); err == nil {
1662 data := sdat[s.Value:]
1663 strlen := bo.Uint64(data[:8])
1664 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt?
1665 fatalf("string literal too big")
1667 strlens[n] = int(strlen)
1671 break
1676 buildStrings()
1678 return d, ints, floats, strs
1681 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp())
1682 panic("not reached")
1685 // gccDefines runs gcc -E -dM -xc - over the C program stdin
1686 // and returns the corresponding standard output, which is the
1687 // #defines that gcc encountered while processing the input
1688 // and its included files.
1689 func (p *Package) gccDefines(stdin []byte) string {
1690 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc")
1691 base = append(base, p.gccMachine()...)
1692 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-"))
1693 return stdout
1696 // gccErrors runs gcc over the C program stdin and returns
1697 // the errors that gcc prints. That is, this function expects
1698 // gcc to fail.
1699 func (p *Package) gccErrors(stdin []byte) string {
1700 // TODO(rsc): require failure
1701 args := p.gccCmd()
1703 // Optimization options can confuse the error messages; remove them.
1704 nargs := make([]string, 0, len(args))
1705 for _, arg := range args {
1706 if !strings.HasPrefix(arg, "-O") {
1707 nargs = append(nargs, arg)
1711 if *debugGcc {
1712 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " "))
1713 os.Stderr.Write(stdin)
1714 fmt.Fprint(os.Stderr, "EOF\n")
1716 stdout, stderr, _ := run(stdin, nargs)
1717 if *debugGcc {
1718 os.Stderr.Write(stdout)
1719 os.Stderr.Write(stderr)
1721 return string(stderr)
1724 // runGcc runs the gcc command line args with stdin on standard input.
1725 // If the command exits with a non-zero exit status, runGcc prints
1726 // details about what was run and exits.
1727 // Otherwise runGcc returns the data written to standard output and standard error.
1728 // Note that for some of the uses we expect useful data back
1729 // on standard error, but for those uses gcc must still exit 0.
1730 func runGcc(stdin []byte, args []string) (string, string) {
1731 if *debugGcc {
1732 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " "))
1733 os.Stderr.Write(stdin)
1734 fmt.Fprint(os.Stderr, "EOF\n")
1736 stdout, stderr, ok := run(stdin, args)
1737 if *debugGcc {
1738 os.Stderr.Write(stdout)
1739 os.Stderr.Write(stderr)
1741 if !ok {
1742 os.Stderr.Write(stderr)
1743 os.Exit(2)
1745 return string(stdout), string(stderr)
1748 // A typeConv is a translator from dwarf types to Go types
1749 // with equivalent memory layout.
1750 type typeConv struct {
1751 // Cache of already-translated or in-progress types.
1752 m map[dwarf.Type]*Type
1754 // Map from types to incomplete pointers to those types.
1755 ptrs map[dwarf.Type][]*Type
1756 // Keys of ptrs in insertion order (deterministic worklist)
1757 ptrKeys []dwarf.Type
1759 // Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
1760 getTypeIDs map[string]bool
1762 // Predeclared types.
1763 bool ast.Expr
1764 byte ast.Expr // denotes padding
1765 int8, int16, int32, int64 ast.Expr
1766 uint8, uint16, uint32, uint64, uintptr ast.Expr
1767 float32, float64 ast.Expr
1768 complex64, complex128 ast.Expr
1769 void ast.Expr
1770 string ast.Expr
1771 goVoid ast.Expr // _Ctype_void, denotes C's void
1772 goVoidPtr ast.Expr // unsafe.Pointer or *byte
1774 ptrSize int64
1775 intSize int64
1778 var tagGen int
1779 var typedef = make(map[string]*Type)
1780 var goIdent = make(map[string]*ast.Ident)
1782 // unionWithPointer is true for a Go type that represents a C union (or class)
1783 // that may contain a pointer. This is used for cgo pointer checking.
1784 var unionWithPointer = make(map[ast.Expr]bool)
1786 func (c *typeConv) Init(ptrSize, intSize int64) {
1787 c.ptrSize = ptrSize
1788 c.intSize = intSize
1789 c.m = make(map[dwarf.Type]*Type)
1790 c.ptrs = make(map[dwarf.Type][]*Type)
1791 c.getTypeIDs = make(map[string]bool)
1792 c.bool = c.Ident("bool")
1793 c.byte = c.Ident("byte")
1794 c.int8 = c.Ident("int8")
1795 c.int16 = c.Ident("int16")
1796 c.int32 = c.Ident("int32")
1797 c.int64 = c.Ident("int64")
1798 c.uint8 = c.Ident("uint8")
1799 c.uint16 = c.Ident("uint16")
1800 c.uint32 = c.Ident("uint32")
1801 c.uint64 = c.Ident("uint64")
1802 c.uintptr = c.Ident("uintptr")
1803 c.float32 = c.Ident("float32")
1804 c.float64 = c.Ident("float64")
1805 c.complex64 = c.Ident("complex64")
1806 c.complex128 = c.Ident("complex128")
1807 c.void = c.Ident("void")
1808 c.string = c.Ident("string")
1809 c.goVoid = c.Ident("_Ctype_void")
1811 // Normally cgo translates void* to unsafe.Pointer,
1812 // but for historical reasons -godefs uses *byte instead.
1813 if *godefs {
1814 c.goVoidPtr = &ast.StarExpr{X: c.byte}
1815 } else {
1816 c.goVoidPtr = c.Ident("unsafe.Pointer")
1820 // base strips away qualifiers and typedefs to get the underlying type
1821 func base(dt dwarf.Type) dwarf.Type {
1822 for {
1823 if d, ok := dt.(*dwarf.QualType); ok {
1824 dt = d.Type
1825 continue
1827 if d, ok := dt.(*dwarf.TypedefType); ok {
1828 dt = d.Type
1829 continue
1831 break
1833 return dt
1836 // unqual strips away qualifiers from a DWARF type.
1837 // In general we don't care about top-level qualifiers.
1838 func unqual(dt dwarf.Type) dwarf.Type {
1839 for {
1840 if d, ok := dt.(*dwarf.QualType); ok {
1841 dt = d.Type
1842 } else {
1843 break
1846 return dt
1849 // Map from dwarf text names to aliases we use in package "C".
1850 var dwarfToName = map[string]string{
1851 "long int": "long",
1852 "long unsigned int": "ulong",
1853 "unsigned int": "uint",
1854 "short unsigned int": "ushort",
1855 "unsigned short": "ushort", // Used by Clang; issue 13129.
1856 "short int": "short",
1857 "long long int": "longlong",
1858 "long long unsigned int": "ulonglong",
1859 "signed char": "schar",
1860 "unsigned char": "uchar",
1863 const signedDelta = 64
1865 // String returns the current type representation. Format arguments
1866 // are assembled within this method so that any changes in mutable
1867 // values are taken into account.
1868 func (tr *TypeRepr) String() string {
1869 if len(tr.Repr) == 0 {
1870 return ""
1872 if len(tr.FormatArgs) == 0 {
1873 return tr.Repr
1875 return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
1878 // Empty reports whether the result of String would be "".
1879 func (tr *TypeRepr) Empty() bool {
1880 return len(tr.Repr) == 0
1883 // Set modifies the type representation.
1884 // If fargs are provided, repr is used as a format for fmt.Sprintf.
1885 // Otherwise, repr is used unprocessed as the type representation.
1886 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
1887 tr.Repr = repr
1888 tr.FormatArgs = fargs
1891 // FinishType completes any outstanding type mapping work.
1892 // In particular, it resolves incomplete pointer types.
1893 func (c *typeConv) FinishType(pos token.Pos) {
1894 // Completing one pointer type might produce more to complete.
1895 // Keep looping until they're all done.
1896 for len(c.ptrKeys) > 0 {
1897 dtype := c.ptrKeys[0]
1898 c.ptrKeys = c.ptrKeys[1:]
1900 // Note Type might invalidate c.ptrs[dtype].
1901 t := c.Type(dtype, pos)
1902 for _, ptr := range c.ptrs[dtype] {
1903 ptr.Go.(*ast.StarExpr).X = t.Go
1904 ptr.C.Set("%s*", t.C)
1906 c.ptrs[dtype] = nil // retain the map key
1910 // Type returns a *Type with the same memory layout as
1911 // dtype when used as the type of a variable or a struct field.
1912 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
1913 if t, ok := c.m[dtype]; ok {
1914 if t.Go == nil {
1915 fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
1917 return t
1920 t := new(Type)
1921 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
1922 t.Align = -1
1923 t.C = &TypeRepr{Repr: dtype.Common().Name}
1924 c.m[dtype] = t
1926 switch dt := dtype.(type) {
1927 default:
1928 fatalf("%s: unexpected type: %s", lineno(pos), dtype)
1930 case *dwarf.AddrType:
1931 if t.Size != c.ptrSize {
1932 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
1934 t.Go = c.uintptr
1935 t.Align = t.Size
1937 case *dwarf.ArrayType:
1938 if dt.StrideBitSize > 0 {
1939 // Cannot represent bit-sized elements in Go.
1940 t.Go = c.Opaque(t.Size)
1941 break
1943 count := dt.Count
1944 if count == -1 {
1945 // Indicates flexible array member, which Go doesn't support.
1946 // Translate to zero-length array instead.
1947 count = 0
1949 sub := c.Type(dt.Type, pos)
1950 t.Align = sub.Align
1951 t.Go = &ast.ArrayType{
1952 Len: c.intExpr(count),
1953 Elt: sub.Go,
1955 // Recalculate t.Size now that we know sub.Size.
1956 t.Size = count * sub.Size
1957 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
1959 case *dwarf.BoolType:
1960 t.Go = c.bool
1961 t.Align = 1
1963 case *dwarf.CharType:
1964 if t.Size != 1 {
1965 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
1967 t.Go = c.int8
1968 t.Align = 1
1970 case *dwarf.EnumType:
1971 if t.Align = t.Size; t.Align >= c.ptrSize {
1972 t.Align = c.ptrSize
1974 t.C.Set("enum " + dt.EnumName)
1975 signed := 0
1976 t.EnumValues = make(map[string]int64)
1977 for _, ev := range dt.Val {
1978 t.EnumValues[ev.Name] = ev.Val
1979 if ev.Val < 0 {
1980 signed = signedDelta
1983 switch t.Size + int64(signed) {
1984 default:
1985 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
1986 case 1:
1987 t.Go = c.uint8
1988 case 2:
1989 t.Go = c.uint16
1990 case 4:
1991 t.Go = c.uint32
1992 case 8:
1993 t.Go = c.uint64
1994 case 1 + signedDelta:
1995 t.Go = c.int8
1996 case 2 + signedDelta:
1997 t.Go = c.int16
1998 case 4 + signedDelta:
1999 t.Go = c.int32
2000 case 8 + signedDelta:
2001 t.Go = c.int64
2004 case *dwarf.FloatType:
2005 switch t.Size {
2006 default:
2007 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
2008 case 4:
2009 t.Go = c.float32
2010 case 8:
2011 t.Go = c.float64
2013 if t.Align = t.Size; t.Align >= c.ptrSize {
2014 t.Align = c.ptrSize
2017 case *dwarf.ComplexType:
2018 switch t.Size {
2019 default:
2020 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
2021 case 8:
2022 t.Go = c.complex64
2023 case 16:
2024 t.Go = c.complex128
2026 if t.Align = t.Size / 2; t.Align >= c.ptrSize {
2027 t.Align = c.ptrSize
2030 case *dwarf.FuncType:
2031 // No attempt at translation: would enable calls
2032 // directly between worlds, but we need to moderate those.
2033 t.Go = c.uintptr
2034 t.Align = c.ptrSize
2036 case *dwarf.IntType:
2037 if dt.BitSize > 0 {
2038 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
2040 switch t.Size {
2041 default:
2042 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
2043 case 1:
2044 t.Go = c.int8
2045 case 2:
2046 t.Go = c.int16
2047 case 4:
2048 t.Go = c.int32
2049 case 8:
2050 t.Go = c.int64
2051 case 16:
2052 t.Go = &ast.ArrayType{
2053 Len: c.intExpr(t.Size),
2054 Elt: c.uint8,
2057 if t.Align = t.Size; t.Align >= c.ptrSize {
2058 t.Align = c.ptrSize
2061 case *dwarf.PtrType:
2062 // Clang doesn't emit DW_AT_byte_size for pointer types.
2063 if t.Size != c.ptrSize && t.Size != -1 {
2064 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
2066 t.Size = c.ptrSize
2067 t.Align = c.ptrSize
2069 if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
2070 t.Go = c.goVoidPtr
2071 t.C.Set("void*")
2072 dq := dt.Type
2073 for {
2074 if d, ok := dq.(*dwarf.QualType); ok {
2075 t.C.Set(d.Qual + " " + t.C.String())
2076 dq = d.Type
2077 } else {
2078 break
2081 break
2084 // Placeholder initialization; completed in FinishType.
2085 t.Go = &ast.StarExpr{}
2086 t.C.Set("<incomplete>*")
2087 if _, ok := c.ptrs[dt.Type]; !ok {
2088 c.ptrKeys = append(c.ptrKeys, dt.Type)
2090 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
2092 case *dwarf.QualType:
2093 t1 := c.Type(dt.Type, pos)
2094 t.Size = t1.Size
2095 t.Align = t1.Align
2096 t.Go = t1.Go
2097 if unionWithPointer[t1.Go] {
2098 unionWithPointer[t.Go] = true
2100 t.EnumValues = nil
2101 t.Typedef = ""
2102 t.C.Set("%s "+dt.Qual, t1.C)
2103 return t
2105 case *dwarf.StructType:
2106 // Convert to Go struct, being careful about alignment.
2107 // Have to give it a name to simulate C "struct foo" references.
2108 tag := dt.StructName
2109 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible
2110 break
2112 if tag == "" {
2113 tag = "__" + strconv.Itoa(tagGen)
2114 tagGen++
2115 } else if t.C.Empty() {
2116 t.C.Set(dt.Kind + " " + tag)
2118 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag)
2119 t.Go = name // publish before recursive calls
2120 goIdent[name.Name] = name
2121 if dt.ByteSize < 0 {
2122 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown),
2123 // so execute the basic things that the struct case would do
2124 // other than try to determine a Go representation.
2125 tt := *t
2126 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
2127 tt.Go = c.Ident("struct{}")
2128 typedef[name.Name] = &tt
2129 break
2131 switch dt.Kind {
2132 case "class", "union":
2133 t.Go = c.Opaque(t.Size)
2134 if c.dwarfHasPointer(dt, pos) {
2135 unionWithPointer[t.Go] = true
2137 if t.C.Empty() {
2138 t.C.Set("__typeof__(unsigned char[%d])", t.Size)
2140 t.Align = 1 // TODO: should probably base this on field alignment.
2141 typedef[name.Name] = t
2142 case "struct":
2143 g, csyntax, align := c.Struct(dt, pos)
2144 if t.C.Empty() {
2145 t.C.Set(csyntax)
2147 t.Align = align
2148 tt := *t
2149 if tag != "" {
2150 tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
2152 tt.Go = g
2153 typedef[name.Name] = &tt
2156 case *dwarf.TypedefType:
2157 // Record typedef for printing.
2158 if dt.Name == "_GoString_" {
2159 // Special C name for Go string type.
2160 // Knows string layout used by compilers: pointer plus length,
2161 // which rounds up to 2 pointers after alignment.
2162 t.Go = c.string
2163 t.Size = c.ptrSize * 2
2164 t.Align = c.ptrSize
2165 break
2167 if dt.Name == "_GoBytes_" {
2168 // Special C name for Go []byte type.
2169 // Knows slice layout used by compilers: pointer, length, cap.
2170 t.Go = c.Ident("[]byte")
2171 t.Size = c.ptrSize + 4 + 4
2172 t.Align = c.ptrSize
2173 break
2175 name := c.Ident("_Ctype_" + dt.Name)
2176 goIdent[name.Name] = name
2177 sub := c.Type(dt.Type, pos)
2178 if c.badPointerTypedef(dt) {
2179 // Treat this typedef as a uintptr.
2180 s := *sub
2181 s.Go = c.uintptr
2182 sub = &s
2184 t.Go = name
2185 if unionWithPointer[sub.Go] {
2186 unionWithPointer[t.Go] = true
2188 t.Size = sub.Size
2189 t.Align = sub.Align
2190 oldType := typedef[name.Name]
2191 if oldType == nil {
2192 tt := *t
2193 tt.Go = sub.Go
2194 typedef[name.Name] = &tt
2197 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
2198 // use that as the Go form for this typedef too, so that the typedef will be interchangeable
2199 // with the base type.
2200 // In -godefs mode, do this for all typedefs.
2201 if isStructUnionClass(sub.Go) || *godefs {
2202 t.Go = sub.Go
2204 if isStructUnionClass(sub.Go) {
2205 // Use the typedef name for C code.
2206 typedef[sub.Go.(*ast.Ident).Name].C = t.C
2209 // If we've seen this typedef before, and it
2210 // was an anonymous struct/union/class before
2211 // too, use the old definition.
2212 // TODO: it would be safer to only do this if
2213 // we verify that the types are the same.
2214 if oldType != nil && isStructUnionClass(oldType.Go) {
2215 t.Go = oldType.Go
2219 case *dwarf.UcharType:
2220 if t.Size != 1 {
2221 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
2223 t.Go = c.uint8
2224 t.Align = 1
2226 case *dwarf.UintType:
2227 if dt.BitSize > 0 {
2228 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
2230 switch t.Size {
2231 default:
2232 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
2233 case 1:
2234 t.Go = c.uint8
2235 case 2:
2236 t.Go = c.uint16
2237 case 4:
2238 t.Go = c.uint32
2239 case 8:
2240 t.Go = c.uint64
2241 case 16:
2242 t.Go = &ast.ArrayType{
2243 Len: c.intExpr(t.Size),
2244 Elt: c.uint8,
2247 if t.Align = t.Size; t.Align >= c.ptrSize {
2248 t.Align = c.ptrSize
2251 case *dwarf.VoidType:
2252 t.Go = c.goVoid
2253 t.C.Set("void")
2254 t.Align = 1
2257 switch dtype.(type) {
2258 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType:
2259 s := dtype.Common().Name
2260 if s != "" {
2261 if ss, ok := dwarfToName[s]; ok {
2262 s = ss
2264 s = strings.Replace(s, " ", "", -1)
2265 name := c.Ident("_Ctype_" + s)
2266 tt := *t
2267 typedef[name.Name] = &tt
2268 if !*godefs {
2269 t.Go = name
2274 if t.Size < 0 {
2275 // Unsized types are [0]byte, unless they're typedefs of other types
2276 // or structs with tags.
2277 // if so, use the name we've already defined.
2278 t.Size = 0
2279 switch dt := dtype.(type) {
2280 case *dwarf.TypedefType:
2281 // ok
2282 case *dwarf.StructType:
2283 if dt.StructName != "" {
2284 break
2286 t.Go = c.Opaque(0)
2287 default:
2288 t.Go = c.Opaque(0)
2290 if t.C.Empty() {
2291 t.C.Set("void")
2295 if t.C.Empty() {
2296 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
2299 return t
2302 // isStructUnionClass reports whether the type described by the Go syntax x
2303 // is a struct, union, or class with a tag.
2304 func isStructUnionClass(x ast.Expr) bool {
2305 id, ok := x.(*ast.Ident)
2306 if !ok {
2307 return false
2309 name := id.Name
2310 return strings.HasPrefix(name, "_Ctype_struct_") ||
2311 strings.HasPrefix(name, "_Ctype_union_") ||
2312 strings.HasPrefix(name, "_Ctype_class_")
2315 // FuncArg returns a Go type with the same memory layout as
2316 // dtype when used as the type of a C function argument.
2317 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
2318 t := c.Type(unqual(dtype), pos)
2319 switch dt := dtype.(type) {
2320 case *dwarf.ArrayType:
2321 // Arrays are passed implicitly as pointers in C.
2322 // In Go, we must be explicit.
2323 tr := &TypeRepr{}
2324 tr.Set("%s*", t.C)
2325 return &Type{
2326 Size: c.ptrSize,
2327 Align: c.ptrSize,
2328 Go: &ast.StarExpr{X: t.Go},
2329 C: tr,
2331 case *dwarf.TypedefType:
2332 // C has much more relaxed rules than Go for
2333 // implicit type conversions. When the parameter
2334 // is type T defined as *X, simulate a little of the
2335 // laxness of C by making the argument *X instead of T.
2336 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok {
2337 // Unless the typedef happens to point to void* since
2338 // Go has special rules around using unsafe.Pointer.
2339 if _, void := base(ptr.Type).(*dwarf.VoidType); void {
2340 break
2342 // ...or the typedef is one in which we expect bad pointers.
2343 // It will be a uintptr instead of *X.
2344 if c.badPointerTypedef(dt) {
2345 break
2348 t = c.Type(ptr, pos)
2349 if t == nil {
2350 return nil
2353 // For a struct/union/class, remember the C spelling,
2354 // in case it has __attribute__((unavailable)).
2355 // See issue 2888.
2356 if isStructUnionClass(t.Go) {
2357 t.Typedef = dt.Name
2361 return t
2364 // FuncType returns the Go type analogous to dtype.
2365 // There is no guarantee about matching memory layout.
2366 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
2367 p := make([]*Type, len(dtype.ParamType))
2368 gp := make([]*ast.Field, len(dtype.ParamType))
2369 for i, f := range dtype.ParamType {
2370 // gcc's DWARF generator outputs a single DotDotDotType parameter for
2371 // function pointers that specify no parameters (e.g. void
2372 // (*__cgo_0)()). Treat this special case as void. This case is
2373 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not
2374 // legal).
2375 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 {
2376 p, gp = nil, nil
2377 break
2379 p[i] = c.FuncArg(f, pos)
2380 gp[i] = &ast.Field{Type: p[i].Go}
2382 var r *Type
2383 var gr []*ast.Field
2384 if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok {
2385 gr = []*ast.Field{{Type: c.goVoid}}
2386 } else if dtype.ReturnType != nil {
2387 r = c.Type(unqual(dtype.ReturnType), pos)
2388 gr = []*ast.Field{{Type: r.Go}}
2390 return &FuncType{
2391 Params: p,
2392 Result: r,
2393 Go: &ast.FuncType{
2394 Params: &ast.FieldList{List: gp},
2395 Results: &ast.FieldList{List: gr},
2400 // Identifier
2401 func (c *typeConv) Ident(s string) *ast.Ident {
2402 return ast.NewIdent(s)
2405 // Opaque type of n bytes.
2406 func (c *typeConv) Opaque(n int64) ast.Expr {
2407 return &ast.ArrayType{
2408 Len: c.intExpr(n),
2409 Elt: c.byte,
2413 // Expr for integer n.
2414 func (c *typeConv) intExpr(n int64) ast.Expr {
2415 return &ast.BasicLit{
2416 Kind: token.INT,
2417 Value: strconv.FormatInt(n, 10),
2421 // Add padding of given size to fld.
2422 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
2423 n := len(fld)
2424 fld = fld[0 : n+1]
2425 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
2426 sizes = sizes[0 : n+1]
2427 sizes[n] = size
2428 return fld, sizes
2431 // Struct conversion: return Go and (gc) C syntax for type.
2432 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
2433 // Minimum alignment for a struct is 1 byte.
2434 align = 1
2436 var buf bytes.Buffer
2437 buf.WriteString("struct {")
2438 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
2439 sizes := make([]int64, 0, 2*len(dt.Field)+1)
2440 off := int64(0)
2442 // Rename struct fields that happen to be named Go keywords into
2443 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will
2444 // be mangled. Any existing identifier that already has the same name on
2445 // the C-side will cause the Go-mangled version to be prefixed with _.
2446 // (e.g. in a struct with fields '_type' and 'type', the latter would be
2447 // rendered as '__type' in Go).
2448 ident := make(map[string]string)
2449 used := make(map[string]bool)
2450 for _, f := range dt.Field {
2451 ident[f.Name] = f.Name
2452 used[f.Name] = true
2455 if !*godefs {
2456 for cid, goid := range ident {
2457 if token.Lookup(goid).IsKeyword() {
2458 // Avoid keyword
2459 goid = "_" + goid
2461 // Also avoid existing fields
2462 for _, exist := used[goid]; exist; _, exist = used[goid] {
2463 goid = "_" + goid
2466 used[goid] = true
2467 ident[cid] = goid
2472 anon := 0
2473 for _, f := range dt.Field {
2474 if f.ByteOffset > off {
2475 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
2476 off = f.ByteOffset
2479 name := f.Name
2480 ft := f.Type
2482 // In godefs mode, if this field is a C11
2483 // anonymous union then treat the first field in the
2484 // union as the field in the struct. This handles
2485 // cases like the glibc <sys/resource.h> file; see
2486 // issue 6677.
2487 if *godefs {
2488 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
2489 name = st.Field[0].Name
2490 ident[name] = name
2491 ft = st.Field[0].Type
2495 // TODO: Handle fields that are anonymous structs by
2496 // promoting the fields of the inner struct.
2498 t := c.Type(ft, pos)
2499 tgo := t.Go
2500 size := t.Size
2501 talign := t.Align
2502 if f.BitSize > 0 {
2503 switch f.BitSize {
2504 case 8, 16, 32, 64:
2505 default:
2506 continue
2508 size = f.BitSize / 8
2509 name := tgo.(*ast.Ident).String()
2510 if strings.HasPrefix(name, "int") {
2511 name = "int"
2512 } else {
2513 name = "uint"
2515 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize))
2516 talign = size
2519 if talign > 0 && f.ByteOffset%talign != 0 {
2520 // Drop misaligned fields, the same way we drop integer bit fields.
2521 // The goal is to make available what can be made available.
2522 // Otherwise one bad and unneeded field in an otherwise okay struct
2523 // makes the whole program not compile. Much of the time these
2524 // structs are in system headers that cannot be corrected.
2525 continue
2527 n := len(fld)
2528 fld = fld[0 : n+1]
2529 if name == "" {
2530 name = fmt.Sprintf("anon%d", anon)
2531 anon++
2532 ident[name] = name
2534 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
2535 sizes = sizes[0 : n+1]
2536 sizes[n] = size
2537 off += size
2538 buf.WriteString(t.C.String())
2539 buf.WriteString(" ")
2540 buf.WriteString(name)
2541 buf.WriteString("; ")
2542 if talign > align {
2543 align = talign
2546 if off < dt.ByteSize {
2547 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
2548 off = dt.ByteSize
2551 // If the last field in a non-zero-sized struct is zero-sized
2552 // the compiler is going to pad it by one (see issue 9401).
2553 // We can't permit that, because then the size of the Go
2554 // struct will not be the same as the size of the C struct.
2555 // Our only option in such a case is to remove the field,
2556 // which means that it cannot be referenced from Go.
2557 for off > 0 && sizes[len(sizes)-1] == 0 {
2558 n := len(sizes)
2559 fld = fld[0 : n-1]
2560 sizes = sizes[0 : n-1]
2563 if off != dt.ByteSize {
2564 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
2566 buf.WriteString("}")
2567 csyntax = buf.String()
2569 if *godefs {
2570 godefsFields(fld)
2572 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
2573 return
2576 // dwarfHasPointer returns whether the DWARF type dt contains a pointer.
2577 func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool {
2578 switch dt := dt.(type) {
2579 default:
2580 fatalf("%s: unexpected type: %s", lineno(pos), dt)
2581 return false
2583 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType,
2584 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType,
2585 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType:
2587 return false
2589 case *dwarf.ArrayType:
2590 return c.dwarfHasPointer(dt.Type, pos)
2592 case *dwarf.PtrType:
2593 return true
2595 case *dwarf.QualType:
2596 return c.dwarfHasPointer(dt.Type, pos)
2598 case *dwarf.StructType:
2599 for _, f := range dt.Field {
2600 if c.dwarfHasPointer(f.Type, pos) {
2601 return true
2604 return false
2606 case *dwarf.TypedefType:
2607 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" {
2608 return true
2610 return c.dwarfHasPointer(dt.Type, pos)
2614 func upper(s string) string {
2615 if s == "" {
2616 return ""
2618 r, size := utf8.DecodeRuneInString(s)
2619 if r == '_' {
2620 return "X" + s
2622 return string(unicode.ToUpper(r)) + s[size:]
2625 // godefsFields rewrites field names for use in Go or C definitions.
2626 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec)
2627 // converts names to upper case, and rewrites _ into Pad_godefs_n,
2628 // so that all fields are exported.
2629 func godefsFields(fld []*ast.Field) {
2630 prefix := fieldPrefix(fld)
2631 npad := 0
2632 for _, f := range fld {
2633 for _, n := range f.Names {
2634 if n.Name != prefix {
2635 n.Name = strings.TrimPrefix(n.Name, prefix)
2637 if n.Name == "_" {
2638 // Use exported name instead.
2639 n.Name = "Pad_cgo_" + strconv.Itoa(npad)
2640 npad++
2642 n.Name = upper(n.Name)
2647 // fieldPrefix returns the prefix that should be removed from all the
2648 // field names when generating the C or Go code. For generated
2649 // C, we leave the names as is (tv_sec, tv_usec), since that's what
2650 // people are used to seeing in C. For generated Go code, such as
2651 // package syscall's data structures, we drop a common prefix
2652 // (so sec, usec, which will get turned into Sec, Usec for exporting).
2653 func fieldPrefix(fld []*ast.Field) string {
2654 prefix := ""
2655 for _, f := range fld {
2656 for _, n := range f.Names {
2657 // Ignore field names that don't have the prefix we're
2658 // looking for. It is common in C headers to have fields
2659 // named, say, _pad in an otherwise prefixed header.
2660 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we
2661 // still want to remove the tv_ prefix.
2662 // The check for "orig_" here handles orig_eax in the
2663 // x86 ptrace register sets, which otherwise have all fields
2664 // with reg_ prefixes.
2665 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") {
2666 continue
2668 i := strings.Index(n.Name, "_")
2669 if i < 0 {
2670 continue
2672 if prefix == "" {
2673 prefix = n.Name[:i+1]
2674 } else if prefix != n.Name[:i+1] {
2675 return ""
2679 return prefix
2682 // badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go.
2683 // A typedef is bad if C code sometimes stores non-pointers in this type.
2684 // TODO: Currently our best solution is to find these manually and list them as
2685 // they come up. A better solution is desired.
2686 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
2687 if c.badCFType(dt) {
2688 return true
2690 if c.badJNI(dt) {
2691 return true
2693 return false
2696 func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool {
2697 // The real bad types are CFNumberRef and CFDateRef.
2698 // Sometimes non-pointers are stored in these types.
2699 // CFTypeRef is a supertype of those, so it can have bad pointers in it as well.
2700 // We return true for the other *Ref types just so casting between them is easier.
2701 // We identify the correct set of types as those ending in Ref and for which
2702 // there exists a corresponding GetTypeID function.
2703 // See comment below for details about the bad pointers.
2704 if goos != "darwin" {
2705 return false
2707 s := dt.Name
2708 if !strings.HasSuffix(s, "Ref") {
2709 return false
2711 s = s[:len(s)-3]
2712 if s == "CFType" {
2713 return true
2715 if c.getTypeIDs[s] {
2716 return true
2718 if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] {
2719 // Mutable and immutable variants share a type ID.
2720 return true
2722 return false
2725 // Comment from Darwin's CFInternal.h
2727 // Tagged pointer support
2728 // Low-bit set means tagged object, next 3 bits (currently)
2729 // define the tagged object class, next 4 bits are for type
2730 // information for the specific tagged object class. Thus,
2731 // the low byte is for type info, and the rest of a pointer
2732 // (32 or 64-bit) is for payload, whatever the tagged class.
2734 // Note that the specific integers used to identify the
2735 // specific tagged classes can and will change from release
2736 // to release (that's why this stuff is in CF*Internal*.h),
2737 // as can the definition of type info vs payload above.
2739 #if __LP64__
2740 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1)
2741 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
2742 #else
2743 #define CF_IS_TAGGED_OBJ(PTR) 0
2744 #define CF_TAGGED_OBJ_TYPE(PTR) 0
2745 #endif
2747 enum {
2748 kCFTaggedObjectID_Invalid = 0,
2749 kCFTaggedObjectID_Atom = (0 << 1) + 1,
2750 kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
2751 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
2752 kCFTaggedObjectID_Integer = (3 << 1) + 1,
2753 kCFTaggedObjectID_DateTS = (4 << 1) + 1,
2754 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
2755 kCFTaggedObjectID_Date = (6 << 1) + 1,
2756 kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
2760 func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
2761 // In Dalvik and ART, the jobject type in the JNI interface of the JVM has the
2762 // property that it is sometimes (always?) a small integer instead of a real pointer.
2763 // Note: although only the android JVMs are bad in this respect, we declare the JNI types
2764 // bad regardless of platform, so the same Go code compiles on both android and non-android.
2765 if parent, ok := jniTypes[dt.Name]; ok {
2766 // Try to make sure we're talking about a JNI type, not just some random user's
2767 // type that happens to use the same name.
2768 // C doesn't have the notion of a package, so it's hard to be certain.
2770 // Walk up to jobject, checking each typedef on the way.
2771 w := dt
2772 for parent != "" {
2773 t, ok := w.Type.(*dwarf.TypedefType)
2774 if !ok || t.Name != parent {
2775 return false
2777 w = t
2778 parent, ok = jniTypes[w.Name]
2779 if !ok {
2780 return false
2784 // Check that the typedef is:
2785 // struct _jobject;
2786 // typedef struct _jobject *jobject;
2787 if ptr, ok := w.Type.(*dwarf.PtrType); ok {
2788 if str, ok := ptr.Type.(*dwarf.StructType); ok {
2789 if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete {
2790 return true
2795 return false
2798 // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
2799 // they are mapped. The base "jobject" maps to the empty string.
2800 var jniTypes = map[string]string{
2801 "jobject": "",
2802 "jclass": "jobject",
2803 "jthrowable": "jobject",
2804 "jstring": "jobject",
2805 "jarray": "jobject",
2806 "jbooleanArray": "jarray",
2807 "jbyteArray": "jarray",
2808 "jcharArray": "jarray",
2809 "jshortArray": "jarray",
2810 "jintArray": "jarray",
2811 "jlongArray": "jarray",
2812 "jfloatArray": "jarray",
2813 "jdoubleArray": "jarray",
2814 "jobjectArray": "jarray",
2815 "jweak": "jobject",