OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * ncfileutil.c - open an executable file. FOR TESTING ONLY. | 8 * ncfileutil.c - open an executable file. FOR TESTING ONLY. |
9 */ | 9 */ |
10 | 10 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 return -1; | 179 return -1; |
180 } | 180 } |
181 /* TODO(karl) Remove the cast to size_t, or verify value in range. */ | 181 /* TODO(karl) Remove the cast to size_t, or verify value in range. */ |
182 nread = readat(ncf, fd, ncf->sheaders, (off_t) shsize, (off_t) h.e_shoff); | 182 nread = readat(ncf, fd, ncf->sheaders, (off_t) shsize, (off_t) h.e_shoff); |
183 if (nread < 0 || (size_t) nread < shsize) { | 183 if (nread < 0 || (size_t) nread < shsize) { |
184 ncf->error_fn("nc_load(%s): could not read section headers\n", | 184 ncf->error_fn("nc_load(%s): could not read section headers\n", |
185 ncf->fname); | 185 ncf->fname); |
186 return -1; | 186 return -1; |
187 } | 187 } |
188 | 188 |
| 189 /* Keep a copy of the header around for the validator */ |
| 190 ncf->eheader = calloc(1, sizeof(Elf_Ehdr)); |
| 191 if (ncf->eheader == NULL) { |
| 192 ncf->error_fn("nc_load(%s): calloc(1, sizeof(Elf_Ehdr)) failed\n", |
| 193 ncf->fname); |
| 194 return -1; |
| 195 } |
| 196 *ncf->eheader = h; /* save the copy */ |
| 197 |
189 /* success! */ | 198 /* success! */ |
190 return 0; | 199 return 0; |
191 } | 200 } |
192 | 201 |
193 ncfile *nc_loadfile_depending(const char *filename, | 202 ncfile *nc_loadfile_depending(const char *filename, |
194 nc_loadfile_error_fn error_fn) { | 203 nc_loadfile_error_fn error_fn) { |
195 ncfile *ncf; | 204 ncfile *ncf; |
196 int fd; | 205 int fd; |
197 int rdflags = O_RDONLY | _O_BINARY; | 206 int rdflags = O_RDONLY | _O_BINARY; |
198 fd = OPEN(filename, rdflags); | 207 fd = OPEN(filename, rdflags); |
199 if (fd < 0) return NULL; | 208 if (fd < 0) return NULL; |
200 | 209 |
201 /* Allocate the ncfile structure */ | 210 /* Allocate the ncfile structure */ |
202 ncf = calloc(1, sizeof(ncfile)); | 211 ncf = calloc(1, sizeof(ncfile)); |
203 if (ncf == NULL) return NULL; | 212 if (ncf == NULL) return NULL; |
204 ncf->size = 0; | 213 ncf->size = 0; |
205 ncf->data = NULL; | 214 ncf->data = NULL; |
206 ncf->fname = filename; | 215 ncf->fname = filename; |
207 if (error_fn == NULL) { | 216 if (error_fn == NULL) { |
208 ncf->error_fn = NcLoadFilePrintError; | 217 ncf->error_fn = NcLoadFilePrintError; |
209 } else { | 218 } else { |
210 ncf->error_fn = error_fn; | 219 ncf->error_fn = error_fn; |
211 } | 220 } |
212 | 221 |
213 if (nc_load(ncf, fd) < 0) { | 222 if (nc_load(ncf, fd) < 0) { |
214 close(fd); | 223 close(fd); |
215 free(ncf); | 224 nc_freefile(ncf); |
216 return NULL; | 225 return NULL; |
217 } | 226 } |
218 close(fd); | 227 close(fd); |
219 return ncf; | 228 return ncf; |
220 } | 229 } |
221 | 230 |
222 ncfile *nc_loadfile(const char *filename) { | 231 ncfile *nc_loadfile(const char *filename) { |
223 return nc_loadfile_depending(filename, NULL); | 232 return nc_loadfile_depending(filename, NULL); |
224 } | 233 } |
225 | 234 |
226 ncfile *nc_loadfile_with_error_fn(const char *filename, | 235 ncfile *nc_loadfile_with_error_fn(const char *filename, |
227 nc_loadfile_error_fn error_fn) { | 236 nc_loadfile_error_fn error_fn) { |
228 return nc_loadfile_depending(filename, error_fn); | 237 return nc_loadfile_depending(filename, error_fn); |
229 } | 238 } |
230 | 239 |
231 | 240 |
232 void nc_freefile(ncfile *ncf) { | 241 void nc_freefile(ncfile *ncf) { |
233 if (ncf->data != NULL) free(ncf->data); | 242 if (ncf == NULL) return; |
| 243 free(ncf->data); |
| 244 free(ncf->eheader); |
| 245 free(ncf->pheaders); |
| 246 free(ncf->sheaders); |
234 free(ncf); | 247 free(ncf); |
235 } | 248 } |
236 | 249 |
237 /***********************************************************************/ | 250 /***********************************************************************/ |
238 | 251 |
239 void GetVBaseAndLimit(ncfile *ncf, NaClPcAddress *vbase, | 252 void GetVBaseAndLimit(ncfile *ncf, NaClPcAddress *vbase, |
240 NaClPcAddress *vlimit) { | 253 NaClPcAddress *vlimit) { |
241 int ii; | 254 int ii; |
242 /* TODO(karl) - Define so constant applies to 64-bit pc address. */ | 255 /* TODO(karl) - Define so constant applies to 64-bit pc address. */ |
243 NaClPcAddress base = 0xffffffff; | 256 NaClPcAddress base = 0xffffffff; |
244 NaClPcAddress limit = 0; | 257 NaClPcAddress limit = 0; |
245 | 258 |
246 for (ii = 0; ii < ncf->shnum; ii++) { | 259 for (ii = 0; ii < ncf->shnum; ii++) { |
247 if ((ncf->sheaders[ii].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR) { | 260 if ((ncf->sheaders[ii].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR) { |
248 if (ncf->sheaders[ii].sh_addr < base) base = ncf->sheaders[ii].sh_addr; | 261 if (ncf->sheaders[ii].sh_addr < base) base = ncf->sheaders[ii].sh_addr; |
249 if (ncf->sheaders[ii].sh_addr + ncf->sheaders[ii].sh_size > limit) | 262 if (ncf->sheaders[ii].sh_addr + ncf->sheaders[ii].sh_size > limit) |
250 limit = ncf->sheaders[ii].sh_addr + ncf->sheaders[ii].sh_size; | 263 limit = ncf->sheaders[ii].sh_addr + ncf->sheaders[ii].sh_size; |
251 } | 264 } |
252 } | 265 } |
253 *vbase = base; | 266 *vbase = base; |
254 *vlimit = limit; | 267 *vlimit = limit; |
255 } | 268 } |
OLD | NEW |