Mercurial > hg > chrpath
comparison elf.c @ 1:bbbfb3f97919
implement 32 and 64 bit support
author | Peter Meerwald <p.meerwald@bct-electronic.com> |
---|---|
date | Fri, 20 Jul 2012 11:26:24 +0200 |
parents | b8f7423e385c |
children |
comparison
equal
deleted
inserted
replaced
0:b8f7423e385c | 1:bbbfb3f97919 |
---|---|
15 #include <errno.h> | 15 #include <errno.h> |
16 #include <fcntl.h> | 16 #include <fcntl.h> |
17 #include "protos.h" | 17 #include "protos.h" |
18 | 18 |
19 int | 19 int |
20 elf_open(const char *filename, int flags, Elf_Ehdr *ehdr) | 20 elf32_open(const char *filename, int flags, Elf32_Ehdr *ehdr) |
21 { | 21 { |
22 int fd; | 22 int fd; |
23 | 23 |
24 fd = open(filename, flags); | 24 fd = open(filename, flags); |
25 if (fd == -1) | 25 if (fd == -1) |
34 close(fd); | 34 close(fd); |
35 return -1; | 35 return -1; |
36 } | 36 } |
37 | 37 |
38 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || | 38 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || |
39 ehdr->e_ident[EI_CLASS] != ELFCLASS || | 39 ehdr->e_ident[EI_CLASS] != ELFCLASS32 || |
40 ehdr->e_ident[EI_DATA] != ELFDATA2 || | 40 ehdr->e_ident[EI_DATA] != ELFDATA2 || |
41 ehdr->e_ident[EI_VERSION] != EV_CURRENT) | 41 ehdr->e_ident[EI_VERSION] != EV_CURRENT) |
42 { | 42 { |
43 fprintf(stderr, | 43 fprintf(stderr, |
44 #ifdef WORDS_BIGENDIAN | 44 #ifdef WORDS_BIGENDIAN |
45 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", | 45 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", |
46 #else /* not WORD_BIGENDIAN */ | 46 #else /* not WORD_BIGENDIAN */ |
47 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", | 47 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", |
48 #endif /* not WORD_BIGENDIAN */ | 48 #endif /* not WORD_BIGENDIAN */ |
49 filename, SIZEOF_VOID_P * 8); | 49 filename, 32); |
50 close(fd); | 50 close(fd); |
51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | 51 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ |
52 return -1; | 52 return -1; |
53 } | 53 } |
54 | 54 |
55 if (ehdr->e_phentsize != sizeof(Elf_Phdr)) | 55 printf("32-bit ELF file\n"); |
56 { | 56 |
57 fprintf(stderr, "section size was read as %d, not %d!\n", | 57 if (ehdr->e_phentsize != sizeof(Elf32_Phdr)) |
58 ehdr->e_phentsize, sizeof(Elf_Phdr)); | 58 { |
59 fprintf(stderr, "section size was read as %d, not %lu!\n", | |
60 ehdr->e_phentsize, sizeof(Elf32_Phdr)); | |
59 close(fd); | 61 close(fd); |
60 return -1; | 62 return -1; |
61 } | 63 } |
62 return fd; | 64 return fd; |
63 } | 65 } |
64 | 66 |
65 int | 67 int |
66 elf_find_dynamic_section(int fd, Elf_Ehdr *ehdr, Elf_Phdr *phdr) | 68 elf64_open(const char *filename, int flags, Elf64_Ehdr *ehdr) |
69 { | |
70 int fd; | |
71 | |
72 fd = open(filename, flags); | |
73 if (fd == -1) | |
74 { | |
75 perror ("open"); | |
76 return -1; | |
77 } | |
78 | |
79 if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr)) | |
80 { | |
81 perror ("reading header"); | |
82 close(fd); | |
83 return -1; | |
84 } | |
85 | |
86 if (0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || | |
87 ehdr->e_ident[EI_CLASS] != ELFCLASS64 || | |
88 ehdr->e_ident[EI_DATA] != ELFDATA2 || | |
89 ehdr->e_ident[EI_VERSION] != EV_CURRENT) | |
90 { | |
91 fprintf(stderr, | |
92 #ifdef WORDS_BIGENDIAN | |
93 "`%s' probably isn't a %d-bit MSB-first ELF file.\n", | |
94 #else /* not WORD_BIGENDIAN */ | |
95 "`%s' probably isn't a %d-bit LSB-first ELF file.\n", | |
96 #endif /* not WORD_BIGENDIAN */ | |
97 filename, 64); | |
98 close(fd); | |
99 errno = ENOEXEC; /* Hm, is this the best errno code to use? */ | |
100 return -1; | |
101 } | |
102 | |
103 printf("64-bit ELF file\n"); | |
104 | |
105 if (ehdr->e_phentsize != sizeof(Elf64_Phdr)) | |
106 { | |
107 fprintf(stderr, "section size was read as %d, not %lu!\n", | |
108 ehdr->e_phentsize, sizeof(Elf64_Phdr)); | |
109 close(fd); | |
110 return -1; | |
111 } | |
112 return fd; | |
113 } | |
114 | |
115 int | |
116 elf32_find_dynamic_section(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr) | |
117 { | |
118 int i; | |
119 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | |
120 { | |
121 perror ("positioning for sections"); | |
122 return 1; | |
123 } | |
124 | |
125 for (i = 0; i < ehdr->e_phnum; i++) | |
126 { | |
127 if (read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) | |
128 { | |
129 perror ("reading section header"); | |
130 return 1; | |
131 } | |
132 if (phdr->p_type == PT_DYNAMIC) | |
133 break; | |
134 } | |
135 if (i == ehdr->e_phnum) | |
136 { | |
137 fprintf (stderr, "No dynamic section found.\n"); | |
138 return 2; | |
139 } | |
140 | |
141 if (0 == phdr->p_filesz) | |
142 { | |
143 fprintf (stderr, "Length of dynamic section is zero.\n"); | |
144 return 3; | |
145 } | |
146 | |
147 return 0; | |
148 } | |
149 | |
150 int | |
151 elf64_find_dynamic_section(int fd, Elf64_Ehdr *ehdr, Elf64_Phdr *phdr) | |
67 { | 152 { |
68 int i; | 153 int i; |
69 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) | 154 if (lseek(fd, ehdr->e_phoff, SEEK_SET) == -1) |
70 { | 155 { |
71 perror ("positioning for sections"); | 156 perror ("positioning for sections"); |