/* bin-assemble.c * * Copyright (C) 2006-2021 wolfSSL Inc. * * This file is part of wolfBoot. * * wolfBoot is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * wolfBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *============================================================================= * * assemble binary parts based on address * */ #include #include #include #include #include #include #include #include #include #ifndef BLOCK_SZ #define BLOCK_SZ 1024 #endif #ifndef FILL_BYTE #define FILL_BYTE '\xff' #endif void usage(const char* execname) { fprintf(stderr, "%s output [
]\n" "assemble binary parts with addresses", execname); exit(1); } typedef struct { const char* fname; size_t address; size_t nbytes; } binentry_t; int binentry_address_compare(const void* a, const void* b) { const binentry_t* ba = (const binentry_t*)a; const binentry_t* bb = (const binentry_t*)b; if (ba->address < bb->address) { return -1; } else if (ba->address > bb->address) { return 1; } else { return 0; } } int main(int argc, const char* argv[]) { const char* outname = NULL; size_t i = 0; size_t num_entries = 0; binentry_t* entries = NULL; size_t cur_add = 0; char fill = FILL_BYTE; size_t nr = 0; size_t nw = 0; char data[BLOCK_SZ]; int err = 0; /* require at least 1 input file */ if (argc < 4 || (argc % 2) != 0) { usage(argv[0]); } outname = argv[1]; num_entries = (argc - 2) / 2; entries = malloc(sizeof(binentry_t) * num_entries); if (entries == NULL) { fprintf(stderr, "unable to allocate %zu entries\n;", num_entries); return EXIT_FAILURE; } for (i=0; i entries[i].address) { fprintf(stderr, "overlap with %s(end address 0x%zx) and %s (start address 0x%zx \n", entries[i-1].fname, endaddr, entries[i].fname, entries[i].address); err = 1; } if (err) { return err; } } // TODO: consider handling stdout "-" FILE* fo = fopen(outname, "wb"); if (fo == NULL) { fprintf(stderr, "opening %s failed %s\n", outname, strerror(errno)); return EXIT_FAILURE; } cur_add = entries[0].address; for (i=0; i 0 && fillSz < INT_MAX) { /* fill until address - blocks then bytes */ memset(data, fill, sizeof(data)); while (cur_add + sizeof(data) < entries[i].address) { nw = fwrite(data, 1, sizeof(data), fo); if (nw != sizeof(data)) { fprintf(stderr, "Failed to write %zu fill bytes at 0x%zu\n", sizeof(data), cur_add); return EXIT_FAILURE; } cur_add += sizeof(data); } while (cur_add < entries[i].address) { nw = fwrite(&fill, 1, 1, fo); if (nw != 1) { fprintf(stderr, "Failed to write fill bytes at 0x%zu\n", cur_add); return EXIT_FAILURE; } cur_add++; } fprintf(stderr, "\tAdded %12zu bytes of 0x%02x fill\n", fillSz, (unsigned char)fill); } while (!feof(fi)) { nr = fread(data, 1, BLOCK_SZ, fi); nw = fwrite(data, 1, nr, fo); cur_add += nw; if (nr != nw) { fprintf(stderr, "Failed to wrote %zu bytes of the %zu bytes read from %s\n", nw, nr, entries[i].fname); return EXIT_FAILURE; } if (ferror(fi)) { fprintf(stderr, "error reading from %s\n", entries[i].fname); return EXIT_FAILURE; } if (ferror(fo)) { fprintf(stderr, "error writing to %s\n", entries[i].fname); return EXIT_FAILURE; } } fprintf(stderr, "\tAdded %12zu bytes at 0x%08zx from %s\n", cur_add - entries[i].address, entries[i].address, entries[i].fname); fclose(fi); } fclose(fo); return 0; }