Получить начальный адрес страницы памяти в Linux - PullRequest
1 голос
/ 17 июня 2011

В моем коде мне нужно отслеживать некоторые страницы, которые изменяются.Первоначально я даю им только права на чтение, но на обработчике сигналов я даю им и права на чтение и запись (я не собираюсь объяснять, для чего все это нужно, и в обработчике сигналов на самом деле больше кода, который я 'мы не показаны).

Теперь мой вопрос заключается в том, как получить начальный адрес страницы из адреса памяти, который находится на этой странице.В общем, мне нужно реализовать get_page_start_addr , показанный здесь в коде.До сих пор я делал это только для одной страницы, начальный адрес которой знала моя программа.Но теперь, поскольку мне нужно сделать это для нескольких страниц, мне нужно получить начальный адрес страницы с любого произвольного адреса памяти, поскольку mprotect принимает только адрес начальной страницы в качестве допустимого аргумента.

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");
  }
}

Ответы [ 2 ]

7 голосов
/ 17 июня 2011

В Linux (я полагаю, и в других ОС) страницы выравниваются по границам страниц.Таким образом, если вы знаете свой PAGE_SIZE, тогда вы можете просто получить начало страницы, маскируя младшие биты адреса.

page_start = addr & ~(PAGE_SIZE-1);
1 голос
/ 21 июня 2011

Чтобы точно знать размер страницы, используйте sysconf(_SC_PAGESIZE).

...