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