2016-08-14 17 views
0

Я использую otool для получения информации о моем двоичном файле. Вот часть моего выхода:Как использовать otool для получения размера двоичного файла?

Load command 0 
     cmd LC_SEGMENT_64 
    cmdsize 72 
    segname __PAGEZERO 
    vmaddr 0x0000000000000000 
    vmsize 0x0000000100000000 
    fileoff 0 
filesize 0 
    maxprot 0x00000000 
initprot 0x00000000 
    nsects 0 
    flags 0x0 
Load command 1 
     cmd LC_SEGMENT_64 
    cmdsize 952 
    segname __TEXT 
    vmaddr 0x0000000100000000 
    vmsize 0x0000000000268000 
    fileoff 0 
filesize 2523136 
    maxprot 0x00000005 
initprot 0x00000005 
    nsects 11 
    flags 0x0 

Мы видим здесь, что command 1 с segname __TEXT начинается в vmaddr 0x0000000100000000

Проблема в том, что бинарный размер 2.3MB и 0x0000000100000000 составляет 4 Гб!

Я предполагаю, что «один» в середине адреса связан с 64-битной архитектурой и 0x0000000100000000 фактически адресом 0x00. Я искал информацию об этом, но я не нашел ничего полезного. Может ли кто-нибудь подтвердить мои предположения и объяснить, как именно это работает?

ответ

1

Нет ничего странного.

Сначала «недопустимый сегмент» зарезервирован в нижних 4 ГБ адресного пространства. Это похоже на недействительный 4 КБ или все, что было сохранено для того, чтобы сделать крах Dereference с указателем NULL в 32-битных процессах, только больше (это должно уловить также, например, любое 32-разрядное целое, ошибочно введенное в указатель). В конце концов, почему бы и нет? Это виртуальная память, это бесплатно. Some more details here.

Затем ваш исполняемый текст загружается с границей 4 ГБ. Ничего плохого - имейте в виду, что более низкие 4 ГБ не запекаются по фактической памяти, они просто отмечены как зарезервированные.

В общем, не обязательно странно загружать вещи на «высоких» адресах в 64-разрядном адресном пространстве. Например, стек, как правило, находится в зоне чуть ниже 48-битных границ. Это не похоже на то, что система фактически обеспечивает всю память в середине, виртуальная память делает так, что только страницы, содержащие что-то, потребляют фактическую память (RAM или пространство подкачки). (на самом деле, существует некоторая стоимость в бухгалтерии структуры данных страниц, но она вообще незначительна)

Размер двоичного файла сообщается как в поле размера виртуальной машины, так и в поле размера файла (0x268000 = 2523136 ≈ 2,4 МБ) ,

+0

Так что, когда мое приложение будет загружаться в ОЗУ, оно приземляется на нижние биты вправо? Если я захочу сбросить memmory из RAM, я должен искать память, которая находится между 0x00 и 0x268000? – Sayaki

+1

Нет! Ваш бинарный файл будет отображаться в виртуальной памяти точно так же, как он написан на выходе «otool» - по адресу 0x0000000100000000, то есть чуть выше границы 4 ГБ. Все пространство под ним зарезервировано для «недопустимой» страницы, которая segfaults всякий раз, когда кто-то пытается получить к ней доступ. Где он находится в физической ОЗУ, совершенно не имеет значения (и зависит от прихотей операционной системы - его можно фактически перемещать прозрачно, например, в случае его замены). –

+0

Хорошо, теперь я все получаю. THX за помощь :) – Sayaki

 Смежные вопросы

  • Нет связанных вопросов^_^