view killrpath.c @ 2:7bf4a164d5bb default tip

fix bug: long_options have to be zero terminated
author Peter Meerwald <p.meerwald@bct-electronic.com>
date Fri, 20 Jul 2012 11:28:30 +0200
parents bbbfb3f97919
children
line wrap: on
line source

/*
Taken from another list:

_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>
*/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
#if defined(HAVE_LINK_H)
#  include <link.h>
#endif /* HAVE_LINK_H */
#include <stdlib.h>
#include "protos.h"
#include <string.h>

static int
killrpath32(int fd, Elf32_Ehdr *ehdr) {
   int i;
   Elf32_Phdr phdr;
   Elf32_Dyn *dyns;
   int dynpos;

   if (0 != elf32_find_dynamic_section(fd, ehdr, &phdr))
   {
     perror("found no dynamic section");
     return 1;
   }

   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) != (int)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 ( ! elf_dynpath_tag(dyns[i].d_tag) )
        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) != (int)phdr.p_filesz)
     {
       perror ("writing dynamic section");
       return 1;
     }

   elf_close(fd);

   return 0;
}

static int
killrpath64(int fd, Elf64_Ehdr *ehdr) {
   int i;
   Elf64_Phdr phdr;
   Elf64_Dyn *dyns;
   int dynpos;

   if (0 != elf64_find_dynamic_section(fd, ehdr, &phdr))
   {
     perror("found no dynamic section");
     return 1;
   }

   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) != (int)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 ( ! elf_dynpath_tag(dyns[i].d_tag) )
        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) != (int)phdr.p_filesz)
     {
       perror ("writing dynamic section");
       return 1;
     }

   elf_close(fd);

   return 0;
}

/* Reads an ELF file, nukes all the RPATH entries. */

int
killrpath(const char *filename)
{
   int fd;
   Elf32_Ehdr ehdr32;
   Elf64_Ehdr ehdr64;

   fd = elf32_open(filename, O_RDWR, &ehdr32);
   if (fd >= 0)
   {
      return killrpath32(fd, &ehdr32);
   }

   fd = elf64_open(filename, O_RDWR, &ehdr64);
   if (fd >= 0)
   {
      return killrpath64(fd, &ehdr64);
   }

   perror ("elf_open");
   return 1;
}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.