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