Mercurial > hg > chrpath
comparison elf.c @ 0:b8f7423e385c
import 0.13
| author | Peter Meerwald <pmeerw@pmeerw.net> |
|---|---|
| date | Fri, 20 Jul 2012 01:51:24 +0200 |
| parents | |
| children | bbbfb3f97919 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:b8f7423e385c |
|---|---|
| 1 | |
| 2 #ifdef HAVE_CONFIG_H | |
| 3 # include "config.h" | |
| 4 #endif | |
| 5 | |
| 6 #include <elf.h> | |
| 7 #if defined(HAVE_SYS_LINK_H) | |
| 8 # include <sys/link.h> /* Find DT_RPATH on Solaris 2.6 */ | |
| 9 #endif /* HAVE_SYS_LINK_H */ | |
| 10 #include <stdio.h> | |
| 11 #include <string.h> | |
| 12 #include <unistd.h> | |
| 13 #include <sys/types.h> | |
| 14 #include <sys/stat.h> | |
| 15 #include <errno.h> | |
| 16 #include <fcntl.h> | |
| 17 #include "protos.h" | |
| 18 | |
| 19 int | |
| 20 elf_open(const char *filename, int flags, Elf_Ehdr *ehdr) | |
| 21 { | |
| 22 int fd; | |
| 23 | |
| 24 fd = open(filename, flags); | |
| 25 if (fd == -1) | |
| 26 { | |
| 27 perror ("open"); | |
| 28 return -1; | |
| 29 } | |
| 30 | |
| 31 if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) | |
| 32 { | |
| 33 perror ("reading header"); | |
| 34 close(fd); | |
| 35 return -1; | |
| 36 } | |
| 37 | |
| 38 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || | |
| 39 ehdr->e_ident[EI_CLASS] != ELFCLASS || | |
| 40 ehdr->e_ident[EI_DATA] != ELFDATA2 || | |
| 41 ehdr->e_ident[EI_VERSION] != EV_CURRENT) | |
| 42 { | |
| 43 fprintf(stderr, | |
| 44 #ifdef WORDS_BIGENDIAN | |
| 45 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", | |
| 46 #else /* not WORD_BIGENDIAN */ | |
| 47 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", | |
| 48 #endif /* not WORD_BIGENDIAN */ | |
| 49 filename, SIZEOF_VOID_P * 8); | |
| 50 close(fd); | |
| 51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | |
| 52 return -1; | |
| 53 } | |
| 54 | |
| 55 if (ehdr->e_phentsize != sizeof(Elf_Phdr)) | |
| 56 { | |
| 57 fprintf(stderr, "section size was read as %d, not %d!\n", | |
| 58 ehdr->e_phentsize, sizeof(Elf_Phdr)); | |
| 59 close(fd); | |
| 60 return -1; | |
| 61 } | |
| 62 return fd; | |
| 63 } | |
| 64 | |
| 65 int | |
| 66 elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr) | |
| 67 { | |
| 68 int i; | |
| 69 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | |
| 70 { | |
| 71 perror ("positioning for sections"); | |
| 72 return 1; | |
| 73 } | |
| 74 | |
| 75 for (i = 0; i < ehdr->e_phnum; i++) | |
| 76 { | |
| 77 if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) | |
| 78 { | |
| 79 perror ("reading section header"); | |
| 80 return 1; | |
| 81 } | |
| 82 if (phdr->p_type == PT_DYNAMIC) | |
| 83 break; | |
| 84 } | |
| 85 if (i == ehdr->e_phnum) | |
| 86 { | |
| 87 fprintf (stderr, "No dynamic section found.\n"); | |
| 88 return 2; | |
| 89 } | |
| 90 | |
| 91 if (0 == phdr->p_filesz) | |
| 92 { | |
| 93 fprintf (stderr, "Length of dynamic section is zero.\n"); | |
| 94 return 3; | |
| 95 } | |
| 96 | |
| 97 return 0; | |
| 98 } | |
| 99 | |
| 100 void | |
| 101 elf_close(int fd) | |
| 102 { | |
| 103 close(fd); | |
| 104 } | |
| 105 | |
| 106 const char * | |
| 107 elf_tagname(int tag) | |
| 108 { | |
| 109 switch (tag) { | |
| 110 case DT_RPATH: | |
| 111 return "RPATH"; | |
| 112 break; | |
| 113 #if defined(DT_RUNPATH) | |
| 114 case DT_RUNPATH: | |
| 115 return "RUNPATH"; | |
| 116 break; | |
| 117 #endif /* DT_RUNPATH */ | |
| 118 } | |
| 119 return "UNKNOWN"; | |
| 120 } | |
| 121 | |
| 122 int | |
| 123 elf_dynpath_tag(int tag) | |
| 124 { | |
| 125 return ( tag == DT_RPATH | |
| 126 #if defined(DT_RUNPATH) | |
| 127 || tag == DT_RUNPATH | |
| 128 #endif /* DT_RUNPATH */ | |
| 129 ); | |
| 130 } |
