OSDev.org
https://forum.osdev.org/

GCC Cross Compiler cannot build PIC library properly
https://forum.osdev.org/viewtopic.php?f=1&t=32664
Page 1 of 1

Author:  tongko [ Sat Jan 06, 2018 12:27 pm ]
Post subject:  GCC Cross Compiler cannot build PIC library properly

Hi,
I follow the wiki on GCC Cross Compiler and get myself a working GCC cross compiler until I tried to build some shared libraries.

For a very simple code:
ml_main.h
Code:
#ifndef _ml_main_h_
#define _ml_main_h_

int ml_func(int a, int b);

#endif

ml_main.c
Code:
#include "ml_main.h"

int myglob = 42;

int ml_func(int a, int b) {
   myglob += a;
   return b + myglob;
}


When I build it with the following:
Code:
i686-elf-gcc -c -std=c11 -Wall -Wextra -Werror -masm=intel -g -O0 -fPIC -ffreestanding ml_main.c -o ml_main.o

and link it with the following:
Code:
i686-elf-gcc -o mymodule.so -O0 -nostdlib -shared -fPIC -Wl,-soname,mymodule.so -ffreestanding ml_main.o


I get a warning saying:
Code:
/home/xxxxxx/opt/cross/lib/gcc/i686-elf/7.2.0/../../../../i686-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000008048074


And running readelf -S mymodule.so, I get this result (Notice the Type is EXEC):
Code:
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          2720 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         15
  Section header string table index: 14


But when I change the compiler to regular gcc compiler, I get the follow result with no warning (Notice the Type is DYN):
Code:
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x390
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6928 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         7
  Size of section headers:           64 (bytes)
  Number of section headers:         25
  Section header string table index: 24


So the cross compiler generated doesn't look right for a PIC code, number of PH doesn't look right and number of EH is lesser, too. I wonder is this well known and does this different impact the lazy loading in anyway?

Author:  zesterer [ Sat Jan 06, 2018 2:51 pm ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

I might be mistaken, but I think every dynamic library need a _start symbol in order to initiate the contents of the library (static objects, etc.).

Author:  xenos [ Sat Jan 06, 2018 4:06 pm ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

Where's your linker script? You should specify the entry point there.

Author:  mariuszp [ Sat Jan 06, 2018 5:22 pm ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

i'm not sure if the i686-elf target can even build shared libraries. when modifying GCC for Glidix, i remember i had to edit the OS-specific configuration file (glidix.h) so that it actually forwards the "-shared" switch to the linker.

Author:  Korona [ Sat Jan 06, 2018 6:45 pm ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

zesterer wrote:
I might be mistaken, but I think every dynamic library need a _start symbol in order to initiate the contents of the library (static objects, etc.).

No, _start is only needed for executables and it is specified in the linker script. For shared libraries, you want _init, the .init or the .init_array sections to initialize things.

As XenOS pointed out, the linker script GCC uses is probably just wrong for DSOs. Is this for user-space or your kernel? For user-space you really don't want to supply your own linker scripts, but let LD generate its own scripts.

As mariuszp stated, the ELF targets probably cannot build DSOs. In addition to a suitable linker script you also need PIC-enabled CRT files for DSOs. The hosted GCC cross compiler tutorial on the wiki is a good starting point to adding you own target, even though it does not support DSOs properly. You can also check out my OS' GCC patch here: Click me, it supports DSOs and the LD patch is in the same repo.

In particular, you need to ake sure that your target has a STARTFILE_SPEC and ENDFILE_SPEC that supports DSOs, something like the following:
Code:
#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti.o%s %{shared:crtbeginS.o%s;:crtbegin.o%s}"

and you might also want (sooner or later) to build a shared libgcc.

Author:  tongko [ Mon Jan 08, 2018 8:58 am ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

Hi,
Thanks for all the advise.

@Korona, from the code you show me, my understanding is that we have to let GCC know what target we are building by changing the config in the cross GCC source (correct me if I'm wrong).

But I don't understand where is the info coming from, e.g. "managram-system", "managram-kernel"... we do we specified this during compile time?

also, I think I need to study about functionality of CRT in kernel dev and all about it. Is there any good source I can begin with?

Author:  xenos [ Mon Jan 08, 2018 10:39 am ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

Hosted GCC Cross-Compiler

Author:  Korona [ Mon Jan 08, 2018 11:40 am ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

Yes, you need to replace -managarm-kernel and -managarm-system by -youros (see the hosted compiler tutorial). The target is then specified during configure-time using --target. You probably don't need a -kernel/-system separation; I only need to that be able to build libsupc++ for my kernel without any hacks (as otherwise GCC would try to link against libc and build PIC code and so on).

EDIT: Also try to understand the patch before you blindly copy it: There are some other parts that you do not need either, for example that multilib stuff that I use to build 32-bit and 64-bit binaries with the same compiler.
EDIT2: If in doubt, just ask me what each of the lines do.

Author:  tongko [ Tue Jan 09, 2018 2:29 am ]
Post subject:  Re: GCC Cross Compiler cannot build PIC library properly

XenOS wrote:

Thanks for that!

@Korona, thank you so much for that. The things I need to do now is really try to understand how is these work. Sure I'll raise question if I have doubt understanding those files.

I thought I could handle it, but Windows and Linux is just 2 different world... #-o

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/