亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2068 | 回復: 2
打印 上一主題 下一主題

[內(nèi)核入門] 關(guān)于load_elf_library 函數(shù)的一點疑問 [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2015-08-16 12:52 |只看該作者 |倒序瀏覽

關(guān)于linux 系統(tǒng)中用戶進程的加載和執(zhí)行過程,想必壇子中的弟兄們都比較了解了,如果不了解,可以參考這篇文章
http://72891.cn/thread-1929850-1-1.html  ,毛兄這篇文章比較詳細的介紹了elf格式的進程加載和執(zhí)行,
但是關(guān)于連接解釋器如何加載共享庫沒有詳細介紹,由于linux 共享庫加載到進程中的地址是由系統(tǒng)決定的,應該是從進程的開始
地址偏移一個固定地址開始映射共享庫,但是load_elf_library 函數(shù)中映射共享庫的代碼居然沒有這個偏移量,不知道為什么,

看代碼:

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 函數(shù),此共享庫的起始映射地址直接被設置成共享庫編譯后設置的地址,我認為應該給這個地址加一個固定的偏移量才對,不知道壇子中的弟兄誰對共享庫加載過程比較熟悉,幫忙講一下這個函數(shù)。
謝謝

論壇徽章:
0
2 [報告]
發(fā)表于 2015-08-17 09:12 |只看該作者
沒人頂,自己先頂一下

論壇徽章:
20
程序設計版塊每日發(fā)帖之星
日期:2015-08-17 06:20:00程序設計版塊每日發(fā)帖之星
日期:2016-07-16 06:20:00程序設計版塊每日發(fā)帖之星
日期:2016-07-18 06:20:00每日論壇發(fā)貼之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16賽季CBA聯(lián)賽之江蘇
日期:2017-06-26 11:05:5615-16賽季CBA聯(lián)賽之上海
日期:2017-07-21 18:12:5015-16賽季CBA聯(lián)賽之青島
日期:2017-09-04 17:32:0515-16賽季CBA聯(lián)賽之吉林
日期:2018-03-26 10:02:16程序設計版塊每日發(fā)帖之星
日期:2016-07-15 06:20:0015-16賽季CBA聯(lián)賽之江蘇
日期:2016-07-07 18:37:512015亞冠之薩濟拖拉機
日期:2015-08-17 12:21:08
3 [報告]
發(fā)表于 2015-08-17 12:19 |只看該作者
沒法直接回答樓主的問題,提供一個現(xiàn)象,僅供參考。
同一個程序b,鏈接兩個so,liba1.so和liba2.so,后者的elf內(nèi)容基本一致,但顯然兩個庫最終會加載到不同的線性地址。
  1. [shlib]$ cat a1.c
  2. int add1(int x)
  3. {
  4.         return x + 1;
  5. }
  6. [shlib]$ cat a2.c
  7. int add2(int x)
  8. {
  9.         return x + 2;
  10. }
  11. [shlib]$ cat Makefile
  12. b: b.c liba1.so liba2.so
  13.         gcc -o $@ $< -Wl,-rpath=./ -L. -la1 -la2
  14. lib%.so: %.c
  15.         gcc -c -fPIC $<
  16.         gcc -o $@ -shared ${<:.c=.o}

  17. [shlib]$ readelf -l -W liba1.so liba2.so
  18. File: liba1.so
  19. Program Headers:
  20.   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  21.   LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0005dc 0x0005dc R E 0x200000
  22.   LOAD           0x0005e0 0x00000000002005e0 0x00000000002005e0 0x0001e8 0x0001f8 RW  0x200000
  23.   DYNAMIC        0x000610 0x0000000000200610 0x0000000000200610 0x000180 0x000180 RW  0x8
  24. File: liba2.so
  25. Program Headers:
  26.   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  27.   LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0005dc 0x0005dc R E 0x200000
  28.   LOAD           0x0005e0 0x00000000002005e0 0x00000000002005e0 0x0001e8 0x0001f8 RW  0x200000
  29.   DYNAMIC        0x000610 0x0000000000200610 0x0000000000200610 0x000180 0x000180 RW  0x8
復制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP