@@ -83,7 +83,7 @@ func (a *allocator) init(startSize int) error {
8383 }
8484
8585 if protBE , ok := be .(malloc.ProtectedArenaBackend ); ok {
86- a .mprotect = protBE .Protect
86+ a .mprotect = mprotectHook ( protBE .Protect )
8787 } else {
8888 // No real mprotect for some reason. This shouldn't
8989 // really happen, but continue with a no-op mprotect.
@@ -127,34 +127,48 @@ func initMallocBackend() (malloc.ArenaBackend, error) {
127127 // space right before the text segment but that's not guaranteed
128128 // (particularly when buildmode=pie).
129129
130- // The minimum acceptable address is where the first
131- // instruction in the code segment can still reach the final
132- // address before end. These are unsigned so watch for wrap-around.
130+ // The minimum acceptable address is where the first instruction in the
131+ // code segment can still reach the final address before end. The
132+ // maximum address is similar. These are unsigned so watch for
133+ // wrap-around.
133134 minAddress := end - maxCloneDistance
134135 if minAddress > end || minAddress < absMinAddress {
135136 minAddress = absMinAddress
136137 }
137- for addr := text - pageSize - size ; addr >= minAddress ; addr -= 0x100000 {
138- be , err := malloc .VirtBackend (size , malloc .MmapAddr (addr ), malloc .MmapProt (mprotectExec ), malloc .MmapFlags (_MAP_FIXED_NOREPLACE ))
138+ maxAddress := text + maxCloneDistance - size
139+ if maxAddress < text {
140+ maxAddress = math .MaxUint
141+ }
142+
143+ for addr := text - pageSize - size ; addr >= minAddress ; addr -= pageSize {
144+ be , err := malloc .VirtBackend (size , malloc .MmapAddr (addr ), malloc .MmapProt (mprotectExec ), malloc .MmapFlags (_MMAP_FLAGS ))
139145 if err == nil {
140- return be , nil
146+ if be .Addr () < minAddress || be .Addr () > maxAddress {
147+ // No good, try again.
148+ be .Release ()
149+ } else {
150+ return be , nil
151+ }
141152 }
142153 }
143154
144155 // Nothing was found before the text segment, repeat the process for
145156 // the space after end.
146- maxAddress := text + maxCloneDistance - size
147- if maxAddress < text {
148- maxAddress = math .MaxUint
149- }
150- for addr := end ; addr <= maxAddress ; addr += 0x100000 {
151- be , err := malloc .VirtBackend (size , malloc .MmapAddr (addr ), malloc .MmapProt (mprotectExec ), malloc .MmapFlags (_MAP_FIXED_NOREPLACE ))
157+ for addr := end ; addr <= maxAddress ; addr += pageSize {
158+ be , err := malloc .VirtBackend (size , malloc .MmapAddr (addr ), malloc .MmapProt (mprotectExec ), malloc .MmapFlags (_MMAP_FLAGS ))
152159 if err == nil {
153- return be , nil
160+ if be .Addr () < minAddress || be .Addr () > maxAddress {
161+ // No good, try again.
162+ be .Release ()
163+ } else {
164+ return be , nil
165+ }
154166 }
155167 }
156168
157- return nil , errors .New ("no suitable virtual memory space found" )
169+ // Well, we tried. We tried really hard. There's nothing left to do but
170+ // take whatever address the OS gives us.
171+ return malloc .VirtBackend (size , malloc .MmapAddr (minAddress ), malloc .MmapProt (mprotectExec ), malloc .MmapFlags (_MMAP_FLAGS ))
158172}
159173
160174func (a * allocator ) BeginMutate () error {
0 commit comments