SRobertJames
SRobertJames

Reputation: 9253

How to mmap different regions of the same file into different memory addresses?

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

Answers (1)

SRobertJames
SRobertJames

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

Related Questions