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