I want to generate a PIE file which can be executed normally and can be linked dynamically by other files, so I used gcc's -fPIE
, -shared
, and -pie
options. But I meet some problems. I have 3 files as follows:
$ cat add.c
int add(int a, int b)
{
return a + b;
}
int main()
{
return 0;
}
$ cat add.h
int add(int a, int b);
$ cat main.c
#include <stdio.h>
#include "add.h"
int main()
{
printf("Result of add(1, 2): %d\n", add(1, 2));
return 0;
}
Then I generate libadd.so
by follows command:
gcc -fPIE -pie -shared -o libadd.so add.c
and run it:
$ ./libadd.so
Segmentation fault (core dumped)
Though it can not be executed normally, it can be linked dynamically:
gcc -L. -ladd -o main main.c
run it:
$ LD_LIBRARY_PATH=. ./main
Result of add(1, 2): 3
But if I change the order of options -pie
and -shared
, the situation has changed.
Generate libadd.so
by follows command:
gcc -fPIE -shared -pie -o libadd.so add.c
and run it:
$ ./libadd.so
Because the main function does not have any operations, so there is no print. But when I want to link it, it doesn't work:
$ gcc -L. -ladd -o main main.c
/tmp/ccpimuON.o: In function `main':
main.c:(.text+0xf): undefined reference to `add'
collect2: error: ld returned 1 exit status
So, I don’t understand why this is the case. I didn’t find any information that can help. And how can I achieve my goal? Executable and linkable.