1
0
mirror of https://github.com/koenkooi/foo2zjs.git synced 2026-01-22 03:34:49 +08:00
foo2zjs/arm2hpdl.c
Koen Kooi 66819e6d05 import 'Tarball last modified: Fri Jan 22 05:14:24 2016 CST'
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
2016-01-25 16:22:04 +01:00

252 lines
4.4 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/*
* Global option flags
*/
int Debug = 0;
void
debug(int level, char *fmt, ...)
{
va_list ap;
if (Debug < level)
return;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int
error(int fatal, char *fmt, ...)
{
va_list ap;
if (fatal)
fprintf(stderr, "Error: ");
else
fprintf(stderr, "Warning: ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fatal > 0)
exit(fatal);
else
return (fatal);
}
void
usage(void)
{
fprintf(stderr,
"Usage:\n"
" arm2hpdl [options] sihp1005.img > sihp1005.dl\n"
"\n"
" Add HP download header/trailer to an ARM ELF binary.\n"
" If the file already has an HP header, just copy it to stdout.\n"
"\n"
"Options:\n"
" -D lvl Set Debug level [%d]\n"
, Debug
);
exit(1);
}
/*
* Compute HP-style checksum
*/
long
docheck(long check, unsigned char *buf, int len)
{
int i;
if (len & 1)
error(1, "We should never see an odd number of bytes in this app.\n");
for (i = 0; i < len; i += 2)
check += (buf[i]<<0) | (buf[i+1]<<8);
return check;
}
int
main(int argc, char *argv[])
{
extern int optind;
extern char *optarg;
int c;
int rc;
unsigned char buf[BUFSIZ];
int len;
FILE *fp;
struct stat stats;
int size;
unsigned char elf[4];
long check;
int iself;
int ispjl;
while ( (c = getopt(argc, argv, "D:?h")) != EOF)
switch (c)
{
case 'D':
Debug = atoi(optarg);
break;
default:
usage();
exit(1);
}
argc -= optind;
argv += optind;
if (argc != 1)
usage();
/*
* Open the file and figure out if its an ELF file
* by reading the first 4 bytes.
*/
fp = fopen(argv[0], "r");
if (!fp)
error(1, "Can't open '%s'\n", argv[0]);
len = fread(elf, 1, sizeof(elf), fp);
if (len != 4)
error(1, "Premature EOF on '%s'\n", argv[0]);
iself = 0;
ispjl = 0;
check = 0;
if (memcmp(elf, "\177ELF", 4) == 0)
{
/*
* Its an ELF executable file
*/
unsigned char filhdr[17] =
{
0xbe, 0xef, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
0, 0, 0, 0, /* size goes here */
0, 0, 0,
};
unsigned char sechdr[12] =
{
0xc0, 0xde, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 0, 0
};
iself = 1;
/*
* Create and write the file header
*/
rc = stat(argv[0], &stats);
if (rc < 0)
error(1, "Can't stat '%s'\n", argv[0]);
size = stats.st_size + 12 + 4;
filhdr[10] = size>>24;
filhdr[11] = size>>16;
filhdr[12] = size>> 8;
filhdr[13] = size>> 0;
rc = fwrite(filhdr, 1, sizeof(filhdr), stdout);
/*
* Create and write the section header
*/
//memset(sechdr+2, 0, sizeof(sechdr)-2);
check = docheck(check, sechdr, sizeof(sechdr));
rc = fwrite(sechdr, 1, sizeof(sechdr), stdout);
}
else if (memcmp(elf, "\276\357AB", 4) == 0)
{
/*
* This file already has an HP download header.
* Don't change it.
*/
if (Debug)
error(0, "This file already has an HP header. "
"I will just copy it to stdout.\n");
}
else if (memcmp(elf, "20", 2) == 0)
{
unsigned char hdr[8];
ispjl = 1;
printf("\033%%-12345X@PJL ENTER LANGUAGE=ACL\r\n");
rc = stat(argv[0], &stats);
if (rc < 0)
error(1, "Can't stat '%s'\n", argv[0]);
size = stats.st_size - 8;
hdr[0] = 0x00;
hdr[1] = 0xac;
hdr[2] = 0xc0;
hdr[3] = 0xde;
hdr[4] = size>>24;
hdr[5] = size>>16;
hdr[6] = size>> 8;
hdr[7] = size>> 0;
rc = fwrite(hdr, 1, sizeof(hdr), stdout);
}
else
{
error(1, "I don't understand this file at all!\n");
}
/*
* Write out the 4 bytes we read earlier
*/
if (iself)
check = docheck(check, elf, sizeof(elf));
rc = fwrite(elf, 1, sizeof(elf), stdout);
/*
* Write out the remainder of the file
*/
while ( (len = fread(buf, 1, sizeof(buf), fp)) )
{
if (iself)
check = docheck(check, buf, len);
rc = fwrite(buf, 1, len, stdout);
}
fclose(fp);
/*
* Add the file trailer
*/
if (iself)
{
/*
* Add in the checksum carries and complement it
*/
while (check >> 16)
check = (check&0xffff) + (check>>16);
check = ~check;
putchar(0xff);
putchar(0xff);
putchar((check >> 0) & 0xff);
putchar((check >> 8) & 0xff);
debug(1, "checksum = %lx\n", check);
}
if (ispjl)
printf("\033%%-12345X");
exit(0);
}