This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: __start/__stop symbols not always defined
Hi,
On Fri, 19 Jan 2018, Alan Modra wrote:
> Right, and that documentation goes all the way back to 2008-05-21.
>
> I'm not discounting your comments about dlopen and dlsym, but I believe
> the current behaviour is reasonable and likely gives what most people
> want, particularly those who are concerned about symbol table size.
Okay, I can live with this; the pacemaker guys will have to invent
something then (or stay with what they invented already :) ). (Though
symbol table size ... hmm, it's only for C-representable names, i.e. by
default none)
> > linker script to always define these __start/__stop symbols. Indeed I
> > can't really see a way to somehow force references to those symbols to
> > appear without either wasting code or data space (e.g. "void
> > *__unused_global=&__start___verbose"),
>
> -u __start___verbose on the ld command line ought to work.
Yeah, I should have mentioned this. I tried before writing the mail and
it doesn't work completely. When you have a library providing those
symbols already:
% readelf -sW liborphan.so | grep verbose
10: 0000000000201020 0 NOTYPE GLOBAL PROTECTED 23 __start___verbose
and you want to create an application that itself also uses the same
mechanism (and hence needs its own __start___verbose), but without its
objects containing references to them:
% readelf -sW app.o | grep verbose
% cc -B./ -o app app.o liborphan.so -ldl -Wl,-R,. -Wl,-u,__start___verbose
./ld: warning: type and size of dynamic symbol `__start___verbose' are not
defined
This is only a warning, but the final app only contains an undefined, not
a defined symbol:
% readelf -sW app | grep verbose
4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __start___verbose
I.e. the dynamic symbol stemming from liborphan.so "satisfies" the
undefined reference created from -u SYMBOL instead of causing the own
__start symbol to be created. That's because -u doesn't create a
ref_regular reference which I could fix/change by adding another hack to
ldlang.c:insert_undefined:
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 1526d7b..ff77637 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3413,8 +3413,10 @@ insert_undefined (const char *name)
{
h->type = bfd_link_hash_undefined;
h->u.undef.abfd = NULL;
- if (is_elf_hash_table (link_info.hash))
+ if (is_elf_hash_table (link_info.hash)) {
((struct elf_link_hash_entry *) h)->mark = 1;
+ ((struct elf_link_hash_entry *) h)->ref_regular = 1;
+ }
bfd_link_add_undef (link_info.hash, h);
}
}
(or a mirroring change in the predicate of bfd_elf_define_start_stop
rejecting only-dynamic definitions as satisfying)
Of course, using the -u option isn't really what they would like to use.
If they need changes to the linker command line then they can also use a
linker symbol script merging the __verbose sections and providing (not via
PROVIDE) the start/stop symbols, and _that_ they can also implicitely add
by making their base-logging library (libqb.so) be a linker script itself,
requiring no changes to linker command at all. Which is indeed the
work-around they eventually came up with.
So, while the pre-2.29 behaviour didn't (arguably) match documented
behaviour it worked better in practice (for them). Pff, no idea, I'm torn
:)
Ciao,
Michael.