Hello,
On Mon, 12 Jul 2021, 'Fangrui Song' via Generic System V Application
Binary Interface wrote:
> If ld.lld/ld.bfd/gold keep the current SHT_INIT_ARRAY semantics within
> section groups, for similarity it seems that we shouldn't change
> SHF_LINK_ORDER as well.
> In the end, we don't have a mechanism to make a SHT_INIT_ARRAY GCable.
> The D language compiler seems to want a GCable SHT_INIT_ARRAY
> (
https://github.com/ldc-developers/ldc/issues/3786).
> And we don't have a mechanism to do it.
If one puts an entry into a section twice, why would anyone be surprised
that these two entries are then in fact in the output? Especially with
the above ldc 'issue': it even puts _different_ entries into the section
(them being pointers to different functions, that just so happen to have
the same body). Why should the linker only include one of them?
Assuming you want to devise a mechanism to make SHT_INIT_ARRAY GCable, you
need to think about the implication for these examples:
---- file1.c ----
#include <stdio.h>
static void init () { printf ("init\n"); }
static void init2 () { printf ("init\n"); }
static void (*const init_array []) ()
__attribute__ ((used, section (".init_array")))
= { init };
static void (*const init_array2 []) ()
__attribute__ ((used, section (".init_array")))
= { init2 };
int main() { return 0; }
-----------------
It seems clear enough that here the linker should _not_ remove one of the
entries from .init_array, just because it happens to point to a
semantically equivalent function.
So, why would the linker remove one of the entries if the second
initializer would be literally the same (i.e. 'init')? Why would it
change the picture if the two init_array definitions would be put in
different files?
I think that no matter where the above array definitions are put,
and what entries they contain, the end result should always be the same
(and result in two calls to printf).
So, first we need to ask if we have a problem that we want to fix. Have
we? Basically shouldn't the answer to "but my ctors are called twice" be
"then don't put them twice into .init_array"?
If there are usecases where a GCable init_array makes sense (which ones?),
then it seems sensible to use section groups for that purpose, I guess.
As you mentioned that will result in some problems along the way (we can't
misuse init_array anymore to implement GC roots, but meanwhile GNU_RETAIN
exists, so maybe that's no issue anymore), so is it then still worthwhile
to change anything?
(FWIW: right now I don't see a compelling enough reason to go down the
rabbit hole)
Ciao,
Michael.