Page 1 of 1

OS-specific toolchain and shared libraries

Posted: Fri Jan 16, 2015 10:48 am
by mariuszp
A month or so ago when I was creating a cross-compiler for my OS (glidix) it didn't automatically add crt0.o and such to the executable, so to force it to include them, I modified gcc/config/glidix.h and added a STARTFILE_SPEC and ENDFILE_SPEC at the end, here's what it looks like now:

Code: Select all

/* Useful if you wish to make target-specific gcc changes. */
#undef TARGET_GLIDIX
#define TARGET_GLIDIX 1
 
/* Don't automatically add extern "C" { } around header files. */
#undef  NO_IMPLICIT_EXTERN_C
#define NO_IMPLICIT_EXTERN_C 1
 
/* Additional predefined macros. */
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS()      \
  do {                                \
    builtin_define ("__glidix__");      \
    builtin_define ("__unix__");      \
    builtin_assert ("system=glidix");   \
    builtin_assert ("system=unix");   \
    builtin_assert ("system=posix");   \
  } while(0);

#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"

#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
It now successfully builds static executable, but refuses to build a shared library, because when I run:

Code: Select all

x86_64-glidix-gcc -shared -o out/lib/libc.so out/lib/libc.a
("libc.a" does NOT contain the crt0.o files; they are seperate files installed under /glidix/lib), it tries to link crt0.o into libc.so, and fails due to undefined reference to 'main'. Is there something I am doing horribly wrong? And if so, what is it?

Re: OS-specific toolchain and shared libraries

Posted: Fri Jan 16, 2015 3:16 pm
by gerryg400
My command line looks like this

Code: Select all

x86_64-anvil-gcc -m64 -Wl,-e_start -shared -o libc.so *.o 
So I think your command line is okay. I specifically link in a special version of the start-up code in that list of *.o files because my libc.o is also my ld loader but you needn't do that.

The difference is likely in your STARTFILE_SPEC. You need to tell it to leave out the crt1.o file when you're building shared.

Code: Select all

#undef  STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared:crt1.o%s} \
   crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
The first bit tells gcc not to include crt1.o if the -shared option is supplied

Re: OS-specific toolchain and shared libraries

Posted: Sat Jan 17, 2015 12:37 pm
by mariuszp
Thank you for your help. It also seems that when I create static executable, they are linked so that there is only one program header, which stores all code, data and bss in a single segment, with read-write-execute permission. Does anyone know why it may be creating this one segment instead of 2? There should be, by default, a segment for code (read-and-execute) and for data (read-and-write).

Re: OS-specific toolchain and shared libraries

Posted: Sat Jan 17, 2015 1:21 pm
by mariuszp
OK, I managed to get it to link the shared library but it was linked as an executable instead of a DYN...

EDIT: I used the -v flag and it turns out that GCC is not passing the -shared option to the linker:

Code: Select all

mariusz@mariusz-Satellite-A660:~/Madd/Glidix/glidix/userspace/libc/out/lib$ x86_64-glidix-gcc -v -shared -o libc.so libc.a
Using built-in specs.
COLLECT_GCC=x86_64-glidix-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-glidix/4.9.0/lto-wrapper
Target: x86_64-glidix
Configured with: ../glidix-gcc/configure --target=x86_64-glidix --prefix=/glidix/usr --exec-prefix=/usr --with-sysroot=/glidix --enable-languages=c --disable-nls
Thread model: single
gcc version 4.9.0 (GCC) 
COMPILER_PATH=/usr/libexec/gcc/x86_64-glidix/4.9.0/:/usr/libexec/gcc/x86_64-glidix/4.9.0/:/usr/libexec/gcc/x86_64-glidix/:/usr/lib/gcc/x86_64-glidix/4.9.0/:/usr/lib/gcc/x86_64-glidix/:/usr/lib/gcc/x86_64-glidix/4.9.0/../../../../../usr/x86_64-glidix/bin/
LIBRARY_PATH=/usr/lib/gcc/x86_64-glidix/4.9.0/:/usr/lib/gcc/x86_64-glidix/4.9.0/../../../../../usr/x86_64-glidix/lib/:/glidix/lib/
COLLECT_GCC_OPTIONS='-v' '-shared' '-o' 'libc.so' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-glidix/4.9.0/collect2 -plugin /usr/libexec/gcc/x86_64-glidix/4.9.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-glidix/4.9.0/lto-wrapper -plugin-opt=-fresolution=/tmp/cc3xbPRP.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc --sysroot=/glidix -o libc.so /glidix/lib/crti.o /usr/lib/gcc/x86_64-glidix/4.9.0/crtbegin.o -L/usr/lib/gcc/x86_64-glidix/4.9.0 -L/usr/lib/gcc/x86_64-glidix/4.9.0/../../../../../usr/x86_64-glidix/lib -L/glidix/lib libc.a -lgcc -lgcc /usr/lib/gcc/x86_64-glidix/4.9.0/crtend.o /glidix/lib/crtn.o
/usr/lib/gcc/x86_64-glidix/4.9.0/../../../../../usr/x86_64-glidix/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000004000c0

Re: OS-specific toolchain and shared libraries

Posted: Sat Jan 17, 2015 2:53 pm
by gerryg400
mariuszp wrote:EDIT: I used the -v flag and it turns out that GCC is not passing the -shared option to the linker:
You need a LINK_SPEC to control what gets passed to the linker. Here's mine

Code: Select all

#undef  LINK_SPEC
#define LINK_SPEC "%{" SPEC_64 ":-m elf_x86_64} %{" SPEC_32 ":-m elf_i386} \
  %{shared:-shared} \
  %{!shared: \
    %{!static: \
      %{rdynamic:-export-dynamic} \
      %{" SPEC_32 ":-dynamic-linker " "/lib32/ld-anvil32.so" "} \
      %{" SPEC_64 ":-dynamic-linker " "/lib/ld-anvil.so" "}} \
    %{static:-static}}"
The %{shared:-shared} is the bit you need right now. But to support things like dlopen you need it all.

Re: OS-specific toolchain and shared libraries

Posted: Sat Jan 17, 2015 2:53 pm
by gerryg400
mariuszp wrote:Thank you for your help. It also seems that when I create static executable, they are linked so that there is only one program header, which stores all code, data and bss in a single segment, with read-write-execute permission. Does anyone know why it may be creating this one segment instead of 2? There should be, by default, a segment for code (read-and-execute) and for data (read-and-write).
Did you fix this issue ?