...
Source file src/pkg/cmd/link/internal/ld/outbuf.go
1
2
3
4
5 package ld
6
7 import (
8 "bufio"
9 "cmd/internal/sys"
10 "cmd/link/internal/sym"
11 "encoding/binary"
12 "log"
13 "os"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 type OutBuf struct {
33 arch *sys.Arch
34 off int64
35 w *bufio.Writer
36 buf []byte
37 f *os.File
38 encbuf [8]byte
39 }
40
41 func (out *OutBuf) SeekSet(p int64) {
42 if p == out.off {
43 return
44 }
45 if out.buf == nil {
46 out.Flush()
47 if _, err := out.f.Seek(p, 0); err != nil {
48 Exitf("seeking to %d in %s: %v", p, out.f.Name(), err)
49 }
50 }
51 out.off = p
52 }
53
54 func (out *OutBuf) Offset() int64 {
55 return out.off
56 }
57
58
59
60
61
62
63 func (out *OutBuf) Write(v []byte) (int, error) {
64 if out.buf != nil {
65 n := copy(out.buf[out.off:], v)
66 out.off += int64(n)
67 return n, nil
68 }
69 n, err := out.w.Write(v)
70 out.off += int64(n)
71 return n, err
72 }
73
74 func (out *OutBuf) Write8(v uint8) {
75 if out.buf != nil {
76 out.buf[out.off] = v
77 out.off++
78 return
79 }
80 if err := out.w.WriteByte(v); err == nil {
81 out.off++
82 }
83 }
84
85
86 func (out *OutBuf) WriteByte(v byte) error {
87 out.Write8(v)
88 return nil
89 }
90
91 func (out *OutBuf) Write16(v uint16) {
92 out.arch.ByteOrder.PutUint16(out.encbuf[:], v)
93 out.Write(out.encbuf[:2])
94 }
95
96 func (out *OutBuf) Write32(v uint32) {
97 out.arch.ByteOrder.PutUint32(out.encbuf[:], v)
98 out.Write(out.encbuf[:4])
99 }
100
101 func (out *OutBuf) Write32b(v uint32) {
102 binary.BigEndian.PutUint32(out.encbuf[:], v)
103 out.Write(out.encbuf[:4])
104 }
105
106 func (out *OutBuf) Write64(v uint64) {
107 out.arch.ByteOrder.PutUint64(out.encbuf[:], v)
108 out.Write(out.encbuf[:8])
109 }
110
111 func (out *OutBuf) Write64b(v uint64) {
112 binary.BigEndian.PutUint64(out.encbuf[:], v)
113 out.Write(out.encbuf[:8])
114 }
115
116 func (out *OutBuf) WriteString(s string) {
117 if out.buf != nil {
118 n := copy(out.buf[out.off:], s)
119 if n != len(s) {
120 log.Fatalf("WriteString truncated. buffer size: %d, offset: %d, len(s)=%d", len(out.buf), out.off, len(s))
121 }
122 out.off += int64(n)
123 return
124 }
125 n, _ := out.w.WriteString(s)
126 out.off += int64(n)
127 }
128
129
130
131 func (out *OutBuf) WriteStringN(s string, n int) {
132 out.WriteStringPad(s, n, zeros[:])
133 }
134
135
136
137 func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) {
138 if len(s) >= n {
139 out.WriteString(s[:n])
140 } else {
141 out.WriteString(s)
142 n -= len(s)
143 for n > len(pad) {
144 out.Write(pad)
145 n -= len(pad)
146
147 }
148 out.Write(pad[:n])
149 }
150 }
151
152
153
154
155
156 func (out *OutBuf) WriteSym(s *sym.Symbol) {
157 if out.buf != nil {
158 start := out.off
159 out.Write(s.P)
160 s.P = out.buf[start:out.off]
161 s.Attr.Set(sym.AttrReadOnly, false)
162 } else {
163 out.Write(s.P)
164 }
165 }
166
167 func (out *OutBuf) Flush() {
168 var err error
169 if out.buf != nil {
170 err = out.Msync()
171 } else {
172 err = out.w.Flush()
173 }
174 if err != nil {
175 Exitf("flushing %s: %v", out.f.Name(), err)
176 }
177 }
178
View as plain text