This is the mail archive of the
libc-hacker@cygnus.com
mailing list for the glibc project.
Re: changing embedded RPATH in existing executables.
- To: peeterj@ca.ibm.com
- Subject: Re: changing embedded RPATH in existing executables.
- From: Geoff Keating <geoffk@ozemail.com.au>
- Date: Thu, 29 Apr 1999 17:41:06 +1000
- CC: egcs@cygnus.com, libc-hacker@cygnus.com, linux-gcc@vger.rutgers.edu
- References: <87256761.0059ABD9.00@d53mta05h.boulder.ibm.com>
> From: peeterj@ca.ibm.com
> 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.
_Changing_ is a little tricky, but the attached program strips rpaths
from executables (I find it essential for debugging the binutils).
It's endian-dependent, if you want this for x86 you can just change
the occurrences of 'MSB' to 'LSB' and compile (I should really fix
that).
--
Geoffrey Keating <geoffk@ozemail.com.au>
===File ~/src/killrpath.c===================================
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
#include <stdlib.h>
/* Reads an ELF file, nukes all the RPATH entries. */
int
main(int argc, char **argv)
{
int fd;
Elf32_Ehdr ehdr;
int i;
Elf32_Phdr phdr;
Elf32_Dyn *dyns;
int dynpos;
if (argc != 2)
{
printf ("Usage: %s objectfile\n", argv[0]);
return 1;
}
fd = open(argv[1], O_RDWR);
if (fd == -1)
{
perror ("open");
return 1;
}
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
{
perror ("reading header");
return 1;
}
if (*(unsigned *)ehdr.e_ident != *(const unsigned *)ELFMAG ||
ehdr.e_ident[EI_CLASS] != ELFCLASS32 ||
ehdr.e_ident[EI_DATA] != ELFDATA2MSB ||
ehdr.e_ident[EI_VERSION] != EV_CURRENT)
{
fprintf(stderr, "`%s' probably isn't a 32-bit MSB-first ELF file.\n",
argv[1]);
return 1;
}
if (ehdr.e_phentsize != sizeof(Elf32_Phdr))
{
fprintf(stderr, "section size was read as %d, not %d!\n",
ehdr.e_phentsize, sizeof(Elf32_Phdr));
return 1;
}
if (lseek(fd, ehdr.e_phoff, SEEK_SET) == -1)
{
perror ("positioning for sections");
return 1;
}
for (i = 0; i < ehdr.e_phnum; i++)
{
if (read(fd, &phdr, sizeof(phdr)) != sizeof(phdr))
{
perror ("reading section header");
return 1;
}
if (phdr.p_type == PT_DYNAMIC)
break;
}
if (i == ehdr.e_phnum)
{
fprintf (stderr, "No dynamic section found.\n");
return 2;
}
dyns = malloc(phdr.p_memsz);
if (dyns == NULL)
{
perror ("allocating memory for dynamic section");
return 1;
}
memset(dyns, 0, phdr.p_memsz);
if (lseek(fd, phdr.p_offset, SEEK_SET) == -1
|| read(fd, dyns, phdr.p_filesz) != phdr.p_filesz)
{
perror ("reading dynamic section");
return 1;
}
dynpos = 0;
for (i = 0; dyns[i].d_tag != DT_NULL; i++)
{
dyns[dynpos] = dyns[i];
if (dyns[i].d_tag != DT_RPATH)
dynpos++;
}
for (; dynpos < i; dynpos++)
dyns[dynpos].d_tag = DT_NULL;
if (lseek(fd, phdr.p_offset, SEEK_SET) == -1
|| write(fd, dyns, phdr.p_filesz) != phdr.p_filesz)
{
perror ("writing dynamic section");
return 1;
}
return 0;
}
============================================================