From 2d85707a754122ab940cc1b7c0dd07c3c3f28df7 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 22 Sep 2023 08:59:43 +0100 Subject: [PATCH 1/8] sim: Define an InstructionDisassembler SimObject We want to be able to configure from python the disassembler used by an instruction tracer. The default/base version will reuse existing instruction logic and it will simply call the StaticInst::disassemble method. Change-Id: Ieb16f059a436757c5892dcc82882f6d42090927f Signed-off-by: Giacomo Travaglini --- src/sim/InstTracer.py | 22 ++++++++++++++++++++++ src/sim/SConscript | 2 +- src/sim/insttracer.hh | 43 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/sim/InstTracer.py b/src/sim/InstTracer.py index 34c97dd43e..c8b3673d47 100644 --- a/src/sim/InstTracer.py +++ b/src/sim/InstTracer.py @@ -1,3 +1,15 @@ +# Copyright (c) 2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# # Copyright (c) 2007 The Regents of The University of Michigan # All rights reserved. # @@ -28,8 +40,18 @@ from m5.SimObject import SimObject from m5.params import * +class InstDisassembler(SimObject): + type = "InstDisassembler" + cxx_header = "sim/insttracer.hh" + cxx_class = "gem5::trace::InstDisassembler" + + class InstTracer(SimObject): type = "InstTracer" cxx_header = "sim/insttracer.hh" cxx_class = "gem5::trace::InstTracer" abstract = True + + disassembler = Param.InstDisassembler( + InstDisassembler(), "Instruction Disassembler" + ) diff --git a/src/sim/SConscript b/src/sim/SConscript index e26676c00a..78b06c5b1d 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -105,7 +105,7 @@ GTest('proxy_ptr.test', 'proxy_ptr.test.cc') GTest('serialize.test', 'serialize.test.cc', with_tag('gem5 serialize')) GTest('serialize_handlers.test', 'serialize_handlers.test.cc') -SimObject('InstTracer.py', sim_objects=['InstTracer']) +SimObject('InstTracer.py', sim_objects=['InstTracer', 'InstDisassembler']) SimObject('Process.py', sim_objects=['Process', 'EmulatedDriver']) Source('faults.cc') Source('process.cc') diff --git a/src/sim/insttracer.hh b/src/sim/insttracer.hh index 9c9bca7692..37e29756a2 100644 --- a/src/sim/insttracer.hh +++ b/src/sim/insttracer.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, 2020 ARM Limited + * Copyright (c) 2014, 2017, 2020, 2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -48,6 +48,7 @@ #include "cpu/inst_res.hh" #include "cpu/inst_seq.hh" #include "cpu/static_inst.hh" +#include "params/InstTracer.hh" #include "sim/sim_object.hh" namespace gem5 @@ -286,10 +287,37 @@ class InstRecord bool getFaulting() const { return faulting; } }; +/** + * The base InstDisassembler class provides a one-API interface + * to disassemble the instruction passed as a first argument. + * It also provides a base implementation which is + * simply calling the StaticInst::disassemble method, which + * is the usual interface for disassembling + * a gem5 instruction. + */ +class InstDisassembler : public SimObject +{ + public: + InstDisassembler(const SimObjectParams ¶ms) + : SimObject(params) + {} + + virtual std::string + disassemble(StaticInstPtr inst, + const PCStateBase &pc, + const loader::SymbolTable *symtab) const + { + return inst->disassemble(pc.instAddr(), symtab); + } +}; + class InstTracer : public SimObject { public: - InstTracer(const Params &p) : SimObject(p) {} + PARAMS(InstTracer); + InstTracer(const Params &p) + : SimObject(p), disassembler(p.disassembler) + {} virtual ~InstTracer() {} @@ -297,6 +325,17 @@ class InstTracer : public SimObject getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst, const PCStateBase &pc, const StaticInstPtr macroStaticInst=nullptr) = 0; + + std::string + disassemble(StaticInstPtr inst, + const PCStateBase &pc, + const loader::SymbolTable *symtab=nullptr) const + { + return disassembler->disassemble(inst, pc, symtab); + } + + private: + InstDisassembler *disassembler; }; } // namespace trace From 952c4f5eead8af33bfbff7c63cb0ebe934ebbc5d Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 22 Sep 2023 09:01:09 +0100 Subject: [PATCH 2/8] cpu: Pass a reference of the parent tracer to the ExeTracerRecord Change-Id: I3576df2b7bee1289db60bb6072bd9c90038ca8ce Signed-off-by: Giacomo Travaglini --- src/cpu/exetrace.hh | 21 +++++++++++++++++++-- src/cpu/nativetrace.cc | 23 +++++++++++++++++++++++ src/cpu/nativetrace.hh | 26 +++++++++++++++++--------- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/cpu/exetrace.hh b/src/cpu/exetrace.hh index 143cfa0eb3..3fbeb98bc3 100644 --- a/src/cpu/exetrace.hh +++ b/src/cpu/exetrace.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2001-2005 The Regents of The University of Michigan * All rights reserved. * @@ -49,14 +61,19 @@ class ExeTracerRecord : public InstRecord public: ExeTracerRecord(Tick _when, ThreadContext *_thread, const StaticInstPtr _staticInst, const PCStateBase &_pc, + const ExeTracer &_tracer, const StaticInstPtr _macroStaticInst = NULL) - : InstRecord(_when, _thread, _staticInst, _pc, _macroStaticInst) + : InstRecord(_when, _thread, _staticInst, _pc, _macroStaticInst), + tracer(_tracer) { } void traceInst(const StaticInstPtr &inst, bool ran); void dump(); + + protected: + const ExeTracer &tracer; }; class ExeTracer : public InstTracer @@ -75,7 +92,7 @@ class ExeTracer : public InstTracer return NULL; return new ExeTracerRecord(when, tc, - staticInst, pc, macroStaticInst); + staticInst, pc, *this, macroStaticInst); } }; diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc index 3070205b9f..60efc791de 100644 --- a/src/cpu/nativetrace.cc +++ b/src/cpu/nativetrace.cc @@ -1,4 +1,16 @@ /* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006-2009 The Regents of The University of Michigan * All rights reserved. * @@ -49,6 +61,17 @@ NativeTrace::NativeTrace(const Params &p) fd = native_listener->accept(); } +NativeTraceRecord::NativeTraceRecord( + NativeTrace *_parent, + Tick _when, ThreadContext *_thread, + const StaticInstPtr _staticInst, const PCStateBase &_pc, + const StaticInstPtr _macroStaticInst) + : ExeTracerRecord(_when, _thread, _staticInst, _pc, + *_parent, _macroStaticInst), + parent(_parent) +{ +} + void NativeTraceRecord::dump() { diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh index a19acaca3f..a0866e130f 100644 --- a/src/cpu/nativetrace.hh +++ b/src/cpu/nativetrace.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 2006-2009 The Regents of The University of Michigan * All rights reserved. * @@ -50,20 +62,16 @@ class NativeTrace; class NativeTraceRecord : public ExeTracerRecord { - protected: - NativeTrace * parent; - public: - NativeTraceRecord(NativeTrace * _parent, + NativeTraceRecord(NativeTrace *_parent, Tick _when, ThreadContext *_thread, const StaticInstPtr _staticInst, const PCStateBase &_pc, - const StaticInstPtr _macroStaticInst=nullptr) - : ExeTracerRecord(_when, _thread, _staticInst, _pc, _macroStaticInst), - parent(_parent) - { - } + const StaticInstPtr _macroStaticInst=nullptr); void dump(); + + private: + NativeTrace *parent; }; class NativeTrace : public ExeTracer From 237bbf0e42ab3b7f43d582566e021604794e5462 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 22 Sep 2023 09:05:45 +0100 Subject: [PATCH 3/8] cpu: Disassemble through the InstDisassembler in the ExeTracer Change-Id: I4a0c585b9b8824a0694066bef0ee004f68407111 Signed-off-by: Giacomo Travaglini --- src/cpu/exetrace.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc index 22d0d4be69..6cd5269fa7 100644 --- a/src/cpu/exetrace.cc +++ b/src/cpu/exetrace.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019 ARM Limited + * Copyright (c) 2017, 2019, 2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -101,7 +101,7 @@ ExeTracerRecord::traceInst(const StaticInstPtr &inst, bool ran) // outs << std::setw(26) << std::left; - outs << inst->disassemble(cur_pc, &loader::debugSymbolTable); + outs << tracer.disassemble(inst, *pc, &loader::debugSymbolTable); if (ran) { outs << " : "; From 81b6e296dd79969ceed9314cf5398c55cab3ba5e Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 22 Sep 2023 12:48:14 +0100 Subject: [PATCH 4/8] arch-arm: disassemble member variable not used by TarmacParser We move it to the child class which is what the TarmacTracer actually uses. Change-Id: Ia30892723d2e1f7306dae87c6c9c1d69d00ad73d Signed-off-by: Giacomo Travaglini --- src/arch/arm/tracers/tarmac_base.cc | 6 ------ src/arch/arm/tracers/tarmac_base.hh | 1 - src/arch/arm/tracers/tarmac_record.cc | 8 +++++++- src/arch/arm/tracers/tarmac_record.hh | 3 +++ 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/arch/arm/tracers/tarmac_base.cc b/src/arch/arm/tracers/tarmac_base.cc index 25524d24b6..01add3037a 100644 --- a/src/arch/arm/tracers/tarmac_base.cc +++ b/src/arch/arm/tracers/tarmac_base.cc @@ -68,7 +68,6 @@ TarmacBaseRecord::InstEntry::InstEntry( : taken(predicate) , addr(pc.instAddr()) , opcode(staticInst->getEMI() & 0xffffffff), - disassemble(staticInst->disassemble(addr)), isetstate(pcToISetState(pc)), mode(MODE_USER) { @@ -76,11 +75,6 @@ TarmacBaseRecord::InstEntry::InstEntry( // Operating mode gained by reading the architectural register (CPSR) const CPSR cpsr = thread->readMiscRegNoEffect(MISCREG_CPSR); mode = (OperatingMode) (uint8_t)cpsr.mode; - - // In Tarmac, instruction names are printed in capital - // letters. - std::for_each(disassemble.begin(), disassemble.end(), - [](char& c) { c = toupper(c); }); } TarmacBaseRecord::RegEntry::RegEntry(const PCStateBase &pc) diff --git a/src/arch/arm/tracers/tarmac_base.hh b/src/arch/arm/tracers/tarmac_base.hh index 501eb1b008..9e80f6d1f1 100644 --- a/src/arch/arm/tracers/tarmac_base.hh +++ b/src/arch/arm/tracers/tarmac_base.hh @@ -93,7 +93,6 @@ class TarmacBaseRecord : public InstRecord bool taken; Addr addr; ArmISA::MachInst opcode; - std::string disassemble; ISetState isetstate; ArmISA::OperatingMode mode; }; diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc index 59d6a18b39..23e751112d 100644 --- a/src/arch/arm/tracers/tarmac_record.cc +++ b/src/arch/arm/tracers/tarmac_record.cc @@ -123,7 +123,8 @@ TarmacTracerRecord::TarmacTracerRecord(Tick _when, ThreadContext *_thread, TarmacTracerRecord::TraceInstEntry::TraceInstEntry( const TarmacContext& tarmCtx, bool predicate) - : InstEntry(tarmCtx.thread, *tarmCtx.pc, tarmCtx.staticInst, predicate) + : InstEntry(tarmCtx.thread, *tarmCtx.pc, tarmCtx.staticInst, predicate), + disassemble(tarmCtx.staticInst->disassemble(addr)) { secureMode = isSecure(tarmCtx.thread); @@ -140,6 +141,11 @@ TarmacTracerRecord::TraceInstEntry::TraceInstEntry( // for 16bit (Thumb) instruction. opcode = arm_inst->encoding(); + // In Tarmac, instruction names are printed in capital + // letters. + std::for_each(disassemble.begin(), disassemble.end(), + [](char& c) { c = toupper(c); }); + // Update the instruction count: number of executed // instructions. instCount++; diff --git a/src/arch/arm/tracers/tarmac_record.hh b/src/arch/arm/tracers/tarmac_record.hh index 009df5db29..d80121b1b9 100644 --- a/src/arch/arm/tracers/tarmac_record.hh +++ b/src/arch/arm/tracers/tarmac_record.hh @@ -115,6 +115,9 @@ class TarmacTracerRecord : public TarmacBaseRecord * 32 otherwise (ARM and BigThumb) */ uint8_t instSize; + + /** Instruction disassembly */ + std::string disassemble; }; /** Register Entry */ From 27ce721ad32aff21ce4c494cac4114c5eaf27f19 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 22 Sep 2023 12:56:22 +0100 Subject: [PATCH 5/8] arch-arm: Pass a reference of the parent tracer to TarmacContext Change-Id: I7ab0442353a8b5854bb6b50bd54dac89f83ecc1d Signed-off-by: Giacomo Travaglini --- src/arch/arm/tracers/tarmac_record.cc | 1 + src/arch/arm/tracers/tarmac_tracer.hh | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc index 23e751112d..53a9d4c459 100644 --- a/src/arch/arm/tracers/tarmac_record.cc +++ b/src/arch/arm/tracers/tarmac_record.cc @@ -338,6 +338,7 @@ TarmacTracerRecord::dump() auto ®Queue = tracer.regQueue; const TarmacContext tarmCtx( + tracer, thread, staticInst->isMicroop()? macroStaticInst : staticInst, *pc diff --git a/src/arch/arm/tracers/tarmac_tracer.hh b/src/arch/arm/tracers/tarmac_tracer.hh index f8c7b5ca53..71207b3860 100644 --- a/src/arch/arm/tracers/tarmac_tracer.hh +++ b/src/arch/arm/tracers/tarmac_tracer.hh @@ -58,6 +58,8 @@ class OutputStream; namespace trace { +class TarmacTracer; + /** * This object type is encapsulating the informations needed by * a Tarmac record to generate it's own entries. @@ -65,15 +67,18 @@ namespace trace { class TarmacContext { public: - TarmacContext(ThreadContext* _thread, + TarmacContext(const TarmacTracer &_tracer, + ThreadContext* _thread, const StaticInstPtr _staticInst, const PCStateBase &_pc) - : thread(_thread), staticInst(_staticInst), pc(_pc.clone()) + : tracer(_tracer), thread(_thread), staticInst(_staticInst), + pc(_pc.clone()) {} std::string tarmacCpuName() const; public: + const TarmacTracer &tracer; ThreadContext* thread; const StaticInstPtr staticInst; std::unique_ptr pc; From 34336208b7f2ee917a55d8e43cefd30c1c0929c3 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 22 Sep 2023 13:05:10 +0100 Subject: [PATCH 6/8] arch-arm: Disassemble through InstDisassembler in TarmacTracer Change-Id: I5407338501084c016522749be697dd688ca51735 Signed-off-by: Giacomo Travaglini --- src/arch/arm/tracers/tarmac_record.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc index 53a9d4c459..5aa1f7e957 100644 --- a/src/arch/arm/tracers/tarmac_record.cc +++ b/src/arch/arm/tracers/tarmac_record.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 ARM Limited + * Copyright (c) 2017-2019, 2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -124,7 +124,7 @@ TarmacTracerRecord::TraceInstEntry::TraceInstEntry( const TarmacContext& tarmCtx, bool predicate) : InstEntry(tarmCtx.thread, *tarmCtx.pc, tarmCtx.staticInst, predicate), - disassemble(tarmCtx.staticInst->disassemble(addr)) + disassemble(tarmCtx.tracer.disassemble(tarmCtx.staticInst, *tarmCtx.pc)) { secureMode = isSecure(tarmCtx.thread); From 82675648c874d6f9d00b3cb46c896dda618c4961 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 9 Oct 2023 18:23:40 +0100 Subject: [PATCH 7/8] cpu: Implement a CapstoneDisassembler Capstone is an open source disassembler [1] already used by other projects (like QEMU). gem5 is already capable of disassembling instructions. Every StaticInst is supposed to define a generateDisassembly method which returns the instruction mnemonic (opcode + operand list) as a string. This "distributed" implementation of a disassembler relies on the developer to properly populate the metadata fields of the base instruction class. The growing complexity of the ISA code and the massive reuse of base classes beyond their intended use has led to a disassembling logic which contains several bugs. By allowing a tracer to rely on a third party disassembler, we fill the intruction trace with a more trustworthy instruction stream. This will make any trace parsing tool to work better and it will also allow us to spot/fix our own bugs by comparing instruction traces with native vs custom disassembler [1]: http://www.capstone-engine.org/ Change-Id: I3c4db5072c03d2731265d0398d3863c101dcb180 Signed-off-by: Giacomo Travaglini --- src/cpu/Capstone.py | 45 +++++++++++++++++++ src/cpu/SConscript | 5 ++- src/cpu/SConsopts | 50 ++++++++++++++++++++++ src/cpu/capstone.cc | 90 ++++++++++++++++++++++++++++++++++++++ src/cpu/capstone.hh | 102 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 src/cpu/Capstone.py create mode 100644 src/cpu/SConsopts create mode 100644 src/cpu/capstone.cc create mode 100644 src/cpu/capstone.hh diff --git a/src/cpu/Capstone.py b/src/cpu/Capstone.py new file mode 100644 index 0000000000..4b6b5fd84a --- /dev/null +++ b/src/cpu/Capstone.py @@ -0,0 +1,45 @@ +# Copyright (c) 2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.SimObject import SimObject +from m5.params import * +from m5.objects.InstTracer import InstDisassembler + + +class CapstoneDisassembler(InstDisassembler): + type = "CapstoneDisassembler" + cxx_class = "gem5::trace::CapstoneDisassembler" + cxx_header = "cpu/capstone.hh" + abstract = True diff --git a/src/cpu/SConscript b/src/cpu/SConscript index d6dcd2f6ea..03ba7b924d 100644 --- a/src/cpu/SConscript +++ b/src/cpu/SConscript @@ -1,6 +1,6 @@ # -*- mode:python -*- -# Copyright (c) 2020 ARM Limited +# Copyright (c) 2020, 2023 Arm Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -115,6 +115,9 @@ Source('simple_thread.cc') Source('thread_context.cc') Source('thread_state.cc') Source('timing_expr.cc') +SourceLib('capstone', tags='capstone') +Source('capstone.cc', tags='capstone') +SimObject('Capstone.py', sim_objects=['CapstoneDisassembler'], tags='capstone') SimObject('DummyChecker.py', sim_objects=['DummyChecker']) Source('checker/cpu.cc') diff --git a/src/cpu/SConsopts b/src/cpu/SConsopts new file mode 100644 index 0000000000..94e55ece32 --- /dev/null +++ b/src/cpu/SConsopts @@ -0,0 +1,50 @@ +# Copyright (c) 2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Import('*') + +from gem5_scons import warning + +import gem5_scons + +with gem5_scons.Configure(main) as conf: + # Check for + conf.env['CONF']['HAVE_CAPSTONE'] = conf.CheckHeader('capstone/capstone.h', '<>') + + if conf.env['CONF']['HAVE_CAPSTONE']: + conf.env.TagImplies('capstone', 'gem5 lib') + else: + warning("Header file not found.\n" + "This host has no capstone library installed.") diff --git a/src/cpu/capstone.cc b/src/cpu/capstone.cc new file mode 100644 index 0000000000..4c2896312d --- /dev/null +++ b/src/cpu/capstone.cc @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cpu/capstone.hh" + +#include "base/output.hh" + +namespace gem5 +{ + +namespace trace +{ + +std::string +CapstoneDisassembler::disassemble(StaticInstPtr inst, + const PCStateBase &pc, + const loader::SymbolTable *symtab) const +{ + std::string inst_dist; + if (inst->isPseudo() || inst->isMicroop()) { + // Capstone doesn't have any visibility over microops nor over + // gem5 pseudo ops. Use native disassembler instead + inst_dist = InstDisassembler::disassemble(inst, pc, symtab); + } else { + // Stripping the extended fields from the ExtMachInst + auto mach_inst = inst->getEMI() & mask(inst->size() * 8); + + cs_insn *insn; + // capstone disassembler + if (const csh *curr_handle = currHandle(pc); curr_handle != nullptr) { + size_t count = cs_disasm(*curr_handle, (uint8_t*)&mach_inst, + inst->size(), 0, 0, &insn); + + // As we are passing only one instruction, we are expecting one instruction only + // being disassembled + assert(count <= 1); + + for (int idx = 0; idx < count; idx++) { + inst_dist += csprintf(" %s %s", insn[idx].mnemonic, insn[idx].op_str); + } + } else { + // No valid handle; return an invalid string + inst_dist += " capstone failure"; + } + } + + return inst_dist; +} + +CapstoneDisassembler::CapstoneDisassembler(const Params &p) + : InstDisassembler(p) +{ +} + +} // namespace trace +} // namespace gem5 diff --git a/src/cpu/capstone.hh b/src/cpu/capstone.hh new file mode 100644 index 0000000000..1a197e5086 --- /dev/null +++ b/src/cpu/capstone.hh @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __CPU_CAPSTONE_HH__ +#define __CPU_CAPSTONE_HH__ + +#include + +#include "params/CapstoneDisassembler.hh" +#include "sim/insttracer.hh" + +namespace gem5 +{ + +class ThreadContext; + +namespace trace { + +/** + * Capstone Disassembler: + * The disassembler relies on the capstone library to convert + * the StaticInst encoding into the disassembled string. + * + * One thing to keep in mind is that the disassembled + * instruction might not coincide with the instruction being + * decoded + executed in gem5. This could be the case if + * there was a bug in either gem5 or in capstone itself. + * This scenatio is not possible with the native gem5 disassembler + * as the instruction mnemonic is tightly coupled with the + * decoded(=generated) instruction (you print what you decode) + * + * The Capstone dispatches to the native disassembler in + * two cases: + * + * a) m5 pseudo ops + * b) micro-ops + */ +class CapstoneDisassembler : public InstDisassembler +{ + public: + PARAMS(CapstoneDisassembler); + CapstoneDisassembler(const Params &p); + + std::string + disassemble(StaticInstPtr inst, + const PCStateBase &pc, + const loader::SymbolTable *symtab) const override; + + protected: + + /** + * Return a pointer to the current capstone handle (csh). + * + * Any ISA extension of the Capstone disassembler should + * initialize (with cs_open) one or more capstone handles + * at construcion time. + * (You might need more than one handle in case the ISA + * has more than one mode of operation, e.g. arm and arm64) + * The current handle in use should be returned every time + * the currHandle is called. + */ + virtual const csh* currHandle(const PCStateBase &pc) const = 0; +}; + +} // namespace trace +} // namespace gem5 + +#endif // __CPU_CAPSTONE_HH__ From 8233aa8a9b7cf0b2028d67f9689fa6e05d2a9e13 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Thu, 21 Sep 2023 15:01:42 +0100 Subject: [PATCH 8/8] arch-arm: Implement a CapstoneDisassembler for Arm Change-Id: Id3135bda065efa9b4f3ab36972957fd00c05a53c Signed-off-by: Giacomo Travaglini --- src/arch/arm/tracers/ArmCapstone.py | 44 +++++++++++++++++ src/arch/arm/tracers/SConscript | 7 ++- src/arch/arm/tracers/capstone.cc | 75 +++++++++++++++++++++++++++++ src/arch/arm/tracers/capstone.hh | 69 ++++++++++++++++++++++++++ 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/arch/arm/tracers/ArmCapstone.py create mode 100644 src/arch/arm/tracers/capstone.cc create mode 100644 src/arch/arm/tracers/capstone.hh diff --git a/src/arch/arm/tracers/ArmCapstone.py b/src/arch/arm/tracers/ArmCapstone.py new file mode 100644 index 0000000000..7f1b6a9e8a --- /dev/null +++ b/src/arch/arm/tracers/ArmCapstone.py @@ -0,0 +1,44 @@ +# Copyright (c) 2023 Arm Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from m5.SimObject import SimObject +from m5.params import * +from m5.objects.Capstone import CapstoneDisassembler + + +class ArmCapstoneDisassembler(CapstoneDisassembler): + type = "ArmCapstoneDisassembler" + cxx_class = "gem5::trace::ArmCapstoneDisassembler" + cxx_header = "arch/arm/tracers/capstone.hh" diff --git a/src/arch/arm/tracers/SConscript b/src/arch/arm/tracers/SConscript index 15945a4ac4..ca012c5c2e 100644 --- a/src/arch/arm/tracers/SConscript +++ b/src/arch/arm/tracers/SConscript @@ -1,4 +1,4 @@ -# Copyright (c) 2018 ARM Limited +# Copyright (c) 2018, 2023 Arm Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -42,3 +42,8 @@ Source('tarmac_parser.cc', tags='arm isa') Source('tarmac_tracer.cc', tags='arm isa') Source('tarmac_record.cc', tags='arm isa') Source('tarmac_record_v8.cc', tags='arm isa') + +if env['CONF']['HAVE_CAPSTONE']: + SimObject('ArmCapstone.py', sim_objects=['ArmCapstoneDisassembler'], + tags=['capstone', 'arm isa']) + Source('capstone.cc', tags=['capstone', 'arm isa']) diff --git a/src/arch/arm/tracers/capstone.cc b/src/arch/arm/tracers/capstone.cc new file mode 100644 index 0000000000..469dc46568 --- /dev/null +++ b/src/arch/arm/tracers/capstone.cc @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/arm/tracers/capstone.hh" + +#include "arch/arm/insts/static_inst.hh" +#include "base/output.hh" + +namespace gem5 +{ + +namespace trace +{ + +using namespace ArmISA; + +ArmCapstoneDisassembler::ArmCapstoneDisassembler(const Params &p) + : CapstoneDisassembler(p) +{ + if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &arm64Handle) != CS_ERR_OK) + panic("Unable to open capstone for arm64 disassembly"); + + if (cs_open(CS_ARCH_ARM, CS_MODE_ARM, &armHandle) != CS_ERR_OK) + panic("Unable to open capstone for arm disassembly"); +} + +const csh* +ArmCapstoneDisassembler::currHandle(const PCStateBase &_pc) const +{ + auto pc = _pc.as(); + if (pc.aarch64()) { + return &arm64Handle; + } else { + auto mode = pc.thumb() ? CS_MODE_THUMB : CS_MODE_ARM; + cs_option(armHandle, CS_OPT_MODE, mode); + return &armHandle; + } +} + +} // namespace trace +} // namespace gem5 diff --git a/src/arch/arm/tracers/capstone.hh b/src/arch/arm/tracers/capstone.hh new file mode 100644 index 0000000000..929fbad6f5 --- /dev/null +++ b/src/arch/arm/tracers/capstone.hh @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ARM_TRACERS_CAPSTONE_HH__ +#define __ARCH_ARM_TRACERS_CAPSTONE_HH__ + +#include "cpu/capstone.hh" +#include "params/ArmCapstoneDisassembler.hh" + +namespace gem5 +{ + +class ThreadContext; + +namespace trace +{ + +class ArmCapstoneDisassembler : public CapstoneDisassembler +{ + public: + PARAMS(ArmCapstoneDisassembler); + ArmCapstoneDisassembler(const Params &p); + + protected: + const csh* currHandle(const PCStateBase &pc) const override; + + protected: + csh arm64Handle; + csh armHandle; +}; + +} // namespace trace +} // namespace gem5 + +#endif // __ARCH_ARM_TRACERS_CAPSTONE_HH__