1
2
3
4
5
6
7 package gcimporter
8
9 import (
10 "bufio"
11 "fmt"
12 "io"
13 "strconv"
14 "strings"
15 )
16
17 func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
18
19 hdr := make([]byte, 16+12+6+6+8+10+2)
20 _, err = io.ReadFull(r, hdr)
21 if err != nil {
22 return
23 }
24
25 if false {
26 fmt.Printf("header: %s", hdr)
27 }
28 s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
29 size, err = strconv.Atoi(s)
30 if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
31 err = fmt.Errorf("invalid archive header")
32 return
33 }
34 name = strings.TrimSpace(string(hdr[:16]))
35 return
36 }
37
38
39
40
41
42
43
44 func FindExportData(r *bufio.Reader) (hdr string, err error) {
45
46 line, err := r.ReadSlice('\n')
47 if err != nil {
48 err = fmt.Errorf("can't find export data (%v)", err)
49 return
50 }
51
52 if string(line) == "!<arch>\n" {
53
54 var name string
55 if name, _, err = readGopackHeader(r); err != nil {
56 return
57 }
58
59
60 if name != "__.PKGDEF" {
61 err = fmt.Errorf("go archive is missing __.PKGDEF")
62 return
63 }
64
65
66
67 if line, err = r.ReadSlice('\n'); err != nil {
68 err = fmt.Errorf("can't find export data (%v)", err)
69 return
70 }
71 }
72
73
74
75 if !strings.HasPrefix(string(line), "go object ") {
76 err = fmt.Errorf("not a Go object file")
77 return
78 }
79
80
81
82 for line[0] != '$' {
83 if line, err = r.ReadSlice('\n'); err != nil {
84 err = fmt.Errorf("can't find export data (%v)", err)
85 return
86 }
87 }
88 hdr = string(line)
89
90 return
91 }
92
View as plain text