Condition 1. I have myassembly.s
which do not have main
.
Condition 2. Instead, myassembly.s
have global symbol _start
.
Condition 3. I wanna link _IO_stdin_used
to output binary.
...and here is problematic part.
_IO_stdin_used
is asserted on crt1.o
as you can see :
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
Question. Can I link crt1.o
without _start
?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
I attach my situation more specifically as it may be information needed for analysis.
Here is myassembly.s
.
As aforementioned situation, It use _start
and don't have main
.
.global _start
_start:
push $_STRING1
push $_STRING2
call printf
push $0
call exit
_STRING1:
.string "gogo\n"
_STRING2:
.string "%s"
I assemble and linked it :
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
As you can see above, the output binary works well.
However, when I tried crt1.o
to be linked, the error happens.
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'
Question (Same) Can I link crt1.o
without _start
?
Instead of pulling in the whole rat's tail of crt1.o
, how about you simply define _IO_stdin_used
yourself? Just put this code in one of your assembly files:
.section .rodata
.globl _IO_stdin_used
.type _IO_stdin_used, @object
.align 4
_IO_stdin_used:
.int 0x20001
.size _IO_stdin_used, 4
Otherwise, if you just want to require the presence of _IO_stdin_used
without defining it yourself (for example, because some file in the libc defines it), just put this line into one of your assembly files:
.globl _IO_stdin_used
This causes the assembler to mark _IO_stdin_used
as an undefined global symbol which the linker has to pull in from somewhere.