tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Shared libraries: startup and cleanup


From: Michael Matz
Subject: Re: [Tinycc-devel] Shared libraries: startup and cleanup
Date: Mon, 14 Sep 2015 17:32:11 +0200 (CEST)
User-agent: Alpine 2.20 (LSU 67 2015-01-07)

Hi,

On Thu, 10 Sep 2015, Jared Maddox wrote:

> Does anyone remember if this is supposed to currently work? Is there 
> some sort of caveat, such as requiring a linker flag or script?

No, it's simply not implemented, and even hacks aren't working.  The 
ctor/dtor attributes aren't implemented, and for the section attributes to 
work some stuff in TCCs linker is missing:

.init/.fini sections have to contain straight line code actually calling 
the function in question (the content of .init/.fini simply is run from 
the dynamic loader, so placing functions therein doesn't work, you have to 
place code snippets calling functions into it).  Something like this:

struct S {unsigned opcode; unsigned ofs;};
struct S dtorref __attribute((section(".fini"))) = {0xe8909090, 
(unsigned)( ((char*)dtor) - (char*)&dtorref + 5) };

Don't bother to try, the TCC linker has another problem in that it emits a 
64bit relocation for the reference to dtor where it's actually a 32bit 
field (the call offset), and doesn't support this kind of pointer 
arithmentic anyway.

The modern way of actually emitting ctors/dtors is not .init/.fini but 
rather .init_array and .fini_array.  Those are sections simply containing 
pointers to functions to be called as ctors resp. dtors.  Like so:

#define A __attribute((section(".init_array")))
void * ctorref A = ctor;

On some glibc dynamic linkers this already works, but it doesn't work for 
dtors.  This again is because TCCs linker doesn't generate the right 
information, in this case the executable or shared lib needs DT_INIT_ARRAY 
and DT_FINI_ARRAY dynamic entries that describe where those pointer arrays 
are placed (basically the bounds of the .init_array/.fini_array sections).

Even linking with gcc (circumventing TCCs linker) doesn't help, because 
TCC generates the .init_array sections with 32byte alignment, whereas it 
has to be 8 bytes (on 64bit machines), so there's zero padding from other 
object files (crtbegin.o usually) that makes it crash at runtime.

So, all in all, there is currently no way to make it work with TCC in 
purely C.  You have to resort to assembler, for instance:

% cat ctortest-ctors.s
.section .init_array
.quad ctor
.section .fini_array
.quad dtor

Then link with GCC (and the built-in assembler of TCC doesn't work on the 
above).


Ciao,
Michael.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]