mirror of
https://github.com/kenshineto/kern.git
synced 2025-04-15 06:57:25 +00:00
track util changes as well
This commit is contained in:
parent
6ece4e20ac
commit
e2ac88e189
5 changed files with 140 additions and 101 deletions
38
kernel/vm.c
38
kernel/vm.c
|
@ -353,7 +353,8 @@ pde_t *vm_mkkvm(void)
|
|||
}
|
||||
#if TRACING_VM
|
||||
cio_puts("\nvm_mkkvm() final PD:\n");
|
||||
ptdump(pdir, true, 0, N_PDE);
|
||||
ptdump(pdir, true, 0, 16);
|
||||
ptdump(pdir, true, 0x200, 16);
|
||||
#endif
|
||||
|
||||
return pdir;
|
||||
|
@ -595,31 +596,36 @@ int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm)
|
|||
(uint32_t)addr, pa, (uint32_t)last, (uint32_t)pte, *pte);
|
||||
#endif
|
||||
|
||||
// create the new entry
|
||||
pde_t entry = pa | perm | PTE_P;
|
||||
|
||||
// if this entry has already been mapped, we're in trouble
|
||||
if (IS_PRESENT(*pte)) {
|
||||
if (*pte != entry) {
|
||||
#if TRACING_VM
|
||||
cio_puts(" ALREADY MAPPED?");
|
||||
cio_printf(" PDIX 0x%x PTIX 0x%x\n", PDIX(addr), PTIX(addr));
|
||||
cio_puts(" ALREADY MAPPED?");
|
||||
cio_printf(" PDIX 0x%x PTIX 0x%x\n", PDIX(addr), PTIX(addr));
|
||||
|
||||
// dump the directory
|
||||
ptdump(pdir, true, 0, N_PDE);
|
||||
// dump the directory
|
||||
ptdump(pdir, true, 0, N_PDE);
|
||||
|
||||
// find the relevant PDE entry
|
||||
uint32_t ix = PDIX(va);
|
||||
pde_t entry = pdir[ix];
|
||||
if (!IS_LARGE(entry)) {
|
||||
// round the PMT index down
|
||||
uint32_t ix2 = PTIX(va) & MOD4_MASK;
|
||||
// dump the PMT for the relevant directory entry
|
||||
ptdump((void *)P2V(PDE_ADDR(entry)), false, ix2, 8);
|
||||
}
|
||||
// find the relevant PDE entry
|
||||
uint32_t ix = PDIX(va);
|
||||
pde_t entry = pdir[ix];
|
||||
if (!IS_LARGE(entry)) {
|
||||
// round the PMT index down
|
||||
uint32_t ix2 = PTIX(va) & MOD4_MASK;
|
||||
// dump the PMT for the relevant directory entry
|
||||
ptdump((void *)P2V(PDE_ADDR(entry)), false, ix2, 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
PANIC(0, "mapping an already-mapped address");
|
||||
PANIC(0, "mapping an already-mapped address");
|
||||
}
|
||||
}
|
||||
|
||||
// ok, set the PTE as requested
|
||||
*pte = pa | perm | PTE_P;
|
||||
*pte = entry;
|
||||
|
||||
// nope - move to the next page
|
||||
addr += SZ_PAGE;
|
||||
|
|
|
@ -371,7 +371,7 @@ const pte_t id_map[N_PTE] = {
|
|||
const mapping_t kmap[] = {
|
||||
// va pa_start pa_end perms
|
||||
{ KERN_BASE, 0, EXT_BASE, PDE_RW },
|
||||
{ KERN_VLINK, KERN_PLINK, V2P(_data), 0 },
|
||||
{ KERN_VLINK, KERN_PLINK, V2P(_data), PDE_RW },
|
||||
{ (uint32_t)_data, V2P(_data), KERN_BASE, PDE_RW },
|
||||
{ DEV_BASE, DEV_BASE, 0, PDE_RW }
|
||||
};
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
@ -29,6 +29,7 @@
|
|||
#define DRIVE_USB 0x80
|
||||
|
||||
#define SECT_SIZE 512
|
||||
|
||||
char *progname; /* invocation name of this program */
|
||||
char *bootstrap_filename; /* path of file holding bootstrap program */
|
||||
char *output_filename; /* path of disk image file */
|
||||
|
@ -44,7 +45,9 @@ short drive = DRIVE_USB; /* boot drive */
|
|||
** device) are the only limiting factors on how many program sections
|
||||
** can be loaded.
|
||||
*/
|
||||
|
||||
#define N_INFO (SECT_SIZE / sizeof(short))
|
||||
|
||||
short info[N_INFO];
|
||||
int n_info = N_INFO;
|
||||
|
||||
|
@ -66,7 +69,6 @@ void quit(char *msg, int call_perror)
|
|||
errno = err_num;
|
||||
if (call_perror) {
|
||||
perror(msg);
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
}
|
||||
|
@ -75,12 +77,11 @@ void quit(char *msg, int call_perror)
|
|||
unlink(output_filename);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
const char usage_error_msg[] =
|
||||
"\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } "
|
||||
"...\n\n"
|
||||
"\nUsage: %s [ -d drive ] -b bootfile -o outfile { progfile loadpt } ...\n\n"
|
||||
"\t'drive' is either 'floppy' or 'usb' (default 'usb')\n\n"
|
||||
"\tThere must be at least one program file and load point.\n\n"
|
||||
"\tLoad points may be specified either as 32-bit quantities in hex,\n"
|
||||
|
@ -98,7 +99,6 @@ void usage_error(void)
|
|||
{
|
||||
fprintf(stderr, usage_error_msg, progname);
|
||||
quit(NULL, FALSE);
|
||||
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
|
@ -117,15 +117,16 @@ int copy_file(FILE *in)
|
|||
int i;
|
||||
|
||||
/*
|
||||
** Copy the file to the output, being careful that the
|
||||
** last sector is padded with null bytes out to the
|
||||
** sector size.
|
||||
*/
|
||||
** Copy the file to the output, being careful that the
|
||||
** last sector is padded with null bytes out to the
|
||||
** sector size.
|
||||
*/
|
||||
n_sectors = 0;
|
||||
while ((n_bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
|
||||
// pad this sector out to block size
|
||||
if (n_bytes < sizeof(buf)) {
|
||||
int i;
|
||||
|
||||
for (i = n_bytes; i < sizeof(buf); i += 1) {
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
@ -152,25 +153,25 @@ void process_file(char *name, char *addr)
|
|||
int n_bytes;
|
||||
|
||||
/*
|
||||
** Open the input file.
|
||||
*/
|
||||
** Open the input file.
|
||||
*/
|
||||
FILE *in = fopen(name, "rb");
|
||||
if (in == NULL) {
|
||||
quit(name, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Copy the file to the output, being careful that the
|
||||
** last block is padded with null bytes.
|
||||
*/
|
||||
** Copy the file to the output, being careful that the
|
||||
** last block is padded with null bytes.
|
||||
*/
|
||||
int n_sectors = copy_file(in);
|
||||
fclose(in);
|
||||
|
||||
/*
|
||||
** Decode the address they gave us. We'll accept two forms:
|
||||
** "nnnn:nnnn" for a segment:offset value (assumed to be hex),
|
||||
** "nnnnnnn" for a decimal, hex, or octal value
|
||||
*/
|
||||
** Decode the address they gave us. We'll accept two forms:
|
||||
** "nnnn:nnnn" for a segment:offset value (assumed to be hex),
|
||||
** "nnnnnnn" for a decimal, hex, or octal value
|
||||
*/
|
||||
int valid_address = FALSE;
|
||||
char *cp = strchr(addr, ':');
|
||||
if (cp != NULL) {
|
||||
|
@ -178,46 +179,49 @@ void process_file(char *name, char *addr)
|
|||
if (strlen(addr) == 9 && cp == addr + 4) {
|
||||
char *ep1, *ep2;
|
||||
int a1, a2;
|
||||
|
||||
segment = strtol(addr, &ep1, 16);
|
||||
offset = strtol(addr + 5, &ep2, 16);
|
||||
address = (segment << 4) + offset;
|
||||
valid_address = *ep1 == '\0' && *ep2 == '\0';
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "Bad address format - '%s'\n", addr);
|
||||
quit(NULL, FALSE);
|
||||
}
|
||||
|
||||
} else {
|
||||
// just a number, possibly hex or octal
|
||||
char *ep;
|
||||
|
||||
address = strtol(addr, &ep, 0);
|
||||
segment = (short)(address >> 4);
|
||||
offset = (short)(address & 0xf);
|
||||
valid_address = *ep == '\0' && address <= 0x0009ffff;
|
||||
}
|
||||
|
||||
if (!valid_address) {
|
||||
fprintf(stderr, "%s: Invalid address: %s\n", progname, addr);
|
||||
quit(NULL, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Make sure the program will fit!
|
||||
*/
|
||||
** Make sure the program will fit!
|
||||
*/
|
||||
if (address + n_sectors * SECT_SIZE > 0x0009ffff) {
|
||||
fprintf(stderr, "Program %s too large to start at 0x%08x\n", name,
|
||||
(unsigned int)address);
|
||||
quit(NULL, FALSE);
|
||||
}
|
||||
|
||||
if (n_info < 3) {
|
||||
quit("Too many programs!", FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Looks good: report and store the information.
|
||||
*/
|
||||
** Looks good: report and store the information.
|
||||
*/
|
||||
fprintf(stderr, " %s: %d sectors, loaded at 0x%x\n", name, n_sectors,
|
||||
(unsigned int)address);
|
||||
|
||||
info[--n_info] = n_sectors;
|
||||
info[--n_info] = segment;
|
||||
info[--n_info] = offset;
|
||||
|
@ -226,6 +230,7 @@ void process_file(char *name, char *addr)
|
|||
/*
|
||||
** Global variables set by getopt()
|
||||
*/
|
||||
|
||||
extern int optind, optopt;
|
||||
extern char *optarg;
|
||||
|
||||
|
@ -238,17 +243,21 @@ extern char *optarg;
|
|||
void process_args(int ac, char **av)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = getopt(ac, av, ":d:o:b:")) != EOF) {
|
||||
switch (c) {
|
||||
case ':': /* missing arg value */
|
||||
fprintf(stderr, "missing operand after -%c\n", optopt);
|
||||
/* FALL THROUGH */
|
||||
|
||||
/* FALL THROUGH */ case '?': /* error */
|
||||
case '?': /* error */
|
||||
usage_error();
|
||||
/* NOTREACHED */
|
||||
|
||||
/* NOTREACHED */ case 'b': /* -b bootstrap_file */
|
||||
case 'b': /* -b bootstrap_file */
|
||||
bootstrap_filename = optarg;
|
||||
break;
|
||||
|
||||
case 'd': /* -d drive */
|
||||
switch (*optarg) {
|
||||
case 'f':
|
||||
|
@ -261,27 +270,31 @@ void process_args(int ac, char **av)
|
|||
usage_error();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o': /* -o output_file */
|
||||
output_filename = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage_error();
|
||||
}
|
||||
}
|
||||
|
||||
if (!bootstrap_filename) {
|
||||
fprintf(stderr, "%s: no bootstrap file specified\n", progname);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (!output_filename) {
|
||||
fprintf(stderr, "%s: no disk image file specified\n", progname);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
** Must have at least two remaining arguments (file to load,
|
||||
** address at which it should be loaded), and must have an
|
||||
** even number of remaining arguments.
|
||||
*/
|
||||
** Must have at least two remaining arguments (file to load,
|
||||
** address at which it should be loaded), and must have an
|
||||
** even number of remaining arguments.
|
||||
*/
|
||||
int remain = ac - optind;
|
||||
if (remain < 2 || (remain & 1) != 0) {
|
||||
usage_error();
|
||||
|
@ -307,49 +320,50 @@ int main(int ac, char **av)
|
|||
int i;
|
||||
|
||||
/*
|
||||
** Save the program name for error messages
|
||||
*/
|
||||
** Save the program name for error messages
|
||||
*/
|
||||
progname = strrchr(av[0], '/');
|
||||
if (progname != NULL) {
|
||||
progname++;
|
||||
|
||||
} else {
|
||||
progname = av[0];
|
||||
}
|
||||
|
||||
/*
|
||||
** Process arguments
|
||||
*/
|
||||
** Process arguments
|
||||
*/
|
||||
process_args(ac, av);
|
||||
|
||||
/*
|
||||
** Open the output file
|
||||
*/
|
||||
** Open the output file
|
||||
*/
|
||||
|
||||
out = fopen(output_filename, "wb+");
|
||||
if (out == NULL) {
|
||||
quit(output_filename, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Open the bootstrap file and copy it to the output image.
|
||||
*/
|
||||
** Open the bootstrap file and copy it to the output image.
|
||||
*/
|
||||
bootimage = fopen(bootstrap_filename, "rb");
|
||||
if (bootimage == NULL) {
|
||||
quit(bootstrap_filename, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Remember the size of the bootstrap for later, as we
|
||||
** need to patch some things into it
|
||||
*/
|
||||
** Remember the size of the bootstrap for later, as we
|
||||
** need to patch some things into it
|
||||
*/
|
||||
int n_sectors = copy_file(bootimage);
|
||||
fclose(bootimage);
|
||||
|
||||
bootimage_size = n_sectors * SECT_SIZE;
|
||||
fprintf(stderr, " %s: %d sectors\n", bootstrap_filename, n_sectors);
|
||||
|
||||
/*
|
||||
** Process the programs one by one
|
||||
*/
|
||||
** Process the programs one by one
|
||||
*/
|
||||
ac -= optind;
|
||||
av += optind;
|
||||
while (ac >= 2) {
|
||||
|
@ -359,16 +373,16 @@ int main(int ac, char **av)
|
|||
}
|
||||
|
||||
/*
|
||||
** Check for oddball leftover argument
|
||||
*/
|
||||
** Check for oddball leftover argument
|
||||
*/
|
||||
if (ac > 0) {
|
||||
usage_error();
|
||||
}
|
||||
|
||||
/*
|
||||
** Seek to where the array of module data must begin and read
|
||||
** what's already there.
|
||||
*/
|
||||
** Seek to where the array of module data must begin and read
|
||||
** what's already there.
|
||||
*/
|
||||
n_words = (N_INFO - n_info);
|
||||
n_bytes = n_words * sizeof(info[0]);
|
||||
fseek(out, bootimage_size - n_bytes, SEEK_SET);
|
||||
|
@ -377,8 +391,8 @@ int main(int ac, char **av)
|
|||
}
|
||||
|
||||
/*
|
||||
** If that space is non-zero, we have a problem
|
||||
*/
|
||||
** If that space is non-zero, we have a problem
|
||||
*/
|
||||
for (i = 0; i < n_words; i += 1) {
|
||||
if (existing_data[i] != 0) {
|
||||
quit("Too many programs to load!", FALSE);
|
||||
|
@ -386,19 +400,21 @@ int main(int ac, char **av)
|
|||
}
|
||||
|
||||
/*
|
||||
** We know that we're only overwriting zeros at the end of
|
||||
** the bootstrap image, so it is ok to go ahead and do it.
|
||||
*/
|
||||
** We know that we're only overwriting zeros at the end of
|
||||
** the bootstrap image, so it is ok to go ahead and do it.
|
||||
*/
|
||||
fseek(out, bootimage_size - n_bytes, SEEK_SET);
|
||||
if (fwrite(info + n_info, sizeof(info[0]), n_words, out) != n_words) {
|
||||
quit("Write to boot image failed or was too short", FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
** Write the drive index to the image.
|
||||
*/
|
||||
** Write the drive index to the image.
|
||||
*/
|
||||
fseek(out, 508, SEEK_SET);
|
||||
fwrite((void *)&drive, sizeof(drive), 1, out);
|
||||
|
||||
fclose(out);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -5,18 +5,17 @@
|
|||
**
|
||||
** Examine a binary blob of ELF files.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <ctype.h>
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <elf.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
** Blob file organization
|
||||
|
@ -40,11 +39,11 @@
|
|||
** size Size of this ELF file, in bytes
|
||||
** flags Flags related to this file
|
||||
*/
|
||||
|
||||
// blob header: 8 bytes
|
||||
typedef struct header_s {
|
||||
char magic[4];
|
||||
uint32_t num;
|
||||
|
||||
} header_t;
|
||||
|
||||
// The program table entry is 32 bytes long. To accomplish this, the
|
||||
|
@ -73,8 +72,8 @@ typedef struct prog_s {
|
|||
typedef struct node_s {
|
||||
prog_t *data;
|
||||
struct node_s *next;
|
||||
|
||||
} node_t;
|
||||
|
||||
node_t *progs, *last_prog; // list pointers
|
||||
uint32_t n_progs; // number of files being copied
|
||||
uint32_t offset; // current file area offset
|
||||
|
@ -129,11 +128,12 @@ void process(uint32_t num, prog_t *prog)
|
|||
char *slash = strrchr(prog->name, '/');
|
||||
if (slash == NULL) {
|
||||
slash = prog->name;
|
||||
|
||||
} else {
|
||||
++slash;
|
||||
}
|
||||
|
||||
slash[0] = toupper(slash[0]);
|
||||
|
||||
if (defs) {
|
||||
// just printing #define statements
|
||||
printf("#define %-15s %2d\n", prog->name, num);
|
||||
|
@ -144,7 +144,6 @@ void process(uint32_t num, prog_t *prog)
|
|||
// first one, so print the file header
|
||||
puts(header);
|
||||
putchar('\t');
|
||||
|
||||
} else {
|
||||
// second or later entry; limit to 8 per line
|
||||
fputs(((num & 0x7) == 0) ? ",\n\t" : ", ", stdout);
|
||||
|
@ -160,56 +159,65 @@ void process(uint32_t num, prog_t *prog)
|
|||
prog->size, prog->flags);
|
||||
}
|
||||
}
|
||||
|
||||
void usage(char *name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-d | -e] blob_name\n", name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2 || argc > 3) {
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int nameix = 1;
|
||||
|
||||
// could use getopt() for this, but this is easy enough
|
||||
if (argc == 3) {
|
||||
if (strcmp(argv[1], "-d") == 0) {
|
||||
defs = true;
|
||||
|
||||
} else if (strcmp(argv[1], "-e") == 0) {
|
||||
enums = true;
|
||||
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
nameix = 2;
|
||||
}
|
||||
|
||||
char *name = argv[nameix];
|
||||
|
||||
int fd = open(name, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror(name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
header_t hdr;
|
||||
|
||||
int n = read(fd, &hdr, sizeof(header_t));
|
||||
if (n != sizeof(header_t)) {
|
||||
fprintf(stderr, "%s: header read returned only %d bytes\n", name, n);
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (strcmp(hdr.magic, "BLB") != 0) {
|
||||
fprintf(stderr, "%s: bad magic number\n", name);
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (hdr.num < 1) {
|
||||
fprintf(stderr, "%s: no programs in blob?\n", name);
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
prog_t progs[hdr.num];
|
||||
|
||||
n = read(fd, progs, hdr.num * sizeof(prog_t));
|
||||
if (n != (int)(hdr.num * sizeof(prog_t))) {
|
||||
fprintf(stderr, "%s: prog table only %d bytes, expected %lu\n", name, n,
|
||||
|
@ -217,13 +225,16 @@ int main(int argc, char *argv[])
|
|||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < hdr.num; ++i) {
|
||||
process(i, &progs[i]);
|
||||
}
|
||||
|
||||
if (enums) {
|
||||
// print the file trailer
|
||||
puts(trailer);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -5,17 +5,16 @@
|
|||
**
|
||||
** Create a binary blob from a collection of ELF files.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <elf.h>
|
||||
|
||||
/*
|
||||
** Blob file organization
|
||||
|
@ -39,11 +38,11 @@
|
|||
** size Size of this ELF file, in bytes
|
||||
** flags Flags related to this file
|
||||
*/
|
||||
|
||||
// blob header
|
||||
typedef struct header_s {
|
||||
char magic[4];
|
||||
uint32_t num;
|
||||
|
||||
} header_t;
|
||||
|
||||
// length of the file name field
|
||||
|
@ -68,8 +67,8 @@ typedef struct node_s {
|
|||
prog_t *data;
|
||||
char *fullname;
|
||||
struct node_s *next;
|
||||
|
||||
} node_t;
|
||||
|
||||
node_t *progs, *last_prog; // list pointers
|
||||
uint32_t n_progs; // number of files being copied
|
||||
uint32_t offset; // current file area offset
|
||||
|
@ -115,10 +114,12 @@ void process(const char *name)
|
|||
Elf32_Ehdr hdr;
|
||||
int n = read(fd, &hdr, sizeof(Elf32_Ehdr));
|
||||
close(fd);
|
||||
|
||||
if (n != sizeof(Elf32_Ehdr)) {
|
||||
fprintf(stderr, "%s: header read was short - only %d\n", name, n);
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr.e_ident[EI_MAG0] != ELFMAG0 || hdr.e_ident[EI_MAG1] != ELFMAG1 ||
|
||||
hdr.e_ident[EI_MAG2] != ELFMAG2 || hdr.e_ident[EI_MAG3] != ELFMAG3) {
|
||||
fprintf(stderr, "%s: bad ELF magic number\n", name);
|
||||
|
@ -131,12 +132,14 @@ void process(const char *name)
|
|||
fprintf(stderr, "%s: calloc prog returned NULL\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
node_t *node = calloc(1, sizeof(node_t));
|
||||
if (node == NULL) {
|
||||
free(new);
|
||||
fprintf(stderr, "%s: calloc node returned NULL\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
node->data = new;
|
||||
node->fullname = strdup(name);
|
||||
|
||||
|
@ -147,11 +150,11 @@ void process(const char *name)
|
|||
if (slash == NULL) {
|
||||
// only the file name
|
||||
slash = name;
|
||||
|
||||
} else {
|
||||
// skip the slash
|
||||
++slash;
|
||||
}
|
||||
|
||||
strncpy(new->name, slash, sizeof(new->name) - 1);
|
||||
new->offset = offset;
|
||||
new->size = info.st_size;
|
||||
|
@ -164,7 +167,6 @@ void process(const char *name)
|
|||
if ((info.st_size & FSIZE_MASK) != 0) {
|
||||
// nope, so we must round it up when we write it out
|
||||
new->flags |= FL_ROUNDUP;
|
||||
|
||||
// increases the offset to the next file
|
||||
offset += 8 - (info.st_size & FSIZE_MASK);
|
||||
}
|
||||
|
@ -173,7 +175,6 @@ void process(const char *name)
|
|||
if (progs == NULL) {
|
||||
// first entry
|
||||
progs = node;
|
||||
|
||||
} else {
|
||||
// add to the end
|
||||
if (last_prog == NULL) {
|
||||
|
@ -206,24 +207,23 @@ void copy(FILE *ofd, node_t *node)
|
|||
perror(node->fullname);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buf[512];
|
||||
|
||||
// copy it block-by-block
|
||||
do {
|
||||
int n = read(fd, buf, 512);
|
||||
|
||||
// no bytes --> we're done
|
||||
if (n < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// copy it, and verify the copy count
|
||||
int k = fwrite(buf, 1, n, ofd);
|
||||
if (k != n) {
|
||||
fprintf(stderr, "%s: write of %d returned %d\n", prog->name, n, k);
|
||||
}
|
||||
|
||||
} while (1);
|
||||
|
||||
printf("%s: copied %d", prog->name, prog->size);
|
||||
|
||||
// do we need to round up?
|
||||
|
@ -249,12 +249,14 @@ void copy(FILE *ofd, node_t *node)
|
|||
// all done!
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// construct program list
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
process(argv[i]);
|
||||
}
|
||||
|
||||
if (n_progs < 1) {
|
||||
fputs("Nothing to do... exiting.", stderr);
|
||||
exit(0);
|
||||
|
@ -267,12 +269,14 @@ int main(int argc, char *argv[])
|
|||
perror("user.img");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Processing %d ELF files\n", n_progs);
|
||||
|
||||
// we need to adjust the offset values so they are relative to the
|
||||
// start of the blob, not relative to the start of the file area.
|
||||
// do this by adding the sum of the file header and program entries
|
||||
// to each offset field.
|
||||
|
||||
uint32_t hlen = sizeof(header_t) + n_progs * sizeof(prog_t);
|
||||
node_t *curr = progs;
|
||||
while (curr != NULL) {
|
||||
|
@ -310,6 +314,8 @@ int main(int argc, char *argv[])
|
|||
free(tmp->fullname);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
fclose(ofd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue