tech-toolchain archive

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

Re: "Fixing" new ld(1) DT_NEEDED handling



On 10/14/13 08:45, Martin Husemann wrote:
You guys have lost me - let me try to summarize and please correct me:

AFAIU the solaris linker behaviour (as quoted by uwe) is the only sane
one.

With that (Solaris ld) behaviour, our ld.elf_so behaves sane too, so no
changes there needed.

Creating new "hidden" NEEDED entries would make it possible to catch
wrong linker command lines, like what apparently the binutils folks
tried to do with their changed default. However, this would be a
(trivial) change in object format and require runtime linker changes.

I would be happy if we could get the Solaris linker behaviour. The hidden
needed extension might be something to evaluate closer and, if it shows real
advantages, get discussed upstream.

Unfortunately you can not get the "resolve symbol, but do not copy
NEEDED" behaviour from gnu ld with any combination of options, and you
could not get it from the old version of binutils either. This still
leaves us with two IMHO broken behaviours as only short term options.

I do not see any real harm done with reverting the default. What could
possibly fail if third party software provides all -l args but we would
copy NEEDED entries from indirect references?


I'm wondering which version of binutils was imported. I don't have
a NetBSD machine at hand right now, but on linux with he latest
development version:


$ cat main.c
#include <stdio.h>

extern char *libfunc(void);

int main(void)
{
        printf ("lib returns: '%s'\n", libfunc());
        return 0;
}
$ cat libmain.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

extern char *func_a(void);
extern char *func_b(void);

char *libfunc(void)
{
        size_t totlen;
        char *s1, *s2, *ret;

        s1 = func_a();
        s2 = func_b();

        totlen = strlen(s1) + strlen(s2) + 1;

        ret = malloc(totlen);
        if (! ret) {
                fprintf(stderr, "malloc failed: %s\n", strerror(errno));
                return "<error>";
        }

        strcpy (ret, s1);
        strcpy (ret + strlen(s1), s2);
        return ret;
}
$ cat libfunca.c

char *func_a(void)
{
        return "<funca>";
}
$ cat libfuncb.c

char *func_b(void)
{
        return "<funcb>";
}
$ cat mk
#!/bin/sh

gcc -fPIC -shared -o libfunca.so libfunca.c || exit 1
gcc -fPIC -shared -o libfuncb.so libfuncb.c || exit 1
gcc -fPIC -shared -o libmain.so libmain.c libfunca.so libfuncb.so || exit 1
#gcc -o main main.c libmain.so -Wl,-rpath-link,.
gcc -o main main.c libmain.so -Wl,-rpath,.
$ ./mk
$ ./main
lib returns: '<funca><funcb>'
$ readelf -a main | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libmain.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
$ readelf -a libmain.so | grep NEEDED
 0x0000000000000001 (NEEDED)             Shared library: [libfunca.so]
 0x0000000000000001 (NEEDED)             Shared library: [libfuncb.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
$ ld --version
GNU ld (GNU Binutils) 2.24.51.20131014
Copyright 2013 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
$


Isn't that the desired behaviour?

regards,
chris



Home | Main Index | Thread Index | Old Index