github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/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 "type": 663 if r.Name.Kind != "type" { 664 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 665 } else if r.Name.Type == nil { 666 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 667 // GCC won't raise an error when using pointers to such unknown types. 668 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 669 } else { 670 expr = r.Name.Type.Go 671 } 672 default: 673 if r.Name.Kind == "func" { 674 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 675 } 676 } 677 if *godefs { 678 // Substitute definition for mangled type name. 679 if id, ok := expr.(*ast.Ident); ok { 680 if t := typedef[id.Name]; t != nil { 681 expr = t.Go 682 } 683 if id.Name == r.Name.Mangle && r.Name.Const != "" { 684 expr = ast.NewIdent(r.Name.Const) 685 } 686 } 687 } 688 689 // Copy position information from old expr into new expr, 690 // in case expression being replaced is first on line. 691 // See golang.org/issue/6563. 692 pos := (*r.Expr).Pos() 693 switch x := expr.(type) { 694 case *ast.Ident: 695 expr = &ast.Ident{NamePos: pos, Name: x.Name} 696 } 697 698 *r.Expr = expr 699 } 700 701 // Remove functions only used as expressions, so their respective 702 // bridge functions are not generated. 703 for name, used := range functions { 704 if !used { 705 delete(f.Name, name) 706 } 707 } 708 } 709 710 // gccBaseCmd returns the start of the compiler command line. 711 // It uses $CC if set, or else $GCC, or else the compiler recorded 712 // during the initial build as defaultCC. 713 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 714 func (p *Package) gccBaseCmd() []string { 715 // Use $CC if set, since that's what the build uses. 716 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 { 717 return ret 718 } 719 // Try $GCC if set, since that's what we used to use. 720 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 { 721 return ret 722 } 723 return strings.Fields(defaultCC) 724 } 725 726 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 727 func (p *Package) gccMachine() []string { 728 switch goarch { 729 case "amd64": 730 return []string{"-m64"} 731 case "386": 732 return []string{"-m32"} 733 case "arm": 734 return []string{"-marm"} // not thumb 735 } 736 return nil 737 } 738 739 func gccTmp() string { 740 return *objDir + "_cgo_.o" 741 } 742 743 // gccCmd returns the gcc command line to use for compiling 744 // the input. 745 func (p *Package) gccCmd() []string { 746 c := append(p.gccBaseCmd(), 747 "-w", // no warnings 748 "-Wno-error", // warnings are not errors 749 "-o"+gccTmp(), // write object to tmp 750 "-gdwarf-2", // generate DWARF v2 debugging symbols 751 "-c", // do not link 752 "-xc", // input language is C 753 ) 754 if strings.Contains(c[0], "clang") { 755 c = append(c, 756 "-ferror-limit=0", 757 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 758 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 759 // flag to disable the warning. Yes, really good diagnostics, clang. 760 "-Wno-unknown-warning-option", 761 "-Wno-unneeded-internal-declaration", 762 "-Wno-unused-function", 763 "-Qunused-arguments", 764 // Clang embeds prototypes for some builtin functions, 765 // like malloc and calloc, but all size_t parameters are 766 // incorrectly typed unsigned long. We work around that 767 // by disabling the builtin functions (this is safe as 768 // it won't affect the actual compilation of the C code). 769 // See: http://golang.org/issue/6506. 770 "-fno-builtin", 771 ) 772 } 773 774 c = append(c, p.GccOptions...) 775 c = append(c, p.gccMachine()...) 776 c = append(c, "-") //read input from standard input 777 return c 778 } 779 780 // gccDebug runs gcc -gdwarf-2 over the C program stdin and 781 // returns the corresponding DWARF data and, if present, debug data block. 782 func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) { 783 runGcc(stdin, p.gccCmd()) 784 785 isDebugData := func(s string) bool { 786 // Some systems use leading _ to denote non-assembly symbols. 787 return s == "__cgodebug_data" || s == "___cgodebug_data" 788 } 789 790 if f, err := macho.Open(gccTmp()); err == nil { 791 defer f.Close() 792 d, err := f.DWARF() 793 if err != nil { 794 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 795 } 796 var data []byte 797 if f.Symtab != nil { 798 for i := range f.Symtab.Syms { 799 s := &f.Symtab.Syms[i] 800 if isDebugData(s.Name) { 801 // Found it. Now find data section. 802 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 803 sect := f.Sections[i] 804 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 805 if sdat, err := sect.Data(); err == nil { 806 data = sdat[s.Value-sect.Addr:] 807 } 808 } 809 } 810 } 811 } 812 } 813 return d, f.ByteOrder, data 814 } 815 816 if f, err := elf.Open(gccTmp()); err == nil { 817 defer f.Close() 818 d, err := f.DWARF() 819 if err != nil { 820 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 821 } 822 var data []byte 823 symtab, err := f.Symbols() 824 if err == nil { 825 for i := range symtab { 826 s := &symtab[i] 827 if isDebugData(s.Name) { 828 // Found it. Now find data section. 829 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 830 sect := f.Sections[i] 831 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 832 if sdat, err := sect.Data(); err == nil { 833 data = sdat[s.Value-sect.Addr:] 834 } 835 } 836 } 837 } 838 } 839 } 840 return d, f.ByteOrder, data 841 } 842 843 if f, err := pe.Open(gccTmp()); err == nil { 844 defer f.Close() 845 d, err := f.DWARF() 846 if err != nil { 847 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 848 } 849 var data []byte 850 for _, s := range f.Symbols { 851 if isDebugData(s.Name) { 852 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 853 sect := f.Sections[i] 854 if s.Value < sect.Size { 855 if sdat, err := sect.Data(); err == nil { 856 data = sdat[s.Value:] 857 } 858 } 859 } 860 } 861 } 862 return d, binary.LittleEndian, data 863 } 864 865 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) 866 panic("not reached") 867 } 868 869 // gccDefines runs gcc -E -dM -xc - over the C program stdin 870 // and returns the corresponding standard output, which is the 871 // #defines that gcc encountered while processing the input 872 // and its included files. 873 func (p *Package) gccDefines(stdin []byte) string { 874 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc") 875 base = append(base, p.gccMachine()...) 876 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 877 return stdout 878 } 879 880 // gccErrors runs gcc over the C program stdin and returns 881 // the errors that gcc prints. That is, this function expects 882 // gcc to fail. 883 func (p *Package) gccErrors(stdin []byte) string { 884 // TODO(rsc): require failure 885 args := p.gccCmd() 886 887 if *debugGcc { 888 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 889 os.Stderr.Write(stdin) 890 fmt.Fprint(os.Stderr, "EOF\n") 891 } 892 stdout, stderr, _ := run(stdin, args) 893 if *debugGcc { 894 os.Stderr.Write(stdout) 895 os.Stderr.Write(stderr) 896 } 897 return string(stderr) 898 } 899 900 // runGcc runs the gcc command line args with stdin on standard input. 901 // If the command exits with a non-zero exit status, runGcc prints 902 // details about what was run and exits. 903 // Otherwise runGcc returns the data written to standard output and standard error. 904 // Note that for some of the uses we expect useful data back 905 // on standard error, but for those uses gcc must still exit 0. 906 func runGcc(stdin []byte, args []string) (string, string) { 907 if *debugGcc { 908 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 909 os.Stderr.Write(stdin) 910 fmt.Fprint(os.Stderr, "EOF\n") 911 } 912 stdout, stderr, ok := run(stdin, args) 913 if *debugGcc { 914 os.Stderr.Write(stdout) 915 os.Stderr.Write(stderr) 916 } 917 if !ok { 918 os.Stderr.Write(stderr) 919 os.Exit(2) 920 } 921 return string(stdout), string(stderr) 922 } 923 924 // A typeConv is a translator from dwarf types to Go types 925 // with equivalent memory layout. 926 type typeConv struct { 927 // Cache of already-translated or in-progress types. 928 m map[dwarf.Type]*Type 929 typedef map[string]ast.Expr 930 931 // Map from types to incomplete pointers to those types. 932 ptrs map[dwarf.Type][]*Type 933 // Keys of ptrs in insertion order (deterministic worklist) 934 ptrKeys []dwarf.Type 935 936 // Predeclared types. 937 bool ast.Expr 938 byte ast.Expr // denotes padding 939 int8, int16, int32, int64 ast.Expr 940 uint8, uint16, uint32, uint64, uintptr ast.Expr 941 float32, float64 ast.Expr 942 complex64, complex128 ast.Expr 943 void ast.Expr 944 string ast.Expr 945 goVoid ast.Expr // _Ctype_void, denotes C's void 946 goVoidPtr ast.Expr // unsafe.Pointer or *byte 947 948 ptrSize int64 949 intSize int64 950 } 951 952 var tagGen int 953 var typedef = make(map[string]*Type) 954 var goIdent = make(map[string]*ast.Ident) 955 956 func (c *typeConv) Init(ptrSize, intSize int64) { 957 c.ptrSize = ptrSize 958 c.intSize = intSize 959 c.m = make(map[dwarf.Type]*Type) 960 c.ptrs = make(map[dwarf.Type][]*Type) 961 c.bool = c.Ident("bool") 962 c.byte = c.Ident("byte") 963 c.int8 = c.Ident("int8") 964 c.int16 = c.Ident("int16") 965 c.int32 = c.Ident("int32") 966 c.int64 = c.Ident("int64") 967 c.uint8 = c.Ident("uint8") 968 c.uint16 = c.Ident("uint16") 969 c.uint32 = c.Ident("uint32") 970 c.uint64 = c.Ident("uint64") 971 c.uintptr = c.Ident("uintptr") 972 c.float32 = c.Ident("float32") 973 c.float64 = c.Ident("float64") 974 c.complex64 = c.Ident("complex64") 975 c.complex128 = c.Ident("complex128") 976 c.void = c.Ident("void") 977 c.string = c.Ident("string") 978 c.goVoid = c.Ident("_Ctype_void") 979 980 // Normally cgo translates void* to unsafe.Pointer, 981 // but for historical reasons -godefs uses *byte instead. 982 if *godefs { 983 c.goVoidPtr = &ast.StarExpr{X: c.byte} 984 } else { 985 c.goVoidPtr = c.Ident("unsafe.Pointer") 986 } 987 } 988 989 // base strips away qualifiers and typedefs to get the underlying type 990 func base(dt dwarf.Type) dwarf.Type { 991 for { 992 if d, ok := dt.(*dwarf.QualType); ok { 993 dt = d.Type 994 continue 995 } 996 if d, ok := dt.(*dwarf.TypedefType); ok { 997 dt = d.Type 998 continue 999 } 1000 break 1001 } 1002 return dt 1003 } 1004 1005 // Map from dwarf text names to aliases we use in package "C". 1006 var dwarfToName = map[string]string{ 1007 "long int": "long", 1008 "long unsigned int": "ulong", 1009 "unsigned int": "uint", 1010 "short unsigned int": "ushort", 1011 "short int": "short", 1012 "long long int": "longlong", 1013 "long long unsigned int": "ulonglong", 1014 "signed char": "schar", 1015 "float complex": "complexfloat", 1016 "double complex": "complexdouble", 1017 } 1018 1019 const signedDelta = 64 1020 1021 // String returns the current type representation. Format arguments 1022 // are assembled within this method so that any changes in mutable 1023 // values are taken into account. 1024 func (tr *TypeRepr) String() string { 1025 if len(tr.Repr) == 0 { 1026 return "" 1027 } 1028 if len(tr.FormatArgs) == 0 { 1029 return tr.Repr 1030 } 1031 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 1032 } 1033 1034 // Empty returns true if the result of String would be "". 1035 func (tr *TypeRepr) Empty() bool { 1036 return len(tr.Repr) == 0 1037 } 1038 1039 // Set modifies the type representation. 1040 // If fargs are provided, repr is used as a format for fmt.Sprintf. 1041 // Otherwise, repr is used unprocessed as the type representation. 1042 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 1043 tr.Repr = repr 1044 tr.FormatArgs = fargs 1045 } 1046 1047 // FinishType completes any outstanding type mapping work. 1048 // In particular, it resolves incomplete pointer types. 1049 func (c *typeConv) FinishType(pos token.Pos) { 1050 // Completing one pointer type might produce more to complete. 1051 // Keep looping until they're all done. 1052 for len(c.ptrKeys) > 0 { 1053 dtype := c.ptrKeys[0] 1054 c.ptrKeys = c.ptrKeys[1:] 1055 1056 // Note Type might invalidate c.ptrs[dtype]. 1057 t := c.Type(dtype, pos) 1058 for _, ptr := range c.ptrs[dtype] { 1059 ptr.Go.(*ast.StarExpr).X = t.Go 1060 ptr.C.Set("%s*", t.C) 1061 } 1062 c.ptrs[dtype] = nil // retain the map key 1063 } 1064 } 1065 1066 // Type returns a *Type with the same memory layout as 1067 // dtype when used as the type of a variable or a struct field. 1068 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 1069 if t, ok := c.m[dtype]; ok { 1070 if t.Go == nil { 1071 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 1072 } 1073 return t 1074 } 1075 1076 t := new(Type) 1077 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 1078 t.Align = -1 1079 t.C = &TypeRepr{Repr: dtype.Common().Name} 1080 c.m[dtype] = t 1081 1082 switch dt := dtype.(type) { 1083 default: 1084 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 1085 1086 case *dwarf.AddrType: 1087 if t.Size != c.ptrSize { 1088 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 1089 } 1090 t.Go = c.uintptr 1091 t.Align = t.Size 1092 1093 case *dwarf.ArrayType: 1094 if dt.StrideBitSize > 0 { 1095 // Cannot represent bit-sized elements in Go. 1096 t.Go = c.Opaque(t.Size) 1097 break 1098 } 1099 count := dt.Count 1100 if count == -1 { 1101 // Indicates flexible array member, which Go doesn't support. 1102 // Translate to zero-length array instead. 1103 count = 0 1104 } 1105 sub := c.Type(dt.Type, pos) 1106 t.Align = sub.Align 1107 t.Go = &ast.ArrayType{ 1108 Len: c.intExpr(count), 1109 Elt: sub.Go, 1110 } 1111 // Recalculate t.Size now that we know sub.Size. 1112 t.Size = count * sub.Size 1113 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 1114 1115 case *dwarf.BoolType: 1116 t.Go = c.bool 1117 t.Align = 1 1118 1119 case *dwarf.CharType: 1120 if t.Size != 1 { 1121 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 1122 } 1123 t.Go = c.int8 1124 t.Align = 1 1125 1126 case *dwarf.EnumType: 1127 if t.Align = t.Size; t.Align >= c.ptrSize { 1128 t.Align = c.ptrSize 1129 } 1130 t.C.Set("enum " + dt.EnumName) 1131 signed := 0 1132 t.EnumValues = make(map[string]int64) 1133 for _, ev := range dt.Val { 1134 t.EnumValues[ev.Name] = ev.Val 1135 if ev.Val < 0 { 1136 signed = signedDelta 1137 } 1138 } 1139 switch t.Size + int64(signed) { 1140 default: 1141 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 1142 case 1: 1143 t.Go = c.uint8 1144 case 2: 1145 t.Go = c.uint16 1146 case 4: 1147 t.Go = c.uint32 1148 case 8: 1149 t.Go = c.uint64 1150 case 1 + signedDelta: 1151 t.Go = c.int8 1152 case 2 + signedDelta: 1153 t.Go = c.int16 1154 case 4 + signedDelta: 1155 t.Go = c.int32 1156 case 8 + signedDelta: 1157 t.Go = c.int64 1158 } 1159 1160 case *dwarf.FloatType: 1161 switch t.Size { 1162 default: 1163 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 1164 case 4: 1165 t.Go = c.float32 1166 case 8: 1167 t.Go = c.float64 1168 } 1169 if t.Align = t.Size; t.Align >= c.ptrSize { 1170 t.Align = c.ptrSize 1171 } 1172 1173 case *dwarf.ComplexType: 1174 switch t.Size { 1175 default: 1176 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 1177 case 8: 1178 t.Go = c.complex64 1179 case 16: 1180 t.Go = c.complex128 1181 } 1182 if t.Align = t.Size; t.Align >= c.ptrSize { 1183 t.Align = c.ptrSize 1184 } 1185 1186 case *dwarf.FuncType: 1187 // No attempt at translation: would enable calls 1188 // directly between worlds, but we need to moderate those. 1189 t.Go = c.uintptr 1190 t.Align = c.ptrSize 1191 1192 case *dwarf.IntType: 1193 if dt.BitSize > 0 { 1194 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 1195 } 1196 switch t.Size { 1197 default: 1198 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 1199 case 1: 1200 t.Go = c.int8 1201 case 2: 1202 t.Go = c.int16 1203 case 4: 1204 t.Go = c.int32 1205 case 8: 1206 t.Go = c.int64 1207 } 1208 if t.Align = t.Size; t.Align >= c.ptrSize { 1209 t.Align = c.ptrSize 1210 } 1211 1212 case *dwarf.PtrType: 1213 // Clang doesn't emit DW_AT_byte_size for pointer types. 1214 if t.Size != c.ptrSize && t.Size != -1 { 1215 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype) 1216 } 1217 t.Size = c.ptrSize 1218 t.Align = c.ptrSize 1219 1220 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 1221 t.Go = c.goVoidPtr 1222 t.C.Set("void*") 1223 break 1224 } 1225 1226 // Placeholder initialization; completed in FinishType. 1227 t.Go = &ast.StarExpr{} 1228 t.C.Set("<incomplete>*") 1229 if _, ok := c.ptrs[dt.Type]; !ok { 1230 c.ptrKeys = append(c.ptrKeys, dt.Type) 1231 } 1232 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t) 1233 1234 case *dwarf.QualType: 1235 // Ignore qualifier. 1236 t = c.Type(dt.Type, pos) 1237 c.m[dtype] = t 1238 return t 1239 1240 case *dwarf.StructType: 1241 // Convert to Go struct, being careful about alignment. 1242 // Have to give it a name to simulate C "struct foo" references. 1243 tag := dt.StructName 1244 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 1245 break 1246 } 1247 if tag == "" { 1248 tag = "__" + strconv.Itoa(tagGen) 1249 tagGen++ 1250 } else if t.C.Empty() { 1251 t.C.Set(dt.Kind + " " + tag) 1252 } 1253 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 1254 t.Go = name // publish before recursive calls 1255 goIdent[name.Name] = name 1256 if dt.ByteSize < 0 { 1257 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 1258 // so execute the basic things that the struct case would do 1259 // other than try to determine a Go representation. 1260 tt := *t 1261 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 1262 tt.Go = c.Ident("struct{}") 1263 typedef[name.Name] = &tt 1264 break 1265 } 1266 switch dt.Kind { 1267 case "class", "union": 1268 t.Go = c.Opaque(t.Size) 1269 if t.C.Empty() { 1270 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 1271 } 1272 t.Align = 1 // TODO: should probably base this on field alignment. 1273 typedef[name.Name] = t 1274 case "struct": 1275 g, csyntax, align := c.Struct(dt, pos) 1276 if t.C.Empty() { 1277 t.C.Set(csyntax) 1278 } 1279 t.Align = align 1280 tt := *t 1281 if tag != "" { 1282 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 1283 } 1284 tt.Go = g 1285 typedef[name.Name] = &tt 1286 } 1287 1288 case *dwarf.TypedefType: 1289 // Record typedef for printing. 1290 if dt.Name == "_GoString_" { 1291 // Special C name for Go string type. 1292 // Knows string layout used by compilers: pointer plus length, 1293 // which rounds up to 2 pointers after alignment. 1294 t.Go = c.string 1295 t.Size = c.ptrSize * 2 1296 t.Align = c.ptrSize 1297 break 1298 } 1299 if dt.Name == "_GoBytes_" { 1300 // Special C name for Go []byte type. 1301 // Knows slice layout used by compilers: pointer, length, cap. 1302 t.Go = c.Ident("[]byte") 1303 t.Size = c.ptrSize + 4 + 4 1304 t.Align = c.ptrSize 1305 break 1306 } 1307 name := c.Ident("_Ctype_" + dt.Name) 1308 goIdent[name.Name] = name 1309 sub := c.Type(dt.Type, pos) 1310 t.Go = name 1311 t.Size = sub.Size 1312 t.Align = sub.Align 1313 oldType := typedef[name.Name] 1314 if oldType == nil { 1315 tt := *t 1316 tt.Go = sub.Go 1317 typedef[name.Name] = &tt 1318 } 1319 1320 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 1321 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 1322 // with the base type. 1323 // In -godefs mode, do this for all typedefs. 1324 if isStructUnionClass(sub.Go) || *godefs { 1325 t.Go = sub.Go 1326 1327 if isStructUnionClass(sub.Go) { 1328 // Use the typedef name for C code. 1329 typedef[sub.Go.(*ast.Ident).Name].C = t.C 1330 } 1331 1332 // If we've seen this typedef before, and it 1333 // was an anonymous struct/union/class before 1334 // too, use the old definition. 1335 // TODO: it would be safer to only do this if 1336 // we verify that the types are the same. 1337 if oldType != nil && isStructUnionClass(oldType.Go) { 1338 t.Go = oldType.Go 1339 } 1340 } 1341 1342 case *dwarf.UcharType: 1343 if t.Size != 1 { 1344 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 1345 } 1346 t.Go = c.uint8 1347 t.Align = 1 1348 1349 case *dwarf.UintType: 1350 if dt.BitSize > 0 { 1351 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 1352 } 1353 switch t.Size { 1354 default: 1355 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 1356 case 1: 1357 t.Go = c.uint8 1358 case 2: 1359 t.Go = c.uint16 1360 case 4: 1361 t.Go = c.uint32 1362 case 8: 1363 t.Go = c.uint64 1364 } 1365 if t.Align = t.Size; t.Align >= c.ptrSize { 1366 t.Align = c.ptrSize 1367 } 1368 1369 case *dwarf.VoidType: 1370 t.Go = c.goVoid 1371 t.C.Set("void") 1372 t.Align = 1 1373 } 1374 1375 switch dtype.(type) { 1376 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 1377 s := dtype.Common().Name 1378 if s != "" { 1379 if ss, ok := dwarfToName[s]; ok { 1380 s = ss 1381 } 1382 s = strings.Join(strings.Split(s, " "), "") // strip spaces 1383 name := c.Ident("_Ctype_" + s) 1384 tt := *t 1385 typedef[name.Name] = &tt 1386 if !*godefs { 1387 t.Go = name 1388 } 1389 } 1390 } 1391 1392 if t.Size < 0 { 1393 // Unsized types are [0]byte, unless they're typedefs of other types 1394 // or structs with tags. 1395 // if so, use the name we've already defined. 1396 t.Size = 0 1397 switch dt := dtype.(type) { 1398 case *dwarf.TypedefType: 1399 // ok 1400 case *dwarf.StructType: 1401 if dt.StructName != "" { 1402 break 1403 } 1404 t.Go = c.Opaque(0) 1405 default: 1406 t.Go = c.Opaque(0) 1407 } 1408 if t.C.Empty() { 1409 t.C.Set("void") 1410 } 1411 } 1412 1413 if t.C.Empty() { 1414 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 1415 } 1416 1417 return t 1418 } 1419 1420 // isStructUnionClass reports whether the type described by the Go syntax x 1421 // is a struct, union, or class with a tag. 1422 func isStructUnionClass(x ast.Expr) bool { 1423 id, ok := x.(*ast.Ident) 1424 if !ok { 1425 return false 1426 } 1427 name := id.Name 1428 return strings.HasPrefix(name, "_Ctype_struct_") || 1429 strings.HasPrefix(name, "_Ctype_union_") || 1430 strings.HasPrefix(name, "_Ctype_class_") 1431 } 1432 1433 // FuncArg returns a Go type with the same memory layout as 1434 // dtype when used as the type of a C function argument. 1435 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 1436 t := c.Type(dtype, pos) 1437 switch dt := dtype.(type) { 1438 case *dwarf.ArrayType: 1439 // Arrays are passed implicitly as pointers in C. 1440 // In Go, we must be explicit. 1441 tr := &TypeRepr{} 1442 tr.Set("%s*", t.C) 1443 return &Type{ 1444 Size: c.ptrSize, 1445 Align: c.ptrSize, 1446 Go: &ast.StarExpr{X: t.Go}, 1447 C: tr, 1448 } 1449 case *dwarf.TypedefType: 1450 // C has much more relaxed rules than Go for 1451 // implicit type conversions. When the parameter 1452 // is type T defined as *X, simulate a little of the 1453 // laxness of C by making the argument *X instead of T. 1454 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 1455 // Unless the typedef happens to point to void* since 1456 // Go has special rules around using unsafe.Pointer. 1457 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 1458 break 1459 } 1460 1461 t = c.Type(ptr, pos) 1462 if t == nil { 1463 return nil 1464 } 1465 1466 // Remember the C spelling, in case the struct 1467 // has __attribute__((unavailable)) on it. See issue 2888. 1468 t.Typedef = dt.Name 1469 } 1470 } 1471 return t 1472 } 1473 1474 // FuncType returns the Go type analogous to dtype. 1475 // There is no guarantee about matching memory layout. 1476 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 1477 p := make([]*Type, len(dtype.ParamType)) 1478 gp := make([]*ast.Field, len(dtype.ParamType)) 1479 for i, f := range dtype.ParamType { 1480 // gcc's DWARF generator outputs a single DotDotDotType parameter for 1481 // function pointers that specify no parameters (e.g. void 1482 // (*__cgo_0)()). Treat this special case as void. This case is 1483 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 1484 // legal). 1485 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 1486 p, gp = nil, nil 1487 break 1488 } 1489 p[i] = c.FuncArg(f, pos) 1490 gp[i] = &ast.Field{Type: p[i].Go} 1491 } 1492 var r *Type 1493 var gr []*ast.Field 1494 if _, ok := dtype.ReturnType.(*dwarf.VoidType); ok { 1495 gr = []*ast.Field{{Type: c.goVoid}} 1496 } else if dtype.ReturnType != nil { 1497 r = c.Type(dtype.ReturnType, pos) 1498 gr = []*ast.Field{{Type: r.Go}} 1499 } 1500 return &FuncType{ 1501 Params: p, 1502 Result: r, 1503 Go: &ast.FuncType{ 1504 Params: &ast.FieldList{List: gp}, 1505 Results: &ast.FieldList{List: gr}, 1506 }, 1507 } 1508 } 1509 1510 // Identifier 1511 func (c *typeConv) Ident(s string) *ast.Ident { 1512 return ast.NewIdent(s) 1513 } 1514 1515 // Opaque type of n bytes. 1516 func (c *typeConv) Opaque(n int64) ast.Expr { 1517 return &ast.ArrayType{ 1518 Len: c.intExpr(n), 1519 Elt: c.byte, 1520 } 1521 } 1522 1523 // Expr for integer n. 1524 func (c *typeConv) intExpr(n int64) ast.Expr { 1525 return &ast.BasicLit{ 1526 Kind: token.INT, 1527 Value: strconv.FormatInt(n, 10), 1528 } 1529 } 1530 1531 // Add padding of given size to fld. 1532 func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field { 1533 n := len(fld) 1534 fld = fld[0 : n+1] 1535 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 1536 return fld 1537 } 1538 1539 // Struct conversion: return Go and (6g) C syntax for type. 1540 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 1541 // Minimum alignment for a struct is 1 byte. 1542 align = 1 1543 1544 var buf bytes.Buffer 1545 buf.WriteString("struct {") 1546 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 1547 off := int64(0) 1548 1549 // Rename struct fields that happen to be named Go keywords into 1550 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 1551 // be mangled. Any existing identifier that already has the same name on 1552 // the C-side will cause the Go-mangled version to be prefixed with _. 1553 // (e.g. in a struct with fields '_type' and 'type', the latter would be 1554 // rendered as '__type' in Go). 1555 ident := make(map[string]string) 1556 used := make(map[string]bool) 1557 for _, f := range dt.Field { 1558 ident[f.Name] = f.Name 1559 used[f.Name] = true 1560 } 1561 1562 if !*godefs { 1563 for cid, goid := range ident { 1564 if token.Lookup(goid).IsKeyword() { 1565 // Avoid keyword 1566 goid = "_" + goid 1567 1568 // Also avoid existing fields 1569 for _, exist := used[goid]; exist; _, exist = used[goid] { 1570 goid = "_" + goid 1571 } 1572 1573 used[goid] = true 1574 ident[cid] = goid 1575 } 1576 } 1577 } 1578 1579 anon := 0 1580 for _, f := range dt.Field { 1581 if f.ByteOffset > off { 1582 fld = c.pad(fld, f.ByteOffset-off) 1583 off = f.ByteOffset 1584 } 1585 1586 name := f.Name 1587 ft := f.Type 1588 1589 // In godefs mode, if this field is a C11 1590 // anonymous union then treat the first field in the 1591 // union as the field in the struct. This handles 1592 // cases like the glibc <sys/resource.h> file; see 1593 // issue 6677. 1594 if *godefs { 1595 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] { 1596 name = st.Field[0].Name 1597 ident[name] = name 1598 ft = st.Field[0].Type 1599 } 1600 } 1601 1602 // TODO: Handle fields that are anonymous structs by 1603 // promoting the fields of the inner struct. 1604 1605 t := c.Type(ft, pos) 1606 tgo := t.Go 1607 size := t.Size 1608 talign := t.Align 1609 if f.BitSize > 0 { 1610 if f.BitSize%8 != 0 { 1611 continue 1612 } 1613 size = f.BitSize / 8 1614 name := tgo.(*ast.Ident).String() 1615 if strings.HasPrefix(name, "int") { 1616 name = "int" 1617 } else { 1618 name = "uint" 1619 } 1620 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) 1621 talign = size 1622 } 1623 1624 if talign > 0 && f.ByteOffset%talign != 0 { 1625 // Drop misaligned fields, the same way we drop integer bit fields. 1626 // The goal is to make available what can be made available. 1627 // Otherwise one bad and unneeded field in an otherwise okay struct 1628 // makes the whole program not compile. Much of the time these 1629 // structs are in system headers that cannot be corrected. 1630 continue 1631 } 1632 n := len(fld) 1633 fld = fld[0 : n+1] 1634 if name == "" { 1635 name = fmt.Sprintf("anon%d", anon) 1636 anon++ 1637 ident[name] = name 1638 } 1639 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 1640 off += size 1641 buf.WriteString(t.C.String()) 1642 buf.WriteString(" ") 1643 buf.WriteString(name) 1644 buf.WriteString("; ") 1645 if talign > align { 1646 align = talign 1647 } 1648 } 1649 if off < dt.ByteSize { 1650 fld = c.pad(fld, dt.ByteSize-off) 1651 off = dt.ByteSize 1652 } 1653 if off != dt.ByteSize { 1654 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 1655 } 1656 buf.WriteString("}") 1657 csyntax = buf.String() 1658 1659 if *godefs { 1660 godefsFields(fld) 1661 } 1662 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 1663 return 1664 } 1665 1666 func upper(s string) string { 1667 if s == "" { 1668 return "" 1669 } 1670 r, size := utf8.DecodeRuneInString(s) 1671 if r == '_' { 1672 return "X" + s 1673 } 1674 return string(unicode.ToUpper(r)) + s[size:] 1675 } 1676 1677 // godefsFields rewrites field names for use in Go or C definitions. 1678 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 1679 // converts names to upper case, and rewrites _ into Pad_godefs_n, 1680 // so that all fields are exported. 1681 func godefsFields(fld []*ast.Field) { 1682 prefix := fieldPrefix(fld) 1683 npad := 0 1684 for _, f := range fld { 1685 for _, n := range f.Names { 1686 if n.Name != prefix { 1687 n.Name = strings.TrimPrefix(n.Name, prefix) 1688 } 1689 if n.Name == "_" { 1690 // Use exported name instead. 1691 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 1692 npad++ 1693 } 1694 n.Name = upper(n.Name) 1695 } 1696 } 1697 } 1698 1699 // fieldPrefix returns the prefix that should be removed from all the 1700 // field names when generating the C or Go code. For generated 1701 // C, we leave the names as is (tv_sec, tv_usec), since that's what 1702 // people are used to seeing in C. For generated Go code, such as 1703 // package syscall's data structures, we drop a common prefix 1704 // (so sec, usec, which will get turned into Sec, Usec for exporting). 1705 func fieldPrefix(fld []*ast.Field) string { 1706 prefix := "" 1707 for _, f := range fld { 1708 for _, n := range f.Names { 1709 // Ignore field names that don't have the prefix we're 1710 // looking for. It is common in C headers to have fields 1711 // named, say, _pad in an otherwise prefixed header. 1712 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 1713 // still want to remove the tv_ prefix. 1714 // The check for "orig_" here handles orig_eax in the 1715 // x86 ptrace register sets, which otherwise have all fields 1716 // with reg_ prefixes. 1717 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 1718 continue 1719 } 1720 i := strings.Index(n.Name, "_") 1721 if i < 0 { 1722 continue 1723 } 1724 if prefix == "" { 1725 prefix = n.Name[:i+1] 1726 } else if prefix != n.Name[:i+1] { 1727 return "" 1728 } 1729 } 1730 } 1731 return prefix 1732 }