Consider the following program:
#include <stdio.h>
__attribute__((noinline))
int add(int a, int b)
{
return a + b;
}
int add_external_def(int a, int b);
int main()
{
printf("5 + 5 = %d\n", add(5, 5));
printf("5 + 5 = %d\n", add_external_def(5, 5));
return 0;
}
Compiling this program with Clang 17.0.1, for x86-64 with -O3
will produce some assembly that is basically what I would expect. In this assembly, we call add
, add_external_def
and printf
as follows (godbolt link):
call add
call printf@PLT
call add_external_def@PLT
My understanding here is that printf
requires resolution by the dynamic linker/loader and add_external_def@PLT
will probably just be replaced during link time optimization (please correct me if I am wrong).
However, if I check 'Compile to binary object' these calls are replaced respectively with the following
call 20 <main+0x10>
R_X86_64_PLT32 add-0x4
call 33 <main+0x23>
R_X86_64_PLT32 printf-0x4
call 42 <main+0x32>
R_X86_64_PLT32 add_external_def-0x4
What is the significance of this R_X86_64_PLT32 ...-0x4
part? Where has the information about 'whether this function is to be resolved through the PLT' gone?
From here