| /* |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file "COPYING" in the main directory of this archive |
| * for more details. |
| * |
| * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com |
| */ |
| #include "common.h" |
| #include "load.h" |
| #include <stdio.h> |
| #include <string.h> |
| |
| int load_loadable(char *target, int fd, struct loadable *loadable) |
| { |
| int i; |
| |
| if (0) printf("load_loadable(%p, %d, %p), nsegs = %d\r\n", |
| target, fd, loadable, loadable->n); |
| |
| for (i = 0; i < loadable->n; i++) |
| { |
| struct loadsegment *seg = &loadable->segment[i]; |
| int n; |
| char *t; |
| |
| t = target + (seg->mem - loadable->first); |
| memset(t, 0, seg->length + seg->zeros); |
| if (seg->length) { |
| if (loadable->uncompressed_size) { |
| n = seg->length; |
| memcpy(t, &loadable->uncompressed_data[seg->offset], n); |
| } else |
| n = seekread(fd, t, seg->length, seg->offset); |
| } |
| else |
| n = 0; |
| |
| if (0) printf("loaded segment read %d/%d bytes at %p first word is %x\r\n", |
| n, seg->length, t, ((unsigned *)t)[0]); |
| |
| if (n != seg->length) |
| { |
| printf("ERROR: segment %d read() failed\n", |
| seg - &loadable->segment[0]); |
| return 0; |
| } |
| } |
| |
| return 1; |
| } |
| |
| typedef int (*prepfn_t)(int fd, struct loadable *loadable, int *wide); |
| |
| static prepfn_t prepfn[] = { |
| prepare_ELF32_loadable, |
| prepare_ELF64_loadable, |
| prepare_GZIP_loadable, |
| 0 |
| }; |
| |
| /* try all the loader functions until one works or fails fatally */ |
| int prepare_loadable(int fd, struct loadable *loadable, int *wide) |
| { |
| int r = PREPARE_CONTINUE, i; |
| |
| memset(loadable, 0, sizeof *loadable); |
| |
| for (i = 0; prepfn[i] != 0 && r == PREPARE_CONTINUE; i++) |
| { |
| r = (*prepfn[i])(fd, loadable, wide); |
| if (0) printf("prepare_loadable %d, %p %d\r\n", i, prepfn[i], r); |
| } |
| |
| if (0 && r == PREPARE_OK) |
| { |
| printf("pl: offset0 0x%08x, entry 0x%08x, first 0x%08x, size 0x%08x, n %d\n", |
| loadable->offset0, |
| loadable->entry, |
| loadable->first, |
| loadable->size, |
| loadable->n); |
| } |
| |
| return (r == PREPARE_OK); |
| } |