diff --git a/fadec.h b/fadec.h index 6459419..2b1f293 100644 --- a/fadec.h +++ b/fadec.h @@ -135,8 +135,17 @@ int fd_decode(const uint8_t* buf, size_t len, int mode, uintptr_t address, **/ void fd_format(const FdInstr* instr, char* buf, size_t len); +/** Get the stringified name of an instruction type. + * \param ty An instruction type + * \return The instruction type as string, or "(invalid)". + **/ +const char* fdi_name(FdInstrType ty); -/** Gets the type/mnemonic of the instruction. **/ + +/** Gets the type/mnemonic of the instruction. + * ABI STABILITY NOTE: different versions or builds of the library may use + * different values. When linking as shared library, any interpretation of this + * value is meaningless; in such cases use fdi_name. **/ #define FD_TYPE(instr) ((FdInstrType) (instr)->type) /** DEPRECATED: This functionality is obsolete in favor of FD_OT_OFF. * Gets the address of the instruction. Invalid if decoded address == 0. **/ diff --git a/format.c b/format.c index 9e77da0..8ec8a80 100644 --- a/format.c +++ b/format.c @@ -19,6 +19,13 @@ static const uint16_t _mnemonic_offs[] = { }; #undef FD_DECODE_TABLE_STRTAB2 +const char* +fdi_name(FdInstrType ty) { + if (ty >= sizeof(_mnemonic_offs) / sizeof(_mnemonic_offs[0])) + return "(invalid)"; + return &_mnemonic_str[_mnemonic_offs[ty]]; +} + #define FMT_CONCAT(buf, end, ...) do { \ buf += snprintf(buf, end - buf, __VA_ARGS__); \ if (buf > end) \ @@ -45,7 +52,7 @@ fd_format(const FdInstr* instr, char* buffer, size_t len) if (FD_HAS_LOCK(instr)) FMT_CONCAT(buf, end, "lock:"); - FMT_CONCAT(buf, end, "%s", &_mnemonic_str[_mnemonic_offs[FD_TYPE(instr)]]); + FMT_CONCAT(buf, end, "%s", fdi_name(FD_TYPE(instr))); if (FD_OPSIZE(instr)) FMT_CONCAT(buf, end, "_%u", FD_OPSIZE(instr));