github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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 var safeBytes = []byte(`+-.,/0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz`) 158 159 func safeName(s string) bool { 160 if s == "" { 161 return false 162 } 163 for i := 0; i < len(s); i++ { 164 if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 { 165 return false 166 } 167 } 168 return true 169 } 170 171 // Translate rewrites f.AST, the original Go input, to remove 172 // references to the imported package C, replacing them with 173 // references to the equivalent Go types, functions, and variables. 174 func (p *Package) Translate(f *File) { 175 for _, cref := range f.Ref { 176 // Convert C.ulong to C.unsigned long, etc. 177 cref.Name.C = cname(cref.Name.Go) 178 } 179 p.loadDefines(f) 180 needType := p.guessKinds(f) 181 if len(needType) > 0 { 182 p.loadDWARF(f, needType) 183 } 184 p.rewriteRef(f) 185 } 186 187 // loadDefines coerces gcc into spitting out the #defines in use 188 // in the file f and saves relevant renamings in f.Name[name].Define. 189 func (p *Package) loadDefines(f *File) { 190 var b bytes.Buffer 191 b.WriteString(f.Preamble) 192 b.WriteString(builtinProlog) 193 stdout := p.gccDefines(b.Bytes()) 194 195 for _, line := range strings.Split(stdout, "\n") { 196 if len(line) < 9 || line[0:7] != "#define" { 197 continue 198 } 199 200 line = strings.TrimSpace(line[8:]) 201 202 var key, val string 203 spaceIndex := strings.Index(line, " ") 204 tabIndex := strings.Index(line, "\t") 205 206 if spaceIndex == -1 && tabIndex == -1 { 207 continue 208 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) { 209 key = line[0:spaceIndex] 210 val = strings.TrimSpace(line[spaceIndex:]) 211 } else { 212 key = line[0:tabIndex] 213 val = strings.TrimSpace(line[tabIndex:]) 214 } 215 216 if n := f.Name[key]; n != nil { 217 if *debugDefine { 218 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val) 219 } 220 n.Define = val 221 } 222 } 223 } 224 225 // guessKinds tricks gcc into revealing the kind of each 226 // name xxx for the references C.xxx in the Go input. 227 // The kind is either a constant, type, or variable. 228 func (p *Package) guessKinds(f *File) []*Name { 229 // Determine kinds for names we already know about, 230 // like #defines or 'struct foo', before bothering with gcc. 231 var names, needType []*Name 232 for _, n := range f.Name { 233 // If we've already found this name as a #define 234 // and we can translate it as a constant value, do so. 235 if n.Define != "" { 236 isConst := false 237 if _, err := strconv.Atoi(n.Define); err == nil { 238 isConst = true 239 } else if n.Define[0] == '"' || n.Define[0] == '\'' { 240 if _, err := parser.ParseExpr(n.Define); err == nil { 241 isConst = true 242 } 243 } 244 if isConst { 245 n.Kind = "const" 246 // Turn decimal into hex, just for consistency 247 // with enum-derived constants. Otherwise 248 // in the cgo -godefs output half the constants 249 // are in hex and half are in whatever the #define used. 250 i, err := strconv.ParseInt(n.Define, 0, 64) 251 if err == nil { 252 n.Const = fmt.Sprintf("%#x", i) 253 } else { 254 n.Const = n.Define 255 } 256 continue 257 } 258 259 if isName(n.Define) { 260 n.C = n.Define 261 } 262 } 263 264 needType = append(needType, n) 265 266 // If this is a struct, union, or enum type name, no need to guess the kind. 267 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") { 268 n.Kind = "type" 269 continue 270 } 271 272 // Otherwise, we'll need to find out from gcc. 273 names = append(names, n) 274 } 275 276 // Bypass gcc if there's nothing left to find out. 277 if len(names) == 0 { 278 return needType 279 } 280 281 // Coerce gcc into telling us whether each name is a type, a value, or undeclared. 282 // For names, find out whether they are integer constants. 283 // We used to look at specific warning or error messages here, but that tied the 284 // behavior too closely to specific versions of the compilers. 285 // Instead, arrange that we can infer what we need from only the presence or absence 286 // of an error on a specific line. 287 // 288 // For each name, we generate these lines, where xxx is the index in toSniff plus one. 289 // 290 // #line xxx "not-declared" 291 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__; } 292 // #line xxx "not-type" 293 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__; } 294 // #line xxx "not-const" 295 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__ = (name)*1 }; } 296 // 297 // If we see an error at not-declared:xxx, the corresponding name is not declared. 298 // If we see an error at not-type:xxx, the corresponding name is a type. 299 // If we see an error at not-const:xxx, the corresponding name is not an integer constant. 300 // If we see no errors, we assume the name is an expression but not a constant 301 // (so a variable or a function). 302 // 303 // The specific input forms are chosen so that they are valid C syntax regardless of 304 // whether name denotes a type or an expression. 305 306 var b bytes.Buffer 307 b.WriteString(f.Preamble) 308 b.WriteString(builtinProlog) 309 310 for i, n := range names { 311 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+ 312 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__; }\n"+ 313 "#line %d \"not-type\"\n"+ 314 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__; }\n"+ 315 "#line %d \"not-const\"\n"+ 316 "void __cgo_f_%d_3(void) { enum { __cgo__undefined__ = (%s)*1 }; }\n", 317 i+1, i+1, n.C, 318 i+1, i+1, n.C, 319 i+1, i+1, n.C) 320 } 321 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+ 322 "int __cgo__1 = __cgo__2;\n") 323 324 stderr := p.gccErrors(b.Bytes()) 325 if stderr == "" { 326 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes()) 327 } 328 329 completed := false 330 sniff := make([]int, len(names)) 331 const ( 332 notType = 1 << iota 333 notConst 334 ) 335 for _, line := range strings.Split(stderr, "\n") { 336 if !strings.Contains(line, ": error:") { 337 // we only care about errors. 338 // we tried to turn off warnings on the command line, but one never knows. 339 continue 340 } 341 342 c1 := strings.Index(line, ":") 343 if c1 < 0 { 344 continue 345 } 346 c2 := strings.Index(line[c1+1:], ":") 347 if c2 < 0 { 348 continue 349 } 350 c2 += c1 + 1 351 352 filename := line[:c1] 353 i, _ := strconv.Atoi(line[c1+1 : c2]) 354 i-- 355 if i < 0 || i >= len(names) { 356 continue 357 } 358 359 switch filename { 360 case "completed": 361 // Strictly speaking, there is no guarantee that seeing the error at completed:1 362 // (at the end of the file) means we've seen all the errors from earlier in the file, 363 // but usually it does. Certainly if we don't see the completed:1 error, we did 364 // not get all the errors we expected. 365 completed = true 366 367 case "not-declared": 368 error_(token.NoPos, "%s", strings.TrimSpace(line[c2+1:])) 369 case "not-type": 370 sniff[i] |= notType 371 case "not-const": 372 sniff[i] |= notConst 373 } 374 } 375 376 if !completed { 377 fatalf("%s did not produce error at completed:1\non input:\n%s", p.gccBaseCmd()[0], b.Bytes()) 378 } 379 380 for i, n := range names { 381 switch sniff[i] { 382 case 0: 383 error_(token.NoPos, "could not determine kind of name for C.%s", fixGo(n.Go)) 384 case notType: 385 n.Kind = "const" 386 case notConst: 387 n.Kind = "type" 388 case notConst | notType: 389 n.Kind = "not-type" 390 } 391 } 392 if nerrors > 0 { 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 } 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 or *cdefs 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 expr = ast.NewIdent(name.Mangle) 653 } else if r.Name.Kind == "type" { 654 // Okay - might be new(T) 655 expr = r.Name.Type.Go 656 } else if r.Name.Kind == "var" { 657 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 658 } 659 660 case "type": 661 if r.Name.Kind != "type" { 662 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 663 } else if r.Name.Type == nil { 664 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 665 // GCC won't raise an error when using pointers to such unknown types. 666 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 667 } else { 668 expr = r.Name.Type.Go 669 } 670 default: 671 if r.Name.Kind == "func" { 672 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 673 } 674 } 675 if *godefs || *cdefs { 676 // Substitute definition for mangled type name. 677 if id, ok := expr.(*ast.Ident); ok { 678 if t := typedef[id.Name]; t != nil { 679 expr = t.Go 680 } 681 if id.Name == r.Name.Mangle && r.Name.Const != "" { 682 expr = ast.NewIdent(r.Name.Const) 683 } 684 } 685 } 686 687 // Copy position information from old expr into new expr, 688 // in case expression being replaced is first on line. 689 // See golang.org/issue/6563. 690 pos := (*r.Expr).Pos() 691 switch x := expr.(type) { 692 case *ast.Ident: 693 expr = &ast.Ident{NamePos: pos, Name: x.Name} 694 } 695 696 *r.Expr = expr 697 } 698 699 // Remove functions only used as expressions, so their respective 700 // bridge functions are not generated. 701 for name, used := range functions { 702 if !used { 703 delete(f.Name, name) 704 } 705 } 706 } 707 708 // gccBaseCmd returns the start of the compiler command line. 709 // It uses $CC if set, or else $GCC, or else the compiler recorded 710 // during the initial build as defaultCC. 711 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 712 func (p *Package) gccBaseCmd() []string { 713 // Use $CC if set, since that's what the build uses. 714 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 { 715 return ret 716 } 717 // Try $GCC if set, since that's what we used to use. 718 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 { 719 return ret 720 } 721 return strings.Fields(defaultCC) 722 } 723 724 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 725 func (p *Package) gccMachine() []string { 726 switch goarch { 727 case "amd64": 728 return []string{"-m64"} 729 case "386": 730 return []string{"-m32"} 731 case "arm": 732 return []string{"-marm"} // not thumb 733 } 734 return nil 735 } 736 737 func gccTmp() string { 738 return *objDir + "_cgo_.o" 739 } 740 741 // gccCmd returns the gcc command line to use for compiling 742 // the input. 743 func (p *Package) gccCmd() []string { 744 c := append(p.gccBaseCmd(), 745 "-w", // no warnings 746 "-Wno-error", // warnings are not errors 747 "-o"+gccTmp(), // write object to tmp 748 "-gdwarf-2", // generate DWARF v2 debugging symbols 749 "-c", // do not link 750 "-xc", // input language is C 751 ) 752 if strings.Contains(c[0], "clang") { 753 c = append(c, 754 "-ferror-limit=0", 755 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 756 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 757 // flag to disable the warning. Yes, really good diagnostics, clang. 758 "-Wno-unknown-warning-option", 759 "-Wno-unneeded-internal-declaration", 760 "-Wno-unused-function", 761 "-Qunused-arguments", 762 // Clang embeds prototypes for some builtin functions, 763 // like malloc and calloc, but all size_t parameters are 764 // incorrectly typed unsigned long. We work around that 765 // by disabling the builtin functions (this is safe as 766 // it won't affect the actual compilation of the C code). 767 // See: http://golang.org/issue/6506. 768 "-fno-builtin", 769 ) 770 } 771 772 c = append(c, p.GccOptions...) 773 c = append(c, p.gccMachine()...) 774 c = append(c, "-") //read input from standard input 775 return c 776 } 777 778 // gccDebug runs gcc -gdwarf-2 over the C program stdin and 779 // returns the corresponding DWARF data and, if present, debug data block. 780 func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) { 781 runGcc(stdin, p.gccCmd()) 782 783 isDebugData := func(s string) bool { 784 // Some systems use leading _ to denote non-assembly symbols. 785 return s == "__cgodebug_data" || s == "___cgodebug_data" 786 } 787 788 if f, err := macho.Open(gccTmp()); err == nil { 789 defer f.Close() 790 d, err := f.DWARF() 791 if err != nil { 792 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 793 } 794 var data []byte 795 if f.Symtab != nil { 796 for i := range f.Symtab.Syms { 797 s := &f.Symtab.Syms[i] 798 if isDebugData(s.Name) { 799 // Found it. Now find data section. 800 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 801 sect := f.Sections[i] 802 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 803 if sdat, err := sect.Data(); err == nil { 804 data = sdat[s.Value-sect.Addr:] 805 } 806 } 807 } 808 } 809 } 810 } 811 return d, f.ByteOrder, data 812 } 813 814 if f, err := elf.Open(gccTmp()); err == nil { 815 defer f.Close() 816 d, err := f.DWARF() 817 if err != nil { 818 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 819 } 820 var data []byte 821 symtab, err := f.Symbols() 822 if err == nil { 823 for i := range symtab { 824 s := &symtab[i] 825 if isDebugData(s.Name) { 826 // Found it. Now find data section. 827 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 828 sect := f.Sections[i] 829 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 830 if sdat, err := sect.Data(); err == nil { 831 data = sdat[s.Value-sect.Addr:] 832 } 833 } 834 } 835 } 836 } 837 } 838 return d, f.ByteOrder, data 839 } 840 841 if f, err := pe.Open(gccTmp()); err == nil { 842 defer f.Close() 843 d, err := f.DWARF() 844 if err != nil { 845 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 846 } 847 var data []byte 848 for _, s := range f.Symbols { 849 if isDebugData(s.Name) { 850 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 851 sect := f.Sections[i] 852 if s.Value < sect.Size { 853 if sdat, err := sect.Data(); err == nil { 854 data = sdat[s.Value:] 855 } 856 } 857 } 858 } 859 } 860 return d, binary.LittleEndian, data 861 } 862 863 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) 864 panic("not reached") 865 } 866 867 // gccDefines runs gcc -E -dM -xc - over the C program stdin 868 // and returns the corresponding standard output, which is the 869 // #defines that gcc encountered while processing the input 870 // and its included files. 871 func (p *Package) gccDefines(stdin []byte) string { 872 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc") 873 base = append(base, p.gccMachine()...) 874 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 875 return stdout 876 } 877 878 // gccErrors runs gcc over the C program stdin and returns 879 // the errors that gcc prints. That is, this function expects 880 // gcc to fail. 881 func (p *Package) gccErrors(stdin []byte) string { 882 // TODO(rsc): require failure 883 args := p.gccCmd() 884 885 if *debugGcc { 886 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 887 os.Stderr.Write(stdin) 888 fmt.Fprint(os.Stderr, "EOF\n") 889 } 890 stdout, stderr, _ := run(stdin, args) 891 if *debugGcc { 892 os.Stderr.Write(stdout) 893 os.Stderr.Write(stderr) 894 } 895 return string(stderr) 896 } 897 898 // runGcc runs the gcc command line args with stdin on standard input. 899 // If the command exits with a non-zero exit status, runGcc prints 900 // details about what was run and exits. 901 // Otherwise runGcc returns the data written to standard output and standard error. 902 // Note that for some of the uses we expect useful data back 903 // on standard error, but for those uses gcc must still exit 0. 904 func runGcc(stdin []byte, args []string) (string, string) { 905 if *debugGcc { 906 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 907 os.Stderr.Write(stdin) 908 fmt.Fprint(os.Stderr, "EOF\n") 909 } 910 stdout, stderr, ok := run(stdin, args) 911 if *debugGcc { 912 os.Stderr.Write(stdout) 913 os.Stderr.Write(stderr) 914 } 915 if !ok { 916 os.Stderr.Write(stderr) 917 os.Exit(2) 918 } 919 return string(stdout), string(stderr) 920 } 921 922 // A typeConv is a translator from dwarf types to Go types 923 // with equivalent memory layout. 924 type typeConv struct { 925 // Cache of already-translated or in-progress types. 926 m map[dwarf.Type]*Type 927 typedef map[string]ast.Expr 928 929 // Predeclared types. 930 bool ast.Expr 931 byte ast.Expr // denotes padding 932 int8, int16, int32, int64 ast.Expr 933 uint8, uint16, uint32, uint64, uintptr ast.Expr 934 float32, float64 ast.Expr 935 complex64, complex128 ast.Expr 936 void ast.Expr 937 unsafePointer ast.Expr 938 string ast.Expr 939 goVoid ast.Expr // _Ctype_void, denotes C's void 940 941 ptrSize int64 942 intSize int64 943 } 944 945 var tagGen int 946 var typedef = make(map[string]*Type) 947 var goIdent = make(map[string]*ast.Ident) 948 949 func (c *typeConv) Init(ptrSize, intSize int64) { 950 c.ptrSize = ptrSize 951 c.intSize = intSize 952 c.m = make(map[dwarf.Type]*Type) 953 c.bool = c.Ident("bool") 954 c.byte = c.Ident("byte") 955 c.int8 = c.Ident("int8") 956 c.int16 = c.Ident("int16") 957 c.int32 = c.Ident("int32") 958 c.int64 = c.Ident("int64") 959 c.uint8 = c.Ident("uint8") 960 c.uint16 = c.Ident("uint16") 961 c.uint32 = c.Ident("uint32") 962 c.uint64 = c.Ident("uint64") 963 c.uintptr = c.Ident("uintptr") 964 c.float32 = c.Ident("float32") 965 c.float64 = c.Ident("float64") 966 c.complex64 = c.Ident("complex64") 967 c.complex128 = c.Ident("complex128") 968 c.unsafePointer = c.Ident("unsafe.Pointer") 969 c.void = c.Ident("void") 970 c.string = c.Ident("string") 971 c.goVoid = c.Ident("_Ctype_void") 972 } 973 974 // base strips away qualifiers and typedefs to get the underlying type 975 func base(dt dwarf.Type) dwarf.Type { 976 for { 977 if d, ok := dt.(*dwarf.QualType); ok { 978 dt = d.Type 979 continue 980 } 981 if d, ok := dt.(*dwarf.TypedefType); ok { 982 dt = d.Type 983 continue 984 } 985 break 986 } 987 return dt 988 } 989 990 // Map from dwarf text names to aliases we use in package "C". 991 var dwarfToName = map[string]string{ 992 "long int": "long", 993 "long unsigned int": "ulong", 994 "unsigned int": "uint", 995 "short unsigned int": "ushort", 996 "short int": "short", 997 "long long int": "longlong", 998 "long long unsigned int": "ulonglong", 999 "signed char": "schar", 1000 "float complex": "complexfloat", 1001 "double complex": "complexdouble", 1002 } 1003 1004 const signedDelta = 64 1005 1006 // String returns the current type representation. Format arguments 1007 // are assembled within this method so that any changes in mutable 1008 // values are taken into account. 1009 func (tr *TypeRepr) String() string { 1010 if len(tr.Repr) == 0 { 1011 return "" 1012 } 1013 if len(tr.FormatArgs) == 0 { 1014 return tr.Repr 1015 } 1016 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 1017 } 1018 1019 // Empty returns true if the result of String would be "". 1020 func (tr *TypeRepr) Empty() bool { 1021 return len(tr.Repr) == 0 1022 } 1023 1024 // Set modifies the type representation. 1025 // If fargs are provided, repr is used as a format for fmt.Sprintf. 1026 // Otherwise, repr is used unprocessed as the type representation. 1027 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 1028 tr.Repr = repr 1029 tr.FormatArgs = fargs 1030 } 1031 1032 // Type returns a *Type with the same memory layout as 1033 // dtype when used as the type of a variable or a struct field. 1034 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 1035 if t, ok := c.m[dtype]; ok { 1036 if t.Go == nil { 1037 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 1038 } 1039 return t 1040 } 1041 1042 // clang won't generate DW_AT_byte_size for pointer types, 1043 // so we have to fix it here. 1044 if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 { 1045 dt.ByteSize = c.ptrSize 1046 } 1047 1048 t := new(Type) 1049 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 1050 t.Align = -1 1051 t.C = &TypeRepr{Repr: dtype.Common().Name} 1052 c.m[dtype] = t 1053 1054 switch dt := dtype.(type) { 1055 default: 1056 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 1057 1058 case *dwarf.AddrType: 1059 if t.Size != c.ptrSize { 1060 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 1061 } 1062 t.Go = c.uintptr 1063 t.Align = t.Size 1064 1065 case *dwarf.ArrayType: 1066 if dt.StrideBitSize > 0 { 1067 // Cannot represent bit-sized elements in Go. 1068 t.Go = c.Opaque(t.Size) 1069 break 1070 } 1071 gt := &ast.ArrayType{ 1072 Len: c.intExpr(dt.Count), 1073 } 1074 t.Go = gt // publish before recursive call 1075 sub := c.Type(dt.Type, pos) 1076 t.Align = sub.Align 1077 gt.Elt = sub.Go 1078 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 1079 1080 case *dwarf.BoolType: 1081 t.Go = c.bool 1082 t.Align = 1 1083 1084 case *dwarf.CharType: 1085 if t.Size != 1 { 1086 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 1087 } 1088 t.Go = c.int8 1089 t.Align = 1 1090 1091 case *dwarf.EnumType: 1092 if t.Align = t.Size; t.Align >= c.ptrSize { 1093 t.Align = c.ptrSize 1094 } 1095 t.C.Set("enum " + dt.EnumName) 1096 signed := 0 1097 t.EnumValues = make(map[string]int64) 1098 for _, ev := range dt.Val { 1099 t.EnumValues[ev.Name] = ev.Val 1100 if ev.Val < 0 { 1101 signed = signedDelta 1102 } 1103 } 1104 switch t.Size + int64(signed) { 1105 default: 1106 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 1107 case 1: 1108 t.Go = c.uint8 1109 case 2: 1110 t.Go = c.uint16 1111 case 4: 1112 t.Go = c.uint32 1113 case 8: 1114 t.Go = c.uint64 1115 case 1 + signedDelta: 1116 t.Go = c.int8 1117 case 2 + signedDelta: 1118 t.Go = c.int16 1119 case 4 + signedDelta: 1120 t.Go = c.int32 1121 case 8 + signedDelta: 1122 t.Go = c.int64 1123 } 1124 1125 case *dwarf.FloatType: 1126 switch t.Size { 1127 default: 1128 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 1129 case 4: 1130 t.Go = c.float32 1131 case 8: 1132 t.Go = c.float64 1133 } 1134 if t.Align = t.Size; t.Align >= c.ptrSize { 1135 t.Align = c.ptrSize 1136 } 1137 1138 case *dwarf.ComplexType: 1139 switch t.Size { 1140 default: 1141 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 1142 case 8: 1143 t.Go = c.complex64 1144 case 16: 1145 t.Go = c.complex128 1146 } 1147 if t.Align = t.Size; t.Align >= c.ptrSize { 1148 t.Align = c.ptrSize 1149 } 1150 1151 case *dwarf.FuncType: 1152 // No attempt at translation: would enable calls 1153 // directly between worlds, but we need to moderate those. 1154 t.Go = c.uintptr 1155 t.Align = c.ptrSize 1156 1157 case *dwarf.IntType: 1158 if dt.BitSize > 0 { 1159 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 1160 } 1161 switch t.Size { 1162 default: 1163 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 1164 case 1: 1165 t.Go = c.int8 1166 case 2: 1167 t.Go = c.int16 1168 case 4: 1169 t.Go = c.int32 1170 case 8: 1171 t.Go = c.int64 1172 } 1173 if t.Align = t.Size; t.Align >= c.ptrSize { 1174 t.Align = c.ptrSize 1175 } 1176 1177 case *dwarf.PtrType: 1178 t.Align = c.ptrSize 1179 1180 // Translate void* as unsafe.Pointer 1181 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 1182 t.Go = c.unsafePointer 1183 t.C.Set("void*") 1184 break 1185 } 1186 1187 gt := &ast.StarExpr{} 1188 t.Go = gt // publish before recursive call 1189 sub := c.Type(dt.Type, pos) 1190 gt.X = sub.Go 1191 t.C.Set("%s*", sub.C) 1192 1193 case *dwarf.QualType: 1194 // Ignore qualifier. 1195 t = c.Type(dt.Type, pos) 1196 c.m[dtype] = t 1197 return t 1198 1199 case *dwarf.StructType: 1200 // Convert to Go struct, being careful about alignment. 1201 // Have to give it a name to simulate C "struct foo" references. 1202 tag := dt.StructName 1203 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 1204 break 1205 } 1206 if tag == "" { 1207 tag = "__" + strconv.Itoa(tagGen) 1208 tagGen++ 1209 } else if t.C.Empty() { 1210 t.C.Set(dt.Kind + " " + tag) 1211 } 1212 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 1213 t.Go = name // publish before recursive calls 1214 goIdent[name.Name] = name 1215 if dt.ByteSize < 0 { 1216 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 1217 // so execute the basic things that the struct case would do 1218 // other than try to determine a Go representation. 1219 tt := *t 1220 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 1221 tt.Go = c.Ident("struct{}") 1222 typedef[name.Name] = &tt 1223 break 1224 } 1225 switch dt.Kind { 1226 case "class", "union": 1227 t.Go = c.Opaque(t.Size) 1228 if t.C.Empty() { 1229 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 1230 } 1231 t.Align = 1 // TODO: should probably base this on field alignment. 1232 typedef[name.Name] = t 1233 case "struct": 1234 g, csyntax, align := c.Struct(dt, pos) 1235 if t.C.Empty() { 1236 t.C.Set(csyntax) 1237 } 1238 t.Align = align 1239 tt := *t 1240 if tag != "" { 1241 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 1242 } 1243 tt.Go = g 1244 typedef[name.Name] = &tt 1245 } 1246 1247 case *dwarf.TypedefType: 1248 // Record typedef for printing. 1249 if dt.Name == "_GoString_" { 1250 // Special C name for Go string type. 1251 // Knows string layout used by compilers: pointer plus length, 1252 // which rounds up to 2 pointers after alignment. 1253 t.Go = c.string 1254 t.Size = c.ptrSize * 2 1255 t.Align = c.ptrSize 1256 break 1257 } 1258 if dt.Name == "_GoBytes_" { 1259 // Special C name for Go []byte type. 1260 // Knows slice layout used by compilers: pointer, length, cap. 1261 t.Go = c.Ident("[]byte") 1262 t.Size = c.ptrSize + 4 + 4 1263 t.Align = c.ptrSize 1264 break 1265 } 1266 name := c.Ident("_Ctype_" + dt.Name) 1267 goIdent[name.Name] = name 1268 t.Go = name // publish before recursive call 1269 sub := c.Type(dt.Type, pos) 1270 t.Size = sub.Size 1271 t.Align = sub.Align 1272 oldType := typedef[name.Name] 1273 if oldType == nil { 1274 tt := *t 1275 tt.Go = sub.Go 1276 typedef[name.Name] = &tt 1277 } 1278 1279 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 1280 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 1281 // with the base type. 1282 // In -godefs and -cdefs mode, do this for all typedefs. 1283 if isStructUnionClass(sub.Go) || *godefs || *cdefs { 1284 t.Go = sub.Go 1285 1286 if isStructUnionClass(sub.Go) { 1287 // Use the typedef name for C code. 1288 typedef[sub.Go.(*ast.Ident).Name].C = t.C 1289 } 1290 1291 // If we've seen this typedef before, and it 1292 // was an anonymous struct/union/class before 1293 // too, use the old definition. 1294 // TODO: it would be safer to only do this if 1295 // we verify that the types are the same. 1296 if oldType != nil && isStructUnionClass(oldType.Go) { 1297 t.Go = oldType.Go 1298 } 1299 } 1300 1301 case *dwarf.UcharType: 1302 if t.Size != 1 { 1303 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 1304 } 1305 t.Go = c.uint8 1306 t.Align = 1 1307 1308 case *dwarf.UintType: 1309 if dt.BitSize > 0 { 1310 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 1311 } 1312 switch t.Size { 1313 default: 1314 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 1315 case 1: 1316 t.Go = c.uint8 1317 case 2: 1318 t.Go = c.uint16 1319 case 4: 1320 t.Go = c.uint32 1321 case 8: 1322 t.Go = c.uint64 1323 } 1324 if t.Align = t.Size; t.Align >= c.ptrSize { 1325 t.Align = c.ptrSize 1326 } 1327 1328 case *dwarf.VoidType: 1329 t.Go = c.goVoid 1330 t.C.Set("void") 1331 t.Align = 1 1332 } 1333 1334 switch dtype.(type) { 1335 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 1336 s := dtype.Common().Name 1337 if s != "" { 1338 if ss, ok := dwarfToName[s]; ok { 1339 s = ss 1340 } 1341 s = strings.Join(strings.Split(s, " "), "") // strip spaces 1342 name := c.Ident("_Ctype_" + s) 1343 tt := *t 1344 typedef[name.Name] = &tt 1345 if !*godefs && !*cdefs { 1346 t.Go = name 1347 } 1348 } 1349 } 1350 1351 if t.Size <= 0 { 1352 // Clang does not record the size of a pointer in its DWARF entry, 1353 // so if dtype is an array, the call to dtype.Size at the top of the function 1354 // computed the size as the array length * 0 = 0. 1355 // The type switch called Type (this function) recursively on the pointer 1356 // entry, and the code near the top of the function updated the size to 1357 // be correct, so calling dtype.Size again will produce the correct value. 1358 t.Size = dtype.Size() 1359 if t.Size < 0 { 1360 // Unsized types are [0]byte, unless they're typedefs of other types 1361 // or structs with tags. 1362 // if so, use the name we've already defined. 1363 t.Size = 0 1364 switch dt := dtype.(type) { 1365 case *dwarf.TypedefType: 1366 // ok 1367 case *dwarf.StructType: 1368 if dt.StructName != "" { 1369 break 1370 } 1371 t.Go = c.Opaque(0) 1372 default: 1373 t.Go = c.Opaque(0) 1374 } 1375 if t.C.Empty() { 1376 t.C.Set("void") 1377 } 1378 return t 1379 } 1380 } 1381 1382 if t.C.Empty() { 1383 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 1384 } 1385 1386 return t 1387 } 1388 1389 // isStructUnionClass reports whether the type described by the Go syntax x 1390 // is a struct, union, or class with a tag. 1391 func isStructUnionClass(x ast.Expr) bool { 1392 id, ok := x.(*ast.Ident) 1393 if !ok { 1394 return false 1395 } 1396 name := id.Name 1397 return strings.HasPrefix(name, "_Ctype_struct_") || 1398 strings.HasPrefix(name, "_Ctype_union_") || 1399 strings.HasPrefix(name, "_Ctype_class_") 1400 } 1401 1402 // FuncArg returns a Go type with the same memory layout as 1403 // dtype when used as the type of a C function argument. 1404 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 1405 t := c.Type(dtype, pos) 1406 switch dt := dtype.(type) { 1407 case *dwarf.ArrayType: 1408 // Arrays are passed implicitly as pointers in C. 1409 // In Go, we must be explicit. 1410 tr := &TypeRepr{} 1411 tr.Set("%s*", t.C) 1412 return &Type{ 1413 Size: c.ptrSize, 1414 Align: c.ptrSize, 1415 Go: &ast.StarExpr{X: t.Go}, 1416 C: tr, 1417 } 1418 case *dwarf.TypedefType: 1419 // C has much more relaxed rules than Go for 1420 // implicit type conversions. When the parameter 1421 // is type T defined as *X, simulate a little of the 1422 // laxness of C by making the argument *X instead of T. 1423 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 1424 // Unless the typedef happens to point to void* since 1425 // Go has special rules around using unsafe.Pointer. 1426 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 1427 break 1428 } 1429 1430 t = c.Type(ptr, pos) 1431 if t == nil { 1432 return nil 1433 } 1434 1435 // Remember the C spelling, in case the struct 1436 // has __attribute__((unavailable)) on it. See issue 2888. 1437 t.Typedef = dt.Name 1438 } 1439 } 1440 return t 1441 } 1442 1443 // FuncType returns the Go type analogous to dtype. 1444 // There is no guarantee about matching memory layout. 1445 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 1446 p := make([]*Type, len(dtype.ParamType)) 1447 gp := make([]*ast.Field, len(dtype.ParamType)) 1448 for i, f := range dtype.ParamType { 1449 // gcc's DWARF generator outputs a single DotDotDotType parameter for 1450 // function pointers that specify no parameters (e.g. void 1451 // (*__cgo_0)()). Treat this special case as void. This case is 1452 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 1453 // legal). 1454 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 1455 p, gp = nil, nil 1456 break 1457 } 1458 p[i] = c.FuncArg(f, pos) 1459 gp[i] = &ast.Field{Type: p[i].Go} 1460 } 1461 var r *Type 1462 var gr []*ast.Field 1463 if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok { 1464 gr = []*ast.Field{{Type: c.goVoid}} 1465 } else if dtype.ReturnType != nil { 1466 r = c.Type(dtype.ReturnType, pos) 1467 gr = []*ast.Field{{Type: r.Go}} 1468 } 1469 return &FuncType{ 1470 Params: p, 1471 Result: r, 1472 Go: &ast.FuncType{ 1473 Params: &ast.FieldList{List: gp}, 1474 Results: &ast.FieldList{List: gr}, 1475 }, 1476 } 1477 } 1478 1479 // Identifier 1480 func (c *typeConv) Ident(s string) *ast.Ident { 1481 return ast.NewIdent(s) 1482 } 1483 1484 // Opaque type of n bytes. 1485 func (c *typeConv) Opaque(n int64) ast.Expr { 1486 return &ast.ArrayType{ 1487 Len: c.intExpr(n), 1488 Elt: c.byte, 1489 } 1490 } 1491 1492 // Expr for integer n. 1493 func (c *typeConv) intExpr(n int64) ast.Expr { 1494 return &ast.BasicLit{ 1495 Kind: token.INT, 1496 Value: strconv.FormatInt(n, 10), 1497 } 1498 } 1499 1500 // Add padding of given size to fld. 1501 func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field { 1502 n := len(fld) 1503 fld = fld[0 : n+1] 1504 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 1505 return fld 1506 } 1507 1508 // Struct conversion: return Go and (6g) C syntax for type. 1509 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 1510 var buf bytes.Buffer 1511 buf.WriteString("struct {") 1512 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 1513 off := int64(0) 1514 1515 // Rename struct fields that happen to be named Go keywords into 1516 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 1517 // be mangled. Any existing identifier that already has the same name on 1518 // the C-side will cause the Go-mangled version to be prefixed with _. 1519 // (e.g. in a struct with fields '_type' and 'type', the latter would be 1520 // rendered as '__type' in Go). 1521 ident := make(map[string]string) 1522 used := make(map[string]bool) 1523 for _, f := range dt.Field { 1524 ident[f.Name] = f.Name 1525 used[f.Name] = true 1526 } 1527 1528 if !*godefs && !*cdefs { 1529 for cid, goid := range ident { 1530 if token.Lookup(goid).IsKeyword() { 1531 // Avoid keyword 1532 goid = "_" + goid 1533 1534 // Also avoid existing fields 1535 for _, exist := used[goid]; exist; _, exist = used[goid] { 1536 goid = "_" + goid 1537 } 1538 1539 used[goid] = true 1540 ident[cid] = goid 1541 } 1542 } 1543 } 1544 1545 anon := 0 1546 for _, f := range dt.Field { 1547 if f.ByteOffset > off { 1548 fld = c.pad(fld, f.ByteOffset-off) 1549 off = f.ByteOffset 1550 } 1551 t := c.Type(f.Type, pos) 1552 tgo := t.Go 1553 size := t.Size 1554 talign := t.Align 1555 if f.BitSize > 0 { 1556 if f.BitSize%8 != 0 { 1557 continue 1558 } 1559 size = f.BitSize / 8 1560 name := tgo.(*ast.Ident).String() 1561 if strings.HasPrefix(name, "int") { 1562 name = "int" 1563 } else { 1564 name = "uint" 1565 } 1566 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) 1567 talign = size 1568 } 1569 1570 if talign > 0 && f.ByteOffset%talign != 0 { 1571 // Drop misaligned fields, the same way we drop integer bit fields. 1572 // The goal is to make available what can be made available. 1573 // Otherwise one bad and unneeded field in an otherwise okay struct 1574 // makes the whole program not compile. Much of the time these 1575 // structs are in system headers that cannot be corrected. 1576 continue 1577 } 1578 n := len(fld) 1579 fld = fld[0 : n+1] 1580 name := f.Name 1581 if name == "" { 1582 name = fmt.Sprintf("anon%d", anon) 1583 anon++ 1584 ident[name] = name 1585 } 1586 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 1587 off += size 1588 buf.WriteString(t.C.String()) 1589 buf.WriteString(" ") 1590 buf.WriteString(name) 1591 buf.WriteString("; ") 1592 if talign > align { 1593 align = talign 1594 } 1595 } 1596 if off < dt.ByteSize { 1597 fld = c.pad(fld, dt.ByteSize-off) 1598 off = dt.ByteSize 1599 } 1600 if off != dt.ByteSize { 1601 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 1602 } 1603 buf.WriteString("}") 1604 csyntax = buf.String() 1605 1606 if *godefs || *cdefs { 1607 godefsFields(fld) 1608 } 1609 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 1610 return 1611 } 1612 1613 func upper(s string) string { 1614 if s == "" { 1615 return "" 1616 } 1617 r, size := utf8.DecodeRuneInString(s) 1618 if r == '_' { 1619 return "X" + s 1620 } 1621 return string(unicode.ToUpper(r)) + s[size:] 1622 } 1623 1624 // godefsFields rewrites field names for use in Go or C definitions. 1625 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 1626 // converts names to upper case, and rewrites _ into Pad_godefs_n, 1627 // so that all fields are exported. 1628 func godefsFields(fld []*ast.Field) { 1629 prefix := fieldPrefix(fld) 1630 npad := 0 1631 for _, f := range fld { 1632 for _, n := range f.Names { 1633 if n.Name != prefix { 1634 n.Name = strings.TrimPrefix(n.Name, prefix) 1635 } 1636 if n.Name == "_" { 1637 // Use exported name instead. 1638 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 1639 npad++ 1640 } 1641 if !*cdefs { 1642 n.Name = upper(n.Name) 1643 } 1644 } 1645 p := &f.Type 1646 t := *p 1647 if star, ok := t.(*ast.StarExpr); ok { 1648 star = &ast.StarExpr{X: star.X} 1649 *p = star 1650 p = &star.X 1651 t = *p 1652 } 1653 if id, ok := t.(*ast.Ident); ok { 1654 if id.Name == "unsafe.Pointer" { 1655 *p = ast.NewIdent("*byte") 1656 } 1657 } 1658 } 1659 } 1660 1661 // fieldPrefix returns the prefix that should be removed from all the 1662 // field names when generating the C or Go code. For generated 1663 // C, we leave the names as is (tv_sec, tv_usec), since that's what 1664 // people are used to seeing in C. For generated Go code, such as 1665 // package syscall's data structures, we drop a common prefix 1666 // (so sec, usec, which will get turned into Sec, Usec for exporting). 1667 func fieldPrefix(fld []*ast.Field) string { 1668 if *cdefs { 1669 return "" 1670 } 1671 prefix := "" 1672 for _, f := range fld { 1673 for _, n := range f.Names { 1674 // Ignore field names that don't have the prefix we're 1675 // looking for. It is common in C headers to have fields 1676 // named, say, _pad in an otherwise prefixed header. 1677 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 1678 // still want to remove the tv_ prefix. 1679 // The check for "orig_" here handles orig_eax in the 1680 // x86 ptrace register sets, which otherwise have all fields 1681 // with reg_ prefixes. 1682 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 1683 continue 1684 } 1685 i := strings.Index(n.Name, "_") 1686 if i < 0 { 1687 continue 1688 } 1689 if prefix == "" { 1690 prefix = n.Name[:i+1] 1691 } else if prefix != n.Name[:i+1] { 1692 return "" 1693 } 1694 } 1695 } 1696 return prefix 1697 }