type & PTR_TRUSTED ? "trusted_" : ""
        );
 
-       snprintf(env->type_str_buf, TYPE_STR_BUF_LEN, "%s%s%s",
+       snprintf(env->tmp_str_buf, TMP_STR_BUF_LEN, "%s%s%s",
                 prefix, str[base_type(type)], postfix);
-       return env->type_str_buf;
+       return env->tmp_str_buf;
 }
 
 static char slot_type_char[] = {
        return bt->stack_masks[bt->frame] & (1ull << slot);
 }
 
+/* format registers bitmask, e.g., "r0,r2,r4" for 0x15 mask */
+static void fmt_reg_mask(char *buf, ssize_t buf_sz, u32 reg_mask)
+{
+       DECLARE_BITMAP(mask, 64);
+       bool first = true;
+       int i, n;
+
+       buf[0] = '\0';
+
+       bitmap_from_u64(mask, reg_mask);
+       for_each_set_bit(i, mask, 32) {
+               n = snprintf(buf, buf_sz, "%sr%d", first ? "" : ",", i);
+               first = false;
+               buf += n;
+               buf_sz -= n;
+               if (buf_sz < 0)
+                       break;
+       }
+}
+/* format stack slots bitmask, e.g., "-8,-24,-40" for 0x15 mask */
+static void fmt_stack_mask(char *buf, ssize_t buf_sz, u64 stack_mask)
+{
+       DECLARE_BITMAP(mask, 64);
+       bool first = true;
+       int i, n;
+
+       buf[0] = '\0';
+
+       bitmap_from_u64(mask, stack_mask);
+       for_each_set_bit(i, mask, 64) {
+               n = snprintf(buf, buf_sz, "%s%d", first ? "" : ",", -(i + 1) * 8);
+               first = false;
+               buf += n;
+               buf_sz -= n;
+               if (buf_sz < 0)
+                       break;
+       }
+}
+
 /* For given verifier state backtrack_insn() is called from the last insn to
  * the first insn. Its purpose is to compute a bitmask of registers and
  * stack slots that needs precision in the parent verifier state.
        if (insn->code == 0)
                return 0;
        if (env->log.level & BPF_LOG_LEVEL2) {
-               verbose(env, "regs=%x stack=%llx before ", bt_reg_mask(bt), bt_stack_mask(bt));
+               fmt_reg_mask(env->tmp_str_buf, TMP_STR_BUF_LEN, bt_reg_mask(bt));
+               verbose(env, "mark_precise: frame%d: regs=%s ",
+                       bt->frame, env->tmp_str_buf);
+               fmt_stack_mask(env->tmp_str_buf, TMP_STR_BUF_LEN, bt_stack_mask(bt));
+               verbose(env, "stack=%s before ", env->tmp_str_buf);
                verbose(env, "%d: ", idx);
                print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
        }
        struct bpf_reg_state *reg;
        int i, j;
 
+       if (env->log.level & BPF_LOG_LEVEL2) {
+               verbose(env, "mark_precise: frame%d: falling back to forcing all scalars precise\n",
+                       st->curframe);
+       }
+
        /* big hammer: mark all scalars precise in this path.
         * pop_stack may still get !precise scalars.
         * We also skip current state and go straight to first parent state,
                        func = st->frame[i];
                        for (j = 0; j < BPF_REG_FP; j++) {
                                reg = &func->regs[j];
-                               if (reg->type != SCALAR_VALUE)
+                               if (reg->type != SCALAR_VALUE || reg->precise)
                                        continue;
                                reg->precise = true;
+                               if (env->log.level & BPF_LOG_LEVEL2) {
+                                       verbose(env, "force_precise: frame%d: forcing r%d to be precise\n",
+                                               i, j);
+                               }
                        }
                        for (j = 0; j < func->allocated_stack / BPF_REG_SIZE; j++) {
                                if (!is_spilled_reg(&func->stack[j]))
                                        continue;
                                reg = &func->stack[j].spilled_ptr;
-                               if (reg->type != SCALAR_VALUE)
+                               if (reg->type != SCALAR_VALUE || reg->precise)
                                        continue;
                                reg->precise = true;
+                               if (env->log.level & BPF_LOG_LEVEL2) {
+                                       verbose(env, "force_precise: frame%d: forcing fp%d to be precise\n",
+                                               i, -(j + 1) * 8);
+                               }
                        }
                }
        }
                DECLARE_BITMAP(mask, 64);
                u32 history = st->jmp_history_cnt;
 
-               if (env->log.level & BPF_LOG_LEVEL2)
-                       verbose(env, "last_idx %d first_idx %d\n", last_idx, first_idx);
+               if (env->log.level & BPF_LOG_LEVEL2) {
+                       verbose(env, "mark_precise: frame%d: last_idx %d first_idx %d\n",
+                               bt->frame, last_idx, first_idx);
+               }
 
                if (last_idx < 0) {
                        /* we are at the entry into subprog, which
 
        .fixup_map_array_48b = { 1 },
        .result = VERBOSE_ACCEPT,
        .errstr =
-       "26: (85) call bpf_probe_read_kernel#113\
-       last_idx 26 first_idx 20\
-       regs=4 stack=0 before 25\
-       regs=4 stack=0 before 24\
-       regs=4 stack=0 before 23\
-       regs=4 stack=0 before 22\
-       regs=4 stack=0 before 20\
-       parent didn't have regs=4 stack=0 marks\
-       last_idx 19 first_idx 10\
-       regs=4 stack=0 before 19\
-       regs=200 stack=0 before 18\
-       regs=300 stack=0 before 17\
-       regs=201 stack=0 before 15\
-       regs=201 stack=0 before 14\
-       regs=200 stack=0 before 13\
-       regs=200 stack=0 before 12\
-       regs=200 stack=0 before 11\
-       regs=200 stack=0 before 10\
-       parent already had regs=0 stack=0 marks",
+       "mark_precise: frame0: last_idx 26 first_idx 20\
+       mark_precise: frame0: regs=r2 stack= before 25\
+       mark_precise: frame0: regs=r2 stack= before 24\
+       mark_precise: frame0: regs=r2 stack= before 23\
+       mark_precise: frame0: regs=r2 stack= before 22\
+       mark_precise: frame0: regs=r2 stack= before 20\
+       parent didn't have regs=4 stack=0 marks:\
+       mark_precise: frame0: last_idx 19 first_idx 10\
+       mark_precise: frame0: regs=r2 stack= before 19\
+       mark_precise: frame0: regs=r9 stack= before 18\
+       mark_precise: frame0: regs=r8,r9 stack= before 17\
+       mark_precise: frame0: regs=r0,r9 stack= before 15\
+       mark_precise: frame0: regs=r0,r9 stack= before 14\
+       mark_precise: frame0: regs=r9 stack= before 13\
+       mark_precise: frame0: regs=r9 stack= before 12\
+       mark_precise: frame0: regs=r9 stack= before 11\
+       mark_precise: frame0: regs=r9 stack= before 10\
+       parent already had regs=0 stack=0 marks:",
 },
 {
        "precise: test 2",
        .flags = BPF_F_TEST_STATE_FREQ,
        .errstr =
        "26: (85) call bpf_probe_read_kernel#113\
-       last_idx 26 first_idx 22\
-       regs=4 stack=0 before 25\
-       regs=4 stack=0 before 24\
-       regs=4 stack=0 before 23\
-       regs=4 stack=0 before 22\
-       parent didn't have regs=4 stack=0 marks\
-       last_idx 20 first_idx 20\
-       regs=4 stack=0 before 20\
-       parent didn't have regs=4 stack=0 marks\
-       last_idx 19 first_idx 17\
-       regs=4 stack=0 before 19\
-       regs=200 stack=0 before 18\
-       regs=300 stack=0 before 17\
-       parent already had regs=0 stack=0 marks",
+       mark_precise: frame0: last_idx 26 first_idx 22\
+       mark_precise: frame0: regs=r2 stack= before 25\
+       mark_precise: frame0: regs=r2 stack= before 24\
+       mark_precise: frame0: regs=r2 stack= before 23\
+       mark_precise: frame0: regs=r2 stack= before 22\
+       parent didn't have regs=4 stack=0 marks:\
+       mark_precise: frame0: last_idx 20 first_idx 20\
+       mark_precise: frame0: regs=r2 stack= before 20\
+       parent didn't have regs=4 stack=0 marks:\
+       mark_precise: frame0: last_idx 19 first_idx 17\
+       mark_precise: frame0: regs=r2 stack= before 19\
+       mark_precise: frame0: regs=r9 stack= before 18\
+       mark_precise: frame0: regs=r8,r9 stack= before 17\
+       parent already had regs=0 stack=0 marks:",
 },
 {
        "precise: cross frame pruning",
        },
        .prog_type = BPF_PROG_TYPE_XDP,
        .flags = BPF_F_TEST_STATE_FREQ,
-       .errstr = "5: (2d) if r4 > r0 goto pc+0\
-       last_idx 5 first_idx 5\
-       parent didn't have regs=10 stack=0 marks\
-       last_idx 4 first_idx 2\
-       regs=10 stack=0 before 4\
-       regs=10 stack=0 before 3\
-       regs=0 stack=1 before 2\
-       last_idx 5 first_idx 5\
-       parent didn't have regs=1 stack=0 marks",
+       .errstr = "mark_precise: frame0: last_idx 5 first_idx 5\
+       parent didn't have regs=10 stack=0 marks:\
+       mark_precise: frame0: last_idx 4 first_idx 2\
+       mark_precise: frame0: regs=r4 stack= before 4\
+       mark_precise: frame0: regs=r4 stack= before 3\
+       mark_precise: frame0: regs= stack=-8 before 2\
+       mark_precise: frame0: falling back to forcing all scalars precise\
+       mark_precise: frame0: last_idx 5 first_idx 5\
+       parent didn't have regs=1 stack=0 marks:",
        .result = VERBOSE_ACCEPT,
        .retval = -1,
 },
        },
        .prog_type = BPF_PROG_TYPE_XDP,
        .flags = BPF_F_TEST_STATE_FREQ,
-       .errstr = "last_idx 6 first_idx 6\
-       parent didn't have regs=10 stack=0 marks\
-       last_idx 5 first_idx 3\
-       regs=10 stack=0 before 5\
-       regs=10 stack=0 before 4\
-       regs=0 stack=1 before 3\
-       last_idx 6 first_idx 6\
-       parent didn't have regs=1 stack=0 marks\
-       last_idx 5 first_idx 3\
-       regs=1 stack=0 before 5",
+       .errstr = "mark_precise: frame0: last_idx 6 first_idx 6\
+       parent didn't have regs=10 stack=0 marks:\
+       mark_precise: frame0: last_idx 5 first_idx 3\
+       mark_precise: frame0: regs=r4 stack= before 5\
+       mark_precise: frame0: regs=r4 stack= before 4\
+       mark_precise: frame0: regs= stack=-8 before 3\
+       mark_precise: frame0: falling back to forcing all scalars precise\
+       force_precise: frame0: forcing r0 to be precise\
+       force_precise: frame0: forcing r0 to be precise\
+       mark_precise: frame0: last_idx 6 first_idx 6\
+       parent didn't have regs=1 stack=0 marks:\
+       mark_precise: frame0: last_idx 5 first_idx 3\
+       mark_precise: frame0: regs=r0 stack= before 5",
        .result = VERBOSE_ACCEPT,
        .retval = -1,
 },