mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
librz/bin: autodetect legacy TMS320C1x/C2x/C5x COFF objects
The legacy TMS320 fixed-point families ship as 16-bit big-endian COFF objects whose magic and machine identifiers were not recognised by the COFF loader. Teach the COFF format backend and the bin plugin to detect and load them so the new tms320 c2x/c5x analysis can operate on real object files.
This commit is contained in:
parent
fee84c7f5c
commit
68471f8736
3 changed files with 34 additions and 0 deletions
|
|
@ -91,6 +91,11 @@ static bool coff_is_magic(ut16 arch) {
|
||||||
/* fall-thru */
|
/* fall-thru */
|
||||||
case COFF_FILE_MACHINE_TI_2:
|
case COFF_FILE_MACHINE_TI_2:
|
||||||
/* fall-thru */
|
/* fall-thru */
|
||||||
|
case COFF_FILE_TARGET_TI_TMS320C1x2x5x:
|
||||||
|
/* first-generation TI fixed-point COFF (C1x/C2x/C5x): the target id
|
||||||
|
* doubles as the file magic, unlike the later COFF1/COFF2 (0xc1/0xc2)
|
||||||
|
* which carry a separate target id field. */
|
||||||
|
/* fall-thru */
|
||||||
case COFF_FILE_MACHINE_MIL1750:
|
case COFF_FILE_MACHINE_MIL1750:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
|
|
@ -138,6 +143,7 @@ RZ_API bool rz_coff_supported_arch(RzBuffer *b) {
|
||||||
RZ_API ut32 rz_coff_addr_scale(RZ_NONNULL struct rz_bin_coff_obj *obj) {
|
RZ_API ut32 rz_coff_addr_scale(RZ_NONNULL struct rz_bin_coff_obj *obj) {
|
||||||
rz_return_val_if_fail(obj, 1);
|
rz_return_val_if_fail(obj, 1);
|
||||||
switch (obj->target_id) {
|
switch (obj->target_id) {
|
||||||
|
case COFF_FILE_TARGET_TI_TMS320C1x2x5x:
|
||||||
case COFF_FILE_TARGET_TI_TMS320C5400:
|
case COFF_FILE_TARGET_TI_TMS320C5400:
|
||||||
case COFF_FILE_TARGET_TI_TMS320C2800:
|
case COFF_FILE_TARGET_TI_TMS320C2800:
|
||||||
return 2;
|
return 2;
|
||||||
|
|
@ -258,6 +264,9 @@ static bool bin_coff_init_hdr(RzBuffer *b, struct rz_bin_coff_obj *obj, ut64 *of
|
||||||
return false;
|
return false;
|
||||||
} else if (coff_is_ti_machine(obj)) {
|
} else if (coff_is_ti_machine(obj)) {
|
||||||
return rz_buf_read_ble16_offset(b, offset, &obj->target_id, obj->big_endian);
|
return rz_buf_read_ble16_offset(b, offset, &obj->target_id, obj->big_endian);
|
||||||
|
} else if (obj->hdr.f_magic == COFF_FILE_TARGET_TI_TMS320C1x2x5x) {
|
||||||
|
// Original TI COFF has no separate field: the magic is the target id.
|
||||||
|
obj->target_id = obj->hdr.f_magic;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
#define COFF_FILE_MACHINE_TI_2 0x00c2
|
#define COFF_FILE_MACHINE_TI_2 0x00c2
|
||||||
#define COFF_FILE_MACHINE_MIL1750 0x00db
|
#define COFF_FILE_MACHINE_MIL1750 0x00db
|
||||||
|
|
||||||
|
#define COFF_FILE_TARGET_TI_TMS320C1x2x5x 0x0092
|
||||||
#define COFF_FILE_TARGET_TI_TMS320C3x4x 0x0093
|
#define COFF_FILE_TARGET_TI_TMS320C3x4x 0x0093
|
||||||
#define COFF_FILE_TARGET_TI_TMS470 0x0097
|
#define COFF_FILE_TARGET_TI_TMS470 0x0097
|
||||||
#define COFF_FILE_TARGET_TI_TMS320C5400 0x0098
|
#define COFF_FILE_TARGET_TI_TMS320C5400 0x0098
|
||||||
|
|
|
||||||
|
|
@ -648,10 +648,34 @@ static RzBinInfo *coff_info(RzBinFile *bf) {
|
||||||
ret->cpu = rz_str_dup("r10000");
|
ret->cpu = rz_str_dup("r10000");
|
||||||
ret->bits = 32;
|
ret->bits = 32;
|
||||||
break;
|
break;
|
||||||
|
case COFF_FILE_TARGET_TI_TMS320C1x2x5x:
|
||||||
|
// Original TI COFF (version 0) carried the target id directly in the
|
||||||
|
// file header's f_magic, so a target-id constant is matched here on the
|
||||||
|
// same field that holds COFF_FILE_MACHINE_TI_1/_2 for newer files.
|
||||||
|
// COFF1/COFF2 moved the id into the separate target_id field, handled
|
||||||
|
// by the COFF_FILE_MACHINE_TI_1/_2 case below.
|
||||||
|
// The id is shared by the C1x/C2x/C5x assemblers, so default to the C2x
|
||||||
|
// disassembler (override with -c c5x for a C5x image).
|
||||||
|
ret->machine = rz_str_dup("TMS320C1x/C2x/C5x");
|
||||||
|
ret->cpu = rz_str_dup("c2x");
|
||||||
|
ret->arch = rz_str_dup("tms320");
|
||||||
|
ret->bits = 16;
|
||||||
|
break;
|
||||||
case COFF_FILE_MACHINE_TI_1:
|
case COFF_FILE_MACHINE_TI_1:
|
||||||
/* fall-thru */
|
/* fall-thru */
|
||||||
case COFF_FILE_MACHINE_TI_2:
|
case COFF_FILE_MACHINE_TI_2:
|
||||||
switch (obj->target_id) {
|
switch (obj->target_id) {
|
||||||
|
case COFF_FILE_TARGET_TI_TMS320C1x2x5x:
|
||||||
|
// First-generation TI fixed-point COFF id, shared by the TMS320C1x/
|
||||||
|
// C2x/C5x assemblers. Map it to the legacy single-accumulator C2x
|
||||||
|
// disassembler by default; override with -c for a C5x image. (The
|
||||||
|
// id is rarely present on raw firmware dumps; verify on real object
|
||||||
|
// files before relying on autodetection.)
|
||||||
|
ret->machine = rz_str_dup("TMS320C1x/C2x/C5x");
|
||||||
|
ret->cpu = rz_str_dup("c2x");
|
||||||
|
ret->arch = rz_str_dup("tms320");
|
||||||
|
ret->bits = 16;
|
||||||
|
break;
|
||||||
case COFF_FILE_TARGET_TI_TMS320C3x4x:
|
case COFF_FILE_TARGET_TI_TMS320C3x4x:
|
||||||
ret->machine = rz_str_dup("TMS320C3x/4x");
|
ret->machine = rz_str_dup("TMS320C3x/4x");
|
||||||
/* TMS320C3x/C4x is a floating-point DSP family that
|
/* TMS320C3x/C4x is a floating-point DSP family that
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue