QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1084|回复: 13

怎样制作动态连接器和转交控制权?

[复制链接]
发表于 2005-1-21 21:06:34 | 显示全部楼层 |阅读模式
该动态连接器功能如下:
当用户应用程序指定连接我的动态连接器而不是ld-linux.so.1时
该动态连接器将取得本进程的text, data段。对data段进行扩充,比如原来4 或8k/page 扩充到4M/page. 执行完后,将控制权递交给ld-linux.so.1
以上动作必须在main之前完成
现在不知道怎样制作动态连接器。入口是什么?_libc_main_start ?
怎样将控制权转交给ld-linux.so.1
发表于 2005-1-23 13:55:22 | 显示全部楼层
深奥
回复

使用道具 举报

 楼主| 发表于 2005-1-24 11:16:41 | 显示全部楼层
给各位大虾鞠躬:请求帮助,急!
最主要功能就是我要代替系统分配的data段(8k/page),因为用户程序需要大页面(4M/page).就是内存管理。现在基本实现方法有了。但是对怎样书写动态连接器不了解,入口是什么?
回复

使用道具 举报

发表于 2005-1-24 13:54:58 | 显示全部楼层
说实话,没完全看懂你的需求。
一块研究一下。

琢磨了一下,看了眼linux内核的文档 linux-2.6.x\Documentation\vm\hugetlbpage.txt,总结了下面几点。

1。觉得可能要改内核,至少使用4MB物理页是编译内核时的选项。

2。可执行文件使用那个解释器来执行是在可执行文件里写好的,例如使用ld-linux.so.2,内核通过这个字串来调用相应的解释器。

3。你的可执行文件显然需要书写定制的ld 脚本,来保证数据段是4MB对齐的,因为数据的访问地址是编译时写死的具体值。

4。我的想象,动态连接器应该是分析elf文件的段信息,然后通过mmap调用把各段映射入内存,我想你应该参考一下readelf这个命令以及elf文件的格式说明文档。


小建议,你的问题很新鲜有难度,如果不牵涉商业秘密的话,应该把你的进度想法贴出来供大家参考。
回复

使用道具 举报

 楼主| 发表于 2005-1-25 13:06:00 | 显示全部楼层
谢谢斑竹
实际上elf文件结构我已经看了。readelf也用来分析了。
但是项目对方要求使用自己的动态连接器实现。
我的构想是:
1 写一个daemon用于获取hugepage.(shmget(2))
  2 用户应用程序链接我的动态连接库lpgld.so
    2.1 lpgld.so通过signal和Daemon通信,获取hugepage
    2.2 lpgld.so插入large page 到用户应用程序的data(可能是对elf文件解析,得到Program header, 从header中获取data段首地址,用large page得地质代替)
   2.3 lpgld.so拷贝data段数据到llarge page
  3 释放large page
    请问斑竹,gcc有没有一个选项,在编译是插入一段代码到.fini段最后阿?
回复

使用道具 举报

发表于 2005-1-25 17:38:42 | 显示全部楼层
个人意见,我认为你的想法是错的。

考虑这样的程序

[code:1]
int  a_global_variable;

void a_function(...) {
      ....
      a_global_variable = 123;
      .....
}
[/code:1]

连接器ld会为a_global_variable分配一个固定地址,例如0x8100a000,
其它访问a_global_variable的地方也会变成对0x8100a000地址的直接访问。

shmget并不能保证分配的地址是你需要的地方,而且它是寻找一块未占用的地址,
而.data区是已分配的。


所以,我认为,程序一但开始运行,你就没有什么办法了,因为那时各个段必须已经建立完映射了。
应该是重写一个装载器,由装载器取大页。同时,你要改写系统缺省的ld 编译脚本,让程序的各个段按照4MB边界对齐

由于目前linux内核还无法透明的提供大页支持,
回复

使用道具 举报

发表于 2005-1-25 18:06:21 | 显示全部楼层
只有瞪眼的份
回复

使用道具 举报

 楼主| 发表于 2005-1-26 11:51:01 | 显示全部楼层
所以我打算在main之前完成替换工作。用户在连接我的连接器到应用程序后,执行时,系统先调用我的连接器,实现替换后,将控制权转交ld.so。ld.so运行完后,执行main.
回复

使用道具 举报

 楼主| 发表于 2005-1-26 11:57:35 | 显示全部楼层
装载器的书写,应该怎样啊?
回复

使用道具 举报

发表于 2005-1-26 13:03:27 | 显示全部楼层
我认为不是在main之前,而是在你的程序装入内存之前,由你的装载器来完成各个段的映射。

你可以用命令ld --verbose来查看缺省的连接脚本。仔细看里面的内容
里面对段有ALIGN(0x1000),意思是说生成二进制elf时对段按照4kb对齐。
这有份ld脚本的教程
http://es-sun2.fernuni-hagen.de/cgi-bin/info2html?(ld)Scripts

你也可以在连接时使用参数
  -Tbss ADDRESS               Set address of .bss section
  -Tdata ADDRESS              Set address of .data section
  -Ttext ADDRESS              Set address of .text section
来制定段的起始地址

因为ld.so要进行真正的装载,有两个装载器我觉得是不可行的,所以我觉得唯一可行的
方案就是hack glibc中ld.so的source,让它当发现段是4MB对齐时使用大页。
回复

使用道具 举报

 楼主| 发表于 2005-1-26 15:46:46 | 显示全部楼层
装载器的书写,应该怎样啊?
回复

使用道具 举报

 楼主| 发表于 2005-1-26 15:51:03 | 显示全部楼层
谢谢斑竹,如果可能的话,我会把我的进度发出来供大家参考。
回复

使用道具 举报

 楼主| 发表于 2005-1-27 10:18:26 | 显示全部楼层
还有一个问题:(请教斑竹)线程的stack可以使用Huge TLB吗?
回复

使用道具 举报

发表于 2005-1-28 14:33:43 | 显示全部楼层
[quote:d1c4cee503="mozilla"]只有瞪眼的份 [/quote]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-6 17:26 , Processed in 0.042671 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表