Reputation: 9253
How can I mmap different parts of a file into different memory regions?
I tried with this code, but get File exists
errors:
int fd = open(FN, O_RDONLY);
if (fd == -1) {
perror("");
exit(1);
}
void* retval;
retval = mmap((void*) 0x00401000, 0xb93, PROT_READ | PROT_EXEC, MAP_FIXED_NOREPLACE | MAP_PRIVATE, fd, 0x1000);
if (retval == MAP_FAILED) {
perror("Error mmap 1");
exit(1);
}
retval = mmap((void*) 0x00402000, 0x660, PROT_READ, MAP_FIXED_NOREPLACE | MAP_PRIVATE, fd, 0x2000);
if (retval == MAP_FAILED) {
perror("Error mmap 2");
exit(1);
}
The first mmap works fine; the second fails with File exists
. If I comment out the first one, the second works.
I get this error whether I do MMAP_PRIVATE
or MMAP_SHARED
. Likewise, I get the error if I reuse the original fd, or open a new fd to the same file.
How can I mmap two regions of the same file to different places? Why can't I do this directly, given that the mmap is read only (no PROT_WRITE
) and also copy-on-write (MMAP_PRIVATE
).
Upvotes: 1
Views: 316
Reputation: 9253
The problem is the length
field in the mmap calls, not the fact that it's the same file. Note the length is 0xb932
, 0x660
, but these are rounded up by mmap to 0x1000. Thus, the pages end up taking more memory than expected, causing collisions, which, due to MAP_FIXED_NOREPLACE
, the kernel is unable to replace and fix.
Upvotes: 1