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