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