Closed kmicinski closed 7 years ago
I chatted with @jsjeon about this bug this morning. He agrees that redexer is incorrectly calculating the type of the opcode, and subsequently putting a move/from16
rather than a move-object/from16
. The bug here is somewhere around this line of code:
https://github.com/plum-umd/redexer/blob/master/src/modify.ml#L1296
I'm looking into this bug now.
As mentioned in person, the opr_expander
pass not only adjusts opcodes according to the new range of operands, but also insert prologue/epilogue code, if necessary. if-ne
is one of those examples: it uses only for bit operands, and thus we need an instruction to move around the operand.
According to bytecode dump @kmicinski sent to me, there is a backward control-flow, where v18 holes an object. At the same time, in a normal pass, v18 may have an integer constant. Therefore, data-flow analysis concluded that the type of v18 is just top
I guess, and chose move/from16
, which is somewhat general.
I wonder replacing it with move-object/from16
still doesn't resolve this issue, since there are multiple paths that use the same register with different types. The workaround I can come up with is actually using the other free register whose type (inferred via data-flow analysis) is more accurate than just top.
It sounds like the correct solution is to modify the instrumentation to attempt to use another register of the right sort when the analysis calculates top
for the category, yes?
Right, but as you pointed out, that data-flow analysis (reaching definition) should be fixed, too.
This issue should be merged with #19.
The current fix is going to happen after white/blacklist configuration for various methods in redexer, but after #19 is implemented correctly this should go away
In the "wedding planner" app @eldr4d linked, there was a specific issue that caused badly formed code after rewriting. The original error thrown by the verifier is:
The reason why this is happening is that in the instrumented bytecode, the method
org.codehaus.jackson.map.ser.std.MapSerializer.serializeTypedFields
contains malformed bytecode at the address0x004CEEDE
. The offending instruction at that address is:This comes as the result of a "cleanup" pass within redexer: the
opr_expander
pass in theModify
module. The purpose of this pass is to fix up bytecode instructions that have been thrown out of range by instrumentation. After instrumenting redexer to print the instructions that are replaced as a result of this phase, I have realized that the original instruction replaced is:The instruction sequence is replaced with
This is a necessary step, because
if-ne
only works on four bit operands. But the problem is that v1 is somehow causing a type error? I'm not sure what's happening, so I need to look into the machinery that's being used to allocate registers in this phase.