http://www.technovelty.org/linux/linux-gate.htmlA little tour of linux-gate.soA few people have noticed and wondered what
i...@morrison:~$ ldd /bin/ls
linux-gate.so.1 => (0xffffe000)
librt.so.1 => /lib/tls/librt.so.1 (0xb7fdb000)
libacl.so.1 => /lib/libacl.so.1 (0xb7fd5000)
libc.so.6 => /lib/tls/libc.so.6 (0xb7e9c000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7e8a000)
/lib/ld-linux.so.2 (0xb7feb000)
libattr.so.1 => /lib/libattr.so.1 (0xb7e86000)
It's actually a shared library that is exported by the kernel to
provide a way to make system calls faster. Most architectures have
ways of making system calls that are less expensive than taking a full
trap; If you want the gist of how it works, first we can pull it apart.
The following program reads and dumps the so on a x86 machine. Note
it's just a kernel page, so you can just dump
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <elf.h> #include <alloca.h>
int main(void)
{
int i;
unsigned size = 0;
char *buf;
Elf32_Ehdr *so = (Elf32_Ehdr*)0xffffe000;
Elf32_Phdr *ph = (Elf32_Phdr*)((void*)so + so->e_phoff);
size += so->e_ehsize + (so->e_phentsize * so->e_phnum);
for (i = 0 ; i < so->e_phnum; i++)
{
size += ph->p_memsz;
ph = (void*)ph + so->e_phentsize;
}
buf = alloca(size);
memcpy(buf, so, size);
int f = open("./kernel-gate.so", O_CREAT|O_WRONLY, S_IRWXU);
int w = write(f, buf, size);
printf("wrote %d (%s)\n", w, strerror(errno));
}
At this stage you should have a binary you can look at with, say
i...@morrison:~/tmp$ readelf --symbols ./kernel-gate.so
Symbol table '.dynsym' contains 15 entries:
Num: Value Size Type Bind Vis Ndx Name
[--snip--]
11: ffffe400 20 FUNC GLOBAL DEFAULT 6 __kernel_vsyscall@@LINUX_2.5
12: 00000000 0 OBJECT GLOBAL DEFAULT ABS LINUX_2.5
13: ffffe440 7 FUNC GLOBAL DEFAULT 6 __kernel_rt_sigreturn@@LINUX_ 2.5
14: ffffe420 8 FUNC GLOBAL DEFAULT 6 __kernel_sigreturn@@LINUX_2.5
It's easy if you poke inside the auxiliary vector that is passed to
i...@morrison:~/tmp$ LD_SHOW_AUXV=1 /bin/true AT_SYSINFO: 0xffffe400 AT_SYSINFO_EHDR: 0xffffe000 AT_HWCAP: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe AT_PAGESZ: 4096 AT_CLKTCK: 100 AT_PHDR: 0x8048034 AT_PHENT: 32 AT_PHNUM: 7 AT_BASE: 0xb7feb000 AT_FLAGS: 0x0 AT_ENTRY: 0x8048960 AT_UID: 1000 AT_EUID: 1000 AT_GID: 1000 AT_EGID: 1000 AT_SECURE: 0 AT_PLATFORM: i686 Notice how the If you start to poke through the IA64 works in the same way, although we keep our kernel shared
library at posted at: Mon, 15 Aug 2005 15:06 | in /linux | permalink | add comment (0 others) |
