#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <elf.h> #include <stdlib.h> #include <endian.h> #include <bits/wordsize.h> /* Reads an ELF file, nukes all the RPATH entries. */ int main(int argc, char **argv) { int fd; #if __WORDSIZE==32 Elf32_Ehdr ehdr; Elf32_Phdr phdr; Elf32_Dyn *dyns; #elif __WORDSIZE==64 Elf64_Ehdr ehdr; Elf64_Phdr phdr; Elf64_Dyn *dyns; #endif int i; int dynpos; #if __BYTE_ORDER==__LITTLE_ENDIAN printf ("Using %d-bit LSB format\n", __WORDSIZE); #elif __BYTE_ORDER==__BIG_ENDIAN printf ("Using %d-bit MSB format\n", __WORDSIZE); #else print ("Unknown endian\n"); return 1; #endif 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 || #if __WORDSIZE==32 ehdr.e_ident[EI_CLASS] != ELFCLASS32 || #elif __WORDSIZE==64 ehdr.e_ident[EI_CLASS] != ELFCLASS64 || #endif #if __BYTE_ORDER==__LITTLE_ENDIAN ehdr.e_ident[EI_DATA] != ELFDATA2LSB || #elif __BYTE_ORDER==__BIG_ENDIAN ehdr.e_ident[EI_DATA] != ELFDATA2MSB || #endif ehdr.e_ident[EI_VERSION] != EV_CURRENT) { #if __BYTE_ORDER==__LITTLE_ENDIAN fprintf(stderr, "`%s' probably isn't a %d-bit LSB-first ELF file.\n", #elif __BYTE_ORDER==__BIG_ENDIAN fprintf(stderr, "`%s' probably isn't a %d-bit MSB-first ELF file.\n", #endif argv[1], __WORDSIZE); return 1; } #if __WORDSIZE==32 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; } #elif __WORDSIZE==64 if (ehdr.e_phentsize != sizeof(Elf64_Phdr)) { fprintf(stderr, "section size was read as %d, not %d!\n", ehdr.e_phentsize, sizeof(Elf64_Phdr)); return 1; } #endif 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; }