pkgsrc-Users archive

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

Re: pkg_install fails when archivers/xz is installed



So I went searching for any linker code that is responsible for
generating the DT_NEEDED names, and in binutils I found one file with
two cases.

This is code in src/external/gpl3/binutils/dist/ld/ldelf.c:

(line 1742...)

  /* We have found a dynamic object to include in the link.  The ELF
     backend linker will create a DT_NEEDED entry in the .dynamic
     section naming this file.  If this file includes a DT_SONAME
     entry, it will be used.  Otherwise, the ELF linker will just use
     the name of the file.  For an archive found by searching, like
     this one, the DT_NEEDED entry should consist of just the name of
     the file, without the path information used to find it.  Note
     that we only need to do this if we have a dynamic object; an
     archive will never be referenced by a DT_NEEDED entry.

     FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
     very pretty.  I haven't been able to think of anything that is
     pretty, though.  */
  if (bfd_check_format (entry->the_bfd, bfd_object)
      && (entry->the_bfd->flags & DYNAMIC) != 0)
    {
      ASSERT (entry->flags.maybe_archive && entry->flags.search_dirs);

      /* Rather than duplicating the logic above.  Just use the
         filename we recorded earlier.  */

      if (!entry->flags.full_name_provided)
        filename = lbasename (entry->filename);
      bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
    }

and here, the other call to bfd_elf_set_dt_needed_name, for another case:
(line 346, 361)

  /* We've found a dynamic object matching the DT_NEEDED entry.  */
...
  /* First strip off everything before the last '/'.  */
  soname = lbasename (bfd_get_filename (abfd));
...
  /* Specify the soname to use.  */
    bfd_elf_set_dt_needed_name (abfd, soname);


flags.full_name_provided is related to whether the "lib*.so" is included in
the name given to the linker, as in -l:libc.so , not if a full path is
included: (ldlang.h)

  /* 1 means this file was specified in a -l:namespec option.  */
  unsigned int full_name_provided : 1;

In any case, there is also code in libbfd that relates to this:

/usr/src/external/gpl3/binutils/dist/bfd/elflink.c line 4248:

      /* Find the name to use in a DT_NEEDED entry that refers to this
         object.  If the object has a DT_SONAME entry, we use it.
         Otherwise, if the generic linker stuck something in
         elf_dt_name, we use that.  Otherwise, we just use the file
         name.  */
      if (soname == NULL || *soname == '\0')
        {
          soname = elf_dt_name (abfd);
          if (soname == NULL || *soname == '\0')
            soname = bfd_get_filename (abfd);
        }

      /* Save the SONAME because sometimes the linker emulation code
         will need to know it.  */
      elf_dt_name (abfd) = soname;

(bfd_elf_set_dt_needed_name() sets elf_dt_name (abfd))

and some code that uses this: (line 6749)

              indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
                                          elf_dt_name (vn->vn_bfd) != NULL
                                          ? elf_dt_name (vn->vn_bfd)
                                          : lbasename (vn->vn_bfd->filename),
                                          FALSE);

Now if we had a library at hand without a SONAME set, then it seems like
the full path name would already be used. But I could not find quickly
how to remove a SONAME from an existing library.
I did manage to create a not very complete copy of libc.so without
SONAME, using "ld -shared -no-as-needed libc.so -o libc2.so", and when
linking that, I got indeed

Dynamic Section:
  NEEDED               /tmp/c/libc2.so

Otherwise It looks doable to tweak something to always call
bfd_elf_set_dt_needed_name() with a full path name, although doing it under
condition of some option or such will probably need some seaching how to do
that best.

The dynamic loader seems to be prepared to handle full path names.
Here is _rtld_load_library() which checks for a '/' and if there is one,
it wants an absolute path name for suid binaries:

src/libexec/ld.elf_so/search.c line 109

/*
 * Find the library with the given name, and return its full pathname.
 * The returned string is dynamically allocated.  Generates an error
 * message and returns NULL if the library cannot be found.
...
 */
Obj_Entry *
_rtld_load_library(const char *name, const Obj_Entry *refobj, int flags)
{
...
        if (strchr(name, '/') != NULL) {        /* Hard coded pathname */
                if (name[0] != '/' && !_rtld_trust) {
                        _rtld_error(
                        "absolute pathname required for shared object \"%s\"",
                            name);
                        return NULL;
                }
                pathname = name;
                goto found;
        }


-Olaf.
-- 
Olaf 'Rhialto' Seibert -- rhialto at falu dot nl
___  Anyone who is capable of getting themselves made President should on
\X/  no account be allowed to do the job.       --Douglas Adams, "THGTTG"

--U+BazGySraz5kW0T
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQEcBAEBAgAGBQJfMXRMAAoJEJmJxkVhw/vTSRYH/3Sf5zOPbuSTP110TL4YgTXl
zi+A0j/lOQTDihBNAqIfFuSmbRoofJTd2bz/Gtk6xwErxQFVwxLLOmjPPgJffN4C
WApmAkmB2Nib3w7PaKmd7OW6eSIlHA8Lk9QR4jCDn75rtpNf2GgK2HghQJSk1J+V
ZgPX4HpP0X5kWmc3OXnGZJsJblAa1e/hohgTqhe9+4kfERoTHCZ2L+xbM0U6oOac
c0jacpcABr3fkoLXjlhvTw+4crbT+ScMH1ggLxuKu2ypW3/2fpP4cRDKtfStFxdQ
yUjwmiE6Ytdf+u0vIVF7SXqMi5atMubg7FNRvpFxdzQuVRfyB/O81idgn5vKZTI=
=Cp9X
-----END PGP SIGNATURE-----

--U+BazGySraz5kW0T--

Attachment: signature.asc
Description: PGP signature



Home | Main Index | Thread Index | Old Index