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