¥×¥í¥°¥é¥à¤Ï¤É¤¦Æ°¤¯¤Î¤«? ¡Á ELF¤Î¹õËâ½Ñ¤ò¤«¤¤¤Þ¤ß¤ë
¤â¤¦ÄùÀÚÆü¤Ê¤Î¤Ë¥Í¥¿¤¬¤Ê¤¤¡£¤È¤¤¤¦¤ï¤±¤Ç´Êñ¤Ê¥×¥í¥°¥é¥à "hello, world" ¤¬¤É¤Î¤è¤¦¤Ëµ¯Æ°¤µ¤ì¡¢¤É¤Î¤è¤¦¤Ë½èÍý¤µ¤ì¤ÆÆ°¤¯¤Î¤«¤ò̵°ÕÌ£¤Ë¾Ü¤·¤¯²òÀ⤷¤Æ¤ß¤è¤¦¡£
#include
int
main(int argc, char *argv[])
{
printf("hello, world\n");
exit(0);
}
¤³¤Î hello.c ¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤È¼¡¤Î¤è¤¦¤Êhello¤È¤¤¤¦¥Ð¥¤¥Ê¥ê¤¬¤Ç¤¤ë
% cc -g -o hello hello.c
¤³¤Î hello ¤È¤¤¤¦¥Ð¥¤¥Ê¥ê¤Ï
% file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0, dynamically linked (uses shared libs), not stripped
¤Î¤è¤¦¤Ë ELF¤È¤¤¤¦¥Õ¥©¡¼¥Þ¥Ã¥È¤Î¥Ð¥¤¥Ê¥ê¤Ç¤¢¤ë¡£
dynamically linked ¤Ê¤Î¤Ç ldd ¤ò¤Ä¤«¤¦¤È
% ldd hello
libc.so.6 => /lib/libc.so.6 (0x4001c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
¤Î¤è¤¦¤Ë¤É¤Î shared libs ¤ò»È¤Ã¤Æ¤¤¤ë¤Î¤«¤ò¸«¤ë¤³¤È¤¬¤Ç¤¤ë¡£
¤è¤ê¾Ü¤·¤¯¤Ï objdump ¤ò¤Ä¤«¤¦¤ÈELF¥Ð¥¤¥Ê¥ê¤ÎÃæ¿È¤ò¤ß¤ë¤³¤È¤¬¤Ç¤¤ë¡£
¤¿¤È¤¨¤Ð -x (--all-headers) ¤Ç¤³¤Î¥Ð¥¤¥Ê¥ê¤Î¼Â¹Ô¥³¡¼¥É¤Ç¤Ï¤Ê¤¤¾ðÊ󡢤Ĥޤê¤É¤Î¥¢¡¼¥¥Æ¥¯¥Á¥ã¤à¤±¤Î¥Ð¥¤¥Ê¥ê¤«¡¢¤É¤Îshared libs¤òɬÍפȤ·¤Æ¤¤¤ë¤«¡¢¤É¤¦¤¤¤Ã¤¿symbol¤¬¤Ê¤«¤Ç»È¤ï¤ì¤Æ¤¤¤ë¤«/»È¤ª¤¦¤È¤·¤Æ¤¤¤ë¤«¤Ê¤É¤È¤¤¤Ã¤¿¾ðÊó¤ò¸«¤ë¤³¤È¤¬¤Ç¤¤ë¡£
% objdump -x hello
hello: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
hello
¥¢¡¼¥¥Æ¥¯¥Á¥ã: i386, ¥Õ¥é¥° 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
³«»Ï¥¢¥É¥ì¥¹ 0x08048340
¥×¥í¥°¥é¥à¥Ø¥Ã¥À:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x000000c0 memsz 0x000000c0 flags r-x
INTERP off 0x000000f4 vaddr 0x080480f4 paddr 0x080480f4 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x000004b2 memsz 0x000004b2 flags r-x
LOAD off 0x000004b4 vaddr 0x080494b4 paddr 0x080494b4 align 2**12
filesz 0x00000110 memsz 0x00000128 flags rw-
DYNAMIC off 0x000004c8 vaddr 0x080494c8 paddr 0x080494c8 align 2**2
filesz 0x000000c8 memsz 0x000000c8 flags rw-
NOTE off 0x00000108 vaddr 0x08048108 paddr 0x08048108 align 2**2
filesz 0x00000020 memsz 0x00000020 flags r--
(°Ê²¼Î¬)
¤Þ¤¿ -d (--disassemble) ¤ÇµÕ¥¢¥»¥ó¥Ö¥ë¤¬¡¢¥Ð¥¤¥Ê¥ê¤¬-g¥ª¥×¥·¥ç¥ó¤Ç¥Ó¥ë¥É¤µ¤ì¤Æ¤¤¤ì¤Ð-S(--source) ¤Ç¥½¡¼¥¹¥³¡¼¥É¤È¤ÎÂбþ¤â¸«¤ë¤³¤È¤¬¤Ç¤¤ë¡£
% objdump -d hello
hello: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
¥»¥¯¥·¥ç¥ó .init ¤ÎµÕ¥¢¥»¥ó¥Ö¥ë:
80482bc: 55 push %ebp
80482bd: 89 e5 mov %esp,%ebp
80482bf: 83 ec 08 sub $0x8,%esp
80482c2: e8 9d 00 00 00 call 8048364
80482c7: 90 nop
80482c8: e8 1b 01 00 00 call 80483e8
80482cd: e8 7e 01 00 00 call 8048450 <__do_global_ctors_aux>
80482d2: c9 leave
80482d3: c3 ret
¥»¥¯¥·¥ç¥ó .plt ¤ÎµÕ¥¢¥»¥ó¥Ö¥ë:
(°Ê²¼Î¬)
% objdump -S hello
hello: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
¥»¥¯¥·¥ç¥ó .init ¤ÎµÕ¥¢¥»¥ó¥Ö¥ë:
080482bc <_init>:
(ά)
08048420 :
#include
int
main(int argc, char *argv[])
{
8048420: 55 push %ebp
8048421: 89 e5 mov %esp,%ebp
8048423: 83 ec 08 sub $0x8,%esp
printf("hello, world\n");
8048426: 83 c4 f4 add $0xfffffff4,%esp
8048429: 68 a4 84 04 08 push $0x80484a4
804842e: e8 e1 fe ff ff call 8048314 <_init+0x58>
8048433: 83 c4 10 add $0x10,%esp
exit(0);
8048436: 83 c4 f4 add $0xfffffff4,%esp
8048439: 6a 00 push $0x0
804843b: e8 e4 fe ff ff call 8048324 <_init+0x68>
8048440: 83 c4 10 add $0x10,%esp
}
8048443: c9 leave
8048444: c3 ret
(°Ê²¼Î¬)
¤µ¤Æ¡¢¤³¤ì¤òshell(Î㤨¤Ðbash)¤«¤éµ¯Æ°¤¹¤ë¾ì¹ç¡¢fork(2)¤·¤Æstdin,stdout,stderr¤Ê¤É¤Î¥ê¥À¥¤¥ì¥¯¥È¤Î½èÍý¤Ê¤É¤ò¤·¤Æ¤«¤éexec(2)¤Ç¡¢¥×¥í¥°¥é¥à¤¬fork(2)¤µ¤ì¤¿bash¤«¤éexec(2)¤Ç»ØÄꤷ¤¿¥×¥í¥°¥é¥à(¤³¤Î¾ì¹ç¤Ï hello)¤Ë¤ª¤¤«¤ï¤Ã¤Æ¼Â¹Ô¤¬³«»Ï¤µ¤ì¤ë¡£¤³¤ì¤ò½ç¤ò¤ª¤Ã¤Æ¤ß¤Æ¤¤¤Ã¤Æ¤ß¤è¤¦¡£
¤Þ¤º¡¢execute_cmd.c¤Îshell_execve()¤ÎÃæ¤Ç execve(2)¤¬¸Æ¤Ð¤ì¤ë¡£¤³¤ì¤Ïglibc¤Îsysdeps/unix/sysv/linux/execve.c¤Ç¡¢
return INLINE_SYSCALL (execve, 3, file, argv, envp);
¤Ë¤è¤ê system call¤Î¤è¤Ó¤À¤·¤¬¹Ô¤Ê¤ï¤ì¤ë¡£¤³¤ì¤Ïsysdeps/unix/sysv/linux/i386/sysdep.h ¤Ç #define ¤µ¤ì¤Æ¤ª¤ê°Ê²¼¤Î¤è¤¦¤Ê¤«¤ó¤¸¤Îasm¤ò¼Â¹Ô¤¹¤ë¤³¤È¤Ë¤Ê¤ë
movl ,%edi
movl ,%ecx
movl ,%edx
movl $11, %eax # execve
int $0x80
¤³¤Î¤è¤¦¤Ë %eax ¤ËsystemcallÈֹ桢%edx¡¢%ecx,%edi¤¢¤¿¤ê¤Ë°ú¿ô¤¬¥»¥Ã¥È¤µ¤ì¤Æ¡¢int $0x80¤¬¼Â¹Ô¤µ¤ì¤ë¡£intÌ¿Îá¤Ï¥½¥Õ¥È¥¦¥§¥¢³ä¤ê¹þ¤ß¤Ç¤³¤Î»þÅÀ¤Çkernel mode¤Ë°Ü¹Ô¤¹¤ë¡£kernel¤Î½é´ü²½Ãʳ¬¤Ë arch/i386//kernel/traps.c ¤Îtrap_init()¤Ç
set_system_gate(SYSCALL_VECTOR,&system_call); # SYSCALL_VECTOR = 0x80
¤ÈÀßÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢int $0x80¤¬¸Æ¤Ð¤ì¤ë¤Èsystem_call¤Ø¤ä¤Ã¤Æ¤¯¤ë¡£¤³¤Îsystem_call¤È¤¤¤¦¤Î¤Ïarch/i386/kernel/entry.S¤Ë¤¢¤ë ENTRY(system_call) ¤Ç¤¢¤ë¡£¤³¤³¤Ç¤Ï´ðËÜŪ¤Ë¥ì¥¸¥¹¥¿¤ò¥¹¥¿¥Ã¥¯¤Ë¤Ä¤ó¤Ç%eax¤ÎÆâÍƤ˽¾¤Ã¤Æsys_call_table¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¥¢¥É¥ì¥¹¤òcall¤¹¤ë¤³¤È¤Ë¤Ê¤ë¡£
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
sys_call_table¤â¤ª¤Ê¤¸¤¯entry.S¤Ë¤¢¤ê11ÈÖÌܤ¬ sys_execve ¤Ç¤¢¤ë
ENTRY(sys_call_table)
ά
.long SYMBOL_NAME(sys_unlink) /* 10 */
.long SYMBOL_NAME(sys_execve)
.long SYMBOL_NAME(sys_chdir)
ά
sys_execve¤Ï arch/i386/kernel/process.c ¤Î asmlinkage int sys_execve(struct pt_regs regs)¤Ç¤¢¤ë¡£
asmlinkage int sys_execve(struct pt_regs regs)
{
int error;
char * filename;
filename = getname((char *) regs.ebx);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®
s);
if (error == 0)
current->ptrace &= ~PT_DTRACE;
putname(filename);
out:
return error;
}
¤³¤Î¤è¤¦¤Ë %ebx ¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë̾¤ò¥Á¥§¥Ã¥¯¤·¤¿¤¢¤È¡¢do_execve()¤òÆɤó¤Ç¤¤¤ë¡£system call¤òÆɤó¤À»þ¤Ë%ecx¤Ë¤Ïargv¤ò%edx¤Ë¤Ïenvp¤òÀßÄꤷ¤Æ¤¢¤ë¤Î¤Ç¤³¤³¤Ï
do_execve(filename, argv, envp, ...)
¤Î¤è¤¦¤Ë¤è¤Ó¤À¤·¤Æ¤¤¤ë¤³¤È¤Ë¤Ê¤ë¡£¤³¤³¤Þ¤Ç¤¬arch°Í¸¤Ê¥³¡¼¥É¤Ç¤¢¤ê¤¢¤È¤ÏÈó°Í¸¤Ê¥³¡¼¥É¤Ë°Ü¹Ô¤¹¤ë¡£do_execve()¤Ïfs/exec.c¤Ë¤¢¤ë¡£
do_execve()¤Ç¤Ï¤Þ¤ºfilename¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤«¤éopen_exec()¤ò¤Ä¤«¤Ã¤ÆÆɤߤ³¤ó¤Ç¤¤¤ë¡£¤³¤³¤Ç¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤Î¥Á¥§¥Ã¥¯¤Ê¤É¤â¹Ô¤Ê¤Ã¤Æ¤¤¤ë¡£open¤ËÀ®¸ù¤¹¤ì¤Ðstruct linux_binprm¤Î¾ðÊó¤òÀßÄꤷ¤Æ¤¤¤¯¡£struct linux_binprm¤Ë¤Ïargv¤äenvp,uid,gid¤Ê¤É¤Î¾ðÊó¤¬ÊÝ»ý¤µ¤ì¤Æ¤¤¤ë¡£¤½¤·¤Æexec¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤ÎºÇ½é¤ÎBINPRM_BUF_SIZE (128byte)¤òÆɤߤ³¤à¡£
search_binary_handler()¤Çfile header¤Îmagic number¤Ê¤É¤ò¥Á¥§¥Ã¥¯¤·¡¢¤½¤Îbinary format¤ò¤¢¤Ä¤«¤¦handler¤òstruct linux_binfmt *formats¤Î¤Ê¤«¤«¤éõ¤·¤À¤·¤Æ¤¤¤ë¡£ELF¤Ë´Ø¤·¤Æ¤Ïfs/binfmt_elf.c¤Îelf_format¤ÎÃæ¤Îload_elf_binary()¤ÇELF¥Ø¥Ã¥À¤Î¥Á¥§¥Ã¥¯¤¬¤ª¤³¤Ê¤ï¤ì¤Æ¤¤¤ë¡£¤³¤³¤Çmagic number¤Ê¤ÉɬÍפʾðÊó¤Î¥Á¥§¥Ã¥¯¤Ë¥¯¥ê¥¢¤¹¤ì¤ÐELF header¤òkernel_read()¤ò¤Ä¤«¤Ã¤ÆÆɤߤ³¤ß¤ò¤¹¤ë¡£
¤³¤³¤Ç elf_ppnt->p_type == PT_INTERP ¤Ç .interp section¤ò¤ß¤Ä¤±¤ë¤È¤³¤ÎÆâÍƤòÆɤߤȤ롣¤³¤ÎÆâÍƤÏ
% objdump -s -j .interp hello
hello: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
¥»¥¯¥·¥ç¥ó .interp ¤ÎÆâÍÆ:
80480f4 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so
8048104 2e3200 .2.
¤Ç¤¢¤ë¡£¤Ä¤Þ¤ê elf_interpreter = "/lib/ld-linux.so.2" ¤È¤¤¤¦¤Î¤¬Æɤߤ³¤Þ¤ì¤ë¡£
¤³¤³¤ÇºÆ¤Ó elf_interpreter ¤ò open_exec()¤·¤Æ BINPRM_BUF_SIZEʬ¤À¤±¤è¤ß¤³¤ó¤Ç¤¤¤ë¡£symbolic link¤ò¤¿¤É¤Ã¤Æ¡¢¤³¤ì¤Ï
% file /lib/ld-linux.so.2
/lib/ld-linux.so.2: symbolic link to ld-2.3.1.so
% file /lib/ld-2.3.1.so
/lib/ld-2.3.1.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped
¤È¤¤¤¦ shared object¤ò¼Â¹Ô¤¹¤ë¤³¤È¤Ë¤Ê¤ë¡£
flush_old_exec() ¤Ç¸½ºß¤Îprogram¤Î¾ðÊó¤ò¾Ã¤·¡¢¿·¤·¤¤program¤Î¤¿¤á¤Î¾ðÊó¤Ëcurrent¤Î¾ðÊó¤ò¤¤¤ì¤«¤¨¤Æ¤¤¤¯¡£memory map¤¬½é´ü²½¤µ¤ì¥×¥í¥°¥é¥à¥Ø¥Ã¥À¤ÇLOAD¤Î¤È¤³¤í¤¬map¤µ¤ì¤ë¡£filesz¤è¤êmemsz¤¬¤ª¤ª¤¤¤¾ì¹ç¤Ï¤½¤Îʬ¤Îmemory¤¬¤³¤Î¤¢¤¿¤ê¤Ç 0 ¤Ë fill¤µ¤ì¤ë¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
ºÇ¸å¤Ë elf_interpreter "/lib/ld-2.3.1.so" ¤¬load_elf_interp()¤Ë¤è¤Ã¤Æmemory¾å¤Ëmap¤µ¤ì¤ë¡£
% objdump -x /lib/ld-2.3.1.so
/lib/ld-2.3.1.so: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
/lib/ld-2.3.1.so
¥¢¡¼¥¥Æ¥¯¥Á¥ã: i386, ¥Õ¥é¥° 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
³«»Ï¥¢¥É¥ì¥¹ 0x00000b50
¥×¥í¥°¥é¥à¥Ø¥Ã¥À:
LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12
filesz 0x00010e00 memsz 0x00010e00 flags r-x
LOAD off 0x00011000 vaddr 0x00011000 paddr 0x00011000 align 2**12
filesz 0x00000554 memsz 0x00000700 flags rw-
DYNAMIC off 0x000113f8 vaddr 0x000113f8 paddr 0x000113f8 align 2**2
filesz 0x000000b0 memsz 0x000000b0 flags rw-
(ά)
¤½¤Î¸å¡¢current¤Î¾ðÊó¤ò¤µ¤é¤ËÀßÄꤷ¤Æ¤¤¤Ã¤Æ
start_thread(regs, elf_entry, bprm->p);
¤Ç elf_entry ¤«¤é¼Â¹Ô¤ò³«»Ï¤¹¤ë¡£elf_entry ¤Ï /lib/ld-2.3.1.so ¤Î entry(³«»Ï¥¢¥É¥ì¥¹)¤«¤é¤È¤Ê¤ë¡£start_thread¤Ï include/asm-i386/processor.h ¤Ç¼¡¤Î¤è¤¦¤Ë #define ¤µ¤ì¤Æ¤¤¤ë¡£
#define start_thread(regs, new_eip, new_esp) do { \
__asm__("movl %0,%%fs ; movl %0,%%gs": :"r" (0)); \
set_fs(USER_DS); \
regs->xds = __USER_DS; \
regs->xes = __USER_DS; \
regs->xss = __USER_DS; \
regs->xcs = __USER_CS; \
regs->eip = new_eip; \
regs->esp = new_esp; \
} while (0)
¤Ä¤Þ¤ê elf_entry ¤ò¼¡¤Î %eip ¤È¤·¤ÆÀßÄꤷ¤Æ¤¤¤ë¡£¤³¤ì¤Ç search_binary_handler()¤«¤éreturn¤·¤Ædo_execve()¤¬¤ª¤ê¡¢sys_execve()¤«¤éreturn¤¹¤ë¡£
¤Ç¡¢arch/i386/kernel/entry.S ¤Î
call *SYMBOL_NAME(sys_call_table)(,%eax,4)
¤ËÌá¤Ã¤Æ¤¤Æ°Ê²¼¤¬¼Â¹Ô¤µ¤ì¤ë¡£
movl %eax,EAX(%esp) # save the return value
ENTRY(ret_from_sys_call)
cli # need_resched and signals atomic test
cmpl $0,need_resched(%ebx)
jne reschedule
cmpl $0,sigpending(%ebx)
jne signal_return
restore_all:
RESTORE_ALL
reschedule¤¬¤è¤Ó¤À¤µ¤ì¤Æ¡¢kernel/sched.c¤Îasmlinkage void schedule(void)¤Î
¤Ê¤«¤«¤é include/asm-i386/system.h¤Îswitch_to()¤«¤éarch/i386/kernel/process.c
¤Î__switch_to()¤Ë¤¤Æ %esp, %fs, %gs ¤¬¤¤¤ì¤«¤¨¤é¤ì¤ë¡£
¤½¤¦¤·¤Æ exec¤µ¤ì¤¿¥×¥í¥»¥¹¤ËÀ©¸æ¤¬¤Þ¤ï¤Ã¤Æ¤¯¤ë¤È¡¢¤³¤Îprocess¤Î%eip¡¢¤Ä¤Þ¤êelf_interpreter¤Îentry address¤«¤é¼Â¹Ô¤ò³«»Ï¤¹¤ë¤³¤È¤Ë¤Ê¤ë¡£
% objdump -f /lib/ld-2.3.1.so
/lib/ld-2.3.1.so: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
¥¢¡¼¥¥Æ¥¯¥Á¥ã: i386, ¥Õ¥é¥° 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
³«»Ï¥¢¥É¥ì¥¹ 0x00000b50
% objdump -d /lib/ld-2.3.1.so
(ά)
00000b50 <_start>:
b50: 89 e0 mov %esp,%eax
b52: e8 03 01 00 00 call c5a <_dl_start>
¤È¤¤¤¦¤³¤È¤Ç /lib/ld-2.3.1.so ¤Î _start ¤«¤é¼Â¹Ô¤ò³«»Ï¤¹¤ë¡£¤³¤ì¤Ïsysdeps/i386/dl-machine.h ¤Î #define RTLD_START ¤Î¥³¡¼¥É¤Ç¤¢¤ë¡£
¤Ç_dl_start()¤¬¤è¤Ð¤ì¤ë¡£¤³¤Î_dl_start()¤Ï glibc¤Î elf/rtld.c ¤Î _dl_start()¤Ç¤¢¤ë¡£¤Þ¤º bootstrap_map.l_info¤ò 0 ¤Ç½é´ü²½¤¹¤ë¡£
sysdeps/i386/dl_machine.h ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ëelf_machine_load_address()¤ò
¤Ä¤«¤Ã¤Ædynamic linker¼«ÂΤ¬¤É¤Î¥¢¥É¥ì¥¹¤Ë¤¢¤ë¤«¤òÄ´¤Ù¤Æ¤¤¤ë¡£
¤Ç sysdeps/generic/dl-sysdep.c ¤Î _dl_sysdep_start()¤«¤éelf/rtld.c¤Î
dl_main()¤¬¤è¤Ð¤ì¤Æ¤¯¤ë¡£¤Þ¤º¤³¤³¤Ç process_envvars()¤¬¤è¤Ð¤ì´Ä¶ÊÑ¿ô¤Î
¥Á¥§¥Ã¥¯¤¬¤ª¤³¤Ê¤ï¤ì¤Æ¤¤¤ë¡£¤³¤Î¥³¡¼¥É¤ò¤ß¤ë¤È°Ê²¼¤Î´Ä¶ÊÑ¿ô¤¬
/lib/ld-2.3.1.so¤Ç¤Ä¤«¤ï¤ì¤Æ¤¤¤ë¤³¤È¤¬¤ï¤«¤ë¡£
LD_WARN - Warning level, verbose or not
LD_DEBUG - Debugging of the dynamic linker?
LD_VERBOSE - Print information about versions.
LD_PRELOAD - List of objects to be preloaded.
LD_PROFILE - Which shared object shall be profiled.
LD_BIND_NOW - Do we bind early?
LD_BIND_NOT - ?
LD_SHOW_AUXV - Test whether we want to see the content of the auxiliary
array passed up from the kernel.
LD_HWCAP_MASK - Mask for the important hardware capabilities.
LD_ORIGIN_PATH - Path where the binary is found.
LD_LIBRARY_PATH - The library search path.
LD_DEBUG_OUTPUT - Where to place the profiling data file.
LD_DYNAMIC_WEAK - ?
LD_PROFILE_OUTPUT - Where to place the profiling data file.
LD_TRACE_PRELINKING - The mode of the dynamic linker can be set.
LD_TRACE_LOADED_OBJECTS - The mode of the dynamic linker can be set.
LD_PRELOAD ¤ä LD_LIBRARY_PATH ¤Ï¤è¤¯»È¤ï¤ì¤ë¤¬¡¢Â¾¤Ï¤¢¤Þ¤ê¤Ä¤«¤Ã¤¿¤³¤È¤¬¤Ê¤¤¤³¤È¤À¤í¤¦¡£¤È¤ê¤¢¤¨¤º¤¤¤¯¤Ä¤«¤ò´Êñ¤Ë¾Ò²ð¤·¤è¤¦¡£
% LD_DEBUG=help /lib/ld-2.3.1.so
Valid options for the LD_DEBUG environment variable are:
libs display library search paths
reloc display relocation processing
files display progress for input file
symbols display symbol table processing
bindings display information about symbol binding
versions display version dependencies
all all previous options combined
statistics display relocation statistics
help display this help message and exit
To direct the debugging output into a file instead of standard output
a filename can be specified using the LD_DEBUG_OUTPUT environment variable.
¤¿¤È¤¨¤Ð °Ê²¼¤Î¤è¤¦¤Ê·ë²Ì¤òÆÀ¤ë¤³¤È¤¬¤Ç¤¤ë¡£
% LD_DEBUG=libs ./hello
04836: find library=libc.so.6; searching
04836: search cache=/etc/ld.so.cache
04836: trying file=/lib/libc.so.6
04836:
04836:
04836: calling init: /lib/libc.so.6
04836:
04836:
04836: initialize program: ./hello
04836:
04836:
04836: transferring control: ./hello
04836:
hello, world
04836:
04836: calling fini: /lib/libc.so.6
04836:
% LD_DEBUG=reloc ./hello
04837:
04837: relocation processing: /lib/libc.so.6 (lazy)
04837:
04837: relocation processing: ./hello (lazy)
04837:
04837: relocation processing: /lib/ld-linux.so.2
04837:
04837: calling init: /lib/libc.so.6
04837:
04837:
04837: initialize program: ./hello
04837:
04837:
04837: transferring control: ./hello
04837:
hello, world
04837:
04837: calling fini: /lib/libc.so.6
04837:
% LD_DEBUG=files ./hello
04839:
04839: file=libc.so.6; needed by ./hello
04839: file=libc.so.6; generating link map
04839: dynamic: 0x40129618 base: 0x4001c000 size: 0x00112184
04839: entry: 0x40031a40 phdr: 0x4001c034 phnum: 7
04839:
04839:
04839: calling init: /lib/libc.so.6
04839:
04839:
04839: initialize program: ./hello
04839:
04839:
04839: transferring control: ./hello
04839:
hello, world
04839:
04839: calling fini: /lib/libc.so.6
04839:
% LD_DEBUG=symbols ./hello
04845: symbol=_IO_file_close; lookup in file=./hello
04845: symbol=_IO_file_close; lookup in file=/lib/libc.so.6
04845: symbol=_IO_2_1_stdin_; lookup in file=./hello
04845: symbol=_IO_2_1_stdin_; lookup in file=/lib/libc.so.6
04845: symbol=_IO_2_1_stdout_; lookup in file=./hello
04845: symbol=_IO_2_1_stdout_; lookup in file=/lib/libc.so.6
04845: symbol=_IO_2_1_stderr_; lookup in file=./hello
04845: symbol=_IO_2_1_stderr_; lookup in file=/lib/libc.so.6
(ά)
% LD_DEBUG=bindings ./hello
4849: binding file /lib/libc.so.6 to /lib/libc.so.6: normal symbol `_IO_file_c
lose' [GLIBC_2.0]
04849: binding file /lib/libc.so.6 to /lib/libc.so.6: normal symbol `_IO_2_1_st
din_' [GLIBC_2.1]
04849: binding file /lib/libc.so.6 to /lib/libc.so.6: normal symbol `_IO_2_1_st
dout_' [GLIBC_2.1]
04849: binding file /lib/libc.so.6 to /lib/libc.so.6: normal symbol `_IO_2_1_st
derr_' [GLIBC_2.1]
(ά)
% LD_DEBUG=versions ./hello
04852: checking for version `GLIBC_2.0' in file /lib/libc.so.6 required by file ./hello
04852: checking for version `GLIBC_2.1' in file /lib/ld-linux.so.2 required by file /lib/libc.so.6
04852: checking for version `GLIBC_2.0' in file /lib/ld-linux.so.2 required by file /lib/libc.so.6
04852: checking for version `GLIBC_PRIVATE' in file /lib/ld-linux.so.2 required by file /lib/libc.so.6
04852:
(ά)
% LD_DEBUG=statistics ./hello
04854: number of relocations: 119
04854: number of relocations from cache: 5
hello, world
04854:
04854: runtime linker statistics:
04854: final number of relocations: 126
04854: final number of relocations from cache: 5
LD_DEBUG=all ¤È¤¹¤ì¤Ð¤¹¤Ù¤Æ¤¬½ÐÎϤµ¤ì¤ë¡£¤Þ¤¿LD_DEBUG=help ¤Ç½ñ¤¤¤Æ¤¢¤ëÄ̤ꡢLD_DEBUG_OUTPUT¤â»ØÄꤹ¤ì¤Ð¤½¤Î¥Õ¥¡¥¤¥ë¤Ë½ÐÎϤµ¤ì¤ë¡£
LD_SHOW_AUXV ¤ò»È¤¦¤È¤ª¤â¤·¤í¤¤¾ðÊó¤ò¤ß¤ë¤³¤È¤¬¤Ç¤¤ë¡£
% LD_SHOW_AUXV=1 /lib/ld-2.3.1.so ./hello
AT_HWCAP: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse
AT_PAGESZ: 4096
AT_CLKTCK: 100
AT_PHDR: 0x80000034
AT_PHENT: 32
AT_PHNUM: 3
AT_BASE: 0x0
AT_FLAGS: 0x0
AT_ENTRY: 0x80000b50
AT_UID: 1000
AT_EUID: 1000
AT_GID: 1000
AT_EGID: 1000
AT_PLATFORM: i686
hello, world
¤³¤ì¤Ï sysdeps/generic/dl-sysdep.c¤Î_dl_show_auxv()¤Ç½èÍý¤·¤Æ¤¤¤ë¡£
AT_HWCAP ¤Ë´Ø¤·¤Æ¤Ï sysdeps/unix/sysv/linux/i386/dl-procinfo.h¤Î
_dl_procinfo()¤Ç½èÍý¤·¤Æ¤¤¤ë¡£
¤É¤Î bit ¤¬¤É¤Îʸ»úÎó¤Ë¤Ê¤ë¤«¤Ï sysdeps/unix/sysv/linux/i386/dl-procinfo.c¤Î_dl_x86_cap_flags[][]¤Ç¤¢¤ë¡£Á°¤«¤é½ç¤Ë 1, 2, 4, ... ¤ËÂбþ¤·¤Æ¤¤¤ë¡£
LD_TRACE_PRELINKING ¤Ç¤É¤¦¥ê¥ó¥¯¤µ¤ì¤ë¤«¤ò³Îǧ¤Ç¤¤ë
% LD_TRACE_PRELINKING=1 ./hello
./hello => ./hello (0x08048000, 0x00000000)
libc.so.6 => /lib/libc.so.6 (0x4001c000, 0x4001c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000, 0x40000000)
lookup 0x4001c000 0x000053a0 -> 0x4001c000 0x00064dfc /0 _IO_file_close
lookup 0x4001c000 0x00005530 -> 0x4001c000 0x0010a1e0 /0 _IO_2_1_stdin_
lookup 0x4001c000 0x00004a50 -> 0x4001c000 0x0010a340 /0 _IO_2_1_stdout_
lookup 0x4001c000 0x0000b7e0 -> 0x4001c000 0x0010a4a0 /0 _IO_2_1_stderr_
LD_TRACE_LOADED_OBJECTS ¤Ï¤É¤Îshared libs¤òload¤¹¤ë¤«¤ò¸«¤ë¤³¤È¤¬¤Ç¤¤ë¡£
¤Ä¤Þ¤ê ldd ¤òƱ¤¸¤è¤¦¤ÊÆ°ºî¤ò¤¹¤ë¡£
% LD_TRACE_LOADED_OBJECTS=1 ./hello
libc.so.6 => /lib/libc.so.6 (0x4001c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
process_envvars()¤Î½èÍý¤Î¸å¤Ï /lib/ld-2.3.1.so ¤òľÀܸƤӤÀ¤·¤¿»þ¤Î
½èÍý¤¬¤µ¤ì¤Æ¤¤¤ë¡£
% /lib/ld-2.3.1.so
Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
You have invoked `ld.so', the helper program for shared library executables.
This program usually lives in the file `/lib/ld.so', and special directives
in executable files using ELF shared libraries tell the system's program
loader to load the helper program from this file. This helper program loads
the shared libraries needed by the program executable, prepares the program
to run, and runs it. You may invoke this helper program directly from the
command line to load and run an ELF executable file; this is like executing
that file itself, but always uses this helper program from the file you
specified, instead of the helper program file specified in the executable
file you run. This is mostly of use for maintainers to test new versions
of this helper program; chances are you did not intend to run this program.
--list list all dependencies and how they are resolved
--verify verify that given object really is a dynamically linked
object we can handle
--library-path PATH use given PATH instead of content of the environment
variable LD_LIBRARY_PATH
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names
in LIST
¤¿¤È¤¨¤Ð --list ¥ª¥×¥·¥ç¥ó¤Ï ldd ¤Î¤è¤¦¤ÊÆ°ºî¤ò¤¹¤ë¡£
% /lib/ld-2.3.1.so --list ./hello
libc.so.6 => /lib/libc.so.6 (0x4000a000)
/lib/ld-linux.so.2 => /lib/ld-2.3.1.so (0x80000000)
¤â¤·¤¯¤Ï¼¡¤Î¤è¤¦¤Ë¤¹¤ë¤ÈÉáÄ̤˼¹Ԥ¹¤ë¤³¤È¤â¤Ç¤¤ë¡£
% /lib/ld-2.3.1.so ./hello
hello, world
preloadlist != NULL ¤Î¥Á¥§¥Ã¥¯¤ò¤·¤Æ LD_PRELOAD ¤Î½èÍý¤ò¤·¤Æ¤¤¤ë¡£¤½¤Î¼¡¤Ë/etc/ld.so.preload¤ò¸«¤Æ¤ª¤Ê¤¸¤¯preload¤Î½èÍý¤ò¤¹¤ë¡£
preload¤Î¤ò½èÍý¤ò¤·¤Æ¤«¤éDT_NEEDED¤È¤µ¤ì¤Æ¤¤¤ëshared libs¤Î½èÍý¤ò¤ª¤³¤Ê¤¦¡£objdump -p ¤Ç Dynamic Secion (ưŪ¥»¥¯¥·¥ç¥ó)¤Ç NEEDED ¤Ë¤Ê¤Ã¤Æ¤¤¤ë shared libs ¤Ç¤¢¤ë¡£
% objdump -p ./hello
(ά)
ưŪ¥»¥¯¥·¥ç¥ó:
NEEDED libc.so.6
INIT 0x80482bc
FINI 0x804847c
(ά)
¤Ä¤Þ¤ê¤³¤Î¾ì¹ç¤Ï libc.so.6 ¤ò¥ê¥ó¥¯¤¹¤ë¡£
ºÇ½ªÅª¤Ë dl_main ¤Ç user_entry ¤Ë¥×¥í¥°¥é¥à¤Î³«»Ï¥¢¥É¥ì¥¹¤¬ÀßÄꤵ¤ì¡¢¤½¤ì¤¬
_dl_sysdep_start()¤Îreturn value¤È¤Ê¤Ã¤Æ start_addr ¤Ë¤Ê¤ê
start_addr = _dl_sysdep_start (arg, &dl_main);
¤³¤ì¤¬ _dl_start_final()¤Î return value ¤È¤Ê¤ë¡£
ElfW(Addr) entry = _dl_start_final (arg, &info);
¤³¤Î¸å
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
¤Ç _GLOBAL_OFFSET_TABLE_ ¤ËÂФ·¤ÆÀßÄê¤ò¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ïelf/dynamic-link.h¤Ç#define¤µ¤ì¤Æ¤ª¤ê¡¢¤³¤ÎÃæ¤Çsysdeps/i386/dl-machine.h¤Îelf_machine_runtime_setup()¤¬¤½¤ì¤ò¤·¤Æ¤¤¤ë¡£¤³¤ì¤Ë¤Ä¤¤¤Æ¤Ï¸å¤ËÀâÌÀ¤¹¤ë¡£
¤µ¤Æ entry ¤Ï¤½¤Î¸å
return ELF_MACHINE_START_ADDRESS (GL(dl_loaded), entry);
¤Ç¤µ¤é¤Ë _dl_start()¤Îreturn value¤È¤Ê¤Ã¤Æ sysdeps/i386/dl-machine.h ¤ÎRTLD_START¤Î¥³¡¼¥É¤Ë³¤ _dl_start_user()¤Ë¤¯¤ë¡£GOT¤Ê¤É¤òÀßÄꤷ¡¢ºÇ½ªÅª¤Ë
call _dl_start\n\
_dl_start_user:\n\
# Save the user entry point address in %edi.\n\
movl %eax, %edi\n\
(ά)
# Jump to the user's entry point.\n\
jmp *%edi\n\
¤Ç _dl_start()¤«¤é¤Îreturn value¤Î¥¢¥É¥ì¥¹¤Øjump¤·¥æ¡¼¥¶¤Î¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤¬³«»Ï¤µ¤ì¤ë¡£
hello: ¥Õ¥¡¥¤¥ë·Á¼° elf32-i386
hello
¥¢¡¼¥¥Æ¥¯¥Á¥ã: i386, ¥Õ¥é¥° 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
³«»Ï¥¢¥É¥ì¥¹ 0x08048340
¤Ê¤Î¤Ç³«»Ï¥¢¥É¥ì¥¹¤¬ 0x08048340 ¤Ê¤Î¤Ç
08048340 g F .text 00000000 _start
¤Ç _start ¤«¤é¼Â¹Ô¤¬³«»Ï¤µ¤ì¤ë¡£
08048340 <_start>:
8048340: 31 ed xor %ebp,%ebp
8048342: 5e pop %esi
8048343: 89 e1 mov %esp,%ecx
8048345: 83 e4 f0 and $0xfffffff0,%esp
8048348: 50 push %eax
8048349: 54 push %esp
804834a: 52 push %edx
804834b: 68 7c 84 04 08 push $0x804847c
8048350: 68 bc 82 04 08 push $0x80482bc
8048355: 51 push %ecx
8048356: 56 push %esi
8048357: 68 20 84 04 08 push $0x8048420
804835c: e8 a3 ff ff ff call 8048304 <_init+0x48>
8048361: f4 hlt
8048362: 90 nop
8048363: 90 nop
stack¤Ë°ú¿ô¤òpush¤·¤Æ¤¤¤Ã¤Æ
804835c: e8 a3 ff ff ff call 8048304 <_init+0x48>
¤Ç
8048304: ff 25 b4 95 04 08 jmp *0x80495b4
¤³¤³¤Ç¡¢0x80485a0¡Á¤¬ _GLOBAL_OFFSET_TABLE_ ¤Ê¤Î¤Ç¤³¤ì¤ò»²¾È¤·¤Æ
080495a0 <_GLOBAL_OFFSET_TABLE_>:
080495b4 ¤¬ 0a 83 04 08 ¤Ê¤Î¤Ç 0804830a ¤Ë jmp
804830a: 68 10 00 00 00 push $0x10
804830f: e9 c0 ff ff ff jmp 80482d4 <_init+0x18>
¤Á¤Ê¤ß¤Ë¤³¤Î¤¢¤¿¤ê¤Ï gdb ¤ò¤Ä¤«¤Ã¤Æ¤ß¤ë¤È
(gdb) disassemble 0x804830a
Dump of assembler code for function __libc_start_main:
0x8048304 <__libc_start_main>: jmp *0x80495b4
0x804830a <__libc_start_main+6>: push $0x10
0x804830f <__libc_start_main+11>: jmp 0x80482d4 <_init+24>
End of assembler dump.
¤È __libc_start_main ¤Ç¤¢¤ë¡£¤Á¤Ê¤ß¤Ë¤³¤Î¤¢¤¿¤ê¤Ï¥»¥¯¥·¥ç¥ó.plt¤Ç
¤³¤³¤ò disassemble ¤·¤Æ¤ß¤ë¤È
0x80482e4 <__register_frame_info>: jmp *0x80495ac
0x80482ea <__register_frame_info+6>: push $0x0
0x80482ef <__register_frame_info+11>: jmp 0x80482d4 <_init+24>
0x80482f4 <__deregister_frame_info>: jmp *0x80495b0
0x80482fa <__deregister_frame_info+6>: push $0x8
0x80482ff <__deregister_frame_info+11>: jmp 0x80482d4 <_init+24>
0x8048304 <__libc_start_main>: jmp *0x80495b4
0x804830a <__libc_start_main+6>: push $0x10
0x804830f <__libc_start_main+11>: jmp 0x80482d4 <_init+24>
0x8048314 : jmp *0x80495b8
0x804831a : push $0x18
0x804831f : jmp 0x80482d4 <_init+24>
0x8048324 : jmp *0x80495bc
0x804832a : push $0x20
0x804832f : jmp 0x80482d4 <_init+24>
¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£¤³¤³¤Ï¤É¤¦¤Ê¤Ã¤Æ¤¤¤ë¤«¤ò´Êñ¤ËÀâÌÀ¤·¤è¤¦¡£
¤Þ¤º_GLOBAL_OFFSET_TABLE_¤Ësymbol¤¬resolv¤µ¤ì¤¿¥¢¥É¥ì¥¹¤¬¤Ï¤¤¤ë¤³¤È¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£0x80495b4¤Ë³ÊǼ¤µ¤ì¤ë¥¢¥É¥ì¥¹¤¬¤µ¤·¤Æ¤¤¤ë¤Î¤¬ __libc_start_main¤Î¼ÂÂΤȤʤ롣¤¿¤À¤·ºÇ½é¤Ï¤Þ¤À¥Þ¥Ã¥×¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤Ç¡¢¤½¤Î¾ì¹ç¤Ï 0x804830a ¤ò¤µ¤·¤Æ¤¤¤ë¡£¤³¤³¤Ë¤¯¤ë¤È push $0x10 ¤·¤Æ jmp 0x80482d4 ¤Ç¤¢¤ë¡£0x80482d4¤Ç¤Ï¤Ê¤Ë¤ò¤·¤Æ¤¤¤ë¤«¤È¤¤¤¦¤È
80482d4: ff 35 a4 95 04 08 pushl 0x80495a4
80482da: ff 25 a8 95 04 08 jmp *0x80495a8
¤Ç¤¢¤ë¡£¤³¤³¤Ç 0x80495a8 ¤Ï _GLOBAL_OFFSET_TABLE_ ¤¬ 080495a0 ¤Ê¤Î¤Ç
_GLOBAL_OFFSET_TABLE_[2] ¤ËÁêÅö¤·¤Æ¤¤¤ë¡£¤³¤³¤Ë¤Ï¼Â¤Ï sysdeps/i386/dl-machine.h ¤Î elf_machine_runtime_setup() ¤Ë¤è¤ê
got[1] = (Elf32_Addr) l; /* Identify this shared object. */
got[2] = (Elf32_Addr) &_dl_runtime_resolve;
¤Î¤è¤¦¤ÊÃͤ¬ÂåÆþ¤µ¤ì¤ë¡£¤Ä¤Þ¤ê jmp *0x80495a8 ¤Ç _dl_runtime_resolve()¤ò¸Æ¤Ö¤³¤È¤Ë¤Ê¤ë¡£_dl_runtime_resolv ¤Ï sysdeps/i386/dl-machine.h ¤Ë¤¢¤êelf/dl-runtime.c ¤Î fixup()¤ò¸Æ¤Ö¡£fixup()¤¬shared libs¤È¤Îsymbol¤Îresolve¤ò¤ª¤³¤Ê¤Ã¤Æ¡¢¤³¤Î¾ì¹ç¤Ï __libc_start_main() ¤ò libc.so.6 ¤ÎÃæ¤Î¥ë¡¼¥Á¥ó¤òº¹¤¹¤è¤¦¤Ë¥¢¥É¥ì¥¹¤ò_GLOBAL_OFFSET_TABLE_ ¤ËÅÐÏ¿¤¹¤ë¡£¤½¤¦¤¹¤ë¤³¤È¤Ç¤Þ¤¿Æ±¤¸¥ë¡¼¥Á¥ó¤ò¸Æ¤Ö¤È¤¤Ï
0x8048304 <__libc_start_main>: jmp *0x80495b4
¤Ç 0x80495b4¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¥¢¥É¥ì¥¹¤¬ËÜÅö¤Î¥ë¡¼¥Á¥ó¤Ø¤Î¥¢¥É¥ì¥¹¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤Î¤Çresolve¤¹¤ëɬÍפâ¤Ê¤¯¤½¤³¤Ëjmp¤¹¤ë¤è¤¦¤Ë¤Ê¤ë¡£__libc_start_main()¤Î¼ÂÂΤÏlibc.so.6 ¤Ç ¤³¤ì¤Ï sysdeps/generic/libc-start.c ¤ÎÃæ¤Ë¤¢¤ë¡£¤½¤·¤Æ¤¤¤í¤¤¤í½èÍý¤ò¤·¤¿¸åºÇ½ªÅª¤Ë
result = main (argc, argv, __environ);
¤Ç main()¤ò¸Æ¤Ö¤³¤È¤Ë¤Ê¤ë¡£¤³¤ì¤Ç¤è¤¦¤ä¤¯
int
main(int argc, char *argv[])
{
printf("hello, world\n");
exit(0);
}
¤Þ¤Ç¤¤¿¤³¤È¤Ë¤Ê¤ë¡£¤¢¤È¤Ï¤³¤ì¤ò¼Â¹Ô¤Ç¤¢¤ë¡£¤â¤Á¤í¤ó printf ¤ä exit ¤Ê¤É¤Ï__libc_start_main()¤ÇÀâÌÀ¤·¤¿¤è¤¦¤Êfixup¤¬¤ª¤³¤Ê¤ï¤ì¤Ælibc.so.6¤Èlink¤µ¤ì¤Æ¤½¤ì¤é¤¬¼Â¹Ô¤µ¤ì¤ë¤È¤¤¤¦½èÍý¤¬¤ª¤³¤Ê¤ï¤ì¤ë¡£ºÇ¸å¤Ë
exit (result);
¤Ç exit½èÍý¤ò¤¹¤ë¡£exit()¤âsystem call¤Ç¤¢¤ë¤«¤éexecve()¤Î»þ¤Î¤è¤¦¤Ësysdeps/unix/sysv/linux/_exit.c¤Î
INLINE_SYSCALL (exit, 1, status);
¤Ë¤è¤ê system call 1 (__NR_exit) ¤¬¤è¤Ó¤À¤µ¤ì
ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system ca
ll*/
.long SYMBOL_NAME(sys_exit)
¤«¤é kernel/exit.c ¤Î asmlinkage long sys_exit(int error_code)¤«¤éprocess¤¬¤â¤Ã¤Æ¤¤¤¿resource¤Î²òÊü¤ò¤·¤Æreschedule()¤·¤Æ¾¤Î¥×¥í¥»¥¹¤Ë½èÍý¤ò¤ï¤¿¤·¤Æ¤ª¤ï¤ê¤Ç¤¢¤ë¡£¤¢¤È¤Ï¿Æ¥×¥í¥»¥¹¤¬ wait¤Ç tsk->exit_code ¤Ë¤Î¤³¤Ã¤Æ¤¤¤ë½ªÎ»¥³¡¼¥É¤ò¤Ò¤í¤Ã¤Æ¤â¤é¤¨¤ë¤Þ¤Ç zombie ¾õÂ֤ȤʤäƤ¤¤ë¤Î¤Ç¤¢¤ë¡£¤³¤ì¤Ç¥×¥í¥»¥¹¤Î°ìÀ¸¤¬¤ª¤ï¤ê¤Ç¤¢¤ë¡£¤³¤Î¸¶¹Æ¤â¤³¤³¤Ç¤ª¤·¤Þ¤¤¡£
¤ª¤Þ¤±:
yaegashiÀèÀ¸¤«¤éreadelf(1)¤Ï»È¤ï¤Ê¤¤¤Î¤« ¤È¤¤¤¦»ØŦ¤¬¤¢¤Ã¤¿¤±¤ì¤É¤â¡¢¤â¤¦ÃÙ¤¤¤Î¤Ç¤«¤¤Ê¤ª¤¹¤Î¤Ï¤ä¤á¤Æ¤ª¤¤Þ¤¹¡£readelf(1)¤â¤Ä¤«¤Ã¤Æ¤¤¤í¤¤¤íÍ·¤ó¤Ç¤ß¤ë¤Î¤Ï½ÉÂê¤Ë¤·¤Æ¤ª¤¤Þ¤·¤ç¤¦:-)