1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Annotate Ref in Prog with C types by parsing gcc debug output. 6// Conversion of debug output to Go types. 7 8package main 9 10import ( 11 "bytes" 12 "debug/dwarf" 13 "debug/elf" 14 "debug/macho" 15 "debug/pe" 16 "encoding/binary" 17 "errors" 18 "flag" 19 "fmt" 20 "go/ast" 21 "go/parser" 22 "go/token" 23 "internal/xcoff" 24 "math" 25 "os" 26 "os/exec" 27 "strconv" 28 "strings" 29 "unicode" 30 "unicode/utf8" 31 32 "cmd/internal/quoted" 33) 34 35var debugDefine = flag.Bool("debug-define", false, "print relevant #defines") 36var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations") 37 38var nameToC = map[string]string{ 39 "schar": "signed char", 40 "uchar": "unsigned char", 41 "ushort": "unsigned short", 42 "uint": "unsigned int", 43 "ulong": "unsigned long", 44 "longlong": "long long", 45 "ulonglong": "unsigned long long", 46 "complexfloat": "float _Complex", 47 "complexdouble": "double _Complex", 48} 49 50// cname returns the C name to use for C.s. 51// The expansions are listed in nameToC and also 52// struct_foo becomes "struct foo", and similarly for 53// union and enum. 54func cname(s string) string { 55 if t, ok := nameToC[s]; ok { 56 return t 57 } 58 59 if strings.HasPrefix(s, "struct_") { 60 return "struct " + s[len("struct_"):] 61 } 62 if strings.HasPrefix(s, "union_") { 63 return "union " + s[len("union_"):] 64 } 65 if strings.HasPrefix(s, "enum_") { 66 return "enum " + s[len("enum_"):] 67 } 68 if strings.HasPrefix(s, "sizeof_") { 69 return "sizeof(" + cname(s[len("sizeof_"):]) + ")" 70 } 71 return s 72} 73 74// DiscardCgoDirectives processes the import C preamble, and discards 75// all #cgo CFLAGS and LDFLAGS directives, so they don't make their 76// way into _cgo_export.h. 77func (f *File) DiscardCgoDirectives() { 78 linesIn := strings.Split(f.Preamble, "\n") 79 linesOut := make([]string, 0, len(linesIn)) 80 for _, line := range linesIn { 81 l := strings.TrimSpace(line) 82 if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) { 83 linesOut = append(linesOut, line) 84 } else { 85 linesOut = append(linesOut, "") 86 } 87 } 88 f.Preamble = strings.Join(linesOut, "\n") 89} 90 91// addToFlag appends args to flag. All flags are later written out onto the 92// _cgo_flags file for the build system to use. 93func (p *Package) addToFlag(flag string, args []string) { 94 p.CgoFlags[flag] = append(p.CgoFlags[flag], args...) 95 if flag == "CFLAGS" { 96 // We'll also need these when preprocessing for dwarf information. 97 // However, discard any -g options: we need to be able 98 // to parse the debug info, so stick to what we expect. 99 for _, arg := range args { 100 if !strings.HasPrefix(arg, "-g") { 101 p.GccOptions = append(p.GccOptions, arg) 102 } 103 } 104 } 105} 106 107// splitQuoted splits the string s around each instance of one or more consecutive 108// white space characters while taking into account quotes and escaping, and 109// returns an array of substrings of s or an empty list if s contains only white space. 110// Single quotes and double quotes are recognized to prevent splitting within the 111// quoted region, and are removed from the resulting substrings. If a quote in s 112// isn't closed err will be set and r will have the unclosed argument as the 113// last element. The backslash is used for escaping. 114// 115// For example, the following string: 116// 117// `a b:"c d" 'e''f' "g\""` 118// 119// Would be parsed as: 120// 121// []string{"a", "b:c d", "ef", `g"`} 122// 123func splitQuoted(s string) (r []string, err error) { 124 var args []string 125 arg := make([]rune, len(s)) 126 escaped := false 127 quoted := false 128 quote := '\x00' 129 i := 0 130 for _, r := range s { 131 switch { 132 case escaped: 133 escaped = false 134 case r == '\\': 135 escaped = true 136 continue 137 case quote != 0: 138 if r == quote { 139 quote = 0 140 continue 141 } 142 case r == '"' || r == '\'': 143 quoted = true 144 quote = r 145 continue 146 case unicode.IsSpace(r): 147 if quoted || i > 0 { 148 quoted = false 149 args = append(args, string(arg[:i])) 150 i = 0 151 } 152 continue 153 } 154 arg[i] = r 155 i++ 156 } 157 if quoted || i > 0 { 158 args = append(args, string(arg[:i])) 159 } 160 if quote != 0 { 161 err = errors.New("unclosed quote") 162 } else if escaped { 163 err = errors.New("unfinished escaping") 164 } 165 return args, err 166} 167 168// Translate rewrites f.AST, the original Go input, to remove 169// references to the imported package C, replacing them with 170// references to the equivalent Go types, functions, and variables. 171func (p *Package) Translate(f *File) { 172 for _, cref := range f.Ref { 173 // Convert C.ulong to C.unsigned long, etc. 174 cref.Name.C = cname(cref.Name.Go) 175 } 176 177 var conv typeConv 178 conv.Init(p.PtrSize, p.IntSize) 179 180 p.loadDefines(f) 181 p.typedefs = map[string]bool{} 182 p.typedefList = nil 183 numTypedefs := -1 184 for len(p.typedefs) > numTypedefs { 185 numTypedefs = len(p.typedefs) 186 // Also ask about any typedefs we've seen so far. 187 for _, info := range p.typedefList { 188 if f.Name[info.typedef] != nil { 189 continue 190 } 191 n := &Name{ 192 Go: info.typedef, 193 C: info.typedef, 194 } 195 f.Name[info.typedef] = n 196 f.NamePos[n] = info.pos 197 } 198 needType := p.guessKinds(f) 199 if len(needType) > 0 { 200 p.loadDWARF(f, &conv, needType) 201 } 202 203 // In godefs mode we're OK with the typedefs, which 204 // will presumably also be defined in the file, we 205 // don't want to resolve them to their base types. 206 if *godefs { 207 break 208 } 209 } 210 p.prepareNames(f) 211 if p.rewriteCalls(f) { 212 // Add `import _cgo_unsafe "unsafe"` after the package statement. 213 f.Edit.Insert(f.offset(f.AST.Name.End()), "; import _cgo_unsafe \"unsafe\"") 214 } 215 p.rewriteRef(f) 216} 217 218// loadDefines coerces gcc into spitting out the #defines in use 219// in the file f and saves relevant renamings in f.Name[name].Define. 220func (p *Package) loadDefines(f *File) { 221 var b bytes.Buffer 222 b.WriteString(builtinProlog) 223 b.WriteString(f.Preamble) 224 stdout := p.gccDefines(b.Bytes()) 225 226 for _, line := range strings.Split(stdout, "\n") { 227 if len(line) < 9 || line[0:7] != "#define" { 228 continue 229 } 230 231 line = strings.TrimSpace(line[8:]) 232 233 var key, val string 234 spaceIndex := strings.Index(line, " ") 235 tabIndex := strings.Index(line, "\t") 236 237 if spaceIndex == -1 && tabIndex == -1 { 238 continue 239 } else if tabIndex == -1 || (spaceIndex != -1 && spaceIndex < tabIndex) { 240 key = line[0:spaceIndex] 241 val = strings.TrimSpace(line[spaceIndex:]) 242 } else { 243 key = line[0:tabIndex] 244 val = strings.TrimSpace(line[tabIndex:]) 245 } 246 247 if key == "__clang__" { 248 p.GccIsClang = true 249 } 250 251 if n := f.Name[key]; n != nil { 252 if *debugDefine { 253 fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val) 254 } 255 n.Define = val 256 } 257 } 258} 259 260// guessKinds tricks gcc into revealing the kind of each 261// name xxx for the references C.xxx in the Go input. 262// The kind is either a constant, type, or variable. 263func (p *Package) guessKinds(f *File) []*Name { 264 // Determine kinds for names we already know about, 265 // like #defines or 'struct foo', before bothering with gcc. 266 var names, needType []*Name 267 optional := map[*Name]bool{} 268 for _, key := range nameKeys(f.Name) { 269 n := f.Name[key] 270 // If we've already found this name as a #define 271 // and we can translate it as a constant value, do so. 272 if n.Define != "" { 273 if i, err := strconv.ParseInt(n.Define, 0, 64); err == nil { 274 n.Kind = "iconst" 275 // Turn decimal into hex, just for consistency 276 // with enum-derived constants. Otherwise 277 // in the cgo -godefs output half the constants 278 // are in hex and half are in whatever the #define used. 279 n.Const = fmt.Sprintf("%#x", i) 280 } else if n.Define[0] == '\'' { 281 if _, err := parser.ParseExpr(n.Define); err == nil { 282 n.Kind = "iconst" 283 n.Const = n.Define 284 } 285 } else if n.Define[0] == '"' { 286 if _, err := parser.ParseExpr(n.Define); err == nil { 287 n.Kind = "sconst" 288 n.Const = n.Define 289 } 290 } 291 292 if n.IsConst() { 293 continue 294 } 295 } 296 297 // If this is a struct, union, or enum type name, no need to guess the kind. 298 if strings.HasPrefix(n.C, "struct ") || strings.HasPrefix(n.C, "union ") || strings.HasPrefix(n.C, "enum ") { 299 n.Kind = "type" 300 needType = append(needType, n) 301 continue 302 } 303 304 if (goos == "darwin" || goos == "ios") && strings.HasSuffix(n.C, "Ref") { 305 // For FooRef, find out if FooGetTypeID exists. 306 s := n.C[:len(n.C)-3] + "GetTypeID" 307 n := &Name{Go: s, C: s} 308 names = append(names, n) 309 optional[n] = true 310 } 311 312 // Otherwise, we'll need to find out from gcc. 313 names = append(names, n) 314 } 315 316 // Bypass gcc if there's nothing left to find out. 317 if len(names) == 0 { 318 return needType 319 } 320 321 // Coerce gcc into telling us whether each name is a type, a value, or undeclared. 322 // For names, find out whether they are integer constants. 323 // We used to look at specific warning or error messages here, but that tied the 324 // behavior too closely to specific versions of the compilers. 325 // Instead, arrange that we can infer what we need from only the presence or absence 326 // of an error on a specific line. 327 // 328 // For each name, we generate these lines, where xxx is the index in toSniff plus one. 329 // 330 // #line xxx "not-declared" 331 // void __cgo_f_xxx_1(void) { __typeof__(name) *__cgo_undefined__1; } 332 // #line xxx "not-type" 333 // void __cgo_f_xxx_2(void) { name *__cgo_undefined__2; } 334 // #line xxx "not-int-const" 335 // void __cgo_f_xxx_3(void) { enum { __cgo_undefined__3 = (name)*1 }; } 336 // #line xxx "not-num-const" 337 // void __cgo_f_xxx_4(void) { static const double __cgo_undefined__4 = (name); } 338 // #line xxx "not-str-lit" 339 // void __cgo_f_xxx_5(void) { static const char __cgo_undefined__5[] = (name); } 340 // 341 // If we see an error at not-declared:xxx, the corresponding name is not declared. 342 // If we see an error at not-type:xxx, the corresponding name is not a type. 343 // If we see an error at not-int-const:xxx, the corresponding name is not an integer constant. 344 // If we see an error at not-num-const:xxx, the corresponding name is not a number constant. 345 // If we see an error at not-str-lit:xxx, the corresponding name is not a string literal. 346 // 347 // The specific input forms are chosen so that they are valid C syntax regardless of 348 // whether name denotes a type or an expression. 349 350 var b bytes.Buffer 351 b.WriteString(builtinProlog) 352 b.WriteString(f.Preamble) 353 354 for i, n := range names { 355 fmt.Fprintf(&b, "#line %d \"not-declared\"\n"+ 356 "void __cgo_f_%d_1(void) { __typeof__(%s) *__cgo_undefined__1; }\n"+ 357 "#line %d \"not-type\"\n"+ 358 "void __cgo_f_%d_2(void) { %s *__cgo_undefined__2; }\n"+ 359 "#line %d \"not-int-const\"\n"+ 360 "void __cgo_f_%d_3(void) { enum { __cgo_undefined__3 = (%s)*1 }; }\n"+ 361 "#line %d \"not-num-const\"\n"+ 362 "void __cgo_f_%d_4(void) { static const double __cgo_undefined__4 = (%s); }\n"+ 363 "#line %d \"not-str-lit\"\n"+ 364 "void __cgo_f_%d_5(void) { static const char __cgo_undefined__5[] = (%s); }\n", 365 i+1, i+1, n.C, 366 i+1, i+1, n.C, 367 i+1, i+1, n.C, 368 i+1, i+1, n.C, 369 i+1, i+1, n.C, 370 ) 371 } 372 fmt.Fprintf(&b, "#line 1 \"completed\"\n"+ 373 "int __cgo__1 = __cgo__2;\n") 374 375 // We need to parse the output from this gcc command, so ensure that it 376 // doesn't have any ANSI escape sequences in it. (TERM=dumb is 377 // insufficient; if the user specifies CGO_CFLAGS=-fdiagnostics-color, 378 // GCC will ignore TERM, and GCC can also be configured at compile-time 379 // to ignore TERM.) 380 stderr := p.gccErrors(b.Bytes(), "-fdiagnostics-color=never") 381 if strings.Contains(stderr, "unrecognized command line option") { 382 // We're using an old version of GCC that doesn't understand 383 // -fdiagnostics-color. Those versions can't print color anyway, 384 // so just rerun without that option. 385 stderr = p.gccErrors(b.Bytes()) 386 } 387 if stderr == "" { 388 fatalf("%s produced no output\non input:\n%s", gccBaseCmd[0], b.Bytes()) 389 } 390 391 completed := false 392 sniff := make([]int, len(names)) 393 const ( 394 notType = 1 << iota 395 notIntConst 396 notNumConst 397 notStrLiteral 398 notDeclared 399 ) 400 sawUnmatchedErrors := false 401 for _, line := range strings.Split(stderr, "\n") { 402 // Ignore warnings and random comments, with one 403 // exception: newer GCC versions will sometimes emit 404 // an error on a macro #define with a note referring 405 // to where the expansion occurs. We care about where 406 // the expansion occurs, so in that case treat the note 407 // as an error. 408 isError := strings.Contains(line, ": error:") 409 isErrorNote := strings.Contains(line, ": note:") && sawUnmatchedErrors 410 if !isError && !isErrorNote { 411 continue 412 } 413 414 c1 := strings.Index(line, ":") 415 if c1 < 0 { 416 continue 417 } 418 c2 := strings.Index(line[c1+1:], ":") 419 if c2 < 0 { 420 continue 421 } 422 c2 += c1 + 1 423 424 filename := line[:c1] 425 i, _ := strconv.Atoi(line[c1+1 : c2]) 426 i-- 427 if i < 0 || i >= len(names) { 428 if isError { 429 sawUnmatchedErrors = true 430 } 431 continue 432 } 433 434 switch filename { 435 case "completed": 436 // Strictly speaking, there is no guarantee that seeing the error at completed:1 437 // (at the end of the file) means we've seen all the errors from earlier in the file, 438 // but usually it does. Certainly if we don't see the completed:1 error, we did 439 // not get all the errors we expected. 440 completed = true 441 442 case "not-declared": 443 sniff[i] |= notDeclared 444 case "not-type": 445 sniff[i] |= notType 446 case "not-int-const": 447 sniff[i] |= notIntConst 448 case "not-num-const": 449 sniff[i] |= notNumConst 450 case "not-str-lit": 451 sniff[i] |= notStrLiteral 452 default: 453 if isError { 454 sawUnmatchedErrors = true 455 } 456 continue 457 } 458 459 sawUnmatchedErrors = false 460 } 461 462 if !completed { 463 fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", gccBaseCmd[0], b.Bytes(), stderr) 464 } 465 466 for i, n := range names { 467 switch sniff[i] { 468 default: 469 if sniff[i]¬Declared != 0 && optional[n] { 470 // Ignore optional undeclared identifiers. 471 // Don't report an error, and skip adding n to the needType array. 472 continue 473 } 474 error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go)) 475 case notStrLiteral | notType: 476 n.Kind = "iconst" 477 case notIntConst | notStrLiteral | notType: 478 n.Kind = "fconst" 479 case notIntConst | notNumConst | notType: 480 n.Kind = "sconst" 481 case notIntConst | notNumConst | notStrLiteral: 482 n.Kind = "type" 483 case notIntConst | notNumConst | notStrLiteral | notType: 484 n.Kind = "not-type" 485 } 486 needType = append(needType, n) 487 } 488 if nerrors > 0 { 489 // Check if compiling the preamble by itself causes any errors, 490 // because the messages we've printed out so far aren't helpful 491 // to users debugging preamble mistakes. See issue 8442. 492 preambleErrors := p.gccErrors([]byte(f.Preamble)) 493 if len(preambleErrors) > 0 { 494 error_(token.NoPos, "\n%s errors for preamble:\n%s", gccBaseCmd[0], preambleErrors) 495 } 496 497 fatalf("unresolved names") 498 } 499 500 return needType 501} 502 503// loadDWARF parses the DWARF debug information generated 504// by gcc to learn the details of the constants, variables, and types 505// being referred to as C.xxx. 506func (p *Package) loadDWARF(f *File, conv *typeConv, names []*Name) { 507 // Extract the types from the DWARF section of an object 508 // from a well-formed C program. Gcc only generates DWARF info 509 // for symbols in the object file, so it is not enough to print the 510 // preamble and hope the symbols we care about will be there. 511 // Instead, emit 512 // __typeof__(names[i]) *__cgo__i; 513 // for each entry in names and then dereference the type we 514 // learn for __cgo__i. 515 var b bytes.Buffer 516 b.WriteString(builtinProlog) 517 b.WriteString(f.Preamble) 518 b.WriteString("#line 1 \"cgo-dwarf-inference\"\n") 519 for i, n := range names { 520 fmt.Fprintf(&b, "__typeof__(%s) *__cgo__%d;\n", n.C, i) 521 if n.Kind == "iconst" { 522 fmt.Fprintf(&b, "enum { __cgo_enum__%d = %s };\n", i, n.C) 523 } 524 } 525 526 // We create a data block initialized with the values, 527 // so we can read them out of the object file. 528 fmt.Fprintf(&b, "long long __cgodebug_ints[] = {\n") 529 for _, n := range names { 530 if n.Kind == "iconst" { 531 fmt.Fprintf(&b, "\t%s,\n", n.C) 532 } else { 533 fmt.Fprintf(&b, "\t0,\n") 534 } 535 } 536 // for the last entry, we cannot use 0, otherwise 537 // in case all __cgodebug_data is zero initialized, 538 // LLVM-based gcc will place the it in the __DATA.__common 539 // zero-filled section (our debug/macho doesn't support 540 // this) 541 fmt.Fprintf(&b, "\t1\n") 542 fmt.Fprintf(&b, "};\n") 543 544 // do the same work for floats. 545 fmt.Fprintf(&b, "double __cgodebug_floats[] = {\n") 546 for _, n := range names { 547 if n.Kind == "fconst" { 548 fmt.Fprintf(&b, "\t%s,\n", n.C) 549 } else { 550 fmt.Fprintf(&b, "\t0,\n") 551 } 552 } 553 fmt.Fprintf(&b, "\t1\n") 554 fmt.Fprintf(&b, "};\n") 555 556 // do the same work for strings. 557 for i, n := range names { 558 if n.Kind == "sconst" { 559 fmt.Fprintf(&b, "const char __cgodebug_str__%d[] = %s;\n", i, n.C) 560 fmt.Fprintf(&b, "const unsigned long long __cgodebug_strlen__%d = sizeof(%s)-1;\n", i, n.C) 561 } 562 } 563 564 d, ints, floats, strs := p.gccDebug(b.Bytes(), len(names)) 565 566 // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i. 567 types := make([]dwarf.Type, len(names)) 568 r := d.Reader() 569 for { 570 e, err := r.Next() 571 if err != nil { 572 fatalf("reading DWARF entry: %s", err) 573 } 574 if e == nil { 575 break 576 } 577 switch e.Tag { 578 case dwarf.TagVariable: 579 name, _ := e.Val(dwarf.AttrName).(string) 580 typOff, _ := e.Val(dwarf.AttrType).(dwarf.Offset) 581 if name == "" || typOff == 0 { 582 if e.Val(dwarf.AttrSpecification) != nil { 583 // Since we are reading all the DWARF, 584 // assume we will see the variable elsewhere. 585 break 586 } 587 fatalf("malformed DWARF TagVariable entry") 588 } 589 if !strings.HasPrefix(name, "__cgo__") { 590 break 591 } 592 typ, err := d.Type(typOff) 593 if err != nil { 594 fatalf("loading DWARF type: %s", err) 595 } 596 t, ok := typ.(*dwarf.PtrType) 597 if !ok || t == nil { 598 fatalf("internal error: %s has non-pointer type", name) 599 } 600 i, err := strconv.Atoi(name[7:]) 601 if err != nil { 602 fatalf("malformed __cgo__ name: %s", name) 603 } 604 types[i] = t.Type 605 p.recordTypedefs(t.Type, f.NamePos[names[i]]) 606 } 607 if e.Tag != dwarf.TagCompileUnit { 608 r.SkipChildren() 609 } 610 } 611 612 // Record types and typedef information. 613 for i, n := range names { 614 if strings.HasSuffix(n.Go, "GetTypeID") && types[i].String() == "func() CFTypeID" { 615 conv.getTypeIDs[n.Go[:len(n.Go)-9]] = true 616 } 617 } 618 for i, n := range names { 619 if types[i] == nil { 620 continue 621 } 622 pos := f.NamePos[n] 623 f, fok := types[i].(*dwarf.FuncType) 624 if n.Kind != "type" && fok { 625 n.Kind = "func" 626 n.FuncType = conv.FuncType(f, pos) 627 } else { 628 n.Type = conv.Type(types[i], pos) 629 switch n.Kind { 630 case "iconst": 631 if i < len(ints) { 632 if _, ok := types[i].(*dwarf.UintType); ok { 633 n.Const = fmt.Sprintf("%#x", uint64(ints[i])) 634 } else { 635 n.Const = fmt.Sprintf("%#x", ints[i]) 636 } 637 } 638 case "fconst": 639 if i >= len(floats) { 640 break 641 } 642 switch base(types[i]).(type) { 643 case *dwarf.IntType, *dwarf.UintType: 644 // This has an integer type so it's 645 // not really a floating point 646 // constant. This can happen when the 647 // C compiler complains about using 648 // the value as an integer constant, 649 // but not as a general constant. 650 // Treat this as a variable of the 651 // appropriate type, not a constant, 652 // to get C-style type handling, 653 // avoiding the problem that C permits 654 // uint64(-1) but Go does not. 655 // See issue 26066. 656 n.Kind = "var" 657 default: 658 n.Const = fmt.Sprintf("%f", floats[i]) 659 } 660 case "sconst": 661 if i < len(strs) { 662 n.Const = fmt.Sprintf("%q", strs[i]) 663 } 664 } 665 } 666 conv.FinishType(pos) 667 } 668} 669 670// recordTypedefs remembers in p.typedefs all the typedefs used in dtypes and its children. 671func (p *Package) recordTypedefs(dtype dwarf.Type, pos token.Pos) { 672 p.recordTypedefs1(dtype, pos, map[dwarf.Type]bool{}) 673} 674 675func (p *Package) recordTypedefs1(dtype dwarf.Type, pos token.Pos, visited map[dwarf.Type]bool) { 676 if dtype == nil { 677 return 678 } 679 if visited[dtype] { 680 return 681 } 682 visited[dtype] = true 683 switch dt := dtype.(type) { 684 case *dwarf.TypedefType: 685 if strings.HasPrefix(dt.Name, "__builtin") { 686 // Don't look inside builtin types. There be dragons. 687 return 688 } 689 if !p.typedefs[dt.Name] { 690 p.typedefs[dt.Name] = true 691 p.typedefList = append(p.typedefList, typedefInfo{dt.Name, pos}) 692 p.recordTypedefs1(dt.Type, pos, visited) 693 } 694 case *dwarf.PtrType: 695 p.recordTypedefs1(dt.Type, pos, visited) 696 case *dwarf.ArrayType: 697 p.recordTypedefs1(dt.Type, pos, visited) 698 case *dwarf.QualType: 699 p.recordTypedefs1(dt.Type, pos, visited) 700 case *dwarf.FuncType: 701 p.recordTypedefs1(dt.ReturnType, pos, visited) 702 for _, a := range dt.ParamType { 703 p.recordTypedefs1(a, pos, visited) 704 } 705 case *dwarf.StructType: 706 for _, f := range dt.Field { 707 p.recordTypedefs1(f.Type, pos, visited) 708 } 709 } 710} 711 712// prepareNames finalizes the Kind field of not-type names and sets 713// the mangled name of all names. 714func (p *Package) prepareNames(f *File) { 715 for _, n := range f.Name { 716 if n.Kind == "not-type" { 717 if n.Define == "" { 718 n.Kind = "var" 719 } else { 720 n.Kind = "macro" 721 n.FuncType = &FuncType{ 722 Result: n.Type, 723 Go: &ast.FuncType{ 724 Results: &ast.FieldList{List: []*ast.Field{{Type: n.Type.Go}}}, 725 }, 726 } 727 } 728 } 729 p.mangleName(n) 730 if n.Kind == "type" && typedef[n.Mangle] == nil { 731 typedef[n.Mangle] = n.Type 732 } 733 } 734} 735 736// mangleName does name mangling to translate names 737// from the original Go source files to the names 738// used in the final Go files generated by cgo. 739func (p *Package) mangleName(n *Name) { 740 // When using gccgo variables have to be 741 // exported so that they become global symbols 742 // that the C code can refer to. 743 prefix := "_C" 744 if *gccgo && n.IsVar() { 745 prefix = "C" 746 } 747 n.Mangle = prefix + n.Kind + "_" + n.Go 748} 749 750func (f *File) isMangledName(s string) bool { 751 prefix := "_C" 752 if strings.HasPrefix(s, prefix) { 753 t := s[len(prefix):] 754 for _, k := range nameKinds { 755 if strings.HasPrefix(t, k+"_") { 756 return true 757 } 758 } 759 } 760 return false 761} 762 763// rewriteCalls rewrites all calls that pass pointers to check that 764// they follow the rules for passing pointers between Go and C. 765// This reports whether the package needs to import unsafe as _cgo_unsafe. 766func (p *Package) rewriteCalls(f *File) bool { 767 needsUnsafe := false 768 // Walk backward so that in C.f1(C.f2()) we rewrite C.f2 first. 769 for _, call := range f.Calls { 770 if call.Done { 771 continue 772 } 773 start := f.offset(call.Call.Pos()) 774 end := f.offset(call.Call.End()) 775 str, nu := p.rewriteCall(f, call) 776 if str != "" { 777 f.Edit.Replace(start, end, str) 778 if nu { 779 needsUnsafe = true 780 } 781 } 782 } 783 return needsUnsafe 784} 785 786// rewriteCall rewrites one call to add pointer checks. 787// If any pointer checks are required, we rewrite the call into a 788// function literal that calls _cgoCheckPointer for each pointer 789// argument and then calls the original function. 790// This returns the rewritten call and whether the package needs to 791// import unsafe as _cgo_unsafe. 792// If it returns the empty string, the call did not need to be rewritten. 793func (p *Package) rewriteCall(f *File, call *Call) (string, bool) { 794 // This is a call to C.xxx; set goname to "xxx". 795 // It may have already been mangled by rewriteName. 796 var goname string 797 switch fun := call.Call.Fun.(type) { 798 case *ast.SelectorExpr: 799 goname = fun.Sel.Name 800 case *ast.Ident: 801 goname = strings.TrimPrefix(fun.Name, "_C2func_") 802 goname = strings.TrimPrefix(goname, "_Cfunc_") 803 } 804 if goname == "" || goname == "malloc" { 805 return "", false 806 } 807 name := f.Name[goname] 808 if name == nil || name.Kind != "func" { 809 // Probably a type conversion. 810 return "", false 811 } 812 813 params := name.FuncType.Params 814 args := call.Call.Args 815 816 // Avoid a crash if the number of arguments doesn't match 817 // the number of parameters. 818 // This will be caught when the generated file is compiled. 819 if len(args) != len(params) { 820 return "", false 821 } 822 823 any := false 824 for i, param := range params { 825 if p.needsPointerCheck(f, param.Go, args[i]) { 826 any = true 827 break 828 } 829 } 830 if !any { 831 return "", false 832 } 833 834 // We need to rewrite this call. 835 // 836 // Rewrite C.f(p) to 837 // func() { 838 // _cgo0 := p 839 // _cgoCheckPointer(_cgo0, nil) 840 // C.f(_cgo0) 841 // }() 842 // Using a function literal like this lets us evaluate the 843 // function arguments only once while doing pointer checks. 844 // This is particularly useful when passing additional arguments 845 // to _cgoCheckPointer, as done in checkIndex and checkAddr. 846 // 847 // When the function argument is a conversion to unsafe.Pointer, 848 // we unwrap the conversion before checking the pointer, 849 // and then wrap again when calling C.f. This lets us check 850 // the real type of the pointer in some cases. See issue #25941. 851 // 852 // When the call to C.f is deferred, we use an additional function 853 // literal to evaluate the arguments at the right time. 854 // defer func() func() { 855 // _cgo0 := p 856 // return func() { 857 // _cgoCheckPointer(_cgo0, nil) 858 // C.f(_cgo0) 859 // } 860 // }()() 861 // This works because the defer statement evaluates the first 862 // function literal in order to get the function to call. 863 864 var sb bytes.Buffer 865 sb.WriteString("func() ") 866 if call.Deferred { 867 sb.WriteString("func() ") 868 } 869 870 needsUnsafe := false 871 result := false 872 twoResults := false 873 if !call.Deferred { 874 // Check whether this call expects two results. 875 for _, ref := range f.Ref { 876 if ref.Expr != &call.Call.Fun { 877 continue 878 } 879 if ref.Context == ctxCall2 { 880 sb.WriteString("(") 881 result = true 882 twoResults = true 883 } 884 break 885 } 886 887 // Add the result type, if any. 888 if name.FuncType.Result != nil { 889 rtype := p.rewriteUnsafe(name.FuncType.Result.Go) 890 if rtype != name.FuncType.Result.Go { 891 needsUnsafe = true 892 } 893 sb.WriteString(gofmtLine(rtype)) 894 result = true 895 } 896 897 // Add the second result type, if any. 898 if twoResults { 899 if name.FuncType.Result == nil { 900 // An explicit void result looks odd but it 901 // seems to be how cgo has worked historically. 902 sb.WriteString("_Ctype_void") 903 } 904 sb.WriteString(", error)") 905 } 906 } 907 908 sb.WriteString("{ ") 909 910 // Define _cgoN for each argument value. 911 // Write _cgoCheckPointer calls to sbCheck. 912 var sbCheck bytes.Buffer 913 for i, param := range params { 914 origArg := args[i] 915 arg, nu := p.mangle(f, &args[i], true) 916 if nu { 917 needsUnsafe = true 918 } 919 920 // Use "var x T = ..." syntax to explicitly convert untyped 921 // constants to the parameter type, to avoid a type mismatch. 922 ptype := p.rewriteUnsafe(param.Go) 923 924 if !p.needsPointerCheck(f, param.Go, args[i]) || param.BadPointer { 925 if ptype != param.Go { 926 needsUnsafe = true 927 } 928 fmt.Fprintf(&sb, "var _cgo%d %s = %s; ", i, 929 gofmtLine(ptype), gofmtPos(arg, origArg.Pos())) 930 continue 931 } 932 933 // Check for &a[i]. 934 if p.checkIndex(&sb, &sbCheck, arg, i) { 935 continue 936 } 937 938 // Check for &x. 939 if p.checkAddr(&sb, &sbCheck, arg, i) { 940 continue 941 } 942 943 fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos())) 944 fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d, nil); ", i) 945 } 946 947 if call.Deferred { 948 sb.WriteString("return func() { ") 949 } 950 951 // Write out the calls to _cgoCheckPointer. 952 sb.WriteString(sbCheck.String()) 953 954 if result { 955 sb.WriteString("return ") 956 } 957 958 m, nu := p.mangle(f, &call.Call.Fun, false) 959 if nu { 960 needsUnsafe = true 961 } 962 sb.WriteString(gofmtLine(m)) 963 964 sb.WriteString("(") 965 for i := range params { 966 if i > 0 { 967 sb.WriteString(", ") 968 } 969 fmt.Fprintf(&sb, "_cgo%d", i) 970 } 971 sb.WriteString("); ") 972 if call.Deferred { 973 sb.WriteString("}") 974 } 975 sb.WriteString("}") 976 if call.Deferred { 977 sb.WriteString("()") 978 } 979 sb.WriteString("()") 980 981 return sb.String(), needsUnsafe 982} 983 984// needsPointerCheck reports whether the type t needs a pointer check. 985// This is true if t is a pointer and if the value to which it points 986// might contain a pointer. 987func (p *Package) needsPointerCheck(f *File, t ast.Expr, arg ast.Expr) bool { 988 // An untyped nil does not need a pointer check, and when 989 // _cgoCheckPointer returns the untyped nil the type assertion we 990 // are going to insert will fail. Easier to just skip nil arguments. 991 // TODO: Note that this fails if nil is shadowed. 992 if id, ok := arg.(*ast.Ident); ok && id.Name == "nil" { 993 return false 994 } 995 996 return p.hasPointer(f, t, true) 997} 998 999// hasPointer is used by needsPointerCheck. If top is true it returns 1000// whether t is or contains a pointer that might point to a pointer. 1001// If top is false it reports whether t is or contains a pointer. 1002// f may be nil. 1003func (p *Package) hasPointer(f *File, t ast.Expr, top bool) bool { 1004 switch t := t.(type) { 1005 case *ast.ArrayType: 1006 if t.Len == nil { 1007 if !top { 1008 return true 1009 } 1010 return p.hasPointer(f, t.Elt, false) 1011 } 1012 return p.hasPointer(f, t.Elt, top) 1013 case *ast.StructType: 1014 for _, field := range t.Fields.List { 1015 if p.hasPointer(f, field.Type, top) { 1016 return true 1017 } 1018 } 1019 return false 1020 case *ast.StarExpr: // Pointer type. 1021 if !top { 1022 return true 1023 } 1024 // Check whether this is a pointer to a C union (or class) 1025 // type that contains a pointer. 1026 if unionWithPointer[t.X] { 1027 return true 1028 } 1029 return p.hasPointer(f, t.X, false) 1030 case *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: 1031 return true 1032 case *ast.Ident: 1033 // TODO: Handle types defined within function. 1034 for _, d := range p.Decl { 1035 gd, ok := d.(*ast.GenDecl) 1036 if !ok || gd.Tok != token.TYPE { 1037 continue 1038 } 1039 for _, spec := range gd.Specs { 1040 ts, ok := spec.(*ast.TypeSpec) 1041 if !ok { 1042 continue 1043 } 1044 if ts.Name.Name == t.Name { 1045 return p.hasPointer(f, ts.Type, top) 1046 } 1047 } 1048 } 1049 if def := typedef[t.Name]; def != nil { 1050 return p.hasPointer(f, def.Go, top) 1051 } 1052 if t.Name == "string" { 1053 return !top 1054 } 1055 if t.Name == "error" { 1056 return true 1057 } 1058 if goTypes[t.Name] != nil { 1059 return false 1060 } 1061 // We can't figure out the type. Conservative 1062 // approach is to assume it has a pointer. 1063 return true 1064 case *ast.SelectorExpr: 1065 if l, ok := t.X.(*ast.Ident); !ok || l.Name != "C" { 1066 // Type defined in a different package. 1067 // Conservative approach is to assume it has a 1068 // pointer. 1069 return true 1070 } 1071 if f == nil { 1072 // Conservative approach: assume pointer. 1073 return true 1074 } 1075 name := f.Name[t.Sel.Name] 1076 if name != nil && name.Kind == "type" && name.Type != nil && name.Type.Go != nil { 1077 return p.hasPointer(f, name.Type.Go, top) 1078 } 1079 // We can't figure out the type. Conservative 1080 // approach is to assume it has a pointer. 1081 return true 1082 default: 1083 error_(t.Pos(), "could not understand type %s", gofmt(t)) 1084 return true 1085 } 1086} 1087 1088// mangle replaces references to C names in arg with the mangled names, 1089// rewriting calls when it finds them. 1090// It removes the corresponding references in f.Ref and f.Calls, so that we 1091// don't try to do the replacement again in rewriteRef or rewriteCall. 1092// If addPosition is true, add position info to the idents of C names in arg. 1093func (p *Package) mangle(f *File, arg *ast.Expr, addPosition bool) (ast.Expr, bool) { 1094 needsUnsafe := false 1095 f.walk(arg, ctxExpr, func(f *File, arg interface{}, context astContext) { 1096 px, ok := arg.(*ast.Expr) 1097 if !ok { 1098 return 1099 } 1100 sel, ok := (*px).(*ast.SelectorExpr) 1101 if ok { 1102 if l, ok := sel.X.(*ast.Ident); !ok || l.Name != "C" { 1103 return 1104 } 1105 1106 for _, r := range f.Ref { 1107 if r.Expr == px { 1108 *px = p.rewriteName(f, r, addPosition) 1109 r.Done = true 1110 break 1111 } 1112 } 1113 1114 return 1115 } 1116 1117 call, ok := (*px).(*ast.CallExpr) 1118 if !ok { 1119 return 1120 } 1121 1122 for _, c := range f.Calls { 1123 if !c.Done && c.Call.Lparen == call.Lparen { 1124 cstr, nu := p.rewriteCall(f, c) 1125 if cstr != "" { 1126 // Smuggle the rewritten call through an ident. 1127 *px = ast.NewIdent(cstr) 1128 if nu { 1129 needsUnsafe = true 1130 } 1131 c.Done = true 1132 } 1133 } 1134 } 1135 }) 1136 return *arg, needsUnsafe 1137} 1138 1139// checkIndex checks whether arg has the form &a[i], possibly inside 1140// type conversions. If so, then in the general case it writes 1141// _cgoIndexNN := a 1142// _cgoNN := &cgoIndexNN[i] // with type conversions, if any 1143// to sb, and writes 1144// _cgoCheckPointer(_cgoNN, _cgoIndexNN) 1145// to sbCheck, and returns true. If a is a simple variable or field reference, 1146// it writes 1147// _cgoIndexNN := &a 1148// and dereferences the uses of _cgoIndexNN. Taking the address avoids 1149// making a copy of an array. 1150// 1151// This tells _cgoCheckPointer to check the complete contents of the 1152// slice or array being indexed, but no other part of the memory allocation. 1153func (p *Package) checkIndex(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool { 1154 // Strip type conversions. 1155 x := arg 1156 for { 1157 c, ok := x.(*ast.CallExpr) 1158 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) { 1159 break 1160 } 1161 x = c.Args[0] 1162 } 1163 u, ok := x.(*ast.UnaryExpr) 1164 if !ok || u.Op != token.AND { 1165 return false 1166 } 1167 index, ok := u.X.(*ast.IndexExpr) 1168 if !ok { 1169 return false 1170 } 1171 1172 addr := "" 1173 deref := "" 1174 if p.isVariable(index.X) { 1175 addr = "&" 1176 deref = "*" 1177 } 1178 1179 fmt.Fprintf(sb, "_cgoIndex%d := %s%s; ", i, addr, gofmtPos(index.X, index.X.Pos())) 1180 origX := index.X 1181 index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i)) 1182 if deref == "*" { 1183 index.X = &ast.StarExpr{X: index.X} 1184 } 1185 fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos())) 1186 index.X = origX 1187 1188 fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, %s_cgoIndex%d); ", i, deref, i) 1189 1190 return true 1191} 1192 1193// checkAddr checks whether arg has the form &x, possibly inside type 1194// conversions. If so, it writes 1195// _cgoBaseNN := &x 1196// _cgoNN := _cgoBaseNN // with type conversions, if any 1197// to sb, and writes 1198// _cgoCheckPointer(_cgoBaseNN, true) 1199// to sbCheck, and returns true. This tells _cgoCheckPointer to check 1200// just the contents of the pointer being passed, not any other part 1201// of the memory allocation. This is run after checkIndex, which looks 1202// for the special case of &a[i], which requires different checks. 1203func (p *Package) checkAddr(sb, sbCheck *bytes.Buffer, arg ast.Expr, i int) bool { 1204 // Strip type conversions. 1205 px := &arg 1206 for { 1207 c, ok := (*px).(*ast.CallExpr) 1208 if !ok || len(c.Args) != 1 || !p.isType(c.Fun) { 1209 break 1210 } 1211 px = &c.Args[0] 1212 } 1213 if u, ok := (*px).(*ast.UnaryExpr); !ok || u.Op != token.AND { 1214 return false 1215 } 1216 1217 fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos())) 1218 1219 origX := *px 1220 *px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i)) 1221 fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos())) 1222 *px = origX 1223 1224 // Use "0 == 0" to do the right thing in the unlikely event 1225 // that "true" is shadowed. 1226 fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgoBase%d, 0 == 0); ", i) 1227 1228 return true 1229} 1230 1231// isType reports whether the expression is definitely a type. 1232// This is conservative--it returns false for an unknown identifier. 1233func (p *Package) isType(t ast.Expr) bool { 1234 switch t := t.(type) { 1235 case *ast.SelectorExpr: 1236 id, ok := t.X.(*ast.Ident) 1237 if !ok { 1238 return false 1239 } 1240 if id.Name == "unsafe" && t.Sel.Name == "Pointer" { 1241 return true 1242 } 1243 if id.Name == "C" && typedef["_Ctype_"+t.Sel.Name] != nil { 1244 return true 1245 } 1246 return false 1247 case *ast.Ident: 1248 // TODO: This ignores shadowing. 1249 switch t.Name { 1250 case "unsafe.Pointer", "bool", "byte", 1251 "complex64", "complex128", 1252 "error", 1253 "float32", "float64", 1254 "int", "int8", "int16", "int32", "int64", 1255 "rune", "string", 1256 "uint", "uint8", "uint16", "uint32", "uint64", "uintptr": 1257 1258 return true 1259 } 1260 if strings.HasPrefix(t.Name, "_Ctype_") { 1261 return true 1262 } 1263 case *ast.ParenExpr: 1264 return p.isType(t.X) 1265 case *ast.StarExpr: 1266 return p.isType(t.X) 1267 case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, 1268 *ast.MapType, *ast.ChanType: 1269 1270 return true 1271 } 1272 return false 1273} 1274 1275// isVariable reports whether x is a variable, possibly with field references. 1276func (p *Package) isVariable(x ast.Expr) bool { 1277 switch x := x.(type) { 1278 case *ast.Ident: 1279 return true 1280 case *ast.SelectorExpr: 1281 return p.isVariable(x.X) 1282 case *ast.IndexExpr: 1283 return true 1284 } 1285 return false 1286} 1287 1288// rewriteUnsafe returns a version of t with references to unsafe.Pointer 1289// rewritten to use _cgo_unsafe.Pointer instead. 1290func (p *Package) rewriteUnsafe(t ast.Expr) ast.Expr { 1291 switch t := t.(type) { 1292 case *ast.Ident: 1293 // We don't see a SelectorExpr for unsafe.Pointer; 1294 // this is created by code in this file. 1295 if t.Name == "unsafe.Pointer" { 1296 return ast.NewIdent("_cgo_unsafe.Pointer") 1297 } 1298 case *ast.ArrayType: 1299 t1 := p.rewriteUnsafe(t.Elt) 1300 if t1 != t.Elt { 1301 r := *t 1302 r.Elt = t1 1303 return &r 1304 } 1305 case *ast.StructType: 1306 changed := false 1307 fields := *t.Fields 1308 fields.List = nil 1309 for _, f := range t.Fields.List { 1310 ft := p.rewriteUnsafe(f.Type) 1311 if ft == f.Type { 1312 fields.List = append(fields.List, f) 1313 } else { 1314 fn := *f 1315 fn.Type = ft 1316 fields.List = append(fields.List, &fn) 1317 changed = true 1318 } 1319 } 1320 if changed { 1321 r := *t 1322 r.Fields = &fields 1323 return &r 1324 } 1325 case *ast.StarExpr: // Pointer type. 1326 x1 := p.rewriteUnsafe(t.X) 1327 if x1 != t.X { 1328 r := *t 1329 r.X = x1 1330 return &r 1331 } 1332 } 1333 return t 1334} 1335 1336// rewriteRef rewrites all the C.xxx references in f.AST to refer to the 1337// Go equivalents, now that we have figured out the meaning of all 1338// the xxx. In *godefs mode, rewriteRef replaces the names 1339// with full definitions instead of mangled names. 1340func (p *Package) rewriteRef(f *File) { 1341 // Keep a list of all the functions, to remove the ones 1342 // only used as expressions and avoid generating bridge 1343 // code for them. 1344 functions := make(map[string]bool) 1345 1346 for _, n := range f.Name { 1347 if n.Kind == "func" { 1348 functions[n.Go] = false 1349 } 1350 } 1351 1352 // Now that we have all the name types filled in, 1353 // scan through the Refs to identify the ones that 1354 // are trying to do a ,err call. Also check that 1355 // functions are only used in calls. 1356 for _, r := range f.Ref { 1357 if r.Name.IsConst() && r.Name.Const == "" { 1358 error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go)) 1359 } 1360 1361 if r.Name.Kind == "func" { 1362 switch r.Context { 1363 case ctxCall, ctxCall2: 1364 functions[r.Name.Go] = true 1365 } 1366 } 1367 1368 expr := p.rewriteName(f, r, false) 1369 1370 if *godefs { 1371 // Substitute definition for mangled type name. 1372 if r.Name.Type != nil && r.Name.Kind == "type" { 1373 expr = r.Name.Type.Go 1374 } 1375 if id, ok := expr.(*ast.Ident); ok { 1376 if t := typedef[id.Name]; t != nil { 1377 expr = t.Go 1378 } 1379 if id.Name == r.Name.Mangle && r.Name.Const != "" { 1380 expr = ast.NewIdent(r.Name.Const) 1381 } 1382 } 1383 } 1384 1385 // Copy position information from old expr into new expr, 1386 // in case expression being replaced is first on line. 1387 // See golang.org/issue/6563. 1388 pos := (*r.Expr).Pos() 1389 if x, ok := expr.(*ast.Ident); ok { 1390 expr = &ast.Ident{NamePos: pos, Name: x.Name} 1391 } 1392 1393 // Change AST, because some later processing depends on it, 1394 // and also because -godefs mode still prints the AST. 1395 old := *r.Expr 1396 *r.Expr = expr 1397 1398 // Record source-level edit for cgo output. 1399 if !r.Done { 1400 // Prepend a space in case the earlier code ends 1401 // with '/', which would give us a "//" comment. 1402 repl := " " + gofmtPos(expr, old.Pos()) 1403 end := fset.Position(old.End()) 1404 // Subtract 1 from the column if we are going to 1405 // append a close parenthesis. That will set the 1406 // correct column for the following characters. 1407 sub := 0 1408 if r.Name.Kind != "type" { 1409 sub = 1 1410 } 1411 if end.Column > sub { 1412 repl = fmt.Sprintf("%s /*line :%d:%d*/", repl, end.Line, end.Column-sub) 1413 } 1414 if r.Name.Kind != "type" { 1415 repl = "(" + repl + ")" 1416 } 1417 f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl) 1418 } 1419 } 1420 1421 // Remove functions only used as expressions, so their respective 1422 // bridge functions are not generated. 1423 for name, used := range functions { 1424 if !used { 1425 delete(f.Name, name) 1426 } 1427 } 1428} 1429 1430// rewriteName returns the expression used to rewrite a reference. 1431// If addPosition is true, add position info in the ident name. 1432func (p *Package) rewriteName(f *File, r *Ref, addPosition bool) ast.Expr { 1433 getNewIdent := ast.NewIdent 1434 if addPosition { 1435 getNewIdent = func(newName string) *ast.Ident { 1436 mangledIdent := ast.NewIdent(newName) 1437 if len(newName) == len(r.Name.Go) { 1438 return mangledIdent 1439 } 1440 p := fset.Position((*r.Expr).End()) 1441 if p.Column == 0 { 1442 return mangledIdent 1443 } 1444 return ast.NewIdent(fmt.Sprintf("%s /*line :%d:%d*/", newName, p.Line, p.Column)) 1445 } 1446 } 1447 var expr ast.Expr = getNewIdent(r.Name.Mangle) // default 1448 switch r.Context { 1449 case ctxCall, ctxCall2: 1450 if r.Name.Kind != "func" { 1451 if r.Name.Kind == "type" { 1452 r.Context = ctxType 1453 if r.Name.Type == nil { 1454 error_(r.Pos(), "invalid conversion to C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1455 } 1456 break 1457 } 1458 error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) 1459 break 1460 } 1461 if r.Context == ctxCall2 { 1462 if r.Name.Go == "_CMalloc" { 1463 error_(r.Pos(), "no two-result form for C.malloc") 1464 break 1465 } 1466 // Invent new Name for the two-result function. 1467 n := f.Name["2"+r.Name.Go] 1468 if n == nil { 1469 n = new(Name) 1470 *n = *r.Name 1471 n.AddError = true 1472 n.Mangle = "_C2func_" + n.Go 1473 f.Name["2"+r.Name.Go] = n 1474 } 1475 expr = getNewIdent(n.Mangle) 1476 r.Name = n 1477 break 1478 } 1479 case ctxExpr: 1480 switch r.Name.Kind { 1481 case "func": 1482 if builtinDefs[r.Name.C] != "" { 1483 error_(r.Pos(), "use of builtin '%s' not in function call", fixGo(r.Name.C)) 1484 } 1485 1486 // Function is being used in an expression, to e.g. pass around a C function pointer. 1487 // Create a new Name for this Ref which causes the variable to be declared in Go land. 1488 fpName := "fp_" + r.Name.Go 1489 name := f.Name[fpName] 1490 if name == nil { 1491 name = &Name{ 1492 Go: fpName, 1493 C: r.Name.C, 1494 Kind: "fpvar", 1495 Type: &Type{Size: p.PtrSize, Align: p.PtrSize, C: c("void*"), Go: ast.NewIdent("unsafe.Pointer")}, 1496 } 1497 p.mangleName(name) 1498 f.Name[fpName] = name 1499 } 1500 r.Name = name 1501 // Rewrite into call to _Cgo_ptr to prevent assignments. The _Cgo_ptr 1502 // function is defined in out.go and simply returns its argument. See 1503 // issue 7757. 1504 expr = &ast.CallExpr{ 1505 Fun: &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"}, 1506 Args: []ast.Expr{getNewIdent(name.Mangle)}, 1507 } 1508 case "type": 1509 // Okay - might be new(T), T(x), Generic[T], etc. 1510 if r.Name.Type == nil { 1511 error_(r.Pos(), "expression C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1512 } 1513 case "var": 1514 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1515 case "macro": 1516 expr = &ast.CallExpr{Fun: expr} 1517 } 1518 case ctxSelector: 1519 if r.Name.Kind == "var" { 1520 expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr} 1521 } else { 1522 error_(r.Pos(), "only C variables allowed in selector expression %s", fixGo(r.Name.Go)) 1523 } 1524 case ctxType: 1525 if r.Name.Kind != "type" { 1526 error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go)) 1527 } else if r.Name.Type == nil { 1528 // Use of C.enum_x, C.struct_x or C.union_x without C definition. 1529 // GCC won't raise an error when using pointers to such unknown types. 1530 error_(r.Pos(), "type C.%s: undefined C type '%s'", fixGo(r.Name.Go), r.Name.C) 1531 } 1532 default: 1533 if r.Name.Kind == "func" { 1534 error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) 1535 } 1536 } 1537 return expr 1538} 1539 1540// gofmtPos returns the gofmt-formatted string for an AST node, 1541// with a comment setting the position before the node. 1542func gofmtPos(n ast.Expr, pos token.Pos) string { 1543 s := gofmtLine(n) 1544 p := fset.Position(pos) 1545 if p.Column == 0 { 1546 return s 1547 } 1548 return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s) 1549} 1550 1551// checkGCCBaseCmd returns the start of the compiler command line. 1552// It uses $CC if set, or else $GCC, or else the compiler recorded 1553// during the initial build as defaultCC. 1554// defaultCC is defined in zdefaultcc.go, written by cmd/dist. 1555// 1556// The compiler command line is split into arguments on whitespace. Quotes 1557// are understood, so arguments may contain whitespace. 1558// 1559// checkGCCBaseCmd confirms that the compiler exists in PATH, returning 1560// an error if it does not. 1561func checkGCCBaseCmd() ([]string, error) { 1562 // Use $CC if set, since that's what the build uses. 1563 value := os.Getenv("CC") 1564 if value == "" { 1565 // Try $GCC if set, since that's what we used to use. 1566 value = os.Getenv("GCC") 1567 } 1568 if value == "" { 1569 value = defaultCC(goos, goarch) 1570 } 1571 args, err := quoted.Split(value) 1572 if err != nil { 1573 return nil, err 1574 } 1575 if len(args) == 0 { 1576 return nil, errors.New("CC not set and no default found") 1577 } 1578 if _, err := exec.LookPath(args[0]); err != nil { 1579 return nil, fmt.Errorf("C compiler %q not found: %v", args[0], err) 1580 } 1581 return args[:len(args):len(args)], nil 1582} 1583 1584// gccMachine returns the gcc -m flag to use, either "-m32", "-m64" or "-marm". 1585func (p *Package) gccMachine() []string { 1586 switch goarch { 1587 case "amd64": 1588 if goos == "darwin" { 1589 return []string{"-arch", "x86_64", "-m64"} 1590 } 1591 return []string{"-m64"} 1592 case "arm64": 1593 if goos == "darwin" { 1594 return []string{"-arch", "arm64"} 1595 } 1596 case "386": 1597 return []string{"-m32"} 1598 case "arm": 1599 return []string{"-marm"} // not thumb 1600 case "s390": 1601 return []string{"-m31"} 1602 case "s390x": 1603 return []string{"-m64"} 1604 case "mips64", "mips64le": 1605 if gomips64 == "hardfloat" { 1606 return []string{"-mabi=64", "-mhard-float"} 1607 } else if gomips64 == "softfloat" { 1608 return []string{"-mabi=64", "-msoft-float"} 1609 } 1610 case "mips", "mipsle": 1611 if gomips == "hardfloat" { 1612 return []string{"-mabi=32", "-mfp32", "-mhard-float", "-mno-odd-spreg"} 1613 } else if gomips == "softfloat" { 1614 return []string{"-mabi=32", "-msoft-float"} 1615 } 1616 } 1617 return nil 1618} 1619 1620func gccTmp() string { 1621 return *objDir + "_cgo_.o" 1622} 1623 1624// gccCmd returns the gcc command line to use for compiling 1625// the input. 1626func (p *Package) gccCmd() []string { 1627 c := append(gccBaseCmd, 1628 "-w", // no warnings 1629 "-Wno-error", // warnings are not errors 1630 "-o"+gccTmp(), // write object to tmp 1631 "-gdwarf-2", // generate DWARF v2 debugging symbols 1632 "-c", // do not link 1633 "-xc", // input language is C 1634 ) 1635 if p.GccIsClang { 1636 c = append(c, 1637 "-ferror-limit=0", 1638 // Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn) 1639 // doesn't have -Wno-unneeded-internal-declaration, so we need yet another 1640 // flag to disable the warning. Yes, really good diagnostics, clang. 1641 "-Wno-unknown-warning-option", 1642 "-Wno-unneeded-internal-declaration", 1643 "-Wno-unused-function", 1644 "-Qunused-arguments", 1645 // Clang embeds prototypes for some builtin functions, 1646 // like malloc and calloc, but all size_t parameters are 1647 // incorrectly typed unsigned long. We work around that 1648 // by disabling the builtin functions (this is safe as 1649 // it won't affect the actual compilation of the C code). 1650 // See: https://golang.org/issue/6506. 1651 "-fno-builtin", 1652 ) 1653 } 1654 1655 c = append(c, p.GccOptions...) 1656 c = append(c, p.gccMachine()...) 1657 if goos == "aix" { 1658 c = append(c, "-maix64") 1659 c = append(c, "-mcmodel=large") 1660 } 1661 // disable LTO so we get an object whose symbols we can read 1662 c = append(c, "-fno-lto") 1663 c = append(c, "-") //read input from standard input 1664 return c 1665} 1666 1667// gccDebug runs gcc -gdwarf-2 over the C program stdin and 1668// returns the corresponding DWARF data and, if present, debug data block. 1669func (p *Package) gccDebug(stdin []byte, nnames int) (d *dwarf.Data, ints []int64, floats []float64, strs []string) { 1670 runGcc(stdin, p.gccCmd()) 1671 1672 isDebugInts := func(s string) bool { 1673 // Some systems use leading _ to denote non-assembly symbols. 1674 return s == "__cgodebug_ints" || s == "___cgodebug_ints" 1675 } 1676 isDebugFloats := func(s string) bool { 1677 // Some systems use leading _ to denote non-assembly symbols. 1678 return s == "__cgodebug_floats" || s == "___cgodebug_floats" 1679 } 1680 indexOfDebugStr := func(s string) int { 1681 // Some systems use leading _ to denote non-assembly symbols. 1682 if strings.HasPrefix(s, "___") { 1683 s = s[1:] 1684 } 1685 if strings.HasPrefix(s, "__cgodebug_str__") { 1686 if n, err := strconv.Atoi(s[len("__cgodebug_str__"):]); err == nil { 1687 return n 1688 } 1689 } 1690 return -1 1691 } 1692 indexOfDebugStrlen := func(s string) int { 1693 // Some systems use leading _ to denote non-assembly symbols. 1694 if strings.HasPrefix(s, "___") { 1695 s = s[1:] 1696 } 1697 if strings.HasPrefix(s, "__cgodebug_strlen__") { 1698 if n, err := strconv.Atoi(s[len("__cgodebug_strlen__"):]); err == nil { 1699 return n 1700 } 1701 } 1702 return -1 1703 } 1704 1705 strs = make([]string, nnames) 1706 1707 strdata := make(map[int]string, nnames) 1708 strlens := make(map[int]int, nnames) 1709 1710 buildStrings := func() { 1711 for n, strlen := range strlens { 1712 data := strdata[n] 1713 if len(data) <= strlen { 1714 fatalf("invalid string literal") 1715 } 1716 strs[n] = data[:strlen] 1717 } 1718 } 1719 1720 if f, err := macho.Open(gccTmp()); err == nil { 1721 defer f.Close() 1722 d, err := f.DWARF() 1723 if err != nil { 1724 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1725 } 1726 bo := f.ByteOrder 1727 if f.Symtab != nil { 1728 for i := range f.Symtab.Syms { 1729 s := &f.Symtab.Syms[i] 1730 switch { 1731 case isDebugInts(s.Name): 1732 // Found it. Now find data section. 1733 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1734 sect := f.Sections[i] 1735 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1736 if sdat, err := sect.Data(); err == nil { 1737 data := sdat[s.Value-sect.Addr:] 1738 ints = make([]int64, len(data)/8) 1739 for i := range ints { 1740 ints[i] = int64(bo.Uint64(data[i*8:])) 1741 } 1742 } 1743 } 1744 } 1745 case isDebugFloats(s.Name): 1746 // Found it. Now find data section. 1747 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1748 sect := f.Sections[i] 1749 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1750 if sdat, err := sect.Data(); err == nil { 1751 data := sdat[s.Value-sect.Addr:] 1752 floats = make([]float64, len(data)/8) 1753 for i := range floats { 1754 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1755 } 1756 } 1757 } 1758 } 1759 default: 1760 if n := indexOfDebugStr(s.Name); n != -1 { 1761 // Found it. Now find data section. 1762 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1763 sect := f.Sections[i] 1764 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1765 if sdat, err := sect.Data(); err == nil { 1766 data := sdat[s.Value-sect.Addr:] 1767 strdata[n] = string(data) 1768 } 1769 } 1770 } 1771 break 1772 } 1773 if n := indexOfDebugStrlen(s.Name); n != -1 { 1774 // Found it. Now find data section. 1775 if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) { 1776 sect := f.Sections[i] 1777 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1778 if sdat, err := sect.Data(); err == nil { 1779 data := sdat[s.Value-sect.Addr:] 1780 strlen := bo.Uint64(data[:8]) 1781 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1782 fatalf("string literal too big") 1783 } 1784 strlens[n] = int(strlen) 1785 } 1786 } 1787 } 1788 break 1789 } 1790 } 1791 } 1792 1793 buildStrings() 1794 } 1795 return d, ints, floats, strs 1796 } 1797 1798 if f, err := elf.Open(gccTmp()); err == nil { 1799 defer f.Close() 1800 d, err := f.DWARF() 1801 if err != nil { 1802 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1803 } 1804 bo := f.ByteOrder 1805 symtab, err := f.Symbols() 1806 if err == nil { 1807 for i := range symtab { 1808 s := &symtab[i] 1809 switch { 1810 case isDebugInts(s.Name): 1811 // Found it. Now find data section. 1812 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1813 sect := f.Sections[i] 1814 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1815 if sdat, err := sect.Data(); err == nil { 1816 data := sdat[s.Value-sect.Addr:] 1817 ints = make([]int64, len(data)/8) 1818 for i := range ints { 1819 ints[i] = int64(bo.Uint64(data[i*8:])) 1820 } 1821 } 1822 } 1823 } 1824 case isDebugFloats(s.Name): 1825 // Found it. Now find data section. 1826 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1827 sect := f.Sections[i] 1828 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1829 if sdat, err := sect.Data(); err == nil { 1830 data := sdat[s.Value-sect.Addr:] 1831 floats = make([]float64, len(data)/8) 1832 for i := range floats { 1833 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1834 } 1835 } 1836 } 1837 } 1838 default: 1839 if n := indexOfDebugStr(s.Name); n != -1 { 1840 // Found it. Now find data section. 1841 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1842 sect := f.Sections[i] 1843 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1844 if sdat, err := sect.Data(); err == nil { 1845 data := sdat[s.Value-sect.Addr:] 1846 strdata[n] = string(data) 1847 } 1848 } 1849 } 1850 break 1851 } 1852 if n := indexOfDebugStrlen(s.Name); n != -1 { 1853 // Found it. Now find data section. 1854 if i := int(s.Section); 0 <= i && i < len(f.Sections) { 1855 sect := f.Sections[i] 1856 if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size { 1857 if sdat, err := sect.Data(); err == nil { 1858 data := sdat[s.Value-sect.Addr:] 1859 strlen := bo.Uint64(data[:8]) 1860 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1861 fatalf("string literal too big") 1862 } 1863 strlens[n] = int(strlen) 1864 } 1865 } 1866 } 1867 break 1868 } 1869 } 1870 } 1871 1872 buildStrings() 1873 } 1874 return d, ints, floats, strs 1875 } 1876 1877 if f, err := pe.Open(gccTmp()); err == nil { 1878 defer f.Close() 1879 d, err := f.DWARF() 1880 if err != nil { 1881 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1882 } 1883 bo := binary.LittleEndian 1884 for _, s := range f.Symbols { 1885 switch { 1886 case isDebugInts(s.Name): 1887 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1888 sect := f.Sections[i] 1889 if s.Value < sect.Size { 1890 if sdat, err := sect.Data(); err == nil { 1891 data := sdat[s.Value:] 1892 ints = make([]int64, len(data)/8) 1893 for i := range ints { 1894 ints[i] = int64(bo.Uint64(data[i*8:])) 1895 } 1896 } 1897 } 1898 } 1899 case isDebugFloats(s.Name): 1900 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1901 sect := f.Sections[i] 1902 if s.Value < sect.Size { 1903 if sdat, err := sect.Data(); err == nil { 1904 data := sdat[s.Value:] 1905 floats = make([]float64, len(data)/8) 1906 for i := range floats { 1907 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1908 } 1909 } 1910 } 1911 } 1912 default: 1913 if n := indexOfDebugStr(s.Name); n != -1 { 1914 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1915 sect := f.Sections[i] 1916 if s.Value < sect.Size { 1917 if sdat, err := sect.Data(); err == nil { 1918 data := sdat[s.Value:] 1919 strdata[n] = string(data) 1920 } 1921 } 1922 } 1923 break 1924 } 1925 if n := indexOfDebugStrlen(s.Name); n != -1 { 1926 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1927 sect := f.Sections[i] 1928 if s.Value < sect.Size { 1929 if sdat, err := sect.Data(); err == nil { 1930 data := sdat[s.Value:] 1931 strlen := bo.Uint64(data[:8]) 1932 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 1933 fatalf("string literal too big") 1934 } 1935 strlens[n] = int(strlen) 1936 } 1937 } 1938 } 1939 break 1940 } 1941 } 1942 } 1943 1944 buildStrings() 1945 1946 return d, ints, floats, strs 1947 } 1948 1949 if f, err := xcoff.Open(gccTmp()); err == nil { 1950 defer f.Close() 1951 d, err := f.DWARF() 1952 if err != nil { 1953 fatalf("cannot load DWARF output from %s: %v", gccTmp(), err) 1954 } 1955 bo := binary.BigEndian 1956 for _, s := range f.Symbols { 1957 switch { 1958 case isDebugInts(s.Name): 1959 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1960 sect := f.Sections[i] 1961 if s.Value < sect.Size { 1962 if sdat, err := sect.Data(); err == nil { 1963 data := sdat[s.Value:] 1964 ints = make([]int64, len(data)/8) 1965 for i := range ints { 1966 ints[i] = int64(bo.Uint64(data[i*8:])) 1967 } 1968 } 1969 } 1970 } 1971 case isDebugFloats(s.Name): 1972 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1973 sect := f.Sections[i] 1974 if s.Value < sect.Size { 1975 if sdat, err := sect.Data(); err == nil { 1976 data := sdat[s.Value:] 1977 floats = make([]float64, len(data)/8) 1978 for i := range floats { 1979 floats[i] = math.Float64frombits(bo.Uint64(data[i*8:])) 1980 } 1981 } 1982 } 1983 } 1984 default: 1985 if n := indexOfDebugStr(s.Name); n != -1 { 1986 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1987 sect := f.Sections[i] 1988 if s.Value < sect.Size { 1989 if sdat, err := sect.Data(); err == nil { 1990 data := sdat[s.Value:] 1991 strdata[n] = string(data) 1992 } 1993 } 1994 } 1995 break 1996 } 1997 if n := indexOfDebugStrlen(s.Name); n != -1 { 1998 if i := int(s.SectionNumber) - 1; 0 <= i && i < len(f.Sections) { 1999 sect := f.Sections[i] 2000 if s.Value < sect.Size { 2001 if sdat, err := sect.Data(); err == nil { 2002 data := sdat[s.Value:] 2003 strlen := bo.Uint64(data[:8]) 2004 if strlen > (1<<(uint(p.IntSize*8)-1) - 1) { // greater than MaxInt? 2005 fatalf("string literal too big") 2006 } 2007 strlens[n] = int(strlen) 2008 } 2009 } 2010 } 2011 break 2012 } 2013 } 2014 } 2015 2016 buildStrings() 2017 return d, ints, floats, strs 2018 } 2019 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE, XCOFF object", gccTmp()) 2020 panic("not reached") 2021} 2022 2023// gccDefines runs gcc -E -dM -xc - over the C program stdin 2024// and returns the corresponding standard output, which is the 2025// #defines that gcc encountered while processing the input 2026// and its included files. 2027func (p *Package) gccDefines(stdin []byte) string { 2028 base := append(gccBaseCmd, "-E", "-dM", "-xc") 2029 base = append(base, p.gccMachine()...) 2030 stdout, _ := runGcc(stdin, append(append(base, p.GccOptions...), "-")) 2031 return stdout 2032} 2033 2034// gccErrors runs gcc over the C program stdin and returns 2035// the errors that gcc prints. That is, this function expects 2036// gcc to fail. 2037func (p *Package) gccErrors(stdin []byte, extraArgs ...string) string { 2038 // TODO(rsc): require failure 2039 args := p.gccCmd() 2040 2041 // Optimization options can confuse the error messages; remove them. 2042 nargs := make([]string, 0, len(args)+len(extraArgs)) 2043 for _, arg := range args { 2044 if !strings.HasPrefix(arg, "-O") { 2045 nargs = append(nargs, arg) 2046 } 2047 } 2048 2049 // Force -O0 optimization and append extra arguments, but keep the 2050 // trailing "-" at the end. 2051 li := len(nargs) - 1 2052 last := nargs[li] 2053 nargs[li] = "-O0" 2054 nargs = append(nargs, extraArgs...) 2055 nargs = append(nargs, last) 2056 2057 if *debugGcc { 2058 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(nargs, " ")) 2059 os.Stderr.Write(stdin) 2060 fmt.Fprint(os.Stderr, "EOF\n") 2061 } 2062 stdout, stderr, _ := run(stdin, nargs) 2063 if *debugGcc { 2064 os.Stderr.Write(stdout) 2065 os.Stderr.Write(stderr) 2066 } 2067 return string(stderr) 2068} 2069 2070// runGcc runs the gcc command line args with stdin on standard input. 2071// If the command exits with a non-zero exit status, runGcc prints 2072// details about what was run and exits. 2073// Otherwise runGcc returns the data written to standard output and standard error. 2074// Note that for some of the uses we expect useful data back 2075// on standard error, but for those uses gcc must still exit 0. 2076func runGcc(stdin []byte, args []string) (string, string) { 2077 if *debugGcc { 2078 fmt.Fprintf(os.Stderr, "$ %s <<EOF\n", strings.Join(args, " ")) 2079 os.Stderr.Write(stdin) 2080 fmt.Fprint(os.Stderr, "EOF\n") 2081 } 2082 stdout, stderr, ok := run(stdin, args) 2083 if *debugGcc { 2084 os.Stderr.Write(stdout) 2085 os.Stderr.Write(stderr) 2086 } 2087 if !ok { 2088 os.Stderr.Write(stderr) 2089 os.Exit(2) 2090 } 2091 return string(stdout), string(stderr) 2092} 2093 2094// A typeConv is a translator from dwarf types to Go types 2095// with equivalent memory layout. 2096type typeConv struct { 2097 // Cache of already-translated or in-progress types. 2098 m map[string]*Type 2099 2100 // Map from types to incomplete pointers to those types. 2101 ptrs map[string][]*Type 2102 // Keys of ptrs in insertion order (deterministic worklist) 2103 // ptrKeys contains exactly the keys in ptrs. 2104 ptrKeys []dwarf.Type 2105 2106 // Type names X for which there exists an XGetTypeID function with type func() CFTypeID. 2107 getTypeIDs map[string]bool 2108 2109 // badStructs contains C structs that should be marked NotInHeap. 2110 notInHeapStructs map[string]bool 2111 2112 // Predeclared types. 2113 bool ast.Expr 2114 byte ast.Expr // denotes padding 2115 int8, int16, int32, int64 ast.Expr 2116 uint8, uint16, uint32, uint64, uintptr ast.Expr 2117 float32, float64 ast.Expr 2118 complex64, complex128 ast.Expr 2119 void ast.Expr 2120 string ast.Expr 2121 goVoid ast.Expr // _Ctype_void, denotes C's void 2122 goVoidPtr ast.Expr // unsafe.Pointer or *byte 2123 goVoidPtrNoHeap ast.Expr // *_Ctype_void_notinheap, like goVoidPtr but marked NotInHeap 2124 2125 ptrSize int64 2126 intSize int64 2127} 2128 2129var tagGen int 2130var typedef = make(map[string]*Type) 2131var goIdent = make(map[string]*ast.Ident) 2132 2133// unionWithPointer is true for a Go type that represents a C union (or class) 2134// that may contain a pointer. This is used for cgo pointer checking. 2135var unionWithPointer = make(map[ast.Expr]bool) 2136 2137// anonymousStructTag provides a consistent tag for an anonymous struct. 2138// The same dwarf.StructType pointer will always get the same tag. 2139var anonymousStructTag = make(map[*dwarf.StructType]string) 2140 2141func (c *typeConv) Init(ptrSize, intSize int64) { 2142 c.ptrSize = ptrSize 2143 c.intSize = intSize 2144 c.m = make(map[string]*Type) 2145 c.ptrs = make(map[string][]*Type) 2146 c.getTypeIDs = make(map[string]bool) 2147 c.notInHeapStructs = make(map[string]bool) 2148 c.bool = c.Ident("bool") 2149 c.byte = c.Ident("byte") 2150 c.int8 = c.Ident("int8") 2151 c.int16 = c.Ident("int16") 2152 c.int32 = c.Ident("int32") 2153 c.int64 = c.Ident("int64") 2154 c.uint8 = c.Ident("uint8") 2155 c.uint16 = c.Ident("uint16") 2156 c.uint32 = c.Ident("uint32") 2157 c.uint64 = c.Ident("uint64") 2158 c.uintptr = c.Ident("uintptr") 2159 c.float32 = c.Ident("float32") 2160 c.float64 = c.Ident("float64") 2161 c.complex64 = c.Ident("complex64") 2162 c.complex128 = c.Ident("complex128") 2163 c.void = c.Ident("void") 2164 c.string = c.Ident("string") 2165 c.goVoid = c.Ident("_Ctype_void") 2166 c.goVoidPtrNoHeap = c.Ident("*_Ctype_void_notinheap") 2167 2168 // Normally cgo translates void* to unsafe.Pointer, 2169 // but for historical reasons -godefs uses *byte instead. 2170 if *godefs { 2171 c.goVoidPtr = &ast.StarExpr{X: c.byte} 2172 } else { 2173 c.goVoidPtr = c.Ident("unsafe.Pointer") 2174 } 2175} 2176 2177// base strips away qualifiers and typedefs to get the underlying type 2178func base(dt dwarf.Type) dwarf.Type { 2179 for { 2180 if d, ok := dt.(*dwarf.QualType); ok { 2181 dt = d.Type 2182 continue 2183 } 2184 if d, ok := dt.(*dwarf.TypedefType); ok { 2185 dt = d.Type 2186 continue 2187 } 2188 break 2189 } 2190 return dt 2191} 2192 2193// unqual strips away qualifiers from a DWARF type. 2194// In general we don't care about top-level qualifiers. 2195func unqual(dt dwarf.Type) dwarf.Type { 2196 for { 2197 if d, ok := dt.(*dwarf.QualType); ok { 2198 dt = d.Type 2199 } else { 2200 break 2201 } 2202 } 2203 return dt 2204} 2205 2206// Map from dwarf text names to aliases we use in package "C". 2207var dwarfToName = map[string]string{ 2208 "long int": "long", 2209 "long unsigned int": "ulong", 2210 "unsigned int": "uint", 2211 "short unsigned int": "ushort", 2212 "unsigned short": "ushort", // Used by Clang; issue 13129. 2213 "short int": "short", 2214 "long long int": "longlong", 2215 "long long unsigned int": "ulonglong", 2216 "signed char": "schar", 2217 "unsigned char": "uchar", 2218} 2219 2220const signedDelta = 64 2221 2222// String returns the current type representation. Format arguments 2223// are assembled within this method so that any changes in mutable 2224// values are taken into account. 2225func (tr *TypeRepr) String() string { 2226 if len(tr.Repr) == 0 { 2227 return "" 2228 } 2229 if len(tr.FormatArgs) == 0 { 2230 return tr.Repr 2231 } 2232 return fmt.Sprintf(tr.Repr, tr.FormatArgs...) 2233} 2234 2235// Empty reports whether the result of String would be "". 2236func (tr *TypeRepr) Empty() bool { 2237 return len(tr.Repr) == 0 2238} 2239 2240// Set modifies the type representation. 2241// If fargs are provided, repr is used as a format for fmt.Sprintf. 2242// Otherwise, repr is used unprocessed as the type representation. 2243func (tr *TypeRepr) Set(repr string, fargs ...interface{}) { 2244 tr.Repr = repr 2245 tr.FormatArgs = fargs 2246} 2247 2248// FinishType completes any outstanding type mapping work. 2249// In particular, it resolves incomplete pointer types. 2250func (c *typeConv) FinishType(pos token.Pos) { 2251 // Completing one pointer type might produce more to complete. 2252 // Keep looping until they're all done. 2253 for len(c.ptrKeys) > 0 { 2254 dtype := c.ptrKeys[0] 2255 dtypeKey := dtype.String() 2256 c.ptrKeys = c.ptrKeys[1:] 2257 ptrs := c.ptrs[dtypeKey] 2258 delete(c.ptrs, dtypeKey) 2259 2260 // Note Type might invalidate c.ptrs[dtypeKey]. 2261 t := c.Type(dtype, pos) 2262 for _, ptr := range ptrs { 2263 ptr.Go.(*ast.StarExpr).X = t.Go 2264 ptr.C.Set("%s*", t.C) 2265 } 2266 } 2267} 2268 2269// Type returns a *Type with the same memory layout as 2270// dtype when used as the type of a variable or a struct field. 2271func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type { 2272 return c.loadType(dtype, pos, "") 2273} 2274 2275// loadType recursively loads the requested dtype and its dependency graph. 2276func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Type { 2277 // Always recompute bad pointer typedefs, as the set of such 2278 // typedefs changes as we see more types. 2279 checkCache := true 2280 if dtt, ok := dtype.(*dwarf.TypedefType); ok && c.badPointerTypedef(dtt) { 2281 checkCache = false 2282 } 2283 2284 // The cache key should be relative to its parent. 2285 // See issue https://golang.org/issue/31891 2286 key := parent + " > " + dtype.String() 2287 2288 if checkCache { 2289 if t, ok := c.m[key]; ok { 2290 if t.Go == nil { 2291 fatalf("%s: type conversion loop at %s", lineno(pos), dtype) 2292 } 2293 return t 2294 } 2295 } 2296 2297 t := new(Type) 2298 t.Size = dtype.Size() // note: wrong for array of pointers, corrected below 2299 t.Align = -1 2300 t.C = &TypeRepr{Repr: dtype.Common().Name} 2301 c.m[key] = t 2302 2303 switch dt := dtype.(type) { 2304 default: 2305 fatalf("%s: unexpected type: %s", lineno(pos), dtype) 2306 2307 case *dwarf.AddrType: 2308 if t.Size != c.ptrSize { 2309 fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype) 2310 } 2311 t.Go = c.uintptr 2312 t.Align = t.Size 2313 2314 case *dwarf.ArrayType: 2315 if dt.StrideBitSize > 0 { 2316 // Cannot represent bit-sized elements in Go. 2317 t.Go = c.Opaque(t.Size) 2318 break 2319 } 2320 count := dt.Count 2321 if count == -1 { 2322 // Indicates flexible array member, which Go doesn't support. 2323 // Translate to zero-length array instead. 2324 count = 0 2325 } 2326 sub := c.Type(dt.Type, pos) 2327 t.Align = sub.Align 2328 t.Go = &ast.ArrayType{ 2329 Len: c.intExpr(count), 2330 Elt: sub.Go, 2331 } 2332 // Recalculate t.Size now that we know sub.Size. 2333 t.Size = count * sub.Size 2334 t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count) 2335 2336 case *dwarf.BoolType: 2337 t.Go = c.bool 2338 t.Align = 1 2339 2340 case *dwarf.CharType: 2341 if t.Size != 1 { 2342 fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype) 2343 } 2344 t.Go = c.int8 2345 t.Align = 1 2346 2347 case *dwarf.EnumType: 2348 if t.Align = t.Size; t.Align >= c.ptrSize { 2349 t.Align = c.ptrSize 2350 } 2351 t.C.Set("enum " + dt.EnumName) 2352 signed := 0 2353 t.EnumValues = make(map[string]int64) 2354 for _, ev := range dt.Val { 2355 t.EnumValues[ev.Name] = ev.Val 2356 if ev.Val < 0 { 2357 signed = signedDelta 2358 } 2359 } 2360 switch t.Size + int64(signed) { 2361 default: 2362 fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype) 2363 case 1: 2364 t.Go = c.uint8 2365 case 2: 2366 t.Go = c.uint16 2367 case 4: 2368 t.Go = c.uint32 2369 case 8: 2370 t.Go = c.uint64 2371 case 1 + signedDelta: 2372 t.Go = c.int8 2373 case 2 + signedDelta: 2374 t.Go = c.int16 2375 case 4 + signedDelta: 2376 t.Go = c.int32 2377 case 8 + signedDelta: 2378 t.Go = c.int64 2379 } 2380 2381 case *dwarf.FloatType: 2382 switch t.Size { 2383 default: 2384 fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype) 2385 case 4: 2386 t.Go = c.float32 2387 case 8: 2388 t.Go = c.float64 2389 } 2390 if t.Align = t.Size; t.Align >= c.ptrSize { 2391 t.Align = c.ptrSize 2392 } 2393 2394 case *dwarf.ComplexType: 2395 switch t.Size { 2396 default: 2397 fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype) 2398 case 8: 2399 t.Go = c.complex64 2400 case 16: 2401 t.Go = c.complex128 2402 } 2403 if t.Align = t.Size / 2; t.Align >= c.ptrSize { 2404 t.Align = c.ptrSize 2405 } 2406 2407 case *dwarf.FuncType: 2408 // No attempt at translation: would enable calls 2409 // directly between worlds, but we need to moderate those. 2410 t.Go = c.uintptr 2411 t.Align = c.ptrSize 2412 2413 case *dwarf.IntType: 2414 if dt.BitSize > 0 { 2415 fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype) 2416 } 2417 switch t.Size { 2418 default: 2419 fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype) 2420 case 1: 2421 t.Go = c.int8 2422 case 2: 2423 t.Go = c.int16 2424 case 4: 2425 t.Go = c.int32 2426 case 8: 2427 t.Go = c.int64 2428 case 16: 2429 t.Go = &ast.ArrayType{ 2430 Len: c.intExpr(t.Size), 2431 Elt: c.uint8, 2432 } 2433 } 2434 if t.Align = t.Size; t.Align >= c.ptrSize { 2435 t.Align = c.ptrSize 2436 } 2437 2438 case *dwarf.PtrType: 2439 // Clang doesn't emit DW_AT_byte_size for pointer types. 2440 if t.Size != c.ptrSize && t.Size != -1 { 2441 fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype) 2442 } 2443 t.Size = c.ptrSize 2444 t.Align = c.ptrSize 2445 2446 if _, ok := base(dt.Type).(*dwarf.VoidType); ok { 2447 t.Go = c.goVoidPtr 2448 t.C.Set("void*") 2449 dq := dt.Type 2450 for { 2451 if d, ok := dq.(*dwarf.QualType); ok { 2452 t.C.Set(d.Qual + " " + t.C.String()) 2453 dq = d.Type 2454 } else { 2455 break 2456 } 2457 } 2458 break 2459 } 2460 2461 // Placeholder initialization; completed in FinishType. 2462 t.Go = &ast.StarExpr{} 2463 t.C.Set("<incomplete>*") 2464 key := dt.Type.String() 2465 if _, ok := c.ptrs[key]; !ok { 2466 c.ptrKeys = append(c.ptrKeys, dt.Type) 2467 } 2468 c.ptrs[key] = append(c.ptrs[key], t) 2469 2470 case *dwarf.QualType: 2471 t1 := c.Type(dt.Type, pos) 2472 t.Size = t1.Size 2473 t.Align = t1.Align 2474 t.Go = t1.Go 2475 if unionWithPointer[t1.Go] { 2476 unionWithPointer[t.Go] = true 2477 } 2478 t.EnumValues = nil 2479 t.Typedef = "" 2480 t.C.Set("%s "+dt.Qual, t1.C) 2481 return t 2482 2483 case *dwarf.StructType: 2484 // Convert to Go struct, being careful about alignment. 2485 // Have to give it a name to simulate C "struct foo" references. 2486 tag := dt.StructName 2487 if dt.ByteSize < 0 && tag == "" { // opaque unnamed struct - should not be possible 2488 break 2489 } 2490 if tag == "" { 2491 tag = anonymousStructTag[dt] 2492 if tag == "" { 2493 tag = "__" + strconv.Itoa(tagGen) 2494 tagGen++ 2495 anonymousStructTag[dt] = tag 2496 } 2497 } else if t.C.Empty() { 2498 t.C.Set(dt.Kind + " " + tag) 2499 } 2500 name := c.Ident("_Ctype_" + dt.Kind + "_" + tag) 2501 t.Go = name // publish before recursive calls 2502 goIdent[name.Name] = name 2503 if dt.ByteSize < 0 { 2504 // Size calculation in c.Struct/c.Opaque will die with size=-1 (unknown), 2505 // so execute the basic things that the struct case would do 2506 // other than try to determine a Go representation. 2507 tt := *t 2508 tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}} 2509 tt.Go = c.Ident("struct{}") 2510 if dt.Kind == "struct" { 2511 // We don't know what the representation of this struct is, so don't let 2512 // anyone allocate one on the Go side. As a side effect of this annotation, 2513 // pointers to this type will not be considered pointers in Go. They won't 2514 // get writebarrier-ed or adjusted during a stack copy. This should handle 2515 // all the cases badPointerTypedef used to handle, but hopefully will 2516 // continue to work going forward without any more need for cgo changes. 2517 tt.NotInHeap = true 2518 // TODO: we should probably do the same for unions. Unions can't live 2519 // on the Go heap, right? It currently doesn't work for unions because 2520 // they are defined as a type alias for struct{}, not a defined type. 2521 } 2522 typedef[name.Name] = &tt 2523 break 2524 } 2525 switch dt.Kind { 2526 case "class", "union": 2527 t.Go = c.Opaque(t.Size) 2528 if c.dwarfHasPointer(dt, pos) { 2529 unionWithPointer[t.Go] = true 2530 } 2531 if t.C.Empty() { 2532 t.C.Set("__typeof__(unsigned char[%d])", t.Size) 2533 } 2534 t.Align = 1 // TODO: should probably base this on field alignment. 2535 typedef[name.Name] = t 2536 case "struct": 2537 g, csyntax, align := c.Struct(dt, pos) 2538 if t.C.Empty() { 2539 t.C.Set(csyntax) 2540 } 2541 t.Align = align 2542 tt := *t 2543 if tag != "" { 2544 tt.C = &TypeRepr{"struct %s", []interface{}{tag}} 2545 } 2546 tt.Go = g 2547 tt.NotInHeap = c.notInHeapStructs[tag] 2548 typedef[name.Name] = &tt 2549 } 2550 2551 case *dwarf.TypedefType: 2552 // Record typedef for printing. 2553 if dt.Name == "_GoString_" { 2554 // Special C name for Go string type. 2555 // Knows string layout used by compilers: pointer plus length, 2556 // which rounds up to 2 pointers after alignment. 2557 t.Go = c.string 2558 t.Size = c.ptrSize * 2 2559 t.Align = c.ptrSize 2560 break 2561 } 2562 if dt.Name == "_GoBytes_" { 2563 // Special C name for Go []byte type. 2564 // Knows slice layout used by compilers: pointer, length, cap. 2565 t.Go = c.Ident("[]byte") 2566 t.Size = c.ptrSize + 4 + 4 2567 t.Align = c.ptrSize 2568 break 2569 } 2570 name := c.Ident("_Ctype_" + dt.Name) 2571 goIdent[name.Name] = name 2572 akey := "" 2573 if c.anonymousStructTypedef(dt) { 2574 // only load type recursively for typedefs of anonymous 2575 // structs, see issues 37479 and 37621. 2576 akey = key 2577 } 2578 sub := c.loadType(dt.Type, pos, akey) 2579 if c.badPointerTypedef(dt) { 2580 // Treat this typedef as a uintptr. 2581 s := *sub 2582 s.Go = c.uintptr 2583 s.BadPointer = true 2584 sub = &s 2585 // Make sure we update any previously computed type. 2586 if oldType := typedef[name.Name]; oldType != nil { 2587 oldType.Go = sub.Go 2588 oldType.BadPointer = true 2589 } 2590 } 2591 if c.badVoidPointerTypedef(dt) { 2592 // Treat this typedef as a pointer to a NotInHeap void. 2593 s := *sub 2594 s.Go = c.goVoidPtrNoHeap 2595 sub = &s 2596 // Make sure we update any previously computed type. 2597 if oldType := typedef[name.Name]; oldType != nil { 2598 oldType.Go = sub.Go 2599 } 2600 } 2601 // Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>" 2602 // typedefs that should be marked NotInHeap. 2603 if ptr, ok := dt.Type.(*dwarf.PtrType); ok { 2604 if strct, ok := ptr.Type.(*dwarf.StructType); ok { 2605 if c.badStructPointerTypedef(dt.Name, strct) { 2606 c.notInHeapStructs[strct.StructName] = true 2607 // Make sure we update any previously computed type. 2608 name := "_Ctype_struct_" + strct.StructName 2609 if oldType := typedef[name]; oldType != nil { 2610 oldType.NotInHeap = true 2611 } 2612 } 2613 } 2614 } 2615 t.Go = name 2616 t.BadPointer = sub.BadPointer 2617 t.NotInHeap = sub.NotInHeap 2618 if unionWithPointer[sub.Go] { 2619 unionWithPointer[t.Go] = true 2620 } 2621 t.Size = sub.Size 2622 t.Align = sub.Align 2623 oldType := typedef[name.Name] 2624 if oldType == nil { 2625 tt := *t 2626 tt.Go = sub.Go 2627 tt.BadPointer = sub.BadPointer 2628 tt.NotInHeap = sub.NotInHeap 2629 typedef[name.Name] = &tt 2630 } 2631 2632 // If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo", 2633 // use that as the Go form for this typedef too, so that the typedef will be interchangeable 2634 // with the base type. 2635 // In -godefs mode, do this for all typedefs. 2636 if isStructUnionClass(sub.Go) || *godefs { 2637 t.Go = sub.Go 2638 2639 if isStructUnionClass(sub.Go) { 2640 // Use the typedef name for C code. 2641 typedef[sub.Go.(*ast.Ident).Name].C = t.C 2642 } 2643 2644 // If we've seen this typedef before, and it 2645 // was an anonymous struct/union/class before 2646 // too, use the old definition. 2647 // TODO: it would be safer to only do this if 2648 // we verify that the types are the same. 2649 if oldType != nil && isStructUnionClass(oldType.Go) { 2650 t.Go = oldType.Go 2651 } 2652 } 2653 2654 case *dwarf.UcharType: 2655 if t.Size != 1 { 2656 fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype) 2657 } 2658 t.Go = c.uint8 2659 t.Align = 1 2660 2661 case *dwarf.UintType: 2662 if dt.BitSize > 0 { 2663 fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype) 2664 } 2665 switch t.Size { 2666 default: 2667 fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype) 2668 case 1: 2669 t.Go = c.uint8 2670 case 2: 2671 t.Go = c.uint16 2672 case 4: 2673 t.Go = c.uint32 2674 case 8: 2675 t.Go = c.uint64 2676 case 16: 2677 t.Go = &ast.ArrayType{ 2678 Len: c.intExpr(t.Size), 2679 Elt: c.uint8, 2680 } 2681 } 2682 if t.Align = t.Size; t.Align >= c.ptrSize { 2683 t.Align = c.ptrSize 2684 } 2685 2686 case *dwarf.VoidType: 2687 t.Go = c.goVoid 2688 t.C.Set("void") 2689 t.Align = 1 2690 } 2691 2692 switch dtype.(type) { 2693 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.ComplexType, *dwarf.IntType, *dwarf.FloatType, *dwarf.UcharType, *dwarf.UintType: 2694 s := dtype.Common().Name 2695 if s != "" { 2696 if ss, ok := dwarfToName[s]; ok { 2697 s = ss 2698 } 2699 s = strings.Replace(s, " ", "", -1) 2700 name := c.Ident("_Ctype_" + s) 2701 tt := *t 2702 typedef[name.Name] = &tt 2703 if !*godefs { 2704 t.Go = name 2705 } 2706 } 2707 } 2708 2709 if t.Size < 0 { 2710 // Unsized types are [0]byte, unless they're typedefs of other types 2711 // or structs with tags. 2712 // if so, use the name we've already defined. 2713 t.Size = 0 2714 switch dt := dtype.(type) { 2715 case *dwarf.TypedefType: 2716 // ok 2717 case *dwarf.StructType: 2718 if dt.StructName != "" { 2719 break 2720 } 2721 t.Go = c.Opaque(0) 2722 default: 2723 t.Go = c.Opaque(0) 2724 } 2725 if t.C.Empty() { 2726 t.C.Set("void") 2727 } 2728 } 2729 2730 if t.C.Empty() { 2731 fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype) 2732 } 2733 2734 return t 2735} 2736 2737// isStructUnionClass reports whether the type described by the Go syntax x 2738// is a struct, union, or class with a tag. 2739func isStructUnionClass(x ast.Expr) bool { 2740 id, ok := x.(*ast.Ident) 2741 if !ok { 2742 return false 2743 } 2744 name := id.Name 2745 return strings.HasPrefix(name, "_Ctype_struct_") || 2746 strings.HasPrefix(name, "_Ctype_union_") || 2747 strings.HasPrefix(name, "_Ctype_class_") 2748} 2749 2750// FuncArg returns a Go type with the same memory layout as 2751// dtype when used as the type of a C function argument. 2752func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type { 2753 t := c.Type(unqual(dtype), pos) 2754 switch dt := dtype.(type) { 2755 case *dwarf.ArrayType: 2756 // Arrays are passed implicitly as pointers in C. 2757 // In Go, we must be explicit. 2758 tr := &TypeRepr{} 2759 tr.Set("%s*", t.C) 2760 return &Type{ 2761 Size: c.ptrSize, 2762 Align: c.ptrSize, 2763 Go: &ast.StarExpr{X: t.Go}, 2764 C: tr, 2765 } 2766 case *dwarf.TypedefType: 2767 // C has much more relaxed rules than Go for 2768 // implicit type conversions. When the parameter 2769 // is type T defined as *X, simulate a little of the 2770 // laxness of C by making the argument *X instead of T. 2771 if ptr, ok := base(dt.Type).(*dwarf.PtrType); ok { 2772 // Unless the typedef happens to point to void* since 2773 // Go has special rules around using unsafe.Pointer. 2774 if _, void := base(ptr.Type).(*dwarf.VoidType); void { 2775 break 2776 } 2777 // ...or the typedef is one in which we expect bad pointers. 2778 // It will be a uintptr instead of *X. 2779 if c.baseBadPointerTypedef(dt) { 2780 break 2781 } 2782 2783 t = c.Type(ptr, pos) 2784 if t == nil { 2785 return nil 2786 } 2787 2788 // For a struct/union/class, remember the C spelling, 2789 // in case it has __attribute__((unavailable)). 2790 // See issue 2888. 2791 if isStructUnionClass(t.Go) { 2792 t.Typedef = dt.Name 2793 } 2794 } 2795 } 2796 return t 2797} 2798 2799// FuncType returns the Go type analogous to dtype. 2800// There is no guarantee about matching memory layout. 2801func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType { 2802 p := make([]*Type, len(dtype.ParamType)) 2803 gp := make([]*ast.Field, len(dtype.ParamType)) 2804 for i, f := range dtype.ParamType { 2805 // gcc's DWARF generator outputs a single DotDotDotType parameter for 2806 // function pointers that specify no parameters (e.g. void 2807 // (*__cgo_0)()). Treat this special case as void. This case is 2808 // invalid according to ISO C anyway (i.e. void (*__cgo_1)(...) is not 2809 // legal). 2810 if _, ok := f.(*dwarf.DotDotDotType); ok && i == 0 { 2811 p, gp = nil, nil 2812 break 2813 } 2814 p[i] = c.FuncArg(f, pos) 2815 gp[i] = &ast.Field{Type: p[i].Go} 2816 } 2817 var r *Type 2818 var gr []*ast.Field 2819 if _, ok := base(dtype.ReturnType).(*dwarf.VoidType); ok { 2820 gr = []*ast.Field{{Type: c.goVoid}} 2821 } else if dtype.ReturnType != nil { 2822 r = c.Type(unqual(dtype.ReturnType), pos) 2823 gr = []*ast.Field{{Type: r.Go}} 2824 } 2825 return &FuncType{ 2826 Params: p, 2827 Result: r, 2828 Go: &ast.FuncType{ 2829 Params: &ast.FieldList{List: gp}, 2830 Results: &ast.FieldList{List: gr}, 2831 }, 2832 } 2833} 2834 2835// Identifier 2836func (c *typeConv) Ident(s string) *ast.Ident { 2837 return ast.NewIdent(s) 2838} 2839 2840// Opaque type of n bytes. 2841func (c *typeConv) Opaque(n int64) ast.Expr { 2842 return &ast.ArrayType{ 2843 Len: c.intExpr(n), 2844 Elt: c.byte, 2845 } 2846} 2847 2848// Expr for integer n. 2849func (c *typeConv) intExpr(n int64) ast.Expr { 2850 return &ast.BasicLit{ 2851 Kind: token.INT, 2852 Value: strconv.FormatInt(n, 10), 2853 } 2854} 2855 2856// Add padding of given size to fld. 2857func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) { 2858 n := len(fld) 2859 fld = fld[0 : n+1] 2860 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)} 2861 sizes = sizes[0 : n+1] 2862 sizes[n] = size 2863 return fld, sizes 2864} 2865 2866// Struct conversion: return Go and (gc) C syntax for type. 2867func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) { 2868 // Minimum alignment for a struct is 1 byte. 2869 align = 1 2870 2871 var buf bytes.Buffer 2872 buf.WriteString("struct {") 2873 fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field 2874 sizes := make([]int64, 0, 2*len(dt.Field)+1) 2875 off := int64(0) 2876 2877 // Rename struct fields that happen to be named Go keywords into 2878 // _{keyword}. Create a map from C ident -> Go ident. The Go ident will 2879 // be mangled. Any existing identifier that already has the same name on 2880 // the C-side will cause the Go-mangled version to be prefixed with _. 2881 // (e.g. in a struct with fields '_type' and 'type', the latter would be 2882 // rendered as '__type' in Go). 2883 ident := make(map[string]string) 2884 used := make(map[string]bool) 2885 for _, f := range dt.Field { 2886 ident[f.Name] = f.Name 2887 used[f.Name] = true 2888 } 2889 2890 if !*godefs { 2891 for cid, goid := range ident { 2892 if token.Lookup(goid).IsKeyword() { 2893 // Avoid keyword 2894 goid = "_" + goid 2895 2896 // Also avoid existing fields 2897 for _, exist := used[goid]; exist; _, exist = used[goid] { 2898 goid = "_" + goid 2899 } 2900 2901 used[goid] = true 2902 ident[cid] = goid 2903 } 2904 } 2905 } 2906 2907 anon := 0 2908 for _, f := range dt.Field { 2909 name := f.Name 2910 ft := f.Type 2911 2912 // In godefs mode, if this field is a C11 2913 // anonymous union then treat the first field in the 2914 // union as the field in the struct. This handles 2915 // cases like the glibc <sys/resource.h> file; see 2916 // issue 6677. 2917 if *godefs { 2918 if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] { 2919 name = st.Field[0].Name 2920 ident[name] = name 2921 ft = st.Field[0].Type 2922 } 2923 } 2924 2925 // TODO: Handle fields that are anonymous structs by 2926 // promoting the fields of the inner struct. 2927 2928 t := c.Type(ft, pos) 2929 tgo := t.Go 2930 size := t.Size 2931 talign := t.Align 2932 if f.BitOffset > 0 || f.BitSize > 0 { 2933 // The layout of bitfields is implementation defined, 2934 // so we don't know how they correspond to Go fields 2935 // even if they are aligned at byte boundaries. 2936 continue 2937 } 2938 2939 if talign > 0 && f.ByteOffset%talign != 0 { 2940 // Drop misaligned fields, the same way we drop integer bit fields. 2941 // The goal is to make available what can be made available. 2942 // Otherwise one bad and unneeded field in an otherwise okay struct 2943 // makes the whole program not compile. Much of the time these 2944 // structs are in system headers that cannot be corrected. 2945 continue 2946 } 2947 2948 // Round off up to talign, assumed to be a power of 2. 2949 off = (off + talign - 1) &^ (talign - 1) 2950 2951 if f.ByteOffset > off { 2952 fld, sizes = c.pad(fld, sizes, f.ByteOffset-off) 2953 off = f.ByteOffset 2954 } 2955 if f.ByteOffset < off { 2956 // Drop a packed field that we can't represent. 2957 continue 2958 } 2959 2960 n := len(fld) 2961 fld = fld[0 : n+1] 2962 if name == "" { 2963 name = fmt.Sprintf("anon%d", anon) 2964 anon++ 2965 ident[name] = name 2966 } 2967 fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo} 2968 sizes = sizes[0 : n+1] 2969 sizes[n] = size 2970 off += size 2971 buf.WriteString(t.C.String()) 2972 buf.WriteString(" ") 2973 buf.WriteString(name) 2974 buf.WriteString("; ") 2975 if talign > align { 2976 align = talign 2977 } 2978 } 2979 if off < dt.ByteSize { 2980 fld, sizes = c.pad(fld, sizes, dt.ByteSize-off) 2981 off = dt.ByteSize 2982 } 2983 2984 // If the last field in a non-zero-sized struct is zero-sized 2985 // the compiler is going to pad it by one (see issue 9401). 2986 // We can't permit that, because then the size of the Go 2987 // struct will not be the same as the size of the C struct. 2988 // Our only option in such a case is to remove the field, 2989 // which means that it cannot be referenced from Go. 2990 for off > 0 && sizes[len(sizes)-1] == 0 { 2991 n := len(sizes) 2992 fld = fld[0 : n-1] 2993 sizes = sizes[0 : n-1] 2994 } 2995 2996 if off != dt.ByteSize { 2997 fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize) 2998 } 2999 buf.WriteString("}") 3000 csyntax = buf.String() 3001 3002 if *godefs { 3003 godefsFields(fld) 3004 } 3005 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} 3006 return 3007} 3008 3009// dwarfHasPointer reports whether the DWARF type dt contains a pointer. 3010func (c *typeConv) dwarfHasPointer(dt dwarf.Type, pos token.Pos) bool { 3011 switch dt := dt.(type) { 3012 default: 3013 fatalf("%s: unexpected type: %s", lineno(pos), dt) 3014 return false 3015 3016 case *dwarf.AddrType, *dwarf.BoolType, *dwarf.CharType, *dwarf.EnumType, 3017 *dwarf.FloatType, *dwarf.ComplexType, *dwarf.FuncType, 3018 *dwarf.IntType, *dwarf.UcharType, *dwarf.UintType, *dwarf.VoidType: 3019 3020 return false 3021 3022 case *dwarf.ArrayType: 3023 return c.dwarfHasPointer(dt.Type, pos) 3024 3025 case *dwarf.PtrType: 3026 return true 3027 3028 case *dwarf.QualType: 3029 return c.dwarfHasPointer(dt.Type, pos) 3030 3031 case *dwarf.StructType: 3032 for _, f := range dt.Field { 3033 if c.dwarfHasPointer(f.Type, pos) { 3034 return true 3035 } 3036 } 3037 return false 3038 3039 case *dwarf.TypedefType: 3040 if dt.Name == "_GoString_" || dt.Name == "_GoBytes_" { 3041 return true 3042 } 3043 return c.dwarfHasPointer(dt.Type, pos) 3044 } 3045} 3046 3047func upper(s string) string { 3048 if s == "" { 3049 return "" 3050 } 3051 r, size := utf8.DecodeRuneInString(s) 3052 if r == '_' { 3053 return "X" + s 3054 } 3055 return string(unicode.ToUpper(r)) + s[size:] 3056} 3057 3058// godefsFields rewrites field names for use in Go or C definitions. 3059// It strips leading common prefixes (like tv_ in tv_sec, tv_usec) 3060// converts names to upper case, and rewrites _ into Pad_godefs_n, 3061// so that all fields are exported. 3062func godefsFields(fld []*ast.Field) { 3063 prefix := fieldPrefix(fld) 3064 3065 // Issue 48396: check for duplicate field names. 3066 if prefix != "" { 3067 names := make(map[string]bool) 3068 fldLoop: 3069 for _, f := range fld { 3070 for _, n := range f.Names { 3071 name := n.Name 3072 if name == "_" { 3073 continue 3074 } 3075 if name != prefix { 3076 name = strings.TrimPrefix(n.Name, prefix) 3077 } 3078 name = upper(name) 3079 if names[name] { 3080 // Field name conflict: don't remove prefix. 3081 prefix = "" 3082 break fldLoop 3083 } 3084 names[name] = true 3085 } 3086 } 3087 } 3088 3089 npad := 0 3090 for _, f := range fld { 3091 for _, n := range f.Names { 3092 if n.Name != prefix { 3093 n.Name = strings.TrimPrefix(n.Name, prefix) 3094 } 3095 if n.Name == "_" { 3096 // Use exported name instead. 3097 n.Name = "Pad_cgo_" + strconv.Itoa(npad) 3098 npad++ 3099 } 3100 n.Name = upper(n.Name) 3101 } 3102 } 3103} 3104 3105// fieldPrefix returns the prefix that should be removed from all the 3106// field names when generating the C or Go code. For generated 3107// C, we leave the names as is (tv_sec, tv_usec), since that's what 3108// people are used to seeing in C. For generated Go code, such as 3109// package syscall's data structures, we drop a common prefix 3110// (so sec, usec, which will get turned into Sec, Usec for exporting). 3111func fieldPrefix(fld []*ast.Field) string { 3112 prefix := "" 3113 for _, f := range fld { 3114 for _, n := range f.Names { 3115 // Ignore field names that don't have the prefix we're 3116 // looking for. It is common in C headers to have fields 3117 // named, say, _pad in an otherwise prefixed header. 3118 // If the struct has 3 fields tv_sec, tv_usec, _pad1, then we 3119 // still want to remove the tv_ prefix. 3120 // The check for "orig_" here handles orig_eax in the 3121 // x86 ptrace register sets, which otherwise have all fields 3122 // with reg_ prefixes. 3123 if strings.HasPrefix(n.Name, "orig_") || strings.HasPrefix(n.Name, "_") { 3124 continue 3125 } 3126 i := strings.Index(n.Name, "_") 3127 if i < 0 { 3128 continue 3129 } 3130 if prefix == "" { 3131 prefix = n.Name[:i+1] 3132 } else if prefix != n.Name[:i+1] { 3133 return "" 3134 } 3135 } 3136 } 3137 return prefix 3138} 3139 3140// anonymousStructTypedef reports whether dt is a C typedef for an anonymous 3141// struct. 3142func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool { 3143 st, ok := dt.Type.(*dwarf.StructType) 3144 return ok && st.StructName == "" 3145} 3146 3147// badPointerTypedef reports whether dt is a C typedef that should not be 3148// considered a pointer in Go. A typedef is bad if C code sometimes stores 3149// non-pointers in this type. 3150// TODO: Currently our best solution is to find these manually and list them as 3151// they come up. A better solution is desired. 3152// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file. 3153func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool { 3154 if c.badCFType(dt) { 3155 return true 3156 } 3157 if c.badJNI(dt) { 3158 return true 3159 } 3160 if c.badEGLType(dt) { 3161 return true 3162 } 3163 return false 3164} 3165 3166// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be NotInHeap. 3167func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool { 3168 // Match the Windows HANDLE type (#42018). 3169 if goos != "windows" || dt.Name != "HANDLE" { 3170 return false 3171 } 3172 // Check that the typedef is "typedef void *<name>". 3173 if ptr, ok := dt.Type.(*dwarf.PtrType); ok { 3174 if _, ok := ptr.Type.(*dwarf.VoidType); ok { 3175 return true 3176 } 3177 } 3178 return false 3179} 3180 3181// badStructPointerTypedef is like badVoidPointerTypedefs but for structs. 3182func (c *typeConv) badStructPointerTypedef(name string, dt *dwarf.StructType) bool { 3183 // Windows handle types can all potentially contain non-pointers. 3184 // badVoidPointerTypedef handles the "void *" HANDLE type, but other 3185 // handles are defined as 3186 // 3187 // struct <name>__{int unused;}; typedef struct <name>__ *name; 3188 // 3189 // by the DECLARE_HANDLE macro in STRICT mode. The macro is declared in 3190 // the Windows ntdef.h header, 3191 // 3192 // https://github.com/tpn/winsdk-10/blob/master/Include/10.0.16299.0/shared/ntdef.h#L779 3193 if goos != "windows" { 3194 return false 3195 } 3196 if len(dt.Field) != 1 { 3197 return false 3198 } 3199 if dt.StructName != name+"__" { 3200 return false 3201 } 3202 if f := dt.Field[0]; f.Name != "unused" || f.Type.Common().Name != "int" { 3203 return false 3204 } 3205 return true 3206} 3207 3208// baseBadPointerTypedef reports whether the base of a chain of typedefs is a bad typedef 3209// as badPointerTypedef reports. 3210func (c *typeConv) baseBadPointerTypedef(dt *dwarf.TypedefType) bool { 3211 for { 3212 if t, ok := dt.Type.(*dwarf.TypedefType); ok { 3213 dt = t 3214 continue 3215 } 3216 break 3217 } 3218 return c.badPointerTypedef(dt) 3219} 3220 3221func (c *typeConv) badCFType(dt *dwarf.TypedefType) bool { 3222 // The real bad types are CFNumberRef and CFDateRef. 3223 // Sometimes non-pointers are stored in these types. 3224 // CFTypeRef is a supertype of those, so it can have bad pointers in it as well. 3225 // We return true for the other *Ref types just so casting between them is easier. 3226 // We identify the correct set of types as those ending in Ref and for which 3227 // there exists a corresponding GetTypeID function. 3228 // See comment below for details about the bad pointers. 3229 if goos != "darwin" && goos != "ios" { 3230 return false 3231 } 3232 s := dt.Name 3233 if !strings.HasSuffix(s, "Ref") { 3234 return false 3235 } 3236 s = s[:len(s)-3] 3237 if s == "CFType" { 3238 return true 3239 } 3240 if c.getTypeIDs[s] { 3241 return true 3242 } 3243 if i := strings.Index(s, "Mutable"); i >= 0 && c.getTypeIDs[s[:i]+s[i+7:]] { 3244 // Mutable and immutable variants share a type ID. 3245 return true 3246 } 3247 return false 3248} 3249 3250// Comment from Darwin's CFInternal.h 3251/* 3252// Tagged pointer support 3253// Low-bit set means tagged object, next 3 bits (currently) 3254// define the tagged object class, next 4 bits are for type 3255// information for the specific tagged object class. Thus, 3256// the low byte is for type info, and the rest of a pointer 3257// (32 or 64-bit) is for payload, whatever the tagged class. 3258// 3259// Note that the specific integers used to identify the 3260// specific tagged classes can and will change from release 3261// to release (that's why this stuff is in CF*Internal*.h), 3262// as can the definition of type info vs payload above. 3263// 3264#if __LP64__ 3265#define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1) 3266#define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF) 3267#else 3268#define CF_IS_TAGGED_OBJ(PTR) 0 3269#define CF_TAGGED_OBJ_TYPE(PTR) 0 3270#endif 3271 3272enum { 3273 kCFTaggedObjectID_Invalid = 0, 3274 kCFTaggedObjectID_Atom = (0 << 1) + 1, 3275 kCFTaggedObjectID_Undefined3 = (1 << 1) + 1, 3276 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1, 3277 kCFTaggedObjectID_Integer = (3 << 1) + 1, 3278 kCFTaggedObjectID_DateTS = (4 << 1) + 1, 3279 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data 3280 kCFTaggedObjectID_Date = (6 << 1) + 1, 3281 kCFTaggedObjectID_Undefined7 = (7 << 1) + 1, 3282}; 3283*/ 3284 3285func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool { 3286 // In Dalvik and ART, the jobject type in the JNI interface of the JVM has the 3287 // property that it is sometimes (always?) a small integer instead of a real pointer. 3288 // Note: although only the android JVMs are bad in this respect, we declare the JNI types 3289 // bad regardless of platform, so the same Go code compiles on both android and non-android. 3290 if parent, ok := jniTypes[dt.Name]; ok { 3291 // Try to make sure we're talking about a JNI type, not just some random user's 3292 // type that happens to use the same name. 3293 // C doesn't have the notion of a package, so it's hard to be certain. 3294 3295 // Walk up to jobject, checking each typedef on the way. 3296 w := dt 3297 for parent != "" { 3298 t, ok := w.Type.(*dwarf.TypedefType) 3299 if !ok || t.Name != parent { 3300 return false 3301 } 3302 w = t 3303 parent, ok = jniTypes[w.Name] 3304 if !ok { 3305 return false 3306 } 3307 } 3308 3309 // Check that the typedef is either: 3310 // 1: 3311 // struct _jobject; 3312 // typedef struct _jobject *jobject; 3313 // 2: (in NDK16 in C++) 3314 // class _jobject {}; 3315 // typedef _jobject* jobject; 3316 // 3: (in NDK16 in C) 3317 // typedef void* jobject; 3318 if ptr, ok := w.Type.(*dwarf.PtrType); ok { 3319 switch v := ptr.Type.(type) { 3320 case *dwarf.VoidType: 3321 return true 3322 case *dwarf.StructType: 3323 if v.StructName == "_jobject" && len(v.Field) == 0 { 3324 switch v.Kind { 3325 case "struct": 3326 if v.Incomplete { 3327 return true 3328 } 3329 case "class": 3330 if !v.Incomplete { 3331 return true 3332 } 3333 } 3334 } 3335 } 3336 } 3337 } 3338 return false 3339} 3340 3341func (c *typeConv) badEGLType(dt *dwarf.TypedefType) bool { 3342 if dt.Name != "EGLDisplay" && dt.Name != "EGLConfig" { 3343 return false 3344 } 3345 // Check that the typedef is "typedef void *<name>". 3346 if ptr, ok := dt.Type.(*dwarf.PtrType); ok { 3347 if _, ok := ptr.Type.(*dwarf.VoidType); ok { 3348 return true 3349 } 3350 } 3351 return false 3352} 3353 3354// jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which 3355// they are mapped. The base "jobject" maps to the empty string. 3356var jniTypes = map[string]string{ 3357 "jobject": "", 3358 "jclass": "jobject", 3359 "jthrowable": "jobject", 3360 "jstring": "jobject", 3361 "jarray": "jobject", 3362 "jbooleanArray": "jarray", 3363 "jbyteArray": "jarray", 3364 "jcharArray": "jarray", 3365 "jshortArray": "jarray", 3366 "jintArray": "jarray", 3367 "jlongArray": "jarray", 3368 "jfloatArray": "jarray", 3369 "jdoubleArray": "jarray", 3370 "jobjectArray": "jarray", 3371 "jweak": "jobject", 3372} 3373