diff options
| author | Rafał Miłecki | 2021-11-27 15:31:03 +0000 |
|---|---|---|
| committer | Rafał Miłecki | 2021-12-02 07:33:30 +0000 |
| commit | a37ccaff50e50cf3553d4bc7852a3e389e85535d (patch) | |
| tree | 89c0138784c1b769410ad91455198eae719c3d73 | |
| parent | 1fa145e7042508bd561daf52e7c749266e5b2a03 (diff) | |
| download | firmware-utils-a37ccaff50e50cf3553d4bc7852a3e389e85535d.tar.gz | |
otrx: support unsorted partitions offsets
TRX format doesn't guarantee that it contains partitions offsets in a
sorted order. Store partitions info in context struct and make sure it's
sorted.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
| -rw-r--r-- | src/otrx.c | 54 |
1 files changed, 42 insertions, 12 deletions
@@ -42,9 +42,16 @@ struct trx_header { uint32_t offset[3]; }; +struct otrx_part { + int idx; + size_t offset; + size_t length; +}; + struct otrx_ctx { FILE *fp; struct trx_header hdr; + struct otrx_part parts[TRX_MAX_PARTS]; /* Sorted partitions */ }; char *trx_path; @@ -174,12 +181,26 @@ static void otrx_close(FILE *fp) { fclose(fp); } +static int otrx_part_compar(const void *a, const void *b) +{ + const struct otrx_part *partA = a; + const struct otrx_part *partB = b; + + if (!partA->offset) + return 1; + if (!partB->offset) + return -1; + + return partA->offset - partB->offset; +} + static int otrx_open_parse(const char *pathname, const char *mode, struct otrx_ctx *otrx) { size_t length; size_t bytes; int err; + int i; otrx->fp = otrx_open(pathname, mode); if (!otrx->fp) { @@ -214,6 +235,22 @@ static int otrx_open_parse(const char *pathname, const char *mode, goto err_close; } + for (i = 0; i < TRX_MAX_PARTS; i++) { + otrx->parts[i].idx = i; + otrx->parts[i].offset = le32_to_cpu(otrx->hdr.offset[i]); + } + qsort(otrx->parts, TRX_MAX_PARTS, sizeof(otrx->parts[0]), otrx_part_compar); + + /* Calculate length of every partition */ + for (i = 0; i < TRX_MAX_PARTS; i++) { + if (otrx->parts[i].offset) { + if (i + 1 >= TRX_MAX_PARTS || !otrx->parts[i + 1].offset) + otrx->parts[i].length = le32_to_cpu(otrx->hdr.length) - otrx->parts[i].offset; + else + otrx->parts[i].length = otrx->parts[i + 1].offset - otrx->parts[i].offset; + } + } + return 0; err_close: @@ -589,21 +626,14 @@ static int otrx_extract(int argc, char **argv) { } for (i = 0; i < TRX_MAX_PARTS; i++) { - size_t length; + struct otrx_part *part = &otrx.parts[i]; - if (!partition[i]) - continue; - if (!otrx.hdr.offset[i]) { - printf("TRX doesn't contain partition %d, can't extract %s\n", i + 1, partition[i]); + if (!part->offset && partition[part->idx]) + printf("TRX doesn't contain partition %d, can't extract %s\n", part->idx + 1, partition[part->idx]); + if (!part->offset || !partition[part->idx]) continue; - } - - if (i + 1 >= TRX_MAX_PARTS || !otrx.hdr.offset[i + 1]) - length = le32_to_cpu(otrx.hdr.length) - le32_to_cpu(otrx.hdr.offset[i]); else - length = le32_to_cpu(otrx.hdr.offset[i + 1]) - le32_to_cpu(otrx.hdr.offset[i]); - - otrx_extract_copy(otrx.fp, trx_offset + le32_to_cpu(otrx.hdr.offset[i]), length, partition[i]); + otrx_extract_copy(otrx.fp, trx_offset + part->offset, part->length, partition[part->idx]); } otrx_close(otrx.fp); |