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