summaryrefslogtreecommitdiff
path: root/makerun.c
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2023-03-10 22:21:21 +0000
committerJohn-Mark Bell <jmb@netsurf-browser.org>2023-03-10 22:21:21 +0000
commita6a833a50b3287e6c719d9d5d54f909a894ebaa1 (patch)
tree31c5a48009f0f4a0eb604f04efa57432b7d5307e /makerun.c
parent3fe86945effb26bc695ce60bb766bb1524df41d9 (diff)
downloadmakerun-a6a833a50b3287e6c719d9d5d54f909a894ebaa1.tar.gz
makerun-a6a833a50b3287e6c719d9d5d54f909a894ebaa1.tar.bz2
Add support for relocateable AIFs
Rework to use inttypes, improve support for squeezed images and handle relocateable images correctly.
Diffstat (limited to 'makerun.c')
-rw-r--r--makerun.c135
1 files changed, 112 insertions, 23 deletions
diff --git a/makerun.c b/makerun.c
index 8871b8f..5008b1b 100644
--- a/makerun.c
+++ b/makerun.c
@@ -1,3 +1,4 @@
+#include <inttypes.h>
#include <stdio.h>
#include <string.h>
@@ -7,25 +8,40 @@
#endif
struct header {
- unsigned int decompress;
- unsigned int selfreloc;
- unsigned int zeroinit;
- unsigned int entry;
- unsigned int exit;
- unsigned int rosize;
- unsigned int rwsize;
- unsigned int dbsize;
- unsigned int zisize;
- unsigned int dbtype;
- unsigned int base;
- unsigned int wkspace;
+ uint32_t decompress;
+ uint32_t selfreloc;
+ uint32_t zeroinit;
+ uint32_t entry;
+ uint32_t exit;
+ uint32_t rosize;
+ uint32_t rwsize;
+ uint32_t dbsize;
+ uint32_t zisize;
+ uint32_t dbtype;
+ uint32_t base;
+ uint32_t wkspace;
+ uint32_t flags;
+ uint32_t database;
+ uint32_t r1;
+ uint32_t r2;
+ uint32_t zicode[16];
+};
+
+struct sqz_header {
+ uint32_t decsize;
+ uint32_t encsize;
+ uint32_t tabsize;
+ uint32_t nshorts;
+ uint32_t nlongs;
+ uint32_t bytestomove;
};
int main(int argc, char **argv)
{
FILE *f, *g;
struct header header;
- unsigned int file_size;
+ long flen;
+ size_t file_size, reloc_size = 0;
char buf[256];
if (argc != 4) {
@@ -40,10 +56,64 @@ int main(int argc, char **argv)
return 1;
}
- fread((void*)&header, sizeof(struct header), 1, f);
+ if (fseek(f, 0, SEEK_END) < 0 || (flen = ftell(f)) < 0 ||
+ fseek(f, 0, SEEK_SET) < 0) {
+ fprintf(stderr, "Failed reading file size\n");
+ fclose(f);
+ return 1;
+ }
+ file_size = (size_t) flen;
+
+ if (file_size < sizeof(struct header) ||
+ fread(&header, sizeof(struct header), 1, f) != 1) {
+ fprintf(stderr, "Failed reading image header");
+ fclose(f);
+ return 1;
+ }
+
+ if ((header.decompress >> 24) == 0xEB) {
+ /* Image is compressed */
+ struct sqz_header sqzhdr;
+ uint8_t buf[1024], *lastb;
+ /* Compute offset of squeeze data (if any) */
+ size_t off = ((header.decompress & 0xFFFFFF) << 2) + 8 - (6*4);
+ /* Read in at most 1024 trailing bytes */
+ if (file_size - off > sizeof(buf)) {
+ fprintf(stderr, "Decompression buffer too small\n");
+ fclose(f);
+ return 1;
+ }
+ if (fseek(f, (long) off, SEEK_SET) < 0 ||
+ fread(buf, file_size - off, 1, f) != 1) {
+ fprintf(stderr, "Failed reading decompression code\n");
+ fclose(f);
+ return 1;
+ }
+ /* Look for squeeze signature (file size must be a multiple
+ * of 15 and must end "rcc X.YZ\n" padded out with spaces */
+ lastb = buf + (file_size - off);
+ while (lastb > buf && *(lastb-1) == ' ')
+ lastb--;
+ if ((file_size & 0xf) != 0xf || (lastb - 9 <= buf) ||
+ *(lastb-9) != 'r' || *(lastb-8) != 'c' ||
+ *(lastb-7) != 'c' || *(lastb-6) != ' ' ||
+ *(lastb-4) != '.' || *(lastb-1) != '\n') {
+ fprintf(stderr, "Unknown compression scheme\n");
+ fclose(f);
+ return 1;
+ }
+
+ /* We have been squeezed: sanity check compressed size */
+ memcpy(&sqzhdr, buf, sizeof(sqzhdr));
+ if (sizeof(header) + 4 + sqzhdr.encsize + sqzhdr.tabsize !=
+ off) {
+ fprintf(stderr, "Malformed squeeze data\n");
+ fclose(f);
+ return 1;
+ }
- fseek(f, 0, SEEK_END);
- file_size = ftell(f);
+ file_size = sizeof(header) + (size_t) sqzhdr.decsize;
+ }
fclose(f);
@@ -56,19 +126,38 @@ int main(int argc, char **argv)
return 1;
}
- if (header.rosize + header.rwsize + header.dbsize !=
- file_size) {
- if ((header.decompress >> 24) != 0xEB) {
- fprintf(stderr, "Mismatched field sizes\n");
+ if ((header.selfreloc >> 24) == 0xEB) {
+ /* Image is relocateable */
+ size_t off = 4 +
+ ((header.selfreloc & 0xFFFFFF) << 2) + 8;
+
+ if (off >= file_size) {
+ fprintf(stderr, "Relocation code missing\n");
return 1;
}
+
+ /* Deduct relocation code and tables from file size */
+ reloc_size = file_size - off;
+ file_size -= reloc_size;
+ /* Add relocation workspace on to reloc size */
+ reloc_size += header.wkspace;
}
- file_size = header.rosize + header.rwsize +
- header.dbsize + header.zisize +
+ if (header.rosize + header.rwsize + header.dbsize !=
+ file_size) {
+ fprintf(stderr, "Mismatched field sizes\n");
+ return 1;
+ }
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
+ file_size += max(header.zisize, reloc_size) +
0x8000 /* 32k of scratch space */;
+#undef max
}
+ /* Round slotsize up to the next 4k boundary */
+ file_size = (file_size + 0xfff) & ~0xfff;
+
f = fopen(argv[2], "r");
if (f == NULL) {
fprintf(stderr, "Failed opening %s\n", argv[2]);
@@ -84,7 +173,7 @@ int main(int argc, char **argv)
while (fgets(buf, sizeof(buf), f) != NULL) {
if (strncmp(buf, "WIMPSLOT\n", 9) == 0) {
- fprintf(g, "WimpSlot -min %dk -max %dk\n",
+ fprintf(g, "WimpSlot -min %zuk -max %zuk\n",
(file_size / 1024), (file_size / 1024));
} else {
fputs(buf, g);