Как просмотреть информацию о карте памяти Linux в C? - PullRequest
2 голосов
/ 09 ноября 2011

Я динамически загружаю некоторые библиотеки Linux в C. Я могу получить начальные адреса библиотек, используя

dlinfo

(см. 1 ).

Однако я не могу найти информацию для определения размера библиотеки.

Единственное, что я обнаружил, это то, что нужно прочитать

/ proc / [pid] / maps

файл и проанализируйте его для получения соответствующей информации (см. 2 ). Есть ли более элегантный метод?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2011

Парсинг /proc/self/maps (или, возможно, popen - с помощью команды pmap) кажется мне все еще самой легкой вещью. Также есть функция dladdr (при условии, что у вас есть адрес для начала).

0 голосов
/ 09 ноября 2011

(Этот ответ зависит от LINUX / GLIBC)

Согласно http://s.eresi -project.org / inc / article / elf-rtld.txt

есть link_map * map; map-> l_map_start & map-> l_map_end

    /* 
        ** Start and finish of memory map for this object.  
    ** l_map_start need not be the same as l_addr.  
    */
    ElfW(Addr) l_map_start, l_map_end;

Это немного не точно, как сказано здесь http://www.cygwin.com/ml/libc-hacker/2007-06/msg00014.html = некоторые библиотеки не являются непрерывными в памяти; в письме есть несколько примеров ... например это самая внутренняя (для rtld) функция, чтобы определить, является ли данный адрес внутри адресного пространства lib или нет, основываясь на link_map и непосредственной работе с сегментами ELF:

/* Return non-zero if ADDR lies within one of L's segments.  */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
  int n = l->l_phnum;
  const ElfW(Addr) reladdr = addr - l->l_addr;

  while (--n >= 0)
    if (l->l_phdr[n].p_type == PT_LOAD
    && reladdr - l->l_phdr[n].p_vaddr >= 0
    && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
      return 1;
  return 0;
}

И эта функция является Другой альтернативой, которая заключается в том, чтобы находить заголовки программ / или заголовки разделов загруженного ELF (есть некоторые ссылки на такую ​​информацию в link_map)

И самое простое - использовать системный вызов stat с map->l_name - для чтения размера файла с диска (неточно в определении огромного раздела bss).

...