Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the behavior of these linkers?

From this question, I've seen a funny code which compile (although with warnings) and produce a segmentation fault (gcc 4.4.4; clang 2.8):

main;

If we expand it, here is the result:

int main = 0;

So what is the linker's behavior here?

like image 559
md5 Avatar asked Dec 26 '22 16:12

md5


2 Answers

The linker's behavior is that it defines a symbol called main in either the program's data or BSS segment. It is 4 bytes long and initialized to 0. Ordinarily, it creates a symbol in the program's code segment (typically called .text) with the executable code for the main function.

The C runtime starts up at a fixed entry point (typically called _start), initializes a bunch of stuff (e.g. sets up the program's arguments), and calls the main function. When main is executable code, this is all fine and dandy, but if it's instead 4 zero bytes, the program will transfer control to those zero bytes and try to execute them.

Typically, the data and BSS segments are marked as non-executable, so when you try to execute code there, the processor will raise an exception, which the OS will interpret and then terminate your program with a signal. If somehow the segment it's in is executable, then it will try to execute the machine instructions defined by 00 00 00 00. In x86 and x86-64, that's an illegal instruction, so you'd also get a SIGILL signal in POSIX OSes.

like image 161
Adam Rosenfield Avatar answered Jan 05 '23 16:01

Adam Rosenfield


Under my system (CentOS 6.3), main is placed into the BSS and contains all 0's, hence the crash:

Program received signal SIGSEGV, Segmentation fault.
0x00000000006007f0 in main ()
(gdb) where
#0  0x00000000006007f0 in main ()
(gdb) l
"main" is not a function
(gdb) disass 0x6007f0
Dump of assembler code for function main:
=> 0x00000000006007f0 <+0>: add    %al,(%rax)
   0x00000000006007f2 <+2>: add    %al,(%rax)
End of assembler dump.
(gdb) info symbol &main
main in section .bss of /home/ajd/tmp/x
(gdb) x/16b 0x6007f0
0x6007f0 <main>:    0   0   0   0   0   0   0   0
0x6007f8:   0   0   0   0   0   0   0   0
(gdb) 
like image 43
trojanfoe Avatar answered Jan 05 '23 17:01

trojanfoe