王朝网络
分享
 
 
 

把共享库(SO)加载到指定的内存地址

王朝other·作者佚名  2006-07-04
宽屏版  字体: |||超大  

把共享库(SO)加载到指定的内存地址

一位朋友最近遇到一个棘手的问题,希望把共享库(SO)加载到指定的内存地址,目的可能是想通过prelink来加快应用程序的起动速度。他问我有没有什么方法。我知道Windows下是可以的,比如在VC6里设置/base的值就行了,所以相信在linux下也是可行的。

VC有编译选项可以设置,猜想gcc也应该有吧。gcc本身只是一个外壳,链接工作是由于ld完成的,当然是应该去阅读ld命令行选项文档。很快发现ld有个—image-base选项,可以设置动态库的加载地址。

通过Xlinker把这个参数传递给ld,但是ld不能识别这个选项:

gcc -g -shared test.c -Xlinker --image-base -Xlinker 0x00c00000 -o libtest.so

/usr/bin/ld: unrecognized option '--image-base'

/usr/bin/ld: use the --help option for usage information

collect2: ld returned 1 exit statu

s

再仔细看手册,原来这个选项只适用于PE文件,PE文件是Windows下专用的,在linux下自然用不了,看来得另想办法。

我知道ld script可以控制ld的行为,于是研究ld script的写法,按照手册里的说明,写了一个简单的ld script:

SECTIONS

{

. = 0x00c00000;

.text : { *(.text) }

.data : { *(.data) }

.bss : { *(.bss) }

}

按下列方式编译:

gcc -shared -g -Xlinker --script -Xlinker ld.s test.c -o libtest.so

gcc -g main.c -L./ -ltest -o test.exe

用ldd查看,加载地址正确。

[root@localhost lds]# ldd test.exe

linux-gate.so.1 => (0x00aff000)

libtest.so => ./libtest.so (0x00c00000)

libc.so.6 => /lib/libc.so.6 (0x007fa000)

/lib/ld-linux.so.2 (0x007dd000)

但运行时会crash:

[root@localhost lds]# ./test.exe

Segmentation fault

调试运行可以发现:

(gdb) r

Starting program: /work/test/lds/test.exe

Reading symbols from shared object read from target memory...done.

Loaded system supplied DSO at 0x452000

Program received signal SIGSEGV, Segmentation fault.

0x007e7a10 in _dl_relocate_object () from /lib/ld-linux.so.2

(gdb) bt

#0 0x007e7a10 in _dl_relocate_object () from /lib/ld-linux.so.2

#1 0x007e0833 in dl_main () from /lib/ld-linux.so.2

#2 0x007f056b in _dl_sysdep_start () from /lib/ld-linux.so.2

#3 0x007df48f in _dl_start () from /lib/ld-linux.so.2

#4 0x007dd847 in _start () from /lib/ld-linux.so.2

猜想可能是ld.s写得不全,导致一些信息不正确。于是用ld –verbose导出一个默认的ld script。不出所料,默认的ld script非常冗长,下面是开头一段:

/* Script for -z combreloc: combine and sort reloc sections */

OUTPUT_FORMAT("elf32-i386", "elf32-i386",

"elf32-i386")

OUTPUT_ARCH(i386)

ENTRY(_start)

SEARCH_DIR("/usr/i386-redhat-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");

SECTIONS

{

/* Read-only sections, merged into text segment: */

PROVIDE (__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS;

.interp : { *(.interp) }

.hash : { *(.hash) }

.dynsym : { *(.dynsym) }

.dynstr : { *(.dynstr) }

.gnu.version : { *(.gnu.version) }

.gnu.version_d : { *(.gnu.version_d) }

.gnu.version_r : { *(.gnu.version_r) }

按照ld script的语法,我把它修改为(红色部分为新增行):

/* Script for -z combreloc: combine and sort reloc sections */

OUTPUT_FORMAT("elf32-i386", "elf32-i386",

"elf32-i386")

OUTPUT_ARCH(i386)

ENTRY(_start)

SEARCH_DIR("/usr/i386-redhat-linux/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");

SECTIONS

{

/* Read-only sections, merged into text segment: */

PROVIDE (__executable_start = 0x08048000); . = 0x08048000 + SIZEOF_HEADERS;

. = 0x00c00000;

.interp : { *(.interp) }

.hash : { *(.hash) }

.dynsym : { *(.dynsym) }

.dynstr : { *(.dynstr) }

.gnu.version : { *(.gnu.version) }

.gnu.version_d : { *(.gnu.version_d) }

.gnu.version_r : { *(.gnu.version_r) }

用这个ld script再次测试,一切正常。又验证多个共享库的情况,也正常,下面是测试数据:

test.c

int test(int n)

{

return n;

}

test1.c

int test1(int n)

{

return n;

}

main.c

extern int test(int n);

extern int test1(int n);

#include <stdio.h>

int main(int argc, char* argv[])

{

printf("Hello: %d %d\n", test(100), test1(200));

getchar();

return 0;

}

Makefile

all:

gcc -shared -g -Xlinker --script -Xlinker ld.s test.c -o libtest.so

gcc -shared -g -Xlinker --script -Xlinker ld1.s test1.c -o libtest1.so

gcc -g main.c -L./ -ltest -ltest1 -o test.exe

clean:

rm -f *.so *.exe

libtest.so的加载地址为:0x00c00000

libtest1.so的加载地址为:0x00d00000

ldd显示结果:

linux-gate.so.1 => (0x00aa3000)

libtest.so => ./libtest.so (0x00c00000)

libtest1.so => ./libtest1.so (0x00d00000)

libc.so.6 => /lib/libc.so.6 (0x007fa000)

/lib/ld-linux.so.2 (0x007dd000)

maps的内容为:

007dd000-007f6000 r-xp 00000000 03:01 521466 /lib/ld-2.4.so

007f6000-007f7000 r-xp 00018000 03:01 521466 /lib/ld-2.4.so

007f7000-007f8000 rwxp 00019000 03:01 521466 /lib/ld-2.4.so

007fa000-00926000 r-xp 00000000 03:01 523579 /lib/libc-2.4.so

00926000-00929000 r-xp 0012b000 03:01 523579 /lib/libc-2.4.so

00929000-0092a000 rwxp 0012e000 03:01 523579 /lib/libc-2.4.so

0092a000-0092d000 rwxp 0092a000 00:00 0

00c00000-00c01000 r-xp 00001000 03:03 16370 /work/test/ldsex/libtest.so

00c01000-00c02000 rwxp 00001000 03:03 16370 /work/test/ldsex/libtest.so

00cf1000-00cf2000 r-xp 00cf1000 00:00 0 [vdso]

00d00000-00d01000 r-xp 00001000 03:03 16373 /work/test/ldsex/libtest1.so

00d01000-00d02000 rwxp 00001000 03:03 16373 /work/test/ldsex/libtest1.so

08048000-08049000 r-xp 00000000 03:03 16374 /work/test/ldsex/test.exe

08049000-0804a000 rw-p 00000000 03:03 16374 /work/test/ldsex/test.exe

b7fdf000-b7fe0000 rw-p b7fdf000 00:00 0

b7fed000-b7ff0000 rw-p b7fed000 00:00 0

bf8db000-bf8f0000 rw-p bf8db000 00:00 0 [stack]

从以上测试结果可以看出,这种方法是可行的。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有