Print this page
patch fixups

@@ -14,10 +14,11 @@
  */
 
 #include <stdio.h>
 #include <libdisasm.h>
 #include <sys/sysmacros.h>
+#include <sys/debug.h>
 #include <sys/byteorder.h>
 
 #include "libdisasm_impl.h"
 
 #define ILC2LEN(ilc)    (2 * ((ilc) >= 2 ? (ilc) : (ilc) + 1))

@@ -68,11 +69,11 @@
  * IF_TBL) or a multiple mnemonics tables (indicated with IF_MULTI).
  *
  * Extended opcode tables indicade which additional bits of the instruction
  * should be inspected.  These bits are used as an index into the sub table.
  *
- * Multiple mnemonic tables, are used to print different mnemonics depending
+ * Multiple mnemonic tables are used to print different mnemonics depending
  * on the architecture.  Over the years, certain instructions got a new
  * preferred mnemonic.  For example, 0xa70 is test-under-mask-high (tmh) on
  * System/390.  On z/Architecture systems, the instruction behaves
  * identically (and the assembler hapilly accepts tmh), but the preferred
  * mnemonic is tmlh (test-under-mask-low-high) because z/Architecture

@@ -93,10 +94,14 @@
  *    bc   7,0x123(%r1,%r2)
  *
  * we print:
  *
  *    bne  0x123(%r1,%r2)
+ *
+ * Note that we are using designated initializers via the INSTR/TABLE/MULTI
+ * macros and therefore the below tables can be sparse.  We rely on unset
+ * entries having zero format fields (aka. IF_INVAL) per C99.
  */
 
 /* BEGIN CSTYLED */
 enum ifmt {
         /* invalid */

@@ -179,24 +184,24 @@
 /* END CSTYLED */
 
 struct inst_table {
         union {
                 struct {
-                        const char *name;
-                        unsigned flags;
-                } inst;
-                struct {
-                        const struct inst_table *ptr;
-                        uint8_t off:4;
-                        uint8_t shift:4;
-                        uint8_t mask;
-                } table;
-                struct {
-                        const struct inst_table *ptr;
-                } multi;
-        } u;
-        enum ifmt fmt;
+                        const char *it_name;
+                        unsigned it_flags;
+                } it_inst;
+                struct {
+                        const struct inst_table *it_ptr;
+                        uint8_t it_off:4;
+                        uint8_t it_shift:4;
+                        uint8_t it_mask;
+                } it_table;
+                struct {
+                        const struct inst_table *it_ptr;
+                } it_multi;
+        } it_u;
+        enum ifmt it_fmt;
 };
 
 #define BITFLD(a, b)            DECL_BITFIELD2(b:4, a:4)
 
 union inst {

@@ -528,28 +533,28 @@
                 uint8_t d2l;
         } ssf;
 };
 
 #define INSTR(op, m, fm, fl)    [op] = { \
-                                        .u.inst = { \
-                                                .name = (m), \
-                                                .flags = (fl), \
+                                        .it_u.it_inst = { \
+                                                .it_name = (m), \
+                                                .it_flags = (fl), \
                                         }, \
-                                        .fmt = (fm), \
+                                        .it_fmt = (fm), \
                                 }
 #define TABLE(op, tbl, o, s, m) [op] = { \
-                                        .u.table = { \
-                                                .ptr = (tbl), \
-                                                .off = (o), \
-                                                .shift = (s), \
-                                                .mask = (m), \
+                                        .it_u.it_table = { \
+                                                .it_ptr = (tbl), \
+                                                .it_off = (o), \
+                                                .it_shift = (s), \
+                                                .it_mask = (m), \
                                         }, \
-                                        .fmt = IF_TBL, \
+                                        .it_fmt = IF_TBL, \
                                 }
 #define MULTI(op, tbl)          [op] = { \
