Reputation: 30765
In my code, I need to keep track of some pages which are being modified. Initially I give only read access to them, but on the signal handler I give them both read and write access (I am not going to explain what is the purpose for all that and there is actually more code in the signal handler, which I've not shown).
Now my question is how to get the starting address of a page from a memory address which resides in that page. So basically I need to implement the get_page_start_addr shown here in the code. Up till now, I was only doing it for a single page, whose starting address my program knew. But now, since I need to do it for multiple pages, I need to get the starting address of the page from any arbitrary memory address, because mprotect only accepts starting page address as valid argument.
static void memory_change_handler(int sig, siginfo_t *si, void *unused)
{
long addr = (long)si->si_addr;
long page_start_addr = get_page_start_addr( addr );
if (mprotect((void*)page_start_addr, pagesize, PROT_READ | PROT_WRITE) == -1)
{
print_error();
handle_error("mprotect");
}
}
Upvotes: 2
Views: 4468
Reputation: 3
You can take that address (unsigned long) /pagesize and *pagesize. This gives you the first page address of your logical address.
Upvotes: 0
Reputation: 37437
In Linux (in other OSes too, I guess), pages are aligned at page boundaries. Thus, if you know your PAGE_SIZE
, then you can simply get the start of the page by masking the lower address bits.
page_start = addr & ~(PAGE_SIZE-1);
Upvotes: 10