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