OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Annotate Ref in Prog with C types by parsing gcc debug output. | 5 // Annotate Ref in Prog with C types by parsing gcc debug output. |
6 // Conversion of debug output to Go types. | 6 // Conversion of debug output to Go types. |
7 | 7 |
8 package main | 8 package main |
9 | 9 |
10 import ( | 10 import ( |
11 "bytes" | 11 "bytes" |
12 "debug/dwarf" | 12 "debug/dwarf" |
13 "debug/elf" | 13 "debug/elf" |
14 "debug/macho" | 14 "debug/macho" |
15 "debug/pe" | 15 "debug/pe" |
16 "flag" | 16 "flag" |
17 "fmt" | 17 "fmt" |
18 "go/ast" | 18 "go/ast" |
19 "go/parser" | 19 "go/parser" |
20 "go/token" | 20 "go/token" |
21 "os" | 21 "os" |
22 "strconv" | 22 "strconv" |
23 "strings" | 23 "strings" |
24 ) | 24 ) |
25 | 25 |
26 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines") | 26 var debugDefine = flag.Bool("debug-define", false, "print relevant #defines") |
27 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations") | 27 var debugGcc = flag.Bool("debug-gcc", false, "print gcc invocations") |
28 | 28 |
29 var nameToC = map[string]string{ | 29 var nameToC = map[string]string{ |
30 » "schar": "signed char", | 30 » "schar": "signed char", |
31 » "uchar": "unsigned char", | 31 » "uchar": "unsigned char", |
32 » "ushort": "unsigned short", | 32 » "ushort": "unsigned short", |
33 » "uint": "unsigned int", | 33 » "uint": "unsigned int", |
34 » "ulong": "unsigned long", | 34 » "ulong": "unsigned long", |
35 » "longlong": "long long", | 35 » "longlong": "long long", |
36 » "ulonglong": "unsigned long long", | 36 » "ulonglong": "unsigned long long", |
| 37 » "complexfloat": "float complex", |
| 38 » "complexdouble": "double complex", |
37 } | 39 } |
38 | 40 |
39 // cname returns the C name to use for C.s. | 41 // cname returns the C name to use for C.s. |
40 // The expansions are listed in nameToC and also | 42 // The expansions are listed in nameToC and also |
41 // struct_foo becomes "struct foo", and similarly for | 43 // struct_foo becomes "struct foo", and similarly for |
42 // union and enum. | 44 // union and enum. |
43 func cname(s string) string { | 45 func cname(s string) string { |
44 if t, ok := nameToC[s]; ok { | 46 if t, ok := nameToC[s]; ok { |
45 return t | 47 return t |
46 } | 48 } |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 // Cache of already-translated or in-progress types. | 582 // Cache of already-translated or in-progress types. |
581 m map[dwarf.Type]*Type | 583 m map[dwarf.Type]*Type |
582 typedef map[string]ast.Expr | 584 typedef map[string]ast.Expr |
583 | 585 |
584 // Predeclared types. | 586 // Predeclared types. |
585 bool ast.Expr | 587 bool ast.Expr |
586 byte ast.Expr // denotes padding | 588 byte ast.Expr // denotes padding |
587 int8, int16, int32, int64 ast.Expr | 589 int8, int16, int32, int64 ast.Expr |
588 uint8, uint16, uint32, uint64, uintptr ast.Expr | 590 uint8, uint16, uint32, uint64, uintptr ast.Expr |
589 float32, float64 ast.Expr | 591 float32, float64 ast.Expr |
| 592 complex64, complex128 ast.Expr |
590 void ast.Expr | 593 void ast.Expr |
591 unsafePointer ast.Expr | 594 unsafePointer ast.Expr |
592 string ast.Expr | 595 string ast.Expr |
593 | 596 |
594 ptrSize int64 | 597 ptrSize int64 |
595 } | 598 } |
596 | 599 |
597 var tagGen int | 600 var tagGen int |
598 var typedef = make(map[string]ast.Expr) | 601 var typedef = make(map[string]ast.Expr) |
599 | 602 |
600 func (c *typeConv) Init(ptrSize int64) { | 603 func (c *typeConv) Init(ptrSize int64) { |
601 c.ptrSize = ptrSize | 604 c.ptrSize = ptrSize |
602 c.m = make(map[dwarf.Type]*Type) | 605 c.m = make(map[dwarf.Type]*Type) |
603 c.bool = c.Ident("bool") | 606 c.bool = c.Ident("bool") |
604 c.byte = c.Ident("byte") | 607 c.byte = c.Ident("byte") |
605 c.int8 = c.Ident("int8") | 608 c.int8 = c.Ident("int8") |
606 c.int16 = c.Ident("int16") | 609 c.int16 = c.Ident("int16") |
607 c.int32 = c.Ident("int32") | 610 c.int32 = c.Ident("int32") |
608 c.int64 = c.Ident("int64") | 611 c.int64 = c.Ident("int64") |
609 c.uint8 = c.Ident("uint8") | 612 c.uint8 = c.Ident("uint8") |
610 c.uint16 = c.Ident("uint16") | 613 c.uint16 = c.Ident("uint16") |
611 c.uint32 = c.Ident("uint32") | 614 c.uint32 = c.Ident("uint32") |
612 c.uint64 = c.Ident("uint64") | 615 c.uint64 = c.Ident("uint64") |
613 c.uintptr = c.Ident("uintptr") | 616 c.uintptr = c.Ident("uintptr") |
614 c.float32 = c.Ident("float32") | 617 c.float32 = c.Ident("float32") |
615 c.float64 = c.Ident("float64") | 618 c.float64 = c.Ident("float64") |
| 619 c.complex64 = c.Ident("complex64") |
| 620 c.complex128 = c.Ident("complex128") |
616 c.unsafePointer = c.Ident("unsafe.Pointer") | 621 c.unsafePointer = c.Ident("unsafe.Pointer") |
617 c.void = c.Ident("void") | 622 c.void = c.Ident("void") |
618 c.string = c.Ident("string") | 623 c.string = c.Ident("string") |
619 } | 624 } |
620 | 625 |
621 // base strips away qualifiers and typedefs to get the underlying type | 626 // base strips away qualifiers and typedefs to get the underlying type |
622 func base(dt dwarf.Type) dwarf.Type { | 627 func base(dt dwarf.Type) dwarf.Type { |
623 for { | 628 for { |
624 if d, ok := dt.(*dwarf.QualType); ok { | 629 if d, ok := dt.(*dwarf.QualType); ok { |
625 dt = d.Type | 630 dt = d.Type |
(...skipping 11 matching lines...) Expand all Loading... |
637 // Map from dwarf text names to aliases we use in package "C". | 642 // Map from dwarf text names to aliases we use in package "C". |
638 var dwarfToName = map[string]string{ | 643 var dwarfToName = map[string]string{ |
639 "long int": "long", | 644 "long int": "long", |
640 "long unsigned int": "ulong", | 645 "long unsigned int": "ulong", |
641 "unsigned int": "uint", | 646 "unsigned int": "uint", |
642 "short unsigned int": "ushort", | 647 "short unsigned int": "ushort", |
643 "short int": "short", | 648 "short int": "short", |
644 "long long int": "longlong", | 649 "long long int": "longlong", |
645 "long long unsigned int": "ulonglong", | 650 "long long unsigned int": "ulonglong", |
646 "signed char": "schar", | 651 "signed char": "schar", |
| 652 "float complex": "complexfloat", |
| 653 "double complex": "complexdouble", |
647 } | 654 } |
648 | 655 |
649 // Type returns a *Type with the same memory layout as | 656 // Type returns a *Type with the same memory layout as |
650 // dtype when used as the type of a variable or a struct field. | 657 // dtype when used as the type of a variable or a struct field. |
651 func (c *typeConv) Type(dtype dwarf.Type) *Type { | 658 func (c *typeConv) Type(dtype dwarf.Type) *Type { |
652 if t, ok := c.m[dtype]; ok { | 659 if t, ok := c.m[dtype]; ok { |
653 if t.Go == nil { | 660 if t.Go == nil { |
654 fatal("type conversion loop at %s", dtype) | 661 fatal("type conversion loop at %s", dtype) |
655 } | 662 } |
656 return t | 663 return t |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 fatal("unexpected: %d-byte float type - %s", t.Size, dty
pe) | 745 fatal("unexpected: %d-byte float type - %s", t.Size, dty
pe) |
739 case 4: | 746 case 4: |
740 t.Go = c.float32 | 747 t.Go = c.float32 |
741 case 8: | 748 case 8: |
742 t.Go = c.float64 | 749 t.Go = c.float64 |
743 } | 750 } |
744 if t.Align = t.Size; t.Align >= c.ptrSize { | 751 if t.Align = t.Size; t.Align >= c.ptrSize { |
745 t.Align = c.ptrSize | 752 t.Align = c.ptrSize |
746 } | 753 } |
747 | 754 |
| 755 case *dwarf.ComplexType: |
| 756 switch t.Size { |
| 757 default: |
| 758 fatal("unexpected: %d-byte complex type - %s", t.Size, d
type) |
| 759 case 8: |
| 760 t.Go = c.complex64 |
| 761 case 16: |
| 762 t.Go = c.complex128 |
| 763 } |
| 764 if t.Align = t.Size; t.Align >= c.ptrSize { |
| 765 t.Align = c.ptrSize |
| 766 } |
| 767 |
748 case *dwarf.FuncType: | 768 case *dwarf.FuncType: |
749 // No attempt at translation: would enable calls | 769 // No attempt at translation: would enable calls |
750 // directly between worlds, but we need to moderate those. | 770 // directly between worlds, but we need to moderate those. |
751 t.Go = c.uintptr | 771 t.Go = c.uintptr |
752 t.Align = c.ptrSize | 772 t.Align = c.ptrSize |
753 | 773 |
754 case *dwarf.IntType: | 774 case *dwarf.IntType: |
755 if dt.BitSize > 0 { | 775 if dt.BitSize > 0 { |
756 fatal("unexpected: %d-bit int type - %s", dt.BitSize, dt
ype) | 776 fatal("unexpected: %d-bit int type - %s", dt.BitSize, dt
ype) |
757 } | 777 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 off = dt.ByteSize | 1067 off = dt.ByteSize |
1048 } | 1068 } |
1049 if off != dt.ByteSize { | 1069 if off != dt.ByteSize { |
1050 fatal("struct size calculation error") | 1070 fatal("struct size calculation error") |
1051 } | 1071 } |
1052 buf.WriteString("}") | 1072 buf.WriteString("}") |
1053 csyntax = buf.String() | 1073 csyntax = buf.String() |
1054 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} | 1074 expr = &ast.StructType{Fields: &ast.FieldList{List: fld}} |
1055 return | 1075 return |
1056 } | 1076 } |
OLD | NEW |