Skip to content

Commit

Permalink
Make munmap() actually work. (#198)
Browse files Browse the repository at this point in the history
Before this commit, he header of a mapped area, `struct map`, was
defined as follows:

    struct map {
        int prot;
        int flags;
        off_t offset;
        size_t length;
        char body[];
    };

Because the size and alignment of an `off_t` is 8 bytes, the entire
structure was padded to 24 bytes. However, the offset of `body` into
`struct map` was only 20 bytes. Therefore the code in mmap() and
munmap() did not agree on the offset from header to body.

This commit changes mmap() to skip the entire header, which is what
munmap() expects and what the size calculation uses.
  • Loading branch information
whitequark authored May 26, 2020
1 parent 86550c3 commit 9b9d243
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions libc-bottom-half/mman/mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ struct map {
int flags;
off_t offset;
size_t length;
char body[];
};

void *mmap(void *addr, size_t length, int prot, int flags,
Expand Down Expand Up @@ -84,8 +83,9 @@ void *mmap(void *addr, size_t length, int prot, int flags,

// Initialize the main memory buffer, either with the contents of a file,
// or with zeros.
addr = map + 1;
if ((flags & MAP_ANON) == 0) {
char *body = map->body;
char *body = (char *)addr;
while (length > 0) {
const ssize_t nread = pread(fd, body, length, offset);
if (nread < 0) {
Expand All @@ -100,10 +100,10 @@ void *mmap(void *addr, size_t length, int prot, int flags,
body += (size_t)nread;
}
} else {
memset(map->body, 0, length);
memset(addr, 0, length);
}

return map->body;
return addr;
}

int munmap(void *addr, size_t length) {
Expand Down

0 comments on commit 9b9d243

Please sign in to comment.