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