- 论坛徽章:
- 0
|
关于linux 系统中用户进程的加载和执行过程,想必坛子中的弟兄们都比较了解了,如果不了解,可以参考这篇文章
http://bbs.chinaunix.net/thread-1929850-1-1.html ,毛兄这篇文章比较详细的介绍了elf格式的进程加载和执行,
但是关于连接解释器如何加载共享库没有详细介绍,由于linux 共享库加载到进程中的地址是由系统决定的,应该是从进程的开始
地址偏移一个固定地址开始映射共享库,但是load_elf_library 函数中映射共享库的代码居然没有这个偏移量,不知道为什么,
看代码:
static int load_elf_library(struct file *file)
{
struct elf_phdr *elf_phdata;
struct elf_phdr *eppnt;
unsigned long elf_bss, bss, len;
int retval, error, i, j;
struct elfhdr elf_ex;
error = -ENOEXEC;
retval = kernel_read(file, 0, (char *)&elf_ex, sizeof(elf_ex));
if (retval != sizeof(elf_ex))
goto out;
if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
goto out;
/* First of all, some simple consistency checks */
if (elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
!elf_check_arch(&elf_ex) || !file->f_op->mmap)
goto out;
/* Now read in all of the header information */
j = sizeof(struct elf_phdr) * elf_ex.e_phnum;
/* j < ELF_MIN_ALIGN because elf_ex.e_phnum <= 2 */
error = -ENOMEM;
elf_phdata = kmalloc(j, GFP_KERNEL);
if (!elf_phdata)
goto out;
eppnt = elf_phdata;
error = -ENOEXEC;
retval = kernel_read(file, elf_ex.e_phoff, (char *)eppnt, j);
if (retval != j)
goto out_free_ph;
for (j = 0, i = 0; i<elf_ex.e_phnum; i++)
if ((eppnt + i)->p_type == PT_LOAD)
j++;
if (j != 1)
goto out_free_ph;
while (eppnt->p_type != PT_LOAD)
eppnt++;
/* Now use mmap to map the library into memory. */
error = vm_mmap(file,
ELF_PAGESTART(eppnt->p_vaddr),
(eppnt->p_filesz +
ELF_PAGEOFFSET(eppnt->p_vaddr)),
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
(eppnt->p_offset -
ELF_PAGEOFFSET(eppnt->p_vaddr)));
if (error != ELF_PAGESTART(eppnt->p_vaddr))
goto out_free_ph;
elf_bss = eppnt->p_vaddr + eppnt->p_filesz;
if (padzero(elf_bss)) {
error = -EFAULT;
goto out_free_ph;
}
len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
ELF_MIN_ALIGN - 1);
bss = eppnt->p_memsz + eppnt->p_vaddr;
if (bss > len)
vm_brk(len, bss - len);
error = 0;
out_free_ph:
kfree(elf_phdata);
out:
return error;
}
看vm_mmap 函数,此共享库的起始映射地址直接被设置成共享库编译后设置的地址,我认为应该给这个地址加一个固定的偏移量才对,不知道坛子中的弟兄谁对共享库加载过程比较熟悉,帮忙讲一下这个函数。
谢谢
|
|