Estou olhando para o código-fonte do Linux 5.0-rc5 em arch/x86/entry/syscalls/syscall_64.tbl
, descobri que não há um número syscall separado para x32 mmap
.
Então, como o kernel sabe que estamos usando a ABI x32 no espaço do usuário para não nos fornecer um endereço mapeado além de 4GiB?
Ou, em geral, como syscalls que podem retornar um endereço sabem que estamos usando x32 e não devem retornar um endereço além de 4GiB?
Os processos que desejam fazer uma syscall x32 definirão um bit no número de chamada do sistema, o que permitirá que o kernel os diferencie.
Da página de manual do syscall(2):
x32 não é realmente um ambiente separado; um programa x32 pode fazer chamadas de sistema x64 e vice-versa; isso é diferente da emulação ia32, que também pode ser suportada lado a lado com x64 e x32.
Esse bit é verificado no kernel através da
in_x32_syscall()
função:Encontrar onde a implementação do código do kernel
mmap()
está verificando é um exercício para o leitor (não é difícil). O kernel também definirá o__X32_SYSCALL_BIT
próprio explicitamente noRAX
registro salvo (o número syscall) no caso de um execve() de um binário x32.Se você observar a assinatura da função de
mmap
:você notará que o tamanho da memória (
length
) é umsize_t
parâmetro.Agora,
size_t
é um tipo dependente de plataforma .size_t
é de 32 bits em uma plataforma de 32 bits e 64 bits em uma plataforma de 64 bits.O mesmo vale para
void *
. Um ponteiro em uma arquitetura de 32 bits será um endereço de 32 bits.Portanto, não é o kernel que precisa saber, o compilador realmente cuida disso.