-                                        .u.multi.ptr = (tbl), \
-                                        .fmt = IF_MULTI, \
+                                        .it_u.it_multi.it_ptr = (tbl), \
+                                        .it_fmt = IF_MULTI, \
                                 }
 
 /*
  * Instruction tables based on:
  *   GA22-7000-4   System/370 Principles of Operation

@@ -1788,16 +1793,21 @@
 #define X       R
 
 static inline uint32_t
 val_8_4_8(uint32_t hi, uint32_t mid, uint32_t lo)
 {
+        ASSERT0(hi & ~0xff);
+        ASSERT0(mid & ~0xf);
+        ASSERT0(lo & ~0xff);
         return ((hi << 12) | (mid << 8) | lo);
 }
 
 static inline uint32_t
 val_16_16(uint32_t hi, uint32_t lo)
 {
+        ASSERT0(hi & ~0xffff);
+        ASSERT0(lo & ~0xffff);
         return ((BE_16(hi) << 16) | BE_16(lo));
 }
 
 static inline int32_t
 sval_16_16(uint32_t hi, uint32_t lo)

@@ -1806,34 +1816,40 @@
 }
 
 static inline uint32_t
 val_8_16(uint32_t hi, uint32_t lo)
 {
+        ASSERT0(hi & ~0xff);
+        ASSERT0(lo & ~0xffff);
         return ((hi << 16) | BE_16(lo));
 }
 
 static inline int32_t
 sval_8_16(uint32_t hi, uint32_t lo)
 {
         int32_t tmp = val_8_16(hi, lo);
 
+        /* sign extend */
         if (tmp & 0x00800000)
                 return (0xff000000 | tmp);
         return (tmp);
 }
 
 static inline uint32_t
 val_4_8(uint32_t hi, uint32_t lo)
 {
+        ASSERT0(hi & ~0xf);
+        ASSERT0(lo & ~0xff);
         return ((hi << 8) | lo);
 }
 
 static inline int32_t
 sval_4_8(uint32_t hi, uint32_t lo)
 {
         uint32_t tmp = val_4_8(hi, lo);
 
+        /* sign extend */
         if (tmp & 0x800)
                 return (0xfffff000 | tmp);
         return (tmp);
 }
 

@@ -2466,34 +2482,34 @@
 dis_s390(uint64_t addr, union inst *inst, char *buf, size_t buflen, int mach)
 {
         const struct inst_table *tbl = &tbl_xx[inst->raw[0]];
         int tmp;
 
-        while (tbl->fmt == IF_TBL || tbl->fmt == IF_MULTI) {
-                if (tbl->fmt == IF_TBL) {
+        while (tbl->it_fmt == IF_TBL || tbl->it_fmt == IF_MULTI) {
+                if (tbl->it_fmt == IF_TBL) {
                         int idx;
 
-                        idx   = inst->raw[tbl->u.table.off];
-                        idx >>= tbl->u.table.shift;
-                        idx  &= tbl->u.table.mask;
-
-                        tbl = &tbl->u.table.ptr[idx];
-                } else if (tbl->fmt == IF_MULTI) {
-                        tbl = &tbl->u.multi.ptr[mach];
+                        idx   = inst->raw[tbl->it_u.it_table.it_off];
+                        idx >>= tbl->it_u.it_table.it_shift;
+                        idx  &= tbl->it_u.it_table.it_mask;
+
+                        tbl = &tbl->it_u.it_table.it_ptr[idx];
+                } else if (tbl->it_fmt == IF_MULTI) {
+                        tbl = &tbl->it_u.it_multi.it_ptr[mach];
                 }
         }
 
-        if (tbl->fmt == IF_INVAL)
+        if (tbl->it_fmt == IF_INVAL)
                 goto inval;
 
-        if ((tbl->u.inst.flags & mach) == 0)
+        if ((tbl->it_u.it_inst.it_flags & mach) == 0)
                 goto inval;
 
-        tmp = snprintf(buf, buflen, "%-7s ", tbl->u.inst.name);
+        tmp = snprintf(buf, buflen, "%-7s ", tbl->it_u.it_inst.it_name);
 
-        fmt_fxns[tbl->fmt](addr, inst, buf + tmp, buflen - tmp,
-            tbl->u.inst.flags);
+        fmt_fxns[tbl->it_fmt](addr, inst, buf + tmp, buflen - tmp,
+            tbl->it_u.it_inst.it_flags);
 
         return (0);
 
 inval:
         (void) snprintf(buf, buflen, "??");