This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Define __start/__stop symbols when there is only a dynamic def
Hi,
On Mon, 29 Jan 2018, H.J. Lu wrote:
> Yes, it looks very odd. I thought the issue was with the __start/__stop
> symbols in the shared object, not with executable. Why is -E needed?
> I don't want to second guess. Michael, can you provide a testcase to
> show your use case?
It's exactly as I described in the thread linked by Alan. But sure,
here's some code:
% cat lib.c
extern int __start___verbose[];
extern int __stop___verbose[];
extern int foo2(void);
int foo (void)
{
static int my_var __attribute__((section("__verbose"))) = 5;
if (__start___verbose == __stop___verbose // ref_regular
|| __start___verbose[0] != 5)
return -1;
else
return 0;
}
% cat app.c
#include <stdlib.h>
#include <stdio.h>
extern int foo (void);
extern int __start___verbose[];
extern int __stop___verbose[];
int bar (void)
{
static int my_var __attribute__((section("__verbose"))) = 6;
// no ref_regular!
return 0;
}
int main()
{
if (bar () != 0)
{
printf("main: wrong __start___verbose\n");
exit(2);
}
return 0;
}
% cc -g -c -o app.o app.c
% cc -g -fPIC -c -o lib.o lib.c
% cc -B./ -shared -o liborphan.so lib.o -Wl,-R,.
% cc -B./ -o app app.o liborphan.so -ldl -Wl,-R,.
(This assumes that ./ld is the new binutils link editor)
% readelf -sW liborphan.so | grep verbose
7: 0000000000201024 0 NOTYPE GLOBAL PROTECTED 23 __stop___verbose
11: 0000000000201020 0 NOTYPE GLOBAL PROTECTED 23 __start___verbose
56: 0000000000201024 0 NOTYPE GLOBAL PROTECTED 23 __stop___verbose
63: 0000000000201020 0 NOTYPE GLOBAL PROTECTED 23 __start___verbose
So, liborphan.so provides the symbols we want.
% readelf -sW app | grep verbose
<nothing>
%
But app itself does not. As Alan and me discussed in the thread this is
unfortunate and not how binutils worked before 2.29, but OTOH it's how it
was documented all along. But still on the other other hand (ahem)
pacemaker relies on the above (i.e. expects that app does provide these
symbols in the above situation). One work-around would have been to use -u
__start___verbose, except that work-around doesn't work with unpatched
binutils, because the -u symbols aren't ref_regular:
% cc -Wl,-u,__start___verbose -B./ -o app app.o liborphan.so -ldl -Wl,-R,.
./ld: warning: type and size of dynamic symbol `__start___verbose' are not
defined
I proposed two alternatives to make the -u work-around work. Alan
thankfully seems to have reconsidered and instead changed elflink such
that now app provides the symbols even without changes to the link command
line, i.e. like binutils behaved before 2.29.
Or, rather, there's one more thing missing to make it really behave like <
2.29, and that's the reason why Alans testcase needs -E currently. When
we create a start/stop symbol it needs to be dynamic (otherwise it doesn't
make much sense), but isn't automatically made so, so this is needed in
addition, then the -E is useless:
@@ -14347,6 +14356,7 @@ bfd_elf_define_start_stop (struct bfd_link_info
*info,
h->def_dynamic = 0;
h->start_stop = 1;
h->u2.start_stop_section = sec;
+ bfd_elf_link_record_dynamic_symbol (info, h);
if (symbol[0] == '.')
{
/* .startof. and .sizeof. symbols are local. */
Or something along the lines (perhaps doing this only in the
C-representable case, and then only if not made hidden or so).
Ciao,
Michael.