Ответ 1
Канонические правила адреса означают, что в 64-битном виртуальном адресном пространстве имеется гигантское отверстие. 2 ^ 47-1 не соприкасается со следующим допустимым адресом над ним, поэтому один mmap
не будет включать какой-либо из неиспользуемых диапазонов 64-разрядных адресов.
+----------+
| 2^64-1 | 0xffffffffffffffff
| ... |
| 2^64-2^47| 0xffff800000000000
+----------+
| |
| unusable |
| |
+----------+
| 2^47-1 | 0x00007fffffffffff
| ... |
| 0 | 0x0000000000000000
+----------+
Другими словами:
Есть ли у гарантии, что вам никогда не будет выделена память, чей диапазон адресов не зависит от 47-го бита?
Да. 48-разрядное адресное пространство, поддерживаемое текущим оборудованием, является детальностью реализации. Правила канонических адресов гарантируют, что будущие системы могут поддерживать больше виртуальных битов адреса, не нарушая при этом обратной совместимости в какой-либо значительной степени. Вам просто нужен флаг совместимости, чтобы ОС не давала процессу каких-либо областей памяти с большими битами не все равно. Будущему аппарату не нужно поддерживать какой-либо флаг, чтобы игнорировать высокие биты адреса или нет, потому что в старших битах в настоящий момент ошибка.
Удовлетворяющий факт: Linux по умолчанию использует сопоставление стека в верхней части нижнего диапазона действительных адресов.
например.
$ gdb /bin/ls
...
(gdb) b _start
Function "_start" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (_start) pending.
(gdb) r
Starting program: /bin/ls
Breakpoint 1, 0x00007ffff7dd9cd0 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) p $rsp
$1 = (void *) 0x7fffffffd850
(gdb) exit
$ calc
2^47-1
0x7fffffffffff