__cxx_global_var_init rearranged by lld

Hi

I’m working on replacing our linker (ld 2.24) with lld however, seems like some of the template ctors are not placed in the same order by lld and we end up with some null pointers and I believe it has to do with the order of initializations of.

I used nm -n to compare the symbols in the output of ld vs lld and found that many symbols are placed differently…

When I grep the symbols to only see __cxx_global_var_init… I see that some are placed by lld differently than ld

Question:

The __cxx_global_var_initN symbols usually have a unique number (N) at the end but for my case there are few that do not have the unique number and some don’t even have any number (Just __cxx_global_var_init) because they are originated from different compilation units so I can’t use --symbol-ordering-file to tell lld to place them in the order I like. How can I force these symbols to have unique number so there is no confusion ?

Has anyone else had the same kind of problem before? And how did you fix it?

Thanks

A

Guessing in the dark here - I'd say your programs are relying on
unspecified behavior on the order of certain global constructors, and
should be changed to not do that.

But if you have a reduced test case that shows the difference in
behavior we can take a closer look and verify whether that's actually
what's happening.

Guessing in the dark here - I'd say your programs are relying on
unspecified behavior on the order of certain global constructors, and
should be changed to not do that.

But if you have a reduced test case that shows the difference in
behavior we can take a closer look and verify whether that's actually
what's happening.

Hi

I’m working on replacing our linker (ld 2.24) with lld however, seems like some of the template ctors are not placed in the same order by lld and we end up with some null pointers and I believe it has to do with the order of initializations of.

I used nm -n to compare the symbols in the output of ld vs lld and found that many symbols are placed differently…

When I grep the symbols to only see __cxx_global_var_init… I see that some are placed by lld differently than ld

Question:

The __cxx_global_var_initN symbols usually have a unique number (N) at the end but for my case there are few that do not have the unique number and some don’t even have any number (Just __cxx_global_var_init) because they are originated from different compilation units so I can’t use --symbol-ordering-file to tell lld to place them in the order I like. How can I force these symbols to have unique number so there is no confusion ?

The name --symbol-ordering-file may be a bit confusing. It reorders input sections containing the
specified symbols instead of symbols themselves. If you project does not enable -ffunction-sections,
the specified symbols just describe how .text sections from various .o should be ordered.

--symbol-ordering-file specified symbols can be either global or local.

On x86 and x86-64, if you specify __cxx_global_var_init.1 in --symbol-ordering-file, all input
sections with a symbol named __cxx_global_var_init.1 will be ordered before others.
Since multiple .o can define __cxx_global_var_init.1 (a local symbol), you are likely order multiple
.o together, which may not be intended.
(On aarch64, ppc64 and other thunk targets, LLD does some layout work by finding an appropriate
insertion point: unordered.. ordered.. unordered..)

__cxx_global_var_init and suffixed __cxx_global_var_init.N are relative to the same section
.text.startup . clang doesn't create multiple .text.startup even if you specify -ffunction-sections,
so you can't reorder dynamic initializers in one translation unit. This design is to prevent silent
violation of C++ standard.