M
M
mr-ZA2019-03-13 00:53:42
C++ / C#
mr-ZA, 2019-03-13 00:53:42

Compiling c++?

Hello everyone, explain one thing about compiling sources, there is a code as an example:
#mainx.cpp#

#include <iostream>
#include "printx.h"		
using namespace std;

int main()
{
    int a = 4;

    cout << "Calling function!" << endl;
    cout << printx(a) << endl;


return 0;
}

#printx.h# #printx.cpp#
void printx(int );

#include <iostream>
#include "printx.h"

void printx(int x)
{
   for (int i = 0; i < x; i++) {
      std::cout << "hello" << std::endl;
   }
}

I understand that the file "printx.h" it essentially inserts the prototype of the printx () function into the source "printx.cpp" and "mainx.cpp" to control its call (for example, the correct number of arguments). Then the question is, does mainx find out that there is a printx() function at the stage of linking [mainx.o] and [printx.o]? How is it passed to [mainx] that the printx() function exists?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2019-03-13
@mr-ZA

it turns out that mainx learns about the fact that there is a function printx () at the stage of linking [mainx.o] and [printx.o]?

Yes.
It is the job of the linker to link references to undefined symbols with the definitions of those symbols.
In main.o, the call command is placed at the printx call site, an undefined printx symbol is entered in the symbols section, and an entry is added in the relocation section linking the call command with the symbol:
objdump -dr mainx.o
...
0000000000000000 <main>:
   0:   55                      push   %rbp
...
  3a:   89 c7                   mov    %eax,%edi
  3c:   e8 00 00 00 00          callq  41 <main+0x41>
                        3d: R_X86_64_PLT32      _Z6printxi-0x4
  41:   b8 00 00 00 00          mov    $0x0,%eax
  46:   c9                      leaveq 
  47:   c3                      retq   
...

readelf -a mainx.o
...
Relocation section '.rela.text' at offset 0x580 contains 12 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
...
00000000003d  001400000004 R_X86_64_PLT32    0000000000000000 _Z6printxi - 4
...

Symbol table '.symtab' contains 25 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
...
    20: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z6printxi
...

In printx.o, in the character section, the character associated with the address in the code where the printx function is defined is entered:
readelf -a printx.cpp
...
Symbol table '.symtab' contains 24 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
...
    14: 0000000000000000    75 FUNC    GLOBAL DEFAULT    1 _Z6printxi
...

Here value == 0 -- because printx ended up at address 0 in the .text section.
The linker combines the input sections according to the linking script, and then inserts the end addresses of the symbols in the places that refer to them.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question