commit
0e7461d4a3
|
@ -2256,6 +2256,7 @@ pub fn attachSegfaultHandler() void {
|
|||
|
||||
os.sigaction(os.SIGSEGV, &act, null);
|
||||
os.sigaction(os.SIGILL, &act, null);
|
||||
os.sigaction(os.SIGBUS, &act, null);
|
||||
}
|
||||
|
||||
fn resetSegfaultHandler() void {
|
||||
|
@ -2273,6 +2274,7 @@ fn resetSegfaultHandler() void {
|
|||
};
|
||||
os.sigaction(os.SIGSEGV, &act, null);
|
||||
os.sigaction(os.SIGILL, &act, null);
|
||||
os.sigaction(os.SIGBUS, &act, null);
|
||||
}
|
||||
|
||||
fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_void) callconv(.C) noreturn {
|
||||
|
@ -2285,6 +2287,7 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_vo
|
|||
switch (sig) {
|
||||
os.SIGSEGV => std.debug.warn("Segmentation fault at address 0x{x}\n", .{addr}),
|
||||
os.SIGILL => std.debug.warn("Illegal instruction at address 0x{x}\n", .{addr}),
|
||||
os.SIGBUS => std.debug.warn("Bus error at address 0x{x}\n", .{addr}),
|
||||
else => unreachable,
|
||||
}
|
||||
switch (builtin.arch) {
|
||||
|
|
|
@ -72,11 +72,17 @@ pub fn syscall6(
|
|||
arg5: usize,
|
||||
arg6: usize,
|
||||
) usize {
|
||||
// The 6th argument is passed via memory as we're out of registers if ebp is
|
||||
// used as frame pointer. We push arg6 value on the stack before changing
|
||||
// ebp or esp as the compiler may reference it as an offset relative to one
|
||||
// of those two registers.
|
||||
return asm volatile (
|
||||
\\ push %[arg6]
|
||||
\\ push %%ebp
|
||||
\\ mov %[arg6], %%ebp
|
||||
\\ mov 4(%%esp), %%ebp
|
||||
\\ int $0x80
|
||||
\\ pop %%ebp
|
||||
\\ add $4, %%esp
|
||||
: [ret] "={eax}" (-> usize)
|
||||
: [number] "{eax}" (number),
|
||||
[arg1] "{ebx}" (arg1),
|
||||
|
|
|
@ -256,3 +256,101 @@ test "memfd_create" {
|
|||
expect(bytes_read == 4);
|
||||
expect(mem.eql(u8, buf[0..4], "test"));
|
||||
}
|
||||
|
||||
test "mmap" {
|
||||
if (builtin.os == .windows)
|
||||
return error.SkipZigTest;
|
||||
|
||||
// Simple mmap() call with non page-aligned size
|
||||
{
|
||||
const data = try os.mmap(
|
||||
null,
|
||||
1234,
|
||||
os.PROT_READ | os.PROT_WRITE,
|
||||
os.MAP_ANONYMOUS | os.MAP_PRIVATE,
|
||||
-1,
|
||||
0,
|
||||
);
|
||||
defer os.munmap(data);
|
||||
|
||||
testing.expectEqual(@as(usize, 1234), data.len);
|
||||
|
||||
// By definition the data returned by mmap is zero-filled
|
||||
std.mem.set(u8, data[0 .. data.len - 1], 0x55);
|
||||
testing.expect(mem.indexOfScalar(u8, data, 0).? == 1234 - 1);
|
||||
}
|
||||
|
||||
const test_out_file = "os_tmp_test";
|
||||
// Must be a multiple of 4096 so that the test works with mmap2
|
||||
const alloc_size = 8 * 4096;
|
||||
|
||||
// Create a file used for testing mmap() calls with a file descriptor
|
||||
{
|
||||
const file = try fs.cwd().createFile(test_out_file, .{});
|
||||
defer file.close();
|
||||
|
||||
var out_stream = file.outStream();
|
||||
const stream = &out_stream.stream;
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < alloc_size / @sizeOf(u32)) : (i += 1) {
|
||||
try stream.writeIntNative(u32, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Map the whole file
|
||||
{
|
||||
const file = try fs.cwd().createFile(test_out_file, .{
|
||||
.read = true,
|
||||
.truncate = false,
|
||||
});
|
||||
defer file.close();
|
||||
|
||||
const data = try os.mmap(
|
||||
null,
|
||||
alloc_size,
|
||||
os.PROT_READ,
|
||||
os.MAP_PRIVATE,
|
||||
file.handle,
|
||||
0,
|
||||
);
|
||||
defer os.munmap(data);
|
||||
|
||||
var mem_stream = io.SliceInStream.init(data);
|
||||
const stream = &mem_stream.stream;
|
||||
|
||||
var i: u32 = 0;
|
||||
while (i < alloc_size / @sizeOf(u32)) : (i += 1) {
|
||||
testing.expectEqual(i, try stream.readIntNative(u32));
|
||||
}
|
||||
}
|
||||
|
||||
// Map the upper half of the file
|
||||
{
|
||||
const file = try fs.cwd().createFile(test_out_file, .{
|
||||
.read = true,
|
||||
.truncate = false,
|
||||
});
|
||||
defer file.close();
|
||||
|
||||
const data = try os.mmap(
|
||||
null,
|
||||
alloc_size,
|
||||
os.PROT_READ,
|
||||
os.MAP_PRIVATE,
|
||||
file.handle,
|
||||
alloc_size / 2,
|
||||
);
|
||||
defer os.munmap(data);
|
||||
|
||||
var mem_stream = io.SliceInStream.init(data);
|
||||
const stream = &mem_stream.stream;
|
||||
|
||||
var i: u32 = alloc_size / 2 / @sizeOf(u32);
|
||||
while (i < alloc_size / @sizeOf(u32)) : (i += 1) {
|
||||
testing.expectEqual(i, try stream.readIntNative(u32));
|
||||
}
|
||||
}
|
||||
|
||||
try fs.cwd().deleteFile(test_out_file);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue