1
2
3
4
5
6
7
8 package ld
9
10 import (
11 "syscall"
12 )
13
14
15
16
17 func (out *OutBuf) Mmap(filesize uint64) (err error) {
18 oldlen := len(out.buf)
19 if oldlen != 0 {
20 out.munmap()
21 }
22
23 for {
24 if err = out.fallocate(filesize); err != syscall.EINTR {
25 break
26 }
27 }
28 if err != nil {
29
30
31
32 if err != syscall.ENOTSUP && err != syscall.EPERM && err != errNoFallocate {
33 return err
34 }
35 }
36 err = out.f.Truncate(int64(filesize))
37 if err != nil {
38 Exitf("resize output file failed: %v", err)
39 }
40 out.buf, err = syscall.Mmap(int(out.f.Fd()), 0, int(filesize), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED|syscall.MAP_FILE)
41 if err != nil {
42 return err
43 }
44
45
46 if uint64(oldlen+len(out.heap)) > filesize {
47 panic("mmap size too small")
48 }
49 copy(out.buf[oldlen:], out.heap)
50 out.heap = out.heap[:0]
51 return nil
52 }
53
54 func (out *OutBuf) munmap() {
55 if out.buf == nil {
56 return
57 }
58 syscall.Munmap(out.buf)
59 out.buf = nil
60 }
61
View as plain text