// Appends an instruction to the existing buffer and then // attempts to match the output of that instructions disassembly // against a regex expression. Fails if no match is found. template <typename LamdaType> void CompareInstruction(LamdaType fn, constchar* EXP) {
ImplantInstruction(fn);
masm.FinalizeCode();
// This gets the last instruction in the buffer. // The end address of the buffer is at the end of the last instruction. // sizeof(Instruction) is 1 byte as it in an empty class. // Therefore we need to go back kInstructionSize * sizeof(Instruction) bytes // in order to get to the start of the last instruction. const Instruction* targetInstruction =
masm.GetBuffer()->GetEndAddress<Instruction*>()->
GetInstructionAtOffset(-static_cast<signed>(kInstructionSize));
decoder.Decode(targetInstruction);
constchar* disassembly = disasm->GetOutput();
if (!std::regex_match(disassembly, std::regex(EXP))) { const uint32_t encoding = static_cast<uint32_t>(targetInstruction->GetInstructionBits());
#define IMPLANT(fn) \ do { \
ImplantInstruction([&]() { this->masm.fn; }); \
} while (0)
#define COMPARE(fn, output) \ do { \
CompareInstruction([&]() { this->masm.fn; }, (output)); \
} while (0)
// These tests map onto the named per instruction instrumentation functions in: // ART/art/disassembler/disassembler_arm.cc // Context can be found in the logic conditional on incoming instruction types and sequences in the // ART disassembler. As of writing the functionality we are testing for that of additional // diagnostic info being appended to the end of the ART disassembly output.
TEST_F(ArtDisassemblerTest, LoadLiteralVisitBadAddress) {
SetupAssembly(0xffffff);
// Check we append an erroneous hint "(?)" for literal load instructions with // out of scope literal pool value addresses.
COMPARE(ldr(x0, vixl::aarch64::Assembler::ImmLLiteral(1000)), "ldr x0, pc\\+128000 \\(addr -?0x[0-9a-fA-F]+\\) \\(\\?\\)");
}
// Test that we do not append anything for ineligible instruction.
COMPARE(ldr(x0, MemOperand(x18, 0)), "ldr x0, \\[x18\\]$");
// Check we do append some extra info in the right text format for valid literal load instruction.
COMPARE(ldr(w0, vixl::aarch64::Assembler::ImmLLiteral(0)), "ldr w0, pc\\+0 \\(addr -?0x[0-9a-f]+\\) \\(0x18000000 / 402653184\\)"); // We don't compare with exact value even though it's a known literal (the encoding of the // instruction itself) since the precision of printed floating point values could change.
COMPARE(ldr(s0, vixl::aarch64::Assembler::ImmLLiteral(0)), "ldr s0, pc\\+0 \\(addr -?0x[0-9a-f]+\\) \\([0-9]+.[0-9]+e(\\+|-)[0-9]+\\)");
}
// Test that we do not append anything for ineligible instruction.
COMPARE(ldr(x0, MemOperand(x18, 8)), "ldr x0, \\[x18, #8\\]$"); // Test that we do append the function name if the instruction is a load from the address // stored in the TR register.
COMPARE(ldr(x0, MemOperand(x19, 8)), "ldr x0, \\[tr, #8\\] ; thin_lock_thread_id");
}
// Test that we do append the function name if the instruction is a branch // to a load that reads data from the address in the TR register, into the IPO register // followed by a BR branching using the IPO register.
COMPARE(bl(&destination), "bl #-0x8 \\(addr -?0x[0-9a-f]+\\) ; state_and_flags");
}
} // namespace arm64
} // namespace art
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.