github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/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 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 var fbody ast.Stmt 717 if name.FuncType.Result == nil { 718 fbody = &ast.ExprStmt{ 719 X: fcall, 720 } 721 } else { 722 fbody = &ast.ReturnStmt{ 723 Results: []ast.Expr{fcall}, 724 } 725 rtype := p.rewriteUnsafe(name.FuncType.Result.Go) 726 if rtype != name.FuncType.Result.Go { 727 needsUnsafe = true 728 } 729 ftype.Results = &ast.FieldList{ 730 List: []*ast.Field{ 731 &ast.Field{ 732 Type: rtype, 733 }, 734 }, 735 } 736 } 737 call.Call.Fun = &ast.FuncLit{ 738 Type: ftype, 739 Body: &ast.BlockStmt{ 740 List: append(stmts, fbody), 741 }, 742 } 743 call.Call.Lparen = token.NoPos 744 call.Call.Rparen = token.NoPos 745 746 // There is a Ref pointing to the old call.Call.Fun. 747 for _, ref := range f.Ref { 748 if ref.Expr == &call.Call.Fun { 749 ref.Expr = &fcall.Fun 750 751 // If this call expects two results, we have to 752 // adjust the results of the function we generated. 753 if ref.Context == "call2" { 754 ftype.Results.List = append(ftype.Results.List, 755 &ast.Field{ 756 Type: ast.NewIdent("error"), 757 }) 758 } 759 } 760 } 761 762 return needsUnsafe 763 } 764 765 // needsPointerCheck returns whether the type t needs a pointer check. 766 // This is true if t is a pointer and if the value to which it points 767 // might contain a pointer. 768 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool { 769 // An untyped nil does not need a pointer check, and when 770 // _cgoCheckPointer returns the untyped nil the type assertion we 771 // are going to insert will fail. Easier to just skip nil arguments. 772 // TODO: Note that this fails if nil is shadowed. 773 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" { 774 return false 775 } 776 777 return p.hasPointer(f, t, true) 778 } 779 780 // hasPointer is used by needsPointerCheck. If top is true it returns 781 // whether t is or contains a pointer that might point to a pointer. 782 // If top is false it returns whether t is or contains a pointer. 783 // f may be nil. 784 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool { 785 switch t := t.(type) { 786 case *ast.ArrayType: 787 if t.Len == nil { 788 if !top { 789 return true 790 } 791 return p.hasPointer(f, t.Elt, false) 792 } 793 return p.hasPointer(f, t.Elt, top) 794 case *ast.StructType: 795 for _, field := range t.Fields.List { 796 if p.hasPointer(f, field.Type, top) { 797 return true 798 } 799 } 800 return false 801 case *ast.StarExpr: // Pointer type. 802 if !top { 803 return true 804 } 805 return p.hasPointer(f, t.X, false) 806 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: 807 return true 808 case *ast.Ident: 809 // TODO: Handle types defined within function. 810 for _, d := range p.Decl { 811 gd, ok := d.(*ast.GenDecl) 812 if !ok || gd.Tok != token.TYPE { 813 continue 814 } 815 for _, spec := range gd.Specs { 816 ts, ok := spec.(*ast.TypeSpec) 817 if !ok { 818 continue 819 } 820 if ts.Name.Name == t.Name { 821 return p.hasPointer(f, ts.Type, top) 822 } 823 } 824 } 825 if def := typedef[t.Name]; def != nil { 826 return p.hasPointer(f, def.Go, top) 827 } 828 if t.Name == "string" { 829 return !top 830 } 831 if t.Name == "error" { 832 return true 833 } 834 if goTypes[t.Name] != nil { 835 return false 836 } 837 // We can't figure out the type. Conservative 838 // approach is to assume it has a pointer. 839 return true 840 case *ast.SelectorExpr: 841 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" { 842 // Type defined in a different package. 843 // Conservative approach is to assume it has a 844 // pointer. 845 return true 846 } 847 if f == nil { 848 // Conservative approach: assume pointer. 849 return true 850 } 851 name := f.Name[t.Sel.Name] 852 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil { 853 return p.hasPointer(f, name.Type.Go, top) 854 } 855 // We can't figure out the type. Conservative 856 // approach is to assume it has a pointer. 857 return true 858 default: 859 error_(t.Pos(), "could not understand type %s", gofmt(t)) 860 return true 861 } 862 } 863 864 // checkAddrArgs tries to add arguments to the call of 865 // _cgoCheckPointer when the argument is an address expression. We 866 // pass true to mean that the argument is an address operation of 867 // something other than a slice index, which means that it's only 868 // necessary to check the specific element pointed to, not the entire 869 // object. This is for &s.f, where f is a field in a struct. We can 870 // pass a slice or array, meaning that we should check the entire 871 // slice or array but need not check any other part of the object. 872 // This is for &s.a[i], where we need to check all of a. However, we 873 // only pass the slice or array if we can refer to it without side 874 // effects. 875 func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr { 876 // Strip type conversions. 877 for { 878 c, ok := x.(*ast.CallExpr) 879 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) { 880 break 881 } 882 x = c.Args[0] 883 } 884 u, ok := x.(*ast.UnaryExpr) 885 if !ok || u.Op != token.AND { 886 return args 887 } 888 index, ok := u.X.(*ast.IndexExpr) 889 if !ok { 890 // This is the address of something that is not an 891 // index expression. We only need to examine the 892 // single value to which it points. 893 // TODO: what if true is shadowed? 894 return append(args, ast.NewIdent("true")) 895 } 896 if !p.hasSideEffects(f, index.X) { 897 // Examine the entire slice. 898 return append(args, index.X) 899 } 900 // Treat the pointer as unknown. 901 return args 902 } 903 904 // hasSideEffects returns whether the expression x has any side 905 // effects. x is an expression, not a statement, so the only side 906 // effect is a function call. 907 func (p *Package) hasSideEffects(f *File, x ast.Expr) bool { 908 found := false 909 f.walk(x, "expr", 910 func(f *File, x interface{}, context string) { 911 switch x.(type) { 912 case *ast.CallExpr: 913 found = true 914 } 915 }) 916 return found 917 } 918 919 // isType returns whether the expression is definitely a type. 920 // This is conservative--it returns false for an unknown identifier. 921 func (p *Package) isType(t ast.Expr) bool { 922 switch t := t.(type) { 923 case *ast.SelectorExpr: 924 id, ok := t.X.(*ast.Ident) 925 if !ok { 926 return false 927 } 928 if id.Name == "unsafe" && t.Sel.Name == "Pointer" { 929 return true 930 } 931 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil { 932 return true 933 } 934 return false 935 case *ast.Ident: 936 // TODO: This ignores shadowing. 937 switch t.Name { 938 case "unsafe.Pointer", "bool", "byte", 939 "complex64", "complex128", 940 "error", 941 "float32", "float64", 942 "int", "int8", "int16", "int32", "int64", 943 "rune", "string", 944 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr": 945 946 return true 947 } 948 case *ast.StarExpr: 949 return p.isType(t.X) 950 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, 951 *ast.MapType, *ast.ChanType: 952 953 return true 954 } 955 return false 956 } 957 958 // rewriteUnsafe returns a version of t with references to unsafe.Pointer 959 // rewritten to use _cgo_unsafe.Pointer instead. 960 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr { 961 switch t := t.(type) { 962 case *ast.Ident: 963 // We don't see a SelectorExpr for unsafe.Pointer; 964 // this is created by code in this file. 965 if t.Name == "unsafe.Pointer" { 966 return ast.NewIdent("_cgo_unsafe.Pointer") 967 } 968 case *ast.ArrayType: 969 t1 := p.rewriteUnsafe(t.Elt) 970 if t1 != t.Elt { 971 r := *t 972 r.Elt = t1 973 return &r 974 } 975 case *ast.StructType: 976 changed := false 977 fields := *t.Fields 978 fields.List = nil 979 for _, f := range t.Fields.List { 980 ft := p.rewriteUnsafe(f.Type) 981 if ft == f.Type { 982 fields.List = append(fields.List, f) 983 } else { 984 fn := *f 985 fn.Type = ft 986 fields.List = append(fields.List, &fn) 987 changed = true 988 } 989 } 990 if changed { 991 r := *t 992 r.Fields = &fields 993 return &r 994 } 995 case *ast.StarExpr: // Pointer type. 996 x1 := p.rewriteUnsafe(t.X) 997 if x1 != t.X { 998 r := *t 999 r.X = x1 1000 return &r 1001 } 1002 } 1003 return t 1004 } 1005 1006 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the 1007 // Go equivalents, now that we have figured out the meaning of all 1008 // the xxx. In *godefs mode, rewriteRef replaces the names 1009 // with full definitions instead of mangled names. 1010 func (p *Package) rewriteRef(f *File) { 1011 // Keep a list of all the functions, to remove the ones 1012 // only used as expressions and avoid generating bridge 1013 // code for them. 1014 functions := make(map[string]bool) 1015 1016 // Assign mangled names. 1017 for _, n := range f.Name { 1018 if n.Kind == "not-type" { 1019 n.Kind = "var" 1020 } 1021 if n.Mangle == "" { 1022 p.mangleName(n) 1023 } 1024 if n.Kind == "func" { 1025 functions[n.Go] = false 1026 } 1027 } 1028 1029 // Now that we have all the name types filled in, 1030 // scan through the Refs to identify the ones that 1031 // are trying to do a ,err call. Also check that 1032 // functions are only used in calls. 1033 for _, r := range f.Ref { 1034 if r.Name.Kind == "const" && r.Name.Const == "" { 1035 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go)) 1036 } 1037 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default 1038 switch r.Context { 1039 case "call", "call2": 1040 if r.Name.Kind != "func" { 1041 if r.Name.Kind == "type" { 1042 r.Context = "type" 1043 if r.Name.Type == nil { 1044 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1045 break 1046 } 1047 expr = r.Name.Type.Go 1048 break 1049 } 1050 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) 1051 break 1052 } 1053 functions[r.Name.Go] = true 1054 if r.Context == "call2" { 1055 if r.Name.Go == "_CMalloc" { 1056 error_(r.Pos(), "no two-result form for C.malloc") 1057 break 1058 } 1059 // Invent new Name for the two-result function. 1060 n := f.Name["2"+r.Name.Go] 1061 if n == nil { 1062 n = new(Name) 1063 *n = *r.Name 1064 n.AddError = true 1065 n.Mangle = "_C2func_" + n.Go 1066 f.Name["2"+r.Name.Go] = n 1067 } 1068 expr = ast.NewIdent(n.Mangle) 1069 r.Name = n 1070 break 1071 } 1072 case "expr": 1073 if r.Name.Kind == "func" { 1074 // Function is being used in an expression, to e.g. pass around a C function pointer. 1075 // Create a new Name for this Ref which causes the variable to be declared in Go land. 1076 fpName := "fp_" + r.Name.Go 1077 name := f.Name[fpName] 1078 if name == nil { 1079 name = &Name{ 1080 Go: fpName, 1081 C: r.Name.C, 1082 Kind: "fpvar", 1083 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")}, 1084 } 1085 p.mangleName(name) 1086 f.Name[fpName] = name 1087 } 1088 r.Name = name 1089 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr 1090 // function is defined in out.go and simply returns its argument. See 1091 // issue 7757. 1092 expr = &ast.CallExpr{ 1093 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"}, 1094 Args: []ast.Expr{ast.NewIdent(name.Mangle)}, 1095 } 1096 } else if r.Name.Kind == "type" { 1097 // Okay - might be new(T) 1098 if r.Name.Type == nil { 1099 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1100 break 1101 } 1102 expr = r.Name.Type.Go 1103 } else if r.Name.Kind == "var" { 1104 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1105 } 1106 1107 case "selector": 1108 if r.Name.Kind == "var" { 1109 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1110 } else { 1111 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go)) 1112 } 1113 1114 case "type": 1115 if r.Name.Kind != "type" { 1116 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 1117 } else if r.Name.Type == nil { 1118 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 1119 // GCC won't raise an error when using pointers to such unknown types. 1120 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1121 } else { 1122 expr = r.Name.Type.Go 1123 } 1124 default: 1125 if r.Name.Kind == "func" { 1126 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 1127 } 1128 } 1129 if *godefs { 1130 // Substitute definition for mangled type name. 1131 if id, ok := expr.(*ast.Ident); ok { 1132 if t := typedef[id.Name]; t != nil { 1133 expr = t.Go 1134 } 1135 if id.Name == r.Name.Mangle && r.Name.Const != "" { 1136 expr = ast.NewIdent(r.Name.Const) 1137 } 1138 } 1139 } 1140 1141 // Copy position information from old expr into new expr, 1142 // in case expression being replaced is first on line. 1143 // See golang.org/issue/6563. 1144 pos := (*r.Expr).Pos() 1145 switch x := expr.(type) { 1146 case *ast.Ident: 1147 expr = &ast.Ident{NamePos: pos, Name: x.Name} 1148 } 1149 1150 *r.Expr = expr 1151 } 1152 1153 // Remove functions only used as expressions, so their respective 1154 // bridge functions are not generated. 1155 for name, used := range functions { 1156 if !used { 1157 delete(f.Name, name) 1158 } 1159 } 1160 } 1161 1162 // gccBaseCmd returns the start of the compiler command line. 1163 // It uses $CC if set, or else $GCC, or else the compiler recorded 1164 // during the initial build as defaultCC. 1165 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 1166 func (p *Package) gccBaseCmd() []string { 1167 // Use $CC if set, since that's what the build uses. 1168 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 { 1169 return ret 1170 } 1171 // Try $GCC if set, since that's what we used to use. 1172 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 { 1173 return ret 1174 } 1175 return strings.Fields(defaultCC) 1176 } 1177 1178 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 1179 func (p *Package) gccMachine() []string { 1180 switch goarch { 1181 case "amd64": 1182 return []string{"-m64"} 1183 case "386": 1184 return []string{"-m32"} 1185 case "arm": 1186 return []string{"-marm"} // not thumb 1187 case "s390": 1188 return []string{"-m31"} 1189 case "s390x": 1190 return []string{"-m64"} 1191 case "mips64", "mips64le": 1192 return []string{"-mabi=64"} 1193 } 1194 return nil 1195 } 1196 1197 func gccTmp() string { 1198 return *objDir + "_cgo_.o" 1199 } 1200 1201 // gccCmd returns the gcc command line to use for compiling 1202 // the input. 1203 func (p *Package) gccCmd() []string { 1204 c := append(p.gccBaseCmd(), 1205 "-w", // no warnings 1206 "-Wno-error", // warnings are not errors 1207 "-o"+gccTmp(), // write object to tmp 1208 "-gdwarf-2", // generate DWARF v2 debugging symbols 1209 "-c", // do not link 1210 "-xc", // input language is C 1211 ) 1212 if p.GccIsClang { 1213 c = append(c, 1214 "-ferror-limit=0", 1215 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 1216 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 1217 // flag to disable the warning. Yes, really good diagnostics, clang. 1218 "-Wno-unknown-warning-option", 1219 "-Wno-unneeded-internal-declaration", 1220 "-Wno-unused-function", 1221 "-Qunused-arguments", 1222 // Clang embeds prototypes for some builtin functions, 1223 // like malloc and calloc, but all size_t parameters are 1224 // incorrectly typed unsigned long. We work around that 1225 // by disabling the builtin functions (this is safe as 1226 // it won't affect the actual compilation of the C code). 1227 // See: https://golang.org/issue/6506. 1228 "-fno-builtin", 1229 ) 1230 } 1231 1232 c = append(c, p.GccOptions...) 1233 c = append(c, p.gccMachine()...) 1234 c = append(c, "-") //read input from standard input 1235 return c 1236 } 1237 1238 // gccDebug runs gcc -gdwarf-2 over the C program stdin and 1239 // returns the corresponding DWARF data and, if present, debug data block. 1240 func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) { 1241 runGcc(stdin, p.gccCmd()) 1242 1243 isDebugData := func(s string) bool { 1244 // Some systems use leading _ to denote non-assembly symbols. 1245 return s == "__cgodebug_data" || s == "___cgodebug_data" 1246 } 1247 1248 if f, err := macho.Open(gccTmp()); err == nil { 1249 defer f.Close() 1250 d, err := f.DWARF() 1251 if err != nil { 1252 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1253 } 1254 var data []byte 1255 if f.Symtab != nil { 1256 for i := range f.Symtab.Syms { 1257 s := &f.Symtab.Syms[i] 1258 if isDebugData(s.Name) { 1259 // Found it. Now find data section. 1260 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1261 sect := f.Sections[i] 1262 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1263 if sdat, err := sect.Data(); err == nil { 1264 data = sdat[s.Value-sect.Addr:] 1265 } 1266 } 1267 } 1268 } 1269 } 1270 } 1271 return d, f.ByteOrder, data 1272 } 1273 1274 if f, err := elf.Open(gccTmp()); err == nil { 1275 defer f.Close() 1276 d, err := f.DWARF() 1277 if err != nil { 1278 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1279 } 1280 var data []byte 1281 symtab, err := f.Symbols() 1282 if err == nil { 1283 for i := range symtab { 1284 s := &symtab[i] 1285 if isDebugData(s.Name) { 1286 // Found it. Now find data section. 1287 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1288 sect := f.Sections[i] 1289 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1290 if sdat, err := sect.Data(); err == nil { 1291 data = sdat[s.Value-sect.Addr:] 1292 } 1293 } 1294 } 1295 } 1296 } 1297 } 1298 return d, f.ByteOrder, data 1299 } 1300 1301 if f, err := pe.Open(gccTmp()); err == nil { 1302 defer f.Close() 1303 d, err := f.DWARF() 1304 if err != nil { 1305 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1306 } 1307 var data []byte 1308 for _, s := range f.Symbols { 1309 if isDebugData(s.Name) { 1310 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1311 sect := f.Sections[i] 1312 if s.Value < sect.Size { 1313 if sdat, err := sect.Data(); err == nil { 1314 data = sdat[s.Value:] 1315 } 1316 } 1317 } 1318 } 1319 } 1320 return d, binary.LittleEndian, data 1321 } 1322 1323 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) 1324 panic("not reached") 1325 } 1326 1327 // gccDefines runs gcc -E -dM -xc - over the C program stdin 1328 // and returns the corresponding standard output, which is the 1329 // #defines that gcc encountered while processing the input 1330 // and its included files. 1331 func (p *Package) gccDefines(stdin []byte) string { 1332 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc") 1333 base = append(base, p.gccMachine()...) 1334 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 1335 return stdout 1336 } 1337 1338 // gccErrors runs gcc over the C program stdin and returns 1339 // the errors that gcc prints. That is, this function expects 1340 // gcc to fail. 1341 func (p *Package) gccErrors(stdin []byte) string { 1342 // TODO(rsc): require failure 1343 args := p.gccCmd() 1344 1345 // Optimization options can confuse the error messages; remove them. 1346 nargs := make([]string, 0, len(args)) 1347 for _, arg := range args { 1348 if !strings.HasPrefix(arg, "-O") { 1349 nargs = append(nargs, arg) 1350 } 1351 } 1352 1353 if *debugGcc { 1354 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " ")) 1355 os.Stderr.Write(stdin) 1356 fmt.Fprint(os.Stderr, "EOF\n") 1357 } 1358 stdout, stderr, _ := run(stdin, nargs) 1359 if *debugGcc { 1360 os.Stderr.Write(stdout) 1361 os.Stderr.Write(stderr) 1362 } 1363 return string(stderr) 1364 } 1365 1366 // runGcc runs the gcc command line args with stdin on standard input. 1367 // If the command exits with a non-zero exit status, runGcc prints 1368 // details about what was run and exits. 1369 // Otherwise runGcc returns the data written to standard output and standard error. 1370 // Note that for some of the uses we expect useful data back 1371 // on standard error, but for those uses gcc must still exit 0. 1372 func runGcc(stdin []byte, args []string) (string, string) { 1373 if *debugGcc { 1374 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 1375 os.Stderr.Write(stdin) 1376 fmt.Fprint(os.Stderr, "EOF\n") 1377 } 1378 stdout, stderr, ok := run(stdin, args) 1379 if *debugGcc { 1380 os.Stderr.Write(stdout) 1381 os.Stderr.Write(stderr) 1382 } 1383 if !ok { 1384 os.Stderr.Write(stderr) 1385 os.Exit(2) 1386 } 1387 return string(stdout), string(stderr) 1388 } 1389 1390 // A typeConv is a translator from dwarf types to Go types 1391 // with equivalent memory layout. 1392 type typeConv struct { 1393 // Cache of already-translated or in-progress types. 1394 m map[dwarf.Type]*Type 1395 1396 // Map from types to incomplete pointers to those types. 1397 ptrs map[dwarf.Type][]*Type 1398 // Keys of ptrs in insertion order (deterministic worklist) 1399 ptrKeys []dwarf.Type 1400 1401 // Predeclared types. 1402 bool ast.Expr 1403 byte ast.Expr // denotes padding 1404 int8, int16, int32, int64 ast.Expr 1405 uint8, uint16, uint32, uint64, uintptr ast.Expr 1406 float32, float64 ast.Expr 1407 complex64, complex128 ast.Expr 1408 void ast.Expr 1409 string ast.Expr 1410 goVoid ast.Expr // _Ctype_void, denotes C's void 1411 goVoidPtr ast.Expr // unsafe.Pointer or *byte 1412 1413 ptrSize int64 1414 intSize int64 1415 } 1416 1417 var tagGen int 1418 var typedef = make(map[string]*Type) 1419 var goIdent = make(map[string]*ast.Ident) 1420 1421 func (c *typeConv) Init(ptrSize, intSize int64) { 1422 c.ptrSize = ptrSize 1423 c.intSize = intSize 1424 c.m = make(map[dwarf.Type]*Type) 1425 c.ptrs = make(map[dwarf.Type][]*Type) 1426 c.bool = c.Ident("bool") 1427 c.byte = c.Ident("byte") 1428 c.int8 = c.Ident("int8") 1429 c.int16 = c.Ident("int16") 1430 c.int32 = c.Ident("int32") 1431 c.int64 = c.Ident("int64") 1432 c.uint8 = c.Ident("uint8") 1433 c.uint16 = c.Ident("uint16") 1434 c.uint32 = c.Ident("uint32") 1435 c.uint64 = c.Ident("uint64") 1436 c.uintptr = c.Ident("uintptr") 1437 c.float32 = c.Ident("float32") 1438 c.float64 = c.Ident("float64") 1439 c.complex64 = c.Ident("complex64") 1440 c.complex128 = c.Ident("complex128") 1441 c.void = c.Ident("void") 1442 c.string = c.Ident("string") 1443 c.goVoid = c.Ident("_Ctype_void") 1444 1445 // Normally cgo translates void* to unsafe.Pointer, 1446 // but for historical reasons -godefs uses *byte instead. 1447 if *godefs { 1448 c.goVoidPtr = &ast.StarExpr{X: c.byte} 1449 } else { 1450 c.goVoidPtr = c.Ident("unsafe.Pointer") 1451 } 1452 } 1453 1454 // base strips away qualifiers and typedefs to get the underlying type 1455 func base(dt dwarf.Type) dwarf.Type { 1456 for { 1457 if d, ok := dt.(*dwarf.QualType); ok { 1458 dt = d.Type 1459 continue 1460 } 1461 if d, ok := dt.(*dwarf.TypedefType); ok { 1462 dt = d.Type 1463 continue 1464 } 1465 break 1466 } 1467 return dt 1468 } 1469 1470 // Map from dwarf text names to aliases we use in package "C". 1471 var dwarfToName = map[string]string{ 1472 "long int": "long", 1473 "long unsigned int": "ulong", 1474 "unsigned int": "uint", 1475 "short unsigned int": "ushort", 1476 "unsigned short": "ushort", // Used by Clang; issue 13129. 1477 "short int": "short", 1478 "long long int": "longlong", 1479 "long long unsigned int": "ulonglong", 1480 "signed char": "schar", 1481 "unsigned char": "uchar", 1482 } 1483 1484 const signedDelta = 64 1485 1486 // String returns the current type representation. Format arguments 1487 // are assembled within this method so that any changes in mutable 1488 // values are taken into account. 1489 func (tr *TypeRepr) String() string { 1490 if len(tr.Repr) == 0 { 1491 return "" 1492 } 1493 if len(tr.FormatArgs) == 0 { 1494 return tr.Repr 1495 } 1496 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 1497 } 1498 1499 // Empty reports whether the result of String would be "". 1500 func (tr *TypeRepr) Empty() bool { 1501 return len(tr.Repr) == 0 1502 } 1503 1504 // Set modifies the type representation. 1505 // If fargs are provided, repr is used as a format for fmt.Sprintf. 1506 // Otherwise, repr is used unprocessed as the type representation. 1507 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 1508 tr.Repr = repr 1509 tr.FormatArgs = fargs 1510 } 1511 1512 // FinishType completes any outstanding type mapping work. 1513 // In particular, it resolves incomplete pointer types. 1514 func (c *typeConv) FinishType(pos token.Pos) { 1515 // Completing one pointer type might produce more to complete. 1516 // Keep looping until they're all done. 1517 for len(c.ptrKeys) > 0 { 1518 dtype := c.ptrKeys[0] 1519 c.ptrKeys = c.ptrKeys[1:] 1520 1521 // Note Type might invalidate c.ptrs[dtype]. 1522 t := c.Type(dtype, pos) 1523 for _, ptr := range c.ptrs[dtype] { 1524 ptr.Go.(*ast.StarExpr).X = t.Go 1525 ptr.C.Set("%s*", t.C) 1526 } 1527 c.ptrs[dtype] = nil // retain the map key 1528 } 1529 } 1530 1531 // Type returns a *Type with the same memory layout as 1532 // dtype when used as the type of a variable or a struct field. 1533 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 1534 if t, ok := c.m[dtype]; ok { 1535 if t.Go == nil { 1536 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 1537 } 1538 return t 1539 } 1540 1541 t := new(Type) 1542 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 1543 t.Align = -1 1544 t.C = &TypeRepr{Repr: dtype.Common().Name} 1545 c.m[dtype] = t 1546 1547 switch dt := dtype.(type) { 1548 default: 1549 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 1550 1551 case *dwarf.AddrType: 1552 if t.Size != c.ptrSize { 1553 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 1554 } 1555 t.Go = c.uintptr 1556 t.Align = t.Size 1557 1558 case *dwarf.ArrayType: 1559 if dt.StrideBitSize > 0 { 1560 // Cannot represent bit-sized elements in Go. 1561 t.Go = c.Opaque(t.Size) 1562 break 1563 } 1564 count := dt.Count 1565 if count == -1 { 1566 // Indicates flexible array member, which Go doesn't support. 1567 // Translate to zero-length array instead. 1568 count = 0 1569 } 1570 sub := c.Type(dt.Type, pos) 1571 t.Align = sub.Align 1572 t.Go = &ast.ArrayType{ 1573 Len: c.intExpr(count), 1574 Elt: sub.Go, 1575 } 1576 // Recalculate t.Size now that we know sub.Size. 1577 t.Size = count * sub.Size 1578 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 1579 1580 case *dwarf.BoolType: 1581 t.Go = c.bool 1582 t.Align = 1 1583 1584 case *dwarf.CharType: 1585 if t.Size != 1 { 1586 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 1587 } 1588 t.Go = c.int8 1589 t.Align = 1 1590 1591 case *dwarf.EnumType: 1592 if t.Align = t.Size; t.Align >= c.ptrSize { 1593 t.Align = c.ptrSize 1594 } 1595 t.C.Set("enum " + dt.EnumName) 1596 signed := 0 1597 t.EnumValues = make(map[string]int64) 1598 for _, ev := range dt.Val { 1599 t.EnumValues[ev.Name] = ev.Val 1600 if ev.Val < 0 { 1601 signed = signedDelta 1602 } 1603 } 1604 switch t.Size + int64(signed) { 1605 default: 1606 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 1607 case 1: 1608 t.Go = c.uint8 1609 case 2: 1610 t.Go = c.uint16 1611 case 4: 1612 t.Go = c.uint32 1613 case 8: 1614 t.Go = c.uint64 1615 case 1 + signedDelta: 1616 t.Go = c.int8 1617 case 2 + signedDelta: 1618 t.Go = c.int16 1619 case 4 + signedDelta: 1620 t.Go = c.int32 1621 case 8 + signedDelta: 1622 t.Go = c.int64 1623 } 1624 1625 case *dwarf.FloatType: 1626 switch t.Size { 1627 default: 1628 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 1629 case 4: 1630 t.Go = c.float32 1631 case 8: 1632 t.Go = c.float64 1633 } 1634 if t.Align = t.Size; t.Align >= c.ptrSize { 1635 t.Align = c.ptrSize 1636 } 1637 1638 case *dwarf.ComplexType: 1639 switch t.Size { 1640 default: 1641 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 1642 case 8: 1643 t.Go = c.complex64 1644 case 16: 1645 t.Go = c.complex128 1646 } 1647 if t.Align = t.Size / 2; t.Align >= c.ptrSize { 1648 t.Align = c.ptrSize 1649 } 1650 1651 case *dwarf.FuncType: 1652 // No attempt at translation: would enable calls 1653 // directly between worlds, but we need to moderate those. 1654 t.Go = c.uintptr 1655 t.Align = c.ptrSize 1656 1657 case *dwarf.IntType: 1658 if dt.BitSize > 0 { 1659 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 1660 } 1661 switch t.Size { 1662 default: 1663 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 1664 case 1: 1665 t.Go = c.int8 1666 case 2: 1667 t.Go = c.int16 1668 case 4: 1669 t.Go = c.int32 1670 case 8: 1671 t.Go = c.int64 1672 case 16: 1673 t.Go = &ast.ArrayType{ 1674 Len: c.intExpr(t.Size), 1675 Elt: c.uint8, 1676 } 1677 } 1678 if t.Align = t.Size; t.Align >= c.ptrSize { 1679 t.Align = c.ptrSize 1680 } 1681 1682 case *dwarf.PtrType: 1683 // Clang doesn't emit DW_AT_byte_size for pointer types. 1684 if t.Size != c.ptrSize && t.Size != -1 { 1685 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype) 1686 } 1687 t.Size = c.ptrSize 1688 t.Align = c.ptrSize 1689 1690 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 1691 t.Go = c.goVoidPtr 1692 t.C.Set("void*") 1693 break 1694 } 1695 1696 // Placeholder initialization; completed in FinishType. 1697 t.Go = &ast.StarExpr{} 1698 t.C.Set("<incomplete>*") 1699 if _, ok := c.ptrs[dt.Type]; !ok { 1700 c.ptrKeys = append(c.ptrKeys, dt.Type) 1701 } 1702 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t) 1703 1704 case *dwarf.QualType: 1705 // Ignore qualifier. 1706 t = c.Type(dt.Type, pos) 1707 c.m[dtype] = t 1708 return t 1709 1710 case *dwarf.StructType: 1711 // Convert to Go struct, being careful about alignment. 1712 // Have to give it a name to simulate C "struct foo" references. 1713 tag := dt.StructName 1714 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 1715 break 1716 } 1717 if tag == "" { 1718 tag = "__" + strconv.Itoa(tagGen) 1719 tagGen++ 1720 } else if t.C.Empty() { 1721 t.C.Set(dt.Kind + " " + tag) 1722 } 1723 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 1724 t.Go = name // publish before recursive calls 1725 goIdent[name.Name] = name 1726 if dt.ByteSize < 0 { 1727 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 1728 // so execute the basic things that the struct case would do 1729 // other than try to determine a Go representation. 1730 tt := *t 1731 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 1732 tt.Go = c.Ident("struct{}") 1733 typedef[name.Name] = &tt 1734 break 1735 } 1736 switch dt.Kind { 1737 case "class", "union": 1738 t.Go = c.Opaque(t.Size) 1739 if t.C.Empty() { 1740 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 1741 } 1742 t.Align = 1 // TODO: should probably base this on field alignment. 1743 typedef[name.Name] = t 1744 case "struct": 1745 g, csyntax, align := c.Struct(dt, pos) 1746 if t.C.Empty() { 1747 t.C.Set(csyntax) 1748 } 1749 t.Align = align 1750 tt := *t 1751 if tag != "" { 1752 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 1753 } 1754 tt.Go = g 1755 typedef[name.Name] = &tt 1756 } 1757 1758 case *dwarf.TypedefType: 1759 // Record typedef for printing. 1760 if dt.Name == "_GoString_" { 1761 // Special C name for Go string type. 1762 // Knows string layout used by compilers: pointer plus length, 1763 // which rounds up to 2 pointers after alignment. 1764 t.Go = c.string 1765 t.Size = c.ptrSize * 2 1766 t.Align = c.ptrSize 1767 break 1768 } 1769 if dt.Name == "_GoBytes_" { 1770 // Special C name for Go []byte type. 1771 // Knows slice layout used by compilers: pointer, length, cap. 1772 t.Go = c.Ident("[]byte") 1773 t.Size = c.ptrSize + 4 + 4 1774 t.Align = c.ptrSize 1775 break 1776 } 1777 name := c.Ident("_Ctype_" + dt.Name) 1778 goIdent[name.Name] = name 1779 sub := c.Type(dt.Type, pos) 1780 t.Go = name 1781 t.Size = sub.Size 1782 t.Align = sub.Align 1783 oldType := typedef[name.Name] 1784 if oldType == nil { 1785 tt := *t 1786 tt.Go = sub.Go 1787 typedef[name.Name] = &tt 1788 } 1789 1790 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 1791 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 1792 // with the base type. 1793 // In -godefs mode, do this for all typedefs. 1794 if isStructUnionClass(sub.Go) || *godefs { 1795 t.Go = sub.Go 1796 1797 if isStructUnionClass(sub.Go) { 1798 // Use the typedef name for C code. 1799 typedef[sub.Go.(*ast.Ident).Name].C = t.C 1800 } 1801 1802 // If we've seen this typedef before, and it 1803 // was an anonymous struct/union/class before 1804 // too, use the old definition. 1805 // TODO: it would be safer to only do this if 1806 // we verify that the types are the same. 1807 if oldType != nil && isStructUnionClass(oldType.Go) { 1808 t.Go = oldType.Go 1809 } 1810 } 1811 1812 case *dwarf.UcharType: 1813 if t.Size != 1 { 1814 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 1815 } 1816 t.Go = c.uint8 1817 t.Align = 1 1818 1819 case *dwarf.UintType: 1820 if dt.BitSize > 0 { 1821 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 1822 } 1823 switch t.Size { 1824 default: 1825 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 1826 case 1: 1827 t.Go = c.uint8 1828 case 2: 1829 t.Go = c.uint16 1830 case 4: 1831 t.Go = c.uint32 1832 case 8: 1833 t.Go = c.uint64 1834 case 16: 1835 t.Go = &ast.ArrayType{ 1836 Len: c.intExpr(t.Size), 1837 Elt: c.uint8, 1838 } 1839 } 1840 if t.Align = t.Size; t.Align >= c.ptrSize { 1841 t.Align = c.ptrSize 1842 } 1843 1844 case *dwarf.VoidType: 1845 t.Go = c.goVoid 1846 t.C.Set("void") 1847 t.Align = 1 1848 } 1849 1850 switch dtype.(type) { 1851 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 1852 s := dtype.Common().Name 1853 if s != "" { 1854 if ss, ok := dwarfToName[s]; ok { 1855 s = ss 1856 } 1857 s = strings.Join(strings.Split(s, " "), "") // strip spaces 1858 name := c.Ident("_Ctype_" + s) 1859 tt := *t 1860 typedef[name.Name] = &tt 1861 if !*godefs { 1862 t.Go = name 1863 } 1864 } 1865 } 1866 1867 if t.Size < 0 { 1868 // Unsized types are [0]byte, unless they're typedefs of other types 1869 // or structs with tags. 1870 // if so, use the name we've already defined. 1871 t.Size = 0 1872 switch dt := dtype.(type) { 1873 case *dwarf.TypedefType: 1874 // ok 1875 case *dwarf.StructType: 1876 if dt.StructName != "" { 1877 break 1878 } 1879 t.Go = c.Opaque(0) 1880 default: 1881 t.Go = c.Opaque(0) 1882 } 1883 if t.C.Empty() { 1884 t.C.Set("void") 1885 } 1886 } 1887 1888 if t.C.Empty() { 1889 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 1890 } 1891 1892 return t 1893 } 1894 1895 // isStructUnionClass reports whether the type described by the Go syntax x 1896 // is a struct, union, or class with a tag. 1897 func isStructUnionClass(x ast.Expr) bool { 1898 id, ok := x.(*ast.Ident) 1899 if !ok { 1900 return false 1901 } 1902 name := id.Name 1903 return strings.HasPrefix(name, "_Ctype_struct_") || 1904 strings.HasPrefix(name, "_Ctype_union_") || 1905 strings.HasPrefix(name, "_Ctype_class_") 1906 } 1907 1908 // FuncArg returns a Go type with the same memory layout as 1909 // dtype when used as the type of a C function argument. 1910 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 1911 t := c.Type(dtype, pos) 1912 switch dt := dtype.(type) { 1913 case *dwarf.ArrayType: 1914 // Arrays are passed implicitly as pointers in C. 1915 // In Go, we must be explicit. 1916 tr := &TypeRepr{} 1917 tr.Set("%s*", t.C) 1918 return &Type{ 1919 Size: c.ptrSize, 1920 Align: c.ptrSize, 1921 Go: &ast.StarExpr{X: t.Go}, 1922 C: tr, 1923 } 1924 case *dwarf.TypedefType: 1925 // C has much more relaxed rules than Go for 1926 // implicit type conversions. When the parameter 1927 // is type T defined as *X, simulate a little of the 1928 // laxness of C by making the argument *X instead of T. 1929 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 1930 // Unless the typedef happens to point to void* since 1931 // Go has special rules around using unsafe.Pointer. 1932 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 1933 break 1934 } 1935 1936 t = c.Type(ptr, pos) 1937 if t == nil { 1938 return nil 1939 } 1940 1941 // For a struct/union/class, remember the C spelling, 1942 // in case it has __attribute__((unavailable)). 1943 // See issue 2888. 1944 if isStructUnionClass(t.Go) { 1945 t.Typedef = dt.Name 1946 } 1947 } 1948 } 1949 return t 1950 } 1951 1952 // FuncType returns the Go type analogous to dtype. 1953 // There is no guarantee about matching memory layout. 1954 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 1955 p := make([]*Type, len(dtype.ParamType)) 1956 gp := make([]*ast.Field, len(dtype.ParamType)) 1957 for i, f := range dtype.ParamType { 1958 // gcc's DWARF generator outputs a single DotDotDotType parameter for 1959 // function pointers that specify no parameters (e.g. void 1960 // (*__cgo_0)()). Treat this special case as void. This case is 1961 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 1962 // legal). 1963 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 1964 p, gp = nil, nil 1965 break 1966 } 1967 p[i] = c.FuncArg(f, pos) 1968 gp[i] = &ast.Field{Type: p[i].Go} 1969 } 1970 var r *Type 1971 var gr []*ast.Field 1972 if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok { 1973 gr = []*ast.Field{{Type: c.goVoid}} 1974 } else if dtype.ReturnType != nil { 1975 r = c.Type(dtype.ReturnType, pos) 1976 gr = []*ast.Field{{Type: r.Go}} 1977 } 1978 return &FuncType{ 1979 Params: p, 1980 Result: r, 1981 Go: &ast.FuncType{ 1982 Params: &ast.FieldList{List: gp}, 1983 Results: &ast.FieldList{List: gr}, 1984 }, 1985 } 1986 } 1987 1988 // Identifier 1989 func (c *typeConv) Ident(s string) *ast.Ident { 1990 return ast.NewIdent(s) 1991 } 1992 1993 // Opaque type of n bytes. 1994 func (c *typeConv) Opaque(n int64) ast.Expr { 1995 return &ast.ArrayType{ 1996 Len: c.intExpr(n), 1997 Elt: c.byte, 1998 } 1999 } 2000 2001 // Expr for integer n. 2002 func (c *typeConv) intExpr(n int64) ast.Expr { 2003 return &ast.BasicLit{ 2004 Kind: token.INT, 2005 Value: strconv.FormatInt(n, 10), 2006 } 2007 } 2008 2009 // Add padding of given size to fld. 2010 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) { 2011 n := len(fld) 2012 fld = fld[0 : n+1] 2013 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 2014 sizes = sizes[0 : n+1] 2015 sizes[n] = size 2016 return fld, sizes 2017 } 2018 2019 // Struct conversion: return Go and (gc) C syntax for type. 2020 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 2021 // Minimum alignment for a struct is 1 byte. 2022 align = 1 2023 2024 var buf bytes.Buffer 2025 buf.WriteString("struct {") 2026 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 2027 sizes := make([]int64, 0, 2*len(dt.Field)+1) 2028 off := int64(0) 2029 2030 // Rename struct fields that happen to be named Go keywords into 2031 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 2032 // be mangled. Any existing identifier that already has the same name on 2033 // the C-side will cause the Go-mangled version to be prefixed with _. 2034 // (e.g. in a struct with fields '_type' and 'type', the latter would be 2035 // rendered as '__type' in Go). 2036 ident := make(map[string]string) 2037 used := make(map[string]bool) 2038 for _, f := range dt.Field { 2039 ident[f.Name] = f.Name 2040 used[f.Name] = true 2041 } 2042 2043 if !*godefs { 2044 for cid, goid := range ident { 2045 if token.Lookup(goid).IsKeyword() { 2046 // Avoid keyword 2047 goid = "_" + goid 2048 2049 // Also avoid existing fields 2050 for _, exist := used[goid]; exist; _, exist = used[goid] { 2051 goid = "_" + goid 2052 } 2053 2054 used[goid] = true 2055 ident[cid] = goid 2056 } 2057 } 2058 } 2059 2060 anon := 0 2061 for _, f := range dt.Field { 2062 if f.ByteOffset > off { 2063 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off) 2064 off = f.ByteOffset 2065 } 2066 2067 name := f.Name 2068 ft := f.Type 2069 2070 // In godefs mode, if this field is a C11 2071 // anonymous union then treat the first field in the 2072 // union as the field in the struct. This handles 2073 // cases like the glibc <sys/resource.h> file; see 2074 // issue 6677. 2075 if *godefs { 2076 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] { 2077 name = st.Field[0].Name 2078 ident[name] = name 2079 ft = st.Field[0].Type 2080 } 2081 } 2082 2083 // TODO: Handle fields that are anonymous structs by 2084 // promoting the fields of the inner struct. 2085 2086 t := c.Type(ft, pos) 2087 tgo := t.Go 2088 size := t.Size 2089 talign := t.Align 2090 if f.BitSize > 0 { 2091 if f.BitSize%8 != 0 { 2092 continue 2093 } 2094 size = f.BitSize / 8 2095 name := tgo.(*ast.Ident).String() 2096 if strings.HasPrefix(name, "int") { 2097 name = "int" 2098 } else { 2099 name = "uint" 2100 } 2101 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) 2102 talign = size 2103 } 2104 2105 if talign > 0 && f.ByteOffset%talign != 0 { 2106 // Drop misaligned fields, the same way we drop integer bit fields. 2107 // The goal is to make available what can be made available. 2108 // Otherwise one bad and unneeded field in an otherwise okay struct 2109 // makes the whole program not compile. Much of the time these 2110 // structs are in system headers that cannot be corrected. 2111 continue 2112 } 2113 n := len(fld) 2114 fld = fld[0 : n+1] 2115 if name == "" { 2116 name = fmt.Sprintf("anon%d", anon) 2117 anon++ 2118 ident[name] = name 2119 } 2120 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 2121 sizes = sizes[0 : n+1] 2122 sizes[n] = size 2123 off += size 2124 buf.WriteString(t.C.String()) 2125 buf.WriteString(" ") 2126 buf.WriteString(name) 2127 buf.WriteString("; ") 2128 if talign > align { 2129 align = talign 2130 } 2131 } 2132 if off < dt.ByteSize { 2133 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off) 2134 off = dt.ByteSize 2135 } 2136 2137 // If the last field in a non-zero-sized struct is zero-sized 2138 // the compiler is going to pad it by one (see issue 9401). 2139 // We can't permit that, because then the size of the Go 2140 // struct will not be the same as the size of the C struct. 2141 // Our only option in such a case is to remove the field, 2142 // which means that it cannot be referenced from Go. 2143 for off > 0 && sizes[len(sizes)-1] == 0 { 2144 n := len(sizes) 2145 fld = fld[0 : n-1] 2146 sizes = sizes[0 : n-1] 2147 } 2148 2149 if off != dt.ByteSize { 2150 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 2151 } 2152 buf.WriteString("}") 2153 csyntax = buf.String() 2154 2155 if *godefs { 2156 godefsFields(fld) 2157 } 2158 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 2159 return 2160 } 2161 2162 func upper(s string) string { 2163 if s == "" { 2164 return "" 2165 } 2166 r, size := utf8.DecodeRuneInString(s) 2167 if r == '_' { 2168 return "X" + s 2169 } 2170 return string(unicode.ToUpper(r)) + s[size:] 2171 } 2172 2173 // godefsFields rewrites field names for use in Go or C definitions. 2174 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 2175 // converts names to upper case, and rewrites _ into Pad_godefs_n, 2176 // so that all fields are exported. 2177 func godefsFields(fld []*ast.Field) { 2178 prefix := fieldPrefix(fld) 2179 npad := 0 2180 for _, f := range fld { 2181 for _, n := range f.Names { 2182 if n.Name != prefix { 2183 n.Name = strings.TrimPrefix(n.Name, prefix) 2184 } 2185 if n.Name == "_" { 2186 // Use exported name instead. 2187 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 2188 npad++ 2189 } 2190 n.Name = upper(n.Name) 2191 } 2192 } 2193 } 2194 2195 // fieldPrefix returns the prefix that should be removed from all the 2196 // field names when generating the C or Go code. For generated 2197 // C, we leave the names as is (tv_sec, tv_usec), since that's what 2198 // people are used to seeing in C. For generated Go code, such as 2199 // package syscall's data structures, we drop a common prefix 2200 // (so sec, usec, which will get turned into Sec, Usec for exporting). 2201 func fieldPrefix(fld []*ast.Field) string { 2202 prefix := "" 2203 for _, f := range fld { 2204 for _, n := range f.Names { 2205 // Ignore field names that don't have the prefix we're 2206 // looking for. It is common in C headers to have fields 2207 // named, say, _pad in an otherwise prefixed header. 2208 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 2209 // still want to remove the tv_ prefix. 2210 // The check for "orig_" here handles orig_eax in the 2211 // x86 ptrace register sets, which otherwise have all fields 2212 // with reg_ prefixes. 2213 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 2214 continue 2215 } 2216 i := strings.Index(n.Name, "_") 2217 if i < 0 { 2218 continue 2219 } 2220 if prefix == "" { 2221 prefix = n.Name[:i+1] 2222 } else if prefix != n.Name[:i+1] { 2223 return "" 2224 } 2225 } 2226 } 2227 return prefix 2228 }