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