...
1
2
3
4
5
6
7
8
9
10
11 package gccgoexportdata
12
13
14
15
16 import (
17 "bytes"
18 "debug/elf"
19 "fmt"
20 "go/token"
21 "go/types"
22 "io"
23 "io/ioutil"
24 "strconv"
25 "strings"
26
27 "golang.org/x/tools/go/internal/gccgoimporter"
28 )
29
30
31
32
33
34
35 func CompilerInfo(gccgo string, args ...string) (version, triple string, dirs []string, err error) {
36 var inst gccgoimporter.GccgoInstallation
37 err = inst.InitFromDriver(gccgo, args...)
38 if err == nil {
39 version = inst.GccVersion
40 triple = inst.TargetTriple
41 dirs = inst.SearchPaths()
42 }
43 return
44 }
45
46
47
48 func NewReader(r io.Reader) (io.Reader, error) {
49 data, err := ioutil.ReadAll(r)
50 if err != nil {
51 return nil, err
52 }
53
54
55 const archiveMagic = "!<arch>\n"
56 if bytes.HasPrefix(data, []byte(archiveMagic)) {
57 section, err := firstSection(data[len(archiveMagic):])
58 if err != nil {
59 return nil, err
60 }
61 data = section
62 }
63
64
65
66 ef, err := elf.NewFile(bytes.NewReader(data))
67 if err != nil {
68 return nil, err
69 }
70 sec := ef.Section(".go_export")
71 if sec == nil {
72 return nil, fmt.Errorf("no .go_export section")
73 }
74 return sec.Open(), nil
75 }
76
77
78
79 func firstSection(a []byte) ([]byte, error) {
80 for len(a) >= 60 {
81 var hdr []byte
82 hdr, a = a[:60], a[60:]
83
84 name := strings.TrimSpace(string(hdr[:16]))
85
86 sizeStr := string(hdr[48:58])
87 size, err := strconv.Atoi(strings.TrimSpace(sizeStr))
88 if err != nil {
89 return nil, fmt.Errorf("invalid size: %q", sizeStr)
90 }
91
92 if len(a) < size {
93 return nil, fmt.Errorf("invalid section size: %d", size)
94 }
95
96
97 var payload []byte
98 payload, a = a[:size], a[size+size&1:]
99
100
101
102
103
104 if name == "/" || name == "/SYM64/" || name == "//" {
105 continue
106 }
107
108 return payload, nil
109 }
110 return nil, fmt.Errorf("archive has no regular sections")
111 }
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 func Read(in io.Reader, _ *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) {
128 return gccgoimporter.Parse(in, imports, path)
129 }
130
View as plain text