katsusan / gowiki

0 stars 0 forks source link

when-go-binary-elf-loaded(1) #7

Open katsusan opened 4 years ago

katsusan commented 4 years ago

Address space

以linux-amd64为例,程序入口点为_rt0_amd64_linux,此时rsp指向的值为argc,rsp+0x8指向argv[0]的地址,依次计算。

下面是一个例子,运行/tmp/newobj acb 234 xxx,刚运行到entry point时内存分布如下: addr value comment
0x7ffffffee7d0 0x0000000000000000 ELF Auxiliary Vector结束
0x7ffffffee7c8 0x00007ffffffee810 AT_PLATFORM的值,指向"x86_64"
0x7ffffffee7c0 0x000000000000000f 0xf,代表AT_PLATFORM
... ... ...
0x7ffffffee6c8 0x000000001f8bfbff AT_HWCAP的值
0x7ffffffee6c0 0x0000000000000010 0x10,代表AT_HWCAP
0x7ffffffee6b8 0x00007ffffffef000 AT_SYSINFO_EHDR的值
0x7ffffffee6b0 0x0000000000000021 0x21,代表AT_SYSINFO_EHDR
0x7ffffffee6a8 0x0000000000000000 NULL,上面为ELF Auxiliary Vector的值
... ... ...
0x7ffffffee600 0x00007ffffffee82f env[0],即"TERM=xterm-256"的地址
0x7ffffffee5f8 0x0000000000000000 NULL,上面为环境变量的地址
0x7ffffffee5f0 0x00007ffffffee82b rsp+0x20,argv[3]即"xxx"的地址
0x7ffffffee5e8 0x00007ffffffee827 rsp+0x18, argv[2]即"234"的地址
0x7ffffffee5e0 0x00007ffffffee823 rsp+0x10, argv[1]即"acb"的地址
0x7ffffffee5d8 0x00007ffffffee817 rsp+0x8, argv[0]即“tmp/newobj”的地址
0x7ffffffee5d0 0x0000000000000004 rsp, argc=4

关于ELF Auxiliary Vector

ELF Auxiliary Vector可以用来传递内核信息给用户空间,参考About ELF Auxiliary Vectors 其值定义在include/uapi/linux/auxvec.h和arch/ia64/include/uapi/asm/auxvec.h。

#define AT_NULL   0 /* end of vector */
#define AT_IGNORE 1 /* entry should be ignored */
#define AT_EXECFD 2 /* file descriptor of program */
#define AT_PHDR   3 /* program headers for program */
#define AT_PHENT  4 /* size of program header entry */
#define AT_PHNUM  5 /* number of program headers */
#define AT_PAGESZ 6 /* system page size */
#define AT_BASE   7 /* base address of interpreter */
#define AT_FLAGS  8 /* flags */
#define AT_ENTRY  9 /* entry point of program */
#define AT_NOTELF 10    /* program is not ELF */
#define AT_UID    11    /* real uid */
#define AT_EUID   12    /* effective uid */
#define AT_GID    13    /* real gid */
#define AT_EGID   14    /* effective gid */
#define AT_PLATFORM 15  /* string identifying CPU for optimizations */
#define AT_HWCAP  16    /* arch dependent hints at CPU capabilities */
#define AT_CLKTCK 17    /* frequency at which times() increments */
/* AT_* values 18 through 22 are reserved */
#define AT_SECURE 23   /* secure mode boolean */
#define AT_BASE_PLATFORM 24 /* string identifying real platform, may
                 * differ from AT_PLATFORM. */
#define AT_RANDOM 25    /* address of 16 random bytes */
#define AT_HWCAP2 26    /* extension of AT_HWCAP */

#define AT_EXECFN  31   /* filename of program */

#define AT_SYSINFO  32            /*vsyscall entry point at some architectures, use should be avoided*/
#define AT_SYSINFO_EHDR 33  /*vDSO base address*/

可以执行LD_SHOW_AUXV=1 /bin/true来查看ELF Auxiliary Vector的值。

➜  /tmp LD_SHOW_AUXV=1 /bin/true
AT_SYSINFO_EHDR: 0x7fffe7a76000
AT_HWCAP:        1f8bfbff
AT_PAGESZ:       4096
AT_CLKTCK:       100
AT_PHDR:         0x7ff3be600040
AT_PHENT:        56
AT_PHNUM:        9
AT_BASE:         0x7ff3be200000
AT_FLAGS:        0x0
AT_ENTRY:        0x7ff3be6017b0
AT_UID:          0
AT_EUID:         0
AT_GID:          0
AT_EGID:         0
AT_SECURE:       0
AT_RANDOM:       0x7fffe76df820
AT_EXECFN:       /bin/true
AT_PLATFORM:     x86_64

view example

image