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.rewriteRef(f) 171 } 172 173 // loadDefines coerces gcc into spitting out the #defines in use 174 // in the file f and saves relevant renamings in f.Name[name].Define. 175 func (p *Package) loadDefines(f *File) { 176 var b bytes.Buffer 177 b.WriteString(f.Preamble) 178 b.WriteString(builtinProlog) 179 stdout := p.gccDefines(b.Bytes()) 180 181 for _, line := range strings.Split(stdout, "\n") { 182 if len(line) < 9 || line[0:7] != "#define" { 183 continue 184 } 185 186 line = strings.TrimSpace(line[8:]) 187 188 var key, val string 189 spaceIndex := strings.Index(line, " ") 190 tabIndex := strings.Index(line, "\t") 191 192 if spaceIndex == -1 && tabIndex == -1 { 193 continue 194 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) { 195 key = line[0:spaceIndex] 196 val = strings.TrimSpace(line[spaceIndex:]) 197 } else { 198 key = line[0:tabIndex] 199 val = strings.TrimSpace(line[tabIndex:]) 200 } 201 202 if key == "__clang__" { 203 p.GccIsClang = true 204 } 205 206 if n := f.Name[key]; n != nil { 207 if *debugDefine { 208 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val) 209 } 210 n.Define = val 211 } 212 } 213 } 214 215 // guessKinds tricks gcc into revealing the kind of each 216 // name xxx for the references C.xxx in the Go input. 217 // The kind is either a constant, type, or variable. 218 func (p *Package) guessKinds(f *File) []*Name { 219 // Determine kinds for names we already know about, 220 // like #defines or 'struct foo', before bothering with gcc. 221 var names, needType []*Name 222 for _, key := range nameKeys(f.Name) { 223 n := f.Name[key] 224 // If we've already found this name as a #define 225 // and we can translate it as a constant value, do so. 226 if n.Define != "" { 227 isConst := false 228 if _, err := strconv.Atoi(n.Define); err == nil { 229 isConst = true 230 } else if n.Define[0] == '"' || n.Define[0] == '\'' { 231 if _, err := parser.ParseExpr(n.Define); err == nil { 232 isConst = true 233 } 234 } 235 if isConst { 236 n.Kind = "const" 237 // Turn decimal into hex, just for consistency 238 // with enum-derived constants. Otherwise 239 // in the cgo -godefs output half the constants 240 // are in hex and half are in whatever the #define used. 241 i, err := strconv.ParseInt(n.Define, 0, 64) 242 if err == nil { 243 n.Const = fmt.Sprintf("%#x", i) 244 } else { 245 n.Const = n.Define 246 } 247 continue 248 } 249 250 if isName(n.Define) { 251 n.C = n.Define 252 } 253 } 254 255 needType = append(needType, n) 256 257 // If this is a struct, union, or enum type name, no need to guess the kind. 258 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") { 259 n.Kind = "type" 260 continue 261 } 262 263 // Otherwise, we'll need to find out from gcc. 264 names = append(names, n) 265 } 266 267 // Bypass gcc if there's nothing left to find out. 268 if len(names) == 0 { 269 return needType 270 } 271 272 // Coerce gcc into telling us whether each name is a type, a value, or undeclared. 273 // For names, find out whether they are integer constants. 274 // We used to look at specific warning or error messages here, but that tied the 275 // behavior too closely to specific versions of the compilers. 276 // Instead, arrange that we can infer what we need from only the presence or absence 277 // of an error on a specific line. 278 // 279 // For each name, we generate these lines, where xxx is the index in toSniff plus one. 280 // 281 // #line xxx "not-declared" 282 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; } 283 // #line xxx "not-type" 284 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__; } 285 // #line xxx "not-const" 286 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; } 287 // 288 // If we see an error at not-declared:xxx, the corresponding name is not declared. 289 // If we see an error at not-type:xxx, the corresponding name is a type. 290 // If we see an error at not-const:xxx, the corresponding name is not an integer constant. 291 // If we see no errors, we assume the name is an expression but not a constant 292 // (so a variable or a function). 293 // 294 // The specific input forms are chosen so that they are valid C syntax regardless of 295 // whether name denotes a type or an expression. 296 297 var b bytes.Buffer 298 b.WriteString(f.Preamble) 299 b.WriteString(builtinProlog) 300 301 for i, n := range names { 302 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+ 303 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+ 304 "#line %d \"not-type\"\n"+ 305 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+ 306 "#line %d \"not-const\"\n"+ 307 "void __cgo_f_%d_3(void) { enum { __cgo__undefined__ = (%s)*1 }; }\n", 308 i+1, i+1, n.C, 309 i+1, i+1, n.C, 310 i+1, i+1, n.C) 311 } 312 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+ 313 "int __cgo__1 = __cgo__2;\n") 314 315 stderr := p.gccErrors(b.Bytes()) 316 if stderr == "" { 317 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes()) 318 } 319 320 completed := false 321 sniff := make([]int, len(names)) 322 const ( 323 notType = 1 << iota 324 notConst 325 notDeclared 326 ) 327 for _, line := range strings.Split(stderr, "\n") { 328 if !strings.Contains(line, ": error:") { 329 // we only care about errors. 330 // we tried to turn off warnings on the command line, but one never knows. 331 continue 332 } 333 334 c1 := strings.Index(line, ":") 335 if c1 < 0 { 336 continue 337 } 338 c2 := strings.Index(line[c1+1:], ":") 339 if c2 < 0 { 340 continue 341 } 342 c2 += c1 + 1 343 344 filename := line[:c1] 345 i, _ := strconv.Atoi(line[c1+1 : c2]) 346 i-- 347 if i < 0 || i >= len(names) { 348 continue 349 } 350 351 switch filename { 352 case "completed": 353 // Strictly speaking, there is no guarantee that seeing the error at completed:1 354 // (at the end of the file) means we've seen all the errors from earlier in the file, 355 // but usually it does. Certainly if we don't see the completed:1 error, we did 356 // not get all the errors we expected. 357 completed = true 358 359 case "not-declared": 360 sniff[i] |= notDeclared 361 case "not-type": 362 sniff[i] |= notType 363 case "not-const": 364 sniff[i] |= notConst 365 } 366 } 367 368 if !completed { 369 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr) 370 } 371 372 for i, n := range names { 373 switch sniff[i] { 374 default: 375 error_(token.NoPos, "could not determine kind of name for C.%s", fixGo(n.Go)) 376 case notType: 377 n.Kind = "const" 378 case notConst: 379 n.Kind = "type" 380 case notConst | notType: 381 n.Kind = "not-type" 382 } 383 } 384 if nerrors > 0 { 385 // Check if compiling the preamble by itself causes any errors, 386 // because the messages we've printed out so far aren't helpful 387 // to users debugging preamble mistakes. See issue 8442. 388 preambleErrors := p.gccErrors([]byte(f.Preamble)) 389 if len(preambleErrors) > 0 { 390 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors) 391 } 392 393 fatalf("unresolved names") 394 } 395 396 needType = append(needType, names...) 397 return needType 398 } 399 400 // loadDWARF parses the DWARF debug information generated 401 // by gcc to learn the details of the constants, variables, and types 402 // being referred to as C.xxx. 403 func (p *Package) loadDWARF(f *File, names []*Name) { 404 // Extract the types from the DWARF section of an object 405 // from a well-formed C program. Gcc only generates DWARF info 406 // for symbols in the object file, so it is not enough to print the 407 // preamble and hope the symbols we care about will be there. 408 // Instead, emit 409 // __typeof__(names[i]) *__cgo__i; 410 // for each entry in names and then dereference the type we 411 // learn for __cgo__i. 412 var b bytes.Buffer 413 b.WriteString(f.Preamble) 414 b.WriteString(builtinProlog) 415 for i, n := range names { 416 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i) 417 if n.Kind == "const" { 418 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C) 419 } 420 } 421 422 // Apple's LLVM-based gcc does not include the enumeration 423 // names and values in its DWARF debug output. In case we're 424 // using such a gcc, create a data block initialized with the values. 425 // We can read them out of the object file. 426 fmt.Fprintf(&b, "long long __cgodebug_data[] = {\n") 427 for _, n := range names { 428 if n.Kind == "const" { 429 fmt.Fprintf(&b, "\t%s,\n", n.C) 430 } else { 431 fmt.Fprintf(&b, "\t0,\n") 432 } 433 } 434 // for the last entry, we can not use 0, otherwise 435 // in case all __cgodebug_data is zero initialized, 436 // LLVM-based gcc will place the it in the __DATA.__common 437 // zero-filled section (our debug/macho doesn't support 438 // this) 439 fmt.Fprintf(&b, "\t1\n") 440 fmt.Fprintf(&b, "};\n") 441 442 d, bo, debugData := p.gccDebug(b.Bytes()) 443 enumVal := make([]int64, len(debugData)/8) 444 for i := range enumVal { 445 enumVal[i] = int64(bo.Uint64(debugData[i*8:])) 446 } 447 448 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i. 449 types := make([]dwarf.Type, len(names)) 450 enums := make([]dwarf.Offset, len(names)) 451 nameToIndex := make(map[*Name]int) 452 for i, n := range names { 453 nameToIndex[n] = i 454 } 455 nameToRef := make(map[*Name]*Ref) 456 for _, ref := range f.Ref { 457 nameToRef[ref.Name] = ref 458 } 459 r := d.Reader() 460 for { 461 e, err := r.Next() 462 if err != nil { 463 fatalf("reading DWARF entry: %s", err) 464 } 465 if e == nil { 466 break 467 } 468 switch e.Tag { 469 case dwarf.TagEnumerationType: 470 offset := e.Offset 471 for { 472 e, err := r.Next() 473 if err != nil { 474 fatalf("reading DWARF entry: %s", err) 475 } 476 if e.Tag == 0 { 477 break 478 } 479 if e.Tag == dwarf.TagEnumerator { 480 entryName := e.Val(dwarf.AttrName).(string) 481 if strings.HasPrefix(entryName, "__cgo_enum__") { 482 n, _ := strconv.Atoi(entryName[len("__cgo_enum__"):]) 483 if 0 <= n && n < len(names) { 484 enums[n] = offset 485 } 486 } 487 } 488 } 489 case dwarf.TagVariable: 490 name, _ := e.Val(dwarf.AttrName).(string) 491 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset) 492 if name == "" || typOff == 0 { 493 fatalf("malformed DWARF TagVariable entry") 494 } 495 if !strings.HasPrefix(name, "__cgo__") { 496 break 497 } 498 typ, err := d.Type(typOff) 499 if err != nil { 500 fatalf("loading DWARF type: %s", err) 501 } 502 t, ok := typ.(*dwarf.PtrType) 503 if !ok || t == nil { 504 fatalf("internal error: %s has non-pointer type", name) 505 } 506 i, err := strconv.Atoi(name[7:]) 507 if err != nil { 508 fatalf("malformed __cgo__ name: %s", name) 509 } 510 if enums[i] != 0 { 511 t, err := d.Type(enums[i]) 512 if err != nil { 513 fatalf("loading DWARF type: %s", err) 514 } 515 types[i] = t 516 } else { 517 types[i] = t.Type 518 } 519 } 520 if e.Tag != dwarf.TagCompileUnit { 521 r.SkipChildren() 522 } 523 } 524 525 // Record types and typedef information. 526 var conv typeConv 527 conv.Init(p.PtrSize, p.IntSize) 528 for i, n := range names { 529 if types[i] == nil { 530 continue 531 } 532 pos := token.NoPos 533 if ref, ok := nameToRef[n]; ok { 534 pos = ref.Pos() 535 } 536 f, fok := types[i].(*dwarf.FuncType) 537 if n.Kind != "type" && fok { 538 n.Kind = "func" 539 n.FuncType = conv.FuncType(f, pos) 540 } else { 541 n.Type = conv.Type(types[i], pos) 542 if enums[i] != 0 && n.Type.EnumValues != nil { 543 k := fmt.Sprintf("__cgo_enum__%d", i) 544 n.Kind = "const" 545 n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k]) 546 // Remove injected enum to ensure the value will deep-compare 547 // equally in future loads of the same constant. 548 delete(n.Type.EnumValues, k) 549 } 550 // Prefer debug data over DWARF debug output, if we have it. 551 if n.Kind == "const" && i < len(enumVal) { 552 n.Const = fmt.Sprintf("%#x", enumVal[i]) 553 } 554 } 555 conv.FinishType(pos) 556 } 557 } 558 559 // mangleName does name mangling to translate names 560 // from the original Go source files to the names 561 // used in the final Go files generated by cgo. 562 func (p *Package) mangleName(n *Name) { 563 // When using gccgo variables have to be 564 // exported so that they become global symbols 565 // that the C code can refer to. 566 prefix := "_C" 567 if *gccgo && n.IsVar() { 568 prefix = "C" 569 } 570 n.Mangle = prefix + n.Kind + "_" + n.Go 571 } 572 573 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the 574 // Go equivalents, now that we have figured out the meaning of all 575 // the xxx. In *godefs mode, rewriteRef replaces the names 576 // with full definitions instead of mangled names. 577 func (p *Package) rewriteRef(f *File) { 578 // Keep a list of all the functions, to remove the ones 579 // only used as expressions and avoid generating bridge 580 // code for them. 581 functions := make(map[string]bool) 582 583 // Assign mangled names. 584 for _, n := range f.Name { 585 if n.Kind == "not-type" { 586 n.Kind = "var" 587 } 588 if n.Mangle == "" { 589 p.mangleName(n) 590 } 591 if n.Kind == "func" { 592 functions[n.Go] = false 593 } 594 } 595 596 // Now that we have all the name types filled in, 597 // scan through the Refs to identify the ones that 598 // are trying to do a ,err call. Also check that 599 // functions are only used in calls. 600 for _, r := range f.Ref { 601 if r.Name.Kind == "const" && r.Name.Const == "" { 602 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go)) 603 } 604 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default 605 switch r.Context { 606 case "call", "call2": 607 if r.Name.Kind != "func" { 608 if r.Name.Kind == "type" { 609 r.Context = "type" 610 expr = r.Name.Type.Go 611 break 612 } 613 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) 614 break 615 } 616 functions[r.Name.Go] = true 617 if r.Context == "call2" { 618 if r.Name.Go == "_CMalloc" { 619 error_(r.Pos(), "no two-result form for C.malloc") 620 break 621 } 622 // Invent new Name for the two-result function. 623 n := f.Name["2"+r.Name.Go] 624 if n == nil { 625 n = new(Name) 626 *n = *r.Name 627 n.AddError = true 628 n.Mangle = "_C2func_" + n.Go 629 f.Name["2"+r.Name.Go] = n 630 } 631 expr = ast.NewIdent(n.Mangle) 632 r.Name = n 633 break 634 } 635 case "expr": 636 if r.Name.Kind == "func" { 637 // Function is being used in an expression, to e.g. pass around a C function pointer. 638 // Create a new Name for this Ref which causes the variable to be declared in Go land. 639 fpName := "fp_" + r.Name.Go 640 name := f.Name[fpName] 641 if name == nil { 642 name = &Name{ 643 Go: fpName, 644 C: r.Name.C, 645 Kind: "fpvar", 646 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")}, 647 } 648 p.mangleName(name) 649 f.Name[fpName] = name 650 } 651 r.Name = name 652 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr 653 // function is defined in out.go and simply returns its argument. See 654 // issue 7757. 655 expr = &ast.CallExpr{ 656 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"}, 657 Args: []ast.Expr{ast.NewIdent(name.Mangle)}, 658 } 659 } else if r.Name.Kind == "type" { 660 // Okay - might be new(T) 661 expr = r.Name.Type.Go 662 } else if r.Name.Kind == "var" { 663 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 664 } 665 666 case "selector": 667 if r.Name.Kind == "var" { 668 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 669 } else { 670 error_(r.Pos(), "only C variables allowed in selector expression", fixGo(r.Name.Go)) 671 } 672 673 case "type": 674 if r.Name.Kind != "type" { 675 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 676 } else if r.Name.Type == nil { 677 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 678 // GCC won't raise an error when using pointers to such unknown types. 679 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 680 } else { 681 expr = r.Name.Type.Go 682 } 683 default: 684 if r.Name.Kind == "func" { 685 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 686 } 687 } 688 if *godefs { 689 // Substitute definition for mangled type name. 690 if id, ok := expr.(*ast.Ident); ok { 691 if t := typedef[id.Name]; t != nil { 692 expr = t.Go 693 } 694 if id.Name == r.Name.Mangle && r.Name.Const != "" { 695 expr = ast.NewIdent(r.Name.Const) 696 } 697 } 698 } 699 700 // Copy position information from old expr into new expr, 701 // in case expression being replaced is first on line. 702 // See golang.org/issue/6563. 703 pos := (*r.Expr).Pos() 704 switch x := expr.(type) { 705 case *ast.Ident: 706 expr = &ast.Ident{NamePos: pos, Name: x.Name} 707 } 708 709 *r.Expr = expr 710 } 711 712 // Remove functions only used as expressions, so their respective 713 // bridge functions are not generated. 714 for name, used := range functions { 715 if !used { 716 delete(f.Name, name) 717 } 718 } 719 } 720 721 // gccBaseCmd returns the start of the compiler command line. 722 // It uses $CC if set, or else $GCC, or else the compiler recorded 723 // during the initial build as defaultCC. 724 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 725 func (p *Package) gccBaseCmd() []string { 726 // Use $CC if set, since that's what the build uses. 727 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 { 728 return ret 729 } 730 // Try $GCC if set, since that's what we used to use. 731 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 { 732 return ret 733 } 734 return strings.Fields(defaultCC) 735 } 736 737 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 738 func (p *Package) gccMachine() []string { 739 switch goarch { 740 case "amd64": 741 return []string{"-m64"} 742 case "386": 743 return []string{"-m32"} 744 case "arm": 745 return []string{"-marm"} // not thumb 746 case "s390": 747 return []string{"-m31"} 748 case "s390x": 749 return []string{"-m64"} 750 } 751 return nil 752 } 753 754 func gccTmp() string { 755 return *objDir + "_cgo_.o" 756 } 757 758 // gccCmd returns the gcc command line to use for compiling 759 // the input. 760 func (p *Package) gccCmd() []string { 761 c := append(p.gccBaseCmd(), 762 "-w", // no warnings 763 "-Wno-error", // warnings are not errors 764 "-o"+gccTmp(), // write object to tmp 765 "-gdwarf-2", // generate DWARF v2 debugging symbols 766 "-c", // do not link 767 "-xc", // input language is C 768 ) 769 if p.GccIsClang { 770 c = append(c, 771 "-ferror-limit=0", 772 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 773 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 774 // flag to disable the warning. Yes, really good diagnostics, clang. 775 "-Wno-unknown-warning-option", 776 "-Wno-unneeded-internal-declaration", 777 "-Wno-unused-function", 778 "-Qunused-arguments", 779 // Clang embeds prototypes for some builtin functions, 780 // like malloc and calloc, but all size_t parameters are 781 // incorrectly typed unsigned long. We work around that 782 // by disabling the builtin functions (this is safe as 783 // it won't affect the actual compilation of the C code). 784 // See: https://golang.org/issue/6506. 785 "-fno-builtin", 786 ) 787 } 788 789 c = append(c, p.GccOptions...) 790 c = append(c, p.gccMachine()...) 791 c = append(c, "-") //read input from standard input 792 return c 793 } 794 795 // gccDebug runs gcc -gdwarf-2 over the C program stdin and 796 // returns the corresponding DWARF data and, if present, debug data block. 797 func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) { 798 runGcc(stdin, p.gccCmd()) 799 800 isDebugData := func(s string) bool { 801 // Some systems use leading _ to denote non-assembly symbols. 802 return s == "__cgodebug_data" || s == "___cgodebug_data" 803 } 804 805 if f, err := macho.Open(gccTmp()); err == nil { 806 defer f.Close() 807 d, err := f.DWARF() 808 if err != nil { 809 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 810 } 811 var data []byte 812 if f.Symtab != nil { 813 for i := range f.Symtab.Syms { 814 s := &f.Symtab.Syms[i] 815 if isDebugData(s.Name) { 816 // Found it. Now find data section. 817 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 818 sect := f.Sections[i] 819 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 820 if sdat, err := sect.Data(); err == nil { 821 data = sdat[s.Value-sect.Addr:] 822 } 823 } 824 } 825 } 826 } 827 } 828 return d, f.ByteOrder, data 829 } 830 831 if f, err := elf.Open(gccTmp()); err == nil { 832 defer f.Close() 833 d, err := f.DWARF() 834 if err != nil { 835 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 836 } 837 var data []byte 838 symtab, err := f.Symbols() 839 if err == nil { 840 for i := range symtab { 841 s := &symtab[i] 842 if isDebugData(s.Name) { 843 // Found it. Now find data section. 844 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 845 sect := f.Sections[i] 846 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 847 if sdat, err := sect.Data(); err == nil { 848 data = sdat[s.Value-sect.Addr:] 849 } 850 } 851 } 852 } 853 } 854 } 855 return d, f.ByteOrder, data 856 } 857 858 if f, err := pe.Open(gccTmp()); err == nil { 859 defer f.Close() 860 d, err := f.DWARF() 861 if err != nil { 862 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 863 } 864 var data []byte 865 for _, s := range f.Symbols { 866 if isDebugData(s.Name) { 867 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 868 sect := f.Sections[i] 869 if s.Value < sect.Size { 870 if sdat, err := sect.Data(); err == nil { 871 data = sdat[s.Value:] 872 } 873 } 874 } 875 } 876 } 877 return d, binary.LittleEndian, data 878 } 879 880 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) 881 panic("not reached") 882 } 883 884 // gccDefines runs gcc -E -dM -xc - over the C program stdin 885 // and returns the corresponding standard output, which is the 886 // #defines that gcc encountered while processing the input 887 // and its included files. 888 func (p *Package) gccDefines(stdin []byte) string { 889 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc") 890 base = append(base, p.gccMachine()...) 891 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 892 return stdout 893 } 894 895 // gccErrors runs gcc over the C program stdin and returns 896 // the errors that gcc prints. That is, this function expects 897 // gcc to fail. 898 func (p *Package) gccErrors(stdin []byte) string { 899 // TODO(rsc): require failure 900 args := p.gccCmd() 901 902 if *debugGcc { 903 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 904 os.Stderr.Write(stdin) 905 fmt.Fprint(os.Stderr, "EOF\n") 906 } 907 stdout, stderr, _ := run(stdin, args) 908 if *debugGcc { 909 os.Stderr.Write(stdout) 910 os.Stderr.Write(stderr) 911 } 912 return string(stderr) 913 } 914 915 // runGcc runs the gcc command line args with stdin on standard input. 916 // If the command exits with a non-zero exit status, runGcc prints 917 // details about what was run and exits. 918 // Otherwise runGcc returns the data written to standard output and standard error. 919 // Note that for some of the uses we expect useful data back 920 // on standard error, but for those uses gcc must still exit 0. 921 func runGcc(stdin []byte, args []string) (string, string) { 922 if *debugGcc { 923 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 924 os.Stderr.Write(stdin) 925 fmt.Fprint(os.Stderr, "EOF\n") 926 } 927 stdout, stderr, ok := run(stdin, args) 928 if *debugGcc { 929 os.Stderr.Write(stdout) 930 os.Stderr.Write(stderr) 931 } 932 if !ok { 933 os.Stderr.Write(stderr) 934 os.Exit(2) 935 } 936 return string(stdout), string(stderr) 937 } 938 939 // A typeConv is a translator from dwarf types to Go types 940 // with equivalent memory layout. 941 type typeConv struct { 942 // Cache of already-translated or in-progress types. 943 m map[dwarf.Type]*Type 944 typedef map[string]ast.Expr 945 946 // Map from types to incomplete pointers to those types. 947 ptrs map[dwarf.Type][]*Type 948 // Keys of ptrs in insertion order (deterministic worklist) 949 ptrKeys []dwarf.Type 950 951 // Predeclared types. 952 bool ast.Expr 953 byte ast.Expr // denotes padding 954 int8, int16, int32, int64 ast.Expr 955 uint8, uint16, uint32, uint64, uintptr ast.Expr 956 float32, float64 ast.Expr 957 complex64, complex128 ast.Expr 958 void ast.Expr 959 string ast.Expr 960 goVoid ast.Expr // _Ctype_void, denotes C's void 961 goVoidPtr ast.Expr // unsafe.Pointer or *byte 962 963 ptrSize int64 964 intSize int64 965 } 966 967 var tagGen int 968 var typedef = make(map[string]*Type) 969 var goIdent = make(map[string]*ast.Ident) 970 971 func (c *typeConv) Init(ptrSize, intSize int64) { 972 c.ptrSize = ptrSize 973 c.intSize = intSize 974 c.m = make(map[dwarf.Type]*Type) 975 c.ptrs = make(map[dwarf.Type][]*Type) 976 c.bool = c.Ident("bool") 977 c.byte = c.Ident("byte") 978 c.int8 = c.Ident("int8") 979 c.int16 = c.Ident("int16") 980 c.int32 = c.Ident("int32") 981 c.int64 = c.Ident("int64") 982 c.uint8 = c.Ident("uint8") 983 c.uint16 = c.Ident("uint16") 984 c.uint32 = c.Ident("uint32") 985 c.uint64 = c.Ident("uint64") 986 c.uintptr = c.Ident("uintptr") 987 c.float32 = c.Ident("float32") 988 c.float64 = c.Ident("float64") 989 c.complex64 = c.Ident("complex64") 990 c.complex128 = c.Ident("complex128") 991 c.void = c.Ident("void") 992 c.string = c.Ident("string") 993 c.goVoid = c.Ident("_Ctype_void") 994 995 // Normally cgo translates void* to unsafe.Pointer, 996 // but for historical reasons -godefs uses *byte instead. 997 if *godefs { 998 c.goVoidPtr = &ast.StarExpr{X: c.byte} 999 } else { 1000 c.goVoidPtr = c.Ident("unsafe.Pointer") 1001 } 1002 } 1003 1004 // base strips away qualifiers and typedefs to get the underlying type 1005 func base(dt dwarf.Type) dwarf.Type { 1006 for { 1007 if d, ok := dt.(*dwarf.QualType); ok { 1008 dt = d.Type 1009 continue 1010 } 1011 if d, ok := dt.(*dwarf.TypedefType); ok { 1012 dt = d.Type 1013 continue 1014 } 1015 break 1016 } 1017 return dt 1018 } 1019 1020 // Map from dwarf text names to aliases we use in package "C". 1021 var dwarfToName = map[string]string{ 1022 "long int": "long", 1023 "long unsigned int": "ulong", 1024 "unsigned int": "uint", 1025 "short unsigned int": "ushort", 1026 "short int": "short", 1027 "long long int": "longlong", 1028 "long long unsigned int": "ulonglong", 1029 "signed char": "schar", 1030 "float complex": "complexfloat", 1031 "double complex": "complexdouble", 1032 } 1033 1034 const signedDelta = 64 1035 1036 // String returns the current type representation. Format arguments 1037 // are assembled within this method so that any changes in mutable 1038 // values are taken into account. 1039 func (tr *TypeRepr) String() string { 1040 if len(tr.Repr) == 0 { 1041 return "" 1042 } 1043 if len(tr.FormatArgs) == 0 { 1044 return tr.Repr 1045 } 1046 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 1047 } 1048 1049 // Empty reports whether the result of String would be "". 1050 func (tr *TypeRepr) Empty() bool { 1051 return len(tr.Repr) == 0 1052 } 1053 1054 // Set modifies the type representation. 1055 // If fargs are provided, repr is used as a format for fmt.Sprintf. 1056 // Otherwise, repr is used unprocessed as the type representation. 1057 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 1058 tr.Repr = repr 1059 tr.FormatArgs = fargs 1060 } 1061 1062 // FinishType completes any outstanding type mapping work. 1063 // In particular, it resolves incomplete pointer types. 1064 func (c *typeConv) FinishType(pos token.Pos) { 1065 // Completing one pointer type might produce more to complete. 1066 // Keep looping until they're all done. 1067 for len(c.ptrKeys) > 0 { 1068 dtype := c.ptrKeys[0] 1069 c.ptrKeys = c.ptrKeys[1:] 1070 1071 // Note Type might invalidate c.ptrs[dtype]. 1072 t := c.Type(dtype, pos) 1073 for _, ptr := range c.ptrs[dtype] { 1074 ptr.Go.(*ast.StarExpr).X = t.Go 1075 ptr.C.Set("%s*", t.C) 1076 } 1077 c.ptrs[dtype] = nil // retain the map key 1078 } 1079 } 1080 1081 // Type returns a *Type with the same memory layout as 1082 // dtype when used as the type of a variable or a struct field. 1083 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 1084 if t, ok := c.m[dtype]; ok { 1085 if t.Go == nil { 1086 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 1087 } 1088 return t 1089 } 1090 1091 t := new(Type) 1092 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 1093 t.Align = -1 1094 t.C = &TypeRepr{Repr: dtype.Common().Name} 1095 c.m[dtype] = t 1096 1097 switch dt := dtype.(type) { 1098 default: 1099 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 1100 1101 case *dwarf.AddrType: 1102 if t.Size != c.ptrSize { 1103 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 1104 } 1105 t.Go = c.uintptr 1106 t.Align = t.Size 1107 1108 case *dwarf.ArrayType: 1109 if dt.StrideBitSize > 0 { 1110 // Cannot represent bit-sized elements in Go. 1111 t.Go = c.Opaque(t.Size) 1112 break 1113 } 1114 count := dt.Count 1115 if count == -1 { 1116 // Indicates flexible array member, which Go doesn't support. 1117 // Translate to zero-length array instead. 1118 count = 0 1119 } 1120 sub := c.Type(dt.Type, pos) 1121 t.Align = sub.Align 1122 t.Go = &ast.ArrayType{ 1123 Len: c.intExpr(count), 1124 Elt: sub.Go, 1125 } 1126 // Recalculate t.Size now that we know sub.Size. 1127 t.Size = count * sub.Size 1128 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 1129 1130 case *dwarf.BoolType: 1131 t.Go = c.bool 1132 t.Align = 1 1133 1134 case *dwarf.CharType: 1135 if t.Size != 1 { 1136 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 1137 } 1138 t.Go = c.int8 1139 t.Align = 1 1140 1141 case *dwarf.EnumType: 1142 if t.Align = t.Size; t.Align >= c.ptrSize { 1143 t.Align = c.ptrSize 1144 } 1145 t.C.Set("enum " + dt.EnumName) 1146 signed := 0 1147 t.EnumValues = make(map[string]int64) 1148 for _, ev := range dt.Val { 1149 t.EnumValues[ev.Name] = ev.Val 1150 if ev.Val < 0 { 1151 signed = signedDelta 1152 } 1153 } 1154 switch t.Size + int64(signed) { 1155 default: 1156 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 1157 case 1: 1158 t.Go = c.uint8 1159 case 2: 1160 t.Go = c.uint16 1161 case 4: 1162 t.Go = c.uint32 1163 case 8: 1164 t.Go = c.uint64 1165 case 1 + signedDelta: 1166 t.Go = c.int8 1167 case 2 + signedDelta: 1168 t.Go = c.int16 1169 case 4 + signedDelta: 1170 t.Go = c.int32 1171 case 8 + signedDelta: 1172 t.Go = c.int64 1173 } 1174 1175 case *dwarf.FloatType: 1176 switch t.Size { 1177 default: 1178 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 1179 case 4: 1180 t.Go = c.float32 1181 case 8: 1182 t.Go = c.float64 1183 } 1184 if t.Align = t.Size; t.Align >= c.ptrSize { 1185 t.Align = c.ptrSize 1186 } 1187 1188 case *dwarf.ComplexType: 1189 switch t.Size { 1190 default: 1191 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 1192 case 8: 1193 t.Go = c.complex64 1194 case 16: 1195 t.Go = c.complex128 1196 } 1197 if t.Align = t.Size; t.Align >= c.ptrSize { 1198 t.Align = c.ptrSize 1199 } 1200 1201 case *dwarf.FuncType: 1202 // No attempt at translation: would enable calls 1203 // directly between worlds, but we need to moderate those. 1204 t.Go = c.uintptr 1205 t.Align = c.ptrSize 1206 1207 case *dwarf.IntType: 1208 if dt.BitSize > 0 { 1209 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 1210 } 1211 switch t.Size { 1212 default: 1213 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 1214 case 1: 1215 t.Go = c.int8 1216 case 2: 1217 t.Go = c.int16 1218 case 4: 1219 t.Go = c.int32 1220 case 8: 1221 t.Go = c.int64 1222 } 1223 if t.Align = t.Size; t.Align >= c.ptrSize { 1224 t.Align = c.ptrSize 1225 } 1226 1227 case *dwarf.PtrType: 1228 // Clang doesn't emit DW_AT_byte_size for pointer types. 1229 if t.Size != c.ptrSize && t.Size != -1 { 1230 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype) 1231 } 1232 t.Size = c.ptrSize 1233 t.Align = c.ptrSize 1234 1235 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 1236 t.Go = c.goVoidPtr 1237 t.C.Set("void*") 1238 break 1239 } 1240 1241 // Placeholder initialization; completed in FinishType. 1242 t.Go = &ast.StarExpr{} 1243 t.C.Set("<incomplete>*") 1244 if _, ok := c.ptrs[dt.Type]; !ok { 1245 c.ptrKeys = append(c.ptrKeys, dt.Type) 1246 } 1247 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t) 1248 1249 case *dwarf.QualType: 1250 // Ignore qualifier. 1251 t = c.Type(dt.Type, pos) 1252 c.m[dtype] = t 1253 return t 1254 1255 case *dwarf.StructType: 1256 // Convert to Go struct, being careful about alignment. 1257 // Have to give it a name to simulate C "struct foo" references. 1258 tag := dt.StructName 1259 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 1260 break 1261 } 1262 if tag == "" { 1263 tag = "__" + strconv.Itoa(tagGen) 1264 tagGen++ 1265 } else if t.C.Empty() { 1266 t.C.Set(dt.Kind + " " + tag) 1267 } 1268 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 1269 t.Go = name // publish before recursive calls 1270 goIdent[name.Name] = name 1271 if dt.ByteSize < 0 { 1272 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 1273 // so execute the basic things that the struct case would do 1274 // other than try to determine a Go representation. 1275 tt := *t 1276 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 1277 tt.Go = c.Ident("struct{}") 1278 typedef[name.Name] = &tt 1279 break 1280 } 1281 switch dt.Kind { 1282 case "class", "union": 1283 t.Go = c.Opaque(t.Size) 1284 if t.C.Empty() { 1285 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 1286 } 1287 t.Align = 1 // TODO: should probably base this on field alignment. 1288 typedef[name.Name] = t 1289 case "struct": 1290 g, csyntax, align := c.Struct(dt, pos) 1291 if t.C.Empty() { 1292 t.C.Set(csyntax) 1293 } 1294 t.Align = align 1295 tt := *t 1296 if tag != "" { 1297 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 1298 } 1299 tt.Go = g 1300 typedef[name.Name] = &tt 1301 } 1302 1303 case *dwarf.TypedefType: 1304 // Record typedef for printing. 1305 if dt.Name == "_GoString_" { 1306 // Special C name for Go string type. 1307 // Knows string layout used by compilers: pointer plus length, 1308 // which rounds up to 2 pointers after alignment. 1309 t.Go = c.string 1310 t.Size = c.ptrSize * 2 1311 t.Align = c.ptrSize 1312 break 1313 } 1314 if dt.Name == "_GoBytes_" { 1315 // Special C name for Go []byte type. 1316 // Knows slice layout used by compilers: pointer, length, cap. 1317 t.Go = c.Ident("[]byte") 1318 t.Size = c.ptrSize + 4 + 4 1319 t.Align = c.ptrSize 1320 break 1321 } 1322 name := c.Ident("_Ctype_" + dt.Name) 1323 goIdent[name.Name] = name 1324 sub := c.Type(dt.Type, pos) 1325 t.Go = name 1326 t.Size = sub.Size 1327 t.Align = sub.Align 1328 oldType := typedef[name.Name] 1329 if oldType == nil { 1330 tt := *t 1331 tt.Go = sub.Go 1332 typedef[name.Name] = &tt 1333 } 1334 1335 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 1336 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 1337 // with the base type. 1338 // In -godefs mode, do this for all typedefs. 1339 if isStructUnionClass(sub.Go) || *godefs { 1340 t.Go = sub.Go 1341 1342 if isStructUnionClass(sub.Go) { 1343 // Use the typedef name for C code. 1344 typedef[sub.Go.(*ast.Ident).Name].C = t.C 1345 } 1346 1347 // If we've seen this typedef before, and it 1348 // was an anonymous struct/union/class before 1349 // too, use the old definition. 1350 // TODO: it would be safer to only do this if 1351 // we verify that the types are the same. 1352 if oldType != nil && isStructUnionClass(oldType.Go) { 1353 t.Go = oldType.Go 1354 } 1355 } 1356 1357 case *dwarf.UcharType: 1358 if t.Size != 1 { 1359 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 1360 } 1361 t.Go = c.uint8 1362 t.Align = 1 1363 1364 case *dwarf.UintType: 1365 if dt.BitSize > 0 { 1366 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 1367 } 1368 switch t.Size { 1369 default: 1370 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 1371 case 1: 1372 t.Go = c.uint8 1373 case 2: 1374 t.Go = c.uint16 1375 case 4: 1376 t.Go = c.uint32 1377 case 8: 1378 t.Go = c.uint64 1379 } 1380 if t.Align = t.Size; t.Align >= c.ptrSize { 1381 t.Align = c.ptrSize 1382 } 1383 1384 case *dwarf.VoidType: 1385 t.Go = c.goVoid 1386 t.C.Set("void") 1387 t.Align = 1 1388 } 1389 1390 switch dtype.(type) { 1391 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 1392 s := dtype.Common().Name 1393 if s != "" { 1394 if ss, ok := dwarfToName[s]; ok { 1395 s = ss 1396 } 1397 s = strings.Join(strings.Split(s, " "), "") // strip spaces 1398 name := c.Ident("_Ctype_" + s) 1399 tt := *t 1400 typedef[name.Name] = &tt 1401 if !*godefs { 1402 t.Go = name 1403 } 1404 } 1405 } 1406 1407 if t.Size < 0 { 1408 // Unsized types are [0]byte, unless they're typedefs of other types 1409 // or structs with tags. 1410 // if so, use the name we've already defined. 1411 t.Size = 0 1412 switch dt := dtype.(type) { 1413 case *dwarf.TypedefType: 1414 // ok 1415 case *dwarf.StructType: 1416 if dt.StructName != "" { 1417 break 1418 } 1419 t.Go = c.Opaque(0) 1420 default: 1421 t.Go = c.Opaque(0) 1422 } 1423 if t.C.Empty() { 1424 t.C.Set("void") 1425 } 1426 } 1427 1428 if t.C.Empty() { 1429 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 1430 } 1431 1432 return t 1433 } 1434 1435 // isStructUnionClass reports whether the type described by the Go syntax x 1436 // is a struct, union, or class with a tag. 1437 func isStructUnionClass(x ast.Expr) bool { 1438 id, ok := x.(*ast.Ident) 1439 if !ok { 1440 return false 1441 } 1442 name := id.Name 1443 return strings.HasPrefix(name, "_Ctype_struct_") || 1444 strings.HasPrefix(name, "_Ctype_union_") || 1445 strings.HasPrefix(name, "_Ctype_class_") 1446 } 1447 1448 // FuncArg returns a Go type with the same memory layout as 1449 // dtype when used as the type of a C function argument. 1450 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 1451 t := c.Type(dtype, pos) 1452 switch dt := dtype.(type) { 1453 case *dwarf.ArrayType: 1454 // Arrays are passed implicitly as pointers in C. 1455 // In Go, we must be explicit. 1456 tr := &TypeRepr{} 1457 tr.Set("%s*", t.C) 1458 return &Type{ 1459 Size: c.ptrSize, 1460 Align: c.ptrSize, 1461 Go: &ast.StarExpr{X: t.Go}, 1462 C: tr, 1463 } 1464 case *dwarf.TypedefType: 1465 // C has much more relaxed rules than Go for 1466 // implicit type conversions. When the parameter 1467 // is type T defined as *X, simulate a little of the 1468 // laxness of C by making the argument *X instead of T. 1469 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 1470 // Unless the typedef happens to point to void* since 1471 // Go has special rules around using unsafe.Pointer. 1472 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 1473 break 1474 } 1475 1476 t = c.Type(ptr, pos) 1477 if t == nil { 1478 return nil 1479 } 1480 1481 // Remember the C spelling, in case the struct 1482 // has __attribute__((unavailable)) on it. See issue 2888. 1483 t.Typedef = dt.Name 1484 } 1485 } 1486 return t 1487 } 1488 1489 // FuncType returns the Go type analogous to dtype. 1490 // There is no guarantee about matching memory layout. 1491 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 1492 p := make([]*Type, len(dtype.ParamType)) 1493 gp := make([]*ast.Field, len(dtype.ParamType)) 1494 for i, f := range dtype.ParamType { 1495 // gcc's DWARF generator outputs a single DotDotDotType parameter for 1496 // function pointers that specify no parameters (e.g. void 1497 // (*__cgo_0)()). Treat this special case as void. This case is 1498 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 1499 // legal). 1500 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 1501 p, gp = nil, nil 1502 break 1503 } 1504 p[i] = c.FuncArg(f, pos) 1505 gp[i] = &ast.Field{Type: p[i].Go} 1506 } 1507 var r *Type 1508 var gr []*ast.Field 1509 if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok { 1510 gr = []*ast.Field{{Type: c.goVoid}} 1511 } else if dtype.ReturnType != nil { 1512 r = c.Type(dtype.ReturnType, pos) 1513 gr = []*ast.Field{{Type: r.Go}} 1514 } 1515 return &FuncType{ 1516 Params: p, 1517 Result: r, 1518 Go: &ast.FuncType{ 1519 Params: &ast.FieldList{List: gp}, 1520 Results: &ast.FieldList{List: gr}, 1521 }, 1522 } 1523 } 1524 1525 // Identifier 1526 func (c *typeConv) Ident(s string) *ast.Ident { 1527 return ast.NewIdent(s) 1528 } 1529 1530 // Opaque type of n bytes. 1531 func (c *typeConv) Opaque(n int64) ast.Expr { 1532 return &ast.ArrayType{ 1533 Len: c.intExpr(n), 1534 Elt: c.byte, 1535 } 1536 } 1537 1538 // Expr for integer n. 1539 func (c *typeConv) intExpr(n int64) ast.Expr { 1540 return &ast.BasicLit{ 1541 Kind: token.INT, 1542 Value: strconv.FormatInt(n, 10), 1543 } 1544 } 1545 1546 // Add padding of given size to fld. 1547 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) { 1548 n := len(fld) 1549 fld = fld[0 : n+1] 1550 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 1551 sizes = sizes[0 : n+1] 1552 sizes[n] = size 1553 return fld, sizes 1554 } 1555 1556 // Struct conversion: return Go and (gc) C syntax for type. 1557 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 1558 // Minimum alignment for a struct is 1 byte. 1559 align = 1 1560 1561 var buf bytes.Buffer 1562 buf.WriteString("struct {") 1563 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 1564 sizes := make([]int64, 0, 2*len(dt.Field)+1) 1565 off := int64(0) 1566 1567 // Rename struct fields that happen to be named Go keywords into 1568 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 1569 // be mangled. Any existing identifier that already has the same name on 1570 // the C-side will cause the Go-mangled version to be prefixed with _. 1571 // (e.g. in a struct with fields '_type' and 'type', the latter would be 1572 // rendered as '__type' in Go). 1573 ident := make(map[string]string) 1574 used := make(map[string]bool) 1575 for _, f := range dt.Field { 1576 ident[f.Name] = f.Name 1577 used[f.Name] = true 1578 } 1579 1580 if !*godefs { 1581 for cid, goid := range ident { 1582 if token.Lookup(goid).IsKeyword() { 1583 // Avoid keyword 1584 goid = "_" + goid 1585 1586 // Also avoid existing fields 1587 for _, exist := used[goid]; exist; _, exist = used[goid] { 1588 goid = "_" + goid 1589 } 1590 1591 used[goid] = true 1592 ident[cid] = goid 1593 } 1594 } 1595 } 1596 1597 anon := 0 1598 for _, f := range dt.Field { 1599 if f.ByteOffset > off { 1600 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off) 1601 off = f.ByteOffset 1602 } 1603 1604 name := f.Name 1605 ft := f.Type 1606 1607 // In godefs mode, if this field is a C11 1608 // anonymous union then treat the first field in the 1609 // union as the field in the struct. This handles 1610 // cases like the glibc <sys/resource.h> file; see 1611 // issue 6677. 1612 if *godefs { 1613 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] { 1614 name = st.Field[0].Name 1615 ident[name] = name 1616 ft = st.Field[0].Type 1617 } 1618 } 1619 1620 // TODO: Handle fields that are anonymous structs by 1621 // promoting the fields of the inner struct. 1622 1623 t := c.Type(ft, pos) 1624 tgo := t.Go 1625 size := t.Size 1626 talign := t.Align 1627 if f.BitSize > 0 { 1628 if f.BitSize%8 != 0 { 1629 continue 1630 } 1631 size = f.BitSize / 8 1632 name := tgo.(*ast.Ident).String() 1633 if strings.HasPrefix(name, "int") { 1634 name = "int" 1635 } else { 1636 name = "uint" 1637 } 1638 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) 1639 talign = size 1640 } 1641 1642 if talign > 0 && f.ByteOffset%talign != 0 { 1643 // Drop misaligned fields, the same way we drop integer bit fields. 1644 // The goal is to make available what can be made available. 1645 // Otherwise one bad and unneeded field in an otherwise okay struct 1646 // makes the whole program not compile. Much of the time these 1647 // structs are in system headers that cannot be corrected. 1648 continue 1649 } 1650 n := len(fld) 1651 fld = fld[0 : n+1] 1652 if name == "" { 1653 name = fmt.Sprintf("anon%d", anon) 1654 anon++ 1655 ident[name] = name 1656 } 1657 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 1658 sizes = sizes[0 : n+1] 1659 sizes[n] = size 1660 off += size 1661 buf.WriteString(t.C.String()) 1662 buf.WriteString(" ") 1663 buf.WriteString(name) 1664 buf.WriteString("; ") 1665 if talign > align { 1666 align = talign 1667 } 1668 } 1669 if off < dt.ByteSize { 1670 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off) 1671 off = dt.ByteSize 1672 } 1673 1674 // If the last field in a non-zero-sized struct is zero-sized 1675 // the compiler is going to pad it by one (see issue 9401). 1676 // We can't permit that, because then the size of the Go 1677 // struct will not be the same as the size of the C struct. 1678 // Our only option in such a case is to remove the field, 1679 // which means that it can not be referenced from Go. 1680 for off > 0 && sizes[len(sizes)-1] == 0 { 1681 n := len(sizes) 1682 fld = fld[0 : n-1] 1683 sizes = sizes[0 : n-1] 1684 } 1685 1686 if off != dt.ByteSize { 1687 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 1688 } 1689 buf.WriteString("}") 1690 csyntax = buf.String() 1691 1692 if *godefs { 1693 godefsFields(fld) 1694 } 1695 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 1696 return 1697 } 1698 1699 func upper(s string) string { 1700 if s == "" { 1701 return "" 1702 } 1703 r, size := utf8.DecodeRuneInString(s) 1704 if r == '_' { 1705 return "X" + s 1706 } 1707 return string(unicode.ToUpper(r)) + s[size:] 1708 } 1709 1710 // godefsFields rewrites field names for use in Go or C definitions. 1711 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 1712 // converts names to upper case, and rewrites _ into Pad_godefs_n, 1713 // so that all fields are exported. 1714 func godefsFields(fld []*ast.Field) { 1715 prefix := fieldPrefix(fld) 1716 npad := 0 1717 for _, f := range fld { 1718 for _, n := range f.Names { 1719 if n.Name != prefix { 1720 n.Name = strings.TrimPrefix(n.Name, prefix) 1721 } 1722 if n.Name == "_" { 1723 // Use exported name instead. 1724 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 1725 npad++ 1726 } 1727 n.Name = upper(n.Name) 1728 } 1729 } 1730 } 1731 1732 // fieldPrefix returns the prefix that should be removed from all the 1733 // field names when generating the C or Go code. For generated 1734 // C, we leave the names as is (tv_sec, tv_usec), since that's what 1735 // people are used to seeing in C. For generated Go code, such as 1736 // package syscall's data structures, we drop a common prefix 1737 // (so sec, usec, which will get turned into Sec, Usec for exporting). 1738 func fieldPrefix(fld []*ast.Field) string { 1739 prefix := "" 1740 for _, f := range fld { 1741 for _, n := range f.Names { 1742 // Ignore field names that don't have the prefix we're 1743 // looking for. It is common in C headers to have fields 1744 // named, say, _pad in an otherwise prefixed header. 1745 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 1746 // still want to remove the tv_ prefix. 1747 // The check for "orig_" here handles orig_eax in the 1748 // x86 ptrace register sets, which otherwise have all fields 1749 // with reg_ prefixes. 1750 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 1751 continue 1752 } 1753 i := strings.Index(n.Name, "_") 1754 if i < 0 { 1755 continue 1756 } 1757 if prefix == "" { 1758 prefix = n.Name[:i+1] 1759 } else if prefix != n.Name[:i+1] { 1760 return "" 1761 } 1762 } 1763 } 1764 return prefix 1765 } 1766