This is the mail archive of the libc-hacker@cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

changing embedded RPATH in existing executables.




Hello,

I would like to be able to change the embedded rpath in executable and
shared libraries using libbfd.  The development platform in question here
is linux/i386.

[ I was also thinking of using something similar (presuming it's possible)
to change the NEEDED tags for redhat glibc-2.1 built executables so that
they can be run on non-redhat glibc-2.1 distributions.   Redhat 6.0 has
used a different SONAME for it's glibc-2.1 built libstdc++.so.2.9.0 then
any of the other glibc-2.1distributions, so ISVs and other external package
creators will have to build separate executables/packages for redhat
glibc-2.1 and for any other glibc-2.1 based distributions if they use C++.
The other possibilty would be for everybody to ship their own libstdc++
(and use -Wl,-rpath to force it to be used instead of the system one) so
that their binaries will work on different distributions.  However, I am
not sure this is feasable because of the GPL. ]

Based on objdump, and some of the libbfd elf code I wrote the program below
that can be used to find the RPATH start in the ELF .dynamic section, but
now that I have found it I don't know how to write modifications back into
the section.  I tried bfd_openw instead of bfd_openr, but the code to find
the RPATH doesn't work after doing that (the bfd_check_format_matches call
fails).

Can anybody provide me with some hints for the next step.

Peeter
--
#include "bfd.h"
#include <stdlib.h>
#include <stdio.h>

#include "sysdep.h"
#include "bfdlink.h"
#include "libbfd.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"

int main (int argc, char **argv)
{
  bfd *file;
  char **matching;
  asection *s;

  bfd_init ();

  if (argc != 2)
     abort();

  file = bfd_openr (argv[1], "elf32-i386");
  if (!file)
     abort();

#if 0
  if (!bfd_set_format(file, bfd_object))
     abort();
#endif

  if (!bfd_check_format_matches (file, bfd_object, &matching))
     abort();

  s = bfd_get_section_by_name (file, ".dynamic");
  if (s != NULL)
  {
      int elfsec;
      unsigned long link;
      bfd_byte *extdyn, *extdynend;
      size_t extdynsize;
      void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
      bfd_byte *dynbuf = NULL;

      dynbuf = (bfd_byte *) bfd_malloc (s->_raw_size);
      if (dynbuf == NULL)
        abort();

      if (! bfd_get_section_contents (file, s, (PTR) dynbuf, (file_ptr) 0,
                                      s->_raw_size))
        abort();

      elfsec = _bfd_elf_section_from_bfd_section (file, s);
      if (elfsec == -1)
        abort();
      link = elf_elfsections (file)[elfsec]->sh_link;

      extdynsize = get_elf_backend_data (file)->s->sizeof_dyn;
      swap_dyn_in = get_elf_backend_data (file)->s->swap_dyn_in;

      extdyn = dynbuf;
      extdynend = extdyn + s->_raw_size;
      for (; extdyn < extdynend; extdyn += extdynsize)
      {
          Elf_Internal_Dyn dyn;
          const char * tag = NULL;

          (*swap_dyn_in) (file, (PTR) extdyn, &dyn);

          if (dyn.d_tag == DT_RPATH)
             tag = "RPATH";

          if (dyn.d_tag == DT_SONAME)
             tag = "SONAME";

          if (tag)
          {
              const char *string;

              string = bfd_elf_string_from_elf_section (file, link,
                                                        dyn.d_un.d_val);
              if (string == NULL)
                abort();
              printf ("%s:%s\n", tag, string);
//              strcpy((char *)string, "x");
          }
      }
#if 0
      {
      bfd * out;
      asection * snew;

      out = bfd_create("out", file);
      if (!out)
         abort();

      snew = bfd_get_section_by_name (out, ".dynamic"); // doesn't work
      if (!snew)
         abort();

      if (! bfd_set_section_contents (out, snew, (PTR) dynbuf, (file_ptr)
0,
                                      s->_raw_size))
         abort();

      bfd_close(out);
      }
#endif
  }

  bfd_close (file);

  return 0;
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]