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