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 need these when preprocessing for dwarf information.
93 p
.GccOptions
= append(p
.GccOptions
, args
...)
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.
102 // Discard argument in "-I objdir" case.
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
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
) {
134 arg
:= make([]rune
, len(s
))
139 for _
, r
:= range s
{
151 case r
== '"' || r
== '\'':
155 case unicode
.IsSpace(r
):
158 args
= append(args
, string(arg
[:i
]))
167 args
= append(args
, string(arg
[:i
]))
170 err
= errors
.New("unclosed quote")
172 err
= errors
.New("unfinished escaping")
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
)
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\"")
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
) {
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" {
210 line
= strings
.TrimSpace(line
[8:])
213 spaceIndex
:= strings
.Index(line
, " ")
214 tabIndex
:= strings
.Index(line
, "\t")
216 if spaceIndex
== -1 && tabIndex
== -1 {
218 } else if tabIndex
== -1 ||
(spaceIndex
!= -1 && spaceIndex
< tabIndex
) {
219 key
= line
[0:spaceIndex
]
220 val
= strings
.TrimSpace(line
[spaceIndex
:])
222 key
= line
[0:tabIndex
]
223 val
= strings
.TrimSpace(line
[tabIndex
:])
226 if key
== "__clang__" {
230 if n
:= f
.Name
[key
]; n
!= nil {
232 fmt
.Fprintf(os
.Stderr
, "#define %s %s\n", key
, 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
) {
249 // If we've already found this name as a #define
250 // and we can translate it as a constant value, do so.
252 if i
, err
:= strconv
.ParseInt(n
.Define
, 0, 64); err
== nil {
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 {
264 } else if n
.Define
[0] == '"' {
265 if _
, err
:= parser
.ParseExpr(n
.Define
); err
== nil {
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 ") {
279 needType
= append(needType
, n
)
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
)
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.
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.
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",
351 fmt
.Fprintf(&b
, "#line 1 \"completed\"\n"+
352 "int __cgo__1 = __cgo__2;\n")
354 stderr
:= p
.gccErrors(b
.Bytes())
356 fatalf("%s produced no output\non input:\n%s", p
.gccBaseCmd()[0], b
.Bytes())
360 sniff
:= make([]int, len(names
))
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
376 isError
:= strings
.Contains(line
, ": error:")
377 isErrorNote
:= strings
.Contains(line
, ": note:") && sawUnmatchedErrors
378 if !isError
&& !isErrorNote
{
382 c1
:= strings
.Index(line
, ":")
386 c2
:= strings
.Index(line
[c1
+1:], ":")
392 filename
:= line
[:c1
]
393 i
, _
:= strconv
.Atoi(line
[c1
+1 : c2
])
395 if i
< 0 || i
>= len(names
) {
397 sawUnmatchedErrors
= true
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.
411 sniff
[i
] |
= notDeclared
414 case "not-int-const":
415 sniff
[i
] |
= notIntConst
416 case "not-num-const":
417 sniff
[i
] |
= notNumConst
419 sniff
[i
] |
= notStrLiteral
422 sawUnmatchedErrors
= true
427 sawUnmatchedErrors
= false
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
{
437 if sniff
[i
]¬Declared
!= 0 && optional
[n
] {
438 // Ignore optional undeclared identifiers.
439 // Don't report an error, and skip adding n to the needType array.
442 error_(f
.NamePos
[n
], "could not determine kind of name for C.%s", fixGo(n
.Go
))
443 case notStrLiteral | notType
:
445 case notIntConst | notStrLiteral | notType
:
447 case notIntConst | notNumConst | notType
:
449 case notIntConst | notNumConst | notStrLiteral
:
451 case notIntConst | notNumConst | notStrLiteral | notType
:
454 needType
= append(needType
, n
)
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")
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.
480 // __typeof__(names[i]) *__cgo__i;
481 // for each entry in names and then dereference the type we
482 // learn for __cgo__i.
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
)
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
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
)
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
))
540 fatalf("reading DWARF entry: %s", err
)
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.
555 fatalf("malformed DWARF TagVariable entry")
557 if !strings
.HasPrefix(name
, "__cgo__") {
560 typ
, err
:= d
.Type(typOff
)
562 fatalf("loading DWARF type: %s", err
)
564 t
, ok
:= typ
.(*dwarf
.PtrType
)
566 fatalf("internal error: %s has non-pointer type", name
)
568 i
, err
:= strconv
.Atoi(name
[7:])
570 fatalf("malformed __cgo__ name: %s", name
)
574 if e
.Tag
!= dwarf
.TagCompileUnit
{
579 // Record types and typedef information.
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
{
592 f
, fok
:= types
[i
].(*dwarf
.FuncType
)
593 if n
.Kind
!= "type" && fok
{
595 n
.FuncType
= conv
.FuncType(f
, pos
)
597 n
.Type
= conv
.Type(types
[i
], pos
)
601 if _
, ok
:= types
[i
].(*dwarf
.UintType
); ok
{
602 n
.Const
= fmt
.Sprintf("%#x", uint64(ints
[i
]))
604 n
.Const
= fmt
.Sprintf("%#x", ints
[i
])
609 n
.Const
= fmt
.Sprintf("%f", floats
[i
])
613 n
.Const
= fmt
.Sprintf("%q", strs
[i
])
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.
629 if *gccgo
&& n
.IsVar() {
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 {
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" {
646 name
:= f
.Name
[goname
]
647 if name
.Kind
!= "func" {
648 // Probably a type conversion.
651 if p
.rewriteCall(f
, call
, name
) {
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
) {
672 for i
, param
:= range name
.FuncType
.Params
{
673 if p
.needsPointerCheck(f
, param
.Go
, call
.Call
.Args
[i
]) {
682 // We need to rewrite this call.
684 // We are going to rewrite C.f(p) to
685 // func (_cgo0 ptype) {
686 // _cgoCheckPointer(_cgo0)
689 // Using a function literal like this lets us do correct
690 // argument type checking, and works correctly if the call is
693 params
:= make([]*ast
.Field
, len(name
.FuncType
.Params
))
694 nargs
:= make([]ast
.Expr
, len(name
.FuncType
.Params
))
696 for i
, param
:= range name
.FuncType
.Params
{
697 // params is going to become the parameters of the
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
))
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
{
716 params
[i
] = &ast
.Field
{
717 Names
: []*ast
.Ident
{nparam
},
721 if !p
.needsPointerCheck(f
, param
.Go
, origArg
) {
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.
730 Fun
: ast
.NewIdent("_cgoCheckPointer"),
736 // Add optional additional arguments for an address
738 c
.Args
= p
.checkAddrArgs(f
, c
.Args
, origArg
)
740 stmt
:= &ast
.ExprStmt
{
743 stmts
= append(stmts
, stmt
)
746 const cgoMarker
= "__cgo__###__marker__"
747 fcall
:= &ast
.CallExpr
{
748 Fun
: ast
.NewIdent(cgoMarker
),
751 ftype
:= &ast
.FuncType
{
752 Params
: &ast
.FieldList
{
756 if name
.FuncType
.Result
!= nil {
757 rtype
:= p
.rewriteUnsafe(name
.FuncType
.Result
.Go
)
758 if rtype
!= name
.FuncType
.Result
.Go
{
761 ftype
.Results
= &ast
.FieldList
{
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
{
781 Type
: ast
.NewIdent("_Ctype_void"),
786 ftype
.Results
.List
= append(ftype
.Results
.List
,
788 Type
: ast
.NewIdent("error"),
794 if ftype
.Results
== nil {
795 fbody
= &ast
.ExprStmt
{
799 fbody
= &ast
.ReturnStmt
{
800 Results
: []ast
.Expr
{fcall
},
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])
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" {
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.
836 func (p
*Package
) hasPointer(f
*File
, t ast
.Expr
, top
bool) bool {
837 switch t
:= t
.(type) {
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
) {
853 case *ast
.StarExpr
: // Pointer type.
857 // Check whether this is a pointer to a C union (or class)
858 // type that contains a pointer.
859 if unionWithPointer
[t
.X
] {
862 return p
.hasPointer(f
, t
.X
, false)
863 case *ast
.FuncType
, *ast
.InterfaceType
, *ast
.MapType
, *ast
.ChanType
:
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
{
872 for _
, spec
:= range gd
.Specs
{
873 ts
, ok
:= spec
.(*ast
.TypeSpec
)
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" {
888 if t
.Name
== "error" {
891 if goTypes
[t
.Name
] != nil {
894 // We can't figure out the type. Conservative
895 // approach is to assume it has a pointer.
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
905 // Conservative approach: assume pointer.
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.
916 error_(t
.Pos(), "could not understand type %s", gofmt(t
))
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
932 func (p
*Package
) checkAddrArgs(f
*File
, args
[]ast
.Expr
, x ast
.Expr
) []ast
.Expr
{
933 // Strip type conversions.
935 c
, ok
:= x
.(*ast
.CallExpr
)
936 if !ok ||
len(c
.Args
) != 1 ||
!p
.isType(c
.Fun
) {
941 u
, ok
:= x
.(*ast
.UnaryExpr
)
942 if !ok || u
.Op
!= token
.AND
{
945 index
, ok
:= u
.X
.(*ast
.IndexExpr
)
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.
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 {
967 func(f
*File
, x
interface{}, context astContext
) {
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
)
985 if id
.Name
== "unsafe" && t
.Sel
.Name
== "Pointer" {
988 if id
.Name
== "C" && typedef
["_Ctype_"+t
.Sel
.Name
] != nil {
993 // TODO: This ignores shadowing.
995 case "unsafe.Pointer", "bool", "byte",
996 "complex64", "complex128",
998 "float32", "float64",
999 "int", "int8", "int16", "int32", "int64",
1001 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr":
1006 return p
.isType(t
.X
)
1007 case *ast
.ArrayType
, *ast
.StructType
, *ast
.FuncType
, *ast
.InterfaceType
,
1008 *ast
.MapType
, *ast
.ChanType
:
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) {
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
)
1032 case *ast
.StructType
:
1036 for _
, f
:= range t
.Fields
.List
{
1037 ft
:= p
.rewriteUnsafe(f
.Type
)
1039 fields
.List
= append(fields
.List
, f
)
1043 fields
.List
= append(fields
.List
, &fn
)
1052 case *ast
.StarExpr
: // Pointer type.
1053 x1
:= p
.rewriteUnsafe(t
.X
)
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
1071 functions
:= make(map[string]bool)
1073 // Assign mangled names.
1074 for _
, n
:= range f
.Name
{
1075 if n
.Kind
== "not-type" {
1080 n
.FuncType
= &FuncType
{
1083 Results
: &ast
.FieldList
{List
: []*ast
.Field
{{Type
: n
.Type
.Go
}}},
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
1106 case ctxCall
, ctxCall2
:
1107 if r
.Name
.Kind
!= "func" {
1108 if r
.Name
.Kind
== "type" {
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
)
1114 expr
= r
.Name
.Type
.Go
1117 error_(r
.Pos(), "call of non-function C.%s", fixGo(r
.Name
.Go
))
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")
1126 // Invent new Name for the two-result function.
1127 n
:= f
.Name
["2"+r
.Name
.Go
]
1132 n
.Mangle
= "_C2func_" + n
.Go
1133 f
.Name
["2"+r
.Name
.Go
] = n
1135 expr
= ast
.NewIdent(n
.Mangle
)
1140 switch r
.Name
.Kind
{
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
]
1155 Type
: &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("void*"), Go
: ast
.NewIdent("unsafe.Pointer")},
1158 f
.Name
[fpName
] = 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
1164 expr
= &ast
.CallExpr
{
1165 Fun
: &ast
.Ident
{NamePos
: (*r
.Expr
).Pos(), Name
: "_Cgo_ptr"},
1166 Args
: []ast
.Expr
{ast
.NewIdent(name
.Mangle
)},
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
)
1174 expr
= r
.Name
.Type
.Go
1176 expr
= &ast
.StarExpr
{Star
: (*r
.Expr
).Pos(), X
: expr
}
1178 expr
= &ast
.CallExpr
{Fun
: expr
}
1181 if r
.Name
.Kind
== "var" {
1182 expr
= &ast
.StarExpr
{Star
: (*r
.Expr
).Pos(), X
: expr
}
1184 error_(r
.Pos(), "only C variables allowed in selector expression %s", fixGo(r
.Name
.Go
))
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
)
1194 expr
= r
.Name
.Type
.Go
1197 if r
.Name
.Kind
== "func" {
1198 error_(r
.Pos(), "must call C.%s", fixGo(r
.Name
.Go
))
1203 // Substitute definition for mangled type name.
1204 if id
, ok
:= expr
.(*ast
.Ident
); ok
{
1205 if t
:= typedef
[id
.Name
]; t
!= nil {
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) {
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.
1228 // Record source-level edit for cgo output.
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
{
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 {
1254 // Try $GCC if set, since that's what we used to use.
1255 if ret
:= strings
.Fields(os
.Getenv("GCC")); len(ret
) > 0 {
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 {
1265 return []string{"-m64"}
1267 return []string{"-m32"}
1269 return []string{"-marm"} // not thumb
1271 return []string{"-m31"}
1273 return []string{"-m64"}
1274 case "mips64", "mips64le":
1275 return []string{"-mabi=64"}
1276 case "mips", "mipsle":
1277 return []string{"-mabi=32"}
1280 return []string{"-maix64"}
1286 func gccTmp() string {
1287 return *objDir
+ "_cgo_.o"
1290 // gccCmd returns the gcc command line to use for compiling
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
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.
1321 c
= append(c
, p
.GccOptions
...)
1322 c
= append(c
, p
.gccMachine()...)
1323 c
= append(c
, "-") //read input from standard input
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
, "___") {
1345 if strings
.HasPrefix(s
, "__cgodebug_str__") {
1346 if n
, err
:= strconv
.Atoi(s
[len("__cgodebug_str__"):]); err
== nil {
1352 indexOfDebugStrlen
:= func(s
string) int {
1353 // Some systems use leading _ to denote non-assembly symbols.
1354 if strings
.HasPrefix(s
, "___") {
1357 if strings
.HasPrefix(s
, "__cgodebug_strlen__") {
1358 if n
, err
:= strconv
.Atoi(s
[len("__cgodebug_strlen__"):]); err
== nil {
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
{
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 {
1384 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1387 if f
.Symtab
!= nil {
1388 for i
:= range f
.Symtab
.Syms
{
1389 s
:= &f
.Symtab
.Syms
[i
]
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:]))
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
)
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
)
1455 return d
, ints
, floats
, strs
1458 if f
, err
:= elf
.Open(gccTmp()); err
== nil {
1462 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1465 symtab
, err
:= f
.Symbols()
1467 for i
:= range symtab
{
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:]))
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
)
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
)
1534 return d
, ints
, floats
, strs
1537 if f
, err
:= pe
.Open(gccTmp()); err
== nil {
1541 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1543 bo
:= binary
.LittleEndian
1544 for _
, s
:= range f
.Symbols
{
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:]))
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
)
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
)
1606 return d
, ints
, floats
, strs
1609 if f
, err
:= xcoff
.Open(gccTmp()); err
== nil {
1613 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err
)
1615 bo
:= binary
.BigEndian
1616 for _
, s
:= range f
.Symbols
{
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:]))
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
)
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
)
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
...), "-"))
1696 // gccErrors runs gcc over the C program stdin and returns
1697 // the errors that gcc prints. That is, this function expects
1699 func (p
*Package
) gccErrors(stdin
[]byte) string {
1700 // TODO(rsc): require failure
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
)
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
)
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) {
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
)
1738 os
.Stderr
.Write(stdout
)
1739 os
.Stderr
.Write(stderr
)
1742 os
.Stderr
.Write(stderr
)
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.
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
1771 goVoid ast
.Expr
// _Ctype_void, denotes C's void
1772 goVoidPtr ast
.Expr
// unsafe.Pointer or *byte
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) {
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.
1814 c
.goVoidPtr
= &ast
.StarExpr
{X
: c
.byte}
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
{
1823 if d
, ok
:= dt
.(*dwarf
.QualType
); ok
{
1827 if d
, ok
:= dt
.(*dwarf
.TypedefType
); ok
{
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
{
1840 if d
, ok
:= dt
.(*dwarf
.QualType
); ok
{
1849 // Map from dwarf text names to aliases we use in package "C".
1850 var dwarfToName
= map[string]string{
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 {
1872 if len(tr
.FormatArgs
) == 0 {
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{}) {
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
{
1915 fatalf("%s: type conversion loop at %s", lineno(pos
), dtype
)
1921 t
.Size
= dtype
.Size() // note: wrong for array of pointers, corrected below
1923 t
.C
= &TypeRepr
{Repr
: dtype
.Common().Name
}
1926 switch dt
:= dtype
.(type) {
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
)
1937 case *dwarf
.ArrayType
:
1938 if dt
.StrideBitSize
> 0 {
1939 // Cannot represent bit-sized elements in Go.
1940 t
.Go
= c
.Opaque(t
.Size
)
1945 // Indicates flexible array member, which Go doesn't support.
1946 // Translate to zero-length array instead.
1949 sub
:= c
.Type(dt
.Type
, pos
)
1951 t
.Go
= &ast
.ArrayType
{
1952 Len
: c
.intExpr(count
),
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
:
1963 case *dwarf
.CharType
:
1965 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos
), t
.Size
, dtype
)
1970 case *dwarf
.EnumType
:
1971 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
1974 t
.C
.Set("enum " + dt
.EnumName
)
1976 t
.EnumValues
= make(map[string]int64)
1977 for _
, ev
:= range dt
.Val
{
1978 t
.EnumValues
[ev
.Name
] = ev
.Val
1980 signed
= signedDelta
1983 switch t
.Size
+ int64(signed
) {
1985 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos
), t
.Size
, dtype
)
1994 case 1 + signedDelta
:
1996 case 2 + signedDelta
:
1998 case 4 + signedDelta
:
2000 case 8 + signedDelta
:
2004 case *dwarf
.FloatType
:
2007 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos
), t
.Size
, dtype
)
2013 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
2017 case *dwarf
.ComplexType
:
2020 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos
), t
.Size
, dtype
)
2026 if t
.Align
= t
.Size
/ 2; 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.
2036 case *dwarf
.IntType
:
2038 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos
), dt
.BitSize
, dtype
)
2042 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos
), t
.Size
, dtype
)
2052 t
.Go
= &ast
.ArrayType
{
2053 Len
: c
.intExpr(t
.Size
),
2057 if t
.Align
= t
.Size
; 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
)
2069 if _
, ok
:= base(dt
.Type
).(*dwarf
.VoidType
); ok
{
2074 if d
, ok
:= dq
.(*dwarf
.QualType
); ok
{
2075 t
.C
.Set(d
.Qual
+ " " + t
.C
.String())
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
)
2097 if unionWithPointer
[t1
.Go
] {
2098 unionWithPointer
[t
.Go
] = true
2102 t
.C
.Set("%s "+dt
.Qual
, t1
.C
)
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
2113 tag
= "__" + strconv
.Itoa(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.
2126 tt
.C
= &TypeRepr
{"%s %s", []interface{}{dt
.Kind
, tag
}}
2127 tt
.Go
= c
.Ident("struct{}")
2128 typedef
[name
.Name
] = &tt
2132 case "class", "union":
2133 t
.Go
= c
.Opaque(t
.Size
)
2134 if c
.dwarfHasPointer(dt
, pos
) {
2135 unionWithPointer
[t
.Go
] = true
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
2143 g
, csyntax
, align
:= c
.Struct(dt
, pos
)
2150 tt
.C
= &TypeRepr
{"struct %s", []interface{}{tag
}}
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.
2163 t
.Size
= c
.ptrSize
* 2
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
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.
2185 if unionWithPointer
[sub
.Go
] {
2186 unionWithPointer
[t
.Go
] = true
2190 oldType
:= typedef
[name
.Name
]
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
{
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
) {
2219 case *dwarf
.UcharType
:
2221 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos
), t
.Size
, dtype
)
2226 case *dwarf
.UintType
:
2228 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos
), dt
.BitSize
, dtype
)
2232 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos
), t
.Size
, dtype
)
2242 t
.Go
= &ast
.ArrayType
{
2243 Len
: c
.intExpr(t
.Size
),
2247 if t
.Align
= t
.Size
; t
.Align
>= c
.ptrSize
{
2251 case *dwarf
.VoidType
:
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
2261 if ss
, ok
:= dwarfToName
[s
]; ok
{
2264 s
= strings
.Replace(s
, " ", "", -1)
2265 name
:= c
.Ident("_Ctype_" + s
)
2267 typedef
[name
.Name
] = &tt
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.
2279 switch dt
:= dtype
.(type) {
2280 case *dwarf
.TypedefType
:
2282 case *dwarf
.StructType
:
2283 if dt
.StructName
!= "" {
2296 fatalf("%s: internal error: did not create C name for %s", lineno(pos
), dtype
)
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
)
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.
2328 Go
: &ast
.StarExpr
{X
: t
.Go
},
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
{
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
) {
2348 t
= c
.Type(ptr
, pos
)
2353 // For a struct/union/class, remember the C spelling,
2354 // in case it has __attribute__((unavailable)).
2356 if isStructUnionClass(t
.Go
) {
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
2375 if _
, ok
:= f
.(*dwarf
.DotDotDotType
); ok
&& i
== 0 {
2379 p
[i
] = c
.FuncArg(f
, pos
)
2380 gp
[i
] = &ast
.Field
{Type
: p
[i
].Go
}
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
}}
2394 Params
: &ast
.FieldList
{List
: gp
},
2395 Results
: &ast
.FieldList
{List
: gr
},
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
{
2413 // Expr for integer n.
2414 func (c
*typeConv
) intExpr(n
int64) ast
.Expr
{
2415 return &ast
.BasicLit
{
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) {
2425 fld
[n
] = &ast
.Field
{Names
: []*ast
.Ident
{c
.Ident("_")}, Type
: c
.Opaque(size
)}
2426 sizes
= sizes
[0 : n
+1]
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.
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)
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
2456 for cid
, goid
:= range ident
{
2457 if token
.Lookup(goid
).IsKeyword() {
2461 // Also avoid existing fields
2462 for _
, exist
:= used
[goid
]; exist
; _
, exist
= used
[goid
] {
2473 for _
, f
:= range dt
.Field
{
2474 if f
.ByteOffset
> off
{
2475 fld
, sizes
= c
.pad(fld
, sizes
, f
.ByteOffset
-off
)
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
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
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
)
2508 size
= f
.BitSize
/ 8
2509 name
:= tgo
.(*ast
.Ident
).String()
2510 if strings
.HasPrefix(name
, "int") {
2515 tgo
= ast
.NewIdent(name
+ fmt
.Sprint(f
.BitSize
))
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.
2530 name
= fmt
.Sprintf("anon%d", anon
)
2534 fld
[n
] = &ast
.Field
{Names
: []*ast
.Ident
{c
.Ident(ident
[name
])}, Type
: tgo
}
2535 sizes
= sizes
[0 : n
+1]
2538 buf
.WriteString(t
.C
.String())
2539 buf
.WriteString(" ")
2540 buf
.WriteString(name
)
2541 buf
.WriteString("; ")
2546 if off
< dt
.ByteSize
{
2547 fld
, sizes
= c
.pad(fld
, sizes
, dt
.ByteSize
-off
)
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 {
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()
2572 expr
= &ast
.StructType
{Fields
: &ast
.FieldList
{List
: fld
}}
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) {
2580 fatalf("%s: unexpected type: %s", lineno(pos
), dt
)
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
:
2589 case *dwarf
.ArrayType
:
2590 return c
.dwarfHasPointer(dt
.Type
, pos
)
2592 case *dwarf
.PtrType
:
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
) {
2606 case *dwarf
.TypedefType
:
2607 if dt
.Name
== "_GoString_" || dt
.Name
== "_GoBytes_" {
2610 return c
.dwarfHasPointer(dt
.Type
, pos
)
2614 func upper(s
string) string {
2618 r
, size
:= utf8
.DecodeRuneInString(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
)
2632 for _
, f
:= range fld
{
2633 for _
, n
:= range f
.Names
{
2634 if n
.Name
!= prefix
{
2635 n
.Name
= strings
.TrimPrefix(n
.Name
, prefix
)
2638 // Use exported name instead.
2639 n
.Name
= "Pad_cgo_" + strconv
.Itoa(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 {
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
, "_") {
2668 i
:= strings
.Index(n
.Name
, "_")
2673 prefix
= n
.Name
[:i
+1]
2674 } else if prefix
!= n
.Name
[:i
+1] {
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
) {
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" {
2708 if !strings
.HasSuffix(s
, "Ref") {
2715 if c
.getTypeIDs
[s
] {
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.
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.
2740 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1)
2741 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
2743 #define CF_IS_TAGGED_OBJ(PTR) 0
2744 #define CF_TAGGED_OBJ_TYPE(PTR) 0
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.
2773 t
, ok
:= w
.Type
.(*dwarf
.TypedefType
)
2774 if !ok || t
.Name
!= parent
{
2778 parent
, ok
= jniTypes
[w
.Name
]
2784 // Check that the typedef is:
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
{
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{
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",