1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
/*
* 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);
}
|