我可以链接除特定符号以外的库吗?

时间:2018-09-17 12:19:20

标签: assembly x86 linker dynamic-linking dynamic-library

条件1。 我有myassembly.s,而没有main

条件2。 相反,myassembly.s具有全局符号 _start

条件3。 我想链接_IO_stdin_used以输出二进制文件。

...这是有问题的部分。
如您所见,_IO_stdin_used已在crt1.o上声明:

jiwon@jiwon:/tmp$ readelf -s /usr/lib/i386-linux-gnu/crt1.o
Symbol table '.symtab' contains 17 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 SECTION LOCAL  DEFAULT    1 
     ...
     8: 00000000     4 OBJECT  GLOBAL DEFAULT    4 _fp_hw
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_csu_fini
    10: 00000000     0 FUNC    GLOBAL DEFAULT    2 _start
    11: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_csu_init
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND main
    13: 00000000     0 NOTYPE  WEAK   DEFAULT    6 data_start
    14: 00000000     4 OBJECT  GLOBAL DEFAULT    5 _IO_stdin_used
    15: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_start_main
    16: 00000000     0 NOTYPE  GLOBAL DEFAULT    6 __data_start



问题。 。是否可以在没有crt1.o的情况下链接_start

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~

...

我更具体地陈述我的情况,因为它可能是分析所需的信息。

这里是myassembly.s
如前所述,它使用_start而没有main

.global _start
_start:
 push $_STRING1
 push $_STRING2
 call printf
 push $0
 call exit
_STRING1:
 .string "gogo\n"
_STRING2:
 .string "%s"


我组装并链接了它:

jiwon@jiwon:/tmp$ as -o stackoverflow.o stackoverflow.s 
jiwon@jiwon:/tmp$ ld -o stackoverflow -dynamic-linker /lib/ld-linux.so.2  /usr/lib/i386-linux-gnu/crti.o -lc stackoverflow.o /usr/lib/i386-linux-gnu/crtn.o

jiwon@jiwon:/tmp$ ./stackoverflow 
gogo


如您在上面看到的,输出二进制文件运行良好。 但是,当我尝试链接crt1.o时,会发生错误。

jiwon@jiwon:/tmp$ ld -o stackoverflow -dynamic-linker /lib/ld-linux.so.2  /usr/lib/i386-linux-gnu/crti.o -lc stackoverflow.o /usr/lib/i386-linux-gnu/crtn.o /usr/lib/i386-linux-gnu/crt1.o
/usr/lib/i386-linux-gnu/crt1.o: In function `_start':
(.text+0x0): multiple definition of `_start'
stackoverflow.o:(.text+0x0): first defined here
/usr/lib/i386-linux-gnu/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/i386-linux-gnu/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'
/usr/lib/i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'



问题(相同) ,是否可以在没有crt1.o的情况下链接_start

1 个答案:

答案 0 :(得分:1)

您可以自己定义crt1.o,而不是抽出_IO_stdin_used的整个老鼠尾巴呢?只需将这段代码放在您的一个汇编文件中:

        .section .rodata
        .globl _IO_stdin_used
        .type _IO_stdin_used, @object
        .align 4
_IO_stdin_used:
        .int 0x20001
        .size _IO_stdin_used, 4

否则,如果您只想要求_IO_stdin_used的存在而不自己定义它(例如,因为libc中的某个文件定义了它),只需将此行放入您的一个汇编文件中:

        .globl _IO_stdin_used

这将导致汇编器将_IO_stdin_used标记为未定义的全局符号,链接器必须将其从某个位置插入。