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