OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [exp/] [types/] [exportdata.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// This file implements ExportData.
6
 
7
package types
8
 
9
import (
10
        "bufio"
11
        "errors"
12
        "fmt"
13
        "io"
14
        "os"
15
        "strconv"
16
        "strings"
17
)
18
 
19
func readGopackHeader(buf *bufio.Reader) (name string, size int, err error) {
20
        // See $GOROOT/include/ar.h.
21
        hdr := make([]byte, 16+12+6+6+8+10+2)
22
        _, err = io.ReadFull(buf, hdr)
23
        if err != nil {
24
                return
25
        }
26
        if trace {
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 = errors.New("invalid archive header")
33
                return
34
        }
35
        name = strings.TrimSpace(string(hdr[:16]))
36
        return
37
}
38
 
39
type dataReader struct {
40
        *bufio.Reader
41
        io.Closer
42
}
43
 
44
// ExportData returns a readCloser positioned at the beginning of the
45
// export data section of the given object/archive file, or an error.
46
// It is the caller's responsibility to close the readCloser.
47
//
48
func ExportData(filename string) (rc io.ReadCloser, err error) {
49
        file, err := os.Open(filename)
50
        if err != nil {
51
                return
52
        }
53
 
54
        defer func() {
55
                if err != nil {
56
                        file.Close()
57
                        // Add file name to error.
58
                        err = fmt.Errorf("reading export data: %s: %v", filename, err)
59
                }
60
        }()
61
 
62
        buf := bufio.NewReader(file)
63
 
64
        // Read first line to make sure this is an object file.
65
        line, err := buf.ReadSlice('\n')
66
        if err != nil {
67
                return
68
        }
69
        if string(line) == "!\n" {
70
                // Archive file.  Scan to __.PKGDEF, which should
71
                // be second archive entry.
72
                var name string
73
                var size int
74
 
75
                // First entry should be __.SYMDEF.
76
                // Read and discard.
77
                if name, size, err = readGopackHeader(buf); err != nil {
78
                        return
79
                }
80
                if name != "__.SYMDEF" {
81
                        err = errors.New("go archive does not begin with __.SYMDEF")
82
                        return
83
                }
84
                const block = 4096
85
                tmp := make([]byte, block)
86
                for size > 0 {
87
                        n := size
88
                        if n > block {
89
                                n = block
90
                        }
91
                        _, err = io.ReadFull(buf, tmp[:n])
92
                        if err != nil {
93
                                return
94
                        }
95
                        size -= n
96
                }
97
 
98
                // Second entry should be __.PKGDEF.
99
                if name, size, err = readGopackHeader(buf); err != nil {
100
                        return
101
                }
102
                if name != "__.PKGDEF" {
103
                        err = errors.New("go archive is missing __.PKGDEF")
104
                        return
105
                }
106
 
107
                // Read first line of __.PKGDEF data, so that line
108
                // is once again the first line of the input.
109
                line, err = buf.ReadSlice('\n')
110
                if err != nil {
111
                        return
112
                }
113
        }
114
 
115
        // Now at __.PKGDEF in archive or still at beginning of file.
116
        // Either way, line should begin with "go object ".
117
        if !strings.HasPrefix(string(line), "go object ") {
118
                err = errors.New("not a go object file")
119
                return
120
        }
121
 
122
        // Skip over object header to export data.
123
        // Begins after first line with $$.
124
        for line[0] != '$' {
125
                line, err = buf.ReadSlice('\n')
126
                if err != nil {
127
                        return
128
                }
129
        }
130
 
131
        rc = &dataReader{buf, file}
132
        return
133
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.