| ... | ... | @@ -292,32 +292,69 @@ pub const Thread = struct { |
| 292 | 292 | l += tls_img.alloc_size; |
| 293 | 293 | } |
| 294 | 294 | } |
| 295 | | break :blk l; |
| 295 | // Round the size to the page size. |
| 296 | break :blk mem.alignForward(l, mem.page_size); |
| 296 | 297 | }; |
| 297 | | // Map the whole stack with no rw permissions to avoid committing the |
| 298 | | // whole region right away |
| 299 | | const mmap_slice = os.mmap( |
| 300 | | null, |
| 301 | | mem.alignForward(mmap_len, mem.page_size), |
| 302 | | os.PROT_NONE, |
| 303 | | os.MAP_PRIVATE | os.MAP_ANONYMOUS, |
| 304 | | -1, |
| 305 | | 0, |
| 306 | | ) catch |err| switch (err) { |
| 307 | | error.MemoryMappingNotSupported => unreachable, |
| 308 | | error.AccessDenied => unreachable, |
| 309 | | error.PermissionDenied => unreachable, |
| 310 | | else => |e| return e, |
| 311 | | }; |
| 312 | | errdefer os.munmap(mmap_slice); |
| 313 | | |
| 314 | | // Map everything but the guard page as rw |
| 315 | | os.mprotect( |
| 316 | | mmap_slice, |
| 317 | | os.PROT_READ | os.PROT_WRITE, |
| 318 | | ) catch |err| switch (err) { |
| 319 | | error.AccessDenied => unreachable, |
| 320 | | else => |e| return e, |
| 298 | |
| 299 | const mmap_slice = mem: { |
| 300 | if (std.Target.current.os.tag != .netbsd) { |
| 301 | // Map the whole stack with no rw permissions to avoid |
| 302 | // committing the whole region right away |
| 303 | const mmap_slice = os.mmap( |
| 304 | null, |
| 305 | mmap_len, |
| 306 | os.PROT_NONE, |
| 307 | os.MAP_PRIVATE | os.MAP_ANONYMOUS, |
| 308 | -1, |
| 309 | 0, |
| 310 | ) catch |err| switch (err) { |
| 311 | error.MemoryMappingNotSupported => unreachable, |
| 312 | error.AccessDenied => unreachable, |
| 313 | error.PermissionDenied => unreachable, |
| 314 | else => |e| return e, |
| 315 | }; |
| 316 | errdefer os.munmap(mmap_slice); |
| 317 | |
| 318 | // Map everything but the guard page as rw |
| 319 | os.mprotect( |
| 320 | mmap_slice[guard_end_offset..], |
| 321 | os.PROT_READ | os.PROT_WRITE, |
| 322 | ) catch |err| switch (err) { |
| 323 | error.AccessDenied => unreachable, |
| 324 | else => |e| return e, |
| 325 | }; |
| 326 | |
| 327 | break :mem mmap_slice; |
| 328 | } else { |
| 329 | // NetBSD mprotect is very strict and doesn't allow to "upgrade" |
| 330 | // a PROT_NONE mapping to a RW one so let's allocate everything |
| 331 | // right away |
| 332 | const mmap_slice = os.mmap( |
| 333 | null, |
| 334 | mmap_len, |
| 335 | os.PROT_READ | os.PROT_WRITE, |
| 336 | os.MAP_PRIVATE | os.MAP_ANONYMOUS, |
| 337 | -1, |
| 338 | 0, |
| 339 | ) catch |err| switch (err) { |
| 340 | error.MemoryMappingNotSupported => unreachable, |
| 341 | error.AccessDenied => unreachable, |
| 342 | error.PermissionDenied => unreachable, |
| 343 | else => |e| return e, |
| 344 | }; |
| 345 | errdefer os.munmap(mmap_slice); |
| 346 | |
| 347 | // Remap the guard page with no permissions |
| 348 | os.mprotect( |
| 349 | mmap_slice[0..guard_end_offset], |
| 350 | os.PROT_NONE, |
| 351 | ) catch |err| switch (err) { |
| 352 | error.AccessDenied => unreachable, |
| 353 | else => |e| return e, |
| 354 | }; |
| 355 | |
| 356 | break :mem mmap_slice; |
| 357 | } |
| 321 | 358 | }; |
| 322 | 359 | |
| 323 | 360 | const mmap_addr = @ptrToInt(mmap_slice.ptr); |