ºìÁªLinuxÃÅ»§
Linux°ïÖú

linuxÏ°ѹ²Ïí¿â(SO)¼ÓÔص½Ö¸¶¨µÄÄÚ´æµØÖ·

·¢²¼Ê±¼ä:2008-03-08 00:25:15À´Ô´:ºìÁª×÷Õß:Prospects
һλÅóÓÑ×î½üÓöµ½Ò»¸ö¼¬ÊÖµÄÎÊÌ⣬ϣÍû°Ñ¹²Ïí¿â(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ÔٴβâÊÔ£¬Ò»ÇÐÕý³£¡£ÓÖÑéÖ¤¶à¸ö¹²Ïí¿âµÄÇé¿ö£¬Ò²Õý³££¬ÏÂÃæÊDzâÊÔÊý¾Ý£º

test.c
int test(intn)
{
returnn;
}

test1.c
inttest1(intn)
{
returnn;
}

main.c
externinttest(intn);
externinttest1(intn);
#include

intmain(intargc, 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]

´ÓÒÔÉϲâÊÔ½á¹û¿ÉÒÔ¿´³ö£¬ÕâÖÖ·½·¨ÊÇ¿ÉÐеġ£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