github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/cmd/cgo/gcc.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Annotate Ref in Prog with C types by parsing gcc debug output. 6 // Conversion of debug output to Go types. 7 8 package main 9 10 import ( 11 "bytes" 12 "debug/dwarf" 13 "debug/elf" 14 "debug/macho" 15 "debug/pe" 16 "encoding/binary" 17 "errors" 18 "flag" 19 "fmt" 20 "go/ast" 21 "go/parser" 22 "go/token" 23 "math" 24 "os" 25 "strconv" 26 "strings" 27 "unicode" 28 "unicode/utf8" 29 ) 30 31 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines") 32 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations") 33 34 var nameToC = map[string]string{ 35 "schar": "signed char", 36 "uchar": "unsigned char", 37 "ushort": "unsigned short", 38 "uint": "unsigned int", 39 "ulong": "unsigned long", 40 "longlong": "long long", 41 "ulonglong": "unsigned long long", 42 "complexfloat": "float _Complex", 43 "complexdouble": "double _Complex", 44 } 45 46 // cname returns the C name to use for C.s. 47 // The expansions are listed in nameToC and also 48 // struct_foo becomes "struct foo", and similarly for 49 // union and enum. 50 func cname(s string) string { 51 if t, ok := nameToC[s]; ok { 52 return t 53 } 54 55 if strings.HasPrefix(s, "struct_") { 56 return "struct " + s[len("struct_"):] 57 } 58 if strings.HasPrefix(s, "union_") { 59 return "union " + s[len("union_"):] 60 } 61 if strings.HasPrefix(s, "enum_") { 62 return "enum " + s[len("enum_"):] 63 } 64 if strings.HasPrefix(s, "sizeof_") { 65 return "sizeof(" + cname(s[len("sizeof_"):]) + ")" 66 } 67 return s 68 } 69 70 // DiscardCgoDirectives processes the import C preamble, and discards 71 // all #cgo CFLAGS and LDFLAGS directives, so they don't make their 72 // way into _cgo_export.h. 73 func (f *File) DiscardCgoDirectives() { 74 linesIn := strings.Split(f.Preamble, "\n") 75 linesOut := make([]string, 0, len(linesIn)) 76 for _, line := range linesIn { 77 l := strings.TrimSpace(line) 78 if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) { 79 linesOut = append(linesOut, line) 80 } else { 81 linesOut = append(linesOut, "") 82 } 83 } 84 f.Preamble = strings.Join(linesOut, "\n") 85 } 86 87 // addToFlag appends args to flag. All flags are later written out onto the 88 // _cgo_flags file for the build system to use. 89 func (p *Package) addToFlag(flag string, args []string) { 90 p.CgoFlags[flag] = append(p.CgoFlags[flag], args...) 91 if flag == "CFLAGS" { 92 // We'll also need these when preprocessing for dwarf information. 93 p.GccOptions = append(p.GccOptions, args...) 94 } 95 } 96 97 // splitQuoted splits the string s around each instance of one or more consecutive 98 // white space characters while taking into account quotes and escaping, and 99 // returns an array of substrings of s or an empty list if s contains only white space. 100 // Single quotes and double quotes are recognized to prevent splitting within the 101 // quoted region, and are removed from the resulting substrings. If a quote in s 102 // isn't closed err will be set and r will have the unclosed argument as the 103 // last element. The backslash is used for escaping. 104 // 105 // For example, the following string: 106 // 107 // `a b:"c d" 'e''f' "g\""` 108 // 109 // Would be parsed as: 110 // 111 // []string{"a", "b:c d", "ef", `g"`} 112 // 113 func splitQuoted(s string) (r []string, err error) { 114 var args []string 115 arg := make([]rune, len(s)) 116 escaped := false 117 quoted := false 118 quote := '\x00' 119 i := 0 120 for _, r := range s { 121 switch { 122 case escaped: 123 escaped = false 124 case r == '\\': 125 escaped = true 126 continue 127 case quote != 0: 128 if r == quote { 129 quote = 0 130 continue 131 } 132 case r == '"' || r == '\'': 133 quoted = true 134 quote = r 135 continue 136 case unicode.IsSpace(r): 137 if quoted || i > 0 { 138 quoted = false 139 args = append(args, string(arg[:i])) 140 i = 0 141 } 142 continue 143 } 144 arg[i] = r 145 i++ 146 } 147 if quoted || i > 0 { 148 args = append(args, string(arg[:i])) 149 } 150 if quote != 0 { 151 err = errors.New("unclosed quote") 152 } else if escaped { 153 err = errors.New("unfinished escaping") 154 } 155 return args, err 156 } 157 158 // Translate rewrites f.AST, the original Go input, to remove 159 // references to the imported package C, replacing them with 160 // references to the equivalent Go types, functions, and variables. 161 func (p *Package) Translate(f *File) { 162 for _, cref := range f.Ref { 163 // Convert C.ulong to C.unsigned long, etc. 164 cref.Name.C = cname(cref.Name.Go) 165 } 166 p.loadDefines(f) 167 needType := p.guessKinds(f) 168 if len(needType) > 0 { 169 p.loadDWARF(f, needType) 170 } 171 if p.rewriteCalls(f) { 172 // Add `import _cgo_unsafe "unsafe"` after the package statement. 173 f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"") 174 } 175 p.rewriteRef(f) 176 } 177 178 // loadDefines coerces gcc into spitting out the #defines in use 179 // in the file f and saves relevant renamings in f.Name[name].Define. 180 func (p *Package) loadDefines(f *File) { 181 var b bytes.Buffer 182 b.WriteString(builtinProlog) 183 b.WriteString(f.Preamble) 184 stdout := p.gccDefines(b.Bytes()) 185 186 for _, line := range strings.Split(stdout, "\n") { 187 if len(line) < 9 || line[0:7] != "#define" { 188 continue 189 } 190 191 line = strings.TrimSpace(line[8:]) 192 193 var key, val string 194 spaceIndex := strings.Index(line, " ") 195 tabIndex := strings.Index(line, "\t") 196 197 if spaceIndex == -1 && tabIndex == -1 { 198 continue 199 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) { 200 key = line[0:spaceIndex] 201 val = strings.TrimSpace(line[spaceIndex:]) 202 } else { 203 key = line[0:tabIndex] 204 val = strings.TrimSpace(line[tabIndex:]) 205 } 206 207 if key == "__clang__" { 208 p.GccIsClang = true 209 } 210 211 if n := f.Name[key]; n != nil { 212 if *debugDefine { 213 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val) 214 } 215 n.Define = val 216 } 217 } 218 } 219 220 // guessKinds tricks gcc into revealing the kind of each 221 // name xxx for the references C.xxx in the Go input. 222 // The kind is either a constant, type, or variable. 223 func (p *Package) guessKinds(f *File) []*Name { 224 // Determine kinds for names we already know about, 225 // like #defines or 'struct foo', before bothering with gcc. 226 var names, needType []*Name 227 for _, key := range nameKeys(f.Name) { 228 n := f.Name[key] 229 // If we've already found this name as a #define 230 // and we can translate it as a constant value, do so. 231 if n.Define != "" { 232 if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil { 233 n.Kind = "iconst" 234 // Turn decimal into hex, just for consistency 235 // with enum-derived constants. Otherwise 236 // in the cgo -godefs output half the constants 237 // are in hex and half are in whatever the #define used. 238 n.Const = fmt.Sprintf("%#x", i) 239 } else if n.Define[0] == '\'' { 240 if _, err := parser.ParseExpr(n.Define); err == nil { 241 n.Kind = "iconst" 242 n.Const = n.Define 243 } 244 } else if n.Define[0] == '"' { 245 if _, err := parser.ParseExpr(n.Define); err == nil { 246 n.Kind = "sconst" 247 n.Const = n.Define 248 } 249 } 250 251 if n.IsConst() { 252 continue 253 } 254 } 255 256 // If this is a struct, union, or enum type name, no need to guess the kind. 257 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") { 258 n.Kind = "type" 259 needType = append(needType, n) 260 continue 261 } 262 263 // Otherwise, we'll need to find out from gcc. 264 names = append(names, n) 265 } 266 267 // Bypass gcc if there's nothing left to find out. 268 if len(names) == 0 { 269 return needType 270 } 271 272 // Coerce gcc into telling us whether each name is a type, a value, or undeclared. 273 // For names, find out whether they are integer constants. 274 // We used to look at specific warning or error messages here, but that tied the 275 // behavior too closely to specific versions of the compilers. 276 // Instead, arrange that we can infer what we need from only the presence or absence 277 // of an error on a specific line. 278 // 279 // For each name, we generate these lines, where xxx is the index in toSniff plus one. 280 // 281 // #line xxx "not-declared" 282 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; } 283 // #line xxx "not-type" 284 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; } 285 // #line xxx "not-int-const" 286 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; } 287 // #line xxx "not-num-const" 288 // void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); } 289 // #line xxx "not-str-lit" 290 // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); } 291 // 292 // If we see an error at not-declared:xxx, the corresponding name is not declared. 293 // If we see an error at not-type:xxx, the corresponding name is a type. 294 // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant. 295 // If we see an error at not-num-const:xxx, the corresponding name is not a number constant. 296 // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal. 297 // 298 // The specific input forms are chosen so that they are valid C syntax regardless of 299 // whether name denotes a type or an expression. 300 301 var b bytes.Buffer 302 b.WriteString(builtinProlog) 303 b.WriteString(f.Preamble) 304 305 for i, n := range names { 306 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+ 307 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+ 308 "#line %d \"not-type\"\n"+ 309 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+ 310 "#line %d \"not-int-const\"\n"+ 311 "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+ 312 "#line %d \"not-num-const\"\n"+ 313 "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+ 314 "#line %d \"not-str-lit\"\n"+ 315 "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n", 316 i+1, i+1, n.C, 317 i+1, i+1, n.C, 318 i+1, i+1, n.C, 319 i+1, i+1, n.C, 320 i+1, i+1, n.C, 321 ) 322 } 323 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+ 324 "int __cgo__1 = __cgo__2;\n") 325 326 stderr := p.gccErrors(b.Bytes()) 327 if stderr == "" { 328 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes()) 329 } 330 331 completed := false 332 sniff := make([]int, len(names)) 333 const ( 334 notType = 1 << iota 335 notIntConst 336 notNumConst 337 notStrLiteral 338 notDeclared 339 ) 340 sawUnmatchedErrors := false 341 for _, line := range strings.Split(stderr, "\n") { 342 // Ignore warnings and random comments, with one 343 // exception: newer GCC versions will sometimes emit 344 // an error on a macro #define with a note referring 345 // to where the expansion occurs. We care about where 346 // the expansion occurs, so in that case treat the note 347 // as an error. 348 isError := strings.Contains(line, ": error:") 349 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors 350 if !isError && !isErrorNote { 351 continue 352 } 353 354 c1 := strings.Index(line, ":") 355 if c1 < 0 { 356 continue 357 } 358 c2 := strings.Index(line[c1+1:], ":") 359 if c2 < 0 { 360 continue 361 } 362 c2 += c1 + 1 363 364 filename := line[:c1] 365 i, _ := strconv.Atoi(line[c1+1 : c2]) 366 i-- 367 if i < 0 || i >= len(names) { 368 if isError { 369 sawUnmatchedErrors = true 370 } 371 continue 372 } 373 374 switch filename { 375 case "completed": 376 // Strictly speaking, there is no guarantee that seeing the error at completed:1 377 // (at the end of the file) means we've seen all the errors from earlier in the file, 378 // but usually it does. Certainly if we don't see the completed:1 error, we did 379 // not get all the errors we expected. 380 completed = true 381 382 case "not-declared": 383 sniff[i] |= notDeclared 384 case "not-type": 385 sniff[i] |= notType 386 case "not-int-const": 387 sniff[i] |= notIntConst 388 case "not-num-const": 389 sniff[i] |= notNumConst 390 case "not-str-lit": 391 sniff[i] |= notStrLiteral 392 default: 393 if isError { 394 sawUnmatchedErrors = true 395 } 396 continue 397 } 398 399 sawUnmatchedErrors = false 400 } 401 402 if !completed { 403 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr) 404 } 405 406 for i, n := range names { 407 switch sniff[i] { 408 default: 409 error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go)) 410 case notStrLiteral | notType: 411 n.Kind = "iconst" 412 case notIntConst | notStrLiteral | notType: 413 n.Kind = "fconst" 414 case notIntConst | notNumConst | notType: 415 n.Kind = "sconst" 416 case notIntConst | notNumConst | notStrLiteral: 417 n.Kind = "type" 418 case notIntConst | notNumConst | notStrLiteral | notType: 419 n.Kind = "not-type" 420 } 421 } 422 if nerrors > 0 { 423 // Check if compiling the preamble by itself causes any errors, 424 // because the messages we've printed out so far aren't helpful 425 // to users debugging preamble mistakes. See issue 8442. 426 preambleErrors := p.gccErrors([]byte(f.Preamble)) 427 if len(preambleErrors) > 0 { 428 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors) 429 } 430 431 fatalf("unresolved names") 432 } 433 434 needType = append(needType, names...) 435 return needType 436 } 437 438 // loadDWARF parses the DWARF debug information generated 439 // by gcc to learn the details of the constants, variables, and types 440 // being referred to as C.xxx. 441 func (p *Package) loadDWARF(f *File, names []*Name) { 442 // Extract the types from the DWARF section of an object 443 // from a well-formed C program. Gcc only generates DWARF info 444 // for symbols in the object file, so it is not enough to print the 445 // preamble and hope the symbols we care about will be there. 446 // Instead, emit 447 // __typeof__(names[i]) *__cgo__i; 448 // for each entry in names and then dereference the type we 449 // learn for __cgo__i. 450 var b bytes.Buffer 451 b.WriteString(builtinProlog) 452 b.WriteString(f.Preamble) 453 b.WriteString("#line 1 \"cgo-dwarf-inference\"\n") 454 for i, n := range names { 455 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i) 456 if n.Kind == "iconst" { 457 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C) 458 } 459 } 460 461 // We create a data block initialized with the values, 462 // so we can read them out of the object file. 463 fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n") 464 for _, n := range names { 465 if n.Kind == "iconst" { 466 fmt.Fprintf(&b, "\t%s,\n", n.C) 467 } else { 468 fmt.Fprintf(&b, "\t0,\n") 469 } 470 } 471 // for the last entry, we cannot use 0, otherwise 472 // in case all __cgodebug_data is zero initialized, 473 // LLVM-based gcc will place the it in the __DATA.__common 474 // zero-filled section (our debug/macho doesn't support 475 // this) 476 fmt.Fprintf(&b, "\t1\n") 477 fmt.Fprintf(&b, "};\n") 478 479 // do the same work for floats. 480 fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n") 481 for _, n := range names { 482 if n.Kind == "fconst" { 483 fmt.Fprintf(&b, "\t%s,\n", n.C) 484 } else { 485 fmt.Fprintf(&b, "\t0,\n") 486 } 487 } 488 fmt.Fprintf(&b, "\t1\n") 489 fmt.Fprintf(&b, "};\n") 490 491 // do the same work for strings. 492 for i, n := range names { 493 if n.Kind == "sconst" { 494 fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C) 495 fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C) 496 } 497 } 498 499 d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names)) 500 501 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i. 502 types := make([]dwarf.Type, len(names)) 503 r := d.Reader() 504 for { 505 e, err := r.Next() 506 if err != nil { 507 fatalf("reading DWARF entry: %s", err) 508 } 509 if e == nil { 510 break 511 } 512 switch e.Tag { 513 case dwarf.TagVariable: 514 name, _ := e.Val(dwarf.AttrName).(string) 515 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset) 516 if name == "" || typOff == 0 { 517 if e.Val(dwarf.AttrSpecification) != nil { 518 // Since we are reading all the DWARF, 519 // assume we will see the variable elsewhere. 520 break 521 } 522 fatalf("malformed DWARF TagVariable entry") 523 } 524 if !strings.HasPrefix(name, "__cgo__") { 525 break 526 } 527 typ, err := d.Type(typOff) 528 if err != nil { 529 fatalf("loading DWARF type: %s", err) 530 } 531 t, ok := typ.(*dwarf.PtrType) 532 if !ok || t == nil { 533 fatalf("internal error: %s has non-pointer type", name) 534 } 535 i, err := strconv.Atoi(name[7:]) 536 if err != nil { 537 fatalf("malformed __cgo__ name: %s", name) 538 } 539 types[i] = t.Type 540 } 541 if e.Tag != dwarf.TagCompileUnit { 542 r.SkipChildren() 543 } 544 } 545 546 // Record types and typedef information. 547 var conv typeConv 548 conv.Init(p.PtrSize, p.IntSize) 549 for i, n := range names { 550 if types[i] == nil { 551 continue 552 } 553 pos := f.NamePos[n] 554 f, fok := types[i].(*dwarf.FuncType) 555 if n.Kind != "type" && fok { 556 n.Kind = "func" 557 n.FuncType = conv.FuncType(f, pos) 558 } else { 559 n.Type = conv.Type(types[i], pos) 560 switch n.Kind { 561 case "iconst": 562 if i < len(ints) { 563 if _, ok := types[i].(*dwarf.UintType); ok { 564 n.Const = fmt.Sprintf("%#x", uint64(ints[i])) 565 } else { 566 n.Const = fmt.Sprintf("%#x", ints[i]) 567 } 568 } 569 case "fconst": 570 if i < len(floats) { 571 n.Const = fmt.Sprintf("%f", floats[i]) 572 } 573 case "sconst": 574 if i < len(strs) { 575 n.Const = fmt.Sprintf("%q", strs[i]) 576 } 577 } 578 } 579 conv.FinishType(pos) 580 } 581 } 582 583 // mangleName does name mangling to translate names 584 // from the original Go source files to the names 585 // used in the final Go files generated by cgo. 586 func (p *Package) mangleName(n *Name) { 587 // When using gccgo variables have to be 588 // exported so that they become global symbols 589 // that the C code can refer to. 590 prefix := "_C" 591 if *gccgo && n.IsVar() { 592 prefix = "C" 593 } 594 n.Mangle = prefix + n.Kind + "_" + n.Go 595 } 596 597 // rewriteCalls rewrites all calls that pass pointers to check that 598 // they follow the rules for passing pointers between Go and C. 599 // This returns whether the package needs to import unsafe as _cgo_unsafe. 600 func (p *Package) rewriteCalls(f *File) bool { 601 needsUnsafe := false 602 for _, call := range f.Calls { 603 // This is a call to C.xxx; set goname to "xxx". 604 goname := call.Call.Fun.(*ast.SelectorExpr).Sel.Name 605 if goname == "malloc" { 606 continue 607 } 608 name := f.Name[goname] 609 if name.Kind != "func" { 610 // Probably a type conversion. 611 continue 612 } 613 if p.rewriteCall(f, call, name) { 614 needsUnsafe = true 615 } 616 } 617 return needsUnsafe 618 } 619 620 // rewriteCall rewrites one call to add pointer checks. 621 // If any pointer checks are required, we rewrite the call into a 622 // function literal that calls _cgoCheckPointer for each pointer 623 // argument and then calls the original function. 624 // This returns whether the package needs to import unsafe as _cgo_unsafe. 625 func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool { 626 // Avoid a crash if the number of arguments is 627 // less than the number of parameters. 628 // This will be caught when the generated file is compiled. 629 if len(call.Call.Args) < len(name.FuncType.Params) { 630 return false 631 } 632 633 any := false 634 for i, param := range name.FuncType.Params { 635 if p.needsPointerCheck(f, param.Go, call.Call.Args[i]) { 636 any = true 637 break 638 } 639 } 640 if !any { 641 return false 642 } 643 644 // We need to rewrite this call. 645 // 646 // We are going to rewrite C.f(p) to 647 // func (_cgo0 ptype) { 648 // _cgoCheckPointer(_cgo0) 649 // C.f(_cgo0) 650 // }(p) 651 // Using a function literal like this lets us do correct 652 // argument type checking, and works correctly if the call is 653 // deferred. 654 needsUnsafe := false 655 params := make([]*ast.Field, len(name.FuncType.Params)) 656 nargs := make([]ast.Expr, len(name.FuncType.Params)) 657 var stmts []ast.Stmt 658 for i, param := range name.FuncType.Params { 659 // params is going to become the parameters of the 660 // function literal. 661 // nargs is going to become the list of arguments made 662 // by the call within the function literal. 663 // nparam is the parameter of the function literal that 664 // corresponds to param. 665 666 origArg := call.Call.Args[i] 667 nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i)) 668 nargs[i] = nparam 669 670 // The Go version of the C type might use unsafe.Pointer, 671 // but the file might not import unsafe. 672 // Rewrite the Go type if necessary to use _cgo_unsafe. 673 ptype := p.rewriteUnsafe(param.Go) 674 if ptype != param.Go { 675 needsUnsafe = true 676 } 677 678 params[i] = &ast.Field{ 679 Names: []*ast.Ident{nparam}, 680 Type: ptype, 681 } 682 683 if !p.needsPointerCheck(f, param.Go, origArg) { 684 continue 685 } 686 687 // Run the cgo pointer checks on nparam. 688 689 // Change the function literal to call the real function 690 // with the parameter passed through _cgoCheckPointer. 691 c := &ast.CallExpr{ 692 Fun: ast.NewIdent("_cgoCheckPointer"), 693 Args: []ast.Expr{ 694 nparam, 695 }, 696 } 697 698 // Add optional additional arguments for an address 699 // expression. 700 c.Args = p.checkAddrArgs(f, c.Args, origArg) 701 702 stmt := &ast.ExprStmt{ 703 X: c, 704 } 705 stmts = append(stmts, stmt) 706 } 707 708 const cgoMarker = "__cgo__###__marker__" 709 fcall := &ast.CallExpr{ 710 Fun: ast.NewIdent(cgoMarker), 711 Args: nargs, 712 } 713 ftype := &ast.FuncType{ 714 Params: &ast.FieldList{ 715 List: params, 716 }, 717 } 718 if name.FuncType.Result != nil { 719 rtype := p.rewriteUnsafe(name.FuncType.Result.Go) 720 if rtype != name.FuncType.Result.Go { 721 needsUnsafe = true 722 } 723 ftype.Results = &ast.FieldList{ 724 List: []*ast.Field{ 725 &ast.Field{ 726 Type: rtype, 727 }, 728 }, 729 } 730 } 731 732 // If this call expects two results, we have to 733 // adjust the results of the function we generated. 734 for _, ref := range f.Ref { 735 if ref.Expr == &call.Call.Fun && ref.Context == ctxCall2 { 736 if ftype.Results == nil { 737 // An explicit void argument 738 // looks odd but it seems to 739 // be how cgo has worked historically. 740 ftype.Results = &ast.FieldList{ 741 List: []*ast.Field{ 742 &ast.Field{ 743 Type: ast.NewIdent("_Ctype_void"), 744 }, 745 }, 746 } 747 } 748 ftype.Results.List = append(ftype.Results.List, 749 &ast.Field{ 750 Type: ast.NewIdent("error"), 751 }) 752 } 753 } 754 755 var fbody ast.Stmt 756 if ftype.Results == nil { 757 fbody = &ast.ExprStmt{ 758 X: fcall, 759 } 760 } else { 761 fbody = &ast.ReturnStmt{ 762 Results: []ast.Expr{fcall}, 763 } 764 } 765 lit := &ast.FuncLit{ 766 Type: ftype, 767 Body: &ast.BlockStmt{ 768 List: append(stmts, fbody), 769 }, 770 } 771 text := strings.Replace(gofmt(lit), "\n", ";", -1) 772 repl := strings.Split(text, cgoMarker) 773 f.Edit.Insert(f.offset(call.Call.Fun.Pos()), repl[0]) 774 f.Edit.Insert(f.offset(call.Call.Fun.End()), repl[1]) 775 776 return needsUnsafe 777 } 778 779 // needsPointerCheck returns whether the type t needs a pointer check. 780 // This is true if t is a pointer and if the value to which it points 781 // might contain a pointer. 782 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool { 783 // An untyped nil does not need a pointer check, and when 784 // _cgoCheckPointer returns the untyped nil the type assertion we 785 // are going to insert will fail. Easier to just skip nil arguments. 786 // TODO: Note that this fails if nil is shadowed. 787 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" { 788 return false 789 } 790 791 return p.hasPointer(f, t, true) 792 } 793 794 // hasPointer is used by needsPointerCheck. If top is true it returns 795 // whether t is or contains a pointer that might point to a pointer. 796 // If top is false it returns whether t is or contains a pointer. 797 // f may be nil. 798 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool { 799 switch t := t.(type) { 800 case *ast.ArrayType: 801 if t.Len == nil { 802 if !top { 803 return true 804 } 805 return p.hasPointer(f, t.Elt, false) 806 } 807 return p.hasPointer(f, t.Elt, top) 808 case *ast.StructType: 809 for _, field := range t.Fields.List { 810 if p.hasPointer(f, field.Type, top) { 811 return true 812 } 813 } 814 return false 815 case *ast.StarExpr: // Pointer type. 816 if !top { 817 return true 818 } 819 // Check whether this is a pointer to a C union (or class) 820 // type that contains a pointer. 821 if unionWithPointer[t.X] { 822 return true 823 } 824 return p.hasPointer(f, t.X, false) 825 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: 826 return true 827 case *ast.Ident: 828 // TODO: Handle types defined within function. 829 for _, d := range p.Decl { 830 gd, ok := d.(*ast.GenDecl) 831 if !ok || gd.Tok != token.TYPE { 832 continue 833 } 834 for _, spec := range gd.Specs { 835 ts, ok := spec.(*ast.TypeSpec) 836 if !ok { 837 continue 838 } 839 if ts.Name.Name == t.Name { 840 return p.hasPointer(f, ts.Type, top) 841 } 842 } 843 } 844 if def := typedef[t.Name]; def != nil { 845 return p.hasPointer(f, def.Go, top) 846 } 847 if t.Name == "string" { 848 return !top 849 } 850 if t.Name == "error" { 851 return true 852 } 853 if goTypes[t.Name] != nil { 854 return false 855 } 856 // We can't figure out the type. Conservative 857 // approach is to assume it has a pointer. 858 return true 859 case *ast.SelectorExpr: 860 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" { 861 // Type defined in a different package. 862 // Conservative approach is to assume it has a 863 // pointer. 864 return true 865 } 866 if f == nil { 867 // Conservative approach: assume pointer. 868 return true 869 } 870 name := f.Name[t.Sel.Name] 871 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil { 872 return p.hasPointer(f, name.Type.Go, top) 873 } 874 // We can't figure out the type. Conservative 875 // approach is to assume it has a pointer. 876 return true 877 default: 878 error_(t.Pos(), "could not understand type %s", gofmt(t)) 879 return true 880 } 881 } 882 883 // checkAddrArgs tries to add arguments to the call of 884 // _cgoCheckPointer when the argument is an address expression. We 885 // pass true to mean that the argument is an address operation of 886 // something other than a slice index, which means that it's only 887 // necessary to check the specific element pointed to, not the entire 888 // object. This is for &s.f, where f is a field in a struct. We can 889 // pass a slice or array, meaning that we should check the entire 890 // slice or array but need not check any other part of the object. 891 // This is for &s.a[i], where we need to check all of a. However, we 892 // only pass the slice or array if we can refer to it without side 893 // effects. 894 func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr { 895 // Strip type conversions. 896 for { 897 c, ok := x.(*ast.CallExpr) 898 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) { 899 break 900 } 901 x = c.Args[0] 902 } 903 u, ok := x.(*ast.UnaryExpr) 904 if !ok || u.Op != token.AND { 905 return args 906 } 907 index, ok := u.X.(*ast.IndexExpr) 908 if !ok { 909 // This is the address of something that is not an 910 // index expression. We only need to examine the 911 // single value to which it points. 912 // TODO: what if true is shadowed? 913 return append(args, ast.NewIdent("true")) 914 } 915 if !p.hasSideEffects(f, index.X) { 916 // Examine the entire slice. 917 return append(args, index.X) 918 } 919 // Treat the pointer as unknown. 920 return args 921 } 922 923 // hasSideEffects returns whether the expression x has any side 924 // effects. x is an expression, not a statement, so the only side 925 // effect is a function call. 926 func (p *Package) hasSideEffects(f *File, x ast.Expr) bool { 927 found := false 928 f.walk(x, ctxExpr, 929 func(f *File, x interface{}, context astContext) { 930 switch x.(type) { 931 case *ast.CallExpr: 932 found = true 933 } 934 }) 935 return found 936 } 937 938 // isType returns whether the expression is definitely a type. 939 // This is conservative--it returns false for an unknown identifier. 940 func (p *Package) isType(t ast.Expr) bool { 941 switch t := t.(type) { 942 case *ast.SelectorExpr: 943 id, ok := t.X.(*ast.Ident) 944 if !ok { 945 return false 946 } 947 if id.Name == "unsafe" && t.Sel.Name == "Pointer" { 948 return true 949 } 950 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil { 951 return true 952 } 953 return false 954 case *ast.Ident: 955 // TODO: This ignores shadowing. 956 switch t.Name { 957 case "unsafe.Pointer", "bool", "byte", 958 "complex64", "complex128", 959 "error", 960 "float32", "float64", 961 "int", "int8", "int16", "int32", "int64", 962 "rune", "string", 963 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr": 964 965 return true 966 } 967 case *ast.StarExpr: 968 return p.isType(t.X) 969 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, 970 *ast.MapType, *ast.ChanType: 971 972 return true 973 } 974 return false 975 } 976 977 // rewriteUnsafe returns a version of t with references to unsafe.Pointer 978 // rewritten to use _cgo_unsafe.Pointer instead. 979 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr { 980 switch t := t.(type) { 981 case *ast.Ident: 982 // We don't see a SelectorExpr for unsafe.Pointer; 983 // this is created by code in this file. 984 if t.Name == "unsafe.Pointer" { 985 return ast.NewIdent("_cgo_unsafe.Pointer") 986 } 987 case *ast.ArrayType: 988 t1 := p.rewriteUnsafe(t.Elt) 989 if t1 != t.Elt { 990 r := *t 991 r.Elt = t1 992 return &r 993 } 994 case *ast.StructType: 995 changed := false 996 fields := *t.Fields 997 fields.List = nil 998 for _, f := range t.Fields.List { 999 ft := p.rewriteUnsafe(f.Type) 1000 if ft == f.Type { 1001 fields.List = append(fields.List, f) 1002 } else { 1003 fn := *f 1004 fn.Type = ft 1005 fields.List = append(fields.List, &fn) 1006 changed = true 1007 } 1008 } 1009 if changed { 1010 r := *t 1011 r.Fields = &fields 1012 return &r 1013 } 1014 case *ast.StarExpr: // Pointer type. 1015 x1 := p.rewriteUnsafe(t.X) 1016 if x1 != t.X { 1017 r := *t 1018 r.X = x1 1019 return &r 1020 } 1021 } 1022 return t 1023 } 1024 1025 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the 1026 // Go equivalents, now that we have figured out the meaning of all 1027 // the xxx. In *godefs mode, rewriteRef replaces the names 1028 // with full definitions instead of mangled names. 1029 func (p *Package) rewriteRef(f *File) { 1030 // Keep a list of all the functions, to remove the ones 1031 // only used as expressions and avoid generating bridge 1032 // code for them. 1033 functions := make(map[string]bool) 1034 1035 // Assign mangled names. 1036 for _, n := range f.Name { 1037 if n.Kind == "not-type" { 1038 if n.Define == "" { 1039 n.Kind = "var" 1040 } else { 1041 n.Kind = "macro" 1042 n.FuncType = &FuncType{ 1043 Result: n.Type, 1044 Go: &ast.FuncType{ 1045 Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}}, 1046 }, 1047 } 1048 } 1049 } 1050 if n.Mangle == "" { 1051 p.mangleName(n) 1052 } 1053 if n.Kind == "func" { 1054 functions[n.Go] = false 1055 } 1056 } 1057 1058 // Now that we have all the name types filled in, 1059 // scan through the Refs to identify the ones that 1060 // are trying to do a ,err call. Also check that 1061 // functions are only used in calls. 1062 for _, r := range f.Ref { 1063 if r.Name.IsConst() && r.Name.Const == "" { 1064 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go)) 1065 } 1066 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default 1067 switch r.Context { 1068 case ctxCall, ctxCall2: 1069 if r.Name.Kind != "func" { 1070 if r.Name.Kind == "type" { 1071 r.Context = ctxType 1072 if r.Name.Type == nil { 1073 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1074 break 1075 } 1076 expr = r.Name.Type.Go 1077 break 1078 } 1079 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) 1080 break 1081 } 1082 functions[r.Name.Go] = true 1083 if r.Context == ctxCall2 { 1084 if r.Name.Go == "_CMalloc" { 1085 error_(r.Pos(), "no two-result form for C.malloc") 1086 break 1087 } 1088 // Invent new Name for the two-result function. 1089 n := f.Name["2"+r.Name.Go] 1090 if n == nil { 1091 n = new(Name) 1092 *n = *r.Name 1093 n.AddError = true 1094 n.Mangle = "_C2func_" + n.Go 1095 f.Name["2"+r.Name.Go] = n 1096 } 1097 expr = ast.NewIdent(n.Mangle) 1098 r.Name = n 1099 break 1100 } 1101 case ctxExpr: 1102 switch r.Name.Kind { 1103 case "func": 1104 if builtinDefs[r.Name.C] != "" { 1105 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C)) 1106 } 1107 1108 // Function is being used in an expression, to e.g. pass around a C function pointer. 1109 // Create a new Name for this Ref which causes the variable to be declared in Go land. 1110 fpName := "fp_" + r.Name.Go 1111 name := f.Name[fpName] 1112 if name == nil { 1113 name = &Name{ 1114 Go: fpName, 1115 C: r.Name.C, 1116 Kind: "fpvar", 1117 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")}, 1118 } 1119 p.mangleName(name) 1120 f.Name[fpName] = name 1121 } 1122 r.Name = name 1123 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr 1124 // function is defined in out.go and simply returns its argument. See 1125 // issue 7757. 1126 expr = &ast.CallExpr{ 1127 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"}, 1128 Args: []ast.Expr{ast.NewIdent(name.Mangle)}, 1129 } 1130 case "type": 1131 // Okay - might be new(T) 1132 if r.Name.Type == nil { 1133 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1134 break 1135 } 1136 expr = r.Name.Type.Go 1137 case "var": 1138 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1139 case "macro": 1140 expr = &ast.CallExpr{Fun: expr} 1141 } 1142 case ctxSelector: 1143 if r.Name.Kind == "var" { 1144 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1145 } else { 1146 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go)) 1147 } 1148 case ctxType: 1149 if r.Name.Kind != "type" { 1150 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 1151 } else if r.Name.Type == nil { 1152 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 1153 // GCC won't raise an error when using pointers to such unknown types. 1154 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1155 } else { 1156 expr = r.Name.Type.Go 1157 } 1158 default: 1159 if r.Name.Kind == "func" { 1160 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 1161 } 1162 } 1163 1164 if *godefs { 1165 // Substitute definition for mangled type name. 1166 if id, ok := expr.(*ast.Ident); ok { 1167 if t := typedef[id.Name]; t != nil { 1168 expr = t.Go 1169 } 1170 if id.Name == r.Name.Mangle && r.Name.Const != "" { 1171 expr = ast.NewIdent(r.Name.Const) 1172 } 1173 } 1174 } 1175 1176 // Copy position information from old expr into new expr, 1177 // in case expression being replaced is first on line. 1178 // See golang.org/issue/6563. 1179 pos := (*r.Expr).Pos() 1180 switch x := expr.(type) { 1181 case *ast.Ident: 1182 expr = &ast.Ident{NamePos: pos, Name: x.Name} 1183 } 1184 1185 // Change AST, because some later processing depends on it, 1186 // and also because -godefs mode still prints the AST. 1187 old := *r.Expr 1188 *r.Expr = expr 1189 1190 // Record source-level edit for cgo output. 1191 repl := gofmt(expr) 1192 if r.Name.Kind != "type" { 1193 repl = "(" + repl + ")" 1194 } 1195 f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl) 1196 } 1197 1198 // Remove functions only used as expressions, so their respective 1199 // bridge functions are not generated. 1200 for name, used := range functions { 1201 if !used { 1202 delete(f.Name, name) 1203 } 1204 } 1205 } 1206 1207 // gccBaseCmd returns the start of the compiler command line. 1208 // It uses $CC if set, or else $GCC, or else the compiler recorded 1209 // during the initial build as defaultCC. 1210 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 1211 func (p *Package) gccBaseCmd() []string { 1212 // Use $CC if set, since that's what the build uses. 1213 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 { 1214 return ret 1215 } 1216 // Try $GCC if set, since that's what we used to use. 1217 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 { 1218 return ret 1219 } 1220 return strings.Fields(defaultCC(goos, goarch)) 1221 } 1222 1223 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 1224 func (p *Package) gccMachine() []string { 1225 switch goarch { 1226 case "amd64": 1227 return []string{"-m64"} 1228 case "386": 1229 return []string{"-m32"} 1230 case "arm": 1231 return []string{"-marm"} // not thumb 1232 case "s390": 1233 return []string{"-m31"} 1234 case "s390x": 1235 return []string{"-m64"} 1236 case "mips64", "mips64le": 1237 return []string{"-mabi=64"} 1238 case "mips", "mipsle": 1239 return []string{"-mabi=32"} 1240 } 1241 return nil 1242 } 1243 1244 func gccTmp() string { 1245 return *objDir + "_cgo_.o" 1246 } 1247 1248 // gccCmd returns the gcc command line to use for compiling 1249 // the input. 1250 func (p *Package) gccCmd() []string { 1251 c := append(p.gccBaseCmd(), 1252 "-w", // no warnings 1253 "-Wno-error", // warnings are not errors 1254 "-o"+gccTmp(), // write object to tmp 1255 "-gdwarf-2", // generate DWARF v2 debugging symbols 1256 "-c", // do not link 1257 "-xc", // input language is C 1258 ) 1259 if p.GccIsClang { 1260 c = append(c, 1261 "-ferror-limit=0", 1262 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 1263 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 1264 // flag to disable the warning. Yes, really good diagnostics, clang. 1265 "-Wno-unknown-warning-option", 1266 "-Wno-unneeded-internal-declaration", 1267 "-Wno-unused-function", 1268 "-Qunused-arguments", 1269 // Clang embeds prototypes for some builtin functions, 1270 // like malloc and calloc, but all size_t parameters are 1271 // incorrectly typed unsigned long. We work around that 1272 // by disabling the builtin functions (this is safe as 1273 // it won't affect the actual compilation of the C code). 1274 // See: https://golang.org/issue/6506. 1275 "-fno-builtin", 1276 ) 1277 } 1278 1279 c = append(c, p.GccOptions...) 1280 c = append(c, p.gccMachine()...) 1281 c = append(c, "-") //read input from standard input 1282 return c 1283 } 1284 1285 // gccDebug runs gcc -gdwarf-2 over the C program stdin and 1286 // returns the corresponding DWARF data and, if present, debug data block. 1287 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) { 1288 runGcc(stdin, p.gccCmd()) 1289 1290 isDebugInts := func(s string) bool { 1291 // Some systems use leading _ to denote non-assembly symbols. 1292 return s == "__cgodebug_ints" || s == "___cgodebug_ints" 1293 } 1294 isDebugFloats := func(s string) bool { 1295 // Some systems use leading _ to denote non-assembly symbols. 1296 return s == "__cgodebug_floats" || s == "___cgodebug_floats" 1297 } 1298 indexOfDebugStr := func(s string) int { 1299 // Some systems use leading _ to denote non-assembly symbols. 1300 if strings.HasPrefix(s, "___") { 1301 s = s[1:] 1302 } 1303 if strings.HasPrefix(s, "__cgodebug_str__") { 1304 if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil { 1305 return n 1306 } 1307 } 1308 return -1 1309 } 1310 indexOfDebugStrlen := func(s string) int { 1311 // Some systems use leading _ to denote non-assembly symbols. 1312 if strings.HasPrefix(s, "___") { 1313 s = s[1:] 1314 } 1315 if strings.HasPrefix(s, "__cgodebug_strlen__") { 1316 if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil { 1317 return n 1318 } 1319 } 1320 return -1 1321 } 1322 1323 strs = make([]string, nnames) 1324 1325 strdata := make(map[int]string, nnames) 1326 strlens := make(map[int]int, nnames) 1327 1328 buildStrings := func() { 1329 for n, strlen := range strlens { 1330 data := strdata[n] 1331 if len(data) <= strlen { 1332 fatalf("invalid string literal") 1333 } 1334 strs[n] = string(data[:strlen]) 1335 } 1336 } 1337 1338 if f, err := macho.Open(gccTmp()); err == nil { 1339 defer f.Close() 1340 d, err := f.DWARF() 1341 if err != nil { 1342 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1343 } 1344 bo := f.ByteOrder 1345 if f.Symtab != nil { 1346 for i := range f.Symtab.Syms { 1347 s := &f.Symtab.Syms[i] 1348 switch { 1349 case isDebugInts(s.Name): 1350 // Found it. Now find data section. 1351 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1352 sect := f.Sections[i] 1353 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1354 if sdat, err := sect.Data(); err == nil { 1355 data := sdat[s.Value-sect.Addr:] 1356 ints = make([]int64, len(data)/8) 1357 for i := range ints { 1358 ints[i] = int64(bo.Uint64(data[i*8:])) 1359 } 1360 } 1361 } 1362 } 1363 case isDebugFloats(s.Name): 1364 // Found it. Now find data section. 1365 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1366 sect := f.Sections[i] 1367 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1368 if sdat, err := sect.Data(); err == nil { 1369 data := sdat[s.Value-sect.Addr:] 1370 floats = make([]float64, len(data)/8) 1371 for i := range floats { 1372 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1373 } 1374 } 1375 } 1376 } 1377 default: 1378 if n := indexOfDebugStr(s.Name); n != -1 { 1379 // Found it. Now find data section. 1380 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1381 sect := f.Sections[i] 1382 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1383 if sdat, err := sect.Data(); err == nil { 1384 data := sdat[s.Value-sect.Addr:] 1385 strdata[n] = string(data) 1386 } 1387 } 1388 } 1389 break 1390 } 1391 if n := indexOfDebugStrlen(s.Name); n != -1 { 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 strlen := bo.Uint64(data[:8]) 1399 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1400 fatalf("string literal too big") 1401 } 1402 strlens[n] = int(strlen) 1403 } 1404 } 1405 } 1406 break 1407 } 1408 } 1409 } 1410 1411 buildStrings() 1412 } 1413 return d, ints, floats, strs 1414 } 1415 1416 if f, err := elf.Open(gccTmp()); err == nil { 1417 defer f.Close() 1418 d, err := f.DWARF() 1419 if err != nil { 1420 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1421 } 1422 bo := f.ByteOrder 1423 symtab, err := f.Symbols() 1424 if err == nil { 1425 for i := range symtab { 1426 s := &symtab[i] 1427 switch { 1428 case isDebugInts(s.Name): 1429 // Found it. Now find data section. 1430 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1431 sect := f.Sections[i] 1432 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1433 if sdat, err := sect.Data(); err == nil { 1434 data := sdat[s.Value-sect.Addr:] 1435 ints = make([]int64, len(data)/8) 1436 for i := range ints { 1437 ints[i] = int64(bo.Uint64(data[i*8:])) 1438 } 1439 } 1440 } 1441 } 1442 case isDebugFloats(s.Name): 1443 // Found it. Now find data section. 1444 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1445 sect := f.Sections[i] 1446 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1447 if sdat, err := sect.Data(); err == nil { 1448 data := sdat[s.Value-sect.Addr:] 1449 floats = make([]float64, len(data)/8) 1450 for i := range floats { 1451 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1452 } 1453 } 1454 } 1455 } 1456 default: 1457 if n := indexOfDebugStr(s.Name); n != -1 { 1458 // Found it. Now find data section. 1459 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1460 sect := f.Sections[i] 1461 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1462 if sdat, err := sect.Data(); err == nil { 1463 data := sdat[s.Value-sect.Addr:] 1464 strdata[n] = string(data) 1465 } 1466 } 1467 } 1468 break 1469 } 1470 if n := indexOfDebugStrlen(s.Name); n != -1 { 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 strlen := bo.Uint64(data[:8]) 1478 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1479 fatalf("string literal too big") 1480 } 1481 strlens[n] = int(strlen) 1482 } 1483 } 1484 } 1485 break 1486 } 1487 } 1488 } 1489 1490 buildStrings() 1491 } 1492 return d, ints, floats, strs 1493 } 1494 1495 if f, err := pe.Open(gccTmp()); err == nil { 1496 defer f.Close() 1497 d, err := f.DWARF() 1498 if err != nil { 1499 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1500 } 1501 bo := binary.LittleEndian 1502 for _, s := range f.Symbols { 1503 switch { 1504 case isDebugInts(s.Name): 1505 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1506 sect := f.Sections[i] 1507 if s.Value < sect.Size { 1508 if sdat, err := sect.Data(); err == nil { 1509 data := sdat[s.Value:] 1510 ints = make([]int64, len(data)/8) 1511 for i := range ints { 1512 ints[i] = int64(bo.Uint64(data[i*8:])) 1513 } 1514 } 1515 } 1516 } 1517 case isDebugFloats(s.Name): 1518 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1519 sect := f.Sections[i] 1520 if s.Value < sect.Size { 1521 if sdat, err := sect.Data(); err == nil { 1522 data := sdat[s.Value:] 1523 floats = make([]float64, len(data)/8) 1524 for i := range floats { 1525 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1526 } 1527 } 1528 } 1529 } 1530 default: 1531 if n := indexOfDebugStr(s.Name); n != -1 { 1532 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1533 sect := f.Sections[i] 1534 if s.Value < sect.Size { 1535 if sdat, err := sect.Data(); err == nil { 1536 data := sdat[s.Value:] 1537 strdata[n] = string(data) 1538 } 1539 } 1540 } 1541 break 1542 } 1543 if n := indexOfDebugStrlen(s.Name); n != -1 { 1544 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1545 sect := f.Sections[i] 1546 if s.Value < sect.Size { 1547 if sdat, err := sect.Data(); err == nil { 1548 data := sdat[s.Value:] 1549 strlen := bo.Uint64(data[:8]) 1550 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1551 fatalf("string literal too big") 1552 } 1553 strlens[n] = int(strlen) 1554 } 1555 } 1556 } 1557 break 1558 } 1559 } 1560 } 1561 1562 buildStrings() 1563 1564 return d, ints, floats, strs 1565 } 1566 1567 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) 1568 panic("not reached") 1569 } 1570 1571 // gccDefines runs gcc -E -dM -xc - over the C program stdin 1572 // and returns the corresponding standard output, which is the 1573 // #defines that gcc encountered while processing the input 1574 // and its included files. 1575 func (p *Package) gccDefines(stdin []byte) string { 1576 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc") 1577 base = append(base, p.gccMachine()...) 1578 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 1579 return stdout 1580 } 1581 1582 // gccErrors runs gcc over the C program stdin and returns 1583 // the errors that gcc prints. That is, this function expects 1584 // gcc to fail. 1585 func (p *Package) gccErrors(stdin []byte) string { 1586 // TODO(rsc): require failure 1587 args := p.gccCmd() 1588 1589 // Optimization options can confuse the error messages; remove them. 1590 nargs := make([]string, 0, len(args)) 1591 for _, arg := range args { 1592 if !strings.HasPrefix(arg, "-O") { 1593 nargs = append(nargs, arg) 1594 } 1595 } 1596 1597 if *debugGcc { 1598 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " ")) 1599 os.Stderr.Write(stdin) 1600 fmt.Fprint(os.Stderr, "EOF\n") 1601 } 1602 stdout, stderr, _ := run(stdin, nargs) 1603 if *debugGcc { 1604 os.Stderr.Write(stdout) 1605 os.Stderr.Write(stderr) 1606 } 1607 return string(stderr) 1608 } 1609 1610 // runGcc runs the gcc command line args with stdin on standard input. 1611 // If the command exits with a non-zero exit status, runGcc prints 1612 // details about what was run and exits. 1613 // Otherwise runGcc returns the data written to standard output and standard error. 1614 // Note that for some of the uses we expect useful data back 1615 // on standard error, but for those uses gcc must still exit 0. 1616 func runGcc(stdin []byte, args []string) (string, string) { 1617 if *debugGcc { 1618 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 1619 os.Stderr.Write(stdin) 1620 fmt.Fprint(os.Stderr, "EOF\n") 1621 } 1622 stdout, stderr, ok := run(stdin, args) 1623 if *debugGcc { 1624 os.Stderr.Write(stdout) 1625 os.Stderr.Write(stderr) 1626 } 1627 if !ok { 1628 os.Stderr.Write(stderr) 1629 os.Exit(2) 1630 } 1631 return string(stdout), string(stderr) 1632 } 1633 1634 // A typeConv is a translator from dwarf types to Go types 1635 // with equivalent memory layout. 1636 type typeConv struct { 1637 // Cache of already-translated or in-progress types. 1638 m map[dwarf.Type]*Type 1639 1640 // Map from types to incomplete pointers to those types. 1641 ptrs map[dwarf.Type][]*Type 1642 // Keys of ptrs in insertion order (deterministic worklist) 1643 ptrKeys []dwarf.Type 1644 1645 // Predeclared types. 1646 bool ast.Expr 1647 byte ast.Expr // denotes padding 1648 int8, int16, int32, int64 ast.Expr 1649 uint8, uint16, uint32, uint64, uintptr ast.Expr 1650 float32, float64 ast.Expr 1651 complex64, complex128 ast.Expr 1652 void ast.Expr 1653 string ast.Expr 1654 goVoid ast.Expr // _Ctype_void, denotes C's void 1655 goVoidPtr ast.Expr // unsafe.Pointer or *byte 1656 1657 ptrSize int64 1658 intSize int64 1659 } 1660 1661 var tagGen int 1662 var typedef = make(map[string]*Type) 1663 var goIdent = make(map[string]*ast.Ident) 1664 1665 // unionWithPointer is true for a Go type that represents a C union (or class) 1666 // that may contain a pointer. This is used for cgo pointer checking. 1667 var unionWithPointer = make(map[ast.Expr]bool) 1668 1669 func (c *typeConv) Init(ptrSize, intSize int64) { 1670 c.ptrSize = ptrSize 1671 c.intSize = intSize 1672 c.m = make(map[dwarf.Type]*Type) 1673 c.ptrs = make(map[dwarf.Type][]*Type) 1674 c.bool = c.Ident("bool") 1675 c.byte = c.Ident("byte") 1676 c.int8 = c.Ident("int8") 1677 c.int16 = c.Ident("int16") 1678 c.int32 = c.Ident("int32") 1679 c.int64 = c.Ident("int64") 1680 c.uint8 = c.Ident("uint8") 1681 c.uint16 = c.Ident("uint16") 1682 c.uint32 = c.Ident("uint32") 1683 c.uint64 = c.Ident("uint64") 1684 c.uintptr = c.Ident("uintptr") 1685 c.float32 = c.Ident("float32") 1686 c.float64 = c.Ident("float64") 1687 c.complex64 = c.Ident("complex64") 1688 c.complex128 = c.Ident("complex128") 1689 c.void = c.Ident("void") 1690 c.string = c.Ident("string") 1691 c.goVoid = c.Ident("_Ctype_void") 1692 1693 // Normally cgo translates void* to unsafe.Pointer, 1694 // but for historical reasons -godefs uses *byte instead. 1695 if *godefs { 1696 c.goVoidPtr = &ast.StarExpr{X: c.byte} 1697 } else { 1698 c.goVoidPtr = c.Ident("unsafe.Pointer") 1699 } 1700 } 1701 1702 // base strips away qualifiers and typedefs to get the underlying type 1703 func base(dt dwarf.Type) dwarf.Type { 1704 for { 1705 if d, ok := dt.(*dwarf.QualType); ok { 1706 dt = d.Type 1707 continue 1708 } 1709 if d, ok := dt.(*dwarf.TypedefType); ok { 1710 dt = d.Type 1711 continue 1712 } 1713 break 1714 } 1715 return dt 1716 } 1717 1718 // unqual strips away qualifiers from a DWARF type. 1719 // In general we don't care about top-level qualifiers. 1720 func unqual(dt dwarf.Type) dwarf.Type { 1721 for { 1722 if d, ok := dt.(*dwarf.QualType); ok { 1723 dt = d.Type 1724 } else { 1725 break 1726 } 1727 } 1728 return dt 1729 } 1730 1731 // Map from dwarf text names to aliases we use in package "C". 1732 var dwarfToName = map[string]string{ 1733 "long int": "long", 1734 "long unsigned int": "ulong", 1735 "unsigned int": "uint", 1736 "short unsigned int": "ushort", 1737 "unsigned short": "ushort", // Used by Clang; issue 13129. 1738 "short int": "short", 1739 "long long int": "longlong", 1740 "long long unsigned int": "ulonglong", 1741 "signed char": "schar", 1742 "unsigned char": "uchar", 1743 } 1744 1745 const signedDelta = 64 1746 1747 // String returns the current type representation. Format arguments 1748 // are assembled within this method so that any changes in mutable 1749 // values are taken into account. 1750 func (tr *TypeRepr) String() string { 1751 if len(tr.Repr) == 0 { 1752 return "" 1753 } 1754 if len(tr.FormatArgs) == 0 { 1755 return tr.Repr 1756 } 1757 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 1758 } 1759 1760 // Empty reports whether the result of String would be "". 1761 func (tr *TypeRepr) Empty() bool { 1762 return len(tr.Repr) == 0 1763 } 1764 1765 // Set modifies the type representation. 1766 // If fargs are provided, repr is used as a format for fmt.Sprintf. 1767 // Otherwise, repr is used unprocessed as the type representation. 1768 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 1769 tr.Repr = repr 1770 tr.FormatArgs = fargs 1771 } 1772 1773 // FinishType completes any outstanding type mapping work. 1774 // In particular, it resolves incomplete pointer types. 1775 func (c *typeConv) FinishType(pos token.Pos) { 1776 // Completing one pointer type might produce more to complete. 1777 // Keep looping until they're all done. 1778 for len(c.ptrKeys) > 0 { 1779 dtype := c.ptrKeys[0] 1780 c.ptrKeys = c.ptrKeys[1:] 1781 1782 // Note Type might invalidate c.ptrs[dtype]. 1783 t := c.Type(dtype, pos) 1784 for _, ptr := range c.ptrs[dtype] { 1785 ptr.Go.(*ast.StarExpr).X = t.Go 1786 ptr.C.Set("%s*", t.C) 1787 } 1788 c.ptrs[dtype] = nil // retain the map key 1789 } 1790 } 1791 1792 // Type returns a *Type with the same memory layout as 1793 // dtype when used as the type of a variable or a struct field. 1794 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 1795 if t, ok := c.m[dtype]; ok { 1796 if t.Go == nil { 1797 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 1798 } 1799 return t 1800 } 1801 1802 t := new(Type) 1803 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 1804 t.Align = -1 1805 t.C = &TypeRepr{Repr: dtype.Common().Name} 1806 c.m[dtype] = t 1807 1808 switch dt := dtype.(type) { 1809 default: 1810 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 1811 1812 case *dwarf.AddrType: 1813 if t.Size != c.ptrSize { 1814 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 1815 } 1816 t.Go = c.uintptr 1817 t.Align = t.Size 1818 1819 case *dwarf.ArrayType: 1820 if dt.StrideBitSize > 0 { 1821 // Cannot represent bit-sized elements in Go. 1822 t.Go = c.Opaque(t.Size) 1823 break 1824 } 1825 count := dt.Count 1826 if count == -1 { 1827 // Indicates flexible array member, which Go doesn't support. 1828 // Translate to zero-length array instead. 1829 count = 0 1830 } 1831 sub := c.Type(dt.Type, pos) 1832 t.Align = sub.Align 1833 t.Go = &ast.ArrayType{ 1834 Len: c.intExpr(count), 1835 Elt: sub.Go, 1836 } 1837 // Recalculate t.Size now that we know sub.Size. 1838 t.Size = count * sub.Size 1839 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 1840 1841 case *dwarf.BoolType: 1842 t.Go = c.bool 1843 t.Align = 1 1844 1845 case *dwarf.CharType: 1846 if t.Size != 1 { 1847 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 1848 } 1849 t.Go = c.int8 1850 t.Align = 1 1851 1852 case *dwarf.EnumType: 1853 if t.Align = t.Size; t.Align >= c.ptrSize { 1854 t.Align = c.ptrSize 1855 } 1856 t.C.Set("enum " + dt.EnumName) 1857 signed := 0 1858 t.EnumValues = make(map[string]int64) 1859 for _, ev := range dt.Val { 1860 t.EnumValues[ev.Name] = ev.Val 1861 if ev.Val < 0 { 1862 signed = signedDelta 1863 } 1864 } 1865 switch t.Size + int64(signed) { 1866 default: 1867 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 1868 case 1: 1869 t.Go = c.uint8 1870 case 2: 1871 t.Go = c.uint16 1872 case 4: 1873 t.Go = c.uint32 1874 case 8: 1875 t.Go = c.uint64 1876 case 1 + signedDelta: 1877 t.Go = c.int8 1878 case 2 + signedDelta: 1879 t.Go = c.int16 1880 case 4 + signedDelta: 1881 t.Go = c.int32 1882 case 8 + signedDelta: 1883 t.Go = c.int64 1884 } 1885 1886 case *dwarf.FloatType: 1887 switch t.Size { 1888 default: 1889 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 1890 case 4: 1891 t.Go = c.float32 1892 case 8: 1893 t.Go = c.float64 1894 } 1895 if t.Align = t.Size; t.Align >= c.ptrSize { 1896 t.Align = c.ptrSize 1897 } 1898 1899 case *dwarf.ComplexType: 1900 switch t.Size { 1901 default: 1902 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 1903 case 8: 1904 t.Go = c.complex64 1905 case 16: 1906 t.Go = c.complex128 1907 } 1908 if t.Align = t.Size / 2; t.Align >= c.ptrSize { 1909 t.Align = c.ptrSize 1910 } 1911 1912 case *dwarf.FuncType: 1913 // No attempt at translation: would enable calls 1914 // directly between worlds, but we need to moderate those. 1915 t.Go = c.uintptr 1916 t.Align = c.ptrSize 1917 1918 case *dwarf.IntType: 1919 if dt.BitSize > 0 { 1920 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 1921 } 1922 switch t.Size { 1923 default: 1924 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 1925 case 1: 1926 t.Go = c.int8 1927 case 2: 1928 t.Go = c.int16 1929 case 4: 1930 t.Go = c.int32 1931 case 8: 1932 t.Go = c.int64 1933 case 16: 1934 t.Go = &ast.ArrayType{ 1935 Len: c.intExpr(t.Size), 1936 Elt: c.uint8, 1937 } 1938 } 1939 if t.Align = t.Size; t.Align >= c.ptrSize { 1940 t.Align = c.ptrSize 1941 } 1942 1943 case *dwarf.PtrType: 1944 // Clang doesn't emit DW_AT_byte_size for pointer types. 1945 if t.Size != c.ptrSize && t.Size != -1 { 1946 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype) 1947 } 1948 t.Size = c.ptrSize 1949 t.Align = c.ptrSize 1950 1951 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 1952 t.Go = c.goVoidPtr 1953 t.C.Set("void*") 1954 dq := dt.Type 1955 for { 1956 if d, ok := dq.(*dwarf.QualType); ok { 1957 t.C.Set(d.Qual + " " + t.C.String()) 1958 dq = d.Type 1959 } else { 1960 break 1961 } 1962 } 1963 break 1964 } 1965 1966 // Placeholder initialization; completed in FinishType. 1967 t.Go = &ast.StarExpr{} 1968 t.C.Set("<incomplete>*") 1969 if _, ok := c.ptrs[dt.Type]; !ok { 1970 c.ptrKeys = append(c.ptrKeys, dt.Type) 1971 } 1972 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t) 1973 1974 case *dwarf.QualType: 1975 t1 := c.Type(dt.Type, pos) 1976 t.Size = t1.Size 1977 t.Align = t1.Align 1978 t.Go = t1.Go 1979 if unionWithPointer[t1.Go] { 1980 unionWithPointer[t.Go] = true 1981 } 1982 t.EnumValues = nil 1983 t.Typedef = "" 1984 t.C.Set("%s "+dt.Qual, t1.C) 1985 return t 1986 1987 case *dwarf.StructType: 1988 // Convert to Go struct, being careful about alignment. 1989 // Have to give it a name to simulate C "struct foo" references. 1990 tag := dt.StructName 1991 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 1992 break 1993 } 1994 if tag == "" { 1995 tag = "__" + strconv.Itoa(tagGen) 1996 tagGen++ 1997 } else if t.C.Empty() { 1998 t.C.Set(dt.Kind + " " + tag) 1999 } 2000 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 2001 t.Go = name // publish before recursive calls 2002 goIdent[name.Name] = name 2003 if dt.ByteSize < 0 { 2004 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 2005 // so execute the basic things that the struct case would do 2006 // other than try to determine a Go representation. 2007 tt := *t 2008 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 2009 tt.Go = c.Ident("struct{}") 2010 typedef[name.Name] = &tt 2011 break 2012 } 2013 switch dt.Kind { 2014 case "class", "union": 2015 t.Go = c.Opaque(t.Size) 2016 if c.dwarfHasPointer(dt, pos) { 2017 unionWithPointer[t.Go] = true 2018 } 2019 if t.C.Empty() { 2020 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 2021 } 2022 t.Align = 1 // TODO: should probably base this on field alignment. 2023 typedef[name.Name] = t 2024 case "struct": 2025 g, csyntax, align := c.Struct(dt, pos) 2026 if t.C.Empty() { 2027 t.C.Set(csyntax) 2028 } 2029 t.Align = align 2030 tt := *t 2031 if tag != "" { 2032 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 2033 } 2034 tt.Go = g 2035 typedef[name.Name] = &tt 2036 } 2037 2038 case *dwarf.TypedefType: 2039 // Record typedef for printing. 2040 if dt.Name == "_GoString_" { 2041 // Special C name for Go string type. 2042 // Knows string layout used by compilers: pointer plus length, 2043 // which rounds up to 2 pointers after alignment. 2044 t.Go = c.string 2045 t.Size = c.ptrSize * 2 2046 t.Align = c.ptrSize 2047 break 2048 } 2049 if dt.Name == "_GoBytes_" { 2050 // Special C name for Go []byte type. 2051 // Knows slice layout used by compilers: pointer, length, cap. 2052 t.Go = c.Ident("[]byte") 2053 t.Size = c.ptrSize + 4 + 4 2054 t.Align = c.ptrSize 2055 break 2056 } 2057 name := c.Ident("_Ctype_" + dt.Name) 2058 goIdent[name.Name] = name 2059 sub := c.Type(dt.Type, pos) 2060 if badPointerTypedef(dt) { 2061 // Treat this typedef as a uintptr. 2062 s := *sub 2063 s.Go = c.uintptr 2064 sub = &s 2065 } 2066 t.Go = name 2067 if unionWithPointer[sub.Go] { 2068 unionWithPointer[t.Go] = true 2069 } 2070 t.Size = sub.Size 2071 t.Align = sub.Align 2072 oldType := typedef[name.Name] 2073 if oldType == nil { 2074 tt := *t 2075 tt.Go = sub.Go 2076 typedef[name.Name] = &tt 2077 } 2078 2079 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 2080 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 2081 // with the base type. 2082 // In -godefs mode, do this for all typedefs. 2083 if isStructUnionClass(sub.Go) || *godefs { 2084 t.Go = sub.Go 2085 2086 if isStructUnionClass(sub.Go) { 2087 // Use the typedef name for C code. 2088 typedef[sub.Go.(*ast.Ident).Name].C = t.C 2089 } 2090 2091 // If we've seen this typedef before, and it 2092 // was an anonymous struct/union/class before 2093 // too, use the old definition. 2094 // TODO: it would be safer to only do this if 2095 // we verify that the types are the same. 2096 if oldType != nil && isStructUnionClass(oldType.Go) { 2097 t.Go = oldType.Go 2098 } 2099 } 2100 2101 case *dwarf.UcharType: 2102 if t.Size != 1 { 2103 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 2104 } 2105 t.Go = c.uint8 2106 t.Align = 1 2107 2108 case *dwarf.UintType: 2109 if dt.BitSize > 0 { 2110 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 2111 } 2112 switch t.Size { 2113 default: 2114 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 2115 case 1: 2116 t.Go = c.uint8 2117 case 2: 2118 t.Go = c.uint16 2119 case 4: 2120 t.Go = c.uint32 2121 case 8: 2122 t.Go = c.uint64 2123 case 16: 2124 t.Go = &ast.ArrayType{ 2125 Len: c.intExpr(t.Size), 2126 Elt: c.uint8, 2127 } 2128 } 2129 if t.Align = t.Size; t.Align >= c.ptrSize { 2130 t.Align = c.ptrSize 2131 } 2132 2133 case *dwarf.VoidType: 2134 t.Go = c.goVoid 2135 t.C.Set("void") 2136 t.Align = 1 2137 } 2138 2139 switch dtype.(type) { 2140 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 2141 s := dtype.Common().Name 2142 if s != "" { 2143 if ss, ok := dwarfToName[s]; ok { 2144 s = ss 2145 } 2146 s = strings.Replace(s, " ", "", -1) 2147 name := c.Ident("_Ctype_" + s) 2148 tt := *t 2149 typedef[name.Name] = &tt 2150 if !*godefs { 2151 t.Go = name 2152 } 2153 } 2154 } 2155 2156 if t.Size < 0 { 2157 // Unsized types are [0]byte, unless they're typedefs of other types 2158 // or structs with tags. 2159 // if so, use the name we've already defined. 2160 t.Size = 0 2161 switch dt := dtype.(type) { 2162 case *dwarf.TypedefType: 2163 // ok 2164 case *dwarf.StructType: 2165 if dt.StructName != "" { 2166 break 2167 } 2168 t.Go = c.Opaque(0) 2169 default: 2170 t.Go = c.Opaque(0) 2171 } 2172 if t.C.Empty() { 2173 t.C.Set("void") 2174 } 2175 } 2176 2177 if t.C.Empty() { 2178 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 2179 } 2180 2181 return t 2182 } 2183 2184 // isStructUnionClass reports whether the type described by the Go syntax x 2185 // is a struct, union, or class with a tag. 2186 func isStructUnionClass(x ast.Expr) bool { 2187 id, ok := x.(*ast.Ident) 2188 if !ok { 2189 return false 2190 } 2191 name := id.Name 2192 return strings.HasPrefix(name, "_Ctype_struct_") || 2193 strings.HasPrefix(name, "_Ctype_union_") || 2194 strings.HasPrefix(name, "_Ctype_class_") 2195 } 2196 2197 // FuncArg returns a Go type with the same memory layout as 2198 // dtype when used as the type of a C function argument. 2199 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 2200 t := c.Type(unqual(dtype), pos) 2201 switch dt := dtype.(type) { 2202 case *dwarf.ArrayType: 2203 // Arrays are passed implicitly as pointers in C. 2204 // In Go, we must be explicit. 2205 tr := &TypeRepr{} 2206 tr.Set("%s*", t.C) 2207 return &Type{ 2208 Size: c.ptrSize, 2209 Align: c.ptrSize, 2210 Go: &ast.StarExpr{X: t.Go}, 2211 C: tr, 2212 } 2213 case *dwarf.TypedefType: 2214 // C has much more relaxed rules than Go for 2215 // implicit type conversions. When the parameter 2216 // is type T defined as *X, simulate a little of the 2217 // laxness of C by making the argument *X instead of T. 2218 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 2219 // Unless the typedef happens to point to void* since 2220 // Go has special rules around using unsafe.Pointer. 2221 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 2222 break 2223 } 2224 // ...or the typedef is one in which we expect bad pointers. 2225 // It will be a uintptr instead of *X. 2226 if badPointerTypedef(dt) { 2227 break 2228 } 2229 2230 // If we already know the typedef for t just use that. 2231 // See issue 19832. 2232 if def := typedef[t.Go.(*ast.Ident).Name]; def != nil { 2233 break 2234 } 2235 2236 t = c.Type(ptr, pos) 2237 if t == nil { 2238 return nil 2239 } 2240 2241 // For a struct/union/class, remember the C spelling, 2242 // in case it has __attribute__((unavailable)). 2243 // See issue 2888. 2244 if isStructUnionClass(t.Go) { 2245 t.Typedef = dt.Name 2246 } 2247 } 2248 } 2249 return t 2250 } 2251 2252 // FuncType returns the Go type analogous to dtype. 2253 // There is no guarantee about matching memory layout. 2254 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 2255 p := make([]*Type, len(dtype.ParamType)) 2256 gp := make([]*ast.Field, len(dtype.ParamType)) 2257 for i, f := range dtype.ParamType { 2258 // gcc's DWARF generator outputs a single DotDotDotType parameter for 2259 // function pointers that specify no parameters (e.g. void 2260 // (*__cgo_0)()). Treat this special case as void. This case is 2261 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 2262 // legal). 2263 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 2264 p, gp = nil, nil 2265 break 2266 } 2267 p[i] = c.FuncArg(f, pos) 2268 gp[i] = &ast.Field{Type: p[i].Go} 2269 } 2270 var r *Type 2271 var gr []*ast.Field 2272 if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok { 2273 gr = []*ast.Field{{Type: c.goVoid}} 2274 } else if dtype.ReturnType != nil { 2275 r = c.Type(unqual(dtype.ReturnType), pos) 2276 gr = []*ast.Field{{Type: r.Go}} 2277 } 2278 return &FuncType{ 2279 Params: p, 2280 Result: r, 2281 Go: &ast.FuncType{ 2282 Params: &ast.FieldList{List: gp}, 2283 Results: &ast.FieldList{List: gr}, 2284 }, 2285 } 2286 } 2287 2288 // Identifier 2289 func (c *typeConv) Ident(s string) *ast.Ident { 2290 return ast.NewIdent(s) 2291 } 2292 2293 // Opaque type of n bytes. 2294 func (c *typeConv) Opaque(n int64) ast.Expr { 2295 return &ast.ArrayType{ 2296 Len: c.intExpr(n), 2297 Elt: c.byte, 2298 } 2299 } 2300 2301 // Expr for integer n. 2302 func (c *typeConv) intExpr(n int64) ast.Expr { 2303 return &ast.BasicLit{ 2304 Kind: token.INT, 2305 Value: strconv.FormatInt(n, 10), 2306 } 2307 } 2308 2309 // Add padding of given size to fld. 2310 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) { 2311 n := len(fld) 2312 fld = fld[0 : n+1] 2313 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 2314 sizes = sizes[0 : n+1] 2315 sizes[n] = size 2316 return fld, sizes 2317 } 2318 2319 // Struct conversion: return Go and (gc) C syntax for type. 2320 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 2321 // Minimum alignment for a struct is 1 byte. 2322 align = 1 2323 2324 var buf bytes.Buffer 2325 buf.WriteString("struct {") 2326 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 2327 sizes := make([]int64, 0, 2*len(dt.Field)+1) 2328 off := int64(0) 2329 2330 // Rename struct fields that happen to be named Go keywords into 2331 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 2332 // be mangled. Any existing identifier that already has the same name on 2333 // the C-side will cause the Go-mangled version to be prefixed with _. 2334 // (e.g. in a struct with fields '_type' and 'type', the latter would be 2335 // rendered as '__type' in Go). 2336 ident := make(map[string]string) 2337 used := make(map[string]bool) 2338 for _, f := range dt.Field { 2339 ident[f.Name] = f.Name 2340 used[f.Name] = true 2341 } 2342 2343 if !*godefs { 2344 for cid, goid := range ident { 2345 if token.Lookup(goid).IsKeyword() { 2346 // Avoid keyword 2347 goid = "_" + goid 2348 2349 // Also avoid existing fields 2350 for _, exist := used[goid]; exist; _, exist = used[goid] { 2351 goid = "_" + goid 2352 } 2353 2354 used[goid] = true 2355 ident[cid] = goid 2356 } 2357 } 2358 } 2359 2360 anon := 0 2361 for _, f := range dt.Field { 2362 if f.ByteOffset > off { 2363 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off) 2364 off = f.ByteOffset 2365 } 2366 2367 name := f.Name 2368 ft := f.Type 2369 2370 // In godefs mode, if this field is a C11 2371 // anonymous union then treat the first field in the 2372 // union as the field in the struct. This handles 2373 // cases like the glibc <sys/resource.h> file; see 2374 // issue 6677. 2375 if *godefs { 2376 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] { 2377 name = st.Field[0].Name 2378 ident[name] = name 2379 ft = st.Field[0].Type 2380 } 2381 } 2382 2383 // TODO: Handle fields that are anonymous structs by 2384 // promoting the fields of the inner struct. 2385 2386 t := c.Type(ft, pos) 2387 tgo := t.Go 2388 size := t.Size 2389 talign := t.Align 2390 if f.BitSize > 0 { 2391 switch f.BitSize { 2392 case 8, 16, 32, 64: 2393 default: 2394 continue 2395 } 2396 size = f.BitSize / 8 2397 name := tgo.(*ast.Ident).String() 2398 if strings.HasPrefix(name, "int") { 2399 name = "int" 2400 } else { 2401 name = "uint" 2402 } 2403 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) 2404 talign = size 2405 } 2406 2407 if talign > 0 && f.ByteOffset%talign != 0 { 2408 // Drop misaligned fields, the same way we drop integer bit fields. 2409 // The goal is to make available what can be made available. 2410 // Otherwise one bad and unneeded field in an otherwise okay struct 2411 // makes the whole program not compile. Much of the time these 2412 // structs are in system headers that cannot be corrected. 2413 continue 2414 } 2415 n := len(fld) 2416 fld = fld[0 : n+1] 2417 if name == "" { 2418 name = fmt.Sprintf("anon%d", anon) 2419 anon++ 2420 ident[name] = name 2421 } 2422 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 2423 sizes = sizes[0 : n+1] 2424 sizes[n] = size 2425 off += size 2426 buf.WriteString(t.C.String()) 2427 buf.WriteString(" ") 2428 buf.WriteString(name) 2429 buf.WriteString("; ") 2430 if talign > align { 2431 align = talign 2432 } 2433 } 2434 if off < dt.ByteSize { 2435 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off) 2436 off = dt.ByteSize 2437 } 2438 2439 // If the last field in a non-zero-sized struct is zero-sized 2440 // the compiler is going to pad it by one (see issue 9401). 2441 // We can't permit that, because then the size of the Go 2442 // struct will not be the same as the size of the C struct. 2443 // Our only option in such a case is to remove the field, 2444 // which means that it cannot be referenced from Go. 2445 for off > 0 && sizes[len(sizes)-1] == 0 { 2446 n := len(sizes) 2447 fld = fld[0 : n-1] 2448 sizes = sizes[0 : n-1] 2449 } 2450 2451 if off != dt.ByteSize { 2452 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 2453 } 2454 buf.WriteString("}") 2455 csyntax = buf.String() 2456 2457 if *godefs { 2458 godefsFields(fld) 2459 } 2460 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 2461 return 2462 } 2463 2464 // dwarfHasPointer returns whether the DWARF type dt contains a pointer. 2465 func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool { 2466 switch dt := dt.(type) { 2467 default: 2468 fatalf("%s: unexpected type: %s", lineno(pos), dt) 2469 return false 2470 2471 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType, 2472 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType, 2473 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType: 2474 2475 return false 2476 2477 case *dwarf.ArrayType: 2478 return c.dwarfHasPointer(dt.Type, pos) 2479 2480 case *dwarf.PtrType: 2481 return true 2482 2483 case *dwarf.QualType: 2484 return c.dwarfHasPointer(dt.Type, pos) 2485 2486 case *dwarf.StructType: 2487 for _, f := range dt.Field { 2488 if c.dwarfHasPointer(f.Type, pos) { 2489 return true 2490 } 2491 } 2492 return false 2493 2494 case *dwarf.TypedefType: 2495 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" { 2496 return true 2497 } 2498 return c.dwarfHasPointer(dt.Type, pos) 2499 } 2500 } 2501 2502 func upper(s string) string { 2503 if s == "" { 2504 return "" 2505 } 2506 r, size := utf8.DecodeRuneInString(s) 2507 if r == '_' { 2508 return "X" + s 2509 } 2510 return string(unicode.ToUpper(r)) + s[size:] 2511 } 2512 2513 // godefsFields rewrites field names for use in Go or C definitions. 2514 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 2515 // converts names to upper case, and rewrites _ into Pad_godefs_n, 2516 // so that all fields are exported. 2517 func godefsFields(fld []*ast.Field) { 2518 prefix := fieldPrefix(fld) 2519 npad := 0 2520 for _, f := range fld { 2521 for _, n := range f.Names { 2522 if n.Name != prefix { 2523 n.Name = strings.TrimPrefix(n.Name, prefix) 2524 } 2525 if n.Name == "_" { 2526 // Use exported name instead. 2527 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 2528 npad++ 2529 } 2530 n.Name = upper(n.Name) 2531 } 2532 } 2533 } 2534 2535 // fieldPrefix returns the prefix that should be removed from all the 2536 // field names when generating the C or Go code. For generated 2537 // C, we leave the names as is (tv_sec, tv_usec), since that's what 2538 // people are used to seeing in C. For generated Go code, such as 2539 // package syscall's data structures, we drop a common prefix 2540 // (so sec, usec, which will get turned into Sec, Usec for exporting). 2541 func fieldPrefix(fld []*ast.Field) string { 2542 prefix := "" 2543 for _, f := range fld { 2544 for _, n := range f.Names { 2545 // Ignore field names that don't have the prefix we're 2546 // looking for. It is common in C headers to have fields 2547 // named, say, _pad in an otherwise prefixed header. 2548 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 2549 // still want to remove the tv_ prefix. 2550 // The check for "orig_" here handles orig_eax in the 2551 // x86 ptrace register sets, which otherwise have all fields 2552 // with reg_ prefixes. 2553 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 2554 continue 2555 } 2556 i := strings.Index(n.Name, "_") 2557 if i < 0 { 2558 continue 2559 } 2560 if prefix == "" { 2561 prefix = n.Name[:i+1] 2562 } else if prefix != n.Name[:i+1] { 2563 return "" 2564 } 2565 } 2566 } 2567 return prefix 2568 } 2569 2570 // badPointerTypedef reports whether t is a C typedef that should not be considered a pointer in Go. 2571 // A typedef is bad if C code sometimes stores non-pointers in this type. 2572 // TODO: Currently our best solution is to find these manually and list them as 2573 // they come up. A better solution is desired. 2574 func badPointerTypedef(dt *dwarf.TypedefType) bool { 2575 if badCFType(dt) { 2576 return true 2577 } 2578 if badJNI(dt) { 2579 return true 2580 } 2581 return false 2582 } 2583 2584 func badCFType(dt *dwarf.TypedefType) bool { 2585 // The real bad types are CFNumberRef and CFDateRef. 2586 // Sometimes non-pointers are stored in these types. 2587 // CFTypeRef is a supertype of those, so it can have bad pointers in it as well. 2588 // We return true for the other CF*Ref types just so casting between them is easier. 2589 // See comment below for details about the bad pointers. 2590 return goos == "darwin" && strings.HasPrefix(dt.Name, "CF") && strings.HasSuffix(dt.Name, "Ref") 2591 } 2592 2593 // Comment from Darwin's CFInternal.h 2594 /* 2595 // Tagged pointer support 2596 // Low-bit set means tagged object, next 3 bits (currently) 2597 // define the tagged object class, next 4 bits are for type 2598 // information for the specific tagged object class. Thus, 2599 // the low byte is for type info, and the rest of a pointer 2600 // (32 or 64-bit) is for payload, whatever the tagged class. 2601 // 2602 // Note that the specific integers used to identify the 2603 // specific tagged classes can and will change from release 2604 // to release (that's why this stuff is in CF*Internal*.h), 2605 // as can the definition of type info vs payload above. 2606 // 2607 #if __LP64__ 2608 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1) 2609 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF) 2610 #else 2611 #define CF_IS_TAGGED_OBJ(PTR) 0 2612 #define CF_TAGGED_OBJ_TYPE(PTR) 0 2613 #endif 2614 2615 enum { 2616 kCFTaggedObjectID_Invalid = 0, 2617 kCFTaggedObjectID_Atom = (0 << 1) + 1, 2618 kCFTaggedObjectID_Undefined3 = (1 << 1) + 1, 2619 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1, 2620 kCFTaggedObjectID_Integer = (3 << 1) + 1, 2621 kCFTaggedObjectID_DateTS = (4 << 1) + 1, 2622 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data 2623 kCFTaggedObjectID_Date = (6 << 1) + 1, 2624 kCFTaggedObjectID_Undefined7 = (7 << 1) + 1, 2625 }; 2626 */ 2627 2628 func badJNI(dt *dwarf.TypedefType) bool { 2629 // In Dalvik and ART, the jobject type in the JNI interface of the JVM has the 2630 // property that it is sometimes (always?) a small integer instead of a real pointer. 2631 // Note: although only the android JVMs are bad in this respect, we declare the JNI types 2632 // bad regardless of platform, so the same Go code compiles on both android and non-android. 2633 if parent, ok := jniTypes[dt.Name]; ok { 2634 // Try to make sure we're talking about a JNI type, not just some random user's 2635 // type that happens to use the same name. 2636 // C doesn't have the notion of a package, so it's hard to be certain. 2637 2638 // Walk up to jobject, checking each typedef on the way. 2639 w := dt 2640 for parent != "" { 2641 t, ok := w.Type.(*dwarf.TypedefType) 2642 if !ok || t.Name != parent { 2643 return false 2644 } 2645 w = t 2646 parent, ok = jniTypes[w.Name] 2647 if !ok { 2648 return false 2649 } 2650 } 2651 2652 // Check that the typedef is: 2653 // struct _jobject; 2654 // typedef struct _jobject *jobject; 2655 if ptr, ok := w.Type.(*dwarf.PtrType); ok { 2656 if str, ok := ptr.Type.(*dwarf.StructType); ok { 2657 if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete { 2658 return true 2659 } 2660 } 2661 } 2662 } 2663 return false 2664 } 2665 2666 // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which 2667 // they are mapped. The base "jobject" maps to the empty string. 2668 var jniTypes = map[string]string{ 2669 "jobject": "", 2670 "jclass": "jobject", 2671 "jthrowable": "jobject", 2672 "jstring": "jobject", 2673 "jarray": "jobject", 2674 "jbooleanArray": "jarray", 2675 "jbyteArray": "jarray", 2676 "jcharArray": "jarray", 2677 "jshortArray": "jarray", 2678 "jintArray": "jarray", 2679 "jlongArray": "jarray", 2680 "jfloatArray": "jarray", 2681 "jdoubleArray": "jarray", 2682 "jobjectArray": "jarray", 2683 "jweak": "jobject", 2684 }