misc: Integrate a Capstone Disassembler in gem5 (#494)
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 instruction 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/
This commit is contained in:
44
src/arch/arm/tracers/ArmCapstone.py
Normal file
44
src/arch/arm/tracers/ArmCapstone.py
Normal file
@@ -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"
|
||||
@@ -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'])
|
||||
|
||||
75
src/arch/arm/tracers/capstone.cc
Normal file
75
src/arch/arm/tracers/capstone.cc
Normal file
@@ -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<ArmISA::PCState>();
|
||||
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
|
||||
69
src/arch/arm/tracers/capstone.hh
Normal file
69
src/arch/arm/tracers/capstone.hh
Normal file
@@ -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__
|
||||
@@ -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)
|
||||
|
||||
@@ -93,7 +93,6 @@ class TarmacBaseRecord : public InstRecord
|
||||
bool taken;
|
||||
Addr addr;
|
||||
ArmISA::MachInst opcode;
|
||||
std::string disassemble;
|
||||
ISetState isetstate;
|
||||
ArmISA::OperatingMode mode;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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.tracer.disassemble(tarmCtx.staticInst, *tarmCtx.pc))
|
||||
{
|
||||
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++;
|
||||
@@ -332,6 +338,7 @@ TarmacTracerRecord::dump()
|
||||
auto ®Queue = tracer.regQueue;
|
||||
|
||||
const TarmacContext tarmCtx(
|
||||
tracer,
|
||||
thread,
|
||||
staticInst->isMicroop()? macroStaticInst : staticInst,
|
||||
*pc
|
||||
|
||||
@@ -115,6 +115,9 @@ class TarmacTracerRecord : public TarmacBaseRecord
|
||||
* 32 otherwise (ARM and BigThumb)
|
||||
*/
|
||||
uint8_t instSize;
|
||||
|
||||
/** Instruction disassembly */
|
||||
std::string disassemble;
|
||||
};
|
||||
|
||||
/** Register Entry */
|
||||
|
||||
@@ -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<PCStateBase> pc;
|
||||
|
||||
45
src/cpu/Capstone.py
Normal file
45
src/cpu/Capstone.py
Normal file
@@ -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
|
||||
@@ -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')
|
||||
|
||||
50
src/cpu/SConsopts
Normal file
50
src/cpu/SConsopts
Normal file
@@ -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 <capstone.h>
|
||||
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 <capstone/capstone.h> not found.\n"
|
||||
"This host has no capstone library installed.")
|
||||
90
src/cpu/capstone.cc
Normal file
90
src/cpu/capstone.cc
Normal file
@@ -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
|
||||
102
src/cpu/capstone.hh
Normal file
102
src/cpu/capstone.hh
Normal file
@@ -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 <capstone/capstone.h>
|
||||
|
||||
#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__
|
||||
@@ -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 << " : ";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user