GCC Cross Compiler cannot build PIC library properly

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
tongko
Member
Member
Posts: 26
Joined: Wed Nov 07, 2012 2:40 am
Location: Petaling Jaya, Malaysia

GCC Cross Compiler cannot build PIC library properly

Post by tongko »

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: Select all

#ifndef _ml_main_h_
#define _ml_main_h_

int ml_func(int a, int b);

#endif
ml_main.c

Code: Select all

#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: Select all

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: Select all

i686-elf-gcc -o mymodule.so -O0 -nostdlib -shared -fPIC -Wl,-soname,mymodule.so -ffreestanding ml_main.o
I get a warning saying:

Code: Select all

/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: Select all

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: Select all

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?
User avatar
zesterer
Member
Member
Posts: 59
Joined: Mon Feb 22, 2016 4:40 am
Libera.chat IRC: zesterer
Location: United Kingdom
Contact:

Re: GCC Cross Compiler cannot build PIC library properly

Post by zesterer »

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.).
Current developing Tupai, a monolithic x86 operating system
http://zesterer.homenet.org/projects.shtml
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: GCC Cross Compiler cannot build PIC library properly

Post by xenos »

Where's your linker script? You should specify the entry point there.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: GCC Cross Compiler cannot build PIC library properly

Post by mariuszp »

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.
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: GCC Cross Compiler cannot build PIC library properly

Post by Korona »

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: Select all

#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.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
User avatar
tongko
Member
Member
Posts: 26
Joined: Wed Nov 07, 2012 2:40 am
Location: Petaling Jaya, Malaysia

Re: GCC Cross Compiler cannot build PIC library properly

Post by tongko »

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?
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: GCC Cross Compiler cannot build PIC library properly

Post by xenos »

Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: GCC Cross Compiler cannot build PIC library properly

Post by Korona »

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.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
User avatar
tongko
Member
Member
Posts: 26
Joined: Wed Nov 07, 2012 2:40 am
Location: Petaling Jaya, Malaysia

Re: GCC Cross Compiler cannot build PIC library properly

Post by tongko »

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
Post Reply