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 } |