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