mmapはx32 ABIでどのように機能しますか?

mmapはx32 ABIでどのように機能しますか?

Linux 5.0-rc5ソースコードを見ている間、arch/x86/entry/syscalls/syscall_64.tblx32のための別のシステムコール番号がないことがわかりましたmmap

それでは、カーネルがユーザースペースでx32 ABIを使用しているため、4GiB以上のマッピングされたアドレスを提供していないことをどのように知ることができますか?

あるいは、通常、アドレスを返すことができるシステムコールは、私たちがx32を使用していて4GiB以上を返さないことをどうやって知ることができますか?

答え1

x32システムコールを試みるプロセスは、システムコール番号にビットが設定されているため、カーネルはそれを区別できます。

syscall(2) マンページから:

[5] The x32 ABI uses the same instruction as the x86_64 ABI and  is
    used  on  the  same processors.  To differentiate between them,
    the bit mask __X32_SYSCALL_BIT is bitwise-ORed into the  system
    call  number  for  system calls under the x32 ABI.  Both system
    call tables are available though, so setting the bit is  not  a
    hard requirement.

x32は真のスタンドアロン環境ではありません。 x32プログラムはx64システムコールを実行でき、その逆も同様です。これは、x64およびx32と並列にサポートされる可能性があるia32エミュレーションとは異なります。

このビットは、次の関数を介してカーネルでチェックされますin_x32_syscall()

static inline bool in_x32_syscall(void)
{
#ifdef CONFIG_X86_X32_ABI
        if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
                return true;
#endif
        return false;
}

カーネルコードがmmap()それを実装する場所を見つけることは、読者の練習課題として残されます(難しいことではありません)。 x32バイナリのexecve()の場合、カーネルは__X32_SYSCALL_BIT保存されたレジスタ(システムコール番号)に明示的にそれ自身で設定されます。RAX

答え2

次の関数シグネチャを見るとmmap

void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);

lengthメモリサイズ()がパラメータであることがわかりますsize_t

size_tプラットフォームの依存関係タイプ。size_t32ビットプラットフォームでは32ビット、64ビットプラットフォームでは64ビットです。

同じだvoid *。 32ビットアーキテクチャのポインタは32ビットアドレスです。

したがって、カーネルは知る必要はなく、コンパイラは実際にこれに興味を持っています。

関連情報