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