LEFT | RIGHT |
(no file at all) | |
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 ( |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 pos := token.NoPos | 609 pos := token.NoPos |
610 if ref, ok := nameToRef[n]; ok { | 610 if ref, ok := nameToRef[n]; ok { |
611 pos = ref.Pos() | 611 pos = ref.Pos() |
612 } | 612 } |
613 f, fok := types[i].(*dwarf.FuncType) | 613 f, fok := types[i].(*dwarf.FuncType) |
614 if n.Kind != "type" && fok { | 614 if n.Kind != "type" && fok { |
615 n.Kind = "func" | 615 n.Kind = "func" |
616 n.FuncType = conv.FuncType(f, pos) | 616 n.FuncType = conv.FuncType(f, pos) |
617 } else { | 617 } else { |
618 n.Type = conv.Type(types[i], pos) | 618 n.Type = conv.Type(types[i], pos) |
619 » » » if enums[i] != 0 && n.Type.EnumValues != nil { | 619 » » » // Prefer debug data over DWARF debug output, if we have
it. |
| 620 » » » if n.Kind == "const" && i < len(enumVal) { |
| 621 » » » » n.Const = fmt.Sprintf("%#x", enumVal[i]) |
| 622 » » » } else if enums[i] != 0 && n.Type.EnumValues != nil { |
620 k := fmt.Sprintf("__cgo_enum__%d", i) | 623 k := fmt.Sprintf("__cgo_enum__%d", i) |
621 n.Kind = "const" | 624 n.Kind = "const" |
622 n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k
]) | 625 n.Const = fmt.Sprintf("%#x", n.Type.EnumValues[k
]) |
623 // Remove injected enum to ensure the value will
deep-compare | 626 // Remove injected enum to ensure the value will
deep-compare |
624 // equally in future loads of the same constant. | 627 // equally in future loads of the same constant. |
625 delete(n.Type.EnumValues, k) | 628 delete(n.Type.EnumValues, k) |
626 } else if n.Kind == "const" && i < len(enumVal) { | |
627 n.Const = fmt.Sprintf("%#x", enumVal[i]) | |
628 } | 629 } |
629 } | 630 } |
630 } | 631 } |
631 | 632 |
632 } | 633 } |
633 | 634 |
634 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the | 635 // rewriteRef rewrites all the C.xxx references in f.AST to refer to the |
635 // Go equivalents, now that we have figured out the meaning of all | 636 // Go equivalents, now that we have figured out the meaning of all |
636 // the xxx. In *godefs or *cdefs mode, rewriteRef replaces the names | 637 // the xxx. In *godefs or *cdefs mode, rewriteRef replaces the names |
637 // with full definitions instead of mangled names. | 638 // with full definitions instead of mangled names. |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 data = sdat[s.Va
lue-sect.Addr:] | 796 data = sdat[s.Va
lue-sect.Addr:] |
796 } | 797 } |
797 } | 798 } |
798 } | 799 } |
799 } | 800 } |
800 } | 801 } |
801 } | 802 } |
802 return d, f.ByteOrder, data | 803 return d, f.ByteOrder, data |
803 } | 804 } |
804 | 805 |
805 // Can skip debug data block in ELF and PE for now. | |
806 // The DWARF information is complete. | |
807 | |
808 if f, err := elf.Open(gccTmp()); err == nil { | 806 if f, err := elf.Open(gccTmp()); err == nil { |
809 d, err := f.DWARF() | 807 d, err := f.DWARF() |
810 if err != nil { | 808 if err != nil { |
811 fatalf("cannot load DWARF output from %s: %v", gccTmp(),
err) | 809 fatalf("cannot load DWARF output from %s: %v", gccTmp(),
err) |
812 } | 810 } |
813 » » return d, f.ByteOrder, nil | 811 » » var data []byte |
814 » } | 812 » » symtab, err := f.Symbols() |
| 813 » » if err == nil { |
| 814 » » » for i := range symtab { |
| 815 » » » » s := &symtab[i] |
| 816 » » » » if s.Name == "__cgodebug_data" { |
| 817 » » » » » // Found it. Now find data section. |
| 818 » » » » » if i := int(s.Section); 0 <= i && i < le
n(f.Sections) { |
| 819 » » » » » » sect := f.Sections[i] |
| 820 » » » » » » if sect.Addr <= s.Value && s.Val
ue < sect.Addr+sect.Size { |
| 821 » » » » » » » if sdat, err := sect.Dat
a(); err == nil { |
| 822 » » » » » » » » data = sdat[s.Va
lue-sect.Addr:] |
| 823 » » » » » » » } |
| 824 » » » » » » } |
| 825 » » » » » } |
| 826 » » » » } |
| 827 » » » } |
| 828 » » } |
| 829 » » return d, f.ByteOrder, data |
| 830 » } |
| 831 |
| 832 » // Can skip debug data block in PE for now. |
| 833 » // The DWARF information is complete. |
815 | 834 |
816 if f, err := pe.Open(gccTmp()); err == nil { | 835 if f, err := pe.Open(gccTmp()); err == nil { |
817 d, err := f.DWARF() | 836 d, err := f.DWARF() |
818 if err != nil { | 837 if err != nil { |
819 fatalf("cannot load DWARF output from %s: %v", gccTmp(),
err) | 838 fatalf("cannot load DWARF output from %s: %v", gccTmp(),
err) |
820 } | 839 } |
821 return d, binary.LittleEndian, nil | 840 return d, binary.LittleEndian, nil |
822 } | 841 } |
823 | 842 |
824 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) | 843 fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp()) |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1558 } | 1577 } |
1559 if prefix == "" { | 1578 if prefix == "" { |
1560 prefix = n.Name[:i+1] | 1579 prefix = n.Name[:i+1] |
1561 } else if prefix != n.Name[:i+1] { | 1580 } else if prefix != n.Name[:i+1] { |
1562 return "" | 1581 return "" |
1563 } | 1582 } |
1564 } | 1583 } |
1565 } | 1584 } |
1566 return prefix | 1585 return prefix |
1567 } | 1586 } |
LEFT | RIGHT |