github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/cmd/link/internal/ld/outbuf.go (about) 1 // Copyright 2017 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 package ld 6 7 import ( 8 "github.com/shogo82148/std/cmd/internal/sys" 9 "github.com/shogo82148/std/cmd/link/internal/loader" 10 "github.com/shogo82148/std/os" 11 ) 12 13 // OutBuf is a buffered file writer. 14 // 15 // It is similar to the Writer in cmd/internal/bio with a few small differences. 16 // 17 // First, it tracks the output architecture and uses it to provide 18 // endian helpers. 19 // 20 // Second, it provides a very cheap offset counter that doesn't require 21 // any system calls to read the value. 22 // 23 // Third, it also mmaps the output file (if available). The intended usage is: 24 // - Mmap the output file 25 // - Write the content 26 // - possibly apply any edits in the output buffer 27 // - possibly write more content to the file. These writes take place in a heap 28 // backed buffer that will get synced to disk. 29 // - Munmap the output file 30 // 31 // And finally, it provides a mechanism by which you can multithread the 32 // writing of output files. This mechanism is accomplished by copying a OutBuf, 33 // and using it in the thread/goroutine. 34 // 35 // Parallel OutBuf is intended to be used like: 36 // 37 // func write(out *OutBuf) { 38 // var wg sync.WaitGroup 39 // for i := 0; i < 10; i++ { 40 // wg.Add(1) 41 // view, err := out.View(start[i]) 42 // if err != nil { 43 // // handle output 44 // continue 45 // } 46 // go func(out *OutBuf, i int) { 47 // // do output 48 // wg.Done() 49 // }(view, i) 50 // } 51 // wg.Wait() 52 // } 53 type OutBuf struct { 54 arch *sys.Arch 55 off int64 56 57 buf []byte 58 heap []byte 59 60 name string 61 f *os.File 62 encbuf [8]byte 63 isView bool 64 } 65 66 func (out *OutBuf) Open(name string) error 67 68 func NewOutBuf(arch *sys.Arch) *OutBuf 69 70 func (out *OutBuf) View(start uint64) (*OutBuf, error) 71 72 func (out *OutBuf) Close() error 73 74 // ErrorClose closes the output file (if any). 75 // It is supposed to be called only at exit on error, so it doesn't do 76 // any clean up or buffer flushing, just closes the file. 77 func (out *OutBuf) ErrorClose() 78 79 // Data returns the whole written OutBuf as a byte slice. 80 func (out *OutBuf) Data() []byte 81 82 func (out *OutBuf) SeekSet(p int64) 83 84 func (out *OutBuf) Offset() int64 85 86 // Write writes the contents of v to the buffer. 87 func (out *OutBuf) Write(v []byte) (int, error) 88 89 func (out *OutBuf) Write8(v uint8) 90 91 // WriteByte is an alias for Write8 to fulfill the io.ByteWriter interface. 92 func (out *OutBuf) WriteByte(v byte) error 93 94 func (out *OutBuf) Write16(v uint16) 95 96 func (out *OutBuf) Write32(v uint32) 97 98 func (out *OutBuf) Write32b(v uint32) 99 100 func (out *OutBuf) Write64(v uint64) 101 102 func (out *OutBuf) Write64b(v uint64) 103 104 func (out *OutBuf) WriteString(s string) 105 106 // WriteStringN writes the first n bytes of s. 107 // If n is larger than len(s) then it is padded with zero bytes. 108 func (out *OutBuf) WriteStringN(s string, n int) 109 110 // WriteStringPad writes the first n bytes of s. 111 // If n is larger than len(s) then it is padded with the bytes in pad (repeated as needed). 112 func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) 113 114 // WriteSym writes the content of a Symbol, and returns the output buffer 115 // that we just wrote, so we can apply further edit to the symbol content. 116 // For generator symbols, it also sets the symbol's Data to the output 117 // buffer. 118 func (out *OutBuf) WriteSym(ldr *loader.Loader, s loader.Sym) []byte