diff --git a/libdrgn/dwarf_constants.c b/libdrgn/dwarf_constants.c index 170bb1fa0..85744b32c 100644 --- a/libdrgn/dwarf_constants.c +++ b/libdrgn/dwarf_constants.c @@ -8,6 +8,13 @@ #define X(name, _) if (value == name) return #name; +const char *dw_op_str(int value, char buf[static DW_OP_STR_BUF_LEN]) +{ + DW_OP_DEFINITIONS + snprintf(buf, DW_OP_STR_BUF_LEN, DW_OP_STR_UNKNOWN_FORMAT, value); + return buf; +} + const char *dw_tag_str(int value, char buf[static DW_TAG_STR_BUF_LEN]) { DW_TAG_DEFINITIONS diff --git a/libdrgn/dwarf_constants.h b/libdrgn/dwarf_constants.h index 83a0abed2..64011f182 100644 --- a/libdrgn/dwarf_constants.h +++ b/libdrgn/dwarf_constants.h @@ -963,6 +963,15 @@ enum { DW_MACRO_DEFINITIONS }; X(DW_OP_PGI_omp_thread_num, 0xf8) \ X(DW_OP_hi_user, 0xff) enum { DW_OP_DEFINITIONS }; +#define DW_OP_STR_UNKNOWN_FORMAT "DW_OP_<0x%x>" +#define DW_OP_STR_BUF_LEN (sizeof(DW_OP_STR_UNKNOWN_FORMAT) - 2 + 2 * sizeof(int)) +/** + * Get the name of a `DW_OP` value. + * + * @return Static string if the value is known or @p buf if the value is + * unknown. + */ +const char *dw_op_str(int value, char buf[static DW_OP_STR_BUF_LEN]); #define DW_ORD_DEFINITIONS \ X(DW_ORD_row_major, 0x0) \ diff --git a/libdrgn/dwarf_info.c b/libdrgn/dwarf_info.c index 0afbc43ae..56ab93b99 100644 --- a/libdrgn/dwarf_info.c +++ b/libdrgn/dwarf_info.c @@ -3774,9 +3774,14 @@ drgn_eval_dwarf_expression(struct drgn_dwarf_expression_context *ctx, * DW_OP_xderef_size, DW_OP_xderef_type. */ default: + { + char op_buf[DW_OP_STR_BUF_LEN]; return binary_buffer_error(&ctx->bb, - "unknown DWARF expression opcode %#" PRIx8, - opcode); + "unknown DWARF expression opcode %s; " + "please report this to %s", + dw_op_str(opcode, op_buf), + PACKAGE_BUGREPORT); + } } } diff --git a/scripts/gen_dwarf_constants.py b/scripts/gen_dwarf_constants.py index c63b036fc..2fcca21ad 100755 --- a/scripts/gen_dwarf_constants.py +++ b/scripts/gen_dwarf_constants.py @@ -121,7 +121,7 @@ def insert_after( return result -_DWARF_CONSTANTS_WANT_STR = {"DW_TAG"} +_DWARF_CONSTANTS_WANT_STR = {"DW_OP", "DW_TAG"} def gen_dwarf_constants_h(