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