libopid: refactor disassembly API
authorDmitry Selyutin <ghostmansd@gmail.com>
Mon, 11 Sep 2023 18:56:15 +0000 (21:56 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Wed, 13 Sep 2023 17:26:19 +0000 (20:26 +0300)
src/libopid/opid-check.c
src/libopid/opid-dis.c
src/libopid/opid.h

index fe51ca11e9ec1d92f2895e025e4a4b7498188728..6640bde4bc3ef26e5aa4bdd869999f786bdc162d 100644 (file)
@@ -34,7 +34,7 @@ main(void) {
                 return EXIT_FAILURE;
             }
 
-            printf("%s [", ctx.record->name);
+            printf("%s [", ctx.name);
             opid_foreach_operand(&ctx, operand) {
                 printf("(%" PRIi32 " ",
                     (int32_t)operand->value);
index 945dcd0d4f7bb01888a4043b7cae841a8a3b1515..37eae8755f4919f718e5407778c316d8c3644a53 100644 (file)
@@ -11,18 +11,22 @@ opid_disassemble_operand(uint64_t insn,
 #include "opid-dis-gen.c"
 
 static inline enum opid_state
-opid_disassemble_operands(struct opid_ctx *ctx, uint64_t insn) {
-    for (size_t id = 0; ((id != OPID_OPERANDS) && ctx->record->operands[id]); ++id) {
+opid_disassemble_operands(struct opid_ctx *ctx,
+        struct opid_record const *record,
+        uint64_t insn) {
+    for (size_t id = 0; ((id != OPID_OPERANDS) && record->operands[id]); ++id) {
         enum opid_state state;
 
         state = opid_disassemble_operand(insn,
-            ctx->record->operands[id],
+            record->operands[id],
             &ctx->operands[id]);
         if (state != OPID_SUCCESS) {
             if (state == OPID_ERROR_OPERAND_0)
                 state = (enum opid_state)((size_t)state + id);
             return state;
         }
+
+        ctx->nr_operands = (id + 1);
     }
 
     return OPID_SUCCESS;
@@ -30,10 +34,18 @@ opid_disassemble_operands(struct opid_ctx *ctx, uint64_t insn) {
 
 enum opid_state
 opid_disassemble(struct opid_ctx *ctx, uint64_t insn) {
-    ctx->record = opid_lookup_insn(insn);
-
-    if (ctx->record == NULL)
+    enum opid_state state;
+    struct opid_record const *record;
+    
+    record = opid_lookup_insn(insn);
+    if (record == NULL)
         return OPID_ERROR_LOOKUP;
 
-    return opid_disassemble_operands(ctx, insn);
+    state = opid_disassemble_operands(ctx, record, insn);
+    if (state != OPID_SUCCESS)
+        return state;
+
+    ctx->name = record->name;
+
+    return OPID_SUCCESS;
 }
index ff32fb2f25aa3ba19de5dc72c887de49f50304c5..a6a94597dbb62aa9d6a76fad40691772be48ff02 100644 (file)
@@ -44,14 +44,15 @@ struct opid_operand {
 #define OPID_OPERAND_ADDRESS   (UINT64_C(1) << UINT64_C(7))
 
 struct opid_ctx {
-    struct opid_record const *record;
+    char const *name;
+    size_t nr_operands;
     struct opid_operand operands[OPID_OPERANDS];
 };
 
 #define opid_foreach_operand(ctx, operand) \
     for (size_t id = 0; \
         (((operand = &(ctx)->operands[id]), 1) && \
-            ((id != OPID_OPERANDS) && (ctx)->record->operands[id])); \
+            ((id != OPID_OPERANDS) && (id != (ctx)->nr_operands))); \
         operand = &(ctx)->operands[++id])
 
 enum opid_state