diff options
author | Thomas <doodrabbit@hotmail.com> | 2021-12-17 20:57:03 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-17 20:57:03 -0500 |
commit | af67eaffa7ab1a347a6f0e59ed7f1e107749d15a (patch) | |
tree | b9f90f7b047b3dc5a411dbf65117bf07b237a37d /tools/asmdiff/ntruncompbw.c | |
parent | 3ab18655ca1311019212b3a2a9dbe32e5fbee55d (diff) | |
parent | 44cd7753b5dde323d1e8274b2dc8a5599729e83f (diff) |
Real-match math_util.c
Diffstat (limited to 'tools/asmdiff/ntruncompbw.c')
-rw-r--r-- | tools/asmdiff/ntruncompbw.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/tools/asmdiff/ntruncompbw.c b/tools/asmdiff/ntruncompbw.c new file mode 100644 index 00000000..e97db925 --- /dev/null +++ b/tools/asmdiff/ntruncompbw.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +static inline uint32_t READ32(const unsigned char * ptr) +{ + return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); +} + +static uint32_t MIi_UncompressBackwards(unsigned char ** out_p, size_t compsize) +{ + unsigned char * out = *out_p; + + // Read the pointer to the end of the compressed image + uint8_t * endptr = out + compsize - 8; + uint32_t size = READ32(endptr); + uint32_t offset = READ32(endptr + 4); + out = realloc(out, compsize + offset); + if (out == NULL) + return -1u; + endptr = out + compsize; + uint8_t * dest_p = endptr + offset; + uint8_t * end = endptr - ((uint8_t)(size >> 24)); + uint8_t * start = endptr - (size & ~0xFF000000); + while (end > start) { + uint8_t r5 = *--end; + for (int i = 0; i < 8; i++) { + if ((r5 & 0x80) == 0) + *--dest_p = *--end; + else { + int ip = *--end; + int r7 = *--end; + + + r7 = ((r7 | (ip << 8)) & ~0xF000) + 2; + ip += 0x20; + while (ip >= 0) { + dest_p[-1] = dest_p[r7]; + dest_p--; + ip -= 0x10; + } + } + if (end <= start) + break; + r5 <<= 1; + } + } + *out_p = out; + return compsize + offset; +} + +int main(int argc, char ** argv) +{ + if (argc < 4) { + fprintf(stderr, "usage: %s FILE VMA END\n\ninsufficient arguments\n", argv[0]); + return 1; + } + char * infname = argv[1]; + uint32_t vma = strtoul(argv[2], NULL, 0); + uint32_t end = strtoul(argv[3], NULL, 0); + if (end == 0) { + fprintf(stderr, "compressed size is 0, no action taken\n"); + return 0; + } + FILE * infile = fopen(infname, "r+b"); + if (infile == NULL) { + fclose(infile); + fprintf(stderr, "unable to open file %s for reading\n", infname); + return 1; + } + fseek(infile, 0, SEEK_END); + long infsize = ftell(infile); + fseek(infile, 0, SEEK_SET); + if (infsize != end - vma) { + fclose(infile); + fprintf(stderr, "compressed size does not match file size, I am cowardly doing nothing\n"); + return 0; + } + unsigned char * inbuf = malloc(infsize); + if (inbuf == NULL) { + fclose(infile); + fprintf(stderr, "error: malloc(%d)\n", (int)infsize); + return 1; + } + if (fread(inbuf, 1, infsize, infile) != infsize) { + fclose(infile); + free(inbuf); + fprintf(stderr, "error reading from %s\n", infname); + return 1; + } + uint32_t outsize = MIi_UncompressBackwards(&inbuf, end - vma); + if (outsize == -1u) { + fclose(infile); + fprintf(stderr, "fatal error reallocating for decompression\n"); + return 1; + } + fseek(infile, 0, SEEK_SET); + if (fwrite(inbuf, 1, outsize, infile) != outsize) { + fclose(infile); + free(inbuf); + fprintf(stderr, "error writing back to %s\n", infname); + return 1; + } + fclose(infile); + free(inbuf); + return 0; +} |