summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/Disassembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/Disassembler.cpp')
-rw-r--r--lldb/source/Core/Disassembler.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index c422113b688..2db2d55308e 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -503,6 +503,60 @@ Instruction::DumpEmulation (const ArchSpec &arch)
}
bool
+Instruction::TestEmulation (Stream *out_stream, const char *file_name)
+{
+ if (!out_stream)
+ return false;
+
+ if (!file_name)
+ {
+ out_stream->Printf ("Instruction::TestEmulation: Missing file_name.\n");
+ return false;
+ }
+
+ FILE *test_file = fopen (file_name, "r");
+ if (!test_file)
+ {
+ out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.\n");
+ return false;
+ }
+
+ ArchSpec arch;
+ char buffer[256];
+ if (!fgets (buffer,255, test_file)) // Read/skip first line of file, which should be a comment line (description).
+ {
+ out_stream->Printf ("Instruction::TestEmulation: Read comment line failed.\n");
+ fclose (test_file);
+ return false;
+ }
+ SetDescription (buffer);
+
+ if (fscanf (test_file, "%s", buffer) != 1) // Read the arch or arch-triple from the file
+ {
+ out_stream->Printf ("Instruction::TestEmulation: Read arch failed.\n");
+ fclose (test_file);
+ return false;
+ }
+
+ const char *cptr = buffer;
+ arch.SetTriple (llvm::Triple (cptr));
+
+ bool success = false;
+ std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
+ if (insn_emulator_ap.get())
+ success = insn_emulator_ap->TestEmulation (out_stream, test_file, arch);
+
+ fclose (test_file);
+
+ if (success)
+ out_stream->Printf ("Emulation test succeeded.\n");
+ else
+ out_stream->Printf ("Emulation test failed.\n");
+
+ return success;
+}
+
+bool
Instruction::Emulate (const ArchSpec &arch,
bool auto_advance_pc,
void *baton,
@@ -692,3 +746,97 @@ Disassembler::GetInstructionList () const
{
return m_instruction_list;
}
+
+//----------------------------------------------------------------------
+// Class PseudoInstruction
+//----------------------------------------------------------------------
+PseudoInstruction::PseudoInstruction () :
+ Instruction (Address(), eAddressClassUnknown),
+ m_description ()
+{
+}
+
+PseudoInstruction::~PseudoInstruction ()
+{
+}
+
+void
+PseudoInstruction::Dump (lldb_private::Stream *s,
+ uint32_t max_opcode_byte_size,
+ bool show_address,
+ bool show_bytes,
+ const lldb_private::ExecutionContext* exe_ctx,
+ bool raw)
+{
+ if (!s)
+ return;
+
+ if (show_bytes)
+ m_opcode.Dump (s, max_opcode_byte_size);
+
+ if (m_description.size() > 0)
+ s->Printf ("%s", m_description.c_str());
+ else
+ s->Printf ("<unknown>");
+
+}
+
+bool
+PseudoInstruction::DoesBranch () const
+{
+ // This is NOT a valid question for a pseudo instruction.
+ return false;
+}
+
+size_t
+PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
+ const lldb_private::DataExtractor &data,
+ uint32_t data_offset)
+{
+ return m_opcode.GetByteSize();
+}
+
+
+void
+PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
+{
+ if (!opcode_data)
+ return;
+
+ switch (opcode_size)
+ {
+ case 8:
+ {
+ uint8_t value8 = *((uint8_t *) opcode_data);
+ m_opcode.SetOpcode8 (value8);
+ break;
+ }
+ case 16:
+ {
+ uint16_t value16 = *((uint16_t *) opcode_data);
+ m_opcode.SetOpcode16 (value16);
+ break;
+ }
+ case 32:
+ {
+ uint32_t value32 = *((uint32_t *) opcode_data);
+ m_opcode.SetOpcode32 (value32);
+ break;
+ }
+ case 64:
+ {
+ uint64_t value64 = *((uint64_t *) opcode_data);
+ m_opcode.SetOpcode64 (value64);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void
+PseudoInstruction::SetDescription (const char *description)
+{
+ if (description && strlen (description) > 0)
+ m_description = description;
+}
OpenPOWER on IntegriCloud