How a 64-bit linux kernel launches a 32-bit process from ELF

Looking binfmt_elf.c in the kernel source code, I could not understand what makes the core (64 bit) otherwise in case of a 32-bit process, and a 64-bit process.

Can someone explain to me what I am missing?

(This question is related to my other question about 32-bit instructions in the same process as 64-bit instructions ( link ), but this refers to a separate question.)

0
source share
1 answer

execveat, fs/exec.c SYSCALL_DEFINEx (execveat..) . :

  • do_execveat (..)
    • do_execveat_common (..)
      • exec_binprm (..)
        • search_binary_handler (..)

search_binary_handler . 64- Linux 64- ELF 32- ELF. fs/binfmt_elf.c. 32- fs/compat_binfmt_elf.c, , binfmt_elf.c.

binfmt_elf.c elf_check_arch. , arch/x86/include/asm/elf.h - 64- 32- . 64 EM_X86_64 (62 - include/uapi/ilnux/elf-em.h). 32- EM_386 (3) EM_486 (6) ( ). , , , ELF - , ELF 64- 32-.

32- ELF 64- ELF 64- Linux fs/compat_binfmt_elf.c.

compat_start_thread. start_thread compat_start_thread. arch/x86/kernel/process_64.c. compat_start_thread start_thread_common :

start_thread_common(regs, new_ip, new_sp,
             test_thread_flag(TIF_X32)
             ? __USER_CS : __USER32_CS,
             __USER_DS, __USER_DS);

start_thread start_thread_common :

start_thread_common(regs, new_ip, new_sp,
             __USER_CS, __USER_DS, 0);

, , , - CS - 64- ELF 32- ELF.

__USER_CS __USER32_CS arch/x86/include/asm/segment.h:

#define __USER_CS           (GDT_ENTRY_DEFAULT_USER_CS*8 + 3)
#define __USER32_CS         (GDT_ENTRY_DEFAULT_USER32_CS*8 + 3)

#define GDT_ENTRY_DEFAULT_USER_CS   6
#define GDT_ENTRY_DEFAULT_USER32_CS 4

So __USER_CS 6 * 8 + 3 = 51 = 0x33

__USER32_CS 4 * 8 + 3 = 35 = 0x23

, CS :

CPU , , 16- :

( ):

_part 16- , 13 ( 3 - 15) . ( 2) , GDT LDT. ( 1 0) , 0 3 .

CS 0x23 1 0 3, " ". 2 0, GDT, 3 - 15 - 4, , 4 (GDT).

.

+5

Source: https://habr.com/ru/post/1693800/


All Articles