This commit is contained in:
2026-03-23 12:11:07 +01:00
commit e64eb40b38
4573 changed files with 3117439 additions and 0 deletions

5
external/capstone/contrib/README vendored Normal file
View File

@@ -0,0 +1,5 @@
This directory contains contributions that do not belong to the core engine.
Code here might be helpful for those who want to integrate Capstone into
their own projects.
The license of these code was defined by their authors.

View File

@@ -0,0 +1,3 @@
This directory contains a sample project for using Capstone from a Windows
driver. Open cs_driver.sln with Visual Studio 2013 or newer and see cs_driver.c
for details.

View File

@@ -0,0 +1,49 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cs_driver", "cs_driver\cs_driver.vcxproj", "{F29A9424-0ECD-4FFE-9CB7-C844756373BB}"
ProjectSection(ProjectDependencies) = postProject
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B} = {FE197816-EF84-4E8D-B29D-E0A6BA2B144B}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capstone_static_winkernel", "..\..\msvc\capstone_static_winkernel\capstone_static_winkernel.vcxproj", "{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|Win32.ActiveCfg = Debug|Win32
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|Win32.Build.0 = Debug|Win32
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|Win32.Deploy.0 = Debug|Win32
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|x64.ActiveCfg = Debug|x64
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|x64.Build.0 = Debug|x64
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Debug|x64.Deploy.0 = Debug|x64
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|Win32.ActiveCfg = Release|Win32
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|Win32.Build.0 = Release|Win32
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|Win32.Deploy.0 = Release|Win32
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|x64.ActiveCfg = Release|x64
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|x64.Build.0 = Release|x64
{F29A9424-0ECD-4FFE-9CB7-C844756373BB}.Release|x64.Deploy.0 = Release|x64
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.ActiveCfg = Debug|Win32
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.Build.0 = Debug|Win32
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|Win32.Deploy.0 = Debug|Win32
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.ActiveCfg = Debug|x64
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.Build.0 = Debug|x64
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Debug|x64.Deploy.0 = Debug|x64
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.ActiveCfg = Release|Win32
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.Build.0 = Release|Win32
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|Win32.Deploy.0 = Release|Win32
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.ActiveCfg = Release|x64
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.Build.0 = Release|x64
{FE197816-EF84-4E8D-B29D-E0A6BA2B144B}.Release|x64.Deploy.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,99 @@
/* Capstone Driver */
/* By Satoshi Tanda <tanda.sat@gmail.com>, 2016 */
// Firstly, compile capstone_static_winkernel and
// generate capstone_static_winkernel.lib. It can be done by adding the
// capstone_static_winkernel project to your solution and compiling it first.
//
// Then, configure your driver project (cs_driver in this example) to locate to
// capstone.h and capstone_static_winkernel.lib. To do it, open project
// properties of the project and set Configuration to "All Configurations" and
// Platform to "All Platforms". Then, add the following entries:
// - C/C++ > General > Additional Include Directories
// - $(SolutionDir)capstone\include
// - Linker > Input > Additional Dependencies
// - $(OutDir)capstone_static_winkernel.lib
// - ntstrsafe.lib
//
// Note that ntstrsafe.lib is required to resolve __fltused indirectly used in
// Capstone.
#include <ntddk.h>
#include <capstone/capstone.h>
// 'conversion' : from function pointer 'type1' to data pointer 'type2'
#pragma warning(disable : 4054)
DRIVER_INITIALIZE DriverEntry;
static NTSTATUS cs_driver_hello();
// Driver entry point
EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath) {
printf("Entering DriverEntry()\n");
cs_driver_hello();
printf("Leaving DriverEntry()\n");
return STATUS_CANCELLED;
}
// Hello, Capstone!
static NTSTATUS cs_driver_hello() {
csh handle;
cs_insn *insn;
size_t count;
KFLOATING_SAVE float_save;
NTSTATUS status = STATUS_UNSUCCESSFUL;
// Any of Capstone APIs cannot be called at IRQL higher than DISPATCH_LEVEL
// since our malloc implementation based on ExAllocatePoolWithTag() is not able
// to allocate memory at higher IRQL than the DISPATCH_LEVEL level.
NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
// On a 32bit driver, KeSaveFloatingPointState() is required before using any
// Capstone function because Capstone can access to the MMX/x87 registers and
// 32bit Windows requires drivers to use KeSaveFloatingPointState() before and
// KeRestoreFloatingPointState() after accessing them. See "Using Floating
// Point or MMX in a WDM Driver" on MSDN for more details.
status = KeSaveFloatingPointState(&float_save);
if (!NT_SUCCESS(status)) {
return status;
}
// Do stuff just like user-mode. All functionalities are supported.
if (cs_open(CS_ARCH_X86, (sizeof(void *) == 4) ? CS_MODE_32 : CS_MODE_64,
&handle) != CS_ERR_OK) {
goto exit;
}
count = cs_disasm(handle, (uint8_t *)&cs_driver_hello, 0x80,
(uint64_t)&cs_driver_hello, 0, &insn);
if (count > 0) {
printf("cs_driver!cs_driver_hello:\n");
for (size_t j = 0; j < count; j++) {
printf("0x%p\t%s\t\t%s\n", (void *)(uintptr_t)insn[j].address,
insn[j].mnemonic, insn[j].op_str);
}
cs_free(insn, count);
}
cs_close(&handle);
exit:;
// Restores the nonvolatile floating-point context.
KeRestoreFloatingPointState(&float_save);
return status;
}
// printf()
_Use_decl_annotations_ int __cdecl printf(const char *_Format, ...) {
NTSTATUS status;
va_list args;
va_start(args, _Format);
status = vDbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_ERROR_LEVEL, _Format, args);
va_end(args);
return NT_SUCCESS(status);
}

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F29A9424-0ECD-4FFE-9CB7-C844756373BB}</ProjectGuid>
<TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration>Win8.1 Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
<RootNamespace>cs_driver</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows7</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>KMDF</DriverType>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WppScanConfigurationData Condition="'%(ClCompile. ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WppScanConfigurationData Condition="'%(ClCompile. ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WppScanConfigurationData Condition="'%(ClCompile. ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WppScanConfigurationData Condition="'%(ClCompile. ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<WppKernelMode>true</WppKernelMode>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>$(OutDir)capstone_static_winkernel.lib;ntstrsafe.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="cs_driver.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Driver Files">
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
<Extensions>inf;inv;inx;mof;mc;</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="cs_driver.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,468 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/* This code is used to build the static lookup table used inside the M68KDisassembler.c code
* To run this use the Makefile in the same directory
*/
typedef struct {
const char *name; /* handler function name */
uint16_t mask; /* mask on opcode */
uint16_t match; /* what to match after masking */
uint16_t ea_mask; /* what ea modes are allowed */
uint16_t mask2; /* mask the 2nd word */
uint16_t match2; /* what to match after masking */
} opcode_struct;
/* ======================================================================== */
/* ======================= INSTRUCTION TABLE BUILDER ====================== */
/* ======================================================================== */
/* EA Masks:
800 = data register direct
400 = address register direct
200 = address register indirect
100 = ARI postincrement
80 = ARI pre-decrement
40 = ARI displacement
20 = ARI index
10 = absolute short
8 = absolute long
4 = immediate / sr
2 = pc displacement
1 = pc idx
*/
static opcode_struct g_opcode_info[] = {
/* opcode handler mask match ea_mask mask2 match2*/
{"d68000_1010" , 0xf000, 0xa000, 0x000},
{"d68000_1111" , 0xf000, 0xf000, 0x000},
{"d68000_abcd_rr" , 0xf1f8, 0xc100, 0x000},
{"d68000_abcd_mm" , 0xf1f8, 0xc108, 0x000},
{"d68000_add_er_8" , 0xf1c0, 0xd000, 0xbff},
{"d68000_add_er_16" , 0xf1c0, 0xd040, 0xfff},
{"d68000_add_er_32" , 0xf1c0, 0xd080, 0xfff},
{"d68000_add_re_8" , 0xf1c0, 0xd100, 0x3f8},
{"d68000_add_re_16" , 0xf1c0, 0xd140, 0x3f8},
{"d68000_add_re_32" , 0xf1c0, 0xd180, 0x3f8},
{"d68000_adda_16" , 0xf1c0, 0xd0c0, 0xfff},
{"d68000_adda_32" , 0xf1c0, 0xd1c0, 0xfff},
{"d68000_addi_8" , 0xffc0, 0x0600, 0xbf8},
{"d68000_addi_16" , 0xffc0, 0x0640, 0xbf8},
{"d68000_addi_32" , 0xffc0, 0x0680, 0xbf8},
{"d68000_addq_8" , 0xf1c0, 0x5000, 0xbf8},
{"d68000_addq_16" , 0xf1c0, 0x5040, 0xff8},
{"d68000_addq_32" , 0xf1c0, 0x5080, 0xff8},
{"d68000_addx_rr_8" , 0xf1f8, 0xd100, 0x000},
{"d68000_addx_rr_16" , 0xf1f8, 0xd140, 0x000},
{"d68000_addx_rr_32" , 0xf1f8, 0xd180, 0x000},
{"d68000_addx_mm_8" , 0xf1f8, 0xd108, 0x000},
{"d68000_addx_mm_16" , 0xf1f8, 0xd148, 0x000},
{"d68000_addx_mm_32" , 0xf1f8, 0xd188, 0x000},
{"d68000_and_er_8" , 0xf1c0, 0xc000, 0xbff},
{"d68000_and_er_16" , 0xf1c0, 0xc040, 0xbff},
{"d68000_and_er_32" , 0xf1c0, 0xc080, 0xbff},
{"d68000_and_re_8" , 0xf1c0, 0xc100, 0x3f8},
{"d68000_and_re_16" , 0xf1c0, 0xc140, 0x3f8},
{"d68000_and_re_32" , 0xf1c0, 0xc180, 0x3f8},
{"d68000_andi_to_ccr" , 0xffff, 0x023c, 0x000, 0xff00, 0x0000},
{"d68000_andi_to_sr" , 0xffff, 0x027c, 0x000},
{"d68000_andi_8" , 0xffc0, 0x0200, 0xbf8},
{"d68000_andi_16" , 0xffc0, 0x0240, 0xbf8},
{"d68000_andi_32" , 0xffc0, 0x0280, 0xbf8},
{"d68000_asr_s_8" , 0xf1f8, 0xe000, 0x000},
{"d68000_asr_s_16" , 0xf1f8, 0xe040, 0x000},
{"d68000_asr_s_32" , 0xf1f8, 0xe080, 0x000},
{"d68000_asr_r_8" , 0xf1f8, 0xe020, 0x000},
{"d68000_asr_r_16" , 0xf1f8, 0xe060, 0x000},
{"d68000_asr_r_32" , 0xf1f8, 0xe0a0, 0x000},
{"d68000_asr_ea" , 0xffc0, 0xe0c0, 0x3f8},
{"d68000_asl_s_8" , 0xf1f8, 0xe100, 0x000},
{"d68000_asl_s_16" , 0xf1f8, 0xe140, 0x000},
{"d68000_asl_s_32" , 0xf1f8, 0xe180, 0x000},
{"d68000_asl_r_8" , 0xf1f8, 0xe120, 0x000},
{"d68000_asl_r_16" , 0xf1f8, 0xe160, 0x000},
{"d68000_asl_r_32" , 0xf1f8, 0xe1a0, 0x000},
{"d68000_asl_ea" , 0xffc0, 0xe1c0, 0x3f8},
{"d68000_bcc_8" , 0xf000, 0x6000, 0x000},
{"d68000_bcc_16" , 0xf0ff, 0x6000, 0x000},
{"d68020_bcc_32" , 0xf0ff, 0x60ff, 0x000},
{"d68000_bchg_r" , 0xf1c0, 0x0140, 0xbf8},
{"d68000_bchg_s" , 0xffc0, 0x0840, 0xbf8, 0xff00, 0x0000},
{"d68000_bclr_r" , 0xf1c0, 0x0180, 0xbf8},
{"d68000_bclr_s" , 0xffc0, 0x0880, 0xbf8, 0xff00, 0x0000},
{"d68020_bfchg" , 0xffc0, 0xeac0, 0xa78, 0xf000, 0x0000},
{"d68020_bfclr" , 0xffc0, 0xecc0, 0xa78, 0xf000, 0x0000},
{"d68020_bfexts" , 0xffc0, 0xebc0, 0xa7b, 0x8000, 0x0000},
{"d68020_bfextu" , 0xffc0, 0xe9c0, 0xa7b, 0x8000, 0x0000},
{"d68020_bfffo" , 0xffc0, 0xedc0, 0xa7b, 0x8000, 0x0000},
{"d68020_bfins" , 0xffc0, 0xefc0, 0xa78, 0x8000, 0x0000},
{"d68020_bfset" , 0xffc0, 0xeec0, 0xa78, 0xf000, 0x0000},
{"d68020_bftst" , 0xffc0, 0xe8c0, 0xa7b, 0xf000, 0x0000},
{"d68010_bkpt" , 0xfff8, 0x4848, 0x000},
{"d68000_bra_8" , 0xff00, 0x6000, 0x000},
{"d68000_bra_16" , 0xffff, 0x6000, 0x000},
{"d68020_bra_32" , 0xffff, 0x60ff, 0x000},
{"d68000_bset_r" , 0xf1c0, 0x01c0, 0xbf8},
{"d68000_bset_s" , 0xffc0, 0x08c0, 0xbf8, 0xfe00, 0x0000 },
{"d68000_bsr_8" , 0xff00, 0x6100, 0x000},
{"d68000_bsr_16" , 0xffff, 0x6100, 0x000},
{"d68020_bsr_32" , 0xffff, 0x61ff, 0x000},
{"d68000_btst_r" , 0xf1c0, 0x0100, 0xbff},
{"d68000_btst_s" , 0xffc0, 0x0800, 0xbfb, 0xff00, 0x0000},
{"d68020_callm" , 0xffc0, 0x06c0, 0x27b, 0xff00, 0x0000},
{"d68020_cas_8" , 0xffc0, 0x0ac0, 0x3f8, 0xfe38, 0x0000},
{"d68020_cas_16" , 0xffc0, 0x0cc0, 0x3f8, 0xfe38, 0x0000},
{"d68020_cas_32" , 0xffc0, 0x0ec0, 0x3f8, 0xfe38, 0x0000},
{"d68020_cas2_16" , 0xffff, 0x0cfc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
{"d68020_cas2_32" , 0xffff, 0x0efc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
{"d68000_chk_16" , 0xf1c0, 0x4180, 0xbff},
{"d68020_chk_32" , 0xf1c0, 0x4100, 0xbff},
{"d68020_chk2_cmp2_8" , 0xffc0, 0x00c0, 0x27b, 0x07ff, 0x0000},
{"d68020_chk2_cmp2_16" , 0xffc0, 0x02c0, 0x27b, 0x07ff, 0x0000},
{"d68020_chk2_cmp2_32" , 0xffc0, 0x04c0, 0x27b, 0x07ff, 0x0000},
{"d68040_cinv" , 0xff20, 0xf400, 0x000},
{"d68000_clr_8" , 0xffc0, 0x4200, 0xbf8},
{"d68000_clr_16" , 0xffc0, 0x4240, 0xbf8},
{"d68000_clr_32" , 0xffc0, 0x4280, 0xbf8},
{"d68000_cmp_8" , 0xf1c0, 0xb000, 0xbff},
{"d68000_cmp_16" , 0xf1c0, 0xb040, 0xfff},
{"d68000_cmp_32" , 0xf1c0, 0xb080, 0xfff},
{"d68000_cmpa_16" , 0xf1c0, 0xb0c0, 0xfff},
{"d68000_cmpa_32" , 0xf1c0, 0xb1c0, 0xfff},
{"d68000_cmpi_8" , 0xffc0, 0x0c00, 0xbf8},
{"d68020_cmpi_pcdi_8" , 0xffff, 0x0c3a, 0x000},
{"d68020_cmpi_pcix_8" , 0xffff, 0x0c3b, 0x000},
{"d68000_cmpi_16" , 0xffc0, 0x0c40, 0xbf8},
{"d68020_cmpi_pcdi_16" , 0xffff, 0x0c7a, 0x000},
{"d68020_cmpi_pcix_16" , 0xffff, 0x0c7b, 0x000},
{"d68000_cmpi_32" , 0xffc0, 0x0c80, 0xbf8},
{"d68020_cmpi_pcdi_32" , 0xffff, 0x0cba, 0x000},
{"d68020_cmpi_pcix_32" , 0xffff, 0x0cbb, 0x000},
{"d68000_cmpm_8" , 0xf1f8, 0xb108, 0x000},
{"d68000_cmpm_16" , 0xf1f8, 0xb148, 0x000},
{"d68000_cmpm_32" , 0xf1f8, 0xb188, 0x000},
{"d68020_cpbcc_16" , 0xf1c0, 0xf080, 0x000},
{"d68020_cpbcc_32" , 0xf1c0, 0xf0c0, 0x000},
{"d68020_cpdbcc" , 0xf1f8, 0xf048, 0x000},
{"d68020_cpgen" , 0xf1c0, 0xf000, 0x000},
{"d68020_cprestore" , 0xf1c0, 0xf140, 0x37f},
{"d68020_cpsave" , 0xf1c0, 0xf100, 0x2f8},
{"d68020_cpscc" , 0xf1c0, 0xf040, 0xbf8},
{"d68020_cptrapcc_0" , 0xf1ff, 0xf07c, 0x000},
{"d68020_cptrapcc_16" , 0xf1ff, 0xf07a, 0x000},
{"d68020_cptrapcc_32" , 0xf1ff, 0xf07b, 0x000},
{"d68040_cpush" , 0xff20, 0xf420, 0x000},
{"d68000_dbcc" , 0xf0f8, 0x50c8, 0x000},
{"d68000_dbra" , 0xfff8, 0x51c8, 0x000},
{"d68000_divs" , 0xf1c0, 0x81c0, 0xbff},
{"d68000_divu" , 0xf1c0, 0x80c0, 0xbff},
{"d68020_divl" , 0xff80, 0x4c00, 0xbff, 0x83f8, 0x0000},
{"d68000_eor_8" , 0xf1c0, 0xb100, 0xbf8},
{"d68000_eor_16" , 0xf1c0, 0xb140, 0xbf8},
{"d68000_eor_32" , 0xf1c0, 0xb180, 0xbf8},
{"d68000_eori_to_ccr" , 0xffff, 0x0a3c, 0x000, 0xff00, 0x0000},
{"d68000_eori_to_sr" , 0xffff, 0x0a7c, 0x000},
{"d68000_eori_8" , 0xffc0, 0x0a00, 0xbf8},
{"d68000_eori_16" , 0xffc0, 0x0a40, 0xbf8},
{"d68000_eori_32" , 0xffc0, 0x0a80, 0xbf8},
{"d68000_exg_dd" , 0xf1f8, 0xc140, 0x000},
{"d68000_exg_aa" , 0xf1f8, 0xc148, 0x000},
{"d68000_exg_da" , 0xf1f8, 0xc188, 0x000},
{"d68020_extb_32" , 0xfff8, 0x49c0, 0x000},
{"d68000_ext_16" , 0xfff8, 0x4880, 0x000},
{"d68000_ext_32" , 0xfff8, 0x48c0, 0x000},
{"d68000_illegal" , 0xffff, 0x4afc, 0x000},
{"d68000_jmp" , 0xffc0, 0x4ec0, 0x27b},
{"d68000_jsr" , 0xffc0, 0x4e80, 0x27b},
{"d68000_lea" , 0xf1c0, 0x41c0, 0x27b},
{"d68000_link_16" , 0xfff8, 0x4e50, 0x000},
{"d68020_link_32" , 0xfff8, 0x4808, 0x000},
{"d68000_lsr_s_8" , 0xf1f8, 0xe008, 0x000},
{"d68000_lsr_s_16" , 0xf1f8, 0xe048, 0x000},
{"d68000_lsr_s_32" , 0xf1f8, 0xe088, 0x000},
{"d68000_lsr_r_8" , 0xf1f8, 0xe028, 0x000},
{"d68000_lsr_r_16" , 0xf1f8, 0xe068, 0x000},
{"d68000_lsr_r_32" , 0xf1f8, 0xe0a8, 0x000},
{"d68000_lsr_ea" , 0xffc0, 0xe2c0, 0x3f8},
{"d68000_lsl_s_8" , 0xf1f8, 0xe108, 0x000},
{"d68000_lsl_s_16" , 0xf1f8, 0xe148, 0x000},
{"d68000_lsl_s_32" , 0xf1f8, 0xe188, 0x000},
{"d68000_lsl_r_8" , 0xf1f8, 0xe128, 0x000},
{"d68000_lsl_r_16" , 0xf1f8, 0xe168, 0x000},
{"d68000_lsl_r_32" , 0xf1f8, 0xe1a8, 0x000},
{"d68000_lsl_ea" , 0xffc0, 0xe3c0, 0x3f8},
{"d68000_move_8" , 0xf000, 0x1000, 0xbff},
{"d68000_move_16" , 0xf000, 0x3000, 0xfff},
{"d68000_move_32" , 0xf000, 0x2000, 0xfff},
{"d68000_movea_16" , 0xf1c0, 0x3040, 0xfff},
{"d68000_movea_32" , 0xf1c0, 0x2040, 0xfff},
{"d68000_move_to_ccr" , 0xffc0, 0x44c0, 0xbff},
{"d68010_move_fr_ccr" , 0xffc0, 0x42c0, 0xbf8},
{"d68000_move_to_sr" , 0xffc0, 0x46c0, 0xbff},
{"d68000_move_fr_sr" , 0xffc0, 0x40c0, 0xbf8},
{"d68000_move_to_usp" , 0xfff8, 0x4e60, 0x000},
{"d68000_move_fr_usp" , 0xfff8, 0x4e68, 0x000},
{"d68010_movec" , 0xfffe, 0x4e7a, 0x000},
{"d68000_movem_pd_16" , 0xfff8, 0x48a0, 0x000},
{"d68000_movem_pd_32" , 0xfff8, 0x48e0, 0x000},
{"d68000_movem_re_16" , 0xffc0, 0x4880, 0x2f8},
{"d68000_movem_re_32" , 0xffc0, 0x48c0, 0x2f8},
{"d68000_movem_er_16" , 0xffc0, 0x4c80, 0x37b},
{"d68000_movem_er_32" , 0xffc0, 0x4cc0, 0x37b},
{"d68000_movep_er_16" , 0xf1f8, 0x0108, 0x000},
{"d68000_movep_er_32" , 0xf1f8, 0x0148, 0x000},
{"d68000_movep_re_16" , 0xf1f8, 0x0188, 0x000},
{"d68000_movep_re_32" , 0xf1f8, 0x01c8, 0x000},
{"d68010_moves_8" , 0xffc0, 0x0e00, 0x3f8, 0x07ff, 0x0000},
{"d68010_moves_16" , 0xffc0, 0x0e40, 0x3f8, 0x07ff, 0x0000},
{"d68010_moves_32" , 0xffc0, 0x0e80, 0x3f8, 0x07ff, 0x0000},
{"d68000_moveq" , 0xf100, 0x7000, 0x000},
{"d68040_move16_pi_pi" , 0xfff8, 0xf620, 0x000, 0x8fff, 0x8000},
{"d68040_move16_pi_al" , 0xfff8, 0xf600, 0x000},
{"d68040_move16_al_pi" , 0xfff8, 0xf608, 0x000},
{"d68040_move16_ai_al" , 0xfff8, 0xf610, 0x000},
{"d68040_move16_al_ai" , 0xfff8, 0xf618, 0x000},
{"d68000_muls" , 0xf1c0, 0xc1c0, 0xbff},
{"d68000_mulu" , 0xf1c0, 0xc0c0, 0xbff},
{"d68020_mull" , 0xffc0, 0x4c00, 0xbff, 0x83f8, 0x0000},
{"d68000_nbcd" , 0xffc0, 0x4800, 0xbf8},
{"d68000_neg_8" , 0xffc0, 0x4400, 0xbf8},
{"d68000_neg_16" , 0xffc0, 0x4440, 0xbf8},
{"d68000_neg_32" , 0xffc0, 0x4480, 0xbf8},
{"d68000_negx_8" , 0xffc0, 0x4000, 0xbf8},
{"d68000_negx_16" , 0xffc0, 0x4040, 0xbf8},
{"d68000_negx_32" , 0xffc0, 0x4080, 0xbf8},
{"d68000_nop" , 0xffff, 0x4e71, 0x000},
{"d68000_not_8" , 0xffc0, 0x4600, 0xbf8},
{"d68000_not_16" , 0xffc0, 0x4640, 0xbf8},
{"d68000_not_32" , 0xffc0, 0x4680, 0xbf8},
{"d68000_or_er_8" , 0xf1c0, 0x8000, 0xbff},
{"d68000_or_er_16" , 0xf1c0, 0x8040, 0xbff},
{"d68000_or_er_32" , 0xf1c0, 0x8080, 0xbff},
{"d68000_or_re_8" , 0xf1c0, 0x8100, 0x3f8},
{"d68000_or_re_16" , 0xf1c0, 0x8140, 0x3f8},
{"d68000_or_re_32" , 0xf1c0, 0x8180, 0x3f8},
{"d68000_ori_to_ccr" , 0xffff, 0x003c, 0x000, 0xff00, 0x0000},
{"d68000_ori_to_sr" , 0xffff, 0x007c, 0x000},
{"d68000_ori_8" , 0xffc0, 0x0000, 0xbf8},
{"d68000_ori_16" , 0xffc0, 0x0040, 0xbf8},
{"d68000_ori_32" , 0xffc0, 0x0080, 0xbf8},
{"d68020_pack_rr" , 0xf1f8, 0x8140, 0x000},
{"d68020_pack_mm" , 0xf1f8, 0x8148, 0x000},
{"d68000_pea" , 0xffc0, 0x4840, 0x27b},
{"d68000_reset" , 0xffff, 0x4e70, 0x000},
{"d68000_ror_s_8" , 0xf1f8, 0xe018, 0x000},
{"d68000_ror_s_16" , 0xf1f8, 0xe058, 0x000},
{"d68000_ror_s_32" , 0xf1f8, 0xe098, 0x000},
{"d68000_ror_r_8" , 0xf1f8, 0xe038, 0x000},
{"d68000_ror_r_16" , 0xf1f8, 0xe078, 0x000},
{"d68000_ror_r_32" , 0xf1f8, 0xe0b8, 0x000},
{"d68000_ror_ea" , 0xffc0, 0xe6c0, 0x3f8},
{"d68000_rol_s_8" , 0xf1f8, 0xe118, 0x000},
{"d68000_rol_s_16" , 0xf1f8, 0xe158, 0x000},
{"d68000_rol_s_32" , 0xf1f8, 0xe198, 0x000},
{"d68000_rol_r_8" , 0xf1f8, 0xe138, 0x000},
{"d68000_rol_r_16" , 0xf1f8, 0xe178, 0x000},
{"d68000_rol_r_32" , 0xf1f8, 0xe1b8, 0x000},
{"d68000_rol_ea" , 0xffc0, 0xe7c0, 0x3f8},
{"d68000_roxr_s_8" , 0xf1f8, 0xe010, 0x000},
{"d68000_roxr_s_16" , 0xf1f8, 0xe050, 0x000},
{"d68000_roxr_s_32" , 0xf1f8, 0xe090, 0x000},
{"d68000_roxr_r_8" , 0xf1f8, 0xe030, 0x000},
{"d68000_roxr_r_16" , 0xf1f8, 0xe070, 0x000},
{"d68000_roxr_r_32" , 0xf1f8, 0xe0b0, 0x000},
{"d68000_roxr_ea" , 0xffc0, 0xe4c0, 0x3f8},
{"d68000_roxl_s_8" , 0xf1f8, 0xe110, 0x000},
{"d68000_roxl_s_16" , 0xf1f8, 0xe150, 0x000},
{"d68000_roxl_s_32" , 0xf1f8, 0xe190, 0x000},
{"d68000_roxl_r_8" , 0xf1f8, 0xe130, 0x000},
{"d68000_roxl_r_16" , 0xf1f8, 0xe170, 0x000},
{"d68000_roxl_r_32" , 0xf1f8, 0xe1b0, 0x000},
{"d68000_roxl_ea" , 0xffc0, 0xe5c0, 0x3f8},
{"d68010_rtd" , 0xffff, 0x4e74, 0x000},
{"d68000_rte" , 0xffff, 0x4e73, 0x000},
{"d68020_rtm" , 0xfff0, 0x06c0, 0x000},
{"d68000_rtr" , 0xffff, 0x4e77, 0x000},
{"d68000_rts" , 0xffff, 0x4e75, 0x000},
{"d68000_sbcd_rr" , 0xf1f8, 0x8100, 0x000},
{"d68000_sbcd_mm" , 0xf1f8, 0x8108, 0x000},
{"d68000_scc" , 0xf0c0, 0x50c0, 0xbf8},
{"d68000_stop" , 0xffff, 0x4e72, 0x000},
{"d68000_sub_er_8" , 0xf1c0, 0x9000, 0xbff},
{"d68000_sub_er_16" , 0xf1c0, 0x9040, 0xfff},
{"d68000_sub_er_32" , 0xf1c0, 0x9080, 0xfff},
{"d68000_sub_re_8" , 0xf1c0, 0x9100, 0x3f8},
{"d68000_sub_re_16" , 0xf1c0, 0x9140, 0x3f8},
{"d68000_sub_re_32" , 0xf1c0, 0x9180, 0x3f8},
{"d68000_suba_16" , 0xf1c0, 0x90c0, 0xfff},
{"d68000_suba_32" , 0xf1c0, 0x91c0, 0xfff},
{"d68000_subi_8" , 0xffc0, 0x0400, 0xbf8},
{"d68000_subi_16" , 0xffc0, 0x0440, 0xbf8},
{"d68000_subi_32" , 0xffc0, 0x0480, 0xbf8},
{"d68000_subq_8" , 0xf1c0, 0x5100, 0xbf8},
{"d68000_subq_16" , 0xf1c0, 0x5140, 0xff8},
{"d68000_subq_32" , 0xf1c0, 0x5180, 0xff8},
{"d68000_subx_rr_8" , 0xf1f8, 0x9100, 0x000},
{"d68000_subx_rr_16" , 0xf1f8, 0x9140, 0x000},
{"d68000_subx_rr_32" , 0xf1f8, 0x9180, 0x000},
{"d68000_subx_mm_8" , 0xf1f8, 0x9108, 0x000},
{"d68000_subx_mm_16" , 0xf1f8, 0x9148, 0x000},
{"d68000_subx_mm_32" , 0xf1f8, 0x9188, 0x000},
{"d68000_swap" , 0xfff8, 0x4840, 0x000},
{"d68000_tas" , 0xffc0, 0x4ac0, 0xbf8},
{"d68000_trap" , 0xfff0, 0x4e40, 0x000},
{"d68020_trapcc_0" , 0xf0ff, 0x50fc, 0x000},
{"d68020_trapcc_16" , 0xf0ff, 0x50fa, 0x000},
{"d68020_trapcc_32" , 0xf0ff, 0x50fb, 0x000},
{"d68000_trapv" , 0xffff, 0x4e76, 0x000},
{"d68000_tst_8" , 0xffc0, 0x4a00, 0xbf8},
{"d68020_tst_pcdi_8" , 0xffff, 0x4a3a, 0x000},
{"d68020_tst_pcix_8" , 0xffff, 0x4a3b, 0x000},
{"d68020_tst_i_8" , 0xffff, 0x4a3c, 0x000},
{"d68000_tst_16" , 0xffc0, 0x4a40, 0xbf8},
{"d68020_tst_a_16" , 0xfff8, 0x4a48, 0x000},
{"d68020_tst_pcdi_16" , 0xffff, 0x4a7a, 0x000},
{"d68020_tst_pcix_16" , 0xffff, 0x4a7b, 0x000},
{"d68020_tst_i_16" , 0xffff, 0x4a7c, 0x000},
{"d68000_tst_32" , 0xffc0, 0x4a80, 0xbf8},
{"d68020_tst_a_32" , 0xfff8, 0x4a88, 0x000},
{"d68020_tst_pcdi_32" , 0xffff, 0x4aba, 0x000},
{"d68020_tst_pcix_32" , 0xffff, 0x4abb, 0x000},
{"d68020_tst_i_32" , 0xffff, 0x4abc, 0x000},
{"d68000_unlk" , 0xfff8, 0x4e58, 0x000},
{"d68020_unpk_rr" , 0xf1f8, 0x8180, 0x000},
{"d68020_unpk_mm" , 0xf1f8, 0x8188, 0x000},
{0, 0, 0, 0}
};
/* Check if opcode is using a valid ea mode */
static int valid_ea(unsigned int opcode, unsigned int mask)
{
if (mask == 0)
return 1;
switch(opcode & 0x3f) {
case 0x00: case 0x01: case 0x02: case 0x03:
case 0x04: case 0x05: case 0x06: case 0x07:
return (mask & 0x800) != 0;
case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
return (mask & 0x400) != 0;
case 0x10: case 0x11: case 0x12: case 0x13:
case 0x14: case 0x15: case 0x16: case 0x17:
return (mask & 0x200) != 0;
case 0x18: case 0x19: case 0x1a: case 0x1b:
case 0x1c: case 0x1d: case 0x1e: case 0x1f:
return (mask & 0x100) != 0;
case 0x20: case 0x21: case 0x22: case 0x23:
case 0x24: case 0x25: case 0x26: case 0x27:
return (mask & 0x080) != 0;
case 0x28: case 0x29: case 0x2a: case 0x2b:
case 0x2c: case 0x2d: case 0x2e: case 0x2f:
return (mask & 0x040) != 0;
case 0x30: case 0x31: case 0x32: case 0x33:
case 0x34: case 0x35: case 0x36: case 0x37:
return (mask & 0x020) != 0;
case 0x38:
return (mask & 0x010) != 0;
case 0x39:
return (mask & 0x008) != 0;
case 0x3a:
return (mask & 0x002) != 0;
case 0x3b:
return (mask & 0x001) != 0;
case 0x3c:
return (mask & 0x004) != 0;
}
return 0;
}
#ifndef DECL_SPEC
#ifdef _MSC_VER
#define DECL_SPEC __cdecl
#else
#define DECL_SPEC
#endif // _MSC_VER
#endif // DECL_SPEC
/* Used by qsort */
static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr)
{
unsigned int a = ((const opcode_struct*)aptr)->mask;
unsigned int b = ((const opcode_struct*)bptr)->mask;
a = ((a & 0xAAAA) >> 1) + (a & 0x5555);
a = ((a & 0xCCCC) >> 2) + (a & 0x3333);
a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);
a = ((a & 0xFF00) >> 8) + (a & 0x00FF);
b = ((b & 0xAAAA) >> 1) + (b & 0x5555);
b = ((b & 0xCCCC) >> 2) + (b & 0x3333);
b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F);
b = ((b & 0xFF00) >> 8) + (b & 0x00FF);
return b - a; /* reversed to get greatest to least sorting */
}
/* build the opcode handler jump table */
static void build_opcode_table(void)
{
unsigned int i;
unsigned int opcode;
opcode_struct* ostruct;
unsigned int opcode_info_length = 0;
const unsigned int total_count = 0x10000;
for(ostruct = g_opcode_info;ostruct->name != 0;ostruct++)
opcode_info_length++;
qsort((void *)g_opcode_info, opcode_info_length, sizeof(g_opcode_info[0]), compare_nof_true_bits);
printf("/* This table is auto-generated. DO NOT MANUALLY EDIT! Look in M68KInstructionTblGen.c for more info */\n");
printf("static const instruction_struct g_instruction_table[] = {\n");
for(i=0;i<0x10000;i++) {
const char *name = "d68000_invalid";
uint16_t word2_mask = 0;
uint16_t word2_match = 0;
opcode = i;
/* search through opcode info for a match */
for(ostruct = g_opcode_info;ostruct->name != 0;ostruct++) {
/* match opcode mask and allowed ea modes */
if ((opcode & ostruct->mask) == ostruct->match) {
/* Handle destination ea for move instructions */
if ((!strcmp(ostruct->name, "d68000_move_8") ||
!strcmp(ostruct->name, "d68000_move_16") ||
!strcmp(ostruct->name, "d68000_move_32")) &&
!valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8))
continue;
if (valid_ea(opcode, ostruct->ea_mask)) {
name = ostruct->name;
word2_mask = ostruct->mask2;
word2_match = ostruct->match2;
break;
}
}
}
// Handle so the last entry won't have a , at the end
if (i != total_count - 1) {
printf("\t{ %s, 0x%x, 0x%x },\n", name, word2_mask, word2_match);
} else {
printf("\t{ %s, 0x%x, 0x%x }\n", name, word2_mask, word2_match);
}
}
printf("};\n\n");
}
int main() {
build_opcode_table();
return 0;
}

