Search code examples
linuxmips32

Why does mmap return ENODEV?


I've been trying to figure out how to do memory management in MIPS32 assembly for Linux and I've written this code that allocates 8 bytes using mmap:

.text
.global main
main:
    addi $sp, $sp, -32
    add $a0, $zero, $zero
    addi $a1, $zero, 8
    addi $a2, $zero, 1
    addi $a3, $zero, 2
    sw $zero, 16($sp)
    sw $zero, 20($sp)
    addi $v0, $zero, 4090
    syscall
    lw $a0, ($v0)
    
    add $a0, $zero, $zero
    addi $v0, $zero, 4001
    syscall

However, when I run this code in gdb, I see that the syscall always returns 0x13, which is equal to the ENODEV error on my system. According to mmap's man page, ENODEV is returned if "The underlying filesystem of the specified file does not support memory mapping". I've tried changing the value stored in 16($sp), which is where the 5th argument, the file descriptor, is stored (at least that's what I think). Here's what I'm setting the value of each argument to:

1st argument: void addr[.length] = NULL = 0

2nd argument: size_t length = 8

3rd argument: int prot = PROT_READ = 1

4th argument: int flags = MAP_PRIVATE = 2

5th argument (at 16($sp)): int fd = 0

6th argument (at 20($sp)): off_t offset = 0


Solution

  • Writing this answer for others to read.

    My mistake was that for the flags parameter, I did not use the MAP_ANONYMOUS flag. According to mmap's manpage, the MAP_ANONYMOUS flag indicates that "the mapping is not backed by any file; its contents are initialized to zero" and the fd argument will be ignored.