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