View File

@@ -0,0 +1,15 @@
CC=gcc
ODIR=obj
TBL_GEN=tbl_gen
INC_FILE=../../arch/M68K/M68KInstructionTable.inc
gen_inc: $(TBL_GEN)
./$(TBL_GEN) > $(INC_FILE)
tbl_gen: M68KInstructionTblGen.c
$(CC) -O3 M68KInstructionTblGen.c -o $(TBL_GEN)
.PHONY: clean
clean:
rm $(TBL_GEN)

View File

@@ -0,0 +1,425 @@
#!/usr/bin/env python3
import sys
import bitstring
from capstone import *
from capstone.m68k import *
#
# Objdump with the same output as his binary cousin
#
TODO = """
TODO :
o need more testing on M68K_AM_*_DISP
o cleanup, etc ...
"""
objdump_cmd_example = 'm68k-atari-mint-objdump -b binary -D -mm68k --adjust-vma 0x30664 u/m68k.bin'
objdump_dumpheader_fmt = """
%s: file format binary
Disassembly of section .data:
%08x <.data>:"""
M68000_CODE = b"\x04\x40\x00\x40"
all_tests = (
(CS_ARCH_M68K, CS_MODE_BIG_ENDIAN | CS_MODE_M68K_060, M68000_CODE, "M68060-32 (Big-endian)"),
)
def dump_bytes(b, len):
str = ''
i = 0
while i < len:
str += format("%02x%02x " % (b[i], b[i+1]))
i += 2
return str[:-1]
def dump_op_reg(insn, op_reg):
if op_reg == M68K_REG_A7:
return "%sp"
if op_reg == M68K_REG_A6:
return "%fp"
return '%' + insn.reg_name(op_reg)
def s8(value):
return bitstring.Bits(uint=value, length=8).unpack('int')[0]
def s16(value):
return bitstring.Bits(uint=value, length=16).unpack('int')[0]
def extsign8(value):
if value & 0x80:
return 0xffffffffffffff00 + value
return value
def extsign1616(value):
if value & 0x8000:
return 0xffff0000 + value
return value
def extsign1632(value):
if value & 0x8000:
return 0xffffffffffff0000 + value
return value
def printRegbitsRange(buffer, data, prefix):
str = ''
first = 0
run_length = 0
i = 0
while i < 8:
if (data & (1 << i)):
first = i
run_length = 0
while (i < 7 and (data & (1 << (i + 1)))):
i += 1
run_length += 1
if len(buffer) or len(str):
str += "/"
str += format("%%%s%d" % (prefix, first))
if run_length > 0:
str += format("-%%%s%d" % (prefix, first + run_length))
i += 1
return str
def registerBits(op):
str = ''
data = op.register_bits
str += printRegbitsRange(str, data & 0xff, "d")
str += printRegbitsRange(str, (data >> 8) & 0xff, "a")
str += printRegbitsRange(str, (data >> 16) & 0xff, "fp")
return str
def dump_op_ea(insn, op):
s_spacing = " "
map_index_size_str = { 0: 'w', 1 : 'l' }
str = ''
if op.address_mode == M68K_AM_NONE:
if op.type == M68K_OP_REG_BITS:
return registerBits(op)
if op.type == M68K_OP_REG_PAIR:
return registerPair(op)
if op.type == M68K_OP_REG:
return dump_op_reg(insn, op.reg)
if op.address_mode == M68K_AM_REG_DIRECT_DATA:
return dump_op_reg(insn, op.reg)
if op.address_mode == M68K_AM_REG_DIRECT_ADDR:
return dump_op_reg(insn, op.reg) + "@"
if op.address_mode == M68K_AM_REGI_ADDR:
return dump_op_reg(insn, op.reg) + "@"
if op.address_mode == M68K_AM_REGI_ADDR_POST_INC:
return dump_op_reg(insn, op.reg) + "@+"
if op.address_mode == M68K_AM_REGI_ADDR_PRE_DEC:
return dump_op_reg(insn, op.reg) + "@-"
if op.address_mode == M68K_AM_REGI_ADDR_DISP:
# str = dump_op_reg(insn, op.mem.base_reg - M68K_REG_A0 + 1) #double check and fixme '+1' : 02af 899f 2622
str = dump_op_reg(insn, op.mem.base_reg)
if op.mem.disp:
str += format("@(%d)" % s16(op.mem.disp))
return str
if op.address_mode == M68K_AM_PCI_DISP:
return format("%%pc@(0x%x)" % ( extsign1616(op.mem.disp + 2)))
if op.address_mode == M68K_AM_ABSOLUTE_DATA_SHORT:
return format("0x%x" % (extsign1616(op.imm & 0xffff)))
if op.address_mode == M68K_AM_ABSOLUTE_DATA_LONG:
return format("0x%x" % (op.imm & 0xffffffff))
if op.address_mode == M68K_AM_IMMEDIATE:
if insn.op_size.type == M68K_SIZE_TYPE_FPU:
map_fpu_size_str = { M68K_FPU_SIZE_SINGLE : op.simm, M68K_FPU_SIZE_DOUBLE : op.dimm }
return format("#%f" % (insn.op_size.fpu_size[map_fpu_size_str]))
return format("#$%x" % (op.imm))
if op.address_mode in [ M68K_AM_PCI_INDEX_8_BIT_DISP, M68K_AM_AREGI_INDEX_8_BIT_DISP ]:
disp = op.mem.disp
if op.register_bits == 2:
disp = extsign8(op.mem.disp)
if op.register_bits == 4:
disp = extsign1632(op.mem.disp)
str = dump_op_reg(insn, op.mem.base_reg) + "@(" + "{0:016x}".format(disp) + "," + dump_op_reg(insn, op.mem.index_reg) + ":" + map_index_size_str[op.mem.index_size]
if op.register_bits:
str += format(":%u" % (op.register_bits))
return str + ")"
if op.address_mode in [ M68K_AM_PCI_INDEX_BASE_DISP, M68K_AM_AREGI_INDEX_BASE_DISP ]:
str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg) ))
str += format("@(%016x)@(%016x" % (extsign1632(op.mem.in_disp), extsign1632(op.mem.out_disp)))
if op.mem.index_reg:
str += "," + dump_op_reg(insn, op.mem.index_reg) + ":" + map_index_size_str[op.mem.index_size]
if op.register_bits:
str += format(":%u" % (op.register_bits))
str += ")"
return str
if op.mem.in_disp > 0:
str += format("$%x" % ( op.mem.in_disp))
str += format("(")
if op.address_mode == M68K_AM_PCI_INDEX_BASE_DISP:
str_size = ''
if op.mem.index_size:
str_size = "l"
else:
str_size = "w"
str += format("pc,%s%s.%s" % ( dump_op_reg(insn, op.mem.index_reg)), s_spacing, str_size)
else:
if op.mem.base_reg != M68K_REG_INVALID:
str += format("a%d,%s" % ( op.mem.base_reg - M68K_REG_A0, s_spacing))
str_size = ''
if op.mem.index_size:
str_size = "l"
else:
str_size = "w"
str += format("%s.%s" % ( dump_op_reg(insn, op.mem.index_reg), str_size))
if op.mem.scale > 0:
str += format("%s*%s%d)" % ( s_spacing, s_spacing, op.mem.scale))
else:
str += ")"
return str
# It's ok to just use PCMI here as is as we set base_reg to PC in the disassembler.
# While this is not strictly correct it makes the code
# easier and that is what actually happens when the code is executed anyway.
if op.address_mode in [ M68K_AM_PC_MEMI_POST_INDEX, M68K_AM_PC_MEMI_PRE_INDEX, M68K_AM_MEMI_PRE_INDEX, M68K_AM_MEMI_POST_INDEX]:
if op.mem.base_reg:
str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg) ))
if op.mem.in_disp:
value = op.mem.in_disp
if op.mem.in_disp & 0x8000:
value = 0xffffffffffff0000 + op.mem.in_disp
str += format("@(%016x)@(%016x)" % (value, op.mem.out_disp))
return str
str += format("([")
if op.mem.in_disp > 0:
str += format("$%x" % ( op.mem.in_disp))
if op.mem.base_reg != M68K_REG_INVALID:
if op.mem.in_disp > 0:
str += format(",%s%s" % ( s_spacing, dump_op_reg(insn, op.mem.base_reg)))
else:
str += format("%s" % ( dump_op_reg(insn, op.mem.base_reg)))
if op.address_mode in [ M68K_AM_MEMI_POST_INDEX, M68K_AM_PC_MEMI_POST_INDEX]:
str += format("]")
if op.mem.index_reg != M68K_REG_INVALID:
str_size = ''
if op.mem.index_size:
str_size = "l"
else:
str_size = "w"
str += format(",%s%s.%s" % ( s_spacing, dump_op_reg(insn, op.mem.index_reg), str_size))
if op.mem.scale > 0:
str += format("%s*%s%d" % ( s_spacing, s_spacing, op.mem.scale))
if op.address_mode in [ M68K_AM_MEMI_PRE_INDEX, M68K_AM_PC_MEMI_PRE_INDEX]:
str += format("]")
if op.mem.out_disp > 0:
str += format(",%s$%x" % ( s_spacing, op.mem.out_disp))
str += format(")")
return str
if op.mem.bitfield:
return format("%d:%d" % ( op.mem.offset, op.mem.width))
############# OK
if op.address_mode == M68K_AM_AREGI_INDEX_BASE_DISP:
if op.mem.index_size:
str_size = "l"
else:
str_size = "w"
bits = op.mem.disp
return dump_op_reg(insn, op.mem.base_reg) + "@(" + "{0:016b}".format(bits) + "," + dump_op_reg(insn, op.mem.index_reg) + ":" + str_size + ")"
return ''
# M68K Addressing Modes
map_address_mode_str = {
0 : "M68K_AM_NONE",
1 : "M68K_AM_REG_DIRECT_DATA",
2 : "M68K_AM_REG_DIRECT_ADDR",
3 : "M68K_AM_REGI_ADDR",
4 : "M68K_AM_REGI_ADDR_POST_INC",
5 : "M68K_AM_REGI_ADDR_PRE_DEC",
6 : "M68K_AM_REGI_ADDR_DISP",
7 : "M68K_AM_AREGI_INDEX_8_BIT_DISP",
8 : "M68K_AM_AREGI_INDEX_BASE_DISP",
9 : "M68K_AM_MEMI_POST_INDEX",
10 : "M68K_AM_MEMI_PRE_INDEX",
11 : "M68K_AM_PCI_DISP",
12 : "M68K_AM_PCI_INDEX_8_BIT_DISP",
13 : "M68K_AM_PCI_INDEX_BASE_DISP",
14 : "M68K_AM_PC_MEMI_POST_INDEX",
15 : "M68K_AM_PC_MEMI_PRE_INDEX",
16 : "M68K_AM_ABSOLUTE_DATA_SHORT",
17 : "M68K_AM_ABSOLUTE_DATA_LONG",
18 : "M68K_AM_IMMEDIATE",
}
# Operand type for instruction's operands
map_op_str = {
0 : "M68K_OP_INVALID",
1 : "M68K_OP_REG",
2 : "M68K_OP_IMM",
3 : "M68K_OP_MEM",
4 : "M68K_OP_FP",
5 : "M68K_OP_REG_BITS",
6 : "M68K_OP_REG_PAIR",
}
def debug(insn, op):
if len(sys.argv) > 3:
print("id %d type %s address_mode %s" % (insn.id, map_op_str[op.type], map_address_mode_str[op.address_mode]))
def dump_ops(insn):
str = ''
mnemonic = insn.insn_name()
i = 0
while i < len(insn.operands):
if i > 0:
str += ','
op = insn.operands[i]
debug(insn, op)
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == M68K_INS_INVALID:
return format("0x%04x" % (op.imm))
if op.type == M68K_OP_REG:
str_op_reg = dump_op_ea(insn, op)
if str_op_reg == '' or op.address_mode == M68K_AM_REG_DIRECT_ADDR:
str_op_reg = dump_op_reg(insn, op.reg)
str += str_op_reg
if op.type == M68K_OP_IMM:
str_op_imm = format("#%u" % (op.imm))
if mnemonic in ["bkpt"]:
str_op_imm = format("%u" % (op.imm))
signed_insn = [ "move", "moveq", "cmp", "cmpi", "ori", "bclr", "pack", "unpk", "sub", "add" ]
if mnemonic in signed_insn:
if insn.op_size.size == 1 or mnemonic == "moveq":
str_op_imm = format("#%d" % s8(op.imm))
if insn.op_size.size == 2 or mnemonic == "pack":
str_op_imm = format("#%d" % s16(op.imm))
if insn.op_size.size == 4:
str_op_imm = format("#%d" % (op.imm))
dbxx_insn = [ "dbt", "dbf", "dbhi", "dbls", "dbcc", "dbcs", "dbne", "dbeq", "dbvc", "dbvs", "dbpl", "dbmi", "dbge", "dblt", "dbgt", "dble", "dbra" ]
if is_branch(insn) or mnemonic in dbxx_insn:
str_op_imm = format("0x%x" % (op.imm & 0xffffffff))
str += str_op_imm
if op.type == M68K_OP_MEM:
str_op_mem = dump_op_ea(insn, op)
if str_op_mem == '':
str_op_mem = format("0x%x" % (op.imm))
str += str_op_mem
if op.type in [ M68K_OP_REG_BITS, M68K_OP_REG_PAIR ]:
str += dump_op_ea(insn, op)
# if insn.address == 0x3127c:
# import pdb;pdb.set_trace()
# print("type %u am %u\n" % (op.type, op.address_mode))
i += 1
return str
def is_branch(insn):
mnemonic = insn.insn_name()
branch_insn = [ "bsr", "bra", "bhi", "bls", "bcc", "bcs", "bne", "beq", "bvc", "bvs", "bpl", "bmi", "bge", "blt", "bgt", "ble" ];
return mnemonic in branch_insn
def dump_mnemonic(insn):
# "data" instruction generated by SKIPDATA option has no detail
if insn.id == M68K_INS_INVALID:
return ".short"
mnemonic = insn.insn_name()
ext = { 0: '', 1:'b', 2:'w', 4:'l' }
if is_branch(insn):
ext.update({ 1:'s', 2:'w', 4:'l' })
no_size = [ "pea", "lea", "bset", "bclr", "bchg", "btst", "nbcd", "abcd", "sbcd", "exg", "scc", "sls", "scs", "shi" ]
sxx_insn = [ "st", "sf", "shi", "sls", "scc", "scs", "sne", "seq", "svc", "svs", "spl", "smi", "sge", "slt", "sgt", "sle", "stop" ]
no_size += sxx_insn
no_size += [ "tas" ]
if mnemonic in no_size:
ext.update({ 0:'', 1:'', 2:'', 4:'' })
return mnemonic + ext[insn.op_size.size]
def print_insn_detail_np(insn):
# objdump format hack
if insn.size == 2:
space = ' ' * 11
if insn.size == 4:
space = ' ' * 6
if insn.size >= 6:
space = ' '
space_ops = ''
if len(insn.operands) > 0:
space_ops = ' '
print(" %x:\t%s%s\t%s%s%s" % (insn.address, dump_bytes(insn._raw.bytes, min(insn.size, 6)), space, dump_mnemonic(insn), space_ops, dump_ops(insn)))
if insn.size > 6:
delta = min(insn.size, 6)
print(" %x:\t%s " % (insn.address+delta, dump_bytes(insn._raw.bytes[delta:], min(insn.size-delta, 6))))
def print_objdump_dumpheader(filename='', address=0):
print(objdump_dumpheader_fmt % (filename, address))
# ## Test class Cs
def test_class():
for (arch, mode, code, comment) in all_tests:
filename = "/dev/stdin"
address = 0
if len(sys.argv) > 1:
filename = sys.argv[1]
if len(sys.argv) > 2:
address = int(sys.argv[2],16)
if len(sys.argv) > 3:
debug_mode = True
with open(filename, "rb") as f:
code = f.read()
try:
md = Cs(arch, mode)
md.detail = True
print_objdump_dumpheader(filename, address)
for insn in md.disasm(code, address):
print_insn_detail_np(insn)
except CsError as e:
print("ERROR: %s" % e)
if __name__ == '__main__':
test_class()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,905 @@
From 40ac7444e7f3679fad852564acca4f30f47fb52d Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Thu, 28 Feb 2019 01:37:55 +0800
Subject: [PATCH] update TableGen for generate RISCV port inc for CAPSTONE
---
llvm/lib/Target/RISCV/CMakeLists.txt | 2 +-
llvm/utils/TableGen/AsmWriterEmitter.cpp | 175 ++++++++++++++++--
.../utils/TableGen/FixedLenDecoderEmitter.cpp | 122 ++++++------
llvm/utils/TableGen/InstrInfoEmitter.cpp | 14 +-
llvm/utils/TableGen/RegisterInfoEmitter.cpp | 20 +-
llvm/utils/TableGen/TableGen.cpp | 6 +
6 files changed, 249 insertions(+), 90 deletions(-)
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 1821f4b01..603aa3f54 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -6,7 +6,7 @@ tablegen(LLVM RISCVGenCompressInstEmitter.inc -gen-compress-inst-emitter)
tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
-tablegen(LLVM RISCVGenMappingInsn.inc -gen-mapping-insn)
+tablegen(LLVM RISCVMappingInsn.inc -gen-mapping-insn)
tablegen(LLVM RISCVGenInsnNameMaps.inc -gen-insn-name-maps)
tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index c24dc6052..ac82573fe 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -270,12 +270,13 @@ static void UnescapeString(std::string &Str) {
/// implementation. Destroys all instances of AsmWriterInst information, by
/// clearing the Instructions vector.
void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
+#ifdef CAPSTONE
+ bool PassSubtarget = false;
+#else
Record *AsmWriter = Target.getAsmWriter();
-#ifndef CAPSTONE
StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
-#endif
bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
-
+#endif
O <<
"/// printInstruction - This method is automatically generated by tablegen\n"
"/// from the instruction set description.\n"
@@ -434,7 +435,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
}
// Emit the initial tab character.
-#ifndef CAPSTONE
+#ifdef CAPSTONE
+ O << "#ifndef CAPSTONE_DIET\n"
+ << " SStream_concat0(O, \"\\t\");\n"
+ << "#endif\n\n";
+#else
O << " O << \"\\t\";\n\n";
#endif
@@ -493,10 +498,10 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
<< ((1 << NumBits)-1) << ") {\n"
<< " default: "
#ifdef CAPSTONE
- << "assert(0);\n"
-#endif
+ << "assert(0 && \"Invalid command number.\");\n";
+#else
<< "llvm_unreachable(\"Invalid command number.\");\n";
-
+#endif
// Print out all the cases.
for (unsigned j = 0, e = Commands.size(); j != e; ++j) {
O << " case " << j << ":\n";
@@ -576,9 +581,7 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
}
StringTable.layout();
-#ifdef CAPSTONE
- O << "#ifndef CAPSTONE_DIET\n";
-#endif
+
O << " static const char AsmStrs" << AltName << "[] = {\n";
StringTable.emit(O, printChar);
O << " };\n\n";
@@ -625,7 +628,8 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
O << " "
<< "assert(RegNo && RegNo < " << (Registers.size()+1)
<< " && \"Invalid register number!\");\n"
- << "\n";
+ << "\n"
+ << "#ifndef CAPSTONE_DIET\n";
if (hasAltNames) {
for (const Record *R : AltNameIndices)
@@ -636,7 +640,7 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
if (hasAltNames) {
O << " switch(AltIdx) {\n"
#ifdef CAPSTONE
- << " default: assert(0);\n";
+ << " default: assert(0 && \"Invalid register alt name index!\");\n";
#else
<< " default: llvm_unreachable(\"Invalid register alt name index!\");\n";
#endif
@@ -886,7 +890,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAPrinter IAP(CGA.Result->getAsString(), FlatAliasAsmString);
+#ifndef CAPSTONE // Silence the compiler waring.
StringRef Namespace = Target.getName();
+#endif
std::vector<Record *> ReqFeatures;
if (PassSubtarget) {
// We only consider ReqFeatures predicates if PassSubtarget
@@ -902,7 +908,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
NumMIOps += ResultInstOpnd.MINumOperands;
std::string Cond;
+#ifdef CAPSTONE
+ Cond = std::string("MCInst_getNumOperands(MI) == ") + utostr(NumMIOps);
+#else
Cond = std::string("MI->getNumOperands() == ") + utostr(NumMIOps);
+#endif
IAP.addCond(Cond);
bool CantHandle = false;
@@ -926,9 +936,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
}
break;
}
-
+#ifdef CAPSTONE
+ std::string Op = "MCInst_getOperand(MI, " + utostr(MIOpNum) + ")";
+#else
std::string Op = "MI->getOperand(" + utostr(MIOpNum) + ")";
-
+#endif
const CodeGenInstAlias::ResultOperand &RO = CGA.ResultOperands[i];
switch (RO.Kind) {
@@ -954,19 +966,39 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (Rec->isSubClassOf("RegisterOperand"))
Rec = Rec->getValueAsDef("RegClass");
if (Rec->isSubClassOf("RegisterClass")) {
+#ifdef CAPSTONE
+ IAP.addCond("MCOperand_isReg(" + Op + ")");
+#else
IAP.addCond(Op + ".isReg()");
+#endif
if (!IAP.isOpMapped(ROName)) {
IAP.addOperand(ROName, MIOpNum, PrintMethodIdx);
Record *R = CGA.ResultOperands[i].getRecord();
if (R->isSubClassOf("RegisterOperand"))
R = R->getValueAsDef("RegClass");
+
+#ifdef CAPSTONE
+ Cond = std::string("MCRegisterClass_contains(") +
+ "MCRegisterInfo_getRegClass(" + "MRI, " +
+ Target.getName().str() + "_" + R->getName().str() + "RegClassID)" +
+ ", " +
+ "MCOperand_getReg(" + Op + "))";
+#else
Cond = std::string("MRI.getRegClass(") + Target.getName().str() +
"::" + R->getName().str() + "RegClassID).contains(" + Op +
".getReg())";
+#endif
+
} else {
+#ifdef CAPSTONE
+ Cond = std::string("MCOperand_getReg(") + Op + ") == " +
+ "MCOperand_getReg(MCInst_getOperand(MI, " +
+ utostr(IAP.getOpIndex(ROName)) + "))";
+#else
Cond = Op + ".getReg() == MI->getOperand(" +
utostr(IAP.getOpIndex(ROName)) + ").getReg()";
+#endif
}
} else {
// Assume all printable operands are desired for now. This can be
@@ -984,8 +1016,12 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
break; // No conditions on this operand at all
}
Cond = (Target.getName() + ClassName + "ValidateMCOperand(" + Op +
+ #ifdef CAPSTONE
+ ", " + utostr(Entry) + ")").str();
+ #else
", STI, " + utostr(Entry) + ")")
.str();
+ #endif
}
// for all subcases of ResultOperand::K_Record:
IAP.addCond(Cond);
@@ -994,9 +1030,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
case CodeGenInstAlias::ResultOperand::K_Imm: {
// Just because the alias has an immediate result, doesn't mean the
// MCInst will. An MCExpr could be present, for example.
+#ifdef CAPSTONE
+ IAP.addCond("MCOperand_isImm(" + Op + ")");
+ Cond = "MCOperand_getImm(" + Op + ") == " +
+ itostr(CGA.ResultOperands[i].getImm());
+#else
IAP.addCond(Op + ".isImm()");
-
Cond = Op + ".getImm() == " + itostr(CGA.ResultOperands[i].getImm());
+#endif
+
IAP.addCond(Cond);
break;
}
@@ -1008,8 +1050,14 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
break;
}
+#ifdef CAPSTONE
+ Cond = "MCOperand_getReg(" + Op + ") == " + Target.getName().str() +
+ "_" + CGA.ResultOperands[i].getRegister()->getName().str();
+#else
Cond = Op + ".getReg() == " + Target.getName().str() + "::" +
CGA.ResultOperands[i].getRegister()->getName().str();
+#endif
+
IAP.addCond(Cond);
break;
}
@@ -1019,6 +1067,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (CantHandle) continue;
+#ifndef CAPSTONE
for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) {
Record *R = *I;
StringRef AsmCondString = R->getValueAsString("AssemblerCondString");
@@ -1040,6 +1089,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
IAP.addCond(Cond);
}
}
+#endif
IAPrinterMap[Aliases.first].push_back(std::move(IAP));
}
@@ -1052,10 +1102,17 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
std::string Header;
raw_string_ostream HeaderO(Header);
+#ifdef CAPSTONE
+ HeaderO << "\nstatic bool printAliasInstr(MCInst *MI, SStream * OS, void *info)"
+ << "\n"
+ << "{\n"
+ << " MCRegisterInfo *MRI = (MCRegisterInfo *) info;\n";
+#else
HeaderO << "bool " << Target.getName() << ClassName
<< "::printAliasInstr(const MCInst"
<< " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
<< "raw_ostream &OS) {\n";
+#endif
std::string Cases;
raw_string_ostream CasesO(Cases);
@@ -1079,7 +1136,16 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (UniqueIAPs.empty()) continue;
+#ifdef CAPSTONE
+ // TODO: tricky.
+ const char* tmpCase = Entry.first.c_str();
+ assert (Entry.first.size() > 7);
+ CasesO.indent(2) << "case "
+ << "RISCV_" << std::string(tmpCase + 7) // strlen("RISCV::) == 7
+ << ":\n";
+#else
CasesO.indent(2) << "case " << Entry.first << ":\n";
+#endif
for (IAPrinter *IAP : UniqueIAPs) {
CasesO.indent(4);
@@ -1100,13 +1166,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (!MCOpPredicates.empty())
O << "static bool " << Target.getName() << ClassName
+#ifdef CAPSTONE
+ << "ValidateMCOperand(MCOperand *MCOp,\n"
+#else
<< "ValidateMCOperand(const MCOperand &MCOp,\n"
<< " const MCSubtargetInfo &STI,\n"
+#endif
<< " unsigned PredicateIndex);\n";
O << HeaderO.str();
O.indent(2) << "const char *AsmString;\n";
+#ifdef CAPSTONE
+ O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n";
+#else
O.indent(2) << "switch (MI->getOpcode()) {\n";
+#endif
O.indent(2) << "default: return false;\n";
O << CasesO.str();
O.indent(2) << "}\n\n";
@@ -1114,14 +1188,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
// Code that prints the alias, replacing the operands with the ones from the
// MCInst.
O << " unsigned I = 0;\n";
+#ifdef CAPSTONE
+ O << " char *tmpString = cs_strdup(AsmString);\n";
+#endif
O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n";
O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n";
O << " ++I;\n";
+#ifdef CAPSTONE
+ O << " tmpString[I] = 0;\n";
+ O << " SStream_concat0(OS, \"\\t\");\n";
+ O << " SStream_concat0(OS, tmpString);\n";
+ O << " SStream_concat0(OS, \"\\n\");\n";
+#else
O << " OS << '\\t' << StringRef(AsmString, I);\n";
-
+#endif
O << " if (AsmString[I] != '\\0') {\n";
O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n";
+#ifdef CAPSTONE
+ O << " SStream_concat0(OS, \"\\t\");\n";
+#else
O << " OS << '\\t';\n";
+#endif
O << " ++I;\n";
O << " }\n";
O << " do {\n";
@@ -1131,15 +1218,28 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " ++I;\n";
O << " int OpIdx = AsmString[I++] - 1;\n";
O << " int PrintMethodIdx = AsmString[I++] - 1;\n";
+#ifdef CAPSTONE
+ O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n";
+#else
O << " printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, ";
O << (PassSubtarget ? "STI, " : "");
O << "OS);\n";
+#endif
O << " } else\n";
+
+#ifdef CAPSTONE
+ O << " printOperand(MI, (unsigned)(AsmString[I++]) - 1, OS);\n";
+#else
O << " printOperand(MI, unsigned(AsmString[I++]) - 1, ";
O << (PassSubtarget ? "STI, " : "");
O << "OS);\n";
+#endif
O << " } else {\n";
+#ifdef CAPSTONE
+ O << " SStream_concat0(OS, &AsmString[I++]);\n";
+#else
O << " OS << AsmString[I++];\n";
+#endif
O << " }\n";
O << " } while (AsmString[I] != '\\0');\n";
O << " }\n\n";
@@ -1150,25 +1250,48 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
//////////////////////////////
// Write out the printCustomAliasOperand function
//////////////////////////////
-
+#ifdef CAPSTONE
+ O << "static void "
+#else
O << "void " << Target.getName() << ClassName << "::"
+#endif
<< "printCustomAliasOperand(\n"
+#ifdef CAPSTONE
+ << " MCInst *MI, unsigned OpIdx,\n"
+#else
<< " const MCInst *MI, unsigned OpIdx,\n"
+#endif
<< " unsigned PrintMethodIdx,\n"
+#ifdef CAPSTONE
+ << " SStream *OS) {\n";
+#else
<< (PassSubtarget ? " const MCSubtargetInfo &STI,\n" : "")
<< " raw_ostream &OS) {\n";
+#endif
if (PrintMethods.empty())
+#ifdef CAPSTONE
+ O << " assert(0 && \"Unknown PrintMethod kind\");\n";
+#else
O << " llvm_unreachable(\"Unknown PrintMethod kind\");\n";
+#endif
else {
O << " switch (PrintMethodIdx) {\n"
<< " default:\n"
+#ifdef CAPSTONE
+ << " assert(0 && \"Unknown PrintMethod kind\");\n"
+#else
<< " llvm_unreachable(\"Unknown PrintMethod kind\");\n"
+#endif
<< " break;\n";
for (unsigned i = 0; i < PrintMethods.size(); ++i) {
O << " case " << i << ":\n"
<< " " << PrintMethods[i] << "(MI, OpIdx, "
+#ifdef CAPSTONE
+ << "OS);\n"
+#else
<< (PassSubtarget ? "STI, " : "") << "OS);\n"
+#endif
<< " break;\n";
}
O << " }\n";
@@ -1177,9 +1300,20 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
if (!MCOpPredicates.empty()) {
O << "static bool " << Target.getName() << ClassName
+#ifdef CAPSTONE
+ << "ValidateMCOperand(MCOperand *MCOp,\n"
+#else
<< "ValidateMCOperand(const MCOperand &MCOp,\n"
<< " const MCSubtargetInfo &STI,\n"
- << " unsigned PredicateIndex) {\n"
+#endif
+ << " unsigned PredicateIndex) {\n"
+#ifdef CAPSTONE
+ << " // TODO: need some constant untils operate the MCOperand,\n"
+ << " // but current CAPSTONE does't have.\n"
+ << " // So, We just return true\n"
+ << " return true;\n\n"
+ << "#if 0\n"
+#endif
<< " switch (PredicateIndex) {\n"
<< " default:\n"
<< " llvm_unreachable(\"Unknown MCOperandPredicate kind\");\n"
@@ -1195,6 +1329,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
llvm_unreachable("Unexpected MCOperandPredicate field!");
}
O << " }\n"
+#ifdef CAPSTONE
+ << "#endif\n"
+#endif
<< "}\n\n";
}
@@ -1228,7 +1365,7 @@ void AsmWriterEmitter::run(raw_ostream &O) {
#endif
EmitPrintInstruction(O);
EmitGetRegisterName(O);
-#ifndef CAPSTONE
+#ifdef CAPSTONE
EmitPrintAliasInstruction(O);
#endif
}
diff --git a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 3db428dfa..e1bfaa934 100644
--- a/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -946,13 +946,6 @@ void FixedLenDecoderEmitter::emitTable(formatted_raw_ostream &OS,
void FixedLenDecoderEmitter::
emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
unsigned Indentation) const {
-#ifdef CAPSTONE
- OS.indent(Indentation) << "static bool getbool(uint64_t b)\n";
- OS.indent(Indentation) << "{\n";
- OS.indent(Indentation) << "\treturn b != 0;\n";
- OS.indent(Indentation) << "}\n\n";
-#endif
-
// The predicate function is just a big switch statement based on the
// input predicate index.
OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
@@ -966,26 +959,25 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
OS.indent(Indentation) << "switch (Idx) {\n";
OS.indent(Indentation) << "default: "
#ifdef CAPSTONE
- << "assert(0);\n"
-#endif
+ << "assert(0 && \"Invalid index!\");\n";
+#else
<< "llvm_unreachable(\"Invalid index!\");\n";
+#endif
unsigned Index = 0;
for (const auto &Predicate : Predicates) {
OS.indent(Indentation) << "case " << Index++ << ":\n";
OS.indent(Indentation+2) << "return "
-#ifdef CAPSTONE
- << "getbool"
-#endif
- << "(" << Predicate << ");\n";
+ << Predicate << ";\n";
}
OS.indent(Indentation) << "}\n";
} else {
// No case statement to emit
OS.indent(Indentation)
#ifdef CAPSTONE
- << "assert(0);\n"
-#endif
+ << "assert(0 && \"Invalid index!\");\n";
+#else
<< "llvm_unreachable(\"Invalid index!\");\n";
+#endif
}
Indentation -= 2;
OS.indent(Indentation) << "}\n\n";
@@ -998,10 +990,11 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
// input decoder index.
#ifdef CAPSTONE
#define EDF_EOL " \\\n"
- OS.indent(Indentation) << "#define DecodeToMCInst(fname,fieldname, InsnType) \\\n";
- OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *MI, \\\n";
- OS.indent(Indentation) << " uint64_t Address, const void *Decoder) \\\n";
- OS.indent(Indentation) << "{ \\\n";
+ OS.indent(Indentation) << "#define DecodeToMCInst(fname, fieldname, InsnType) \\\n";
+ OS.indent(Indentation) << "static DecodeStatus fname(DecodeStatus S, unsigned Idx,"
+ << " InsnType insn, MCInst *MI, \\\n";
+ OS.indent(Indentation) << " uint64_t Address, const void *Decoder,\\\n";
+ OS.indent(Indentation) << " bool *DecodeComplete) {\\\n";
#else
#define EDF_EOL "\n"
OS.indent(Indentation) << "template<typename InsnType>\n";
@@ -1011,16 +1004,18 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
<< "Address, const void *Decoder, bool &DecodeComplete) {\n";
#endif
Indentation += 2;
-#ifndef CAPSTONE
+#ifdef CAPSTONE
+ OS.indent(Indentation) << "*DecodeComplete = true;\\\n";
+#else
OS.indent(Indentation) << "DecodeComplete = true;\n";
#endif
OS.indent(Indentation) << "InsnType tmp;" EDF_EOL;
OS.indent(Indentation) << "switch (Idx) {" EDF_EOL;
OS.indent(Indentation) << "default:"
-#ifndef CAPSTONE
- << " llvm_unreachable(\"Invalid index!\");\n";
+#ifdef CAPSTONE
+ << " assert(0 && \"Invalid index!\");\\\n";
#else
- << " assert(0);\\\n";
+ << " llvm_unreachable(\"Invalid index!\");\n";
#endif
unsigned Index = 0;
for (const auto &Decoder : Decoders) {
@@ -1174,8 +1169,27 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
if (Decoder != "") {
OpHasCompleteDecoder = OpInfo.HasCompleteDecoder;
+#ifdef CAPSTONE
+ std::string::size_type posOfLeftAngle = 0, posOfRightAngle = 0;
+ posOfLeftAngle = Decoder.find("<");
+ posOfRightAngle = Decoder.find(">");
+ std::string printDecoder = Decoder;
+ if (posOfLeftAngle != std::string::npos &&
+ posOfRightAngle != std::string::npos) {
+ printDecoder = Decoder.substr(0, posOfLeftAngle);
+ o.indent(Indentation) << Emitter->GuardPrefix
+ << printDecoder
+ << "(MI, tmp, Address, Decoder, "
+ << Decoder.substr(posOfLeftAngle+1, posOfRightAngle-posOfLeftAngle-1);
+ } else
+ o.indent(Indentation) << Emitter->GuardPrefix << Decoder
+ << "(MI, tmp, Address, Decoder";
+ // trick.
+ o << ")"
+#else
o.indent(Indentation) << Emitter->GuardPrefix << Decoder
<< "(MI, tmp, Address, Decoder)"
+#endif
<< Emitter->GuardPostfix
#ifdef CAPSTONE
<< " return MCDisassembler_Fail; \\\n";
@@ -1246,7 +1260,7 @@ static void emitSinglePredicateMatch(raw_ostream &o, StringRef str,
const std::string &PredicateNamespace) {
if (str[0] == '!')
#ifdef CAPSTONE
- o << "~(Bits & " << PredicateNamespace << "_"
+ o << "!(Bits & " << PredicateNamespace << "_"
<< str.slice(1,str.size()) << ")";
#else
o << "!Bits[" << PredicateNamespace << "::"
@@ -2331,15 +2345,13 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
#endif
#ifdef CAPSTONE
- OS << "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
-
+ OS << "#define DecodeInstruction(fname, fieldname, decoder, InsnType) \\\n"
+ << "static DecodeStatus fname(const uint8_t DecodeTable[], "
"MCInst *MI,\\\n"
- << " InsnType insn, uint64_t "
+ << " InsnType insn, uint64_t "
"Address,\\\n"
- << " const void *DisAsm,\\\n"
- << " int feature) {\\\n"
- << " uint64_t Bits = getFeatureBits(feature); \\\n"
- //<< " const FeatureBitset& Bits = STI.getFeatureBits();\n"
+ << " const void *DisAsm, int feature) {\\\n"
+ << " uint64_t Bits = getFeatureBits(feature);\\\n"
<< "\\\n"
<< " const uint8_t *Ptr = DecodeTable;\\\n"
<< " uint32_t CurFieldValue = 0;\\\n"
@@ -2353,52 +2365,42 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " unsigned Start = *++Ptr;\\\n"
<< " unsigned Len = *++Ptr;\\\n"
<< " ++Ptr;\\\n"
- << " CurFieldValue = fieldFromInstruction(insn, Start, Len);\\\n"
+ << " CurFieldValue = fieldname(insn, Start, Len);\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_FilterValue: {\\\n"
- << " // Decode the field value.\\\n"
<< " unsigned Len;\\\n"
<< " InsnType Val = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
<< "\\\n"
- << " // Perform the filter operation.\\\n"
<< " if (Val != CurFieldValue)\\\n"
<< " Ptr += NumToSkip;\\\n"
- << "\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_CheckField: {\\\n"
<< " unsigned Start = *++Ptr;\\\n"
<< " unsigned Len = *++Ptr;\\\n"
- << " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\\\n"
- << " // Decode the field value.\\\n"
+ << " InsnType FieldValue = fieldname(insn, Start, Len);\\\n"
<< " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
<< "\\\n"
- << " // If the actual and expected values don't match, skip.\\\n"
<< " if (ExpectedValue != FieldValue)\\\n"
<< " Ptr += NumToSkip;\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_CheckPredicate: {\\\n"
<< " unsigned Len;\\\n"
- << " // Decode the Predicate Index value.\\\n"
<< " unsigned PIdx = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
- << " // Check the predicate.\\\n"
<< " bool Pred;\\\n"
<< " if (!(Pred = checkDecoderPredicate(PIdx, Bits)))\\\n"
<< " Ptr += NumToSkip;\\\n"
@@ -2407,7 +2409,6 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " }\\\n"
<< " case MCD_OPC_Decode: {\\\n"
<< " unsigned Len;\\\n"
- << " // Decode the Opcode value.\\\n"
<< " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
<< " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n"
@@ -2416,47 +2417,39 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " MCInst_clear(MI);\\\n"
<< " MCInst_setOpcode(MI, Opc);\\\n"
<< " bool DecodeComplete;\\\n"
- << " S = decodeToMCInst(S, DecodeIdx, insn, MI, Address, DisAsm, "
- "DecodeComplete);\\\n"
+ << " S = decoder(S, DecodeIdx, insn, MI, Address, DisAsm, "
+ "&DecodeComplete);\\\n"
<< " assert(DecodeComplete);\\\n"
<< "\\\n"
<< " return S;\\\n"
<< " }\\\n"
<< " case MCD_OPC_TryDecode: {\\\n"
<< " unsigned Len;\\\n"
- << " // Decode the Opcode value.\\\n"
<< " unsigned Opc = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
<< " unsigned DecodeIdx = decodeULEB128(Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
- << " // NumToSkip is a plain 24-bit integer.\\\n"
<< " unsigned NumToSkip = *Ptr++;\\\n"
<< " NumToSkip |= (*Ptr++) << 8;\\\n"
<< " NumToSkip |= (*Ptr++) << 16;\\\n"
<< "\\\n"
- << " // Perform the decode operation.\\\n"
<< " MCInst TmpMI;\\\n"
<< " MCInst_setOpcode(&TmpMI, Opc);\\\n"
- << " bool DecodeComplete;\n"
- << " S = decodeToMCInst(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, "
- "DecodeComplete);\\\n"
+ << " bool DecodeComplete;\\\n"
+ << " S = decoder(S, DecodeIdx, insn, &TmpMI, Address, DisAsm, "
+ "&DecodeComplete);\\\n"
+ << "\\\n"
<< " if (DecodeComplete) {\\\n"
- << " // Decoding complete.\\\n"
- << " MI = &TmpMI;\\\n"
+ << " *MI = TmpMI;\\\n"
<< " return S;\\\n"
<< " } else {\\\n"
<< " assert(S == MCDisassembler_Fail);\\\n"
- << " // If the decoding was incomplete, skip.\\\n"
<< " Ptr += NumToSkip;\\\n"
- << " // Reset decode status. This also drops a SoftFail status "
- "that could be\\\n"
- << " // set before the decode attempt.\\\n"
<< " S = MCDisassembler_Success;\\\n"
<< " }\\\n"
<< " break;\\\n"
<< " }\\\n"
<< " case MCD_OPC_SoftFail: {\\\n"
- << " // Decode the mask values.\\\n"
<< " unsigned Len;\\\n"
<< " InsnType PositiveMask = decodeULEB128(++Ptr, &Len);\\\n"
<< " Ptr += Len;\\\n"
@@ -2472,8 +2465,8 @@ static void emitDecodeInstruction(formatted_raw_ostream &OS) {
<< " }\\\n"
<< " }\\\n"
<< " }\\\n"
- << " assert(0);\\\n"
-
+ << " assert(0 && \"bogosity detected in disassembler state "
+ "machine!\");\\\n"
#else
OS << "template<typename InsnType>\n"
<< "static DecodeStatus decodeInstruction(const uint8_t DecodeTable[], "
@@ -2752,9 +2745,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
emitDecodeInstruction(OS);
#ifdef CAPSTONE
- OS << "FieldFromInstruction(fieldFromInstruction, uint64_t)\n";
- OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint64_t)\n";
- OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint64_t)\n";
+ OS << "// For RISCV instruction is 32 bits.\n";
+ OS << "FieldFromInstruction(fieldFromInstruction, uint32_t)\n";
+ OS << "DecodeToMCInst(decodeToMCInst, fieldFromInstruction, uint32_t)\n";
+ OS << "DecodeInstruction(decodeInstruction, fieldFromInstruction, decodeToMCInst, uint32_t)\n";
#else
OS << "\n} // End llvm namespace\n";
#endif
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 01605184f..e59dace24 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -769,6 +769,7 @@ void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
#ifdef CAPSTONE
std::string GetPublicName(const CodeGenInstruction *Inst) {
std::string Name = Inst->TheDef->getName();
+#if 0
// Apply backward compatibility fixups.
// BRNLE -> BNLER.
if (Name.length() >= 5 && Name.substr(0, 5) == "BRAsm") {
@@ -785,7 +786,7 @@ std::string GetPublicName(const CodeGenInstruction *Inst) {
break;
}
Name = Name.substr(0, pos) + Name.substr(pos + 3);
- }
+ }f 0
// CPSDRxx -> CPSDR.
if (Name.length() >= 2) {
std::string Suffix2 = Name.substr(Name.length() - 2, 2);
@@ -794,7 +795,8 @@ std::string GetPublicName(const CodeGenInstruction *Inst) {
Name = Name.substr(0, Name.length() - 2);
}
}
- return "SYSZ_INS_" + Name;
+#endif
+ return "RISCV_INS_" + Name;
}
std::string GetRegisterName(Record *Reg) {
@@ -802,6 +804,7 @@ std::string GetRegisterName(Record *Reg) {
for (char& c : Name) {
c = toupper(c);
}
+#if 0
// R0L, R0D -> R0.
if (Name.length() >= 3 &&
Name[Name.length() - 3] == 'R' &&
@@ -809,7 +812,8 @@ std::string GetRegisterName(Record *Reg) {
Name[Name.length() - 1] == 'D')) {
Name = Name.substr(0, Name.length() - 3) + Name[Name.length() - 2];
}
- return "SYSZ_REG_" + Name;
+#endif
+ return "RISCV_REG_" + Name;
}
std::string GetGroupName(Record *Pred) {
@@ -817,10 +821,12 @@ std::string GetGroupName(Record *Pred) {
for (char& c : Name) {
c = toupper(c);
}
+#if 0
if (Name.length() >= 7 && Name.substr(0, 7) == "FEATURE") {
Name = Name.substr(7);
}
- return "SYSZ_GRP_" + Name;
+#endif
+ return "RISCV_GRP_" + Name;
}
void EmitMappingInsn(RecordKeeper &RK, raw_ostream &OS) {
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 0df306680..cf9c352d7 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -180,12 +180,20 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
#endif
}
-#ifndef CAPSTONE
const std::vector<Record*> &RegAltNameIndices = Target.getRegAltNameIndices();
// If the only definition is the default NoRegAltName, we don't need to
// emit anything.
if (RegAltNameIndices.size() > 1) {
OS << "\n// Register alternate name indices\n\n";
+#ifdef CAPSTONE
+ OS << "enum {\n";
+ for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i)
+ OS << " " << NAME_PREFIX RegAltNameIndices[i]->getName()
+ << ",\t// " << i << "\n";
+ OS << " " << NAME_PREFIX "NUM_TARGET_REG_ALT_NAMES = "
+ << RegAltNameIndices.size() << "\n";
+ OS << "};\n";
+#else
if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n";
OS << "enum {\n";
@@ -195,11 +203,19 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
OS << "};\n";
if (!Namespace.empty())
OS << "} // end namespace " << Namespace << "\n\n";
+#endif
}
auto &SubRegIndices = Bank.getSubRegIndices();
if (!SubRegIndices.empty()) {
OS << "\n// Subregister indices\n\n";
+#ifdef CAPSTONE
+ OS << "enum {\n" << " " << NAME_PREFIX "NoSubRegister,\n";
+ unsigned i = 0;
+ for (const auto &Idx : SubRegIndices)
+ OS << " " << NAME_PREFIX Idx.getName() << ",\t// " << ++i << "\n";
+ OS << " " << NAME_PREFIX "NUM_TARGET_SUBREGS\n};\n";
+#else
std::string Namespace = SubRegIndices.front().getNamespace();
if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n";
@@ -210,8 +226,8 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
OS << " NUM_TARGET_SUBREGS\n};\n";
if (!Namespace.empty())
OS << "} // end namespace " << Namespace << "\n\n";
- }
#endif
+ }
#ifndef CAPSTONE
OS << "} // end namespace llvm\n\n";
diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp
index 9e2a868be..7ec93c0e0 100644
--- a/llvm/utils/TableGen/TableGen.cpp
+++ b/llvm/utils/TableGen/TableGen.cpp
@@ -27,8 +27,10 @@ enum ActionType {
GenEmitter,
GenRegisterInfo,
GenInstrInfo,
+#ifdef CAPSTONE
GenMappingInsn,
GenInsnNameMaps,
+#endif
GenInstrDocs,
GenAsmWriter,
GenAsmMatcher,
@@ -76,10 +78,12 @@ namespace {
"Generate registers and register classes info"),
clEnumValN(GenInstrInfo, "gen-instr-info",
"Generate instruction descriptions"),
+#ifdef CAPSTONE
clEnumValN(GenMappingInsn, "gen-mapping-insn",
""),
clEnumValN(GenInsnNameMaps, "gen-insn-name-maps",
""),
+#endif
clEnumValN(GenInstrDocs, "gen-instr-docs",
"Generate instruction documentation"),
clEnumValN(GenCallingConv, "gen-callingconv",
@@ -160,12 +164,14 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenInstrInfo:
EmitInstrInfo(Records, OS);
break;
+#ifdef CAPSTONE
case GenMappingInsn:
EmitMappingInsn(Records, OS);
break;
case GenInsnNameMaps:
EmitInsnNameMaps(Records, OS);
break;
+#endif
case GenInstrDocs:
EmitInstrDocs(Records, OS);
break;
--
2.20.1

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
From 5adfa13945a8eb1a104db57b29d27ceba0a2d948 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Sun, 3 Mar 2019 23:16:27 +0800
Subject: [PATCH] fix output TAB for riscv capstone
---
llvm/utils/TableGen/AsmWriterEmitter.cpp | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index ac82573fe..21630f4ce 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -435,14 +435,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
}
// Emit the initial tab character.
-#ifdef CAPSTONE
- O << "#ifndef CAPSTONE_DIET\n"
- << " SStream_concat0(O, \"\\t\");\n"
- << "#endif\n\n";
-#else
- O << " O << \"\\t\";\n\n";
-#endif
-
+ //O << " O << \"\\t\";\n\n";
O << " // Emit the opcode for the instruction.\n";
O << BitsString;
--
2.20.1

View File

@@ -0,0 +1,32 @@
From 9028d6a0ce67296be48a3dae07d954ebe26942e1 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Thu, 7 Mar 2019 00:08:08 +0800
Subject: [PATCH] fix riscv alias inst output useless newline
---
llvm/utils/TableGen/AsmWriterEmitter.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 21630f4ce..9db5f7f54 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -1191,14 +1191,13 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " tmpString[I] = 0;\n";
O << " SStream_concat0(OS, \"\\t\");\n";
O << " SStream_concat0(OS, tmpString);\n";
- O << " SStream_concat0(OS, \"\\n\");\n";
#else
O << " OS << '\\t' << StringRef(AsmString, I);\n";
#endif
O << " if (AsmString[I] != '\\0') {\n";
O << " if (AsmString[I] == ' ' || AsmString[I] == '\\t') {\n";
#ifdef CAPSTONE
- O << " SStream_concat0(OS, \"\\t\");\n";
+ O << " SStream_concat0(OS, \" \");\n";
#else
O << " OS << '\\t';\n";
#endif
--
2.20.1

View File

@@ -0,0 +1,24 @@
From 6830f128011a19e77e8c131cdfcf2f87fb78e316 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Thu, 7 Mar 2019 00:31:51 +0800
Subject: [PATCH] fix riscv inst output more formal
---
llvm/utils/TableGen/AsmWriterEmitter.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 9db5f7f54..fff9f7677 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -1189,7 +1189,6 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " ++I;\n";
#ifdef CAPSTONE
O << " tmpString[I] = 0;\n";
- O << " SStream_concat0(OS, \"\\t\");\n";
O << " SStream_concat0(OS, tmpString);\n";
#else
O << " OS << '\\t' << StringRef(AsmString, I);\n";
--
2.20.1

View File

@@ -0,0 +1,38 @@
From b1a7abb285aaa1436d563a30f65813513a512850 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Fri, 8 Mar 2019 11:09:54 +0800
Subject: [PATCH] fix riscv asmwriter variable declaration place
---
llvm/utils/TableGen/AsmWriterEmitter.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index fff9f7677..90540000f 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -1170,6 +1170,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << HeaderO.str();
O.indent(2) << "const char *AsmString;\n";
#ifdef CAPSTONE
+ O << " unsigned I = 0;\n";
+ O << " char *tmpString;\n";
O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n";
#else
O.indent(2) << "switch (MI->getOpcode()) {\n";
@@ -1180,9 +1182,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
// Code that prints the alias, replacing the operands with the ones from the
// MCInst.
+#ifndef CAPSTONE
O << " unsigned I = 0;\n";
+#endif
#ifdef CAPSTONE
- O << " char *tmpString = cs_strdup(AsmString);\n";
+ O << " tmpString = cs_strdup(AsmString);\n";
#endif
O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n";
O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n";
--
2.20.1

View File

@@ -0,0 +1,24 @@
From 533ce514a7365932e9919be6e63c605d7edf655c Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Wed, 20 Mar 2019 12:26:19 +0800
Subject: [PATCH] fix riscvgenasmwiter.inc memory leak
---
llvm/utils/TableGen/AsmWriterEmitter.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 90540000f..bc32a494b 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -1194,6 +1194,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
#ifdef CAPSTONE
O << " tmpString[I] = 0;\n";
O << " SStream_concat0(OS, tmpString);\n";
+ O << " cs_mem_free(tmpString);\n";
#else
O << " OS << '\\t' << StringRef(AsmString, I);\n";
#endif
--
2.20.1

View File

@@ -0,0 +1,53 @@
From 93d420c95c3cf1d6a369be1ca7f2333fdf670283 Mon Sep 17 00:00:00 2001
From: fanfuqiang <feqin1023@gmail.com>
Date: Wed, 20 Mar 2019 15:15:01 +0800
Subject: [PATCH] using static array contain temp string for riscv asmwriter
---
llvm/utils/TableGen/AsmWriterEmitter.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp
index bc32a494b..8e2bd70c6 100644
--- a/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -1171,7 +1171,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O.indent(2) << "const char *AsmString;\n";
#ifdef CAPSTONE
O << " unsigned I = 0;\n";
- O << " char *tmpString;\n";
+ O << "#define ASMSTRING_CONTAIN_SIZE 64\n";
+ O << " unsigned AsmStringLen = 0;\n";
+ O << " char tmpString_[ASMSTRING_CONTAIN_SIZE];\n";
+ O << " char *tmpString = tmpString_;\n";
O.indent(2) << "switch (MCInst_getOpcode(MI)) {\n";
#else
O.indent(2) << "switch (MI->getOpcode()) {\n";
@@ -1186,7 +1189,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
O << " unsigned I = 0;\n";
#endif
#ifdef CAPSTONE
- O << " tmpString = cs_strdup(AsmString);\n";
+ O << " AsmStringLen = strlen(AsmString);\n";
+ O << " if (ASMSTRING_CONTAIN_SIZE - 1 < AsmStringLen)\n";
+ O << " tmpString = cs_strdup(AsmString);\n";
+ O << " else\n";
+ O << " tmpString = memcpy(tmpString, AsmString, 1 + AsmStringLen);\n\n";
#endif
O << " while (AsmString[I] != ' ' && AsmString[I] != '\\t' &&\n";
O << " AsmString[I] != '$' && AsmString[I] != '\\0')\n";
@@ -1194,7 +1201,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
#ifdef CAPSTONE
O << " tmpString[I] = 0;\n";
O << " SStream_concat0(OS, tmpString);\n";
- O << " cs_mem_free(tmpString);\n";
+ O << " if (ASMSTRING_CONTAIN_SIZE - 1 < AsmStringLen)\n";
+ O << " /* Free the possible cs_strdup() memory. PR#1424. */\n";
+ O << " cs_mem_free(tmpString);\n";
+ O << "#undef ASMSTRING_CONTAIN_SIZE\n\n";
#else
O << " OS << '\\t' << StringRef(AsmString, I);\n";
#endif
--
2.20.1

View File

@@ -0,0 +1,61 @@
# How to update RISCV tables.
* Checkout LLVM. Patches are tested on commit `b81d715c`.
```
git clone https://github.com/llvm/llvm-project.git
git checkout b81d715c
```
* Apply patches from the current directory.
* Run tablegen.
```
cd $LLVM
mkdir build
cd build
cmake -DCMAKE_CXX_FLAGS=-DCAPSTONE -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" ..
make RISCVCommonTableGen
```
* Copy `.inc` files.
```
cp arch/RISCV/RISCVGenInsnNameMaps.inc \
arch/RISCV/RISCVGenInsnNameMaps.inc.old
for inc in $(cd arch/RISCV && ls *.inc); do
cp $LLVM/build/lib/Target/RISCV/$inc arch/RISCV/
done
```
* Fixup `RISCVGenInsnNameMaps.inc`.
```
comm -1 -3 \
<(grep RISCV_INS_ <arch/RISCV/RISCVGenInsnNameMaps.inc.old \
| sort -u) \
<(grep RISCV_INS_ <arch/RISCV/RISCVGenInsnNameMaps.inc \
| sort -u) \
>arch/RISCV/RISCVGenInsnNameMaps.inc.new
cat arch/RISCV/RISCVGenInsnNameMaps.inc.old \
arch/RISCV/RISCVGenInsnNameMaps.inc.new \
>arch/RISCV/RISCVGenInsnNameMaps.inc
```
* Add new groups, insns, registers and formats.
* `include/capstone/RISCV.h`
* `enum RISCV_insn`:
```
comm -1 -3 \
<(perl -ne 'if (/(RISCV_INS_.+),/) { print "\t$1,\n" }' \
<include/capstone/RISCV.h | sort -u) \
<(perl -ne 'if (/(RISCV_INS_.+),/) { print "\t$1,\n" }' \
<arch/RISCV/RISCVMappingInsn.inc | sort -u)
```
* `enum RISCV_insn_group`:
```
perl -ne 'if (/(\{.RISCV_GRP_.*?\}),/) { print "\t$1,\n"; }' < \
arch/RISCV/RISCVMappingInsn.inc | sort -u
```
* `arch/RISCV/RISCVDisassembler.c`
* `arch/RISCV/RISCVInstPrinter.c`
* `arch/RISCV/RISCVMCTargetDesc.c`
* `arch/RISCV/RISCVMCTargetDesc.h`
* `arch/RISCV/RISCVMapping.c`
* `enum group_name_maps`:
```
perl -ne 'if (/(RISCV_GRP_(.*?)),/) { print "\t{ $1, \"" . lc($2) . "\" },\n"; }' \
arch/RISCV/RISCVMappingInsn.inc | sort -u
```

View File

@@ -0,0 +1,11 @@
For Windows kernel programming, the SDK does not offer some functions
needed by Capstone. The missing functions are:
- Memory allocations: malloc(), calloc(), realloc() & free().
- Format input variables & write out result to char buffer: vsnprintf()
This directory contains some code providing above-mentioned functions, so you can
integrate Capstone with your Windows-kernel drivers using C++.
All the code here is contributed by Peter Hlavaty <zer0mem@yahoo.com>
See the full example with Capstone integration at https://github.com/zer0mem/libc.git

View File

@@ -0,0 +1,143 @@
/**
* @file libc.cpp
* @author created by: Peter Hlavaty
*/
#include "libc.h"
#include <memory>
#include <Ntintsafe.h>
#pragma warning(push)
#pragma warning (disable : 4565)
#ifndef _LIBC_POOL_TAG
#define _LIBC_POOL_TAG 'colM'
#endif
// very nice for debug forensics!
struct MEMBLOCK
{
size_t size;
#pragma warning(push)
#pragma warning (disable : 4200)
__declspec(align(MEMORY_ALLOCATION_ALIGNMENT))
char data[0];
#pragma warning(pop)
};
EXTERN_C
__drv_when(return!=0, __drv_allocatesMem(pBlock))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size)
void*
__cdecl malloc(
__in size_t size
)
{
/* A specially crafted size value can trigger the overflow.
If the sum in a value that overflows or underflows the capacity of the type,
the function returns nullptr. */
size_t number_of_bytes = 0;
if (!NT_SUCCESS(RtlSizeTAdd(size, sizeof(MEMBLOCK), &number_of_bytes))){
return nullptr;
}
MEMBLOCK *pBlock = static_cast<MEMBLOCK*>(
ExAllocatePoolWithTag(
NonPagedPoolNxCacheAligned,
number_of_bytes,
_LIBC_POOL_TAG));
if (nullptr == pBlock)
return nullptr;
pBlock->size = size;
return pBlock->data;
}
EXTERN_C
__drv_when(return != 0, __drv_allocatesMem(p))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size * n)
void*
__cdecl calloc(size_t n, size_t size)
{
size_t total = n * size;
void *p = malloc(total);
if (!p) return NULL;
return memset(p, 0, total);
}
EXTERN_C
__drv_when(return!=0, __drv_allocatesMem(inblock))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size)
void*
__cdecl realloc(
__in_opt void* ptr,
__in size_t size
)
{
if (!ptr)
return malloc(size);
std::unique_ptr<unsigned char> inblock = std::unique_ptr<unsigned char>(static_cast<unsigned char*>(ptr));
// alloc new block
void* mem = malloc(size);
if (!mem)
return nullptr;
// copy from old one, not overflow ..
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data)->size, size));
return mem;
}
EXTERN_C
__drv_maxIRQL(DISPATCH_LEVEL)
void
__cdecl free(
__inout_opt __drv_freesMem(Mem) void* ptr
)
{
if (ptr)
ExFreePoolWithTag(CONTAINING_RECORD(ptr, MEMBLOCK, data), _LIBC_POOL_TAG);
}
#pragma warning(pop)
__drv_when(return!=0, __drv_allocatesMem(ptr))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size)
void*
__cdecl operator new(
__in size_t size
)
{
return malloc(size);
}
__drv_maxIRQL(DISPATCH_LEVEL)
void
__cdecl operator delete(
__inout void* ptr
)
{
free(ptr);
}
int
__cdecl vsnprintf(
char *buffer,
size_t count,
const char *format,
va_list argptr
)
{
return vsprintf_s(buffer, count, format, argptr);
}

View File

@@ -0,0 +1,40 @@
/**
* @file libc.h
* @author created by: Peter Hlavaty
*/
#pragma once
#include <ntifs.h>
EXTERN_C
__drv_when(return!=0, __drv_allocatesMem(pBlock))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size)
void* __cdecl malloc(__in size_t size);
EXTERN_C
__drv_when(return != 0, __drv_allocatesMem(p))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size * n)
void* __cdecl calloc(size_t n, size_t size);
EXTERN_C
__drv_when(return!=0, __drv_allocatesMem(inblock))
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
__bcount_opt(size)
void* __cdecl realloc(__in_opt void* ptr, __in size_t size);
EXTERN_C
__drv_maxIRQL(DISPATCH_LEVEL)
void __cdecl free(__inout_opt __drv_freesMem(Mem) void* ptr);
int __cdecl vsnprintf(char *buffer, size_t count,
const char *format, va_list argptr);