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.
17 exec
"internal/execabs"
29 conf
= printer
.Config
{Mode
: printer
.SourcePos
, Tabwidth
: 8}
30 noSourceConf
= printer
.Config
{Tabwidth
: 8}
33 // writeDefs creates output files to be compiled by gc and gcc.
34 func (p
*Package
) writeDefs() {
35 var fgo2
, fc io
.Writer
36 f
:= creat(*objDir
+ "_cgo_gotypes.go")
40 f
:= creat(*objDir
+ "_cgo_defun.c")
44 fm
:= creat(*objDir
+ "_cgo_main.c")
46 var gccgoInit bytes
.Buffer
48 fflg
:= creat(*objDir
+ "_cgo_flags")
50 for k
, v
:= range p
.CgoFlags
{
51 flags
= append(flags
, fmt
.Sprintf("_CGO_%s=%s", k
, strings
.Join(v
, " ")))
52 if k
== "LDFLAGS" && !*gccgo
{
53 for _
, arg
:= range v
{
54 fmt
.Fprintf(fgo2
, "//go:cgo_ldflag %q\n", arg
)
59 for _
, flag
:= range flags
{
60 fmt
.Fprintln(fflg
, flag
)
64 // Write C main file for using gcc to resolve imports.
65 fmt
.Fprintf(fm
, "int main() { return 0; }\n")
66 if *importRuntimeCgo
{
67 fmt
.Fprintf(fm
, "void crosscall2(void(*fn)(void*) __attribute__((unused)), void *a __attribute__((unused)), int c __attribute__((unused)), __SIZE_TYPE__ ctxt __attribute__((unused))) { }\n")
68 fmt
.Fprintf(fm
, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void) { return 0; }\n")
69 fmt
.Fprintf(fm
, "void _cgo_release_context(__SIZE_TYPE__ ctxt __attribute__((unused))) { }\n")
70 fmt
.Fprintf(fm
, "char* _cgo_topofstack(void) { return (char*)0; }\n")
72 // If we're not importing runtime/cgo, we *are* runtime/cgo,
73 // which provides these functions. We just need a prototype.
74 fmt
.Fprintf(fm
, "void crosscall2(void(*fn)(void*), void *a, int c, __SIZE_TYPE__ ctxt);\n")
75 fmt
.Fprintf(fm
, "__SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n")
76 fmt
.Fprintf(fm
, "void _cgo_release_context(__SIZE_TYPE__);\n")
78 fmt
.Fprintf(fm
, "void _cgo_allocate(void *a __attribute__((unused)), int c __attribute__((unused))) { }\n")
79 fmt
.Fprintf(fm
, "void _cgo_panic(void *a __attribute__((unused)), int c __attribute__((unused))) { }\n")
80 fmt
.Fprintf(fm
, "void _cgo_reginit(void) { }\n")
82 // Write second Go output: definitions of _C_xxx.
83 // In a separate file so that the import of "unsafe" does not
84 // pollute the original file.
85 fmt
.Fprintf(fgo2
, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
86 fmt
.Fprintf(fgo2
, "package %s\n\n", p
.PackageName
)
87 fmt
.Fprintf(fgo2
, "import \"unsafe\"\n\n")
89 fmt
.Fprintf(fgo2
, "import \"syscall\"\n\n")
91 if *importRuntimeCgo
{
92 fmt
.Fprintf(fgo2
, "import _cgopackage \"runtime/cgo\"\n\n")
93 fmt
.Fprintf(fgo2
, "type _ _cgopackage.Incomplete\n") // prevent import-not-used error
96 fmt
.Fprintf(fgo2
, "var _ syscall.Errno\n")
98 fmt
.Fprintf(fgo2
, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
101 fmt
.Fprintf(fgo2
, "//go:linkname _Cgo_always_false runtime.cgoAlwaysFalse\n")
102 fmt
.Fprintf(fgo2
, "var _Cgo_always_false bool\n")
103 fmt
.Fprintf(fgo2
, "//go:linkname _Cgo_use runtime.cgoUse\n")
104 fmt
.Fprintf(fgo2
, "func _Cgo_use(interface{})\n")
107 typedefNames
:= make([]string, 0, len(typedef
))
108 for name
:= range typedef
{
109 if name
== "_Ctype_void" {
110 // We provide an appropriate declaration for
111 // _Ctype_void below (#39877).
114 typedefNames
= append(typedefNames
, name
)
116 sort
.Strings(typedefNames
)
117 for _
, name
:= range typedefNames
{
119 fmt
.Fprintf(fgo2
, "type %s ", name
)
120 // We don't have source info for these types, so write them out without source info.
121 // Otherwise types would look like:
123 // type _Ctype_struct_cb struct {
129 // Which is not useful. Moreover we never override source info,
130 // so subsequent source code uses the same source info.
131 // Moreover, empty file name makes compile emit no source debug info at all.
133 noSourceConf
.Fprint(&buf
, fset
, def
.Go
)
134 if bytes
.HasPrefix(buf
.Bytes(), []byte("_Ctype_")) ||
135 strings
.HasPrefix(name
, "_Ctype_enum_") ||
136 strings
.HasPrefix(name
, "_Ctype_union_") {
137 // This typedef is of the form `typedef a b` and should be an alias.
138 fmt
.Fprintf(fgo2
, "= ")
140 fmt
.Fprintf(fgo2
, "%s", buf
.Bytes())
141 fmt
.Fprintf(fgo2
, "\n\n")
144 fmt
.Fprintf(fgo2
, "type _Ctype_void byte\n")
146 fmt
.Fprintf(fgo2
, "type _Ctype_void [0]byte\n")
150 fmt
.Fprint(fgo2
, gccgoGoProlog
)
151 fmt
.Fprint(fc
, p
.cPrologGccgo())
153 fmt
.Fprint(fgo2
, goProlog
)
157 fmt
.Fprintf(fc
, "#line 1 \"cgo-generated-wrappers\"\n")
160 fmt
.Fprintf(fm
, "#line 1 \"cgo-generated-wrappers\"\n")
163 gccgoSymbolPrefix
:= p
.gccgoSymbolPrefix()
165 cVars
:= make(map[string]bool)
166 for _
, key
:= range nameKeys(p
.Name
) {
174 fmt
.Fprintf(fc
, "extern byte *%s;\n", n
.C
)
176 // Force a reference to all symbols so that
177 // the external linker will add DT_NEEDED
178 // entries as needed on ELF systems.
179 // Treat function variables differently
180 // to avoid type confict errors from LTO
181 // (Link Time Optimization).
182 if n
.Kind
== "fpvar" {
183 fmt
.Fprintf(fm
, "extern void %s();\n", n
.C
)
185 fmt
.Fprintf(fm
, "extern char %s[];\n", n
.C
)
186 fmt
.Fprintf(fm
, "void *_cgohack_%s = %s;\n\n", n
.C
, n
.C
)
188 fmt
.Fprintf(fgo2
, "//go:linkname __cgo_%s %s\n", n
.C
, n
.C
)
189 fmt
.Fprintf(fgo2
, "//go:cgo_import_static %s\n", n
.C
)
190 fmt
.Fprintf(fgo2
, "var __cgo_%s byte\n", n
.C
)
197 node
= &ast
.StarExpr
{X
: n
.Type
.Go
}
198 } else if n
.Kind
== "fpvar" {
201 panic(fmt
.Errorf("invalid var kind %q", n
.Kind
))
204 fmt
.Fprintf(fc
, `extern void *%s __asm__("%s.%s");`, n
.Mangle
, gccgoSymbolPrefix
, gccgoToSymbol(n
.Mangle
))
205 fmt
.Fprintf(&gccgoInit
, "\t%s = &%s;\n", n
.Mangle
, n
.C
)
206 fmt
.Fprintf(fc
, "\n")
209 fmt
.Fprintf(fgo2
, "var %s ", n
.Mangle
)
210 conf
.Fprint(fgo2
, fset
, node
)
212 fmt
.Fprintf(fgo2
, " = (")
213 conf
.Fprint(fgo2
, fset
, node
)
214 fmt
.Fprintf(fgo2
, ")(unsafe.Pointer(&__cgo_%s))", n
.C
)
216 fmt
.Fprintf(fgo2
, "\n")
219 fmt
.Fprintf(fc
, "\n")
222 for _
, key
:= range nameKeys(p
.Name
) {
225 fmt
.Fprintf(fgo2
, "const %s = %s\n", n
.Mangle
, n
.Const
)
228 fmt
.Fprintf(fgo2
, "\n")
231 for _
, key
:= range nameKeys(p
.Name
) {
233 if n
.FuncType
!= nil {
234 p
.writeDefsFunc(fgo2
, n
, &callsMalloc
)
238 fgcc
:= creat(*objDir
+ "_cgo_export.c")
239 fgcch
:= creat(*objDir
+ "_cgo_export.h")
241 p
.writeGccgoExports(fgo2
, fm
, fgcc
, fgcch
)
243 p
.writeExports(fgo2
, fm
, fgcc
, fgcch
)
246 if callsMalloc
&& !*gccgo
{
247 fmt
.Fprint(fgo2
, strings
.Replace(cMallocDefGo
, "PREFIX", cPrefix
, -1))
248 fmt
.Fprint(fgcc
, strings
.Replace(strings
.Replace(cMallocDefC
, "PREFIX", cPrefix
, -1), "PACKED", p
.packedAttribute(), -1))
251 if err
:= fgcc
.Close(); err
!= nil {
254 if err
:= fgcch
.Close(); err
!= nil {
258 if *exportHeader
!= "" && len(p
.ExpFunc
) > 0 {
259 fexp
:= creat(*exportHeader
)
260 fgcch
, err
:= os
.Open(*objDir
+ "_cgo_export.h")
265 _
, err
= io
.Copy(fexp
, fgcch
)
269 if err
= fexp
.Close(); err
!= nil {
274 init
:= gccgoInit
.String()
276 // The init function does nothing but simple
277 // assignments, so it won't use much stack space, so
278 // it's OK to not split the stack. Splitting the stack
279 // can run into a bug in clang (as of 2018-11-09):
280 // this is a leaf function, and when clang sees a leaf
281 // function it won't emit the split stack prologue for
282 // the function. However, if this function refers to a
283 // non-split-stack function, which will happen if the
284 // cgo code refers to a C function not compiled with
285 // -fsplit-stack, then the linker will think that it
286 // needs to adjust the split stack prologue, but there
287 // won't be one. Marking the function explicitly
288 // no_split_stack works around this problem by telling
289 // the linker that it's OK if there is no split stack
291 fmt
.Fprintln(fc
, "static void init(void) __attribute__ ((constructor, no_split_stack));")
292 fmt
.Fprintln(fc
, "static void init(void) {")
294 fmt
.Fprintln(fc
, "}")
298 // elfImportedSymbols is like elf.File.ImportedSymbols, but it
299 // includes weak symbols.
301 // A bug in some versions of LLD (at least LLD 8) cause it to emit
302 // several pthreads symbols as weak, but we need to import those. See
303 // issue #31912 or https://bugs.llvm.org/show_bug.cgi?id=42442.
305 // When doing external linking, we hand everything off to the external
306 // linker, which will create its own dynamic symbol tables. For
307 // internal linking, this may turn weak imports into strong imports,
308 // which could cause dynamic linking to fail if a symbol really isn't
309 // defined. However, the standard library depends on everything it
310 // imports, and this is the primary use of dynamic symbol tables with
312 func elfImportedSymbols(f
*elf
.File
) []elf
.ImportedSymbol
{
313 syms
, _
:= f
.DynamicSymbols()
314 var imports
[]elf
.ImportedSymbol
315 for _
, s
:= range syms
{
316 if (elf
.ST_BIND(s
.Info
) == elf
.STB_GLOBAL || elf
.ST_BIND(s
.Info
) == elf
.STB_WEAK
) && s
.Section
== elf
.SHN_UNDEF
{
317 imports
= append(imports
, elf
.ImportedSymbol
{
327 func dynimport(obj
string) {
330 f
, err
:= os
.Create(*dynout
)
337 fmt
.Fprintf(stdout
, "package %s\n", *dynpackage
)
339 if f
, err
:= elf
.Open(obj
); err
== nil {
341 // Emit the cgo_dynamic_linker line.
342 if sec
:= f
.Section(".interp"); sec
!= nil {
343 if data
, err
:= sec
.Data(); err
== nil && len(data
) > 1 {
344 // skip trailing \0 in data
345 fmt
.Fprintf(stdout
, "//go:cgo_dynamic_linker %q\n", string(data
[:len(data
)-1]))
349 sym
:= elfImportedSymbols(f
)
350 for _
, s
:= range sym
{
353 targ
+= "#" + s
.Version
355 checkImportSymName(s
.Name
)
356 checkImportSymName(targ
)
357 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic %s %s %q\n", s
.Name
, targ
, s
.Library
)
359 lib
, _
:= f
.ImportedLibraries()
360 for _
, l
:= range lib
{
361 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic _ _ %q\n", l
)
366 if f
, err
:= macho
.Open(obj
); err
== nil {
367 sym
, _
:= f
.ImportedSymbols()
368 for _
, s
:= range sym
{
369 if len(s
) > 0 && s
[0] == '_' {
372 checkImportSymName(s
)
373 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic %s %s %q\n", s
, s
, "")
375 lib
, _
:= f
.ImportedLibraries()
376 for _
, l
:= range lib
{
377 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic _ _ %q\n", l
)
382 if f
, err
:= pe
.Open(obj
); err
== nil {
383 sym
, _
:= f
.ImportedSymbols()
384 for _
, s
:= range sym
{
385 ss
:= strings
.Split(s
, ":")
386 name
:= strings
.Split(ss
[0], "@")[0]
387 checkImportSymName(name
)
388 checkImportSymName(ss
[0])
389 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic %s %s %q\n", name
, ss
[0], strings
.ToLower(ss
[1]))
394 if f
, err
:= xcoff
.Open(obj
); err
== nil {
395 sym
, err
:= f
.ImportedSymbols()
397 fatalf("cannot load imported symbols from XCOFF file %s: %v", obj
, err
)
399 for _
, s
:= range sym
{
400 if s
.Name
== "runtime_rt0_go" || s
.Name
== "_rt0_ppc64_aix_lib" {
401 // These symbols are imported by runtime/cgo but
402 // must not be added to _cgo_import.go as there are
406 checkImportSymName(s
.Name
)
407 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic %s %s %q\n", s
.Name
, s
.Name
, s
.Library
)
409 lib
, err
:= f
.ImportedLibraries()
411 fatalf("cannot load imported libraries from XCOFF file %s: %v", obj
, err
)
413 for _
, l
:= range lib
{
414 fmt
.Fprintf(stdout
, "//go:cgo_import_dynamic _ _ %q\n", l
)
419 fatalf("cannot parse %s as ELF, Mach-O, PE or XCOFF", obj
)
422 // checkImportSymName checks a symbol name we are going to emit as part
423 // of a //go:cgo_import_dynamic pragma. These names come from object
424 // files, so they may be corrupt. We are going to emit them unquoted,
425 // so while they don't need to be valid symbol names (and in some cases,
426 // involving symbol versions, they won't be) they must contain only
427 // graphic characters and must not contain Go comments.
428 func checkImportSymName(s
string) {
429 for _
, c
:= range s
{
430 if !unicode
.IsGraphic(c
) || unicode
.IsSpace(c
) {
431 fatalf("dynamic symbol %q contains unsupported character", s
)
434 if strings
.Index(s
, "//") >= 0 || strings
.Index(s
, "/*") >= 0 {
435 fatalf("dynamic symbol %q contains Go comment")
439 // Construct a gcc struct matching the gc argument frame.
440 // Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes.
441 // These assumptions are checked by the gccProlog.
442 // Also assumes that gc convention is to word-align the
443 // input and output parameters.
444 func (p
*Package
) structType(n
*Name
) (string, int64) {
446 fmt
.Fprint(&buf
, "struct {\n")
448 for i
, t
:= range n
.FuncType
.Params
{
449 if off%t
.Align
!= 0 {
450 pad
:= t
.Align
- off%t
.Align
451 fmt
.Fprintf(&buf
, "\t\tchar __pad%d[%d];\n", off
, pad
)
458 fmt
.Fprintf(&buf
, "\t\t%s p%d;\n", c
, i
)
461 if off%p
.PtrSize
!= 0 {
462 pad
:= p
.PtrSize
- off%p
.PtrSize
463 fmt
.Fprintf(&buf
, "\t\tchar __pad%d[%d];\n", off
, pad
)
466 if t
:= n
.FuncType
.Result
; t
!= nil {
467 if off%t
.Align
!= 0 {
468 pad
:= t
.Align
- off%t
.Align
469 fmt
.Fprintf(&buf
, "\t\tchar __pad%d[%d];\n", off
, pad
)
472 fmt
.Fprintf(&buf
, "\t\t%s r;\n", t
.C
)
475 if off%p
.PtrSize
!= 0 {
476 pad
:= p
.PtrSize
- off%p
.PtrSize
477 fmt
.Fprintf(&buf
, "\t\tchar __pad%d[%d];\n", off
, pad
)
481 fmt
.Fprintf(&buf
, "\t\tchar unused;\n") // avoid empty struct
483 fmt
.Fprintf(&buf
, "\t}")
484 return buf
.String(), off
487 func (p
*Package
) writeDefsFunc(fgo2 io
.Writer
, n
*Name
, callsMalloc
*bool) {
489 gtype
:= n
.FuncType
.Go
490 void
:= gtype
.Results
== nil ||
len(gtype
.Results
.List
) == 0
492 // Add "error" to return type list.
493 // Type list is known to be 0 or 1 element - it's a C function.
494 err
:= &ast
.Field
{Type
: ast
.NewIdent("error")}
495 l
:= gtype
.Results
.List
497 l
= []*ast
.Field
{err
}
499 l
= []*ast
.Field
{l
[0], err
}
501 t
:= new(ast
.FuncType
)
503 t
.Results
= &ast
.FieldList
{List
: l
}
507 // Go func declaration.
509 Name
: ast
.NewIdent(n
.Mangle
),
513 // Builtins defined in the C prolog.
514 inProlog
:= builtinDefs
[name
] != ""
515 cname
:= fmt
.Sprintf("_cgo%s%s", cPrefix
, n
.Mangle
)
516 paramnames
:= []string(nil)
517 if d
.Type
.Params
!= nil {
518 for i
, param
:= range d
.Type
.Params
.List
{
519 paramName
:= fmt
.Sprintf("p%d", i
)
520 param
.Names
= []*ast
.Ident
{ast
.NewIdent(paramName
)}
521 paramnames
= append(paramnames
, paramName
)
526 // Gccgo style hooks.
527 fmt
.Fprint(fgo2
, "\n")
528 conf
.Fprint(fgo2
, fset
, d
)
529 fmt
.Fprint(fgo2
, " {\n")
531 fmt
.Fprint(fgo2
, "\tdefer syscall.CgocallDone()\n")
532 fmt
.Fprint(fgo2
, "\tsyscall.Cgocall()\n")
535 fmt
.Fprint(fgo2
, "\tsyscall.SetErrno(0)\n")
537 fmt
.Fprint(fgo2
, "\t")
539 fmt
.Fprint(fgo2
, "r := ")
541 fmt
.Fprintf(fgo2
, "%s(%s)\n", cname
, strings
.Join(paramnames
, ", "))
544 fmt
.Fprint(fgo2
, "\te := syscall.GetErrno()\n")
545 fmt
.Fprint(fgo2
, "\tif e != 0 {\n")
546 fmt
.Fprint(fgo2
, "\t\treturn ")
548 fmt
.Fprint(fgo2
, "r, ")
550 fmt
.Fprint(fgo2
, "e\n")
551 fmt
.Fprint(fgo2
, "\t}\n")
552 fmt
.Fprint(fgo2
, "\treturn ")
554 fmt
.Fprint(fgo2
, "r, ")
556 fmt
.Fprint(fgo2
, "nil\n")
558 fmt
.Fprint(fgo2
, "\treturn r\n")
561 fmt
.Fprint(fgo2
, "}\n")
563 // declare the C function.
564 fmt
.Fprintf(fgo2
, "//extern %s\n", cname
)
565 d
.Name
= ast
.NewIdent(cname
)
567 l
:= d
.Type
.Results
.List
568 d
.Type
.Results
.List
= l
[:len(l
)-1]
570 conf
.Fprint(fgo2
, fset
, d
)
571 fmt
.Fprint(fgo2
, "\n")
577 fmt
.Fprint(fgo2
, builtinDefs
[name
])
578 if strings
.Contains(builtinDefs
[name
], "_cgo_cmalloc") {
584 // Wrapper calls into gcc, passing a pointer to the argument frame.
585 fmt
.Fprintf(fgo2
, "//go:cgo_import_static %s\n", cname
)
586 fmt
.Fprintf(fgo2
, "//go:linkname __cgofn_%s %s\n", cname
, cname
)
587 fmt
.Fprintf(fgo2
, "var __cgofn_%s byte\n", cname
)
588 fmt
.Fprintf(fgo2
, "var %s = unsafe.Pointer(&__cgofn_%s)\n", cname
, cname
)
592 d
.Type
.Results
.List
[0].Names
= []*ast
.Ident
{ast
.NewIdent("r1")}
596 d
.Type
.Results
.List
[nret
].Names
= []*ast
.Ident
{ast
.NewIdent("r2")}
599 fmt
.Fprint(fgo2
, "\n")
600 fmt
.Fprint(fgo2
, "//go:cgo_unsafe_args\n")
601 conf
.Fprint(fgo2
, fset
, d
)
602 fmt
.Fprint(fgo2
, " {\n")
604 // NOTE: Using uintptr to hide from escape analysis.
606 if len(paramnames
) > 0 {
607 arg
= "uintptr(unsafe.Pointer(&p0))"
609 arg
= "uintptr(unsafe.Pointer(&r1))"
616 fmt
.Fprintf(fgo2
, "\t%s_cgo_runtime_cgocall(%s, %s)\n", prefix
, cname
, arg
)
618 fmt
.Fprintf(fgo2
, "\tif errno != 0 { r2 = syscall.Errno(errno) }\n")
620 fmt
.Fprintf(fgo2
, "\tif _Cgo_always_false {\n")
621 if d
.Type
.Params
!= nil {
622 for i
:= range d
.Type
.Params
.List
{
623 fmt
.Fprintf(fgo2
, "\t\t_Cgo_use(p%d)\n", i
)
626 fmt
.Fprintf(fgo2
, "\t}\n")
627 fmt
.Fprintf(fgo2
, "\treturn\n")
628 fmt
.Fprintf(fgo2
, "}\n")
631 // writeOutput creates stubs for a specific source file to be compiled by gc
632 func (p
*Package
) writeOutput(f
*File
, srcfile
string) {
634 if strings
.HasSuffix(base
, ".go") {
635 base
= base
[0 : len(base
)-3]
637 base
= filepath
.Base(base
)
638 fgo1
:= creat(*objDir
+ base
+ ".cgo1.go")
639 fgcc
:= creat(*objDir
+ base
+ ".cgo2.c")
641 p
.GoFiles
= append(p
.GoFiles
, base
+".cgo1.go")
642 p
.GccFiles
= append(p
.GccFiles
, base
+".cgo2.c")
644 // Write Go output: Go input with rewrites of C.xxx to _C_xxx.
645 fmt
.Fprintf(fgo1
, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
646 fmt
.Fprintf(fgo1
, "//line %s:1:1\n", srcfile
)
647 fgo1
.Write(f
.Edit
.Bytes())
649 // While we process the vars and funcs, also write gcc output.
650 // Gcc output starts with the preamble.
651 fmt
.Fprintf(fgcc
, "%s\n", builtinProlog
)
652 fmt
.Fprintf(fgcc
, "%s\n", f
.Preamble
)
653 fmt
.Fprintf(fgcc
, "%s\n", gccProlog
)
654 fmt
.Fprintf(fgcc
, "%s\n", tsanProlog
)
655 fmt
.Fprintf(fgcc
, "%s\n", msanProlog
)
657 for _
, key
:= range nameKeys(f
.Name
) {
659 if n
.FuncType
!= nil {
660 p
.writeOutputFunc(fgcc
, n
)
668 // fixGo converts the internal Name.Go field into the name we should show
669 // to users in error messages. There's only one for now: on input we rewrite
670 // C.malloc into C._CMalloc, so change it back here.
671 func fixGo(name
string) string {
672 if name
== "_CMalloc" {
678 var isBuiltin
= map[string]bool{
679 "_Cfunc_CString": true,
680 "_Cfunc_CBytes": true,
681 "_Cfunc_GoString": true,
682 "_Cfunc_GoStringN": true,
683 "_Cfunc_GoBytes": true,
684 "_Cfunc__CMalloc": true,
687 func (p
*Package
) writeOutputFunc(fgcc
*os
.File
, n
*Name
) {
689 if isBuiltin
[name
] || p
.Written
[name
] {
690 // The builtins are already defined in the C prolog, and we don't
691 // want to duplicate function definitions we've already done.
694 p
.Written
[name
] = true
697 p
.writeGccgoOutputFunc(fgcc
, n
)
701 ctype
, _
:= p
.structType(n
)
703 // Gcc wrapper unpacks the C argument struct
704 // and calls the actual C function.
705 fmt
.Fprintf(fgcc
, "CGO_NO_SANITIZE_THREAD\n")
707 fmt
.Fprintf(fgcc
, "int\n")
709 fmt
.Fprintf(fgcc
, "void\n")
711 fmt
.Fprintf(fgcc
, "_cgo%s%s(void *v)\n", cPrefix
, n
.Mangle
)
712 fmt
.Fprintf(fgcc
, "{\n")
714 fmt
.Fprintf(fgcc
, "\tint _cgo_errno;\n")
716 // We're trying to write a gcc struct that matches gc's layout.
717 // Use packed attribute to force no padding in this struct in case
718 // gcc has different packing requirements.
719 fmt
.Fprintf(fgcc
, "\t%s %v *_cgo_a = v;\n", ctype
, p
.packedAttribute())
720 if n
.FuncType
.Result
!= nil {
721 // Save the stack top for use below.
722 fmt
.Fprintf(fgcc
, "\tchar *_cgo_stktop = _cgo_topofstack();\n")
724 tr
:= n
.FuncType
.Result
726 fmt
.Fprintf(fgcc
, "\t__typeof__(_cgo_a->r) _cgo_r;\n")
728 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_acquire();\n")
730 fmt
.Fprintf(fgcc
, "\terrno = 0;\n")
732 fmt
.Fprintf(fgcc
, "\t")
734 fmt
.Fprintf(fgcc
, "_cgo_r = ")
735 if c
:= tr
.C
.String(); c
[len(c
)-1] == '*' {
736 fmt
.Fprint(fgcc
, "(__typeof__(_cgo_a->r)) ")
739 if n
.Kind
== "macro" {
740 fmt
.Fprintf(fgcc
, "%s;\n", n
.C
)
742 fmt
.Fprintf(fgcc
, "%s(", n
.C
)
743 for i
:= range n
.FuncType
.Params
{
745 fmt
.Fprintf(fgcc
, ", ")
747 fmt
.Fprintf(fgcc
, "_cgo_a->p%d", i
)
749 fmt
.Fprintf(fgcc
, ");\n")
752 fmt
.Fprintf(fgcc
, "\t_cgo_errno = errno;\n")
754 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_release();\n")
755 if n
.FuncType
.Result
!= nil {
756 // The cgo call may have caused a stack copy (via a callback).
757 // Adjust the return value pointer appropriately.
758 fmt
.Fprintf(fgcc
, "\t_cgo_a = (void*)((char*)_cgo_a + (_cgo_topofstack() - _cgo_stktop));\n")
759 // Save the return value.
760 fmt
.Fprintf(fgcc
, "\t_cgo_a->r = _cgo_r;\n")
761 // The return value is on the Go stack. If we are using msan,
762 // and if the C value is partially or completely uninitialized,
763 // the assignment will mark the Go stack as uninitialized.
764 // The Go compiler does not update msan for changes to the
765 // stack. It is possible that the stack will remain
766 // uninitialized, and then later be used in a way that is
767 // visible to msan, possibly leading to a false positive.
768 // Mark the stack space as written, to avoid this problem.
770 fmt
.Fprintf(fgcc
, "\t_cgo_msan_write(&_cgo_a->r, sizeof(_cgo_a->r));\n")
773 fmt
.Fprintf(fgcc
, "\treturn _cgo_errno;\n")
775 fmt
.Fprintf(fgcc
, "}\n")
776 fmt
.Fprintf(fgcc
, "\n")
779 // Write out a wrapper for a function when using gccgo. This is a
780 // simple wrapper that just calls the real function. We only need a
781 // wrapper to support static functions in the prologue--without a
782 // wrapper, we can't refer to the function, since the reference is in
784 func (p
*Package
) writeGccgoOutputFunc(fgcc
*os
.File
, n
*Name
) {
785 fmt
.Fprintf(fgcc
, "CGO_NO_SANITIZE_THREAD\n")
786 if t
:= n
.FuncType
.Result
; t
!= nil {
787 fmt
.Fprintf(fgcc
, "%s\n", t
.C
.String())
789 fmt
.Fprintf(fgcc
, "void\n")
791 fmt
.Fprintf(fgcc
, "_cgo%s%s(", cPrefix
, n
.Mangle
)
792 for i
, t
:= range n
.FuncType
.Params
{
794 fmt
.Fprintf(fgcc
, ", ")
800 fmt
.Fprintf(fgcc
, "%s p%d", c
, i
)
802 fmt
.Fprintf(fgcc
, ")\n")
803 fmt
.Fprintf(fgcc
, "{\n")
804 if t
:= n
.FuncType
.Result
; t
!= nil {
805 fmt
.Fprintf(fgcc
, "\t%s _cgo_r;\n", t
.C
.String())
807 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_acquire();\n")
808 fmt
.Fprintf(fgcc
, "\t")
809 if t
:= n
.FuncType
.Result
; t
!= nil {
810 fmt
.Fprintf(fgcc
, "_cgo_r = ")
811 // Cast to void* to avoid warnings due to omitted qualifiers.
812 if c
:= t
.C
.String(); c
[len(c
)-1] == '*' {
813 fmt
.Fprintf(fgcc
, "(void*)")
816 if n
.Kind
== "macro" {
817 fmt
.Fprintf(fgcc
, "%s;\n", n
.C
)
819 fmt
.Fprintf(fgcc
, "%s(", n
.C
)
820 for i
:= range n
.FuncType
.Params
{
822 fmt
.Fprintf(fgcc
, ", ")
824 fmt
.Fprintf(fgcc
, "p%d", i
)
826 fmt
.Fprintf(fgcc
, ");\n")
828 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_release();\n")
829 if t
:= n
.FuncType
.Result
; t
!= nil {
830 fmt
.Fprintf(fgcc
, "\treturn ")
831 // Cast to void* to avoid warnings due to omitted qualifiers
832 // and explicit incompatible struct types.
833 if c
:= t
.C
.String(); c
[len(c
)-1] == '*' {
834 fmt
.Fprintf(fgcc
, "(void*)")
836 fmt
.Fprintf(fgcc
, "_cgo_r;\n")
838 fmt
.Fprintf(fgcc
, "}\n")
839 fmt
.Fprintf(fgcc
, "\n")
842 // packedAttribute returns host compiler struct attribute that will be
843 // used to match gc's struct layout. For example, on 386 Windows,
844 // gcc wants to 8-align int64s, but gc does not.
845 // Use __gcc_struct__ to work around https://gcc.gnu.org/PR52991 on x86,
846 // and https://golang.org/issue/5603.
847 func (p
*Package
) packedAttribute() string {
848 s
:= "__attribute__((__packed__"
849 if !p
.GccIsClang
&& (goarch
== "amd64" || goarch
== "386") {
850 s
+= ", __gcc_struct__"
855 // exportParamName returns the value of param as it should be
856 // displayed in a c header file. If param contains any non-ASCII
857 // characters, this function will return the character p followed by
858 // the value of position; otherwise, this function will return the
860 func exportParamName(param
string, position
int) string {
862 return fmt
.Sprintf("p%d", position
)
867 for i
:= 0; i
< len(param
); i
++ {
868 if param
[i
] > unicode
.MaxASCII
{
869 pname
= fmt
.Sprintf("p%d", position
)
877 // Write out the various stubs we need to support functions exported
878 // from Go so that they are callable from C.
879 func (p
*Package
) writeExports(fgo2
, fm
, fgcc
, fgcch io
.Writer
) {
880 p
.writeExportHeader(fgcch
)
882 fmt
.Fprintf(fgcc
, "/* Code generated by cmd/cgo; DO NOT EDIT. */\n\n")
883 fmt
.Fprintf(fgcc
, "#include <stdlib.h>\n")
884 fmt
.Fprintf(fgcc
, "#include \"_cgo_export.h\"\n\n")
886 // We use packed structs, but they are always aligned.
887 // The pragmas and address-of-packed-member are only recognized as
888 // warning groups in clang 4.0+, so ignore unknown pragmas first.
889 fmt
.Fprintf(fgcc
, "#pragma GCC diagnostic ignored \"-Wunknown-pragmas\"\n")
890 fmt
.Fprintf(fgcc
, "#pragma GCC diagnostic ignored \"-Wpragmas\"\n")
891 fmt
.Fprintf(fgcc
, "#pragma GCC diagnostic ignored \"-Waddress-of-packed-member\"\n")
893 fmt
.Fprintf(fgcc
, "extern void crosscall2(void (*fn)(void *), void *, int, __SIZE_TYPE__);\n")
894 fmt
.Fprintf(fgcc
, "extern __SIZE_TYPE__ _cgo_wait_runtime_init_done(void);\n")
895 fmt
.Fprintf(fgcc
, "extern void _cgo_release_context(__SIZE_TYPE__);\n\n")
896 fmt
.Fprintf(fgcc
, "extern char* _cgo_topofstack(void);")
897 fmt
.Fprintf(fgcc
, "%s\n", tsanProlog
)
898 fmt
.Fprintf(fgcc
, "%s\n", msanProlog
)
900 for _
, exp
:= range p
.ExpFunc
{
903 // Construct a struct that will be used to communicate
904 // arguments from C to Go. The C and Go definitions
905 // just have to agree. The gcc struct will be compiled
906 // with __attribute__((packed)) so all padding must be
907 // accounted for explicitly.
908 ctype
:= "struct {\n"
909 gotype
:= new(bytes
.Buffer
)
910 fmt
.Fprintf(gotype
, "struct {\n")
913 argField
:= func(typ ast
.Expr
, namePat
string, args
...interface{}) {
914 name
:= fmt
.Sprintf(namePat
, args
...)
916 if off%t
.Align
!= 0 {
917 pad
:= t
.Align
- off%t
.Align
918 ctype
+= fmt
.Sprintf("\t\tchar __pad%d[%d];\n", npad
, pad
)
922 ctype
+= fmt
.Sprintf("\t\t%s %s;\n", t
.C
, name
)
923 fmt
.Fprintf(gotype
, "\t\t%s ", name
)
924 noSourceConf
.Fprint(gotype
, fset
, typ
)
925 fmt
.Fprintf(gotype
, "\n")
929 argField(fn
.Recv
.List
[0].Type
, "recv")
932 forFieldList(fntype
.Params
,
933 func(i
int, aname
string, atype ast
.Expr
) {
934 argField(atype
, "p%d", i
)
936 forFieldList(fntype
.Results
,
937 func(i
int, aname
string, atype ast
.Expr
) {
938 argField(atype
, "r%d", i
)
940 if ctype
== "struct {\n" {
941 ctype
+= "\t\tchar unused;\n" // avoid empty struct
944 fmt
.Fprintf(gotype
, "\t}")
946 // Get the return type of the wrapper function
949 if fntype
.Results
== nil ||
len(fntype
.Results
.List
) == 0 {
951 } else if len(fntype
.Results
.List
) == 1 && len(fntype
.Results
.List
[0].Names
) <= 1 {
952 gccResult
= p
.cgoType(fntype
.Results
.List
[0].Type
).C
.String()
954 fmt
.Fprintf(fgcch
, "\n/* Return type for %s */\n", exp
.ExpName
)
955 fmt
.Fprintf(fgcch
, "struct %s_return {\n", exp
.ExpName
)
956 forFieldList(fntype
.Results
,
957 func(i
int, aname
string, atype ast
.Expr
) {
958 fmt
.Fprintf(fgcch
, "\t%s r%d;", p
.cgoType(atype
).C
, i
)
960 fmt
.Fprintf(fgcch
, " /* %s */", aname
)
962 fmt
.Fprint(fgcch
, "\n")
964 fmt
.Fprintf(fgcch
, "};\n")
965 gccResult
= "struct " + exp
.ExpName
+ "_return"
968 // Build the wrapper function compiled by gcc.
970 if goos
== "windows" {
971 gccExport
= "__declspec(dllexport) "
973 s
:= fmt
.Sprintf("%s%s %s(", gccExport
, gccResult
, exp
.ExpName
)
975 s
+= p
.cgoType(fn
.Recv
.List
[0].Type
).C
.String()
978 forFieldList(fntype
.Params
,
979 func(i
int, aname
string, atype ast
.Expr
) {
980 if i
> 0 || fn
.Recv
!= nil {
983 s
+= fmt
.Sprintf("%s %s", p
.cgoType(atype
).C
, exportParamName(aname
, i
))
987 if len(exp
.Doc
) > 0 {
988 fmt
.Fprintf(fgcch
, "\n%s", exp
.Doc
)
989 if !strings
.HasSuffix(exp
.Doc
, "\n") {
990 fmt
.Fprint(fgcch
, "\n")
993 fmt
.Fprintf(fgcch
, "extern %s;\n", s
)
995 fmt
.Fprintf(fgcc
, "extern void _cgoexp%s_%s(void *);\n", cPrefix
, exp
.ExpName
)
996 fmt
.Fprintf(fgcc
, "\nCGO_NO_SANITIZE_THREAD")
997 fmt
.Fprintf(fgcc
, "\n%s\n", s
)
998 fmt
.Fprintf(fgcc
, "{\n")
999 fmt
.Fprintf(fgcc
, "\t__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();\n")
1000 // The results part of the argument structure must be
1001 // initialized to 0 so the write barriers generated by
1002 // the assignments to these fields in Go are safe.
1004 // We use a local static variable to get the zeroed
1005 // value of the argument type. This avoids including
1006 // string.h for memset, and is also robust to C++
1007 // types with constructors. Both GCC and LLVM optimize
1008 // this into just zeroing _cgo_a.
1009 fmt
.Fprintf(fgcc
, "\ttypedef %s %v _cgo_argtype;\n", ctype
, p
.packedAttribute())
1010 fmt
.Fprintf(fgcc
, "\tstatic _cgo_argtype _cgo_zero;\n")
1011 fmt
.Fprintf(fgcc
, "\t_cgo_argtype _cgo_a = _cgo_zero;\n")
1012 if gccResult
!= "void" && (len(fntype
.Results
.List
) > 1 ||
len(fntype
.Results
.List
[0].Names
) > 1) {
1013 fmt
.Fprintf(fgcc
, "\t%s r;\n", gccResult
)
1016 fmt
.Fprintf(fgcc
, "\t_cgo_a.recv = recv;\n")
1018 forFieldList(fntype
.Params
,
1019 func(i
int, aname
string, atype ast
.Expr
) {
1020 fmt
.Fprintf(fgcc
, "\t_cgo_a.p%d = %s;\n", i
, exportParamName(aname
, i
))
1022 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_release();\n")
1023 fmt
.Fprintf(fgcc
, "\tcrosscall2(_cgoexp%s_%s, &_cgo_a, %d, _cgo_ctxt);\n", cPrefix
, exp
.ExpName
, off
)
1024 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_acquire();\n")
1025 fmt
.Fprintf(fgcc
, "\t_cgo_release_context(_cgo_ctxt);\n")
1026 if gccResult
!= "void" {
1027 if len(fntype
.Results
.List
) == 1 && len(fntype
.Results
.List
[0].Names
) <= 1 {
1028 fmt
.Fprintf(fgcc
, "\treturn _cgo_a.r0;\n")
1030 forFieldList(fntype
.Results
,
1031 func(i
int, aname
string, atype ast
.Expr
) {
1032 fmt
.Fprintf(fgcc
, "\tr.r%d = _cgo_a.r%d;\n", i
, i
)
1034 fmt
.Fprintf(fgcc
, "\treturn r;\n")
1037 fmt
.Fprintf(fgcc
, "}\n")
1039 // In internal linking mode, the Go linker sees both
1040 // the C wrapper written above and the Go wrapper it
1041 // references. Hence, export the C wrapper (e.g., for
1042 // if we're building a shared object). The Go linker
1043 // will resolve the C wrapper's reference to the Go
1044 // wrapper without a separate export.
1045 fmt
.Fprintf(fgo2
, "//go:cgo_export_dynamic %s\n", exp
.ExpName
)
1046 // cgo_export_static refers to a symbol by its linker
1047 // name, so set the linker name of the Go wrapper.
1048 fmt
.Fprintf(fgo2
, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix
, exp
.ExpName
, cPrefix
, exp
.ExpName
)
1049 // In external linking mode, the Go linker sees the Go
1050 // wrapper, but not the C wrapper. For this case,
1051 // export the Go wrapper so the host linker can
1052 // resolve the reference from the C wrapper to the Go
1054 fmt
.Fprintf(fgo2
, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix
, exp
.ExpName
)
1056 // Build the wrapper function compiled by cmd/compile.
1057 // This unpacks the argument struct above and calls the Go function.
1058 fmt
.Fprintf(fgo2
, "func _cgoexp%s_%s(a *%s) {\n", cPrefix
, exp
.ExpName
, gotype
)
1060 fmt
.Fprintf(fm
, "void _cgoexp%s_%s(void* p){}\n", cPrefix
, exp
.ExpName
)
1062 fmt
.Fprintf(fgo2
, "\t")
1064 if gccResult
!= "void" {
1065 // Write results back to frame.
1066 forFieldList(fntype
.Results
,
1067 func(i
int, aname
string, atype ast
.Expr
) {
1069 fmt
.Fprintf(fgo2
, ", ")
1071 fmt
.Fprintf(fgo2
, "a.r%d", i
)
1073 fmt
.Fprintf(fgo2
, " = ")
1076 fmt
.Fprintf(fgo2
, "a.recv.")
1078 fmt
.Fprintf(fgo2
, "%s(", exp
.Func
.Name
)
1079 forFieldList(fntype
.Params
,
1080 func(i
int, aname
string, atype ast
.Expr
) {
1082 fmt
.Fprint(fgo2
, ", ")
1084 fmt
.Fprintf(fgo2
, "a.p%d", i
)
1086 fmt
.Fprint(fgo2
, ")\n")
1087 if gccResult
!= "void" {
1088 // Verify that any results don't contain any
1090 forFieldList(fntype
.Results
,
1091 func(i
int, aname
string, atype ast
.Expr
) {
1092 if !p
.hasPointer(nil, atype
, false) {
1095 fmt
.Fprintf(fgo2
, "\t_cgoCheckResult(a.r%d)\n", i
)
1098 fmt
.Fprint(fgo2
, "}\n")
1101 fmt
.Fprintf(fgcch
, "%s", gccExportHeaderEpilog
)
1104 // Write out the C header allowing C code to call exported gccgo functions.
1105 func (p
*Package
) writeGccgoExports(fgo2
, fm
, fgcc
, fgcch io
.Writer
) {
1106 gccgoSymbolPrefix
:= p
.gccgoSymbolPrefix()
1108 p
.writeExportHeader(fgcch
)
1110 fmt
.Fprintf(fgcc
, "/* Code generated by cmd/cgo; DO NOT EDIT. */\n\n")
1111 fmt
.Fprintf(fgcc
, "#include \"_cgo_export.h\"\n")
1113 fmt
.Fprintf(fgcc
, "%s\n", gccgoExportFileProlog
)
1114 fmt
.Fprintf(fgcc
, "%s\n", tsanProlog
)
1115 fmt
.Fprintf(fgcc
, "%s\n", msanProlog
)
1117 for _
, exp
:= range p
.ExpFunc
{
1121 cdeclBuf
:= new(bytes
.Buffer
)
1123 forFieldList(fntype
.Results
,
1124 func(i
int, aname
string, atype ast
.Expr
) { resultCount
++ })
1125 switch resultCount
{
1127 fmt
.Fprintf(cdeclBuf
, "void")
1129 forFieldList(fntype
.Results
,
1130 func(i
int, aname
string, atype ast
.Expr
) {
1131 t
:= p
.cgoType(atype
)
1132 fmt
.Fprintf(cdeclBuf
, "%s", t
.C
)
1135 // Declare a result struct.
1136 fmt
.Fprintf(fgcch
, "\n/* Return type for %s */\n", exp
.ExpName
)
1137 fmt
.Fprintf(fgcch
, "struct %s_return {\n", exp
.ExpName
)
1138 forFieldList(fntype
.Results
,
1139 func(i
int, aname
string, atype ast
.Expr
) {
1140 t
:= p
.cgoType(atype
)
1141 fmt
.Fprintf(fgcch
, "\t%s r%d;", t
.C
, i
)
1143 fmt
.Fprintf(fgcch
, " /* %s */", aname
)
1145 fmt
.Fprint(fgcch
, "\n")
1147 fmt
.Fprintf(fgcch
, "};\n")
1148 fmt
.Fprintf(cdeclBuf
, "struct %s_return", exp
.ExpName
)
1151 cRet
:= cdeclBuf
.String()
1153 cdeclBuf
= new(bytes
.Buffer
)
1154 fmt
.Fprintf(cdeclBuf
, "(")
1156 fmt
.Fprintf(cdeclBuf
, "%s recv", p
.cgoType(fn
.Recv
.List
[0].Type
).C
.String())
1158 // Function parameters.
1159 forFieldList(fntype
.Params
,
1160 func(i
int, aname
string, atype ast
.Expr
) {
1161 if i
> 0 || fn
.Recv
!= nil {
1162 fmt
.Fprintf(cdeclBuf
, ", ")
1164 t
:= p
.cgoType(atype
)
1165 fmt
.Fprintf(cdeclBuf
, "%s p%d", t
.C
, i
)
1167 fmt
.Fprintf(cdeclBuf
, ")")
1168 cParams
:= cdeclBuf
.String()
1170 if len(exp
.Doc
) > 0 {
1171 fmt
.Fprintf(fgcch
, "\n%s", exp
.Doc
)
1174 fmt
.Fprintf(fgcch
, "extern %s %s%s;\n", cRet
, exp
.ExpName
, cParams
)
1176 // We need to use a name that will be exported by the
1177 // Go code; otherwise gccgo will make it static and we
1178 // will not be able to link against it from the C
1180 goName
:= "Cgoexp_" + exp
.ExpName
1181 fmt
.Fprintf(fgcc
, `extern %s %s %s __asm__("%s.%s");`, cRet
, goName
, cParams
, gccgoSymbolPrefix
, gccgoToSymbol(goName
))
1182 fmt
.Fprint(fgcc
, "\n")
1184 fmt
.Fprint(fgcc
, "\nCGO_NO_SANITIZE_THREAD\n")
1185 fmt
.Fprintf(fgcc
, "%s %s %s {\n", cRet
, exp
.ExpName
, cParams
)
1186 if resultCount
> 0 {
1187 fmt
.Fprintf(fgcc
, "\t%s r;\n", cRet
)
1189 fmt
.Fprintf(fgcc
, "\tif(_cgo_wait_runtime_init_done)\n")
1190 fmt
.Fprintf(fgcc
, "\t\t_cgo_wait_runtime_init_done();\n")
1191 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_release();\n")
1192 fmt
.Fprint(fgcc
, "\t")
1193 if resultCount
> 0 {
1194 fmt
.Fprint(fgcc
, "r = ")
1196 fmt
.Fprintf(fgcc
, "%s(", goName
)
1198 fmt
.Fprint(fgcc
, "recv")
1200 forFieldList(fntype
.Params
,
1201 func(i
int, aname
string, atype ast
.Expr
) {
1202 if i
> 0 || fn
.Recv
!= nil {
1203 fmt
.Fprintf(fgcc
, ", ")
1205 fmt
.Fprintf(fgcc
, "p%d", i
)
1207 fmt
.Fprint(fgcc
, ");\n")
1208 fmt
.Fprintf(fgcc
, "\t_cgo_tsan_acquire();\n")
1209 if resultCount
> 0 {
1210 fmt
.Fprint(fgcc
, "\treturn r;\n")
1212 fmt
.Fprint(fgcc
, "}\n")
1214 // Dummy declaration for _cgo_main.c
1215 fmt
.Fprintf(fm
, `char %s[1] __asm__("%s.%s");`, goName
, gccgoSymbolPrefix
, gccgoToSymbol(goName
))
1216 fmt
.Fprint(fm
, "\n")
1218 // For gccgo we use a wrapper function in Go, in order
1219 // to call CgocallBack and CgocallBackDone.
1221 // This code uses printer.Fprint, not conf.Fprint,
1222 // because we don't want //line comments in the middle
1223 // of the function types.
1224 fmt
.Fprint(fgo2
, "\n")
1225 fmt
.Fprintf(fgo2
, "func %s(", goName
)
1227 fmt
.Fprint(fgo2
, "recv ")
1228 printer
.Fprint(fgo2
, fset
, fn
.Recv
.List
[0].Type
)
1230 forFieldList(fntype
.Params
,
1231 func(i
int, aname
string, atype ast
.Expr
) {
1232 if i
> 0 || fn
.Recv
!= nil {
1233 fmt
.Fprintf(fgo2
, ", ")
1235 fmt
.Fprintf(fgo2
, "p%d ", i
)
1236 printer
.Fprint(fgo2
, fset
, atype
)
1238 fmt
.Fprintf(fgo2
, ")")
1239 if resultCount
> 0 {
1240 fmt
.Fprintf(fgo2
, " (")
1241 forFieldList(fntype
.Results
,
1242 func(i
int, aname
string, atype ast
.Expr
) {
1244 fmt
.Fprint(fgo2
, ", ")
1246 printer
.Fprint(fgo2
, fset
, atype
)
1248 fmt
.Fprint(fgo2
, ")")
1250 fmt
.Fprint(fgo2
, " {\n")
1251 fmt
.Fprint(fgo2
, "\tsyscall.CgocallBack()\n")
1252 fmt
.Fprint(fgo2
, "\tdefer syscall.CgocallBackDone()\n")
1253 fmt
.Fprint(fgo2
, "\t")
1254 if resultCount
> 0 {
1255 fmt
.Fprint(fgo2
, "return ")
1258 fmt
.Fprint(fgo2
, "recv.")
1260 fmt
.Fprintf(fgo2
, "%s(", exp
.Func
.Name
)
1261 forFieldList(fntype
.Params
,
1262 func(i
int, aname
string, atype ast
.Expr
) {
1264 fmt
.Fprint(fgo2
, ", ")
1266 fmt
.Fprintf(fgo2
, "p%d", i
)
1268 fmt
.Fprint(fgo2
, ")\n")
1269 fmt
.Fprint(fgo2
, "}\n")
1272 fmt
.Fprintf(fgcch
, "%s", gccExportHeaderEpilog
)
1275 // writeExportHeader writes out the start of the _cgo_export.h file.
1276 func (p
*Package
) writeExportHeader(fgcch io
.Writer
) {
1277 fmt
.Fprintf(fgcch
, "/* Code generated by cmd/cgo; DO NOT EDIT. */\n\n")
1282 fmt
.Fprintf(fgcch
, "/* package %s */\n\n", pkg
)
1283 fmt
.Fprintf(fgcch
, "%s\n", builtinExportProlog
)
1285 // Remove absolute paths from #line comments in the preamble.
1286 // They aren't useful for people using the header file,
1287 // and they mean that the header files change based on the
1288 // exact location of GOPATH.
1289 re
:= regexp
.MustCompile(`(?m)^(#line\s+[0-9]+\s+")[^"]*[/\\]([^"]*")`)
1290 preamble
:= re
.ReplaceAllString(p
.Preamble
, "$1$2")
1292 fmt
.Fprintf(fgcch
, "/* Start of preamble from import \"C\" comments. */\n\n")
1293 fmt
.Fprintf(fgcch
, "%s\n", preamble
)
1294 fmt
.Fprintf(fgcch
, "\n/* End of preamble from import \"C\" comments. */\n\n")
1296 fmt
.Fprintf(fgcch
, "%s\n", p
.gccExportHeaderProlog())
1299 // gccgoToSymbol converts a name to a mangled symbol for gccgo.
1300 func gccgoToSymbol(ppath
string) string {
1301 if gccgoMangler
== nil {
1303 cmd
:= os
.Getenv("GCCGO")
1305 cmd
, err
= exec
.LookPath("gccgo")
1307 fatalf("unable to locate gccgo: %v", err
)
1310 gccgoMangler
, err
= pkgpath
.ToSymbolFunc(cmd
, *objDir
)
1315 return gccgoMangler(ppath
)
1318 // Return the package prefix when using gccgo.
1319 func (p
*Package
) gccgoSymbolPrefix() string {
1324 if *gccgopkgpath
!= "" {
1325 return gccgoToSymbol(*gccgopkgpath
)
1327 if *gccgoprefix
== "" && p
.PackageName
== "main" {
1330 prefix
:= gccgoToSymbol(*gccgoprefix
)
1334 return prefix
+ "." + p
.PackageName
1337 // Call a function for each entry in an ast.FieldList, passing the
1338 // index into the list, the name if any, and the type.
1339 func forFieldList(fl
*ast
.FieldList
, fn
func(int, string, ast
.Expr
)) {
1344 for _
, r
:= range fl
.List
{
1349 for _
, n
:= range r
.Names
{
1350 fn(i
, n
.Name
, r
.Type
)
1357 func c(repr
string, args
...interface{}) *TypeRepr
{
1358 return &TypeRepr
{repr
, args
}
1361 // Map predeclared Go types to Type.
1362 var goTypes
= map[string]*Type
{
1363 "bool": {Size
: 1, Align
: 1, C
: c("GoUint8")},
1364 "byte": {Size
: 1, Align
: 1, C
: c("GoUint8")},
1365 "int": {Size
: 0, Align
: 0, C
: c("GoInt")},
1366 "uint": {Size
: 0, Align
: 0, C
: c("GoUint")},
1367 "rune": {Size
: 4, Align
: 4, C
: c("GoInt32")},
1368 "int8": {Size
: 1, Align
: 1, C
: c("GoInt8")},
1369 "uint8": {Size
: 1, Align
: 1, C
: c("GoUint8")},
1370 "int16": {Size
: 2, Align
: 2, C
: c("GoInt16")},
1371 "uint16": {Size
: 2, Align
: 2, C
: c("GoUint16")},
1372 "int32": {Size
: 4, Align
: 4, C
: c("GoInt32")},
1373 "uint32": {Size
: 4, Align
: 4, C
: c("GoUint32")},
1374 "int64": {Size
: 8, Align
: 8, C
: c("GoInt64")},
1375 "uint64": {Size
: 8, Align
: 8, C
: c("GoUint64")},
1376 "float32": {Size
: 4, Align
: 4, C
: c("GoFloat32")},
1377 "float64": {Size
: 8, Align
: 8, C
: c("GoFloat64")},
1378 "complex64": {Size
: 8, Align
: 4, C
: c("GoComplex64")},
1379 "complex128": {Size
: 16, Align
: 8, C
: c("GoComplex128")},
1382 // Map an ast type to a Type.
1383 func (p
*Package
) cgoType(e ast
.Expr
) *Type
{
1384 switch t
:= e
.(type) {
1387 return &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("%s*", x
.C
)}
1388 case *ast
.ArrayType
:
1390 // Slice: pointer, len, cap.
1391 return &Type
{Size
: p
.PtrSize
* 3, Align
: p
.PtrSize
, C
: c("GoSlice")}
1393 // Non-slice array types are not supported.
1394 case *ast
.StructType
:
1397 return &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("void*")}
1398 case *ast
.InterfaceType
:
1399 return &Type
{Size
: 2 * p
.PtrSize
, Align
: p
.PtrSize
, C
: c("GoInterface")}
1401 return &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("GoMap")}
1403 return &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("GoChan")}
1405 // Look up the type in the top level declarations.
1406 // TODO: Handle types defined within a function.
1407 for _
, d
:= range p
.Decl
{
1408 gd
, ok
:= d
.(*ast
.GenDecl
)
1409 if !ok || gd
.Tok
!= token
.TYPE
{
1412 for _
, spec
:= range gd
.Specs
{
1413 ts
, ok
:= spec
.(*ast
.TypeSpec
)
1417 if ts
.Name
.Name
== t
.Name
{
1418 return p
.cgoType(ts
.Type
)
1422 if def
:= typedef
[t
.Name
]; def
!= nil {
1425 if t
.Name
== "uintptr" {
1426 return &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("GoUintptr")}
1428 if t
.Name
== "string" {
1429 // The string data is 1 pointer + 1 (pointer-sized) int.
1430 return &Type
{Size
: 2 * p
.PtrSize
, Align
: p
.PtrSize
, C
: c("GoString")}
1432 if t
.Name
== "error" {
1433 return &Type
{Size
: 2 * p
.PtrSize
, Align
: p
.PtrSize
, C
: c("GoInterface")}
1435 if r
, ok
:= goTypes
[t
.Name
]; ok
{
1436 if r
.Size
== 0 { // int or uint
1440 rr
.Align
= p
.IntSize
1443 if r
.Align
> p
.PtrSize
{
1448 error_(e
.Pos(), "unrecognized Go type %s", t
.Name
)
1449 return &Type
{Size
: 4, Align
: 4, C
: c("int")}
1450 case *ast
.SelectorExpr
:
1451 id
, ok
:= t
.X
.(*ast
.Ident
)
1452 if ok
&& id
.Name
== "unsafe" && t
.Sel
.Name
== "Pointer" {
1453 return &Type
{Size
: p
.PtrSize
, Align
: p
.PtrSize
, C
: c("void*")}
1456 error_(e
.Pos(), "Go type not supported in export: %s", gofmt(e
))
1457 return &Type
{Size
: 4, Align
: 4, C
: c("int")}
1461 #line 1 "cgo-gcc-prolog"
1463 If x and y are not equal, the type will be invalid
1464 (have a negative array count) and an inscrutable error will come
1465 out of the compiler and hopefully mention "name".
1467 #define __cgo_compile_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2UL+1UL];
1469 /* Check at compile time that the sizes we use match our expectations. */
1470 #define __cgo_size_assert(t, n) __cgo_compile_assert_eq(sizeof(t), (size_t)n, _cgo_sizeof_##t##_is_not_##n)
1472 __cgo_size_assert(char, 1)
1473 __cgo_size_assert(short, 2)
1474 __cgo_size_assert(int, 4)
1475 typedef long long __cgo_long_long;
1476 __cgo_size_assert(__cgo_long_long, 8)
1477 __cgo_size_assert(float, 4)
1478 __cgo_size_assert(double, 8)
1480 extern char* _cgo_topofstack(void);
1483 We use packed structs, but they are always aligned.
1484 The pragmas and address-of-packed-member are only recognized as warning
1485 groups in clang 4.0+, so ignore unknown pragmas first.
1487 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
1488 #pragma GCC diagnostic ignored "-Wpragmas"
1489 #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
1495 // Prologue defining TSAN functions in C.
1496 const noTsanProlog
= `
1497 #define CGO_NO_SANITIZE_THREAD
1498 #define _cgo_tsan_acquire()
1499 #define _cgo_tsan_release()
1502 // This must match the TSAN code in runtime/cgo/libcgo.h.
1503 // This is used when the code is built with the C/C++ Thread SANitizer,
1504 // which is not the same as the Go race detector.
1505 // __tsan_acquire tells TSAN that we are acquiring a lock on a variable,
1506 // in this case _cgo_sync. __tsan_release releases the lock.
1507 // (There is no actual lock, we are just telling TSAN that there is.)
1509 // When we call from Go to C we call _cgo_tsan_acquire.
1510 // When the C function returns we call _cgo_tsan_release.
1511 // Similarly, when C calls back into Go we call _cgo_tsan_release
1512 // and then call _cgo_tsan_acquire when we return to C.
1513 // These calls tell TSAN that there is a serialization point at the C call.
1515 // This is necessary because TSAN, which is a C/C++ tool, can not see
1516 // the synchronization in the Go code. Without these calls, when
1517 // multiple goroutines call into C code, TSAN does not understand
1518 // that the calls are properly synchronized on the Go side.
1520 // To be clear, if the calls are not properly synchronized on the Go side,
1521 // we will be hiding races. But when using TSAN on mixed Go C/C++ code
1522 // it is more important to avoid false positives, which reduce confidence
1523 // in the tool, than to avoid false negatives.
1524 const yesTsanProlog
= `
1525 #line 1 "cgo-tsan-prolog"
1526 #define CGO_NO_SANITIZE_THREAD __attribute__ ((no_sanitize_thread))
1528 long long _cgo_sync __attribute__ ((common));
1530 extern void __tsan_acquire(void*);
1531 extern void __tsan_release(void*);
1533 __attribute__ ((unused))
1534 static void _cgo_tsan_acquire() {
1535 __tsan_acquire(&_cgo_sync);
1538 __attribute__ ((unused))
1539 static void _cgo_tsan_release() {
1540 __tsan_release(&_cgo_sync);
1544 // Set to yesTsanProlog if we see -fsanitize=thread in the flags for gcc.
1545 var tsanProlog
= noTsanProlog
1547 // noMsanProlog is a prologue defining an MSAN function in C.
1548 // This is used when not compiling with -fsanitize=memory.
1549 const noMsanProlog
= `
1550 #define _cgo_msan_write(addr, sz)
1553 // yesMsanProlog is a prologue defining an MSAN function in C.
1554 // This is used when compiling with -fsanitize=memory.
1555 // See the comment above where _cgo_msan_write is called.
1556 const yesMsanProlog
= `
1557 extern void __msan_unpoison(const volatile void *, size_t);
1559 #define _cgo_msan_write(addr, sz) __msan_unpoison((addr), (sz))
1562 // msanProlog is set to yesMsanProlog if we see -fsanitize=memory in the flags
1563 // for the C compiler.
1564 var msanProlog
= noMsanProlog
1566 const builtinProlog
= `
1567 #line 1 "cgo-builtin-prolog"
1568 #include <stddef.h> /* for ptrdiff_t and size_t below */
1570 /* Define intgo when compiling with GCC. */
1571 typedef ptrdiff_t intgo;
1573 #define GO_CGO_GOSTRING_TYPEDEF
1574 typedef struct { const char *p; intgo n; } _GoString_;
1575 typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
1576 _GoString_ GoString(char *p);
1577 _GoString_ GoStringN(char *p, int l);
1578 _GoBytes_ GoBytes(void *p, int n);
1579 char *CString(_GoString_);
1580 void *CBytes(_GoBytes_);
1581 void *_CMalloc(size_t);
1583 __attribute__ ((unused))
1584 static size_t _GoStringLen(_GoString_ s) { return (size_t)s.n; }
1586 __attribute__ ((unused))
1587 static const char *_GoStringPtr(_GoString_ s) { return s.p; }
1591 //go:linkname _cgo_runtime_cgocall runtime.cgocall
1592 func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
1594 //go:linkname _cgoCheckPointer runtime.cgoCheckPointer
1595 func _cgoCheckPointer(interface{}, interface{})
1597 //go:linkname _cgoCheckResult runtime.cgoCheckResult
1598 func _cgoCheckResult(interface{})
1601 const gccgoGoProlog
= `
1602 func _cgoCheckPointer(interface{}, interface{})
1604 func _cgoCheckResult(interface{})
1607 const goStringDef
= `
1608 //go:linkname _cgo_runtime_gostring runtime.gostring
1609 func _cgo_runtime_gostring(*_Ctype_char) string
1611 func _Cfunc_GoString(p *_Ctype_char) string {
1612 return _cgo_runtime_gostring(p)
1616 const goStringNDef
= `
1617 //go:linkname _cgo_runtime_gostringn runtime.gostringn
1618 func _cgo_runtime_gostringn(*_Ctype_char, int) string
1620 func _Cfunc_GoStringN(p *_Ctype_char, l _Ctype_int) string {
1621 return _cgo_runtime_gostringn(p, int(l))
1625 const goBytesDef
= `
1626 //go:linkname _cgo_runtime_gobytes runtime.gobytes
1627 func _cgo_runtime_gobytes(unsafe.Pointer, int) []byte
1629 func _Cfunc_GoBytes(p unsafe.Pointer, l _Ctype_int) []byte {
1630 return _cgo_runtime_gobytes(p, int(l))
1634 const cStringDef
= `
1635 func _Cfunc_CString(s string) *_Ctype_char {
1636 p := _cgo_cmalloc(uint64(len(s)+1))
1637 pp := (*[1<<30]byte)(p)
1640 return (*_Ctype_char)(p)
1645 func _Cfunc_CBytes(b []byte) unsafe.Pointer {
1646 p := _cgo_cmalloc(uint64(len(b)))
1647 pp := (*[1<<30]byte)(p)
1653 const cMallocDef
= `
1654 func _Cfunc__CMalloc(n _Ctype_size_t) unsafe.Pointer {
1655 return _cgo_cmalloc(uint64(n))
1659 var builtinDefs
= map[string]string{
1660 "GoString": goStringDef
,
1661 "GoStringN": goStringNDef
,
1662 "GoBytes": goBytesDef
,
1663 "CString": cStringDef
,
1664 "CBytes": cBytesDef
,
1665 "_CMalloc": cMallocDef
,
1668 // Definitions for C.malloc in Go and in C. We define it ourselves
1669 // since we call it from functions we define, such as C.CString.
1670 // Also, we have historically ensured that C.malloc does not return
1671 // nil even for an allocation of 0.
1673 const cMallocDefGo
= `
1674 //go:cgo_import_static _cgoPREFIX_Cfunc__Cmalloc
1675 //go:linkname __cgofn__cgoPREFIX_Cfunc__Cmalloc _cgoPREFIX_Cfunc__Cmalloc
1676 var __cgofn__cgoPREFIX_Cfunc__Cmalloc byte
1677 var _cgoPREFIX_Cfunc__Cmalloc = unsafe.Pointer(&__cgofn__cgoPREFIX_Cfunc__Cmalloc)
1679 //go:linkname runtime_throw runtime.throw
1680 func runtime_throw(string)
1682 //go:cgo_unsafe_args
1683 func _cgo_cmalloc(p0 uint64) (r1 unsafe.Pointer) {
1684 _cgo_runtime_cgocall(_cgoPREFIX_Cfunc__Cmalloc, uintptr(unsafe.Pointer(&p0)))
1686 runtime_throw("runtime: C malloc failed")
1692 // cMallocDefC defines the C version of C.malloc for the gc compiler.
1693 // It is defined here because C.CString and friends need a definition.
1694 // We define it by hand, rather than simply inventing a reference to
1695 // C.malloc, because <stdlib.h> may not have been included.
1696 // This is approximately what writeOutputFunc would generate, but
1697 // skips the cgo_topofstack code (which is only needed if the C code
1698 // calls back into Go). This also avoids returning nil for an
1699 // allocation of 0 bytes.
1700 const cMallocDefC
= `
1701 CGO_NO_SANITIZE_THREAD
1702 void _cgoPREFIX_Cfunc__Cmalloc(void *v) {
1704 unsigned long long p0;
1708 _cgo_tsan_acquire();
1709 ret = malloc(a->p0);
1710 if (ret == 0 && a->p0 == 0) {
1714 _cgo_tsan_release();
1718 func (p
*Package
) cPrologGccgo() string {
1719 r
:= strings
.NewReplacer(
1721 "GCCGOSYMBOLPREF", p
.gccgoSymbolPrefix(),
1722 "_cgoCheckPointer", gccgoToSymbol("_cgoCheckPointer"),
1723 "_cgoCheckResult", gccgoToSymbol("_cgoCheckResult"))
1724 return r
.Replace(cPrologGccgo
)
1727 const cPrologGccgo
= `
1728 #line 1 "cgo-c-prolog-gccgo"
1733 typedef unsigned char byte;
1734 typedef intptr_t intgo;
1736 struct __go_string {
1737 const unsigned char *__data;
1741 typedef struct __go_open_array {
1747 struct __go_string __go_byte_array_to_string(const void* p, intgo len);
1748 struct __go_open_array __go_string_to_byte_array (struct __go_string str);
1750 extern void runtime_throw(const char *);
1752 const char *_cgoPREFIX_Cfunc_CString(struct __go_string s) {
1753 char *p = malloc(s.__length+1);
1755 runtime_throw("runtime: C malloc failed");
1756 memmove(p, s.__data, s.__length);
1761 void *_cgoPREFIX_Cfunc_CBytes(struct __go_open_array b) {
1762 char *p = malloc(b.__count);
1764 runtime_throw("runtime: C malloc failed");
1765 memmove(p, b.__values, b.__count);
1769 struct __go_string _cgoPREFIX_Cfunc_GoString(char *p) {
1770 intgo len = (p != NULL) ? strlen(p) : 0;
1771 return __go_byte_array_to_string(p, len);
1774 struct __go_string _cgoPREFIX_Cfunc_GoStringN(char *p, int32_t n) {
1775 return __go_byte_array_to_string(p, n);
1778 Slice _cgoPREFIX_Cfunc_GoBytes(char *p, int32_t n) {
1779 struct __go_string s = { (const unsigned char *)p, n };
1780 return __go_string_to_byte_array(s);
1783 void *_cgoPREFIX_Cfunc__CMalloc(size_t n) {
1784 void *p = malloc(n);
1785 if(p == NULL && n == 0)
1788 runtime_throw("runtime: C malloc failed");
1792 struct __go_type_descriptor;
1793 typedef struct __go_empty_interface {
1794 const struct __go_type_descriptor *__type_descriptor;
1798 extern void runtimeCgoCheckPointer(Eface, Eface)
1799 __asm__("runtime.cgoCheckPointer")
1800 __attribute__((weak));
1802 extern void localCgoCheckPointer(Eface, Eface)
1803 __asm__("GCCGOSYMBOLPREF._cgoCheckPointer");
1805 void localCgoCheckPointer(Eface ptr, Eface arg) {
1806 if(runtimeCgoCheckPointer) {
1807 runtimeCgoCheckPointer(ptr, arg);
1811 extern void runtimeCgoCheckResult(Eface)
1812 __asm__("runtime.cgoCheckResult")
1813 __attribute__((weak));
1815 extern void localCgoCheckResult(Eface)
1816 __asm__("GCCGOSYMBOLPREF._cgoCheckResult");
1818 void localCgoCheckResult(Eface val) {
1819 if(runtimeCgoCheckResult) {
1820 runtimeCgoCheckResult(val);
1825 // builtinExportProlog is a shorter version of builtinProlog,
1826 // to be put into the _cgo_export.h file.
1827 // For historical reasons we can't use builtinProlog in _cgo_export.h,
1828 // because _cgo_export.h defines GoString as a struct while builtinProlog
1829 // defines it as a function. We don't change this to avoid unnecessarily
1830 // breaking existing code.
1831 // The test of GO_CGO_GOSTRING_TYPEDEF avoids a duplicate definition
1832 // error if a Go file with a cgo comment #include's the export header
1833 // generated by a different package.
1834 const builtinExportProlog
= `
1835 #line 1 "cgo-builtin-export-prolog"
1837 #include <stddef.h> /* for ptrdiff_t below */
1839 #ifndef GO_CGO_EXPORT_PROLOGUE_H
1840 #define GO_CGO_EXPORT_PROLOGUE_H
1842 #ifndef GO_CGO_GOSTRING_TYPEDEF
1843 typedef struct { const char *p; ptrdiff_t n; } _GoString_;
1849 func (p
*Package
) gccExportHeaderProlog() string {
1850 return strings
.Replace(gccExportHeaderProlog
, "GOINTBITS", fmt
.Sprint(8*p
.IntSize
), -1)
1853 // gccExportHeaderProlog is written to the exported header, after the
1854 // import "C" comment preamble but before the generated declarations
1855 // of exported functions. This permits the generated declarations to
1856 // use the type names that appear in goTypes, above.
1858 // The test of GO_CGO_GOSTRING_TYPEDEF avoids a duplicate definition
1859 // error if a Go file with a cgo comment #include's the export header
1860 // generated by a different package. Unfortunately GoString means two
1861 // different things: in this prolog it means a C name for the Go type,
1862 // while in the prolog written into the start of the C code generated
1863 // from a cgo-using Go file it means the C.GoString function. There is
1864 // no way to resolve this conflict, but it also doesn't make much
1865 // difference, as Go code never wants to refer to the latter meaning.
1866 const gccExportHeaderProlog
= `
1867 /* Start of boilerplate cgo prologue. */
1868 #line 1 "cgo-gcc-export-header-prolog"
1870 #ifndef GO_CGO_PROLOGUE_H
1871 #define GO_CGO_PROLOGUE_H
1873 typedef signed char GoInt8;
1874 typedef unsigned char GoUint8;
1875 typedef short GoInt16;
1876 typedef unsigned short GoUint16;
1877 typedef int GoInt32;
1878 typedef unsigned int GoUint32;
1879 typedef long long GoInt64;
1880 typedef unsigned long long GoUint64;
1881 typedef GoIntGOINTBITS GoInt;
1882 typedef GoUintGOINTBITS GoUint;
1883 typedef __SIZE_TYPE__ GoUintptr;
1884 typedef float GoFloat32;
1885 typedef double GoFloat64;
1886 typedef float _Complex GoComplex64;
1887 typedef double _Complex GoComplex128;
1890 static assertion to make sure the file is being used on architecture
1891 at least with matching size of GoInt.
1893 typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1];
1895 #ifndef GO_CGO_GOSTRING_TYPEDEF
1896 typedef _GoString_ GoString;
1898 typedef void *GoMap;
1899 typedef void *GoChan;
1900 typedef struct { void *t; void *v; } GoInterface;
1901 typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
1905 /* End of boilerplate cgo prologue. */
1912 // gccExportHeaderEpilog goes at the end of the generated header file.
1913 const gccExportHeaderEpilog
= `
1919 // gccgoExportFileProlog is written to the _cgo_export.c file when
1921 // We use weak declarations, and test the addresses, so that this code
1922 // works with older versions of gccgo.
1923 const gccgoExportFileProlog
= `
1924 #line 1 "cgo-gccgo-export-file-prolog"
1925 extern _Bool runtime_iscgo __attribute__ ((weak));
1927 static void GoInit(void) __attribute__ ((constructor));
1928 static void GoInit(void) {
1933 extern __SIZE_TYPE__ _cgo_wait_runtime_init_done(void) __attribute__ ((weak));