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:
Boris Shingarov
2023-10-20 13:47:23 -04:00
committed by GitHub
21 changed files with 629 additions and 29 deletions

View 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"

View File

@@ -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'])

View 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

View 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__

View File

@@ -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)

View File

@@ -93,7 +93,6 @@ class TarmacBaseRecord : public InstRecord
bool taken;
Addr addr;
ArmISA::MachInst opcode;
std::string disassemble;
ISetState isetstate;
ArmISA::OperatingMode mode;
};

View File

@@ -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 &regQueue = tracer.regQueue;
const TarmacContext tarmCtx(
tracer,
thread,
staticInst->isMicroop()? macroStaticInst : staticInst,
*pc

View File

@@ -115,6 +115,9 @@ class TarmacTracerRecord : public TarmacBaseRecord
* 32 otherwise (ARM and BigThumb)
*/
uint8_t instSize;
/** Instruction disassembly */
std::string disassemble;
};
/** Register Entry */

View File

@@ -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
View 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

View File

@@ -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
View 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
View 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
View 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__

View File

@@ -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 << " : ";

View File

@@ -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);
}
};

View File

@@ -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()
{

View File

@@ -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

View File

@@ -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"
)

View File

@@ -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')

View File

@@ -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 &params)
: 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