There were two bugs corrupting the string bytes and instructions. The
first bug involved the implicit sign extension of negative char values.
The second bug involved a faulty optimization (fixup_operands) which
used the incorrect instruction opcode.
1) Cast char to unsigned char before casting to uint32_t.
2) Changed opcode of optimized instruction to (BPF_STX | BPF_MEM | BPF_W).
insn_before_inserter ins(b, j, "opt");
p.mk_mov(ins, n, s1);
j->src1 = s1 = n;
- }
+
+ // Since the content is in the src register, we need
+ // to use BPF_STX instead of BPF_ST
+ j->code = BPF_STX | BPF_MEM | BPF_W;
+ }
if (value *s0 = j->src0)
{
if (i * 4 + j < str_bytes - 1)
{
// ??? assuming little-endian target
- word |= (uint32_t)src[i * 4 + j] << (j * 8);
+ //
+ // Must cast each signed char in src to unsigned char first
+ // in order to avoid the implicit sign extension resulting
+ // from the uint32_t cast.
+ word |= ((uint32_t)(unsigned char)src[i * 4 + j]) << (j * 8);
}
+
this_prog.mk_st(this_ins, BPF_W,
dest, (int32_t)i * 4 + ofs,
this_prog.new_imm(word));