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