}
        switch (entry->type) {
        case TRACE_FN: {
-               struct ftrace_entry *field = (struct ftrace_entry *)entry;
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
 
                seq_print_ip_sym(s, field->ip, sym_flags);
                trace_seq_puts(s, " (");
        }
        case TRACE_CTX:
        case TRACE_WAKE: {
-               struct ctx_switch_entry *field =
-                       (struct ctx_switch_entry *)entry;
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
 
                T = field->next_state < sizeof(state_to_char) ?
                        state_to_char[field->next_state] : 'X';
                break;
        }
        case TRACE_SPECIAL: {
-               struct special_entry *field = (struct special_entry *)entry;
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
 
                trace_seq_printf(s, "# %ld %ld %ld\n",
                                 field->arg1,
                break;
        }
        case TRACE_STACK: {
-               struct stack_entry *field = (struct stack_entry *)entry;
+               struct stack_entry *field;
+
+               trace_assign_type(field, entry);
 
                for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
                        if (i)
                break;
        }
        case TRACE_PRINT: {
-               struct print_entry *field = (struct print_entry *)entry;
+               struct print_entry *field;
+
+               trace_assign_type(field, entry);
 
                seq_print_ip_sym(s, field->ip, sym_flags);
                trace_seq_printf(s, ": %s", field->buf);
 
        switch (entry->type) {
        case TRACE_FN: {
-               struct ftrace_entry *field = (struct ftrace_entry *)entry;
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
 
                ret = seq_print_ip_sym(s, field->ip, sym_flags);
                if (!ret)
        }
        case TRACE_CTX:
        case TRACE_WAKE: {
-               struct ctx_switch_entry *field =
-                       (struct ctx_switch_entry *)entry;
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
 
                S = field->prev_state < sizeof(state_to_char) ?
                        state_to_char[field->prev_state] : 'X';
                break;
        }
        case TRACE_SPECIAL: {
-               struct special_entry *field = (struct special_entry *)entry;
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
 
                ret = trace_seq_printf(s, "# %ld %ld %ld\n",
                                 field->arg1,
                break;
        }
        case TRACE_STACK: {
-               struct stack_entry *field = (struct stack_entry *)entry;
+               struct stack_entry *field;
+
+               trace_assign_type(field, entry);
 
                for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
                        if (i) {
                break;
        }
        case TRACE_PRINT: {
-               struct print_entry *field = (struct print_entry *)entry;
+               struct print_entry *field;
+
+               trace_assign_type(field, entry);
 
                seq_print_ip_sym(s, field->ip, sym_flags);
                trace_seq_printf(s, ": %s", field->buf);
 
        switch (entry->type) {
        case TRACE_FN: {
-               struct ftrace_entry *field = (struct ftrace_entry *)entry;
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
 
                ret = trace_seq_printf(s, "%x %x\n",
                                        field->ip,
        }
        case TRACE_CTX:
        case TRACE_WAKE: {
-               struct ctx_switch_entry *field =
-                       (struct ctx_switch_entry *)entry;
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
 
                S = field->prev_state < sizeof(state_to_char) ?
                        state_to_char[field->prev_state] : 'X';
        }
        case TRACE_SPECIAL:
        case TRACE_STACK: {
-               struct special_entry *field = (struct special_entry *)entry;
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
 
                ret = trace_seq_printf(s, "# %ld %ld %ld\n",
                                 field->arg1,
                break;
        }
        case TRACE_PRINT: {
-               struct print_entry *field = (struct print_entry *)entry;
+               struct print_entry *field;
+
+               trace_assign_type(field, entry);
 
                trace_seq_printf(s, "# %lx %s", field->ip, field->buf);
                if (entry->flags & TRACE_FLAG_CONT)
 
        switch (entry->type) {
        case TRACE_FN: {
-               struct ftrace_entry *field = (struct ftrace_entry *)entry;
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
 
                SEQ_PUT_HEX_FIELD_RET(s, field->ip);
                SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
        }
        case TRACE_CTX:
        case TRACE_WAKE: {
-               struct ctx_switch_entry *field =
-                       (struct ctx_switch_entry *)entry;
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
 
                S = field->prev_state < sizeof(state_to_char) ?
                        state_to_char[field->prev_state] : 'X';
        }
        case TRACE_SPECIAL:
        case TRACE_STACK: {
-               struct special_entry *field = (struct special_entry *)entry;
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
 
                SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
                SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
 
        switch (entry->type) {
        case TRACE_FN: {
-               struct ftrace_entry *field = (struct ftrace_entry *)entry;
+               struct ftrace_entry *field;
+
+               trace_assign_type(field, entry);
 
                SEQ_PUT_FIELD_RET(s, field->ip);
                SEQ_PUT_FIELD_RET(s, field->parent_ip);
                break;
        }
        case TRACE_CTX: {
-               struct ctx_switch_entry *field =
-                       (struct ctx_switch_entry *)entry;
+               struct ctx_switch_entry *field;
+
+               trace_assign_type(field, entry);
 
                SEQ_PUT_FIELD_RET(s, field->prev_pid);
                SEQ_PUT_FIELD_RET(s, field->prev_prio);
        }
        case TRACE_SPECIAL:
        case TRACE_STACK: {
-               struct special_entry *field = (struct special_entry *)entry;
+               struct special_entry *field;
+
+               trace_assign_type(field, entry);
 
                SEQ_PUT_FIELD_RET(s, field->arg1);
                SEQ_PUT_FIELD_RET(s, field->arg2);
 
        struct trace_array_cpu  *data[NR_CPUS];
 };
 
+#define FTRACE_CMP_TYPE(var, type) \
+       __builtin_types_compatible_p(typeof(var), type *)
+
+#undef IF_ASSIGN
+#define IF_ASSIGN(var, entry, etype, id)               \
+       if (FTRACE_CMP_TYPE(var, etype)) {              \
+               var = (typeof(var))(entry);             \
+               WARN_ON(id && (entry)->type != id);     \
+               break;                                  \
+       }
+
+/* Will cause compile errors if type is not found. */
+extern void __ftrace_bad_type(void);
+
+/*
+ * The trace_assign_type is a verifier that the entry type is
+ * the same as the type being assigned. To add new types simply
+ * add a line with the following format:
+ *
+ * IF_ASSIGN(var, ent, type, id);
+ *
+ *  Where "type" is the trace type that includes the trace_entry
+ *  as the "ent" item. And "id" is the trace identifier that is
+ *  used in the trace_type enum.
+ *
+ *  If the type can have more than one id, then use zero.
+ */
+#define trace_assign_type(var, ent)                                    \
+       do {                                                            \
+               IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN);     \
+               IF_ASSIGN(var, ent, struct ctx_switch_entry, 0);        \
+               IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \
+               IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK);   \
+               IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);   \
+               IF_ASSIGN(var, ent, struct special_entry, 0);           \
+               IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,          \
+                         TRACE_MMIO_RW);                               \
+               IF_ASSIGN(var, ent, struct trace_mmiotrace_map,         \
+                         TRACE_MMIO_MAP);                              \
+               IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT);     \
+               __ftrace_bad_type();                                    \
+       } while (0)
 
 /* Return values for print_line callback */
 enum print_line_t {
 
 static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
 {
        struct trace_entry *entry = iter->ent;
-       struct trace_mmiotrace_rw *field =
-               (struct trace_mmiotrace_rw *)entry;
-       struct mmiotrace_rw *rw = &field->rw;
+       struct trace_mmiotrace_rw *field;
+       struct mmiotrace_rw *rw;
        struct trace_seq *s     = &iter->seq;
        unsigned long long t    = ns2usecs(iter->ts);
        unsigned long usec_rem  = do_div(t, 1000000ULL);
        unsigned secs           = (unsigned long)t;
        int ret = 1;
 
+       trace_assign_type(field, entry);
+       rw = &field->rw;
+
        switch (rw->opcode) {
        case MMIO_READ:
                ret = trace_seq_printf(s,
 static enum print_line_t mmio_print_map(struct trace_iterator *iter)
 {
        struct trace_entry *entry = iter->ent;
-       struct mmiotrace_map *m = (struct mmiotrace_map *)entry;
+       struct trace_mmiotrace_map *field;
+       struct mmiotrace_map *m;
        struct trace_seq *s     = &iter->seq;
        unsigned long long t    = ns2usecs(iter->ts);
        unsigned long usec_rem  = do_div(t, 1000000ULL);
        unsigned secs           = (unsigned long)t;
        int ret;
 
+       trace_assign_type(field, entry);
+       m = &field->map;
+
        switch (m->opcode) {
        case MMIO_PROBE:
                ret = trace_seq_printf(s,