ld: foo.o: relocation R_X86_64_PC32 against undefined symbol `bar' can not be used when making a shared object; recompile with -fPIC
I recompile with -fPIC and it still produces this error.
Versions of your compiler and linker? Perhaps your problem is related to this bug, that seems to be fixed now: http://sources.redhat.com/bugzilla/show_bug.cgi?id=584?
Related
Error is as follows:
/usr/bin/ld: gfx.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:4: project] Error 1
and when I add -fPIC or -fPIE, nothing changes. I know that the gfx.o library works, since it was working previously and still works when I ssh on my server.
Make file is as follows:
project: project.c
gcc project.c gfx.o -lx11 -lm -fPIE -o -project
clean:
rm project
I tried to use -fPIE and -fPIC in the makefile. I also treid uninstalling and reinstalling gcc and binutills, but nothing worked.
I figured out that putting -no-pie in the Makefile solves the issue. I don't know if there is a more permanent and widespread fix, but it works.
I'm trying to make a bot like the "!Remindme" reddit bot and i found this Web Scrapper written in C but i don't understand why it don't compile. Can someone help me ? The compiler throw me this :
gcc -o crawler src/crawler.o src/html.o src/http.o src/list.o src/queue.o src/url.o -g -Wall -fPIE -lpthread lib/liburiparser.a
/usr/bin/ld: src/crawler.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: src/html.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: src/http.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: src/url.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: lib/liburiparser.a(UriNormalizeBase.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: lib/liburiparser.a(UriParse.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: lib/liburiparser.a(UriCommon.o): relocation R_X86_64_32S against `.rodata.str1.1' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: lib/liburiparser.a(UriIp4.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status
make: *** [Makefile:20: crawler] Error 1
Even with the flag -fPIE it doesn't work and i'm confuse why. Any help ? :)
You are not compiling you are linking. The linker /usr/bin/ld is talking about that some of the objects files (both direct and from the archive) have to be compiled previously with the -fPIE to work.
You will need to install liburiparser (liburiparser-dev on ubuntu), and run the following command:
gcc -o crawler src/crawler.c src/html.c src/http.c src/list.c src/queue.c src/url.c -g -Wall -lpthread -luriparser -I./include
I suggest you do not use those .o files compiled on other systems, most likely with different CPU architectures.
Side note: I found that you are using https://github.com/iceman201/Web_Scraper, and it seems that they don't have a configured .gitignore to ignore these .o files which are the source of confusion here.
I wrote a simple shared lib which contains the usage of stdout in stdio.h.
#include <stdio.h>
...
fflush(stdout);
...
There was no compilation issue before I added the fflush(stdout) with the command below
$gcc -shared -o a.so a.c
But after adding the fflush(stdout), compiler complains:
/usr/bin/ld: /tmp/ccK4npwc.o: relocation R_X86_64_PC32 against symbol `stdout##GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
Can someone explain the rationale behind this with as much detail as possible? why does it have to be -fPIC here?
EDIT:
Some comments suggest I read on PIC, but that is missing my question. My question is why do I need PIC for this program. In my program, I also uses puts which is from libc. I can compile it fine without -fPIC. But why is -fPIC required with the stdout variable?
I have two object files, one with a symbol that is undefined (from standard input):
bin/src/ghdl_grt/ghwlib.c.o: U sched_getstreams
...and one with the same symbol that is defined:
bin/src/nuttx/nuttx/nuttx.o:0000000000004f0c T sched_getstreams
When I try to link them together, the symbol is for some reason still undefined:
$ ld bin/src/ghdl_grt/ghwlib.c.o bin/src/nuttx/nuttx/nuttx.o -o test.o -lc
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401140
ld: bin/src/ghdl_grt/ghwlib.c.o: in function `ghw_read_range(ghw_handler*)':
/home/jon/controlix-code/src/ghdl_grt/ghwlib.c:351: undefined reference to `sched_getstreams'
What am I missing?
I'm writing a simple C shared library using Eclipse CDT under Linux 64bit.
The code has one reference to the rand() function in the <stdlib.h> It compiles fine but when linking it reports the following error from the linker:
gcc -shared -o "libalg.so" ./sort.o
/usr/bin/ld: ./sort.o: relocation R_X86_64_PC32 against undefined symbol `rand##GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
sort.o is the object file compiled from the file. libalg.so is the target shared library name.
Can anyone explaining why this happen?
Thanks.
On x86_64 architecture gcc requires you to use -fPIC i.e Position Independent Code by default.
The underlying reason for the error is that the relocation type for the symbol rand is of type R_X86_64_PC32 which means that it is PC relative and should lie within 32bit offset from the following instruction.
But the current architecture is of x86_64 type which means that it can lie anywhere within the 64bit address space.
So the dynamic linker actually can not link a symbol with such a relocation type.
Either you have to use -fPIC or compile your code using the -mcmodel=large which will actually make the relocation type to R_X86_64_64.
For more details on how linking is done refer to this great blog by Eli Bendersky