0

I'm a beginner to learn the basic compiling. I create a very simple c file as below

#include <stdio.h>

int main (void) {
  printf("Hello World!\n");
  return 0;
}

then I run the commands,

cpp -E helloworld.c -o helloworld.i
gcc -S helloworld.i -o helloworld.s
as helloworld.s -o helloworld.o
ld -shared -o helloworld /usr/lib64/libc.so helloworld.o

in here, I got an error message like this,

ld -shared -o helloworld /usr/lib64/libc.so helloworld.o
ld: helloworld.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: Nonrepresentable section on output

so I rerun the upper but with a -fPIC

cpp -E helloworld.c -o helloworld.i
gcc -S helloworld.i -o helloworld.s -fPIC
as helloworld.s -o helloworld.o
ld -shared -o helloworld /usr/lib64/libc.so helloworld.o

at last, I got my helloworld, but when I try ./helloworld, I got a Segmentation fault.

anyone can help? Thanks in advance!

glaxy
  • 53
  • 4
  • Is there a reason why you are trying to do each part of the build seperately instead of using `gcc` to build all in one command? That is `gcc -o helloworld helloworld.c`? Your commands are not sufficient as there's more than just `libc` that needs to be linked in. Run `gcc -v helloworld.c` to see the exact steps `gcc` performs and compare with what you have. – kaylum Sep 25 '20 at 04:02
  • yes, gcc -o helloworld helloworld.c works, but I try to understand how ld command works, that's why I do this. it is a little complex that the gcc -v output for me. could you please kindly show some more detail? many thanks! – glaxy Sep 25 '20 at 04:27
  • Then yeah, look at the `gcc -v` output for a better understanding of the command details. It's not as simple as you are currently doing. – kaylum Sep 25 '20 at 04:28
  • OK, any web link to explain the gcc -v output is appreciate! – glaxy Sep 25 '20 at 04:37
  • I find this, https://stackoverflow.com/questions/6656317/linking-a-c-program-directly-with-ld-fails-with-undefined-reference-to-libc-c – glaxy Sep 25 '20 at 08:22

1 Answers1

0

I try the gcc helloworld.c -Wl,--verbose | grep succeeded and get some output as below,

attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o succeeded
attempt to open /tmp/ccSuIvy2.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so succeeded
attempt to open /lib64/libc.so.6 succeeded
attempt to open /usr/lib64/libc_nonshared.a succeeded
attempt to open /lib64/ld-linux-x86-64.so.2 succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o succeeded

but I still don't know how to do the link, I try this one

ld -shared -o helloworld /usr/lib64/libc.so /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib64/crtn.o helloworld.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a /usr/lib64/libc_nonshared.a /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o 

but get an error message,

ld: /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o: relocation R_X86_64_32S against undefined symbol `__libc_csu_fini' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: Nonrepresentable section on output
glaxy
  • 53
  • 4
  • You must use `-fPIC` (or `-fpic`) to produce *Position Independent Code* for the share library because a shared library must be accessed though global offsets rather addresses relative to the program loading the library -- otherwise the relative offsets would refer to a different location each time the library is loaded. See `man gcc` under the `-fpic` option. – David C. Rankin Sep 25 '20 at 05:25
  • but the crtl.o not created by me, it provided by ubuntu, right? – glaxy Sep 25 '20 at 06:43
  • Exactly, and if you want anything, including the c-runtime to load your helloworld, then it has to have global offsets. The bigger issue is what you are attempting to accomplish. You are not using your code as a shared library. Why not create a separate source with a function that prints helloworld and compile that as a shared library and then link it with your main() and call the function that prints helloworld? – David C. Rankin Sep 25 '20 at 07:39