github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/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 "math" 24 "os" 25 "strconv" 26 "strings" 27 "unicode" 28 "unicode/utf8" 29 ) 30 31 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines") 32 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations") 33 34 var nameToC = map[string]string{ 35 "schar": "signed char", 36 "uchar": "unsigned char", 37 "ushort": "unsigned short", 38 "uint": "unsigned int", 39 "ulong": "unsigned long", 40 "longlong": "long long", 41 "ulonglong": "unsigned long long", 42 "complexfloat": "float _Complex", 43 "complexdouble": "double _Complex", 44 } 45 46 // cname returns the C name to use for C.s. 47 // The expansions are listed in nameToC and also 48 // struct_foo becomes "struct foo", and similarly for 49 // union and enum. 50 func cname(s string) string { 51 if t, ok := nameToC[s]; ok { 52 return t 53 } 54 55 if strings.HasPrefix(s, "struct_") { 56 return "struct " + s[len("struct_"):] 57 } 58 if strings.HasPrefix(s, "union_") { 59 return "union " + s[len("union_"):] 60 } 61 if strings.HasPrefix(s, "enum_") { 62 return "enum " + s[len("enum_"):] 63 } 64 if strings.HasPrefix(s, "sizeof_") { 65 return "sizeof(" + cname(s[len("sizeof_"):]) + ")" 66 } 67 return s 68 } 69 70 // DiscardCgoDirectives processes the import C preamble, and discards 71 // all #cgo CFLAGS and LDFLAGS directives, so they don't make their 72 // way into _cgo_export.h. 73 func (f *File) DiscardCgoDirectives() { 74 linesIn := strings.Split(f.Preamble, "\n") 75 linesOut := make([]string, 0, len(linesIn)) 76 for _, line := range linesIn { 77 l := strings.TrimSpace(line) 78 if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) { 79 linesOut = append(linesOut, line) 80 } else { 81 linesOut = append(linesOut, "") 82 } 83 } 84 f.Preamble = strings.Join(linesOut, "\n") 85 } 86 87 // addToFlag appends args to flag. All flags are later written out onto the 88 // _cgo_flags file for the build system to use. 89 func (p *Package) addToFlag(flag string, args []string) { 90 p.CgoFlags[flag] = append(p.CgoFlags[flag], args...) 91 if flag == "CFLAGS" { 92 // We'll also need these when preprocessing for dwarf information. 93 p.GccOptions = append(p.GccOptions, args...) 94 } 95 } 96 97 // splitQuoted splits the string s around each instance of one or more consecutive 98 // white space characters while taking into account quotes and escaping, and 99 // returns an array of substrings of s or an empty list if s contains only white space. 100 // Single quotes and double quotes are recognized to prevent splitting within the 101 // quoted region, and are removed from the resulting substrings. If a quote in s 102 // isn't closed err will be set and r will have the unclosed argument as the 103 // last element. The backslash is used for escaping. 104 // 105 // For example, the following string: 106 // 107 // `a b:"c d" 'e''f' "g\""` 108 // 109 // Would be parsed as: 110 // 111 // []string{"a", "b:c d", "ef", `g"`} 112 // 113 func splitQuoted(s string) (r []string, err error) { 114 var args []string 115 arg := make([]rune, len(s)) 116 escaped := false 117 quoted := false 118 quote := '\x00' 119 i := 0 120 for _, r := range s { 121 switch { 122 case escaped: 123 escaped = false 124 case r == '\\': 125 escaped = true 126 continue 127 case quote != 0: 128 if r == quote { 129 quote = 0 130 continue 131 } 132 case r == '"' || r == '\'': 133 quoted = true 134 quote = r 135 continue 136 case unicode.IsSpace(r): 137 if quoted || i > 0 { 138 quoted = false 139 args = append(args, string(arg[:i])) 140 i = 0 141 } 142 continue 143 } 144 arg[i] = r 145 i++ 146 } 147 if quoted || i > 0 { 148 args = append(args, string(arg[:i])) 149 } 150 if quote != 0 { 151 err = errors.New("unclosed quote") 152 } else if escaped { 153 err = errors.New("unfinished escaping") 154 } 155 return args, err 156 } 157 158 // Translate rewrites f.AST, the original Go input, to remove 159 // references to the imported package C, replacing them with 160 // references to the equivalent Go types, functions, and variables. 161 func (p *Package) Translate(f *File) { 162 for _, cref := range f.Ref { 163 // Convert C.ulong to C.unsigned long, etc. 164 cref.Name.C = cname(cref.Name.Go) 165 } 166 p.loadDefines(f) 167 needType := p.guessKinds(f) 168 if len(needType) > 0 { 169 p.loadDWARF(f, needType) 170 } 171 if p.rewriteCalls(f) { 172 // Add `import _cgo_unsafe "unsafe"` as the first decl 173 // after the package statement. 174 imp := &ast.GenDecl{ 175 Tok: token.IMPORT, 176 Specs: []ast.Spec{ 177 &ast.ImportSpec{ 178 Name: ast.NewIdent("_cgo_unsafe"), 179 Path: &ast.BasicLit{ 180 Kind: token.STRING, 181 Value: `"unsafe"`, 182 }, 183 }, 184 }, 185 } 186 f.AST.Decls = append([]ast.Decl{imp}, f.AST.Decls...) 187 } 188 p.rewriteRef(f) 189 } 190 191 // loadDefines coerces gcc into spitting out the #defines in use 192 // in the file f and saves relevant renamings in f.Name[name].Define. 193 func (p *Package) loadDefines(f *File) { 194 var b bytes.Buffer 195 b.WriteString(f.Preamble) 196 b.WriteString(builtinProlog) 197 stdout := p.gccDefines(b.Bytes()) 198 199 for _, line := range strings.Split(stdout, "\n") { 200 if len(line) < 9 || line[0:7] != "#define" { 201 continue 202 } 203 204 line = strings.TrimSpace(line[8:]) 205 206 var key, val string 207 spaceIndex := strings.Index(line, " ") 208 tabIndex := strings.Index(line, "\t") 209 210 if spaceIndex == -1 && tabIndex == -1 { 211 continue 212 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) { 213 key = line[0:spaceIndex] 214 val = strings.TrimSpace(line[spaceIndex:]) 215 } else { 216 key = line[0:tabIndex] 217 val = strings.TrimSpace(line[tabIndex:]) 218 } 219 220 if key == "__clang__" { 221 p.GccIsClang = true 222 } 223 224 if n := f.Name[key]; n != nil { 225 if *debugDefine { 226 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val) 227 } 228 n.Define = val 229 } 230 } 231 } 232 233 // guessKinds tricks gcc into revealing the kind of each 234 // name xxx for the references C.xxx in the Go input. 235 // The kind is either a constant, type, or variable. 236 func (p *Package) guessKinds(f *File) []*Name { 237 // Determine kinds for names we already know about, 238 // like #defines or 'struct foo', before bothering with gcc. 239 var names, needType []*Name 240 for _, key := range nameKeys(f.Name) { 241 n := f.Name[key] 242 // If we've already found this name as a #define 243 // and we can translate it as a constant value, do so. 244 if n.Define != "" { 245 if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil { 246 n.Kind = "iconst" 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 n.Const = fmt.Sprintf("%#x", i) 252 } else if n.Define[0] == '\'' { 253 if _, err := parser.ParseExpr(n.Define); err == nil { 254 n.Kind = "iconst" 255 n.Const = n.Define 256 } 257 } else if n.Define[0] == '"' { 258 if _, err := parser.ParseExpr(n.Define); err == nil { 259 n.Kind = "sconst" 260 n.Const = n.Define 261 } 262 } 263 264 if n.IsConst() { 265 continue 266 } 267 268 if isName(n.Define) { 269 n.C = n.Define 270 } 271 } 272 273 // If this is a struct, union, or enum type name, no need to guess the kind. 274 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") { 275 n.Kind = "type" 276 needType = append(needType, n) 277 continue 278 } 279 280 // Otherwise, we'll need to find out from gcc. 281 names = append(names, n) 282 } 283 284 // Bypass gcc if there's nothing left to find out. 285 if len(names) == 0 { 286 return needType 287 } 288 289 // Coerce gcc into telling us whether each name is a type, a value, or undeclared. 290 // For names, find out whether they are integer constants. 291 // We used to look at specific warning or error messages here, but that tied the 292 // behavior too closely to specific versions of the compilers. 293 // Instead, arrange that we can infer what we need from only the presence or absence 294 // of an error on a specific line. 295 // 296 // For each name, we generate these lines, where xxx is the index in toSniff plus one. 297 // 298 // #line xxx "not-declared" 299 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; } 300 // #line xxx "not-type" 301 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; } 302 // #line xxx "not-int-const" 303 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; } 304 // #line xxx "not-num-const" 305 // void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); } 306 // #line xxx "not-str-lit" 307 // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); } 308 // 309 // If we see an error at not-declared:xxx, the corresponding name is not declared. 310 // If we see an error at not-type:xxx, the corresponding name is a type. 311 // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant. 312 // If we see an error at not-num-const:xxx, the corresponding name is not a number constant. 313 // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal. 314 // 315 // The specific input forms are chosen so that they are valid C syntax regardless of 316 // whether name denotes a type or an expression. 317 318 var b bytes.Buffer 319 b.WriteString(f.Preamble) 320 b.WriteString(builtinProlog) 321 322 for i, n := range names { 323 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+ 324 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+ 325 "#line %d \"not-type\"\n"+ 326 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+ 327 "#line %d \"not-int-const\"\n"+ 328 "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+ 329 "#line %d \"not-num-const\"\n"+ 330 "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+ 331 "#line %d \"not-str-lit\"\n"+ 332 "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n", 333 i+1, i+1, n.C, 334 i+1, i+1, n.C, 335 i+1, i+1, n.C, 336 i+1, i+1, n.C, 337 i+1, i+1, n.C, 338 ) 339 } 340 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+ 341 "int __cgo__1 = __cgo__2;\n") 342 343 stderr := p.gccErrors(b.Bytes()) 344 if stderr == "" { 345 fatalf("%s produced no output\non input:\n%s", p.gccBaseCmd()[0], b.Bytes()) 346 } 347 348 completed := false 349 sniff := make([]int, len(names)) 350 const ( 351 notType = 1 << iota 352 notIntConst 353 notNumConst 354 notStrLiteral 355 notDeclared 356 ) 357 sawUnmatchedErrors := false 358 for _, line := range strings.Split(stderr, "\n") { 359 // Ignore warnings and random comments, with one 360 // exception: newer GCC versions will sometimes emit 361 // an error on a macro #define with a note referring 362 // to where the expansion occurs. We care about where 363 // the expansion occurs, so in that case treat the note 364 // as an error. 365 isError := strings.Contains(line, ": error:") 366 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors 367 if !isError && !isErrorNote { 368 continue 369 } 370 371 c1 := strings.Index(line, ":") 372 if c1 < 0 { 373 continue 374 } 375 c2 := strings.Index(line[c1+1:], ":") 376 if c2 < 0 { 377 continue 378 } 379 c2 += c1 + 1 380 381 filename := line[:c1] 382 i, _ := strconv.Atoi(line[c1+1 : c2]) 383 i-- 384 if i < 0 || i >= len(names) { 385 if isError { 386 sawUnmatchedErrors = true 387 } 388 continue 389 } 390 391 switch filename { 392 case "completed": 393 // Strictly speaking, there is no guarantee that seeing the error at completed:1 394 // (at the end of the file) means we've seen all the errors from earlier in the file, 395 // but usually it does. Certainly if we don't see the completed:1 error, we did 396 // not get all the errors we expected. 397 completed = true 398 399 case "not-declared": 400 sniff[i] |= notDeclared 401 case "not-type": 402 sniff[i] |= notType 403 case "not-int-const": 404 sniff[i] |= notIntConst 405 case "not-num-const": 406 sniff[i] |= notNumConst 407 case "not-str-lit": 408 sniff[i] |= notStrLiteral 409 default: 410 if isError { 411 sawUnmatchedErrors = true 412 } 413 continue 414 } 415 416 sawUnmatchedErrors = false 417 } 418 419 if !completed { 420 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr) 421 } 422 423 for i, n := range names { 424 switch sniff[i] { 425 default: 426 var tpos token.Pos 427 for _, ref := range f.Ref { 428 if ref.Name == n { 429 tpos = ref.Pos() 430 break 431 } 432 } 433 error_(tpos, "could not determine kind of name for C.%s", fixGo(n.Go)) 434 case notStrLiteral | notType: 435 n.Kind = "iconst" 436 case notIntConst | notStrLiteral | notType: 437 n.Kind = "fconst" 438 case notIntConst | notNumConst | notType: 439 n.Kind = "sconst" 440 case notIntConst | notNumConst | notStrLiteral: 441 n.Kind = "type" 442 case notIntConst | notNumConst | notStrLiteral | notType: 443 n.Kind = "not-type" 444 } 445 } 446 if nerrors > 0 { 447 // Check if compiling the preamble by itself causes any errors, 448 // because the messages we've printed out so far aren't helpful 449 // to users debugging preamble mistakes. See issue 8442. 450 preambleErrors := p.gccErrors([]byte(f.Preamble)) 451 if len(preambleErrors) > 0 { 452 error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors) 453 } 454 455 fatalf("unresolved names") 456 } 457 458 needType = append(needType, names...) 459 return needType 460 } 461 462 // loadDWARF parses the DWARF debug information generated 463 // by gcc to learn the details of the constants, variables, and types 464 // being referred to as C.xxx. 465 func (p *Package) loadDWARF(f *File, names []*Name) { 466 // Extract the types from the DWARF section of an object 467 // from a well-formed C program. Gcc only generates DWARF info 468 // for symbols in the object file, so it is not enough to print the 469 // preamble and hope the symbols we care about will be there. 470 // Instead, emit 471 // __typeof__(names[i]) *__cgo__i; 472 // for each entry in names and then dereference the type we 473 // learn for __cgo__i. 474 var b bytes.Buffer 475 b.WriteString(f.Preamble) 476 b.WriteString(builtinProlog) 477 b.WriteString("#line 1 \"cgo-dwarf-inference\"\n") 478 for i, n := range names { 479 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i) 480 if n.Kind == "iconst" { 481 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C) 482 } 483 } 484 485 // We create a data block initialized with the values, 486 // so we can read them out of the object file. 487 fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n") 488 for _, n := range names { 489 if n.Kind == "iconst" { 490 fmt.Fprintf(&b, "\t%s,\n", n.C) 491 } else { 492 fmt.Fprintf(&b, "\t0,\n") 493 } 494 } 495 // for the last entry, we cannot use 0, otherwise 496 // in case all __cgodebug_data is zero initialized, 497 // LLVM-based gcc will place the it in the __DATA.__common 498 // zero-filled section (our debug/macho doesn't support 499 // this) 500 fmt.Fprintf(&b, "\t1\n") 501 fmt.Fprintf(&b, "};\n") 502 503 // do the same work for floats. 504 fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n") 505 for _, n := range names { 506 if n.Kind == "fconst" { 507 fmt.Fprintf(&b, "\t%s,\n", n.C) 508 } else { 509 fmt.Fprintf(&b, "\t0,\n") 510 } 511 } 512 fmt.Fprintf(&b, "\t1\n") 513 fmt.Fprintf(&b, "};\n") 514 515 // do the same work for strings. 516 for i, n := range names { 517 if n.Kind == "sconst" { 518 fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C) 519 fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C) 520 } 521 } 522 523 d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names)) 524 525 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i. 526 types := make([]dwarf.Type, len(names)) 527 nameToIndex := make(map[*Name]int) 528 for i, n := range names { 529 nameToIndex[n] = i 530 } 531 nameToRef := make(map[*Name]*Ref) 532 for _, ref := range f.Ref { 533 nameToRef[ref.Name] = ref 534 } 535 r := d.Reader() 536 for { 537 e, err := r.Next() 538 if err != nil { 539 fatalf("reading DWARF entry: %s", err) 540 } 541 if e == nil { 542 break 543 } 544 switch e.Tag { 545 case dwarf.TagVariable: 546 name, _ := e.Val(dwarf.AttrName).(string) 547 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset) 548 if name == "" || typOff == 0 { 549 if e.Val(dwarf.AttrSpecification) != nil { 550 // Since we are reading all the DWARF, 551 // assume we will see the variable elsewhere. 552 break 553 } 554 fatalf("malformed DWARF TagVariable entry") 555 } 556 if !strings.HasPrefix(name, "__cgo__") { 557 break 558 } 559 typ, err := d.Type(typOff) 560 if err != nil { 561 fatalf("loading DWARF type: %s", err) 562 } 563 t, ok := typ.(*dwarf.PtrType) 564 if !ok || t == nil { 565 fatalf("internal error: %s has non-pointer type", name) 566 } 567 i, err := strconv.Atoi(name[7:]) 568 if err != nil { 569 fatalf("malformed __cgo__ name: %s", name) 570 } 571 types[i] = t.Type 572 } 573 if e.Tag != dwarf.TagCompileUnit { 574 r.SkipChildren() 575 } 576 } 577 578 // Record types and typedef information. 579 var conv typeConv 580 conv.Init(p.PtrSize, p.IntSize) 581 for i, n := range names { 582 if types[i] == nil { 583 continue 584 } 585 pos := token.NoPos 586 if ref, ok := nameToRef[n]; ok { 587 pos = ref.Pos() 588 } 589 f, fok := types[i].(*dwarf.FuncType) 590 if n.Kind != "type" && fok { 591 n.Kind = "func" 592 n.FuncType = conv.FuncType(f, pos) 593 } else { 594 n.Type = conv.Type(types[i], pos) 595 switch n.Kind { 596 case "iconst": 597 if i < len(ints) { 598 if _, ok := types[i].(*dwarf.UintType); ok { 599 n.Const = fmt.Sprintf("%#x", uint64(ints[i])) 600 } else { 601 n.Const = fmt.Sprintf("%#x", ints[i]) 602 } 603 } 604 case "fconst": 605 if i < len(floats) { 606 n.Const = fmt.Sprintf("%f", floats[i]) 607 } 608 case "sconst": 609 if i < len(strs) { 610 n.Const = fmt.Sprintf("%q", strs[i]) 611 } 612 } 613 } 614 conv.FinishType(pos) 615 } 616 } 617 618 // mangleName does name mangling to translate names 619 // from the original Go source files to the names 620 // used in the final Go files generated by cgo. 621 func (p *Package) mangleName(n *Name) { 622 // When using gccgo variables have to be 623 // exported so that they become global symbols 624 // that the C code can refer to. 625 prefix := "_C" 626 if *gccgo && n.IsVar() { 627 prefix = "C" 628 } 629 n.Mangle = prefix + n.Kind + "_" + n.Go 630 } 631 632 // rewriteCalls rewrites all calls that pass pointers to check that 633 // they follow the rules for passing pointers between Go and C. 634 // This returns whether the package needs to import unsafe as _cgo_unsafe. 635 func (p *Package) rewriteCalls(f *File) bool { 636 needsUnsafe := false 637 for _, call := range f.Calls { 638 // This is a call to C.xxx; set goname to "xxx". 639 goname := call.Call.Fun.(*ast.SelectorExpr).Sel.Name 640 if goname == "malloc" { 641 continue 642 } 643 name := f.Name[goname] 644 if name.Kind != "func" { 645 // Probably a type conversion. 646 continue 647 } 648 if p.rewriteCall(f, call, name) { 649 needsUnsafe = true 650 } 651 } 652 return needsUnsafe 653 } 654 655 // rewriteCall rewrites one call to add pointer checks. 656 // If any pointer checks are required, we rewrite the call into a 657 // function literal that calls _cgoCheckPointer for each pointer 658 // argument and then calls the original function. 659 // This returns whether the package needs to import unsafe as _cgo_unsafe. 660 func (p *Package) rewriteCall(f *File, call *Call, name *Name) bool { 661 // Avoid a crash if the number of arguments is 662 // less than the number of parameters. 663 // This will be caught when the generated file is compiled. 664 if len(call.Call.Args) < len(name.FuncType.Params) { 665 return false 666 } 667 668 any := false 669 for i, param := range name.FuncType.Params { 670 if p.needsPointerCheck(f, param.Go, call.Call.Args[i]) { 671 any = true 672 break 673 } 674 } 675 if !any { 676 return false 677 } 678 679 // We need to rewrite this call. 680 // 681 // We are going to rewrite C.f(p) to 682 // func (_cgo0 ptype) { 683 // _cgoCheckPointer(_cgo0) 684 // C.f(_cgo0) 685 // }(p) 686 // Using a function literal like this lets us do correct 687 // argument type checking, and works correctly if the call is 688 // deferred. 689 needsUnsafe := false 690 params := make([]*ast.Field, len(name.FuncType.Params)) 691 nargs := make([]ast.Expr, len(name.FuncType.Params)) 692 var stmts []ast.Stmt 693 for i, param := range name.FuncType.Params { 694 // params is going to become the parameters of the 695 // function literal. 696 // nargs is going to become the list of arguments made 697 // by the call within the function literal. 698 // nparam is the parameter of the function literal that 699 // corresponds to param. 700 701 origArg := call.Call.Args[i] 702 nparam := ast.NewIdent(fmt.Sprintf("_cgo%d", i)) 703 nargs[i] = nparam 704 705 // The Go version of the C type might use unsafe.Pointer, 706 // but the file might not import unsafe. 707 // Rewrite the Go type if necessary to use _cgo_unsafe. 708 ptype := p.rewriteUnsafe(param.Go) 709 if ptype != param.Go { 710 needsUnsafe = true 711 } 712 713 params[i] = &ast.Field{ 714 Names: []*ast.Ident{nparam}, 715 Type: ptype, 716 } 717 718 if !p.needsPointerCheck(f, param.Go, origArg) { 719 continue 720 } 721 722 // Run the cgo pointer checks on nparam. 723 724 // Change the function literal to call the real function 725 // with the parameter passed through _cgoCheckPointer. 726 c := &ast.CallExpr{ 727 Fun: ast.NewIdent("_cgoCheckPointer"), 728 Args: []ast.Expr{ 729 nparam, 730 }, 731 } 732 733 // Add optional additional arguments for an address 734 // expression. 735 c.Args = p.checkAddrArgs(f, c.Args, origArg) 736 737 stmt := &ast.ExprStmt{ 738 X: c, 739 } 740 stmts = append(stmts, stmt) 741 } 742 743 fcall := &ast.CallExpr{ 744 Fun: call.Call.Fun, 745 Args: nargs, 746 } 747 ftype := &ast.FuncType{ 748 Params: &ast.FieldList{ 749 List: params, 750 }, 751 } 752 if name.FuncType.Result != nil { 753 rtype := p.rewriteUnsafe(name.FuncType.Result.Go) 754 if rtype != name.FuncType.Result.Go { 755 needsUnsafe = true 756 } 757 ftype.Results = &ast.FieldList{ 758 List: []*ast.Field{ 759 &ast.Field{ 760 Type: rtype, 761 }, 762 }, 763 } 764 } 765 766 // There is a Ref pointing to the old call.Call.Fun. 767 for _, ref := range f.Ref { 768 if ref.Expr == &call.Call.Fun { 769 ref.Expr = &fcall.Fun 770 771 // If this call expects two results, we have to 772 // adjust the results of the function we generated. 773 if ref.Context == "call2" { 774 if ftype.Results == nil { 775 // An explicit void argument 776 // looks odd but it seems to 777 // be how cgo has worked historically. 778 ftype.Results = &ast.FieldList{ 779 List: []*ast.Field{ 780 &ast.Field{ 781 Type: ast.NewIdent("_Ctype_void"), 782 }, 783 }, 784 } 785 } 786 ftype.Results.List = append(ftype.Results.List, 787 &ast.Field{ 788 Type: ast.NewIdent("error"), 789 }) 790 } 791 } 792 } 793 794 var fbody ast.Stmt 795 if ftype.Results == nil { 796 fbody = &ast.ExprStmt{ 797 X: fcall, 798 } 799 } else { 800 fbody = &ast.ReturnStmt{ 801 Results: []ast.Expr{fcall}, 802 } 803 } 804 call.Call.Fun = &ast.FuncLit{ 805 Type: ftype, 806 Body: &ast.BlockStmt{ 807 List: append(stmts, fbody), 808 }, 809 } 810 call.Call.Lparen = token.NoPos 811 call.Call.Rparen = token.NoPos 812 813 return needsUnsafe 814 } 815 816 // needsPointerCheck returns whether the type t needs a pointer check. 817 // This is true if t is a pointer and if the value to which it points 818 // might contain a pointer. 819 func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool { 820 // An untyped nil does not need a pointer check, and when 821 // _cgoCheckPointer returns the untyped nil the type assertion we 822 // are going to insert will fail. Easier to just skip nil arguments. 823 // TODO: Note that this fails if nil is shadowed. 824 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" { 825 return false 826 } 827 828 return p.hasPointer(f, t, true) 829 } 830 831 // hasPointer is used by needsPointerCheck. If top is true it returns 832 // whether t is or contains a pointer that might point to a pointer. 833 // If top is false it returns whether t is or contains a pointer. 834 // f may be nil. 835 func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool { 836 switch t := t.(type) { 837 case *ast.ArrayType: 838 if t.Len == nil { 839 if !top { 840 return true 841 } 842 return p.hasPointer(f, t.Elt, false) 843 } 844 return p.hasPointer(f, t.Elt, top) 845 case *ast.StructType: 846 for _, field := range t.Fields.List { 847 if p.hasPointer(f, field.Type, top) { 848 return true 849 } 850 } 851 return false 852 case *ast.StarExpr: // Pointer type. 853 if !top { 854 return true 855 } 856 // Check whether this is a pointer to a C union (or class) 857 // type that contains a pointer. 858 if unionWithPointer[t.X] { 859 return true 860 } 861 return p.hasPointer(f, t.X, false) 862 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: 863 return true 864 case *ast.Ident: 865 // TODO: Handle types defined within function. 866 for _, d := range p.Decl { 867 gd, ok := d.(*ast.GenDecl) 868 if !ok || gd.Tok != token.TYPE { 869 continue 870 } 871 for _, spec := range gd.Specs { 872 ts, ok := spec.(*ast.TypeSpec) 873 if !ok { 874 continue 875 } 876 if ts.Name.Name == t.Name { 877 return p.hasPointer(f, ts.Type, top) 878 } 879 } 880 } 881 if def := typedef[t.Name]; def != nil { 882 return p.hasPointer(f, def.Go, top) 883 } 884 if t.Name == "string" { 885 return !top 886 } 887 if t.Name == "error" { 888 return true 889 } 890 if goTypes[t.Name] != nil { 891 return false 892 } 893 // We can't figure out the type. Conservative 894 // approach is to assume it has a pointer. 895 return true 896 case *ast.SelectorExpr: 897 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" { 898 // Type defined in a different package. 899 // Conservative approach is to assume it has a 900 // pointer. 901 return true 902 } 903 if f == nil { 904 // Conservative approach: assume pointer. 905 return true 906 } 907 name := f.Name[t.Sel.Name] 908 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil { 909 return p.hasPointer(f, name.Type.Go, top) 910 } 911 // We can't figure out the type. Conservative 912 // approach is to assume it has a pointer. 913 return true 914 default: 915 error_(t.Pos(), "could not understand type %s", gofmt(t)) 916 return true 917 } 918 } 919 920 // checkAddrArgs tries to add arguments to the call of 921 // _cgoCheckPointer when the argument is an address expression. We 922 // pass true to mean that the argument is an address operation of 923 // something other than a slice index, which means that it's only 924 // necessary to check the specific element pointed to, not the entire 925 // object. This is for &s.f, where f is a field in a struct. We can 926 // pass a slice or array, meaning that we should check the entire 927 // slice or array but need not check any other part of the object. 928 // This is for &s.a[i], where we need to check all of a. However, we 929 // only pass the slice or array if we can refer to it without side 930 // effects. 931 func (p *Package) checkAddrArgs(f *File, args []ast.Expr, x ast.Expr) []ast.Expr { 932 // Strip type conversions. 933 for { 934 c, ok := x.(*ast.CallExpr) 935 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) { 936 break 937 } 938 x = c.Args[0] 939 } 940 u, ok := x.(*ast.UnaryExpr) 941 if !ok || u.Op != token.AND { 942 return args 943 } 944 index, ok := u.X.(*ast.IndexExpr) 945 if !ok { 946 // This is the address of something that is not an 947 // index expression. We only need to examine the 948 // single value to which it points. 949 // TODO: what if true is shadowed? 950 return append(args, ast.NewIdent("true")) 951 } 952 if !p.hasSideEffects(f, index.X) { 953 // Examine the entire slice. 954 return append(args, index.X) 955 } 956 // Treat the pointer as unknown. 957 return args 958 } 959 960 // hasSideEffects returns whether the expression x has any side 961 // effects. x is an expression, not a statement, so the only side 962 // effect is a function call. 963 func (p *Package) hasSideEffects(f *File, x ast.Expr) bool { 964 found := false 965 f.walk(x, "expr", 966 func(f *File, x interface{}, context string) { 967 switch x.(type) { 968 case *ast.CallExpr: 969 found = true 970 } 971 }) 972 return found 973 } 974 975 // isType returns whether the expression is definitely a type. 976 // This is conservative--it returns false for an unknown identifier. 977 func (p *Package) isType(t ast.Expr) bool { 978 switch t := t.(type) { 979 case *ast.SelectorExpr: 980 id, ok := t.X.(*ast.Ident) 981 if !ok { 982 return false 983 } 984 if id.Name == "unsafe" && t.Sel.Name == "Pointer" { 985 return true 986 } 987 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil { 988 return true 989 } 990 return false 991 case *ast.Ident: 992 // TODO: This ignores shadowing. 993 switch t.Name { 994 case "unsafe.Pointer", "bool", "byte", 995 "complex64", "complex128", 996 "error", 997 "float32", "float64", 998 "int", "int8", "int16", "int32", "int64", 999 "rune", "string", 1000 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr": 1001 1002 return true 1003 } 1004 case *ast.StarExpr: 1005 return p.isType(t.X) 1006 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, 1007 *ast.MapType, *ast.ChanType: 1008 1009 return true 1010 } 1011 return false 1012 } 1013 1014 // rewriteUnsafe returns a version of t with references to unsafe.Pointer 1015 // rewritten to use _cgo_unsafe.Pointer instead. 1016 func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr { 1017 switch t := t.(type) { 1018 case *ast.Ident: 1019 // We don't see a SelectorExpr for unsafe.Pointer; 1020 // this is created by code in this file. 1021 if t.Name == "unsafe.Pointer" { 1022 return ast.NewIdent("_cgo_unsafe.Pointer") 1023 } 1024 case *ast.ArrayType: 1025 t1 := p.rewriteUnsafe(t.Elt) 1026 if t1 != t.Elt { 1027 r := *t 1028 r.Elt = t1 1029 return &r 1030 } 1031 case *ast.StructType: 1032 changed := false 1033 fields := *t.Fields 1034 fields.List = nil 1035 for _, f := range t.Fields.List { 1036 ft := p.rewriteUnsafe(f.Type) 1037 if ft == f.Type { 1038 fields.List = append(fields.List, f) 1039 } else { 1040 fn := *f 1041 fn.Type = ft 1042 fields.List = append(fields.List, &fn) 1043 changed = true 1044 } 1045 } 1046 if changed { 1047 r := *t 1048 r.Fields = &fields 1049 return &r 1050 } 1051 case *ast.StarExpr: // Pointer type. 1052 x1 := p.rewriteUnsafe(t.X) 1053 if x1 != t.X { 1054 r := *t 1055 r.X = x1 1056 return &r 1057 } 1058 } 1059 return t 1060 } 1061 1062 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the 1063 // Go equivalents, now that we have figured out the meaning of all 1064 // the xxx. In *godefs mode, rewriteRef replaces the names 1065 // with full definitions instead of mangled names. 1066 func (p *Package) rewriteRef(f *File) { 1067 // Keep a list of all the functions, to remove the ones 1068 // only used as expressions and avoid generating bridge 1069 // code for them. 1070 functions := make(map[string]bool) 1071 1072 // Assign mangled names. 1073 for _, n := range f.Name { 1074 if n.Kind == "not-type" { 1075 n.Kind = "var" 1076 } 1077 if n.Mangle == "" { 1078 p.mangleName(n) 1079 } 1080 if n.Kind == "func" { 1081 functions[n.Go] = false 1082 } 1083 } 1084 1085 // Now that we have all the name types filled in, 1086 // scan through the Refs to identify the ones that 1087 // are trying to do a ,err call. Also check that 1088 // functions are only used in calls. 1089 for _, r := range f.Ref { 1090 if r.Name.IsConst() && r.Name.Const == "" { 1091 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go)) 1092 } 1093 var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default 1094 switch r.Context { 1095 case "call", "call2": 1096 if r.Name.Kind != "func" { 1097 if r.Name.Kind == "type" { 1098 r.Context = "type" 1099 if r.Name.Type == nil { 1100 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1101 break 1102 } 1103 expr = r.Name.Type.Go 1104 break 1105 } 1106 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) 1107 break 1108 } 1109 functions[r.Name.Go] = true 1110 if r.Context == "call2" { 1111 if r.Name.Go == "_CMalloc" { 1112 error_(r.Pos(), "no two-result form for C.malloc") 1113 break 1114 } 1115 // Invent new Name for the two-result function. 1116 n := f.Name["2"+r.Name.Go] 1117 if n == nil { 1118 n = new(Name) 1119 *n = *r.Name 1120 n.AddError = true 1121 n.Mangle = "_C2func_" + n.Go 1122 f.Name["2"+r.Name.Go] = n 1123 } 1124 expr = ast.NewIdent(n.Mangle) 1125 r.Name = n 1126 break 1127 } 1128 case "expr": 1129 if r.Name.Kind == "func" { 1130 if builtinDefs[r.Name.C] != "" { 1131 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C)) 1132 } 1133 1134 // Function is being used in an expression, to e.g. pass around a C function pointer. 1135 // Create a new Name for this Ref which causes the variable to be declared in Go land. 1136 fpName := "fp_" + r.Name.Go 1137 name := f.Name[fpName] 1138 if name == nil { 1139 name = &Name{ 1140 Go: fpName, 1141 C: r.Name.C, 1142 Kind: "fpvar", 1143 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")}, 1144 } 1145 p.mangleName(name) 1146 f.Name[fpName] = name 1147 } 1148 r.Name = name 1149 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr 1150 // function is defined in out.go and simply returns its argument. See 1151 // issue 7757. 1152 expr = &ast.CallExpr{ 1153 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"}, 1154 Args: []ast.Expr{ast.NewIdent(name.Mangle)}, 1155 } 1156 } else if r.Name.Kind == "type" { 1157 // Okay - might be new(T) 1158 if r.Name.Type == nil { 1159 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1160 break 1161 } 1162 expr = r.Name.Type.Go 1163 } else if r.Name.Kind == "var" { 1164 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1165 } 1166 1167 case "selector": 1168 if r.Name.Kind == "var" { 1169 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1170 } else { 1171 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go)) 1172 } 1173 1174 case "type": 1175 if r.Name.Kind != "type" { 1176 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 1177 } else if r.Name.Type == nil { 1178 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 1179 // GCC won't raise an error when using pointers to such unknown types. 1180 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1181 } else { 1182 expr = r.Name.Type.Go 1183 } 1184 default: 1185 if r.Name.Kind == "func" { 1186 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 1187 } 1188 } 1189 if *godefs { 1190 // Substitute definition for mangled type name. 1191 if id, ok := expr.(*ast.Ident); ok { 1192 if t := typedef[id.Name]; t != nil { 1193 expr = t.Go 1194 } 1195 if id.Name == r.Name.Mangle && r.Name.Const != "" { 1196 expr = ast.NewIdent(r.Name.Const) 1197 } 1198 } 1199 } 1200 1201 // Copy position information from old expr into new expr, 1202 // in case expression being replaced is first on line. 1203 // See golang.org/issue/6563. 1204 pos := (*r.Expr).Pos() 1205 switch x := expr.(type) { 1206 case *ast.Ident: 1207 expr = &ast.Ident{NamePos: pos, Name: x.Name} 1208 } 1209 1210 *r.Expr = expr 1211 } 1212 1213 // Remove functions only used as expressions, so their respective 1214 // bridge functions are not generated. 1215 for name, used := range functions { 1216 if !used { 1217 delete(f.Name, name) 1218 } 1219 } 1220 } 1221 1222 // gccBaseCmd returns the start of the compiler command line. 1223 // It uses $CC if set, or else $GCC, or else the compiler recorded 1224 // during the initial build as defaultCC. 1225 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 1226 func (p *Package) gccBaseCmd() []string { 1227 // Use $CC if set, since that's what the build uses. 1228 if ret := strings.Fields(os.Getenv("CC")); len(ret) > 0 { 1229 return ret 1230 } 1231 // Try $GCC if set, since that's what we used to use. 1232 if ret := strings.Fields(os.Getenv("GCC")); len(ret) > 0 { 1233 return ret 1234 } 1235 return strings.Fields(defaultCC) 1236 } 1237 1238 // gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 1239 func (p *Package) gccMachine() []string { 1240 switch goarch { 1241 case "amd64": 1242 return []string{"-m64"} 1243 case "386": 1244 return []string{"-m32"} 1245 case "arm": 1246 return []string{"-marm"} // not thumb 1247 case "s390": 1248 return []string{"-m31"} 1249 case "s390x": 1250 return []string{"-m64"} 1251 case "mips64", "mips64le": 1252 return []string{"-mabi=64"} 1253 case "mips", "mipsle": 1254 return []string{"-mabi=32"} 1255 } 1256 return nil 1257 } 1258 1259 func gccTmp() string { 1260 return *objDir + "_cgo_.o" 1261 } 1262 1263 // gccCmd returns the gcc command line to use for compiling 1264 // the input. 1265 func (p *Package) gccCmd() []string { 1266 c := append(p.gccBaseCmd(), 1267 "-w", // no warnings 1268 "-Wno-error", // warnings are not errors 1269 "-o"+gccTmp(), // write object to tmp 1270 "-gdwarf-2", // generate DWARF v2 debugging symbols 1271 "-c", // do not link 1272 "-xc", // input language is C 1273 ) 1274 if p.GccIsClang { 1275 c = append(c, 1276 "-ferror-limit=0", 1277 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 1278 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 1279 // flag to disable the warning. Yes, really good diagnostics, clang. 1280 "-Wno-unknown-warning-option", 1281 "-Wno-unneeded-internal-declaration", 1282 "-Wno-unused-function", 1283 "-Qunused-arguments", 1284 // Clang embeds prototypes for some builtin functions, 1285 // like malloc and calloc, but all size_t parameters are 1286 // incorrectly typed unsigned long. We work around that 1287 // by disabling the builtin functions (this is safe as 1288 // it won't affect the actual compilation of the C code). 1289 // See: https://golang.org/issue/6506. 1290 "-fno-builtin", 1291 ) 1292 } 1293 1294 c = append(c, p.GccOptions...) 1295 c = append(c, p.gccMachine()...) 1296 c = append(c, "-") //read input from standard input 1297 return c 1298 } 1299 1300 // gccDebug runs gcc -gdwarf-2 over the C program stdin and 1301 // returns the corresponding DWARF data and, if present, debug data block. 1302 func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) { 1303 runGcc(stdin, p.gccCmd()) 1304 1305 isDebugInts := func(s string) bool { 1306 // Some systems use leading _ to denote non-assembly symbols. 1307 return s == "__cgodebug_ints" || s == "___cgodebug_ints" 1308 } 1309 isDebugFloats := func(s string) bool { 1310 // Some systems use leading _ to denote non-assembly symbols. 1311 return s == "__cgodebug_floats" || s == "___cgodebug_floats" 1312 } 1313 indexOfDebugStr := func(s string) int { 1314 // Some systems use leading _ to denote non-assembly symbols. 1315 if strings.HasPrefix(s, "___") { 1316 s = s[1:] 1317 } 1318 if strings.HasPrefix(s, "__cgodebug_str__") { 1319 if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil { 1320 return n 1321 } 1322 } 1323 return -1 1324 } 1325 indexOfDebugStrlen := func(s string) int { 1326 // Some systems use leading _ to denote non-assembly symbols. 1327 if strings.HasPrefix(s, "___") { 1328 s = s[1:] 1329 } 1330 if strings.HasPrefix(s, "__cgodebug_strlen__") { 1331 if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil { 1332 return n 1333 } 1334 } 1335 return -1 1336 } 1337 1338 strs = make([]string, nnames) 1339 1340 strdata := make(map[int]string, nnames) 1341 strlens := make(map[int]int, nnames) 1342 1343 buildStrings := func() { 1344 for n, strlen := range strlens { 1345 data := strdata[n] 1346 if len(data) <= strlen { 1347 fatalf("invalid string literal") 1348 } 1349 strs[n] = string(data[:strlen]) 1350 } 1351 } 1352 1353 if f, err := macho.Open(gccTmp()); err == nil { 1354 defer f.Close() 1355 d, err := f.DWARF() 1356 if err != nil { 1357 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1358 } 1359 bo := f.ByteOrder 1360 if f.Symtab != nil { 1361 for i := range f.Symtab.Syms { 1362 s := &f.Symtab.Syms[i] 1363 switch { 1364 case isDebugInts(s.Name): 1365 // Found it. Now find data section. 1366 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1367 sect := f.Sections[i] 1368 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1369 if sdat, err := sect.Data(); err == nil { 1370 data := sdat[s.Value-sect.Addr:] 1371 ints = make([]int64, len(data)/8) 1372 for i := range ints { 1373 ints[i] = int64(bo.Uint64(data[i*8:])) 1374 } 1375 } 1376 } 1377 } 1378 case isDebugFloats(s.Name): 1379 // Found it. Now find data section. 1380 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1381 sect := f.Sections[i] 1382 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1383 if sdat, err := sect.Data(); err == nil { 1384 data := sdat[s.Value-sect.Addr:] 1385 floats = make([]float64, len(data)/8) 1386 for i := range floats { 1387 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1388 } 1389 } 1390 } 1391 } 1392 default: 1393 if n := indexOfDebugStr(s.Name); n != -1 { 1394 // Found it. Now find data section. 1395 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1396 sect := f.Sections[i] 1397 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1398 if sdat, err := sect.Data(); err == nil { 1399 data := sdat[s.Value-sect.Addr:] 1400 strdata[n] = string(data) 1401 } 1402 } 1403 } 1404 break 1405 } 1406 if n := indexOfDebugStrlen(s.Name); n != -1 { 1407 // Found it. Now find data section. 1408 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1409 sect := f.Sections[i] 1410 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1411 if sdat, err := sect.Data(); err == nil { 1412 data := sdat[s.Value-sect.Addr:] 1413 strlen := bo.Uint64(data[:8]) 1414 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1415 fatalf("string literal too big") 1416 } 1417 strlens[n] = int(strlen) 1418 } 1419 } 1420 } 1421 break 1422 } 1423 } 1424 } 1425 1426 buildStrings() 1427 } 1428 return d, ints, floats, strs 1429 } 1430 1431 if f, err := elf.Open(gccTmp()); err == nil { 1432 defer f.Close() 1433 d, err := f.DWARF() 1434 if err != nil { 1435 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1436 } 1437 bo := f.ByteOrder 1438 symtab, err := f.Symbols() 1439 if err == nil { 1440 for i := range symtab { 1441 s := &symtab[i] 1442 switch { 1443 case isDebugInts(s.Name): 1444 // Found it. Now find data section. 1445 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1446 sect := f.Sections[i] 1447 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1448 if sdat, err := sect.Data(); err == nil { 1449 data := sdat[s.Value-sect.Addr:] 1450 ints = make([]int64, len(data)/8) 1451 for i := range ints { 1452 ints[i] = int64(bo.Uint64(data[i*8:])) 1453 } 1454 } 1455 } 1456 } 1457 case isDebugFloats(s.Name): 1458 // Found it. Now find data section. 1459 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1460 sect := f.Sections[i] 1461 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1462 if sdat, err := sect.Data(); err == nil { 1463 data := sdat[s.Value-sect.Addr:] 1464 floats = make([]float64, len(data)/8) 1465 for i := range floats { 1466 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1467 } 1468 } 1469 } 1470 } 1471 default: 1472 if n := indexOfDebugStr(s.Name); n != -1 { 1473 // Found it. Now find data section. 1474 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1475 sect := f.Sections[i] 1476 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1477 if sdat, err := sect.Data(); err == nil { 1478 data := sdat[s.Value-sect.Addr:] 1479 strdata[n] = string(data) 1480 } 1481 } 1482 } 1483 break 1484 } 1485 if n := indexOfDebugStrlen(s.Name); n != -1 { 1486 // Found it. Now find data section. 1487 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1488 sect := f.Sections[i] 1489 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1490 if sdat, err := sect.Data(); err == nil { 1491 data := sdat[s.Value-sect.Addr:] 1492 strlen := bo.Uint64(data[:8]) 1493 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1494 fatalf("string literal too big") 1495 } 1496 strlens[n] = int(strlen) 1497 } 1498 } 1499 } 1500 break 1501 } 1502 } 1503 } 1504 1505 buildStrings() 1506 } 1507 return d, ints, floats, strs 1508 } 1509 1510 if f, err := pe.Open(gccTmp()); err == nil { 1511 defer f.Close() 1512 d, err := f.DWARF() 1513 if err != nil { 1514 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1515 } 1516 bo := binary.LittleEndian 1517 for _, s := range f.Symbols { 1518 switch { 1519 case isDebugInts(s.Name): 1520 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1521 sect := f.Sections[i] 1522 if s.Value < sect.Size { 1523 if sdat, err := sect.Data(); err == nil { 1524 data := sdat[s.Value:] 1525 ints = make([]int64, len(data)/8) 1526 for i := range ints { 1527 ints[i] = int64(bo.Uint64(data[i*8:])) 1528 } 1529 } 1530 } 1531 } 1532 case isDebugFloats(s.Name): 1533 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1534 sect := f.Sections[i] 1535 if s.Value < sect.Size { 1536 if sdat, err := sect.Data(); err == nil { 1537 data := sdat[s.Value:] 1538 floats = make([]float64, len(data)/8) 1539 for i := range floats { 1540 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1541 } 1542 } 1543 } 1544 } 1545 default: 1546 if n := indexOfDebugStr(s.Name); n != -1 { 1547 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1548 sect := f.Sections[i] 1549 if s.Value < sect.Size { 1550 if sdat, err := sect.Data(); err == nil { 1551 data := sdat[s.Value:] 1552 strdata[n] = string(data) 1553 } 1554 } 1555 } 1556 break 1557 } 1558 if n := indexOfDebugStrlen(s.Name); n != -1 { 1559 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1560 sect := f.Sections[i] 1561 if s.Value < sect.Size { 1562 if sdat, err := sect.Data(); err == nil { 1563 data := sdat[s.Value:] 1564 strlen := bo.Uint64(data[:8]) 1565 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1566 fatalf("string literal too big") 1567 } 1568 strlens[n] = int(strlen) 1569 } 1570 } 1571 } 1572 break 1573 } 1574 } 1575 } 1576 1577 buildStrings() 1578 1579 return d, ints, floats, strs 1580 } 1581 1582 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) 1583 panic("not reached") 1584 } 1585 1586 // gccDefines runs gcc -E -dM -xc - over the C program stdin 1587 // and returns the corresponding standard output, which is the 1588 // #defines that gcc encountered while processing the input 1589 // and its included files. 1590 func (p *Package) gccDefines(stdin []byte) string { 1591 base := append(p.gccBaseCmd(), "-E", "-dM", "-xc") 1592 base = append(base, p.gccMachine()...) 1593 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 1594 return stdout 1595 } 1596 1597 // gccErrors runs gcc over the C program stdin and returns 1598 // the errors that gcc prints. That is, this function expects 1599 // gcc to fail. 1600 func (p *Package) gccErrors(stdin []byte) string { 1601 // TODO(rsc): require failure 1602 args := p.gccCmd() 1603 1604 // Optimization options can confuse the error messages; remove them. 1605 nargs := make([]string, 0, len(args)) 1606 for _, arg := range args { 1607 if !strings.HasPrefix(arg, "-O") { 1608 nargs = append(nargs, arg) 1609 } 1610 } 1611 1612 if *debugGcc { 1613 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " ")) 1614 os.Stderr.Write(stdin) 1615 fmt.Fprint(os.Stderr, "EOF\n") 1616 } 1617 stdout, stderr, _ := run(stdin, nargs) 1618 if *debugGcc { 1619 os.Stderr.Write(stdout) 1620 os.Stderr.Write(stderr) 1621 } 1622 return string(stderr) 1623 } 1624 1625 // runGcc runs the gcc command line args with stdin on standard input. 1626 // If the command exits with a non-zero exit status, runGcc prints 1627 // details about what was run and exits. 1628 // Otherwise runGcc returns the data written to standard output and standard error. 1629 // Note that for some of the uses we expect useful data back 1630 // on standard error, but for those uses gcc must still exit 0. 1631 func runGcc(stdin []byte, args []string) (string, string) { 1632 if *debugGcc { 1633 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 1634 os.Stderr.Write(stdin) 1635 fmt.Fprint(os.Stderr, "EOF\n") 1636 } 1637 stdout, stderr, ok := run(stdin, args) 1638 if *debugGcc { 1639 os.Stderr.Write(stdout) 1640 os.Stderr.Write(stderr) 1641 } 1642 if !ok { 1643 os.Stderr.Write(stderr) 1644 os.Exit(2) 1645 } 1646 return string(stdout), string(stderr) 1647 } 1648 1649 // A typeConv is a translator from dwarf types to Go types 1650 // with equivalent memory layout. 1651 type typeConv struct { 1652 // Cache of already-translated or in-progress types. 1653 m map[dwarf.Type]*Type 1654 1655 // Map from types to incomplete pointers to those types. 1656 ptrs map[dwarf.Type][]*Type 1657 // Keys of ptrs in insertion order (deterministic worklist) 1658 ptrKeys []dwarf.Type 1659 1660 // Predeclared types. 1661 bool ast.Expr 1662 byte ast.Expr // denotes padding 1663 int8, int16, int32, int64 ast.Expr 1664 uint8, uint16, uint32, uint64, uintptr ast.Expr 1665 float32, float64 ast.Expr 1666 complex64, complex128 ast.Expr 1667 void ast.Expr 1668 string ast.Expr 1669 goVoid ast.Expr // _Ctype_void, denotes C's void 1670 goVoidPtr ast.Expr // unsafe.Pointer or *byte 1671 1672 ptrSize int64 1673 intSize int64 1674 } 1675 1676 var tagGen int 1677 var typedef = make(map[string]*Type) 1678 var goIdent = make(map[string]*ast.Ident) 1679 1680 // unionWithPointer is true for a Go type that represents a C union (or class) 1681 // that may contain a pointer. This is used for cgo pointer checking. 1682 var unionWithPointer = make(map[ast.Expr]bool) 1683 1684 func (c *typeConv) Init(ptrSize, intSize int64) { 1685 c.ptrSize = ptrSize 1686 c.intSize = intSize 1687 c.m = make(map[dwarf.Type]*Type) 1688 c.ptrs = make(map[dwarf.Type][]*Type) 1689 c.bool = c.Ident("bool") 1690 c.byte = c.Ident("byte") 1691 c.int8 = c.Ident("int8") 1692 c.int16 = c.Ident("int16") 1693 c.int32 = c.Ident("int32") 1694 c.int64 = c.Ident("int64") 1695 c.uint8 = c.Ident("uint8") 1696 c.uint16 = c.Ident("uint16") 1697 c.uint32 = c.Ident("uint32") 1698 c.uint64 = c.Ident("uint64") 1699 c.uintptr = c.Ident("uintptr") 1700 c.float32 = c.Ident("float32") 1701 c.float64 = c.Ident("float64") 1702 c.complex64 = c.Ident("complex64") 1703 c.complex128 = c.Ident("complex128") 1704 c.void = c.Ident("void") 1705 c.string = c.Ident("string") 1706 c.goVoid = c.Ident("_Ctype_void") 1707 1708 // Normally cgo translates void* to unsafe.Pointer, 1709 // but for historical reasons -godefs uses *byte instead. 1710 if *godefs { 1711 c.goVoidPtr = &ast.StarExpr{X: c.byte} 1712 } else { 1713 c.goVoidPtr = c.Ident("unsafe.Pointer") 1714 } 1715 } 1716 1717 // base strips away qualifiers and typedefs to get the underlying type 1718 func base(dt dwarf.Type) dwarf.Type { 1719 for { 1720 if d, ok := dt.(*dwarf.QualType); ok { 1721 dt = d.Type 1722 continue 1723 } 1724 if d, ok := dt.(*dwarf.TypedefType); ok { 1725 dt = d.Type 1726 continue 1727 } 1728 break 1729 } 1730 return dt 1731 } 1732 1733 // unqual strips away qualifiers from a DWARF type. 1734 // In general we don't care about top-level qualifiers. 1735 func unqual(dt dwarf.Type) dwarf.Type { 1736 for { 1737 if d, ok := dt.(*dwarf.QualType); ok { 1738 dt = d.Type 1739 } else { 1740 break 1741 } 1742 } 1743 return dt 1744 } 1745 1746 // Map from dwarf text names to aliases we use in package "C". 1747 var dwarfToName = map[string]string{ 1748 "long int": "long", 1749 "long unsigned int": "ulong", 1750 "unsigned int": "uint", 1751 "short unsigned int": "ushort", 1752 "unsigned short": "ushort", // Used by Clang; issue 13129. 1753 "short int": "short", 1754 "long long int": "longlong", 1755 "long long unsigned int": "ulonglong", 1756 "signed char": "schar", 1757 "unsigned char": "uchar", 1758 } 1759 1760 const signedDelta = 64 1761 1762 // String returns the current type representation. Format arguments 1763 // are assembled within this method so that any changes in mutable 1764 // values are taken into account. 1765 func (tr *TypeRepr) String() string { 1766 if len(tr.Repr) == 0 { 1767 return "" 1768 } 1769 if len(tr.FormatArgs) == 0 { 1770 return tr.Repr 1771 } 1772 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 1773 } 1774 1775 // Empty reports whether the result of String would be "". 1776 func (tr *TypeRepr) Empty() bool { 1777 return len(tr.Repr) == 0 1778 } 1779 1780 // Set modifies the type representation. 1781 // If fargs are provided, repr is used as a format for fmt.Sprintf. 1782 // Otherwise, repr is used unprocessed as the type representation. 1783 func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 1784 tr.Repr = repr 1785 tr.FormatArgs = fargs 1786 } 1787 1788 // FinishType completes any outstanding type mapping work. 1789 // In particular, it resolves incomplete pointer types. 1790 func (c *typeConv) FinishType(pos token.Pos) { 1791 // Completing one pointer type might produce more to complete. 1792 // Keep looping until they're all done. 1793 for len(c.ptrKeys) > 0 { 1794 dtype := c.ptrKeys[0] 1795 c.ptrKeys = c.ptrKeys[1:] 1796 1797 // Note Type might invalidate c.ptrs[dtype]. 1798 t := c.Type(dtype, pos) 1799 for _, ptr := range c.ptrs[dtype] { 1800 ptr.Go.(*ast.StarExpr).X = t.Go 1801 ptr.C.Set("%s*", t.C) 1802 } 1803 c.ptrs[dtype] = nil // retain the map key 1804 } 1805 } 1806 1807 // Type returns a *Type with the same memory layout as 1808 // dtype when used as the type of a variable or a struct field. 1809 func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 1810 if t, ok := c.m[dtype]; ok { 1811 if t.Go == nil { 1812 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 1813 } 1814 return t 1815 } 1816 1817 t := new(Type) 1818 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 1819 t.Align = -1 1820 t.C = &TypeRepr{Repr: dtype.Common().Name} 1821 c.m[dtype] = t 1822 1823 switch dt := dtype.(type) { 1824 default: 1825 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 1826 1827 case *dwarf.AddrType: 1828 if t.Size != c.ptrSize { 1829 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 1830 } 1831 t.Go = c.uintptr 1832 t.Align = t.Size 1833 1834 case *dwarf.ArrayType: 1835 if dt.StrideBitSize > 0 { 1836 // Cannot represent bit-sized elements in Go. 1837 t.Go = c.Opaque(t.Size) 1838 break 1839 } 1840 count := dt.Count 1841 if count == -1 { 1842 // Indicates flexible array member, which Go doesn't support. 1843 // Translate to zero-length array instead. 1844 count = 0 1845 } 1846 sub := c.Type(dt.Type, pos) 1847 t.Align = sub.Align 1848 t.Go = &ast.ArrayType{ 1849 Len: c.intExpr(count), 1850 Elt: sub.Go, 1851 } 1852 // Recalculate t.Size now that we know sub.Size. 1853 t.Size = count * sub.Size 1854 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 1855 1856 case *dwarf.BoolType: 1857 t.Go = c.bool 1858 t.Align = 1 1859 1860 case *dwarf.CharType: 1861 if t.Size != 1 { 1862 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 1863 } 1864 t.Go = c.int8 1865 t.Align = 1 1866 1867 case *dwarf.EnumType: 1868 if t.Align = t.Size; t.Align >= c.ptrSize { 1869 t.Align = c.ptrSize 1870 } 1871 t.C.Set("enum " + dt.EnumName) 1872 signed := 0 1873 t.EnumValues = make(map[string]int64) 1874 for _, ev := range dt.Val { 1875 t.EnumValues[ev.Name] = ev.Val 1876 if ev.Val < 0 { 1877 signed = signedDelta 1878 } 1879 } 1880 switch t.Size + int64(signed) { 1881 default: 1882 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 1883 case 1: 1884 t.Go = c.uint8 1885 case 2: 1886 t.Go = c.uint16 1887 case 4: 1888 t.Go = c.uint32 1889 case 8: 1890 t.Go = c.uint64 1891 case 1 + signedDelta: 1892 t.Go = c.int8 1893 case 2 + signedDelta: 1894 t.Go = c.int16 1895 case 4 + signedDelta: 1896 t.Go = c.int32 1897 case 8 + signedDelta: 1898 t.Go = c.int64 1899 } 1900 1901 case *dwarf.FloatType: 1902 switch t.Size { 1903 default: 1904 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 1905 case 4: 1906 t.Go = c.float32 1907 case 8: 1908 t.Go = c.float64 1909 } 1910 if t.Align = t.Size; t.Align >= c.ptrSize { 1911 t.Align = c.ptrSize 1912 } 1913 1914 case *dwarf.ComplexType: 1915 switch t.Size { 1916 default: 1917 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 1918 case 8: 1919 t.Go = c.complex64 1920 case 16: 1921 t.Go = c.complex128 1922 } 1923 if t.Align = t.Size / 2; t.Align >= c.ptrSize { 1924 t.Align = c.ptrSize 1925 } 1926 1927 case *dwarf.FuncType: 1928 // No attempt at translation: would enable calls 1929 // directly between worlds, but we need to moderate those. 1930 t.Go = c.uintptr 1931 t.Align = c.ptrSize 1932 1933 case *dwarf.IntType: 1934 if dt.BitSize > 0 { 1935 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 1936 } 1937 switch t.Size { 1938 default: 1939 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 1940 case 1: 1941 t.Go = c.int8 1942 case 2: 1943 t.Go = c.int16 1944 case 4: 1945 t.Go = c.int32 1946 case 8: 1947 t.Go = c.int64 1948 case 16: 1949 t.Go = &ast.ArrayType{ 1950 Len: c.intExpr(t.Size), 1951 Elt: c.uint8, 1952 } 1953 } 1954 if t.Align = t.Size; t.Align >= c.ptrSize { 1955 t.Align = c.ptrSize 1956 } 1957 1958 case *dwarf.PtrType: 1959 // Clang doesn't emit DW_AT_byte_size for pointer types. 1960 if t.Size != c.ptrSize && t.Size != -1 { 1961 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype) 1962 } 1963 t.Size = c.ptrSize 1964 t.Align = c.ptrSize 1965 1966 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 1967 t.Go = c.goVoidPtr 1968 t.C.Set("void*") 1969 dq := dt.Type 1970 for { 1971 if d, ok := dq.(*dwarf.QualType); ok { 1972 t.C.Set(d.Qual + " " + t.C.String()) 1973 dq = d.Type 1974 } else { 1975 break 1976 } 1977 } 1978 break 1979 } 1980 1981 // Placeholder initialization; completed in FinishType. 1982 t.Go = &ast.StarExpr{} 1983 t.C.Set("<incomplete>*") 1984 if _, ok := c.ptrs[dt.Type]; !ok { 1985 c.ptrKeys = append(c.ptrKeys, dt.Type) 1986 } 1987 c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t) 1988 1989 case *dwarf.QualType: 1990 t1 := c.Type(dt.Type, pos) 1991 t.Size = t1.Size 1992 t.Align = t1.Align 1993 t.Go = t1.Go 1994 if unionWithPointer[t1.Go] { 1995 unionWithPointer[t.Go] = true 1996 } 1997 t.EnumValues = nil 1998 t.Typedef = "" 1999 t.C.Set("%s "+dt.Qual, t1.C) 2000 return t 2001 2002 case *dwarf.StructType: 2003 // Convert to Go struct, being careful about alignment. 2004 // Have to give it a name to simulate C "struct foo" references. 2005 tag := dt.StructName 2006 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 2007 break 2008 } 2009 if tag == "" { 2010 tag = "__" + strconv.Itoa(tagGen) 2011 tagGen++ 2012 } else if t.C.Empty() { 2013 t.C.Set(dt.Kind + " " + tag) 2014 } 2015 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 2016 t.Go = name // publish before recursive calls 2017 goIdent[name.Name] = name 2018 if dt.ByteSize < 0 { 2019 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 2020 // so execute the basic things that the struct case would do 2021 // other than try to determine a Go representation. 2022 tt := *t 2023 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 2024 tt.Go = c.Ident("struct{}") 2025 typedef[name.Name] = &tt 2026 break 2027 } 2028 switch dt.Kind { 2029 case "class", "union": 2030 t.Go = c.Opaque(t.Size) 2031 if c.dwarfHasPointer(dt, pos) { 2032 unionWithPointer[t.Go] = true 2033 } 2034 if t.C.Empty() { 2035 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 2036 } 2037 t.Align = 1 // TODO: should probably base this on field alignment. 2038 typedef[name.Name] = t 2039 case "struct": 2040 g, csyntax, align := c.Struct(dt, pos) 2041 if t.C.Empty() { 2042 t.C.Set(csyntax) 2043 } 2044 t.Align = align 2045 tt := *t 2046 if tag != "" { 2047 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 2048 } 2049 tt.Go = g 2050 typedef[name.Name] = &tt 2051 } 2052 2053 case *dwarf.TypedefType: 2054 // Record typedef for printing. 2055 if dt.Name == "_GoString_" { 2056 // Special C name for Go string type. 2057 // Knows string layout used by compilers: pointer plus length, 2058 // which rounds up to 2 pointers after alignment. 2059 t.Go = c.string 2060 t.Size = c.ptrSize * 2 2061 t.Align = c.ptrSize 2062 break 2063 } 2064 if dt.Name == "_GoBytes_" { 2065 // Special C name for Go []byte type. 2066 // Knows slice layout used by compilers: pointer, length, cap. 2067 t.Go = c.Ident("[]byte") 2068 t.Size = c.ptrSize + 4 + 4 2069 t.Align = c.ptrSize 2070 break 2071 } 2072 name := c.Ident("_Ctype_" + dt.Name) 2073 goIdent[name.Name] = name 2074 sub := c.Type(dt.Type, pos) 2075 t.Go = name 2076 if unionWithPointer[sub.Go] { 2077 unionWithPointer[t.Go] = true 2078 } 2079 t.Size = sub.Size 2080 t.Align = sub.Align 2081 oldType := typedef[name.Name] 2082 if oldType == nil { 2083 tt := *t 2084 tt.Go = sub.Go 2085 typedef[name.Name] = &tt 2086 } 2087 2088 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 2089 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 2090 // with the base type. 2091 // In -godefs mode, do this for all typedefs. 2092 if isStructUnionClass(sub.Go) || *godefs { 2093 t.Go = sub.Go 2094 2095 if isStructUnionClass(sub.Go) { 2096 // Use the typedef name for C code. 2097 typedef[sub.Go.(*ast.Ident).Name].C = t.C 2098 } 2099 2100 // If we've seen this typedef before, and it 2101 // was an anonymous struct/union/class before 2102 // too, use the old definition. 2103 // TODO: it would be safer to only do this if 2104 // we verify that the types are the same. 2105 if oldType != nil && isStructUnionClass(oldType.Go) { 2106 t.Go = oldType.Go 2107 } 2108 } 2109 2110 case *dwarf.UcharType: 2111 if t.Size != 1 { 2112 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 2113 } 2114 t.Go = c.uint8 2115 t.Align = 1 2116 2117 case *dwarf.UintType: 2118 if dt.BitSize > 0 { 2119 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 2120 } 2121 switch t.Size { 2122 default: 2123 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 2124 case 1: 2125 t.Go = c.uint8 2126 case 2: 2127 t.Go = c.uint16 2128 case 4: 2129 t.Go = c.uint32 2130 case 8: 2131 t.Go = c.uint64 2132 case 16: 2133 t.Go = &ast.ArrayType{ 2134 Len: c.intExpr(t.Size), 2135 Elt: c.uint8, 2136 } 2137 } 2138 if t.Align = t.Size; t.Align >= c.ptrSize { 2139 t.Align = c.ptrSize 2140 } 2141 2142 case *dwarf.VoidType: 2143 t.Go = c.goVoid 2144 t.C.Set("void") 2145 t.Align = 1 2146 } 2147 2148 switch dtype.(type) { 2149 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 2150 s := dtype.Common().Name 2151 if s != "" { 2152 if ss, ok := dwarfToName[s]; ok { 2153 s = ss 2154 } 2155 s = strings.Join(strings.Split(s, " "), "") // strip spaces 2156 name := c.Ident("_Ctype_" + s) 2157 tt := *t 2158 typedef[name.Name] = &tt 2159 if !*godefs { 2160 t.Go = name 2161 } 2162 } 2163 } 2164 2165 if t.Size < 0 { 2166 // Unsized types are [0]byte, unless they're typedefs of other types 2167 // or structs with tags. 2168 // if so, use the name we've already defined. 2169 t.Size = 0 2170 switch dt := dtype.(type) { 2171 case *dwarf.TypedefType: 2172 // ok 2173 case *dwarf.StructType: 2174 if dt.StructName != "" { 2175 break 2176 } 2177 t.Go = c.Opaque(0) 2178 default: 2179 t.Go = c.Opaque(0) 2180 } 2181 if t.C.Empty() { 2182 t.C.Set("void") 2183 } 2184 } 2185 2186 if t.C.Empty() { 2187 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 2188 } 2189 2190 return t 2191 } 2192 2193 // isStructUnionClass reports whether the type described by the Go syntax x 2194 // is a struct, union, or class with a tag. 2195 func isStructUnionClass(x ast.Expr) bool { 2196 id, ok := x.(*ast.Ident) 2197 if !ok { 2198 return false 2199 } 2200 name := id.Name 2201 return strings.HasPrefix(name, "_Ctype_struct_") || 2202 strings.HasPrefix(name, "_Ctype_union_") || 2203 strings.HasPrefix(name, "_Ctype_class_") 2204 } 2205 2206 // FuncArg returns a Go type with the same memory layout as 2207 // dtype when used as the type of a C function argument. 2208 func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 2209 t := c.Type(unqual(dtype), pos) 2210 switch dt := dtype.(type) { 2211 case *dwarf.ArrayType: 2212 // Arrays are passed implicitly as pointers in C. 2213 // In Go, we must be explicit. 2214 tr := &TypeRepr{} 2215 tr.Set("%s*", t.C) 2216 return &Type{ 2217 Size: c.ptrSize, 2218 Align: c.ptrSize, 2219 Go: &ast.StarExpr{X: t.Go}, 2220 C: tr, 2221 } 2222 case *dwarf.TypedefType: 2223 // C has much more relaxed rules than Go for 2224 // implicit type conversions. When the parameter 2225 // is type T defined as *X, simulate a little of the 2226 // laxness of C by making the argument *X instead of T. 2227 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 2228 // Unless the typedef happens to point to void* since 2229 // Go has special rules around using unsafe.Pointer. 2230 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 2231 break 2232 } 2233 2234 t = c.Type(ptr, pos) 2235 if t == nil { 2236 return nil 2237 } 2238 2239 // For a struct/union/class, remember the C spelling, 2240 // in case it has __attribute__((unavailable)). 2241 // See issue 2888. 2242 if isStructUnionClass(t.Go) { 2243 t.Typedef = dt.Name 2244 } 2245 } 2246 } 2247 return t 2248 } 2249 2250 // FuncType returns the Go type analogous to dtype. 2251 // There is no guarantee about matching memory layout. 2252 func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 2253 p := make([]*Type, len(dtype.ParamType)) 2254 gp := make([]*ast.Field, len(dtype.ParamType)) 2255 for i, f := range dtype.ParamType { 2256 // gcc's DWARF generator outputs a single DotDotDotType parameter for 2257 // function pointers that specify no parameters (e.g. void 2258 // (*__cgo_0)()). Treat this special case as void. This case is 2259 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 2260 // legal). 2261 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 2262 p, gp = nil, nil 2263 break 2264 } 2265 p[i] = c.FuncArg(f, pos) 2266 gp[i] = &ast.Field{Type: p[i].Go} 2267 } 2268 var r *Type 2269 var gr []*ast.Field 2270 if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok { 2271 gr = []*ast.Field{{Type: c.goVoid}} 2272 } else if dtype.ReturnType != nil { 2273 r = c.Type(unqual(dtype.ReturnType), pos) 2274 gr = []*ast.Field{{Type: r.Go}} 2275 } 2276 return &FuncType{ 2277 Params: p, 2278 Result: r, 2279 Go: &ast.FuncType{ 2280 Params: &ast.FieldList{List: gp}, 2281 Results: &ast.FieldList{List: gr}, 2282 }, 2283 } 2284 } 2285 2286 // Identifier 2287 func (c *typeConv) Ident(s string) *ast.Ident { 2288 return ast.NewIdent(s) 2289 } 2290 2291 // Opaque type of n bytes. 2292 func (c *typeConv) Opaque(n int64) ast.Expr { 2293 return &ast.ArrayType{ 2294 Len: c.intExpr(n), 2295 Elt: c.byte, 2296 } 2297 } 2298 2299 // Expr for integer n. 2300 func (c *typeConv) intExpr(n int64) ast.Expr { 2301 return &ast.BasicLit{ 2302 Kind: token.INT, 2303 Value: strconv.FormatInt(n, 10), 2304 } 2305 } 2306 2307 // Add padding of given size to fld. 2308 func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) { 2309 n := len(fld) 2310 fld = fld[0 : n+1] 2311 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 2312 sizes = sizes[0 : n+1] 2313 sizes[n] = size 2314 return fld, sizes 2315 } 2316 2317 // Struct conversion: return Go and (gc) C syntax for type. 2318 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 2319 // Minimum alignment for a struct is 1 byte. 2320 align = 1 2321 2322 var buf bytes.Buffer 2323 buf.WriteString("struct {") 2324 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 2325 sizes := make([]int64, 0, 2*len(dt.Field)+1) 2326 off := int64(0) 2327 2328 // Rename struct fields that happen to be named Go keywords into 2329 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 2330 // be mangled. Any existing identifier that already has the same name on 2331 // the C-side will cause the Go-mangled version to be prefixed with _. 2332 // (e.g. in a struct with fields '_type' and 'type', the latter would be 2333 // rendered as '__type' in Go). 2334 ident := make(map[string]string) 2335 used := make(map[string]bool) 2336 for _, f := range dt.Field { 2337 ident[f.Name] = f.Name 2338 used[f.Name] = true 2339 } 2340 2341 if !*godefs { 2342 for cid, goid := range ident { 2343 if token.Lookup(goid).IsKeyword() { 2344 // Avoid keyword 2345 goid = "_" + goid 2346 2347 // Also avoid existing fields 2348 for _, exist := used[goid]; exist; _, exist = used[goid] { 2349 goid = "_" + goid 2350 } 2351 2352 used[goid] = true 2353 ident[cid] = goid 2354 } 2355 } 2356 } 2357 2358 anon := 0 2359 for _, f := range dt.Field { 2360 if f.ByteOffset > off { 2361 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off) 2362 off = f.ByteOffset 2363 } 2364 2365 name := f.Name 2366 ft := f.Type 2367 2368 // In godefs mode, if this field is a C11 2369 // anonymous union then treat the first field in the 2370 // union as the field in the struct. This handles 2371 // cases like the glibc <sys/resource.h> file; see 2372 // issue 6677. 2373 if *godefs { 2374 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] { 2375 name = st.Field[0].Name 2376 ident[name] = name 2377 ft = st.Field[0].Type 2378 } 2379 } 2380 2381 // TODO: Handle fields that are anonymous structs by 2382 // promoting the fields of the inner struct. 2383 2384 t := c.Type(ft, pos) 2385 tgo := t.Go 2386 size := t.Size 2387 talign := t.Align 2388 if f.BitSize > 0 { 2389 if f.BitSize%8 != 0 { 2390 continue 2391 } 2392 size = f.BitSize / 8 2393 name := tgo.(*ast.Ident).String() 2394 if strings.HasPrefix(name, "int") { 2395 name = "int" 2396 } else { 2397 name = "uint" 2398 } 2399 tgo = ast.NewIdent(name + fmt.Sprint(f.BitSize)) 2400 talign = size 2401 } 2402 2403 if talign > 0 && f.ByteOffset%talign != 0 { 2404 // Drop misaligned fields, the same way we drop integer bit fields. 2405 // The goal is to make available what can be made available. 2406 // Otherwise one bad and unneeded field in an otherwise okay struct 2407 // makes the whole program not compile. Much of the time these 2408 // structs are in system headers that cannot be corrected. 2409 continue 2410 } 2411 n := len(fld) 2412 fld = fld[0 : n+1] 2413 if name == "" { 2414 name = fmt.Sprintf("anon%d", anon) 2415 anon++ 2416 ident[name] = name 2417 } 2418 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 2419 sizes = sizes[0 : n+1] 2420 sizes[n] = size 2421 off += size 2422 buf.WriteString(t.C.String()) 2423 buf.WriteString(" ") 2424 buf.WriteString(name) 2425 buf.WriteString("; ") 2426 if talign > align { 2427 align = talign 2428 } 2429 } 2430 if off < dt.ByteSize { 2431 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off) 2432 off = dt.ByteSize 2433 } 2434 2435 // If the last field in a non-zero-sized struct is zero-sized 2436 // the compiler is going to pad it by one (see issue 9401). 2437 // We can't permit that, because then the size of the Go 2438 // struct will not be the same as the size of the C struct. 2439 // Our only option in such a case is to remove the field, 2440 // which means that it cannot be referenced from Go. 2441 for off > 0 && sizes[len(sizes)-1] == 0 { 2442 n := len(sizes) 2443 fld = fld[0 : n-1] 2444 sizes = sizes[0 : n-1] 2445 } 2446 2447 if off != dt.ByteSize { 2448 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 2449 } 2450 buf.WriteString("}") 2451 csyntax = buf.String() 2452 2453 if *godefs { 2454 godefsFields(fld) 2455 } 2456 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 2457 return 2458 } 2459 2460 // dwarfHasPointer returns whether the DWARF type dt contains a pointer. 2461 func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool { 2462 switch dt := dt.(type) { 2463 default: 2464 fatalf("%s: unexpected type: %s", lineno(pos), dt) 2465 return false 2466 2467 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType, 2468 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType, 2469 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType: 2470 2471 return false 2472 2473 case *dwarf.ArrayType: 2474 return c.dwarfHasPointer(dt.Type, pos) 2475 2476 case *dwarf.PtrType: 2477 return true 2478 2479 case *dwarf.QualType: 2480 return c.dwarfHasPointer(dt.Type, pos) 2481 2482 case *dwarf.StructType: 2483 for _, f := range dt.Field { 2484 if c.dwarfHasPointer(f.Type, pos) { 2485 return true 2486 } 2487 } 2488 return false 2489 2490 case *dwarf.TypedefType: 2491 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" { 2492 return true 2493 } 2494 return c.dwarfHasPointer(dt.Type, pos) 2495 } 2496 } 2497 2498 func upper(s string) string { 2499 if s == "" { 2500 return "" 2501 } 2502 r, size := utf8.DecodeRuneInString(s) 2503 if r == '_' { 2504 return "X" + s 2505 } 2506 return string(unicode.ToUpper(r)) + s[size:] 2507 } 2508 2509 // godefsFields rewrites field names for use in Go or C definitions. 2510 // It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 2511 // converts names to upper case, and rewrites _ into Pad_godefs_n, 2512 // so that all fields are exported. 2513 func godefsFields(fld []*ast.Field) { 2514 prefix := fieldPrefix(fld) 2515 npad := 0 2516 for _, f := range fld { 2517 for _, n := range f.Names { 2518 if n.Name != prefix { 2519 n.Name = strings.TrimPrefix(n.Name, prefix) 2520 } 2521 if n.Name == "_" { 2522 // Use exported name instead. 2523 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 2524 npad++ 2525 } 2526 n.Name = upper(n.Name) 2527 } 2528 } 2529 } 2530 2531 // fieldPrefix returns the prefix that should be removed from all the 2532 // field names when generating the C or Go code. For generated 2533 // C, we leave the names as is (tv_sec, tv_usec), since that's what 2534 // people are used to seeing in C. For generated Go code, such as 2535 // package syscall's data structures, we drop a common prefix 2536 // (so sec, usec, which will get turned into Sec, Usec for exporting). 2537 func fieldPrefix(fld []*ast.Field) string { 2538 prefix := "" 2539 for _, f := range fld { 2540 for _, n := range f.Names { 2541 // Ignore field names that don't have the prefix we're 2542 // looking for. It is common in C headers to have fields 2543 // named, say, _pad in an otherwise prefixed header. 2544 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 2545 // still want to remove the tv_ prefix. 2546 // The check for "orig_" here handles orig_eax in the 2547 // x86 ptrace register sets, which otherwise have all fields 2548 // with reg_ prefixes. 2549 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 2550 continue 2551 } 2552 i := strings.Index(n.Name, "_") 2553 if i < 0 { 2554 continue 2555 } 2556 if prefix == "" { 2557 prefix = n.Name[:i+1] 2558 } else if prefix != n.Name[:i+1] { 2559 return "" 2560 } 2561 } 2562 } 2563 return prefix 2564 }