OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 6:23 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: __CTOR_LIST__ not populated
PostPosted: Sat Aug 17, 2019 4:01 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
Hi!
I am in the process of building proper hosted GCC cross compiler for my OS. I've got it to almost working state but there is one thing I am stuck for a few days already. Global/static (whatever they are called) constructors don't get called at all when linking non-static executables. For static executables everything works as it should.
What I've found for now:
  • _init function gets called,
  • .ctors and .dtors sections are generated when needed,
  • .init_array and .fini_array sections are generated but __init_array_start, __init_array_end, __fini_array_start and __fini_array_end symbols are not there,
  • __CTOR_LIST__, __CTOR_END__, __DTOR_LIST__ and hidden __DTOR_END__ symbols are there,
  • but distance between *_END__ and *_LIST__ symbols is always 8 (single pointer size), which (I assume) is not right,
  • __CTOR_LIST__ and __DTOR_LIST__ contain -1 pointer which is correct,
  • __CTOR_END__ and __DTOR_END__ all contain single NULL pointer, which is also ok

C library (musl in my case) initialization routine tries to scan over __CTOR and __DTOR lists but they are simply empty. I've followed wiki tutorial when doing the port and expanded on it a little bit to support shared libraries. Code of my GCC port is here https://github.com/pvc988/woot64/tree/m ... /gcc-9.1.0 if it helps. My OS is identified by x86_64-woot (not exactly) triplet. Or maybe I am barking up completely wrong tree and the problem lies within binutils?

EDIT: I think I am onto something. Some part of the build process is hellbent on putting constructors in .init_array section instead of .ctors. Despite using --disable-initfini-array configure option and adding gcc_cv_initfini_array=no to config.gcc. But if I manually remove .init_array and .fini_array sections from linker script then everything starts to work.


Top
 Profile  
 
 Post subject: Re: __CTOR_LIST__ not populated
PostPosted: Sat Aug 17, 2019 7:05 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
GCC on x86_64 does not properly work without .init_array. In fact, the calling convention of .init functions misaligns the stack and breaks if you use SSE (or anything else that relies on 16 byte alignment). Always pass --enable-initfini-array when building a cross-compiler. The dynamic linker should call .init_array.

_________________
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].


Top
 Profile  
 
 Post subject: Re: __CTOR_LIST__ not populated
PostPosted: Sat Aug 17, 2019 7:17 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
I finally figured it out. Turns out that binutils also need --disable-initfini-array configure option. Passing it to both binutils and GCC makes things work.

@Korona Calling constructors from .init_array won't work for me (at least for now) since I am doing dynamic linking in the kernel. I've also disabled musl's built-in linker since I don't really want to have 2 of them. About that SSE thing. I didn't know about that. I am going to do some checking.


Top
 Profile  
 
 Post subject: Re: __CTOR_LIST__ not populated
PostPosted: Sat Aug 17, 2019 9:41 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
After some thinking I however decided to go with .init_array mechanism and modified musl a little bit to accomodate external dynamic linker.
crt1.c needed to make use of __init_array_start and others so linker wouldn't discard them. Then passed their addresses to __libc_start_main which resides in libc.so file. Finally added some #ifdefs and voila, constructors and destructors work perfectly.


Top
 Profile  
 
 Post subject: Re: __CTOR_LIST__ not populated
PostPosted: Sat Aug 17, 2019 10:05 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
Yes, that's a good idea. Let me elaborate on what I said about the calling convention of .init: on x86 and x86_64, GCC generates .init by just appending `call <constructor>` instructions to .init. For example, this is done using the `CRT_CALL_STATIC_FUNCTION` macro in gcc/config/i386/i386.h. The _init function itself is declared in config/i386/crti.S. However, assuming that the stack is aligned correctly (to a 16-byte boundary) before calling _init, it will be misaligned in the constructor functions that are called from .init, as the call instruction only advances RSP by 8 and not by 16. While this would be easy to fix in GCC (just align the stack inside crti.S), no one seems to use this code anyway (otherwise it would be functional, even on x86_64) and .init_array is the more modern alternative to it.

_________________
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].


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 50 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group