What is the behavior of these linkers?

From this question, I saw a funny code that compiles (albeit with warnings) and causes a segmentation error (gcc 4.4.4; clang 2.8):

main; 

If we decompose it, here is the result:

 int main = 0; 

So what is the linker behavior here?

+4
source share
3 answers

The behavior of the linker is that it defines a character called main in the program data or BSS segment. It has a length of 4 bytes and is initialized to 0. It usually creates a character in a segment of program code (usually called .text ) with executable code for the main function.

The C startup environment starts with a fixed entry point (usually called _start ), initializes a bunch of stuff (for example, sets program arguments), and calls the main function. When main is executable code, everything is fine and dandy, but if 4 zero bytes are used instead, the program transfers control to these zero bytes and tries to execute them.

Typically, data segments and BSS are marked as non-executable, so when you try to execute code there, the processor will throw an exception that the OS will interpret and then terminate your program with a signal. If somehow the segment in which it is located is executable, then it will try to execute the machine instructions defined 00 00 00 00 . On x86 and x86-64, this is an illegal instruction, so you will also receive a SIGILL signal on the POSIX OS.

+4
source

The main character is expected to be a function, not an integer. However, the linker does not really care about the main type; character defined. If the main character is not a function with one of the prescribed signatures, you invoke undefined behavior.

Then, the start code calls a β€œfunction”, which is actually an address in the program data segment. This happens incorrectly because the "code" stored at this address is not valid - the first 4 bytes are likely to be zeros; what comes later, everyone guesses. A data segment may be marked as not executable, in which case an attempt to execute data will cause a failure in this account.

When you invoke undefined behavior, anything can happen. The crash here is pretty reasonable.

+3
source

On my system (CentOS 6.3), main is placed in BSS and contains all 0, hence the failure:

 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) 
+3
source

Source: https://habr.com/ru/post/1439201/


All Articles