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