mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 11:31:43 +00:00
Merge remote-tracking branch 'origin/ghidra1_Emulator'
Conflicts: gradle/root/eclipse.gradle
This commit is contained in:
commit
e0e2c58eb7
6
.gitignore
vendored
6
.gitignore
vendored
@ -63,3 +63,9 @@ Release
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
|
||||
# Ignore XTEXT generated dirs/files
|
||||
*/*/*/*/xtend-gen
|
||||
*/*/*/*/src-gen
|
||||
*/*/*/*/model/generated
|
||||
*/*/*/*/test-bin
|
||||
|
@ -1,3 +1,5 @@
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle"
|
||||
|
@ -4,3 +4,4 @@
|
||||
Module.manifest||Public Domain||||END|
|
||||
build.gradle||Public Domain||||END|
|
||||
data/cabextract-1.6.tar.gz||GPL 3||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
|
0
GPL/CabExtract/settings.gradle
Normal file
0
GPL/CabExtract/settings.gradle
Normal file
@ -1,13 +1,13 @@
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle"
|
||||
|
||||
rootProject.assembleDistribution {
|
||||
|
||||
doLast {
|
||||
// eliminate standard module lib directory
|
||||
def assemblePath = destinationDir.path + "/" + getZipPath(this.project)
|
||||
println "DELETE: ${assemblePath}/lib"
|
||||
delete assemblePath + "/lib"
|
||||
}
|
||||
}
|
||||
@ -28,6 +28,7 @@ eclipse.project.name = 'GPL DMG'
|
||||
*
|
||||
*********************************************************************************/
|
||||
sourceSets {
|
||||
|
||||
dmg {
|
||||
java {
|
||||
srcDir 'src/dmg/java'
|
||||
|
@ -16,3 +16,4 @@ data/os/win64/llio_amd64.dll||GPL 3||||END|
|
||||
data/os/win64/llio_i386.dll||GPL 3||||END|
|
||||
data/os/win64/llio_ia64.dll||GPL 3||||END|
|
||||
data/server_memory.cfg||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
|
0
GPL/DMG/settings.gradle
Normal file
0
GPL/DMG/settings.gradle
Normal file
@ -1,3 +1,4 @@
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
|
||||
|
@ -6,4 +6,5 @@
|
||||
##MODULE IP: Public Domain
|
||||
Module.manifest||Public Domain||||END|
|
||||
build.gradle||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
src/demangler_gnu/README.txt||Public Domain||||END|
|
||||
|
0
GPL/DemanglerGnu/settings.gradle
Normal file
0
GPL/DemanglerGnu/settings.gradle
Normal file
0
GPL/GnuDisassembler/Module.manifest
Normal file
0
GPL/GnuDisassembler/Module.manifest
Normal file
20
GPL/GnuDisassembler/README.txt
Normal file
20
GPL/GnuDisassembler/README.txt
Normal file
@ -0,0 +1,20 @@
|
||||
The GnuDisassembler extension module must be built using gradle prior to its' use within Ghidra.
|
||||
|
||||
This module provides the ability to leverage the binutils disassembler capabilities
|
||||
for various processors as a means of verifying Sleigh disassembler output syntax.
|
||||
|
||||
To build this extension for Linux or Mac OS X:
|
||||
|
||||
1. If building for an installation of Ghidra, copy the appropriate source distribution of
|
||||
binutils into this module's root directory. If building within a git clone of the full
|
||||
Ghidra source, copy binutils source distribution file into the ghidra.bin/GPL/GnuDisassembler
|
||||
directory.
|
||||
|
||||
The supported version and archive format is identified within the build.gradle file.
|
||||
If a different binutils distribution is used the build.gradle and/or buildGdis.gradle
|
||||
may require modification.
|
||||
|
||||
2. Run gradle from the module's root directory (see top of build.gradle file for
|
||||
specific instructions).
|
||||
|
||||
This resulting gdis executable will be located in build/os/<platform>.
|
81
GPL/GnuDisassembler/build.gradle
Normal file
81
GPL/GnuDisassembler/build.gradle
Normal file
@ -0,0 +1,81 @@
|
||||
// If extension module does not reside within the Ghidra GPL directory, the Ghidra installation directory
|
||||
// must be specified either by setting the GHIDRA_INSTALL_DIR environment variable or Gradle
|
||||
// project property:
|
||||
//
|
||||
// > export GHIDRA_INSTALL_DIR=<Absolute path to Ghidra>
|
||||
// > gradle build
|
||||
//
|
||||
// or
|
||||
//
|
||||
// > gradle -PGHIDRA_INSTALL_DIR=<Absolute path to Ghidra> build
|
||||
//
|
||||
// In addition, the appropriate binutils source distribution archive must be placed
|
||||
// within this module's directory (see below for binutils version and archive file naming.
|
||||
//
|
||||
// Gradle should be invoked from the directory of the extension module to build. Please see the
|
||||
// application.gradle.version property in <GHIDRA_INSTALL_DIR>/Ghidra/application.properties
|
||||
// for the correction version of Gradle to use for the Ghidra installation you specify.
|
||||
//
|
||||
// Build Prerequisite:
|
||||
// The appropriate binutils source distribution archive (see version and naming below) must be
|
||||
// obtained and placed appropriately prior to building the gdis executable. If working with
|
||||
// a full source distribution of Ghidra the binutils archive should be placed within the module's
|
||||
// shadow directory located within ghidra.bin (ghidra.bin/GPL/GnuDisassembler/). If building within
|
||||
// an unpacked distribution of Ghidra it should be placed directly within the module
|
||||
// directory once the extension has been installed/unpacked by Ghidra. The binutils referenced
|
||||
// by the script below may be downloaded from the following URL:
|
||||
//
|
||||
// https://ftp.gnu.org/pub/gnu/binutils/binutils-2.29.1.tar.bz2
|
||||
//
|
||||
|
||||
ext.binutils = "binutils-2.29.1"
|
||||
ext.binutilsDistro = "${binutils}.tar.bz2"
|
||||
|
||||
ext.ghidraInstallDir = null;
|
||||
|
||||
if (file("../gpl.gradle").exists()) {
|
||||
// Module is located within the Ghidra GPL directory
|
||||
ext.ghidraInstallDir = file("../..").getCanonicalPath()
|
||||
ext.binutilsLocation = file("${ghidraInstallDir}/../ghidra.bin/GPL/${name}").getCanonicalPath()
|
||||
apply from: file("../gpl.gradle").getCanonicalPath()
|
||||
}
|
||||
else {
|
||||
// various module placements for Ghidra installations
|
||||
ext.binutilsLocation = projectDir
|
||||
if (file("../../../GPL/gpl.gradle").exists()) {
|
||||
// Handle GPL extension install within Ghidra Extensions directory
|
||||
ext.ghidraInstallDir = file("../../..").getCanonicalPath()
|
||||
}
|
||||
else {
|
||||
// Handle extension install outside of Ghidra installation - must specify Ghidra install path
|
||||
if (System.env.GHIDRA_INSTALL_DIR) {
|
||||
ext.ghidraInstallDir = System.env.GHIDRA_INSTALL_DIR
|
||||
}
|
||||
else if (project.hasProperty("GHIDRA_INSTALL_DIR")) {
|
||||
ext.ghidraInstallDir = project.getProperty("GHIDRA_INSTALL_DIR")
|
||||
}
|
||||
}
|
||||
if (ghidraInstallDir) {
|
||||
if (ghidraInstallDir.replace("\\","/").endsWith("/")) {
|
||||
ext.ghidraInstallDir = ghidraInstallDir.substring(0, ghidraInstallDir.length()-1)
|
||||
}
|
||||
println "Building with Ghidra installation at $ghidraInstallDir"
|
||||
apply from: new File(ghidraInstallDir).getCanonicalPath() + "/GPL/gpl.gradle"
|
||||
}
|
||||
else {
|
||||
throw new GradleException("GHIDRA_INSTALL_DIR is not defined!")
|
||||
}
|
||||
}
|
||||
|
||||
if (findProject(':Generic') != null) {
|
||||
// Handle integrated Ghidra build - do not build gdis native
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGPLExtension.gradle"
|
||||
delete file("build/os"); // remove any prior build of gdis
|
||||
}
|
||||
else {
|
||||
apply from: "${ghidraInstallDir}/GPL/nativeBuildProperties.gradle"
|
||||
apply from: "buildGdis.gradle"
|
||||
}
|
||||
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Xtra GPL GnuDisassembler'
|
169
GPL/GnuDisassembler/buildGdis.gradle
Normal file
169
GPL/GnuDisassembler/buildGdis.gradle
Normal file
@ -0,0 +1,169 @@
|
||||
/*******************************************************************************************
|
||||
* build.gradle file that applies this script must define two properties
|
||||
* 1) binutilsLocation - the folder where the original binutils.zip lives
|
||||
* 2) binutilsPrebuiltPath - the folder where the custom prebuilt binutils lives or will be built to
|
||||
*******************************************************************************************/
|
||||
|
||||
defaultTasks 'assemble'
|
||||
|
||||
ext.supportedPlatforms = ['osx64', 'linux64']
|
||||
|
||||
ext.binutilsResource = new File("${binutilsLocation}/${binutils}.tar.bz2")
|
||||
|
||||
def binutilsUnpackDir = file("${project.buildDir}/${binutils}/")
|
||||
|
||||
/******************************************************************************************
|
||||
*
|
||||
* For each supported platform build the following tasks:
|
||||
* buildBinutils_<platform> builds binutils for the platform
|
||||
* packageBinutilsDev_<platform> creates the built bundle of stuf we need to build gdis
|
||||
* unpackBinutilsPrebuilt_<platform> unpacks the built bundle to be used to build gdis
|
||||
*
|
||||
******************************************************************************************/
|
||||
|
||||
model {
|
||||
platforms {
|
||||
linux64 {
|
||||
architecture 'x86_64'
|
||||
operatingSystem 'linux'
|
||||
}
|
||||
osx64 {
|
||||
architecture 'x86_64'
|
||||
operatingSystem 'osx'
|
||||
}
|
||||
}
|
||||
|
||||
components {
|
||||
|
||||
gdis(NativeExecutableSpec) {
|
||||
|
||||
// NOTE: Windows build requires Mingw and is very very slow and touchy
|
||||
supportedPlatforms.each { targetPlatform it}
|
||||
|
||||
sources {
|
||||
c {
|
||||
source {
|
||||
srcDir "src/gdis/c"
|
||||
include "disasm_1.c"
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries {
|
||||
all {
|
||||
def binutilsArtifactsDir = file("build/binutils/${targetPlatform.name}")
|
||||
if ((toolChain in Gcc) || (toolChain in Clang)) {
|
||||
cCompiler.args "-I${binutilsArtifactsDir}/include", "-I${binutilsArtifactsDir}/bfd"
|
||||
linker.args "-L${binutilsArtifactsDir}/lib", "-lopcodes", "-lbfd", "-liberty", "-lz", "-ldl"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.compileGdisOsx64ExecutableGdisC {
|
||||
dependsOn 'copyBinutilsArtifcats_osx64'
|
||||
}
|
||||
tasks.compileGdisLinux64ExecutableGdisC {
|
||||
dependsOn 'copyBinutilsArtifcats_linux64'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// change gdis linker output directory to build/os/<platform>
|
||||
gradle.taskGraph.whenReady {
|
||||
def p = this.project
|
||||
p.tasks.withType(LinkExecutable).each { t ->
|
||||
File f = t.linkedFile.getAsFile().get()
|
||||
String filename = f.getName()
|
||||
NativePlatform platform = t.targetPlatform.get()
|
||||
String osName = platform.getName()
|
||||
t.linkedFile = p.file("build/os/${osName}/$filename")
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************************
|
||||
* Task to unpack the standard binutils zip file
|
||||
*******************************************************************************************/
|
||||
task binutilsUnpack {
|
||||
description "Unpack binutils (for building gdis)"
|
||||
group "Native Build Dependencies"
|
||||
outputs.file { binutilsUnpackDir }
|
||||
onlyIf { !binutilsUnpackDir.exists() }
|
||||
|
||||
doFirst {
|
||||
if (!binutilsResource.exists()) {
|
||||
throw new GradleException("${binutilsResource.getCanonicalPath()} not found")
|
||||
}
|
||||
}
|
||||
|
||||
doLast {
|
||||
copy {
|
||||
from tarTree(resources.bzip2("${binutilsResource}"))
|
||||
into file("build")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
supportedPlatforms.each { platform ->
|
||||
|
||||
def buildName = "buildBinutils_${platform}"
|
||||
def postBuildName = "copyBinutilsArtifcats_${platform}"
|
||||
|
||||
def configDir = file("build/config/${platform}")
|
||||
def artifactsDir = file("build/binutils/${platform}")
|
||||
|
||||
task(buildName) {
|
||||
description "Configure and make binutils for $platform (for building gdis)"
|
||||
group "Native Prebuild Dependencies"
|
||||
|
||||
onlyIf { !configDir.exists() }
|
||||
|
||||
dependsOn binutilsUnpack
|
||||
|
||||
inputs.dir binutilsUnpackDir
|
||||
outputs.dir configDir
|
||||
|
||||
doLast {
|
||||
|
||||
File binutilsDir = binutilsUnpackDir
|
||||
delete configDir
|
||||
|
||||
println "Configuring binutils - config directory: $configDir"
|
||||
println "${binutilsDir}/configure --prefix=\"${configDir}\" --enable-targets=all --with-zlib=no --disable-nls --disable-werror"
|
||||
configDir.mkdirs();
|
||||
exec {
|
||||
workingDir configDir
|
||||
commandLine "${binutilsDir}/configure", "--prefix=${configDir}", "--enable-targets=all", "--with-zlib=no", "--disable-nls", "--disable-werror"
|
||||
}
|
||||
|
||||
println "Building binutils - config directory: $configDir"
|
||||
exec {
|
||||
commandLine "make", "-C", "${configDir}", "all"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task(postBuildName, type: Copy) {
|
||||
description "Copy binutil artifcacts for $platform (for building gdis)"
|
||||
group "Native Prebuild Dependencies"
|
||||
|
||||
dependsOn buildName
|
||||
|
||||
destinationDir = artifactsDir
|
||||
|
||||
into("/include") {
|
||||
from("${binutilsUnpackDir}/include")
|
||||
include "**/*.h"
|
||||
}
|
||||
into("/bfd") {
|
||||
from "${configDir}/bfd"
|
||||
include "**/*.h"
|
||||
}
|
||||
into("/lib") {
|
||||
from "${configDir}/bfd/libbfd.a"
|
||||
from "${configDir}/libiberty/libiberty.a"
|
||||
from "${configDir}/opcodes/libopcodes.a"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
13
GPL/GnuDisassembler/certification.manifest
Normal file
13
GPL/GnuDisassembler/certification.manifest
Normal file
@ -0,0 +1,13 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: GPL 2
|
||||
##MODULE IP: Public Domain
|
||||
.project||GHIDRA||||END|
|
||||
Module.manifest||Public Domain||||END|
|
||||
README.txt||Public Domain||||END|
|
||||
build.gradle||Public Domain||||END|
|
||||
buildGdis.gradle||Public Domain||||END|
|
||||
data/arm_test1.s||Public Domain||||END|
|
||||
data/big.elf||Public Domain||||END|
|
||||
data/little.elf||Public Domain||||END|
|
||||
extension.properties||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
7
GPL/GnuDisassembler/data/arm_test1.s
Normal file
7
GPL/GnuDisassembler/data/arm_test1.s
Normal file
@ -0,0 +1,7 @@
|
||||
.text
|
||||
__start:
|
||||
lw $t0, #4
|
||||
li $t1, #0
|
||||
add $t2, $t0, $t1
|
||||
done
|
||||
|
BIN
GPL/GnuDisassembler/data/big.elf
Normal file
BIN
GPL/GnuDisassembler/data/big.elf
Normal file
Binary file not shown.
BIN
GPL/GnuDisassembler/data/little.elf
Normal file
BIN
GPL/GnuDisassembler/data/little.elf
Normal file
Binary file not shown.
6
GPL/GnuDisassembler/extension.properties
Normal file
6
GPL/GnuDisassembler/extension.properties
Normal file
@ -0,0 +1,6 @@
|
||||
name=GnuDisassembler
|
||||
description=GNU Disassembler. Extension is delivered unbuilt. See module README.txt for build instructions.
|
||||
author=Ghidra Team
|
||||
createdOn=6/18/2019
|
||||
version=@extversion@
|
||||
gpl=true
|
0
GPL/GnuDisassembler/settings.gradle
Normal file
0
GPL/GnuDisassembler/settings.gradle
Normal file
457
GPL/GnuDisassembler/src/gdis/c/disasm_1.c
Normal file
457
GPL/GnuDisassembler/src/gdis/c/disasm_1.c
Normal file
@ -0,0 +1,457 @@
|
||||
/* ###
|
||||
* IP: Public Domain
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "bfd.h"
|
||||
#include "dis-asm.h"
|
||||
// #include "bucomm.h" // for set_default_bfd_target()
|
||||
|
||||
#include "gdis.h"
|
||||
|
||||
#define MAX_ASCII_CHAR_BYTE_STRING 256
|
||||
|
||||
|
||||
void listSupportedArchMachTargets(void)
|
||||
{
|
||||
const char** targetList;
|
||||
const char** archList;
|
||||
int i, j;
|
||||
|
||||
targetList = bfd_target_list();
|
||||
if(targetList != NULL){
|
||||
for(i=0, j=0; targetList[i] !=0; i++){
|
||||
printf("Supported Target: %s\n", targetList[i]);
|
||||
}
|
||||
}
|
||||
printf("\ndone with targetList.\n");
|
||||
|
||||
archList = bfd_arch_list();
|
||||
if(archList != NULL){
|
||||
for(i=0, j=0; archList[i] !=0; i++){
|
||||
printf("Supported Arch: %s\n", archList[i]);
|
||||
}
|
||||
}
|
||||
printf("\ndone with archList.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* sprintf to a "stream". */
|
||||
int objdump_sprintf (SFILE *f, const char *format, ...)
|
||||
{
|
||||
|
||||
int i;
|
||||
size_t n;
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
n = vsnprintf (f->buffer + f->pos, BUFF_SIZE, format, args);
|
||||
strncat(disassembled_buffer, f->buffer, n);
|
||||
va_end (args);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void configureDisassembleInfo(bfd* abfd,
|
||||
disassemble_info* info,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian end)
|
||||
{
|
||||
|
||||
memset(sfile.buffer, 0x00, BUFF_SIZE);
|
||||
|
||||
INIT_DISASSEMBLE_INFO(*info, stdout, objdump_sprintf);
|
||||
info->arch = (enum bfd_architecture) arch;
|
||||
info->mach = mach;
|
||||
info->flavour = bfd_get_flavour(abfd);
|
||||
info->endian = end;
|
||||
info->stream = (FILE*)&sfile; // set up our "buffer stream"
|
||||
info->display_endian = BFD_ENDIAN_LITTLE;
|
||||
/* Allow the target to customize the info structure. */
|
||||
disassemble_init_for_target(info);
|
||||
}
|
||||
|
||||
disassembler_ftype configureBfd(bfd* abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian endian,
|
||||
disassemble_info* DI,
|
||||
disassembler_ftype* disassemble_fn)
|
||||
{
|
||||
struct bfd_target *xvec;
|
||||
|
||||
abfd->flags |= EXEC_P;
|
||||
|
||||
|
||||
// set up xvec byteorder.
|
||||
xvec = (struct bfd_target *) malloc (sizeof (struct bfd_target));
|
||||
memset(xvec, 0x00, sizeof (struct bfd_target));
|
||||
memcpy (xvec, abfd->xvec, sizeof (struct bfd_target));
|
||||
xvec->byteorder = endian;
|
||||
abfd->xvec = xvec;
|
||||
|
||||
configureDisassembleInfo(abfd, DI, arch, mach, endian);
|
||||
if(endian == BFD_ENDIAN_BIG){
|
||||
bfd_big_endian(abfd);
|
||||
DI->display_endian = DI->endian = BFD_ENDIAN_BIG;
|
||||
}
|
||||
else{
|
||||
bfd_little_endian(abfd);
|
||||
DI->display_endian = DI->endian = BFD_ENDIAN_LITTLE;
|
||||
}
|
||||
|
||||
/*
|
||||
bfd_error_type err = bfd_get_error();
|
||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||
*/
|
||||
|
||||
/* Use libopcodes to locate a suitable disassembler. */
|
||||
*disassemble_fn = NULL;
|
||||
*disassemble_fn = disassembler (arch, endian == BFD_ENDIAN_BIG, mach, abfd);
|
||||
if (!*disassemble_fn){
|
||||
printf("can't disassemble for arch 0x%08X, mach 0x%08lX\n", arch, mach);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return *disassemble_fn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int disassemble_buffer( disassembler_ftype disassemble_fn,
|
||||
disassemble_info *info,
|
||||
int* offset,
|
||||
PDIS_INFO pDisInfo)
|
||||
{
|
||||
int i, j, size = 0;
|
||||
int len = 0;
|
||||
|
||||
while ( *offset < info->buffer_length ) {
|
||||
/* call the libopcodes disassembler */
|
||||
memset(pDisInfo->disassemblyString, 0x00, MAX_DIS_STRING);
|
||||
|
||||
/* set the insn_info_valid bit to 0, as explained in BFD's
|
||||
* include/dis-asm.h. The bit will then be set to tell us
|
||||
* whether the decoder supports "extra" information about the
|
||||
* instruction.
|
||||
*/
|
||||
info->insn_info_valid = 0;
|
||||
|
||||
size = (*disassemble_fn)(info->buffer_vma + *offset, info);
|
||||
/* -- analyze disassembled instruction here -- */
|
||||
/* -- print any symbol names as labels here -- */
|
||||
|
||||
/* save off corresponding hex bytes */
|
||||
for ( j= 0,i = 0; i < 8; i++, j+=3) {
|
||||
if ( i < size ){
|
||||
sprintf(&(pDisInfo->bytesBufferAscii[j]), "%02X ", info->buffer[*offset + i]);
|
||||
pDisInfo->bytesBufferBin[i] = info->buffer[*offset + i];
|
||||
}
|
||||
}
|
||||
|
||||
/* add the augmented information to our disassembly info struct */
|
||||
pDisInfo->count = size;
|
||||
pDisInfo->insn_info_valid = info->insn_info_valid;
|
||||
pDisInfo->branch_delay_insns = info->branch_delay_insns;
|
||||
pDisInfo->data_size = info->data_size;
|
||||
pDisInfo->insn_type = info->insn_type;
|
||||
pDisInfo->target = info->target;
|
||||
pDisInfo->target2 = info->target2;
|
||||
|
||||
strcat(&(pDisInfo->disassemblyString[0]), disassembled_buffer);
|
||||
memset(disassembled_buffer, 0x00, BUFF_SIZE);
|
||||
|
||||
if(size != 0){
|
||||
*offset += size; /* advance position in buffer */
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
return size;
|
||||
}
|
||||
|
||||
void processBuffer(unsigned char* buff,
|
||||
int buff_len,
|
||||
bfd_vma buff_vma,
|
||||
disassembler_ftype disassemble_fn,
|
||||
struct disassemble_info* DI)
|
||||
{
|
||||
int bytesConsumed = -1;
|
||||
int offset = 0;
|
||||
int numDisassemblies = 0;
|
||||
int i;
|
||||
|
||||
DI->buffer = buff; /* buffer of bytes to disassemble */
|
||||
DI->buffer_length = buff_len; /* size of buffer */
|
||||
DI->buffer_vma = buff_vma; /* base RVA of buffer */
|
||||
|
||||
memset(disassemblyInfoBuffer, 0x00, sizeof(DIS_INFO)*MAX_NUM_ENTRIES);
|
||||
|
||||
while((buff_len - offset) > 0 && bytesConsumed != 0 && numDisassemblies < MAX_NUM_ENTRIES){
|
||||
bytesConsumed = disassemble_buffer( disassemble_fn, DI, &offset, &(disassemblyInfoBuffer[numDisassemblies++]));
|
||||
}
|
||||
for (i = 0; i < numDisassemblies; i++) {
|
||||
printf("%s\nInfo: %d,%d,%d,%d,%d\n", disassemblyInfoBuffer[i].disassemblyString,
|
||||
disassemblyInfoBuffer[i].count,
|
||||
disassemblyInfoBuffer[i].insn_info_valid,
|
||||
disassemblyInfoBuffer[i].branch_delay_insns,
|
||||
disassemblyInfoBuffer[i].data_size,
|
||||
disassemblyInfoBuffer[i].insn_type);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
struct disassemble_info DI;
|
||||
enum bfd_architecture arch;
|
||||
struct bfd_arch_info ai;
|
||||
unsigned long mach;
|
||||
enum bfd_endian endian;
|
||||
unsigned int end;
|
||||
bfd_vma offset;
|
||||
disassembler_ftype disassemble_fn;
|
||||
char *target = default_target;
|
||||
bfd *bfdfile;
|
||||
unsigned long a,m;
|
||||
char* byteString;
|
||||
char elf_file_location[MAX_ELF_FILE_PATH_LEN];
|
||||
char arch_str[256];
|
||||
char mach_str[256];
|
||||
|
||||
if ( argc < 8) {
|
||||
fprintf(stderr, "Usage: %s target-str, arch, mach, disassembly base-addr (for rel offsets instrs), full-path to Little and Big Elfs, big/little ascii-byte-string up to %d chars\n", argv[0], MAX_ASCII_CHAR_BYTE_STRING);
|
||||
listSupportedArchMachTargets();
|
||||
const char** archList = bfd_arch_list();
|
||||
const bfd_arch_info_type* ait;
|
||||
while(*archList != NULL){
|
||||
printf("checking against architecture: %s.\n", *archList);
|
||||
ait = NULL;
|
||||
ait = bfd_scan_arch(*archList);
|
||||
if(ait != NULL){
|
||||
printf("archname: %s arch: 0x%08X, mach: 0x%08lX.\n", ait->arch_name, ait->arch, ait->mach);
|
||||
}
|
||||
archList++;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
end = 0x00000000;
|
||||
endian = (enum bfd_endian) 0x00;
|
||||
mach = 0x00000000;
|
||||
arch = (enum bfd_architecture) 0x00;
|
||||
offset = 0x00000000;
|
||||
|
||||
sscanf(argv[2], "%128s", arch_str);
|
||||
sscanf(argv[3], "%18lX", &mach);
|
||||
sscanf(argv[4], "%10X", &end);
|
||||
sscanf(argv[5], "%18lX", &offset);
|
||||
|
||||
// if arch starts with 0x, then parse a number
|
||||
// else lookup the string in the table to get the arch, ignore the mach
|
||||
if (arch_str[0] == '0' && arch_str[1] == 'x') {
|
||||
sscanf(arch_str, "%10X", &arch);
|
||||
} else {
|
||||
const char** archList = bfd_arch_list();
|
||||
const bfd_arch_info_type* ait;
|
||||
while(*archList != NULL){
|
||||
ait = bfd_scan_arch(*archList);
|
||||
if(strcmp(arch_str, *archList)== 0){
|
||||
arch = ait->arch;
|
||||
mach = ait->mach;
|
||||
break;
|
||||
}
|
||||
ait = NULL;
|
||||
archList++;
|
||||
}
|
||||
if (ait == NULL) {
|
||||
printf("Couldn't find arch %s\n", arch_str);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
endian = (enum bfd_endian) end;
|
||||
/* open a correct type of file to fill in most of the required data. */
|
||||
|
||||
// printf("Arch is: 0x%08X, Machine is: 0x%08lX Endian is: 0x%02X.\n", arch, mach, endian);
|
||||
|
||||
memset(elf_file_location, 0x00, MAX_ELF_FILE_PATH_LEN);
|
||||
strncpy(elf_file_location, argv[6], MAX_ELF_FILE_PATH_LEN-sizeof(LITTLE_ELF_FILE)-2); // actual file name and nulls
|
||||
|
||||
// arg[7] is either a hex string or the string "stdin", which
|
||||
// triggers reading line by line from stdin.
|
||||
|
||||
byteString = argv[7];
|
||||
int stdin_mode = 2; // use CLI
|
||||
if (strcmp(byteString, "stdin") == 0) {
|
||||
stdin_mode = 1; // use STDIN
|
||||
}
|
||||
|
||||
unsigned char byteBuffer[BYTE_BUFFER_SIZE];
|
||||
char byteStringBuffer[(BYTE_BUFFER_SIZE*2)];
|
||||
|
||||
char addressStringBuffer[128];
|
||||
|
||||
if (endian == BFD_ENDIAN_BIG){
|
||||
strcat(elf_file_location, BIG_ELF_FILE);
|
||||
}
|
||||
else {
|
||||
strcat(elf_file_location, LITTLE_ELF_FILE);
|
||||
}
|
||||
|
||||
while (stdin_mode) {
|
||||
|
||||
// convert user input AsciiHex to Binary data for processing
|
||||
char tmp[3];
|
||||
unsigned int byteValue;
|
||||
tmp[0] = tmp[1] = tmp[2] = 0x00;
|
||||
|
||||
if (stdin_mode == 1) { // use stdin
|
||||
// read in the address
|
||||
if (fgets(addressStringBuffer, sizeof(addressStringBuffer), stdin)) {
|
||||
|
||||
//fprintf(stderr, "read: %s\n", addressStringBuffer);
|
||||
//char *p = strchr(addressStringBuffer, '\n');
|
||||
//if (p) {
|
||||
// *p = '\0';
|
||||
//}
|
||||
|
||||
sscanf(addressStringBuffer, "%18lX", &offset);
|
||||
}
|
||||
//getchar();
|
||||
// read in the ASCII hex string from stdin
|
||||
if (fgets(byteStringBuffer, sizeof(byteStringBuffer), stdin)) {
|
||||
|
||||
//fprintf(stderr, "read: %s\n", byteStringBuffer);
|
||||
// remove trailing newline
|
||||
char *p = strchr(byteStringBuffer, '\n');
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
}
|
||||
//if (strcmp(byteStringBuffer, "EOF") == 0) {
|
||||
//return 0; // terminate on EOF string
|
||||
//}
|
||||
} else {
|
||||
fprintf(stderr, "exiting, no ASCII hex found\n");
|
||||
return 0; // finished! #TODO
|
||||
}
|
||||
|
||||
} else {
|
||||
if(strlen(byteString) > BYTE_BUFFER_SIZE*2) {
|
||||
fprintf(stderr, "Max ascii string size is %d you provided: %lu chars. Exiting.\n", BYTE_BUFFER_SIZE*2,
|
||||
strlen(byteString));
|
||||
exit(-1);
|
||||
}
|
||||
strncpy(byteStringBuffer, byteString, BYTE_BUFFER_SIZE*2);
|
||||
stdin_mode = 0; // break out of the while loop
|
||||
}
|
||||
|
||||
int size = strlen(byteStringBuffer);
|
||||
if((size % 2) != 0){
|
||||
fprintf(stderr, "need even-number of ascii chars for byte-stream: (offset: %08lx, %s, %ld)\n", offset, byteStringBuffer, strlen(byteStringBuffer));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(byteBuffer, 0x00, BYTE_BUFFER_SIZE);
|
||||
|
||||
//
|
||||
// TODO:
|
||||
// check to make sure chars are only valid HEX.
|
||||
//
|
||||
int i, j;
|
||||
for(i=j=0; (i < size) && (j < BYTE_BUFFER_SIZE); i+=2, j++){
|
||||
tmp[0] = byteStringBuffer[i];
|
||||
tmp[1] = byteStringBuffer[i+1];
|
||||
tmp[2] = 0;
|
||||
sscanf(tmp, "%02X", &byteValue);
|
||||
byteBuffer[j] = (unsigned char)byteValue;
|
||||
}
|
||||
|
||||
/*
|
||||
for(j=0; j < BYTE_BUFFER_SIZE; j++){
|
||||
printf("0x%02X ", byteBuffer[j]);
|
||||
}
|
||||
*/
|
||||
|
||||
bfd_init( );
|
||||
target = argv[1];
|
||||
bfd_set_default_target(target);
|
||||
|
||||
// printf("Debug: BFD sample file: %s\n", elf_file_location);
|
||||
// printf("Debug: LITTLE: %s\n", LITTLE_ELF_FILE);
|
||||
// printf("Debug: BIG: %s\n", BIG_ELF_FILE);
|
||||
|
||||
if(endian == BFD_ENDIAN_BIG){
|
||||
bfdfile = bfd_openr(elf_file_location, target );
|
||||
if ( ! bfdfile ) {
|
||||
printf("Error opening BIG ELF file: %s\n", elf_file_location);
|
||||
bfd_perror( "Error on bfdfile" );
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
else{
|
||||
bfdfile = bfd_openr(elf_file_location, target );
|
||||
if ( ! bfdfile ) {
|
||||
printf("Error opening LITTLE ELF file: %s\n", elf_file_location);
|
||||
// bfdfile = bfd_openr(elf_file_location, target );
|
||||
bfd_perror( "Error on bfdfile" );
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
|
||||
memset((void*) &DI, 0x00, sizeof(struct disassemble_info));
|
||||
|
||||
disassemble_fn = NULL;
|
||||
|
||||
// important set up!
|
||||
//---------------------------------------
|
||||
ai.arch = arch;
|
||||
ai.mach = mach;
|
||||
bfd_set_arch_info(bfdfile, &ai);
|
||||
//---------------------------------------
|
||||
|
||||
/*
|
||||
bfd_error_type err = bfd_get_error();
|
||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||
*/
|
||||
|
||||
configureBfd(bfdfile, arch, mach, endian, &DI, &disassemble_fn);
|
||||
|
||||
/*
|
||||
err = bfd_get_error();
|
||||
printf("bfd_error_msg: %s.\n", bfd_errmsg(err));
|
||||
*/
|
||||
|
||||
if (disassemble_fn == NULL){
|
||||
fprintf(stderr, "Error: disassemble_fn is NULL. Nothing I can do.\n");
|
||||
exit(1);
|
||||
}
|
||||
else{
|
||||
/*
|
||||
printf("the disassemble_fn func pointer is: 0x%08X.\n", disassemble_fn);
|
||||
printf("We can try to disassemble for this arch/mach. calling disassemble_init_for_target().\n");
|
||||
*/
|
||||
disassemble_init_for_target(&DI);
|
||||
|
||||
// go diassemble the buffer and build up the result in a accumulator string buffer.
|
||||
processBuffer(byteBuffer, size >> 1, offset, disassemble_fn, &DI); //
|
||||
|
||||
}
|
||||
|
||||
free((void*)bfdfile->xvec);
|
||||
bfd_close(bfdfile);
|
||||
|
||||
printf("EOF\n");
|
||||
fflush(stdout);
|
||||
|
||||
} // while loop on lines of stdin
|
||||
|
||||
return 0;
|
||||
}
|
94
GPL/GnuDisassembler/src/gdis/c/gdis.h
Normal file
94
GPL/GnuDisassembler/src/gdis/c/gdis.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* ###
|
||||
* IP: Public Domain
|
||||
*/
|
||||
#ifndef _GDIS_H_
|
||||
#define _GDIS_H_
|
||||
|
||||
#define BYTE_BUFFER_SIZE 128
|
||||
|
||||
#define LITTLE_ELF_FILE "little.elf" // built for intel x64
|
||||
#define BIG_ELF_FILE "big.elf"
|
||||
|
||||
#define BUFF_SIZE 128
|
||||
|
||||
#define MAX_DIS_STRING 128
|
||||
#define MAX_BYTES_STRING 64
|
||||
#define MAX_BYTES 64
|
||||
#define MAX_NUM_ENTRIES 64
|
||||
#define MAX_ELF_FILE_PATH_LEN 512
|
||||
|
||||
|
||||
typedef struct _DIS_INFO_{
|
||||
char disassemblyString[MAX_DIS_STRING];
|
||||
char bytesBufferAscii[MAX_BYTES_STRING];
|
||||
unsigned char bytesBufferBin[MAX_BYTES];
|
||||
|
||||
int count; /* Number of bytes consumed */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
} DIS_INFO, *PDIS_INFO;
|
||||
|
||||
static DIS_INFO disassemblyInfoBuffer[MAX_NUM_ENTRIES];
|
||||
|
||||
char mnemonic[32] = {0}, src[32] = {0}, dest[32] = {0}, arg[32] = {0};
|
||||
char disassembled_buffer[BUFF_SIZE];
|
||||
|
||||
|
||||
/* Pseudo FILE object for strings. */
|
||||
typedef struct
|
||||
{
|
||||
// char *buffer;
|
||||
char buffer[BUFF_SIZE];
|
||||
size_t pos;
|
||||
size_t alloc;
|
||||
} SFILE;
|
||||
|
||||
|
||||
static SFILE sfile;
|
||||
|
||||
static char *default_target = NULL; /* Default at runtime. */
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
void listSupportedArchMachTargets(void);
|
||||
|
||||
int objdump_sprintf (SFILE *f, const char *format, ...);
|
||||
|
||||
void configureDisassembleInfo(bfd* abfd,
|
||||
disassemble_info* info,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian end);
|
||||
|
||||
disassembler_ftype configureBfd(bfd* abfd,
|
||||
enum bfd_architecture arch,
|
||||
unsigned long mach,
|
||||
enum bfd_endian endian,
|
||||
disassemble_info* DI,
|
||||
disassembler_ftype* disassemble_fn);
|
||||
|
||||
int disassemble_buffer( disassembler_ftype disassemble_fn,
|
||||
disassemble_info *info,
|
||||
int* offset,
|
||||
PDIS_INFO pDisInfo);
|
||||
|
||||
void processBuffer(unsigned char* buff,
|
||||
int buff_len,
|
||||
bfd_vma buff_vma,
|
||||
disassembler_ftype disassemble_fn,
|
||||
struct disassemble_info* DI);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -1,5 +1,4 @@
|
||||
##VERSION: 2.0
|
||||
##MODULE IP: Public Domain
|
||||
build.gradle||Public Domain||||END|
|
||||
gpl.gradle||Public Domain||||END|
|
||||
nativeBuildProperties.gradle||Public Domain||||END|
|
||||
settings.gradle||Public Domain||||END|
|
||||
|
@ -1,11 +1,13 @@
|
||||
project.ext.BIN_REPO = file("${projectDir}/../../ghidra.bin").absolutePath
|
||||
|
||||
// BIN_REPO only useable in full Ghidra source configuration
|
||||
project.ext.BIN_REPO = file("../../../ghidra.bin").absolutePath
|
||||
|
||||
project.ext.set("OS_NAMES", ["osx64", "win32", "win64", "linux64"])
|
||||
|
||||
/*********************************************************************************
|
||||
* Returns the local platform name.
|
||||
*********************************************************************************/
|
||||
String getCurrentPlatformName() {
|
||||
ext.getCurrentPlatformName = {
|
||||
|
||||
String osName = System.getProperty("os.name")
|
||||
String archName = System.getProperty("os.arch")
|
||||
@ -37,10 +39,13 @@ String getCurrentPlatformName() {
|
||||
* Helper method that returns a file that is the same relative location in the bin repo
|
||||
* as the given project is in its repo.
|
||||
******************************************************************************************/
|
||||
File getProjectLocationInBinRepo(Project p) {
|
||||
String relativePath = getGhidraRelativePath(p)
|
||||
|
||||
ext.getProjectLocationInBinRepo = {
|
||||
String relativePath = getGhidraRelativePath(this.project)
|
||||
println("RELATIVE: $relativePath")
|
||||
File binRepoRootProject = new File("${BIN_REPO}")
|
||||
if (!binRepoRootProject.isDirectory()) {
|
||||
throw new GradleException("Task requires Ghidra source and ghidra.bin")
|
||||
}
|
||||
return new File(binRepoRootProject, relativePath)
|
||||
}
|
||||
/****************************************************************************************
|
@ -1,4 +0,0 @@
|
||||
|
||||
include "DemanglerGnu"
|
||||
include "DMG"
|
||||
include "CabExtract"
|
0
Ghidra/Extensions/SleighDevTools/Module.manifest
Normal file
0
Ghidra/Extensions/SleighDevTools/Module.manifest
Normal file
9
Ghidra/Extensions/SleighDevTools/build.gradle
Normal file
9
Ghidra/Extensions/SleighDevTools/build.gradle
Normal file
@ -0,0 +1,9 @@
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraExtension.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Xtra SleighDevTools'
|
||||
|
||||
dependencies {
|
||||
compile project(':Base')
|
||||
}
|
34
Ghidra/Extensions/SleighDevTools/certification.manifest
Normal file
34
Ghidra/Extensions/SleighDevTools/certification.manifest
Normal file
@ -0,0 +1,34 @@
|
||||
##VERSION: 2.0
|
||||
.classpath||GHIDRA||||END|
|
||||
.project||GHIDRA||||END|
|
||||
Module.manifest||GHIDRA||||END|
|
||||
build.gradle||GHIDRA||||END|
|
||||
data/ExtensionPoint.manifest||GHIDRA||||END|
|
||||
data/LanguageMap.txt||GHIDRA||||END|
|
||||
extension.properties||GHIDRA||||END|
|
||||
pcodetest/.gitignore||GHIDRA||||END|
|
||||
pcodetest/README.txt||GHIDRA||||END|
|
||||
pcodetest/build||GHIDRA||||END|
|
||||
pcodetest/build.py||GHIDRA||||END|
|
||||
pcodetest/c_src/BIOPS.test||GHIDRA||||END|
|
||||
pcodetest/c_src/BIOPS2.test||GHIDRA||||END|
|
||||
pcodetest/c_src/BIOPS_DOUBLE.test||GHIDRA||||END|
|
||||
pcodetest/c_src/BIOPS_FLOAT.test||GHIDRA||||END|
|
||||
pcodetest/c_src/BIOPS_LONGLONG.test||GHIDRA||||END|
|
||||
pcodetest/c_src/BitManipulation.test||GHIDRA||||END|
|
||||
pcodetest/c_src/DecisionMaking.test||GHIDRA||||END|
|
||||
pcodetest/c_src/GlobalVariables.test||GHIDRA||||END|
|
||||
pcodetest/c_src/IterativeProcessingDoWhile.test||GHIDRA||||END|
|
||||
pcodetest/c_src/IterativeProcessingFor.test||GHIDRA||||END|
|
||||
pcodetest/c_src/IterativeProcessingWhile.test||GHIDRA||||END|
|
||||
pcodetest/c_src/ParameterPassing1.test||GHIDRA||||END|
|
||||
pcodetest/c_src/ParameterPassing2.test||GHIDRA||||END|
|
||||
pcodetest/c_src/ParameterPassing3.test||GHIDRA||||END|
|
||||
pcodetest/c_src/PointerManipulation.test||GHIDRA||||END|
|
||||
pcodetest/c_src/StructUnionManipulation.test||GHIDRA||||END|
|
||||
pcodetest/c_src/misc.test||GHIDRA||||END|
|
||||
pcodetest/c_src/msp430x.ld||GHIDRA||||END|
|
||||
pcodetest/defaults.py||GHIDRA||||END|
|
||||
pcodetest/pcode_defs.py||GHIDRA||||END|
|
||||
pcodetest/pcodetest.py||GHIDRA||||END|
|
||||
pcodetest/tpp.py||GHIDRA||||END|
|
@ -0,0 +1 @@
|
||||
ExternalDisassembler
|
13
Ghidra/Extensions/SleighDevTools/data/LanguageMap.txt
Normal file
13
Ghidra/Extensions/SleighDevTools/data/LanguageMap.txt
Normal file
@ -0,0 +1,13 @@
|
||||
// Format: LanguageID#CustomGDISExecutable
|
||||
//
|
||||
// Mapping of LanguageNameFromGhidra to external (gdis) architecture names is no longer done here.
|
||||
// This functionality has been moved to each language's ldefs file.
|
||||
// External names are mapped via 'external_name' tags in language definitions.
|
||||
// The CustomGDISExecutable is found via a call to Application.getOSFile(), which will search in
|
||||
// the platform-specific OS directory within all modules.
|
||||
//
|
||||
// Lines starting with "//" are not parsed.
|
||||
//
|
||||
// '*' can be used to wild-card parts of the languageID
|
||||
//
|
||||
|
5
Ghidra/Extensions/SleighDevTools/extension.properties
Normal file
5
Ghidra/Extensions/SleighDevTools/extension.properties
Normal file
@ -0,0 +1,5 @@
|
||||
name=SleighDevTools
|
||||
description=Sleigh language development tools including external disassembler capabilities. The GnuDisassembler extension may be also be required as a disassembly provider.
|
||||
author=Ghidra Team
|
||||
createdOn=6/18/2019
|
||||
version=@extversion@
|
@ -0,0 +1,320 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Compare Sliegh disassembly with external disassembly results
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.PseudoDisassembler;
|
||||
import ghidra.app.util.PseudoInstruction;
|
||||
import ghidra.app.util.disassemble.GNUExternalDisassembler;
|
||||
import ghidra.program.disassemble.Disassembler;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.UnknownInstructionException;
|
||||
import ghidra.program.model.listing.BookmarkType;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.scalar.Scalar;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
|
||||
public class CompareSleighExternal extends GhidraScript {
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
if (currentProgram == null) {
|
||||
return;
|
||||
}
|
||||
AddressSetView set = currentSelection;
|
||||
if (set == null || set.isEmpty()) {
|
||||
set = currentProgram.getMemory().getLoadedAndInitializedAddressSet();
|
||||
}
|
||||
|
||||
putEquivalent("xzr", "x31"); // Think they messed up and allowed x31, there is no x31
|
||||
putEquivalent("wzr", "w31"); // Think they messed up and allowed w31, there is no w31
|
||||
putEquivalent("r12", "ip");
|
||||
|
||||
int completed = 0;
|
||||
monitor.initialize(set.getNumAddresses());
|
||||
|
||||
AddressIterator addresses = set.getAddresses(true);
|
||||
|
||||
PseudoDisassembler pseudoDisassembler = new PseudoDisassembler(currentProgram);
|
||||
|
||||
GNUExternalDisassembler dis = new GNUExternalDisassembler();
|
||||
|
||||
long align = currentProgram.getLanguage().getInstructionAlignment();
|
||||
while (addresses.hasNext()) {
|
||||
monitor.checkCanceled();
|
||||
Address addr = addresses.next();
|
||||
|
||||
completed++;
|
||||
|
||||
// only on valid boundaries
|
||||
if ((addr.getOffset() % align) != 0) {
|
||||
continue;
|
||||
}
|
||||
clearBad(addr);
|
||||
|
||||
monitor.setProgress(completed);
|
||||
|
||||
CodeUnit cu = currentProgram.getListing().getCodeUnitAt(addr);
|
||||
if (cu == null) {
|
||||
continue;
|
||||
}
|
||||
String str = dis.getDisassembly(cu);
|
||||
|
||||
str = str.toLowerCase();
|
||||
|
||||
PseudoInstruction pinst = null;
|
||||
try {
|
||||
pinst = pseudoDisassembler.disassemble(addr);
|
||||
} catch (UnknownInstructionException e) {
|
||||
// didn't get an instruction, did external not get one?
|
||||
if (str.startsWith(".inst") && str.endsWith("undefined")) {
|
||||
continue;
|
||||
}
|
||||
markErrorBad(addr,"Unimplemented Instruction", str);
|
||||
continue;
|
||||
}
|
||||
// didn't get an instruction, did external not get one?
|
||||
if (pinst == null && str.startsWith(".inst") && str.endsWith("undefined")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pinst == null) {
|
||||
markErrorBad(addr,"Unimplemented Instruction", str);
|
||||
continue;
|
||||
}
|
||||
|
||||
// collapse both instruction to strings, compare removing whitespace, and to-lower
|
||||
String pStr = pinst.toString().toLowerCase().replaceAll("\\s","");
|
||||
String eStr = str.toLowerCase().replaceAll("\\s", "");
|
||||
|
||||
// simple equivalence
|
||||
if (pStr.equals(eStr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String mnemonic = pinst.getMnemonicString().toLowerCase();
|
||||
if (!str.startsWith(mnemonic)) {
|
||||
markBad(addr,"Mnemonic Disagreement", str + " != " + mnemonic);
|
||||
continue;
|
||||
}
|
||||
|
||||
int start = str.indexOf(" ");
|
||||
|
||||
for (int opIndex = 0; opIndex < pinst.getNumOperands(); opIndex++) {
|
||||
// try to parse the operand string from the instruction
|
||||
int sepEnd = str.indexOf(",", start);
|
||||
|
||||
String extOp = getExtOpStr(str, start, sepEnd);
|
||||
start = sepEnd + 1;
|
||||
|
||||
String valStr = null;
|
||||
|
||||
// TODO: could remove all characters, making sure none are left!
|
||||
int loc = 0;
|
||||
boolean subRegList = false;
|
||||
List<Object> opObjList = pinst.getDefaultOperandRepresentationList(opIndex);
|
||||
for (Object object : opObjList) {
|
||||
if (object instanceof Character) {
|
||||
Character ch = (Character) object;
|
||||
ch = Character.toLowerCase(ch);
|
||||
loc = extOp.indexOf(ch);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+1);
|
||||
continue;
|
||||
}
|
||||
if (ch.equals(',')) {
|
||||
if (subRegList) {
|
||||
continue;
|
||||
}
|
||||
// gotta move into next string, must be embedded comma
|
||||
sepEnd = str.indexOf(",", start);
|
||||
|
||||
extOp = getExtOpStr(str, start, sepEnd);
|
||||
start = sepEnd + 1;
|
||||
continue;
|
||||
}
|
||||
if (ch.equals(' ')) {
|
||||
continue;
|
||||
}
|
||||
markBad(addr,"Missing String Markup", ch.toString());
|
||||
break;
|
||||
}
|
||||
if (object instanceof Scalar) {
|
||||
// find the scalar, hex or decimal
|
||||
Scalar scalar = (Scalar) object;
|
||||
valStr = scalar.toString(16, false, false, "0x", "");
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = scalar.toString(16, true, false, "0x", "");
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = scalar.toString(10, false, true, "", "");
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = scalar.toString(10, false, false, "", "");
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = scalar.toString(16, false, false, "", "");
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = scalar.toString(16, true, false, "", "");
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
markBad(addr,"Missing Scalar", valStr);
|
||||
break;
|
||||
}
|
||||
if (object instanceof Register) {
|
||||
Register reg = (Register) object;
|
||||
loc = extOp.indexOf(reg.getName().toLowerCase());
|
||||
if (loc != -1) {
|
||||
// check for '-' first
|
||||
if (extOp.charAt(0) == '-') {
|
||||
extOp = extOp.substring(1);
|
||||
loc = 0;
|
||||
subRegList = false;
|
||||
}
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+reg.getName().length());
|
||||
if (extOp.length() > 0 && extOp.charAt(0) == '-') {
|
||||
subRegList = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for equivalent register
|
||||
String equivReg = regGetEquivalent(reg.getName());
|
||||
if (equivReg != null) {
|
||||
loc = extOp.indexOf(equivReg);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+equivReg.length());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
loc = extOp.indexOf('-'); // could be a register list, assume we will find beginning and end register
|
||||
if (loc != -1) {
|
||||
continue;
|
||||
}
|
||||
markBad(addr,"Missing Register", reg.toString());
|
||||
break;
|
||||
}
|
||||
if (object instanceof Address) {
|
||||
Address dest = (Address) object;
|
||||
valStr = dest.toString(false,true);
|
||||
valStr = "0x" + valStr;
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = dest.toString(false,false);
|
||||
valStr = "0x" + valStr;
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = dest.toString(false,true);
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
valStr = dest.toString(false,false);
|
||||
loc = extOp.indexOf(valStr);
|
||||
if (loc != -1) {
|
||||
extOp = extOp.substring(0,loc) + extOp.substring(loc+valStr.length());
|
||||
continue;
|
||||
}
|
||||
markBad(addr,"Missing Address", dest.toString());
|
||||
}
|
||||
}
|
||||
extOp = extOp.trim();
|
||||
if (extOp.length() > 0 && !extOp.startsWith(";") && !extOp.startsWith("//") && !extOp.equals("#") && !extOp.matches("[0x]+")) {
|
||||
markBad(addr,"Missing characters", extOp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HashMap<String, String> equivRegisters = new HashMap<String, String>();
|
||||
|
||||
private String regGetEquivalent(String name) {
|
||||
return equivRegisters.get(name);
|
||||
}
|
||||
|
||||
private void putEquivalent(String name, String equiv) {
|
||||
equivRegisters.put(name, equiv);
|
||||
}
|
||||
|
||||
private String getExtOpStr(String str, int start, int sepEnd) {
|
||||
String opS = null;
|
||||
if (start == -1) {
|
||||
return "";
|
||||
}
|
||||
if (sepEnd == -1) {
|
||||
opS = str.substring(start);
|
||||
} else {
|
||||
opS = str.substring(start, sepEnd);
|
||||
}
|
||||
String extOp = opS.trim();
|
||||
return extOp;
|
||||
}
|
||||
|
||||
private void markBad(Address addr, String type, String error) {
|
||||
currentProgram.getBookmarkManager().setBookmark(addr, BookmarkType.WARNING,
|
||||
type,
|
||||
error);
|
||||
}
|
||||
|
||||
private void markErrorBad(Address addr, String type, String error) {
|
||||
currentProgram.getBookmarkManager().setBookmark(addr, BookmarkType.ERROR,
|
||||
Disassembler.ERROR_BOOKMARK_CATEGORY,
|
||||
error);
|
||||
}
|
||||
|
||||
private void clearBad(Address addr) {
|
||||
AddressSet set = new AddressSet(addr);
|
||||
try {
|
||||
currentProgram.getBookmarkManager().removeBookmarks(set, BookmarkType.WARNING, monitor);
|
||||
currentProgram.getBookmarkManager().removeBookmarks(set, BookmarkType.ERROR, monitor);
|
||||
} catch (CancelledException e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.disassemble.GNUExternalDisassembler;
|
||||
import ghidra.app.util.disassemble.GnuDisassembledInstruction;
|
||||
import ghidra.program.model.address.Address;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GNUDisassembleBlockScript extends GhidraScript {
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
|
||||
if (currentProgram == null || currentAddress == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GNUExternalDisassembler dis = new GNUExternalDisassembler();
|
||||
|
||||
Address addr = currentAddress.getNewAddress(currentAddress.getOffset() & -32); // block aligned address
|
||||
|
||||
List<GnuDisassembledInstruction> results = dis.getBlockDisassembly(currentProgram, addr, 5);
|
||||
|
||||
if (results == null) {
|
||||
println("Block Disassembly Failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
int maxByteLen = 0;
|
||||
for (GnuDisassembledInstruction result : results) {
|
||||
maxByteLen = Math.max(maxByteLen, result.getNumberOfBytesInInstruction());
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (GnuDisassembledInstruction result : results) {
|
||||
sb.append(addr.toString());
|
||||
sb.append(' ');
|
||||
int cnt = 0;
|
||||
byte[] bytes = new byte[result.getNumberOfBytesInInstruction()];
|
||||
currentProgram.getMemory().getBytes(addr, bytes);
|
||||
for (byte b : bytes) {
|
||||
if (b >= 0 && b < 0x10) {
|
||||
sb.append('0');
|
||||
}
|
||||
sb.append(Integer.toHexString(b & 0xff));
|
||||
sb.append(' ');
|
||||
++cnt;
|
||||
}
|
||||
if (cnt < maxByteLen) {
|
||||
int pad = (maxByteLen - cnt) * 3;
|
||||
for (int i = 0; i < pad; i++) {
|
||||
sb.append(' ');
|
||||
}
|
||||
}
|
||||
sb.append(result.getInstruction());
|
||||
sb.append("\n");
|
||||
addr = addr.add(bytes.length);
|
||||
}
|
||||
if (sb.length() != 0) {
|
||||
println("Block Disassembly:\n" + sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
1
Ghidra/Extensions/SleighDevTools/pcodetest/.gitignore
vendored
Normal file
1
Ghidra/Extensions/SleighDevTools/pcodetest/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.pyc
|
31
Ghidra/Extensions/SleighDevTools/pcodetest/README.txt
Normal file
31
Ghidra/Extensions/SleighDevTools/pcodetest/README.txt
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
OVERVIEW
|
||||
--------
|
||||
|
||||
The executable 'build' file in this directory is a python script for
|
||||
building pcode test binaries. Each pcode test binary is built using
|
||||
an associated toolchain.
|
||||
|
||||
The list of available pcode test binaries is in the file pcode_defs.py.
|
||||
Each entry in this file indicates the required toolchain, and additional
|
||||
options needed to build the pcode test.
|
||||
|
||||
The defaults.py script should be modified to suit your environment
|
||||
reflecting the installation location of your toolchains, build artifacts, etc.
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
To see a list of available options, run the build script without
|
||||
arguments.
|
||||
|
||||
./build
|
||||
|
||||
It is possible to build everything from scratch with this command:
|
||||
|
||||
./build --pcodetest-all
|
||||
|
||||
Typically, pcode test binaries are built individually per processor,
|
||||
such as:
|
||||
|
||||
./build --pcodetest MIPS16
|
91
Ghidra/Extensions/SleighDevTools/pcodetest/build
Executable file
91
Ghidra/Extensions/SleighDevTools/pcodetest/build
Executable file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import traceback
|
||||
import json
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
||||
from build import *
|
||||
from pcodetest import *
|
||||
|
||||
# set default properties first, then update values from the command
|
||||
# line before they are instantiated.
|
||||
|
||||
execfile('defaults.py')
|
||||
|
||||
parser = argparse.ArgumentParser(description='''Build pcodetests.
|
||||
One and only one of the following options must be given:
|
||||
[--pcodetest, --pcodetest-all, --pcodetest-list]''',
|
||||
epilog='(*) default properties for pcodetest instances',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
|
||||
# all-applicable arguments
|
||||
|
||||
parser.add_argument('-f', '--force', action='store_true', help='force a build')
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help='verbose output where available ')
|
||||
parser.add_argument('--toolchain-root', default=PCodeTest.defaults.toolchain_root, help='directory where toolchain directories can be found (*)')
|
||||
parser.add_argument('--build-root', default=PCodeTest.defaults.build_root, help='temporary directory to hold build files (*)')
|
||||
parser.add_argument('--gcc-version', default=PCodeTest.defaults.gcc_version, help='default version of gcc (*)')
|
||||
|
||||
# required alternates
|
||||
|
||||
required_group = parser.add_mutually_exclusive_group(required=True)
|
||||
required_group.add_argument('--pcodetest', help='the pcode test to build')
|
||||
required_group.add_argument('--pcodetest-all', action='store_true', help='build all pcode tests')
|
||||
required_group.add_argument('--pcodetest-list', action='store_true', help='list available pcode tests')
|
||||
|
||||
# pcodetest arguments
|
||||
|
||||
pcodetest_group = parser.add_argument_group('pcodetest', 'pcodetest options')
|
||||
pcodetest_group.add_argument('--no-publish', action='store_true', help='do not publish pcode test binaries to pcode test root')
|
||||
pcodetest_group.add_argument('--pcodetest-root', default=PCodeTest.defaults.pcodetest_root, help='location to publish pcode tests binaries (*)')
|
||||
pcodetest_group.add_argument('--pcodetest-src', default=PCodeTest.defaults.pcodetest_src, help='location of pcode test .c and .h source files (*)')
|
||||
pcodetest_group.add_argument('--skip-files', nargs='+', default=PCodeTest.defaults.skip_files, help='default .c files to remove from the pcode test image (*)')
|
||||
pcodetest_group.add_argument('--strip-symbols', action='store_true', help='strip symbols from image')
|
||||
pcodetest_group.add_argument('--add-ccflags', default='', help='additional flags to pass to compiler (must be quoted)')
|
||||
pcodetest_group.add_argument('--add-info', action='store_true', help='add data to binary with information about types and symbols')
|
||||
pcodetest_group.add_argument('--build-exe', action='store_true', help='build a guest executable binary (exe)')
|
||||
pcodetest_group.add_argument('--variants', default=json.dumps(PCodeTest.defaults.variants, sort_keys=True, separators=(',',':')), type=json.loads, help='build the (optimization) variants, encoded as a json dict')
|
||||
|
||||
sys.argv.pop(0)
|
||||
args = parser.parse_args(sys.argv)
|
||||
|
||||
PCodeTest.defaults.skip_files = args.skip_files
|
||||
PCodeTest.defaults.pcodetest_root = args.pcodetest_root
|
||||
PCodeTest.defaults.pcodetest_src = args.pcodetest_src
|
||||
PCodeTest.defaults.strip_symbols = args.strip_symbols
|
||||
PCodeTest.defaults.add_ccflags = args.add_ccflags
|
||||
PCodeTest.defaults.add_info = args.add_info
|
||||
PCodeTest.defaults.build_exe = args.build_exe
|
||||
PCodeTest.defaults.variants = args.variants
|
||||
PCodeTest.defaults.verbose = args.verbose
|
||||
PCodeTest.defaults.force = args.force
|
||||
PCodeTest.defaults.no_publish = args.no_publish
|
||||
|
||||
# load the known pcodetests
|
||||
|
||||
execfile('pcode_defs.py')
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
if args.pcodetest_list:
|
||||
PCodeTest.print_all()
|
||||
elif args.pcodetest_all:
|
||||
for n,pct in sorted(PCodeTest.list.iteritems(), key=lambda x: x[0].lower()):
|
||||
if pct.config.build_all:
|
||||
try: PCodeTestBuild.factory(pct).main()
|
||||
except Exception as e:
|
||||
print 'unhandled exception while building %s' % n
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
os.chdir(cwd)
|
||||
elif args.pcodetest:
|
||||
if args.pcodetest in PCodeTest.list:
|
||||
PCodeTest = PCodeTest.list[args.pcodetest]
|
||||
PCodeTestBuild.factory(PCodeTest).main()
|
||||
else:
|
||||
print 'the pcode test %s is not in the list' % args.pcodetest
|
||||
else:
|
||||
parser.print_help()
|
||||
|
291
Ghidra/Extensions/SleighDevTools/pcodetest/build.py
Normal file
291
Ghidra/Extensions/SleighDevTools/pcodetest/build.py
Normal file
@ -0,0 +1,291 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import pwd
|
||||
import grp
|
||||
import re
|
||||
|
||||
class BuildUtil(object):
|
||||
|
||||
def __init__(self):
|
||||
self.log = False
|
||||
self.name = False
|
||||
self.num_errors = 0
|
||||
self.num_warnings = 0
|
||||
|
||||
def run(self, cmd, stdout=False, stderr=False, verbose=True):
|
||||
if isinstance(cmd, basestring):
|
||||
if stdout and stderr:
|
||||
cmd += ' 1>%s 2>%s' % (stdout, stderr)
|
||||
elif stdout and not stderr:
|
||||
cmd += ' 1>%s 2>&1' % (stdout)
|
||||
elif not stdout and stderr:
|
||||
cmd += ' 2>%s' % (stderr)
|
||||
if verbose: self.log_info(cmd)
|
||||
os.system(cmd)
|
||||
else:
|
||||
str = ' '.join(cmd);
|
||||
if stdout:
|
||||
f = file(stdout, 'w+')
|
||||
str += ' 1>%s 2>&1' % (stdout)
|
||||
else:
|
||||
f = subprocess.PIPE
|
||||
if verbose: self.log_info(str)
|
||||
try:
|
||||
sp = subprocess.Popen(cmd, stdout=f, stderr=subprocess.PIPE)
|
||||
except OSError as e:
|
||||
self.log_err(cmd)
|
||||
self.log_err(e)
|
||||
return 0,e.message#raise
|
||||
if stdout: f.close()
|
||||
out, err = sp.communicate()
|
||||
# print 'run returned %d bytes stdout and %d bytes stderr' % (len(out) if out else 0, len(err) if err else 0)
|
||||
return out, err
|
||||
|
||||
def isdir(self, dname):
|
||||
return os.path.isdir(dname)
|
||||
|
||||
def getcwd(self):
|
||||
return os.getcwd()
|
||||
|
||||
def basename(self, fname):
|
||||
return os.path.basename(fname)
|
||||
|
||||
def dirname(self, fname):
|
||||
return os.path.dirname(fname)
|
||||
|
||||
def getmtime(self, fname):
|
||||
return os.path.getmtime(fname)
|
||||
|
||||
def isfile(self, fname):
|
||||
return os.path.isfile(fname)
|
||||
|
||||
def getenv(self, var, dflt):
|
||||
return os.getenv(var, dflt)
|
||||
|
||||
def pw_name(self, fname):
|
||||
return pwd.getpwuid(os.stat(fname).st_uid).pw_name
|
||||
|
||||
def gr_name(self, fname):
|
||||
return grp.getgrgid(os.stat(fname).st_gid).gr_name
|
||||
|
||||
def isatty(self):
|
||||
return os.isatty(sys.stdin.fileno())
|
||||
|
||||
def is_readable_file(self, fname):
|
||||
if not self.isfile(fname):
|
||||
self.log_warn('%s does not exist' % fname)
|
||||
return False
|
||||
if os.stat(fname).st_size == 0:
|
||||
self.log_warn('%s is empty' % fname)
|
||||
return False
|
||||
if os.access(fname, os.R_OK) == 0:
|
||||
self.log_warn('%s is not readable' % fname)
|
||||
return False
|
||||
return True
|
||||
|
||||
def is_executable_file(self, fname):
|
||||
if not self.is_readable_file(fname): return False
|
||||
if os.access(fname, os.X_OK) == 0:
|
||||
self.log_warn('%s is not executable' % fname)
|
||||
return False
|
||||
return True
|
||||
|
||||
# export a file to a directory
|
||||
def export_file(self, fname, dname,):
|
||||
try:
|
||||
if not os.path.isdir(dname):
|
||||
self.makedirs(dname)
|
||||
if os.path.isfile(fname):
|
||||
self.copy(fname, dname, verbose=True)
|
||||
elif os.path.isdir(fname):
|
||||
self.copy(fname, dname, dir=True, verbose=True)
|
||||
except IOError as e:
|
||||
self.log_err('Error occurred exporting %s to %s' % (fname, dname))
|
||||
self.log_err("Unexpected error: %s" % str(e))
|
||||
|
||||
def rmtree(self, dir, verbose=True):
|
||||
if verbose: self.log_info('rm -r %s' % dir)
|
||||
shutil.rmtree(dir)
|
||||
|
||||
def makedirs(self, dir, verbose=True):
|
||||
if verbose: self.log_info('mkdir -p %s' % dir)
|
||||
try: os.makedirs(dir)
|
||||
except: pass
|
||||
|
||||
# copy a file to a directory
|
||||
def copy(self, fname, dname, verbose=True, dir=False):
|
||||
if not dir:
|
||||
if verbose: self.log_info('cp -av %s %s' % (fname, dname))
|
||||
shutil.copy(fname, dname)
|
||||
else:
|
||||
if verbose: self.log_info('cp -avr %s %s' % (fname, dname))
|
||||
if os.path.exists(dname):
|
||||
shutil.rmtree(dname)
|
||||
shutil.copytree(fname, dname)
|
||||
|
||||
def chdir(self, dir, verbose=True):
|
||||
if verbose: self.log_info('cd %s' % dir)
|
||||
os.chdir(dir)
|
||||
|
||||
def remove(self, fname, verbose=True):
|
||||
if verbose: self.log_info('rm -f %s' % fname)
|
||||
try: os.remove(fname)
|
||||
except: pass
|
||||
|
||||
def environment(self, var, val, verbose=True):
|
||||
if verbose: self.log_info('%s=%s' % (var, val))
|
||||
os.environ[var] = val
|
||||
|
||||
def unlink(self, targ, verbose=True):
|
||||
if verbose: self.log_info('unlink %s' % targ)
|
||||
os.unlink(targ)
|
||||
|
||||
def symlink(self, src, targ, verbose=True):
|
||||
if verbose: self.log_info('ln -s %s %s' % (src, targ))
|
||||
if os.path.islink(targ):
|
||||
os.unlink(targ)
|
||||
os.symlink(src, targ)
|
||||
|
||||
def build_dir(self, root, kind, what):
|
||||
return root + "/" + re.sub(r'[^a-zA-Z0-9_-]+', '_', 'build-%s-%s' % (kind, what))
|
||||
|
||||
def log_prefix(self, kind, what):
|
||||
return kind.upper() + ' ' + what
|
||||
|
||||
def open_log(self, root, kind, what, chdir=False):
|
||||
build_dir = self.build_dir(root, kind, what)
|
||||
|
||||
# Get the name of the log file
|
||||
logFile = '%s/log.txt' % build_dir
|
||||
|
||||
self.log_info('%s LOGFILE %s' % (self.log_prefix(kind, what), logFile))
|
||||
|
||||
try: self.rmtree(build_dir, verbose=False)
|
||||
except: pass
|
||||
self.makedirs(build_dir, verbose=False)
|
||||
self.log_open(logFile)
|
||||
if chdir: self.chdir(build_dir)
|
||||
|
||||
def log_open(self, name):
|
||||
if self.log: self.log_close()
|
||||
self.log = open(name, 'w')
|
||||
self.name = name
|
||||
|
||||
def log_close(self):
|
||||
if self.log:
|
||||
if self.num_errors > 0:
|
||||
print '# ERROR: There were errors, see %s' % self.name
|
||||
elif self.num_warnings > 0:
|
||||
print '# WARNING: There were warnings, see %s' % self.name
|
||||
self.log.close()
|
||||
self.log = False
|
||||
self.name = False
|
||||
self.num_errors = 0
|
||||
self.num_warnings = 0
|
||||
|
||||
def log_pr(self, what):
|
||||
if self.log:
|
||||
self.log.write(what + '\n')
|
||||
self.log.flush()
|
||||
else:
|
||||
print what
|
||||
sys.stdout.flush()
|
||||
|
||||
def log_err(self, what):
|
||||
self.log_pr('# ERROR: ' + what)
|
||||
self.num_errors += 1
|
||||
|
||||
def log_warn(self, what):
|
||||
self.log_pr('# WARNING: ' + what)
|
||||
self.num_warnings += 1
|
||||
|
||||
def log_info(self, what):
|
||||
self.log_pr('# INFO: ' + what)
|
||||
|
||||
# create a file with size, type, and symbol info
|
||||
# the function is here because it is useful and has no dependencies
|
||||
|
||||
def mkinfo(self, fname):
|
||||
ifdefs = { 'i8':'HAS_LONGLONG', 'u8':'HAS_LONGLONG', 'f4':'HAS_FLOAT', 'f8':'HAS_DOUBLE' }
|
||||
|
||||
sizes = [
|
||||
'char', 'signed char', 'unsigned char',
|
||||
'short', 'signed short', 'unsigned short',
|
||||
'int', 'signed int', 'unsigned int',
|
||||
'long', 'signed long', 'unsigned long',
|
||||
'long long', 'signed long long', 'unsigned long long',
|
||||
'float', 'double', 'float', 'long double',
|
||||
'i1', 'i2', 'i4', 'u1', 'u2', 'u4', 'i8', 'u8', 'f4', 'f8']
|
||||
|
||||
syms = [
|
||||
'__AVR32__', '__AVR_ARCH__', 'dsPIC30', '__GNUC__', '__has_feature', 'INT4_IS_LONG',
|
||||
'__INT64_TYPE__', '__INT8_TYPE__', '__llvm__', '_M_ARM_FP', '__MSP430__', '_MSV_VER',
|
||||
'__SDCC', '__SIZEOF_DOUBLE__', '__SIZEOF_FLOAT__', '__SIZEOF_SIZE_T__', '__TI_COMPILER_VERSION__',
|
||||
'__INT8_TYPE__', '__INT16_TYPE__', '__INT32_TYPE__', '__INT64_TYPE__', '__UINT8_TYPE__',
|
||||
'__UINT16_TYPE__', '__UINT32_TYPE__', '__UINT64_TYPE__', 'HAS_FLOAT', 'HAS_DOUBLE',
|
||||
'HAS_LONGLONG', 'HAS_FLOAT_OVERRIDE', 'HAS_DOUBLE_OVERRIDE', 'HAS_LONGLONG_OVERRIDE']
|
||||
|
||||
typedefs = { 'i1':1, 'i2':2, 'i4':4, 'u1':1, 'u2':2, 'u4':4, 'i8':8, 'u8':8, 'f4':4, 'f8':8 }
|
||||
|
||||
f = open(fname, 'w')
|
||||
|
||||
f.write('#include "types.h"\n\n')
|
||||
|
||||
i = 0
|
||||
for s in sizes:
|
||||
i += 1
|
||||
d = 'INFO sizeof(%s) = ' % s
|
||||
x = list(d)
|
||||
x = "', '".join(x)
|
||||
x = "'%s', '0'+sizeof(%s), '\\n'" % (x, s)
|
||||
l = 'char size_info_%d[] = {%s};\n' % (i, x)
|
||||
if s in ifdefs: f.write('#ifdef %s\n' % ifdefs[s])
|
||||
f.write(l)
|
||||
if s in ifdefs: f.write('#endif\n')
|
||||
|
||||
for s in typedefs:
|
||||
if s in ifdefs: f.write('#ifdef %s\n' % ifdefs[s])
|
||||
f.write('_Static_assert(sizeof(%s) == %d, "INFO %s should have size %d, is not correct\\n");\n' % (s, typedefs[s], s, typedefs[s]))
|
||||
if s in ifdefs: f.write('#endif\n')
|
||||
|
||||
for s in syms:
|
||||
i += 1
|
||||
f.write('#ifdef %s\n' % s)
|
||||
f.write('char sym_info_%d[] = "INFO %s is defined\\n\";\n' % (i, s))
|
||||
f.write('#else\n')
|
||||
f.write('char sym_info_%d[] = "INFO %s is not defined\\n\";\n' % (i, s))
|
||||
f.write('#endif\n')
|
||||
|
||||
f.close()
|
||||
|
||||
class Config(object):
|
||||
|
||||
def __init__(self, *obj):
|
||||
for o in obj:
|
||||
if isinstance(o, dict): self.__dict__.update(o)
|
||||
else: self.__dict__.update(o.__dict__)
|
||||
|
||||
def format(self, val):
|
||||
if isinstance(val, basestring) and '%' in val:
|
||||
return val % self.__dict__
|
||||
elif isinstance(val, dict):
|
||||
return dict(map(lambda (k,v): (k,self.format(v)), val.iteritems()))
|
||||
else: return val
|
||||
|
||||
def __getattr__(self, attr):
|
||||
return ''
|
||||
|
||||
def expand(self):
|
||||
for k,v in self.__dict__.iteritems():
|
||||
self.__dict__[k] = self.format(v)
|
||||
|
||||
def dump(self):
|
||||
ret = ''
|
||||
for k,v in sorted(self.__dict__.iteritems()):
|
||||
if isinstance(v, basestring): vv = "'" + v + "'"
|
||||
else: vv = str(v)
|
||||
ret += ' '.ljust(10) + k.ljust(20) + vv + '\n'
|
||||
return ret
|
||||
|
677
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS.test
Normal file
677
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS.test
Normal file
@ -0,0 +1,677 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_u1_complexLogic_Main()
|
||||
{
|
||||
extern u1 pcode_u1_complexLogic(u1 a, u1 b, u1 c, u1 d, u1 e, u1 f);
|
||||
ASSERTU1(pcode_u1_complexLogic(237, 210, 0, 0, 153, 76), 11);
|
||||
ASSERTU1(pcode_u1_complexLogic(139, 0, 34, 0, 86, 154), 10);
|
||||
ASSERTU1(pcode_u1_complexLogic(24, 209, 254, 0, 228, 217), 15);
|
||||
ASSERTU1(pcode_u1_complexLogic(0, 9, 209, 0, 165, 150), 11);
|
||||
}
|
||||
|
||||
TEST pcode_u2_complexLogic_Main()
|
||||
{
|
||||
extern u2 pcode_u2_complexLogic(u2 a, u2 b, u2 c, u2 d, u2 e, u2 f);
|
||||
ASSERTU2(pcode_u2_complexLogic(15941, 23971, 41361, 0, 43462, 0), 15);
|
||||
ASSERTU2(pcode_u2_complexLogic(52937, 43562, 0, 0, 48661, 51969), 11);
|
||||
ASSERTU2(pcode_u2_complexLogic(54831, 59630, 16661, 0, 0, 25991), 14);
|
||||
ASSERTU2(pcode_u2_complexLogic(0, 49882, 61260, 0, 8407, 16234), 10);
|
||||
}
|
||||
|
||||
TEST pcode_u4_complexLogic_Main()
|
||||
{
|
||||
extern u4 pcode_u4_complexLogic(u4 a, u4 b, u4 c, u4 d, u4 e, u4 f);
|
||||
ASSERTU4(pcode_u4_complexLogic(2016764524, 1717226057, 1748349614, 0, 1276673168, 0), 15);
|
||||
ASSERTU4(pcode_u4_complexLogic(2009726312, 696947386, 0, 0, 1265204346, 1369602726), 11);
|
||||
ASSERTU4(pcode_u4_complexLogic(1665204916, 1707056552, 564325578, 0, 0, 1010528946), 14);
|
||||
ASSERTU4(pcode_u4_complexLogic(0, 1516266761, 1866000081, 0, 1175526309, 1586903190), 10);
|
||||
}
|
||||
TEST pcode_i1_complexLogic_Main()
|
||||
{
|
||||
extern i1 pcode_i1_complexLogic(i1 a, i1 b, i1 c, i1 d, i1 e, i1 f);
|
||||
ASSERTI1(pcode_i1_complexLogic((i1) -150, 45, (i1) -232, 0, 0, 37), 15);
|
||||
ASSERTI1(pcode_i1_complexLogic((i1) -70, (i1) -39, 134, 0, 229, 63), 14);
|
||||
ASSERTI1(pcode_i1_complexLogic(0, (i1) -164, (i1) -188, 0, (i1) -106, 238), 10);
|
||||
ASSERTI1(pcode_i1_complexLogic(0, 43, (i1) -140, 0, (i1) -182, 135), 11);
|
||||
}
|
||||
|
||||
TEST pcode_i2_complexLogic_Main()
|
||||
{
|
||||
extern i2 pcode_i2_complexLogic(i2 a, i2 b, i2 c, i2 d, i2 e, i2 f);
|
||||
ASSERTI2(pcode_i2_complexLogic(0, 46379, (i2) -52108, 0, (i2) -54966, 53127), 11);
|
||||
ASSERTI2(pcode_i2_complexLogic((i2) -5607, 26256, 23643, 0, (i2) -21648, 0), 14);
|
||||
ASSERTI2(pcode_i2_complexLogic((i2) -19816, 41002, 63272, 0, 4483, 0), 15);
|
||||
ASSERTI2(pcode_i2_complexLogic(0, (i2) -25128, 33393, 0, 61486, 53285), 11);
|
||||
}
|
||||
|
||||
TEST pcode_i4_complexLogic_Main()
|
||||
{
|
||||
extern i4 pcode_i4_complexLogic(i4 a, i4 b, i4 c, i4 d, i4 e, i4 f);
|
||||
ASSERTI4(pcode_i4_complexLogic((i4) -1916250774, 1528806445, (i4) -870305000, 0, 0, 1799560997), 14);
|
||||
ASSERTI4(pcode_i4_complexLogic((i4) -1375179334, (i4) -1539942439, 987987334, 0, 1162088421, 12548159), 15);
|
||||
ASSERTI4(pcode_i4_complexLogic(0, (i4) -750167716, (i4) -1104561852, 0, (i4) -915711850, 737703662), 11);
|
||||
ASSERTI4(pcode_i4_complexLogic(0, 386839851, (i4) -771476364, 0, (i4) -942724790, 1833488263), 10);
|
||||
}
|
||||
|
||||
TEST biopCmpu1u1_Main()
|
||||
{
|
||||
extern u1 biopCmpu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopCmpu1u1(0x1, 0x1), 1);
|
||||
ASSERTU1(biopCmpu1u1(0x1, 0x2), 23);
|
||||
ASSERTU1(biopCmpu1u1(0x2, 0x1), 22);
|
||||
}
|
||||
|
||||
TEST biopCmpu2u2_Main()
|
||||
{
|
||||
extern u2 biopCmpu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopCmpu2u2(0x1, 0x1), 1);
|
||||
ASSERTU2(biopCmpu2u2(0x1, 0x2), 23);
|
||||
ASSERTU2(biopCmpu2u2(0x2, 0x1), 22);
|
||||
}
|
||||
|
||||
TEST biopCmpu4u4_Main()
|
||||
{
|
||||
extern u4 biopCmpu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopCmpu4u4(0x1, 0x1), 1);
|
||||
ASSERTU4(biopCmpu4u4(0x1, 0x2), 23);
|
||||
ASSERTU4(biopCmpu4u4(0x2, 0x1), 22);
|
||||
}
|
||||
|
||||
TEST biopCmpi1i1_Main()
|
||||
{
|
||||
extern i1 biopCmpi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopCmpi1i1(0x1, 0x1), 21);
|
||||
ASSERTI1(biopCmpi1i1(0x1, 0x2), 21);
|
||||
ASSERTI1(biopCmpi1i1(0x2, 0x1), 22);
|
||||
ASSERTI1(biopCmpi1i1(-0x1, -0x1), 21);
|
||||
ASSERTI1(biopCmpi1i1(-0x1, -0x2), 21);
|
||||
ASSERTI1(biopCmpi1i1(-0x2, -0x1), 24);
|
||||
}
|
||||
|
||||
TEST biopCmpi2i2_Main()
|
||||
{
|
||||
extern i2 biopCmpi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopCmpi2i2(0x1, 0x1), 21);
|
||||
ASSERTI2(biopCmpi2i2(0x1, 0x2), 21);
|
||||
ASSERTI2(biopCmpi2i2(0x2, 0x1), 22);
|
||||
ASSERTI2(biopCmpi2i2(-0x1, -0x1), 21);
|
||||
ASSERTI2(biopCmpi2i2(-0x1, -0x2), 21);
|
||||
ASSERTI2(biopCmpi2i2(-0x2, -0x1), 24);
|
||||
}
|
||||
|
||||
TEST biopCmpi4i4_Main()
|
||||
{
|
||||
extern i4 biopCmpi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopCmpi4i4(0x1, 0x1), 21);
|
||||
ASSERTI4(biopCmpi4i4(0x1, 0x2), 21);
|
||||
ASSERTI4(biopCmpi4i4(0x2, 0x1), 22);
|
||||
ASSERTI4(biopCmpi4i4(-0x1, -0x1), 21);
|
||||
ASSERTI4(biopCmpi4i4(-0x1, -0x2), 21);
|
||||
ASSERTI4(biopCmpi4i4(-0x2, -0x1), 24);
|
||||
}
|
||||
|
||||
TEST biopAndi4i4_Main()
|
||||
{
|
||||
extern i4 biopAndi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopAndi4i4(0x01010101, 0x01010101), 0x01010101);
|
||||
ASSERTI4(biopAndi4i4(2, 1), 0);
|
||||
ASSERTI4(/*val*/ biopAndi4i4(I4_MAX, I4_MAX), 2147483647)
|
||||
ASSERTI4(/*val*/ biopAndi4i4(0, 0), 0)
|
||||
ASSERTI4(/*val*/ biopAndi4i4(I4_MIN, I4_MIN), -2147483648)
|
||||
}
|
||||
|
||||
TEST biopLei1i1_Main()
|
||||
{
|
||||
extern i1 biopLei1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopLei1i1(2, 1), 0);
|
||||
ASSERTI1(biopLei1i1(~2, ~1), 1);
|
||||
}
|
||||
|
||||
TEST biopLogicAndu4u4_Main()
|
||||
{
|
||||
extern u4 biopLogicAndu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopLogicAndu4u4(0x01010101, 0x01010101), 1);
|
||||
ASSERTU4(biopLogicAndu4u4(2, 1), 1);
|
||||
ASSERTU4(biopLogicAndu4u4(U4_MAX, U4_MAX), 1)
|
||||
}
|
||||
|
||||
TEST biopGtu2u2_Main()
|
||||
{
|
||||
extern u2 biopGtu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopGtu2u2(2, 1), 1);
|
||||
ASSERTU2(biopGtu2u2(U2_MAX, U2_MAX), 0);
|
||||
ASSERTU2(biopGtu2u2(U2_MAX, 0), 1);
|
||||
ASSERTU2(biopGtu2u2(0, U2_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopEqi1i1_Main()
|
||||
{
|
||||
extern i1 biopEqi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopEqi1i1(2, 1), 0);
|
||||
ASSERTI1(biopEqi1i1(I1_MAX, I1_MAX), 1);
|
||||
ASSERTI1(biopEqi1i1(I1_MAX, I1_MIN), 0);
|
||||
ASSERTI1(biopEqi1i1(I1_MIN, I1_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopOri4i4_Main()
|
||||
{
|
||||
extern i4 biopOri4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopOri4i4(0x01010101, 0x01010101), 0x01010101);
|
||||
ASSERTI4(biopOri4i4(0x01010101, 0x0), 0x01010101);
|
||||
ASSERTI4(biopOri4i4(2, 1), 3);
|
||||
ASSERTI4(biopOri4i4(I4_MAX, I4_MAX), 2147483647);
|
||||
ASSERTI4(biopOri4i4(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST unopNotu4_Main()
|
||||
{
|
||||
extern u4 unopNotu4(u4 lhs);
|
||||
ASSERTU4(unopNotu4(0x01010101), 0);
|
||||
ASSERTU4(unopNotu4(2), 0);
|
||||
ASSERTU4(unopNotu4(U4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST unopPlusu1_Main()
|
||||
{
|
||||
extern u1 unopPlusu1(u1 lhs);
|
||||
ASSERTU1(unopPlusu1(0x01), 0x01);
|
||||
ASSERTU1(unopPlusu1(U1_MAX), 255);
|
||||
ASSERTU1(unopPlusu1(0), 0);
|
||||
}
|
||||
|
||||
TEST biopGeu2u2_Main()
|
||||
{
|
||||
extern u2 biopGeu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopGeu2u2(2, 1), 1);
|
||||
ASSERTU2(biopGeu2u2(U2_MAX, U2_MAX), 1);
|
||||
ASSERTU2(biopGeu2u2(1, 1), 1);
|
||||
ASSERTU2(biopGeu2u2(1, 2), 0);
|
||||
}
|
||||
|
||||
TEST biopNei1i1_Main()
|
||||
{
|
||||
extern i1 biopNei1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopNei1i1(2, 1), 1);
|
||||
ASSERTI1(biopNei1i1(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI1(biopNei1i1(I1_MIN, I1_MIN), 0);
|
||||
ASSERTI1(biopNei1i1(0, 0), 0);
|
||||
}
|
||||
|
||||
|
||||
TEST biopXOri4i4_Main()
|
||||
{
|
||||
extern i4 biopXOri4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopXOri4i4(0x01010101, 0x01010101), 0);
|
||||
ASSERTI4(biopXOri4i4(0x01010101, 0x01000101), 0x10000);
|
||||
ASSERTI4(biopXOri4i4(2, 1), 3);
|
||||
ASSERTI4(biopXOri4i4(I4_MAX, I4_MAX), 0);
|
||||
ASSERTI4(biopXOri4i4(I4_MAX, 0), 2147483647);
|
||||
ASSERTI4(biopXOri4i4(0, 0), 0);
|
||||
}
|
||||
|
||||
|
||||
TEST biopDividi4i4_Main()
|
||||
{
|
||||
extern i4 biopDividi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopDividi4i4(0x01010101, 0x01010101), 1);
|
||||
ASSERTI4(biopDividi4i4(-0x01010101, 0x01010101), -1);
|
||||
ASSERTI4(biopDividi4i4(0, 0x01010101), 0);
|
||||
ASSERTI4(biopDividi4i4(0x01010101, 2), 0x808080);
|
||||
ASSERTI4(biopDividi4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopDividi4i4(I4_MIN, I4_MIN), 1);
|
||||
ASSERTI4(biopDividi4i4(-1, I4_MIN), 0);
|
||||
}
|
||||
|
||||
TEST biopRemainderi4i4_Main()
|
||||
{
|
||||
extern i4 biopRemainderi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopRemainderi4i4(0x01010101, 0x01010101), 0);
|
||||
ASSERTI4(biopRemainderi4i4(I4_MAX, I4_MAX), 0);
|
||||
ASSERTI4(biopRemainderi4i4(I4_MIN, I4_MIN), 0);
|
||||
ASSERTI4(biopRemainderi4i4(0, I4_MIN), 0);
|
||||
ASSERTI4(biopRemainderi4i4(0, I4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopLtu2u2_Main()
|
||||
{
|
||||
extern u2 biopLtu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopLtu2u2(2, 1), 0);
|
||||
ASSERTU2(biopLtu2u2(2, 1), 0);
|
||||
ASSERTU2(biopLtu2u2(U2_MAX, U2_MAX), 0);
|
||||
ASSERTU2(biopLtu2u2(0, 0), 0);
|
||||
ASSERTU2(biopLtu2u2(1, 2), 1);
|
||||
}
|
||||
|
||||
TEST biopAndi1i1_Main()
|
||||
{
|
||||
extern i1 biopAndi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopAndi1i1(2, 1), 0);
|
||||
ASSERTI1(biopAndi1i1(I1_MAX, I1_MAX), 127);
|
||||
ASSERTI1(biopAndi1i1(I1_MIN, I1_MIN), -128);
|
||||
ASSERTI1(biopAndi1i1(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopLogicOri4i4_Main()
|
||||
{
|
||||
extern i4 biopLogicOri4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopLogicOri4i4(0x01010101, 0x01010101), 1);
|
||||
ASSERTI4(biopLogicOri4i4(2, 1), 1);
|
||||
ASSERTI4(biopLogicOri4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopLogicOri4i4(I4_MIN, I4_MIN), 1);
|
||||
ASSERTI4(biopLogicOri4i4(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST unopPlusu4_Main()
|
||||
{
|
||||
extern u4 unopPlusu4(u4 lhs);
|
||||
ASSERTU4(unopPlusu4(0x01010101), 0x01010101);
|
||||
ASSERTU4(unopPlusu4(2), 2);
|
||||
ASSERTU4(unopPlusu4(U4_MAX), -1);
|
||||
ASSERTU4(unopPlusu4(~1000), 4294966295);
|
||||
ASSERTU4(unopPlusu4(0), 0);
|
||||
}
|
||||
|
||||
TEST biopLeu2u2_Main()
|
||||
{
|
||||
extern u2 biopLeu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopLeu2u2(2, 1), 0);
|
||||
ASSERTU2(biopLeu2u2(U2_MAX, U2_MAX), 1);
|
||||
ASSERTU2(biopLeu2u2(U2_MIN, U2_MIN), 1);
|
||||
ASSERTU2(biopLeu2u2(1, 2), 1);
|
||||
}
|
||||
|
||||
TEST biopLogicAndi4i4_Main()
|
||||
{
|
||||
extern i4 biopLogicAndi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopLogicAndi4i4(0x01010101, 0x01010101), 1);
|
||||
ASSERTI4(biopLogicAndi4i4(2, 1), 1);
|
||||
ASSERTI4(biopLogicAndi4i4(0x01000101, 0x01010101), 1);
|
||||
ASSERTI4(biopLogicAndi4i4(0x01000101, 0x0), 0);
|
||||
ASSERTI4(biopLogicAndi4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopLogicAndi4i4(I4_MIN, I4_MIN), 1);
|
||||
ASSERTI4(biopLogicAndi4i4(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopOri1i1_Main()
|
||||
{
|
||||
extern i1 biopOri1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopOri1i1(2, 1), 3);
|
||||
ASSERTI1(biopOri1i1(I1_MAX, I1_MAX), 127);
|
||||
ASSERTI1(biopOri1i1(I1_MIN, I1_MIN), -128);
|
||||
ASSERTI1(biopOri1i1(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopRemainderi2i2_Main()
|
||||
{
|
||||
extern i2 biopRemainderi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopRemainderi2i2(0x0101, 0x0101), 0x0);
|
||||
ASSERTI2(biopRemainderi2i2(I2_MAX, I2_MAX), 0x0);
|
||||
ASSERTI2(biopRemainderi2i2(I2_MIN, I2_MIN), 0x0);
|
||||
ASSERTI2(biopRemainderi2i2(0, I2_MIN), 0x0);
|
||||
}
|
||||
|
||||
TEST biopMulti2i2_Main()
|
||||
{
|
||||
extern i2 biopMulti2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopMulti2i2(0x0101, 0x0101), 0x201);
|
||||
ASSERTI2(biopMulti2i2(0x0101, -0x0101), -513);
|
||||
ASSERTI2(biopMulti2i2(0, -0x0101), 0);
|
||||
ASSERTI2(biopMulti2i2(2, 1), 2);
|
||||
ASSERTI2(biopMulti2i2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTI2(biopMulti2i2(I2_MIN, I2_MIN), 0);
|
||||
ASSERTI2(biopMulti2i2(1, I2_MIN), I2_MIN);
|
||||
ASSERTI2(biopMulti2i2(-1, I2_MIN), -I2_MIN);
|
||||
}
|
||||
|
||||
TEST biopEqu2u2_Main()
|
||||
{
|
||||
extern u2 biopEqu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopEqu2u2(2, 1), 0);
|
||||
ASSERTU2(biopEqu2u2(U2_MAX, U2_MAX), 1);
|
||||
ASSERTU2(biopEqu2u2(U2_MIN, U2_MIN), 1);
|
||||
ASSERTU2(biopEqu2u2(0, 0), 1);
|
||||
}
|
||||
|
||||
TEST biopDividi2i2_Main()
|
||||
{
|
||||
extern i2 biopDividi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopDividi2i2(0x0101, 0x0101), 0x1);
|
||||
ASSERTI2(biopDividi2i2(I2_MAX, I2_MAX), 0x1);
|
||||
ASSERTI2(biopDividi2i2(I2_MIN, I2_MIN), 0x1);
|
||||
}
|
||||
|
||||
TEST unopNoti4_Main()
|
||||
{
|
||||
extern i4 unopNoti4(i4 lhs);
|
||||
ASSERTI4(unopNoti4(0x01010101), 0);
|
||||
ASSERTI4(unopNoti4(2), 0);
|
||||
ASSERTI4(unopNoti4(I4_MAX), 0);
|
||||
ASSERTI4(unopNoti4(I4_MIN), 0);
|
||||
ASSERTI4(unopNoti4(0), 1);
|
||||
}
|
||||
|
||||
TEST biopXOri1i1_Main()
|
||||
{
|
||||
extern i1 biopXOri1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopXOri1i1(2, 1), 3);
|
||||
ASSERTI1(biopXOri1i1(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI1(biopXOri1i1(I1_MIN, I1_MIN), 0);
|
||||
ASSERTI1(biopXOri1i1(I1_MAX, 0), 127);
|
||||
ASSERTI1(biopXOri1i1(I1_MAX, 1), 126);
|
||||
}
|
||||
|
||||
TEST biopRemainderi1i1_Main()
|
||||
{
|
||||
extern i1 biopRemainderi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopRemainderi1i1(0x01, 0x01), 0);
|
||||
ASSERTI1(biopRemainderi1i1(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI1(biopRemainderi1i1(I1_MIN, I1_MIN), 0);
|
||||
ASSERTI1(biopRemainderi1i1(0, I1_MIN), 0);
|
||||
}
|
||||
|
||||
TEST biopSubi2i2_Main()
|
||||
{
|
||||
extern i2 biopSubi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopSubi2i2(0x0101, 0x0100), 0x1);
|
||||
ASSERTI2(biopSubi2i2(0x0100, 0x0101), -0x1);
|
||||
ASSERTI2(biopSubi2i2(0x0101, 0x0101), 0);
|
||||
ASSERTI2(biopSubi2i2(2, 1), 1);
|
||||
ASSERTI2(biopSubi2i2(I2_MAX, I2_MAX), 0);
|
||||
ASSERTI2(biopSubi2i2(I2_MIN, I2_MIN), 0);
|
||||
ASSERTI2(biopSubi2i2(I2_MAX, 0), I2_MAX);
|
||||
ASSERTI2(biopSubi2i2(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopNeu2u2_Main()
|
||||
{
|
||||
extern u2 biopNeu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopNeu2u2(2, 1), 1);
|
||||
ASSERTU2(biopNeu2u2(U2_MAX, U2_MAX), 0);
|
||||
ASSERTU2(biopNeu2u2(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopLogicOri1i1_Main()
|
||||
{
|
||||
extern i1 biopLogicOri1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopLogicOri1i1(2, 1), 1);
|
||||
ASSERTI1(biopLogicOri1i1(I1_MAX, I1_MAX), 1);
|
||||
ASSERTI1(biopLogicOri1i1(I1_MIN, I1_MIN), 1);
|
||||
ASSERTI1(biopLogicOri1i1(0, 0), 0);
|
||||
ASSERTI1(biopLogicOri1i1(0, I1_MAX), 1);
|
||||
ASSERTI1(biopLogicOri1i1(I1_MAX, I1_MIN), 1);
|
||||
}
|
||||
|
||||
TEST biopDividi1i1_Main()
|
||||
{
|
||||
extern i1 biopDividi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopDividi1i1(0x01, 0x01), 1);
|
||||
ASSERTI1(biopDividi1i1(I1_MAX, I1_MAX), 1);
|
||||
ASSERTI1(biopDividi1i1(I1_MIN, I1_MIN), 1);
|
||||
ASSERTI1(biopDividi1i1(I1_MAX, 1), I1_MAX);
|
||||
}
|
||||
|
||||
TEST unopNegativei4_Main()
|
||||
{
|
||||
extern i4 unopNegativei4(i4 lhs);
|
||||
ASSERTI4(unopNegativei4(0x01010101), -0x01010101);
|
||||
ASSERTI4(unopNegativei4(-0x01010101), 0x01010101);
|
||||
ASSERTI4(unopNegativei4(I4_MAX), -I4_MAX);
|
||||
ASSERTI4(unopNegativei4(I4_MIN), I4_MIN);
|
||||
ASSERTI4(unopNegativei4(0), 0);
|
||||
}
|
||||
|
||||
TEST biopAddi2i2_Main()
|
||||
{
|
||||
extern i2 biopAddi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopAddi2i2(0x0101, 0x0101), 514);
|
||||
ASSERTI2(biopAddi2i2(0x0101, -0x0101), 0);
|
||||
ASSERTI2(biopAddi2i2(2, 1), 3);
|
||||
ASSERTI2(biopAddi2i2(I2_MAX, I2_MAX), -2);
|
||||
ASSERTI2(biopAddi2i2(I2_MIN, I2_MIN), 0);
|
||||
ASSERTI2(biopAddi2i2(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopAndu2u2_Main()
|
||||
{
|
||||
extern u2 biopAndu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopAndu2u2(2, 1), 0);
|
||||
ASSERTU2(biopAndu2u2(U2_MAX, U2_MAX), 65535);
|
||||
ASSERTU2(biopAndu2u2(U2_MIN, U2_MIN), 0);
|
||||
ASSERTU2(biopAndu2u2(0, U2_MAX), 0);
|
||||
ASSERTU2(biopAndu2u2(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopLogicAndi1i1_Main()
|
||||
{
|
||||
extern i1 biopLogicAndi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopLogicAndi1i1(2, 1), 1);
|
||||
ASSERTI1(biopLogicAndi1i1(I1_MAX, I1_MAX), 1);
|
||||
ASSERTI1(biopLogicAndi1i1(I1_MIN, I1_MIN), 1);
|
||||
ASSERTI1(biopLogicAndi1i1(0, I1_MAX), 0);
|
||||
ASSERTI1(biopLogicAndi1i1(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST unopPlusi4_Main()
|
||||
{
|
||||
extern i4 unopPlusi4(i4 lhs);
|
||||
ASSERTI4(unopPlusi4(0x01010101), 0x01010101);
|
||||
ASSERTI4(unopPlusi4(-0x01010101), -0x01010101);
|
||||
ASSERTI4(unopPlusi4(2), 2);
|
||||
ASSERTI4(unopPlusi4(I4_MAX), 2147483647);
|
||||
ASSERTI4(unopPlusi4(I4_MIN), -2147483648);
|
||||
ASSERTI4(unopPlusi4(0), 0);
|
||||
}
|
||||
|
||||
TEST biopShtLfti2i2_Main()
|
||||
{
|
||||
extern i2 biopShtLfti2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopShtLfti2i2(0x0101, 16), 0x0);
|
||||
ASSERTI2(biopShtLfti2i2(0x0101, 8), 0x100);
|
||||
ASSERTI2(biopShtLfti2i2(0x0101, 0), 0x101);
|
||||
ASSERTI2(biopShtLfti2i2(2, 1), 4);
|
||||
ASSERTI2(biopShtLfti2i2(I2_MAX, 4), -16);
|
||||
ASSERTI2(biopShtLfti2i2(I2_MIN, 4), 0);
|
||||
ASSERTI2(biopShtLfti2i2(0, 4), 0);
|
||||
}
|
||||
|
||||
TEST biopOru2u2_Main()
|
||||
{
|
||||
extern u2 biopOru2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopOru2u2(2, 1), 3);
|
||||
ASSERTU2(biopOru2u2(U2_MAX, U2_MAX), 65535);
|
||||
ASSERTU2(biopOru2u2(U2_MAX, 0), 65535);
|
||||
ASSERTU2(biopOru2u2(U2_MAX, U2_MAX), 65535);
|
||||
}
|
||||
|
||||
TEST unopNoti1_Main()
|
||||
{
|
||||
extern i1 unopNoti1(i1 lhs);
|
||||
ASSERTI1(unopNoti1(2), 0);
|
||||
ASSERTI1(unopNoti1(I1_MAX), 0);
|
||||
ASSERTI1(unopNoti1(I1_MIN), 0);
|
||||
ASSERTI1(unopNoti1(0), 1);
|
||||
}
|
||||
|
||||
TEST biopMultu4u4_Main()
|
||||
{
|
||||
extern u4 biopMultu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopMultu4u4(0x01010101, 0x01010101), 67305985);
|
||||
ASSERTU4(biopMultu4u4(2, 1), 2);
|
||||
ASSERTU4(biopMultu4u4(~2, ~1), 6);
|
||||
ASSERTU4(biopMultu4u4(U4_MAX, U4_MAX), 1);
|
||||
ASSERTU4(biopMultu4u4(U4_MAX, 1), U4_MAX);
|
||||
ASSERTU4(biopMultu4u4(U4_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopShtRhti2i2_Main()
|
||||
{
|
||||
extern i2 biopShtRhti2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopShtRhti2i2(0x0101, 16), 0x0);
|
||||
ASSERTI2(biopShtRhti2i2(0x0101, 8), 0x1);
|
||||
ASSERTI2(biopShtRhti2i2(0x0101, 0), 0x0101);
|
||||
ASSERTI2(biopShtRhti2i2(2, 1), 1);
|
||||
ASSERTI2(biopShtRhti2i2(I2_MAX, 4), 2047);
|
||||
ASSERTI2(biopShtRhti2i2(I2_MAX, 0), 32767);
|
||||
ASSERTI2(biopShtRhti2i2(I2_MIN, 4), -2048);
|
||||
ASSERTI2(biopShtRhti2i2(I2_MIN, 0), -32768);
|
||||
}
|
||||
|
||||
TEST biopXOru2u2_Main()
|
||||
{
|
||||
extern u2 biopXOru2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopXOru2u2(2, 1), 3);
|
||||
ASSERTU2(biopXOru2u2(U2_MAX, U2_MAX), 0);
|
||||
ASSERTU2(biopXOru2u2(0, 0), 0);
|
||||
ASSERTU2(biopXOru2u2(0, U2_MAX), 65535);
|
||||
}
|
||||
|
||||
TEST biopSubu4u4_Main()
|
||||
{
|
||||
extern u4 biopSubu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopSubu4u4(0x01010101, 0x01010101), 0);
|
||||
ASSERTU4(biopSubu4u4(2, 1), 1);
|
||||
ASSERTU4(biopSubu4u4(~2, ~1), 4294967295);
|
||||
ASSERTU4(biopSubu4u4(U4_MAX, U4_MAX), 0);
|
||||
ASSERTU4(biopSubu4u4(U4_MAX, 0), U4_MAX);
|
||||
ASSERTU4(biopSubu4u4(0, U4_MAX), 1);
|
||||
}
|
||||
|
||||
TEST unopNegativei1_Main()
|
||||
{
|
||||
extern i1 unopNegativei1(i1 lhs);
|
||||
ASSERTI1(unopNegativei1(2), -2);
|
||||
ASSERTI1(unopNegativei1(I1_MAX), -127);
|
||||
ASSERTI1(unopNegativei1(I1_MIN), -128);
|
||||
ASSERTI1(unopNegativei1(0), 0);
|
||||
}
|
||||
|
||||
TEST biopGti2i2_Main()
|
||||
{
|
||||
extern i2 biopGti2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopGti2i2(0x0101, 0x0101), 0);
|
||||
ASSERTI2(biopGti2i2(0x0101, 0x0100), 1);
|
||||
ASSERTI2(biopGti2i2(0x0101, -0x0101), 1);
|
||||
ASSERTI2(biopGti2i2(2, 1), 1);
|
||||
ASSERTI2(biopGti2i2(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI2(biopGti2i2(I1_MIN, I1_MIN), 0);
|
||||
ASSERTI2(biopGti2i2(I1_MAX-1, I1_MAX), 0);
|
||||
ASSERTI2(biopGti2i2(I1_MAX, I1_MAX-1), 1);
|
||||
}
|
||||
|
||||
TEST biopLogicOru2u2_Main()
|
||||
{
|
||||
extern u2 biopLogicOru2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopLogicOru2u2(2, 1), 1);
|
||||
ASSERTU2(biopLogicOru2u2(2, 1), 1);
|
||||
ASSERTU2(biopLogicOru2u2(U2_MAX, U2_MAX), 1);
|
||||
ASSERTU2(biopLogicOru2u2(U2_MIN, U2_MIN), 0);
|
||||
ASSERTU2(biopLogicOru2u2(U2_MAX, U2_MIN), 1);
|
||||
ASSERTU2(biopLogicOru2u2(U2_MAX, 0), 1);
|
||||
ASSERTU2(biopLogicOru2u2(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopAddu4u4_Main()
|
||||
{
|
||||
extern u4 biopAddu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopAddu4u4(0x01010101, 0x01010101), 33686018);
|
||||
ASSERTU4(biopAddu4u4(2, 1), 3);
|
||||
ASSERTU4(biopAddu4u4(~2, ~1), 4294967291);
|
||||
ASSERTU4(biopAddu4u4(U4_MAX, U4_MAX), -2);
|
||||
ASSERTU4(biopAddu4u4(U4_MAX, 0), -1);
|
||||
ASSERTU4(biopAddu4u4(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST unopPlusi1_Main()
|
||||
{
|
||||
extern i1 unopPlusi1(i1 lhs);
|
||||
ASSERTI1(unopPlusi1(2), 2);
|
||||
ASSERTI1(unopPlusi1(I1_MAX), 127);
|
||||
ASSERTI1(unopPlusi1(I1_MIN), -128);
|
||||
ASSERTI1(unopPlusi1(0), 0);
|
||||
}
|
||||
|
||||
TEST biopGei2i2_Main()
|
||||
{
|
||||
extern i2 biopGei2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopGei2i2(2, 1), 1);
|
||||
ASSERTI2(biopGei2i2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTI2(biopGei2i2(I2_MIN, I2_MIN), 1);
|
||||
ASSERTI2(biopGei2i2(I2_MAX, I2_MIN), 1);
|
||||
ASSERTI2(biopGei2i2(I2_MIN, I2_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopLogicAndu2u2_Main()
|
||||
{
|
||||
extern u2 biopLogicAndu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopLogicAndu2u2(2, 1), 1);
|
||||
ASSERTU2(biopLogicAndu2u2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTU2(biopLogicAndu2u2(I2_MIN, I2_MIN), 1);
|
||||
ASSERTU2(biopLogicAndu2u2(I2_MAX, I2_MIN), 1);
|
||||
ASSERTU2(biopLogicAndu2u2(I2_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopMultu1u1_Main()
|
||||
{
|
||||
extern u1 biopMultu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopMultu1u1(0x01, 0x01), 1);
|
||||
ASSERTU1(biopMultu1u1(U1_MAX, 1), U1_MAX);
|
||||
ASSERTU1(biopMultu1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTU1(biopMultu1u1(U1_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopGtu1u1_Main()
|
||||
{
|
||||
extern u1 biopGtu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopGtu1u1(0x01, 0x01), 0);
|
||||
ASSERTU1(biopGtu1u1(U1_MAX, U1_MAX), 0);
|
||||
ASSERTU1(biopGtu1u1(U1_MAX, 0), 1);
|
||||
ASSERTU1(biopGtu1u1(0, U1_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopShtLftu4u4_Main()
|
||||
{
|
||||
extern u4 biopShtLftu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopShtLftu4u4(0x01010101, 16), 0x01010000);
|
||||
ASSERTU4(biopShtLftu4u4(2, 1), 4);
|
||||
ASSERTU4(biopShtLftu4u4(U4_MAX, 4*8-1), 2147483648);
|
||||
ASSERTU4(biopShtLftu4u4(U4_MAX, 4), -16);
|
||||
}
|
||||
|
||||
TEST biopOri2i2_Main()
|
||||
{
|
||||
extern i2 biopOri2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopOri2i2(2, 1), 3);
|
||||
ASSERTI2(biopOri2i2(0x0101, 0x0101), 0x0101);
|
||||
ASSERTI2(biopOri2i2(0x0101, 0x1010), 0x1111);
|
||||
ASSERTI2(biopOri2i2(0x0101, 0x0), 0x0101);
|
||||
ASSERTI2(biopOri2i2(I2_MAX, I2_MAX), 32767);
|
||||
ASSERTI2(biopOri2i2(I2_MAX, I2_MIN), -1);
|
||||
ASSERTI2(biopOri2i2(I2_MAX, 0), 32767);
|
||||
}
|
||||
|
||||
TEST biopLti2i2_Main()
|
||||
{
|
||||
extern i2 biopLti2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopLti2i2(2, 1), 0);
|
||||
ASSERTI2(biopLti2i2(0x0101, 0x0101), 0);
|
||||
ASSERTI2(biopLti2i2(0x0101, -0x0101), 0);
|
||||
ASSERTI2(biopLti2i2(0x0101, -0x0101), 0);
|
||||
ASSERTI2(biopLti2i2(I2_MAX, I2_MAX), 0);
|
||||
ASSERTI2(biopLti2i2(I2_MAX, I2_MIN), 0);
|
||||
ASSERTI2(biopLti2i2(I2_MAX, 0), 0);
|
||||
ASSERTI2(biopLti2i2(0, I2_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopMulti4i4_Main()
|
||||
{
|
||||
extern i4 biopMulti4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopMulti4i4(2, 1), 2);
|
||||
ASSERTI4(biopMulti4i4(0x01010101, 0x01010101), 67305985);
|
||||
ASSERTI4(biopMulti4i4(0x01010101, -16843009), -67305985);
|
||||
ASSERTI4(biopMulti4i4(0, -16843009), 0);
|
||||
ASSERTI4(biopMulti4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopMulti4i4(I4_MAX, I4_MIN), -2147483648);
|
||||
ASSERTI4(biopMulti4i4(I4_MAX, 0), 0);
|
||||
}
|
||||
|
||||
MAIN BIOPS_main() { }
|
662
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS2.test
Normal file
662
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS2.test
Normal file
@ -0,0 +1,662 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST unopNotu2_Main()
|
||||
{
|
||||
extern u2 unopNotu2(u2 lhs);
|
||||
ASSERTU2(unopNotu2(2), 0);
|
||||
ASSERTU2(unopNotu2(U2_MAX), 0);
|
||||
ASSERTU2(unopNotu2(0), 1);
|
||||
}
|
||||
|
||||
TEST biopSubu1u1_Main()
|
||||
{
|
||||
extern u1 biopSubu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopSubu1u1(0x01, 0x01), 0);
|
||||
ASSERTU1(biopSubu1u1(U1_MAX, U1_MAX), 0);
|
||||
ASSERTU1(biopSubu1u1(U1_MAX, 0), U1_MAX);
|
||||
ASSERTU1(biopSubu1u1(0, U1_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopGeu1u1_Main()
|
||||
{
|
||||
extern u1 biopGeu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopGeu1u1(0x01, 0x01), 1);
|
||||
ASSERTU1(biopGeu1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTU1(biopGeu1u1(U1_MAX, 0), 1);
|
||||
ASSERTU1(biopGeu1u1(0, U1_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopShtRhtu4u4_Main()
|
||||
{
|
||||
extern u4 biopShtRhtu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopShtRhtu4u4(0x01010101, 16), 0x0101);
|
||||
ASSERTU4(biopShtRhtu4u4(2, 1), 1);
|
||||
ASSERTU4(biopShtRhtu4u4(U4_MAX, 4), 268435455);
|
||||
ASSERTU4(biopShtRhtu4u4(U4_MAX, 4*8-1), 1);
|
||||
ASSERTU4(biopShtRhtu4u4(4, 4), 0);
|
||||
}
|
||||
|
||||
TEST biopXOri2i2_Main()
|
||||
{
|
||||
extern i2 biopXOri2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopXOri2i2(2, 1), 3);
|
||||
ASSERTI2(biopXOri2i2(0x0101, 0x0101), 0);
|
||||
ASSERTI2(biopXOri2i2(0x0101, 0x1010), 0x1111);
|
||||
ASSERTI2(biopXOri2i2(I2_MAX, I2_MAX), 0);
|
||||
ASSERTI2(biopXOri2i2(I2_MAX, I2_MIN), -1);
|
||||
ASSERTI2(biopXOri2i2(I2_MAX, 0), 32767);
|
||||
ASSERTI2(biopXOri2i2(I2_MAX, -1), -32768);
|
||||
}
|
||||
|
||||
TEST biopLei2i2_Main()
|
||||
{
|
||||
extern i2 biopLei2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopLei2i2(2, 1), 0);
|
||||
ASSERTI2(biopLei2i2(0x0101, 0x0101), 1);
|
||||
ASSERTI2(biopLei2i2(0x0101, 0x0100), 0);
|
||||
ASSERTI2(biopLei2i2(0x0101, -0x0101), 0);
|
||||
ASSERTI2(biopLei2i2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTI2(biopLei2i2(I2_MAX, I2_MIN), 0);
|
||||
ASSERTI2(biopLei2i2(I2_MIN, I2_MAX), 1);
|
||||
ASSERTI2(biopLei2i2(I2_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopSubi4i4_Main()
|
||||
{
|
||||
extern i4 biopSubi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopSubi4i4(2, 1), 1);
|
||||
ASSERTI4(biopSubi4i4(0x01010101, 0x01010101), 0);
|
||||
ASSERTI4(biopSubi4i4(0x01010101, 0x01000100), 0x00010001);
|
||||
ASSERTI4(biopSubi4i4(0x01000100, 0x01010101), -0x00010001);
|
||||
ASSERTI4(biopSubi4i4(I4_MAX, I4_MAX), 0);
|
||||
ASSERTI4(biopSubi4i4(I4_MAX, I4_MIN), -1);
|
||||
ASSERTI4(biopSubi4i4(I4_MAX, 0), 2147483647);
|
||||
ASSERTI4(biopSubi4i4(0, I4_MAX), -2147483647);
|
||||
}
|
||||
|
||||
TEST biopAddu1u1_Main()
|
||||
{
|
||||
extern u1 biopAddu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopAddu1u1(0x01, 0x01), 2);
|
||||
ASSERTU1(biopAddu1u1(U1_MAX, U1_MAX), 254);
|
||||
ASSERTU1(biopAddu1u1(U1_MAX, 0), 255);
|
||||
ASSERTU1(biopAddu1u1(U1_MAX, 1), 0);
|
||||
}
|
||||
|
||||
TEST biopLtu1u1_Main()
|
||||
{
|
||||
extern u1 biopLtu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopLtu1u1(0x01, 0x01), 0);
|
||||
ASSERTU1(biopLtu1u1(U1_MAX, U1_MAX), 0);
|
||||
ASSERTU1(biopLtu1u1(U1_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopGtu4u4_Main()
|
||||
{
|
||||
extern u4 biopGtu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopGtu4u4(0x01010101, 0x01010101), 0);
|
||||
ASSERTU4(biopGtu4u4(2, 1), 1);
|
||||
ASSERTU4(biopGtu4u4(U4_MAX, U4_MAX), 0);
|
||||
ASSERTU4(biopGtu4u4(U4_MAX, 0), 1);
|
||||
ASSERTU4(biopGtu4u4(0, U4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopLogicOri2i2_Main()
|
||||
{
|
||||
extern i2 biopLogicOri2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopLogicOri2i2(0x0101, 0x0101), 1);
|
||||
ASSERTI2(biopLogicOri2i2(2, 1), 1);
|
||||
ASSERTI2(biopLogicOri2i2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTI2(biopLogicOri2i2(I2_MAX, I2_MIN), 1);
|
||||
ASSERTI2(biopLogicOri2i2(I2_MAX, 0), 1);
|
||||
ASSERTI2(biopLogicOri2i2(0, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopEqi2i2_Main()
|
||||
{
|
||||
extern i2 biopEqi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopEqi2i2(2, 1), 0);
|
||||
ASSERTI2(biopEqi2i2(0x0101, 0x0101), 1);
|
||||
ASSERTI2(biopEqi2i2(0x0101, 0x0100), 0);
|
||||
ASSERTI2(biopEqi2i2(0x0101, -0x0101), 0);
|
||||
ASSERTI2(biopEqi2i2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTI2(biopEqi2i2(I2_MIN, I2_MIN), 1);
|
||||
ASSERTI2(biopEqi2i2(I2_MAX-1, I2_MAX), 0);
|
||||
}
|
||||
|
||||
TEST unopPlusu2_Main()
|
||||
{
|
||||
extern u2 unopPlusu2(u2 lhs);
|
||||
ASSERTU2(unopPlusu2(2), 2);
|
||||
ASSERTU2(unopPlusu2(U2_MAX), 65535);
|
||||
ASSERTU2(unopPlusu2(0), 0);
|
||||
}
|
||||
|
||||
TEST biopAddi4i4_Main()
|
||||
{
|
||||
extern i4 biopAddi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopAddi4i4(2, 1), 3);
|
||||
ASSERTI4(biopAddi4i4(0x01010101, 0x01010101), 33686018);
|
||||
ASSERTI4(biopAddi4i4(0x01010101, -0x01010101), 0);
|
||||
ASSERTI4(biopAddi4i4(I4_MAX, I4_MAX), -2);
|
||||
ASSERTI4(biopAddi4i4(I4_MAX, I4_MIN), -1);
|
||||
ASSERTI4(biopAddi4i4(I4_MAX, 0), 2147483647);
|
||||
ASSERTI4(biopAddi4i4(I4_MIN, I4_MIN), 0);
|
||||
}
|
||||
|
||||
TEST biopGeu4u4_Main()
|
||||
{
|
||||
extern u4 biopGeu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopGeu4u4(2, 1), 1);
|
||||
ASSERTU4(biopGeu4u4(U4_MAX, U4_MAX), 1);
|
||||
ASSERTU4(biopGeu4u4(U4_MAX, 0), 1);
|
||||
ASSERTU4(biopGeu4u4(0, U4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopShtLftu1u1_Main()
|
||||
{
|
||||
extern u1 biopShtLftu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopShtLftu1u1(0x01, 2), 0x4);
|
||||
ASSERTU1(biopShtLftu1u1(U1_MAX, 2), 252);
|
||||
ASSERTU1(biopShtLftu1u1(U1_MAX, 8-1), 128);
|
||||
ASSERTU1(biopShtLftu1u1(U1_MAX, 8), 0);
|
||||
ASSERTU1(biopShtLftu1u1(2, 1), 0x4);
|
||||
}
|
||||
|
||||
TEST biopLeu1u1_Main()
|
||||
{
|
||||
extern u1 biopLeu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopLeu1u1(0x01, 0x01), 1);
|
||||
ASSERTU1(biopLeu1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTU1(biopLeu1u1(0, 0), 1);
|
||||
ASSERTU1(biopLeu1u1(U1_MAX, 0), 0);
|
||||
ASSERTU1(biopLeu1u1(0, U1_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopLogicAndi2i2_Main()
|
||||
{
|
||||
extern i2 biopLogicAndi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopLogicAndi2i2(0x0101, 0x0101), 1);
|
||||
ASSERTI2(biopLogicAndi2i2(2, 1), 1);
|
||||
ASSERTI2(biopLogicAndi2i2(0x0101, 0x0101), 1);
|
||||
ASSERTI2(biopLogicAndi2i2(0x0101, 0x0), 0);
|
||||
ASSERTI2(biopLogicAndi2i2(I2_MAX, I2_MAX), 1);
|
||||
ASSERTI2(biopLogicAndi2i2(I2_MIN, I2_MIN), 1);
|
||||
ASSERTI2(biopLogicAndi2i2(I2_MAX, I2_MIN), 1);
|
||||
ASSERTI2(biopLogicAndi2i2(I2_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopNei2i2_Main()
|
||||
{
|
||||
extern i2 biopNei2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopNei2i2(2, 1), 1);
|
||||
ASSERTI2(biopNei2i2(0x0101, 0x0101), 0);
|
||||
ASSERTI2(biopNei2i2(0x0101, 0x0100), 1);
|
||||
ASSERTI2(biopNei2i2(0x0101, -0x0101), 1);
|
||||
ASSERTI2(biopNei2i2(I2_MAX, I2_MAX), 0);
|
||||
ASSERTI2(biopNei2i2(I2_MAX, I2_MIN), 1);
|
||||
ASSERTI2(biopNei2i2(I2_MIN, I2_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopMulti1i1_Main()
|
||||
{
|
||||
extern i1 biopMulti1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopMulti1i1(2, 1), 2);
|
||||
ASSERTI1(biopMulti1i1(I1_MAX, I1_MAX), 1);
|
||||
ASSERTI1(biopMulti1i1(I1_MAX, I1_MIN), -128);
|
||||
ASSERTI1(biopMulti1i1(I1_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopShtLfti4i4_Main()
|
||||
{
|
||||
extern i4 biopShtLfti4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopShtLfti4i4(2, 1), 4);
|
||||
ASSERTI4(biopShtLfti4i4(0x01010101, 16), 0x01010000);
|
||||
ASSERTI4(biopShtLfti4i4(0x01010101, 0), 0x01010101);
|
||||
ASSERTI4(biopShtLfti4i4(I4_MAX, 2), -4);
|
||||
ASSERTI4(biopShtLfti4i4(I4_MAX, 0), 2147483647);
|
||||
}
|
||||
|
||||
TEST biopLtu4u4_Main()
|
||||
{
|
||||
extern u4 biopLtu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopLtu4u4(0x01010101, 0x01010101), 0);
|
||||
ASSERTU4(biopLtu4u4(2, 1), 0);
|
||||
ASSERTU4(biopLtu4u4(U4_MAX, U4_MAX), 0);
|
||||
ASSERTU4(biopLtu4u4(U4_MAX, 0), 0);
|
||||
ASSERTU4(biopLtu4u4(0, U4_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopShtRhtu1u1_Main()
|
||||
{
|
||||
extern u1 biopShtRhtu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopShtRhtu1u1(0x80, 2), 0x20);
|
||||
ASSERTU1(biopShtRhtu1u1(U1_MAX, 2), 63);
|
||||
ASSERTU1(biopShtRhtu1u1(U1_MAX, 8-1), 1);
|
||||
ASSERTU1(biopShtRhtu1u1(U1_MAX, 8), 0);
|
||||
}
|
||||
|
||||
TEST biopEqu1u1_Main()
|
||||
{
|
||||
extern u1 biopEqu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopEqu1u1(0x01, 0x01), 1);
|
||||
ASSERTU1(biopEqu1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTU1(biopEqu1u1(U1_MAX, 0), 0);
|
||||
ASSERTU1(biopEqu1u1(0, U1_MAX), 0);
|
||||
}
|
||||
|
||||
TEST unopNoti2_Main()
|
||||
{
|
||||
extern i2 unopNoti2(i2 lhs);
|
||||
ASSERTI2(unopNoti2(0x0101), 0);
|
||||
ASSERTI2(unopNoti2(2), 0);
|
||||
ASSERTI2(unopNoti2(I2_MAX), 0);
|
||||
ASSERTI2(unopNoti2(I2_MIN), 0);
|
||||
ASSERTI2(unopNoti2(0), 1);
|
||||
}
|
||||
|
||||
TEST biopAndi2i2_Main()
|
||||
{
|
||||
extern i2 biopAndi2i2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopAndi2i2(2, 1), 0);
|
||||
ASSERTI2(biopAndi2i2(0x0101, 0x0101), 0x0101);
|
||||
ASSERTI2(biopAndi2i2(0x0101, 0x1010), 0x0);
|
||||
ASSERTI2(biopAndi2i2(I2_MAX, I2_MAX), 32767);
|
||||
ASSERTI2(biopAndi2i2(I2_MIN, I2_MIN), -32768);
|
||||
ASSERTI2(biopAndi2i2(I2_MAX, I2_MIN), 0);
|
||||
ASSERTI2(biopAndi2i2(I2_MAX, 0), 0x0);
|
||||
}
|
||||
|
||||
TEST biopSubi1i1_Main()
|
||||
{
|
||||
extern i1 biopSubi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopSubi1i1(2, 1), 1);
|
||||
ASSERTI1(biopSubi1i1(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI1(biopSubi1i1(I1_MAX, I1_MIN), -1);
|
||||
ASSERTI1(biopSubi1i1(I1_MIN, I1_MAX), 1);
|
||||
ASSERTI1(biopSubi1i1(I1_MIN, I1_MIN), 0);
|
||||
ASSERTI1(biopSubi1i1(I1_MAX, 0), 127);
|
||||
|
||||
}
|
||||
|
||||
TEST biopNeu1u1_Main()
|
||||
{
|
||||
extern u1 biopNeu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopNeu1u1(0x01, 0x01), 0);
|
||||
ASSERTU1(biopNeu1u1(U1_MAX, U1_MAX), 0);
|
||||
ASSERTU1(biopNeu1u1(U1_MAX, 0), 1);
|
||||
ASSERTU1(biopNeu1u1(0, U1_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopShtRhti4i4_Main()
|
||||
{
|
||||
extern i4 biopShtRhti4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopShtRhti4i4(2, 1), 1);
|
||||
ASSERTI4(biopShtRhti4i4(0x01010101, 16), 0x0101);
|
||||
ASSERTI4(biopShtRhti4i4(0x01010101, 31), 0x0);
|
||||
ASSERTI4(biopShtRhti4i4(0x01010101, 0), 0x01010101);
|
||||
ASSERTI4(biopShtRhti4i4(I4_MAX, 2), 536870911);
|
||||
}
|
||||
|
||||
TEST biopLeu4u4_Main()
|
||||
{
|
||||
extern u4 biopLeu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopLeu4u4(0x01010101, 0x01010101), 1);
|
||||
ASSERTU4(biopLeu4u4(2, 1), 0);
|
||||
ASSERTU4(biopLeu4u4(U4_MAX, U4_MAX), 1);
|
||||
ASSERTU4(biopLeu4u4(U4_MAX, 0), 0);
|
||||
ASSERTU4(biopLeu4u4(0, U4_MAX), 1);
|
||||
}
|
||||
|
||||
TEST unopNegativei2_Main()
|
||||
{
|
||||
extern i2 unopNegativei2(i2 lhs);
|
||||
ASSERTI2(unopNegativei2(0x0101), -0x0101);
|
||||
ASSERTI2(unopNegativei2(-0x0101), 0x0101);
|
||||
ASSERTI2(unopNegativei2(I2_MAX), -32767);
|
||||
ASSERTI2(unopNegativei2(I2_MIN), I2_MIN);
|
||||
ASSERTI2(unopNegativei2(0), 0);
|
||||
}
|
||||
|
||||
TEST biopGti4i4_Main()
|
||||
{
|
||||
extern i4 biopGti4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopGti4i4(2, 1), 1);
|
||||
ASSERTI4(biopGti4i4(0x01010101, 0x01010101), 0);
|
||||
ASSERTI4(biopGti4i4(0x01000101, 0x01010101), 0);
|
||||
ASSERTI4(biopGti4i4(0x01010101, -0x01010101), 1);
|
||||
ASSERTI4(biopGti4i4(I4_MAX, I4_MAX), 0);
|
||||
ASSERTI4(biopGti4i4(I4_MAX, I4_MIN), 1);
|
||||
ASSERTI4(biopGti4i4(I4_MIN, I4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopAddi1i1_Main()
|
||||
{
|
||||
extern i1 biopAddi1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopAddi1i1(2, 1), 3);
|
||||
ASSERTI1(biopAddi1i1(I1_MAX, I1_MAX), -2);
|
||||
ASSERTI1(biopAddi1i1(I1_MAX, I1_MIN), -1);
|
||||
ASSERTI1(biopAddi1i1(I1_MAX, 0), 127);
|
||||
}
|
||||
|
||||
TEST biopAndu1u1_Main()
|
||||
{
|
||||
extern u1 biopAndu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopAndu1u1(0x01, 0x01), 0x01);
|
||||
ASSERTU1(biopAndu1u1(U1_MAX, U1_MAX), 255);
|
||||
ASSERTU1(biopAndu1u1(U1_MAX, 0), 0);
|
||||
ASSERTU1(biopAndu1u1(U1_MAX, 1), 0x01);
|
||||
}
|
||||
|
||||
TEST biopEqu4u4_Main()
|
||||
{
|
||||
extern u4 biopEqu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopEqu4u4(0x01010101, 0x01010101), 1);
|
||||
ASSERTU4(biopEqu4u4(2, 1), 0);
|
||||
ASSERTU4(biopEqu4u4(U4_MAX, U4_MAX), 1);
|
||||
ASSERTU4(biopEqu4u4(U4_MAX, 0), 0);
|
||||
ASSERTU4(biopEqu4u4(0, U4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST unopPlusi2_Main()
|
||||
{
|
||||
extern i2 unopPlusi2(i2 lhs);
|
||||
ASSERTI2(unopPlusi2(0x0101), 0x0101);
|
||||
ASSERTI2(unopPlusi2(-0x0101), -0x0101);
|
||||
ASSERTI2(unopPlusi2(2), 2);
|
||||
ASSERTI2(unopPlusi2(I2_MAX), 32767);
|
||||
ASSERTI2(unopPlusi2(I2_MIN), -32768);
|
||||
ASSERTI2(unopPlusi2(0), 0);
|
||||
}
|
||||
|
||||
TEST biopGei4i4_Main()
|
||||
{
|
||||
extern i4 biopGei4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopGei4i4(2, 1), 1);
|
||||
ASSERTI4(biopGei4i4(-2, 1), 0);
|
||||
ASSERTI4(biopGei4i4(0x01010101, 0x01010100), 1);
|
||||
ASSERTI4(biopGei4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopGei4i4(I4_MAX, I4_MIN), 1);
|
||||
ASSERTI4(biopGei4i4(I4_MIN, I4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopShtLfti1i1_Main()
|
||||
{
|
||||
extern i1 biopShtLfti1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopShtLfti1i1(2, 1), 4);
|
||||
ASSERTI1(biopShtLfti1i1(I1_MAX, 2), -4);
|
||||
ASSERTI1(biopShtLfti1i1(I1_MIN, 2), 0);
|
||||
ASSERTI1(biopShtLfti1i1(I1_MAX, 0), 127);
|
||||
}
|
||||
|
||||
TEST biopOru1u1_Main()
|
||||
{
|
||||
extern u1 biopOru1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopOru1u1(0x01, 0x01), 0x01);
|
||||
ASSERTU1(biopOru1u1(U1_MAX, U1_MAX), U1_MAX);
|
||||
ASSERTU1(biopOru1u1(U1_MAX, U1_MIN), 255);
|
||||
}
|
||||
|
||||
TEST biopNeu4u4_Main()
|
||||
{
|
||||
extern u4 biopNeu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopNeu4u4(0x01010101, 0x01010101), 0);
|
||||
ASSERTU4(biopNeu4u4(2, 1), 1);
|
||||
ASSERTU4(biopNeu4u4(U4_MAX, U4_MAX), 0);
|
||||
ASSERTU4(biopNeu4u4(U4_MAX, 0), 1);
|
||||
ASSERTU4(biopNeu4u4(0, U4_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopMultu2u2_Main()
|
||||
{
|
||||
extern u2 biopMultu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopMultu2u2(2, 1), 2);
|
||||
ASSERTU2(biopMultu2u2(U2_MAX, U2_MAX), 1);
|
||||
ASSERTU2(biopMultu2u2(U2_MAX, 0), 0);
|
||||
ASSERTU2(biopMultu2u2(U2_MAX, 1), U2_MAX);
|
||||
}
|
||||
|
||||
TEST biopShtRhti1i1_Main()
|
||||
{
|
||||
extern i1 biopShtRhti1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopShtRhti1i1(2, 1), 1);
|
||||
ASSERTI1(biopShtRhti1i1(I1_MAX, 2), 31);
|
||||
ASSERTI1(biopShtRhti1i1(16, 4), 1);
|
||||
}
|
||||
|
||||
TEST biopLti4i4_Main()
|
||||
{
|
||||
extern i4 biopLti4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopLti4i4(2, 1), 0);
|
||||
ASSERTI4(biopLti4i4(0x01010101, 0x01010101), 0);
|
||||
ASSERTI4(biopLti4i4(0x01000101, 0x01010101), 1);
|
||||
ASSERTI4(biopLti4i4(0x01010101, -0x01010101), 0);
|
||||
}
|
||||
|
||||
TEST biopAndu4u4_Main()
|
||||
{
|
||||
extern u4 biopAndu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopAndu4u4(0x01010101, 0x01010101), 0x01010101);
|
||||
ASSERTU4(biopAndu4u4(2, 1), 0);
|
||||
ASSERTU4(biopAndu4u4(U4_MAX, U4_MAX), -1);
|
||||
ASSERTU4(biopAndu4u4(U4_MAX, U4_MIN), 0);
|
||||
ASSERTU4(biopAndu4u4(U4_MAX, 0), 0);
|
||||
}
|
||||
|
||||
TEST biopXOru1u1_Main()
|
||||
{
|
||||
extern u1 biopXOru1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopXOru1u1(0x01, 0x01), 0);
|
||||
ASSERTU1(biopXOru1u1(U1_MAX, U1_MAX), 0);
|
||||
ASSERTU1(biopXOru1u1(U1_MAX, 0), 255);
|
||||
}
|
||||
|
||||
TEST biopSubu2u2_Main()
|
||||
{
|
||||
extern u2 biopSubu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopSubu2u2(2, 1), 1);
|
||||
ASSERTU2(biopSubu2u2(2, 1), 1);
|
||||
ASSERTU2(biopSubu2u2(U2_MAX, U2_MAX), 0);
|
||||
ASSERTU2(biopSubu2u2(U2_MAX, 0), U2_MAX);
|
||||
ASSERTU2(biopSubu2u2(0, U2_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopGti1i1_Main()
|
||||
{
|
||||
extern i1 biopGti1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopGti1i1(2, 1), 1);
|
||||
ASSERTI1(biopGti1i1(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI1(biopGti1i1(I1_MAX, I1_MIN), 1);
|
||||
ASSERTI1(biopGti1i1(I1_MIN, I1_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopLei4i4_Main()
|
||||
{
|
||||
extern i4 biopLei4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopLei4i4(2, 1), 0);
|
||||
ASSERTI4(biopLei4i4(0x01010101, 0x01010101), 1);
|
||||
ASSERTI4(biopLei4i4(0x01000101, 0x01010101), 1);
|
||||
ASSERTI4(biopLei4i4(0x01010101, -0x01010101), 0);
|
||||
ASSERTI4(biopLei4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopLei4i4(I4_MAX, I4_MIN), 0);
|
||||
ASSERTI4(biopLei4i4(I4_MIN, I4_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopOru4u4_Main()
|
||||
{
|
||||
extern u4 biopOru4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopOru4u4(0x01010101, 0x01010101), 0x01010101);
|
||||
ASSERTU4(biopOru4u4(2, 1), 3);
|
||||
ASSERTU4(biopOru4u4(U4_MAX, U4_MAX), U4_MAX);
|
||||
ASSERTU4(biopOru4u4(U4_MAX, 0), U4_MAX);
|
||||
}
|
||||
|
||||
TEST biopLogicOru1u1_Main()
|
||||
{
|
||||
extern u1 biopLogicOru1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopLogicOru1u1(0x01, 0x01), 1);
|
||||
ASSERTU1(biopLogicOru1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTU1(biopLogicOru1u1(U1_MAX, 0), 1);
|
||||
}
|
||||
|
||||
TEST biopAddu2u2_Main()
|
||||
{
|
||||
extern u2 biopAddu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopAddu2u2(2, 1), 3);
|
||||
ASSERTU2(biopAddu2u2(U2_MAX, U2_MAX), 65534);
|
||||
ASSERTU2(biopAddu2u2(U2_MAX, 0), U2_MAX);
|
||||
}
|
||||
|
||||
TEST biopGei1i1_Main()
|
||||
{
|
||||
extern i1 biopGei1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopGei1i1(2, 1), 1);
|
||||
ASSERTI1(biopGei1i1(I1_MAX, I1_MAX), 1);
|
||||
ASSERTI1(biopGei1i1(I1_MAX, I1_MIN), 1);
|
||||
ASSERTI1(biopGei1i1(I1_MIN, I1_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopLogicAndu1u1_Main()
|
||||
{
|
||||
extern u1 biopLogicAndu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopLogicAndu1u1(0x01, 0x01), 1);
|
||||
ASSERTU1(biopLogicAndu1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTU1(biopLogicAndu1u1(U1_MAX, 0), 0);
|
||||
ASSERTU1(biopLogicAndu1u1(U1_MAX, 1), 1);
|
||||
}
|
||||
|
||||
TEST biopEqi4i4_Main()
|
||||
{
|
||||
extern i4 biopEqi4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopEqi4i4(0x01010101, -0x01010101), 0);
|
||||
ASSERTI4(biopEqi4i4(2, 1), 0);
|
||||
ASSERTI4(biopEqi4i4(0x01010101, 0x01010101), 1);
|
||||
ASSERTI4(biopEqi4i4(0x01000101, 0x01010101), 0);
|
||||
ASSERTI4(biopEqi4i4(I4_MAX, I4_MAX), 1);
|
||||
ASSERTI4(biopEqi4i4(I4_MAX, I4_MIN), 0);
|
||||
ASSERTI4(biopEqi4i4(I4_MIN, I4_MAX), 0);
|
||||
}
|
||||
|
||||
TEST biopXOru4u4_Main()
|
||||
{
|
||||
extern u4 biopXOru4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopXOru4u4(0x01010101, 0x01010101), 0);
|
||||
ASSERTU4(biopXOru4u4(2, 1), 3);
|
||||
ASSERTU4(biopXOru4u4(U4_MAX, U4_MAX), 0);
|
||||
ASSERTU4(biopXOru4u4(U4_MAX, U4_MIN), -1);
|
||||
ASSERTU4(biopXOru4u4(U4_MAX, 0), -1);
|
||||
}
|
||||
|
||||
TEST biopShtLftu2u2_Main()
|
||||
{
|
||||
extern u2 biopShtLftu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopShtLftu2u2(2, 1), 4);
|
||||
ASSERTU2(biopShtLftu2u2(2, 1), 4);
|
||||
ASSERTU2(biopShtLftu2u2(U2_MAX, 2), 65532);
|
||||
ASSERTU2(biopShtLftu2u2(U2_MAX, 0), 65535);
|
||||
}
|
||||
|
||||
TEST biopNei4i4_Main()
|
||||
{
|
||||
extern i4 biopNei4i4(i4 lhs, i4 rhs);
|
||||
ASSERTI4(biopNei4i4(0x01010101, 0x01010101), 0);
|
||||
ASSERTI4(biopNei4i4(0x01000101, 0x01010101), 1);
|
||||
ASSERTI4(biopNei4i4(0x01000101, -0x01010101), 1);
|
||||
ASSERTI4(biopNei4i4(2, 1), 1);
|
||||
ASSERTI4(biopNei4i4(I4_MAX, I4_MAX), 0);
|
||||
ASSERTI4(biopNei4i4(I4_MAX, I4_MIN), 1);
|
||||
ASSERTI4(biopNei4i4(I4_MIN, I4_MAX), 1);
|
||||
}
|
||||
|
||||
TEST biopLti1i1_Main()
|
||||
{
|
||||
extern i1 biopLti1i1(i1 lhs, i1 rhs);
|
||||
ASSERTI1(biopLti1i1(2, 1), 0);
|
||||
ASSERTI1(biopLti1i1(I1_MAX, I1_MAX), 0);
|
||||
ASSERTI1(biopLti1i1(I1_MAX, I1_MIN), 0);
|
||||
ASSERTI1(biopLti1i1(I1_MIN, I1_MAX), 1);
|
||||
}
|
||||
|
||||
TEST unopNotu1_Main()
|
||||
{
|
||||
extern u1 unopNotu1(u1 lhs);
|
||||
ASSERTU1(unopNotu1(0x01), 0);
|
||||
ASSERTU1(unopNotu1(U1_MAX), 0);
|
||||
ASSERTU1(unopNotu1(0), 1);
|
||||
}
|
||||
|
||||
TEST biopLogicOru4u4_Main()
|
||||
{
|
||||
extern u4 biopLogicOru4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopLogicOru4u4(0x01010101, 0x01010101), 1);
|
||||
ASSERTU4(biopLogicOru4u4(2, 1), 1);
|
||||
ASSERTU4(biopLogicOru4u4(U4_MAX, U4_MAX), 1);
|
||||
ASSERTU4(biopLogicOru4u4(U4_MAX, U4_MIN), 1);
|
||||
}
|
||||
|
||||
TEST biopShtRhtu2u2_Main()
|
||||
{
|
||||
extern u2 biopShtRhtu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopShtRhtu2u2(2, 1), 1);
|
||||
ASSERTU2(biopShtRhtu2u2(U2_MAX, 2), 16383);
|
||||
ASSERTU2(biopShtRhtu2u2(U2_MAX, 0), 65535);
|
||||
}
|
||||
|
||||
TEST biopDividu1u1_Main()
|
||||
{
|
||||
extern i1 biopDividu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTI1(biopDividu1u1(0x01, 0x01), 1);
|
||||
ASSERTI1(biopDividu1u1(U1_MAX, U1_MAX), 1);
|
||||
ASSERTI1(biopDividu1u1(U1_MAX, 1), U1_MAX);
|
||||
}
|
||||
|
||||
TEST biopDividu2u2_Main()
|
||||
{
|
||||
extern i2 biopDividu2u2(i2 lhs, i2 rhs);
|
||||
ASSERTI2(biopDividu2u2(0x0101, 0x0101), 0x1);
|
||||
ASSERTI2(biopDividu2u2(U2_MAX, U2_MAX), 0x1);
|
||||
}
|
||||
|
||||
TEST biopDividu4u4_Main()
|
||||
{
|
||||
extern u4 biopDividu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopDividu4u4(0x01010101, 0x01010101), 1);
|
||||
ASSERTU4(biopDividu4u4(-0x01010101, 0x01010101), 254);
|
||||
ASSERTU4(biopDividu4u4(0, 0x01010101), 0);
|
||||
ASSERTU4(biopDividu4u4(0x01010101, 2), 0x808080);
|
||||
ASSERTU4(biopDividu4u4(U4_MAX, U4_MAX), 1);
|
||||
ASSERTU4(biopDividu4u4(U4_MAX, 1), U4_MAX);
|
||||
}
|
||||
|
||||
TEST biopRemainderu1u1_Main()
|
||||
{
|
||||
extern u1 biopRemainderu1u1(u1 lhs, u1 rhs);
|
||||
ASSERTU1(biopRemainderu1u1(0x01, 0x01), 0);
|
||||
ASSERTU1(biopRemainderu1u1(U1_MAX, U1_MAX), 0);
|
||||
ASSERTU1(biopRemainderu1u1(0, I1_MIN), 0);
|
||||
}
|
||||
|
||||
TEST biopRemainderu2u2_Main()
|
||||
{
|
||||
extern u2 biopRemainderu2u2(u2 lhs, u2 rhs);
|
||||
ASSERTU2(biopRemainderu2u2(0x0101, 0x0101), 0x0);
|
||||
ASSERTU2(biopRemainderu2u2(U2_MAX, 1), 0x0);
|
||||
ASSERTU2(biopRemainderu2u2(U2_MAX, 2), 1);
|
||||
ASSERTU2(biopRemainderu2u2(U2_MAX, U2_MAX), 0x0);
|
||||
}
|
||||
|
||||
TEST biopRemainderu4u4_Main()
|
||||
{
|
||||
extern u4 biopRemainderu4u4(u4 lhs, u4 rhs);
|
||||
ASSERTU4(biopRemainderu4u4(0x01010101, 0x01010101), 0);
|
||||
ASSERTU4(biopRemainderu4u4(U4_MAX, U4_MAX), 0);
|
||||
ASSERTU4(biopRemainderu4u4(I4_MIN, I4_MIN), 0);
|
||||
ASSERTU4(biopRemainderu4u4(~1000, ~10), 4294966295);
|
||||
ASSERTU4(biopRemainderu4u4(0, U4_MAX), 0);
|
||||
}
|
||||
|
||||
MAIN BIOPS2_main()
|
||||
{
|
||||
}
|
||||
|
||||
|
552
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS2_BODY.c
Normal file
552
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS2_BODY.c
Normal file
@ -0,0 +1,552 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
u2 unopNotu2(u2 lhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopSubu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopGeu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopShtRhtu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopXOri2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopLei2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopSubi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopAddu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopLtu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopGtu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopLogicOri2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopEqi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 unopPlusu2(u2 lhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopAddi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopGeu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopShtLftu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopLeu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopLogicAndi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopNei2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopMulti1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopShtLfti4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopLtu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopShtRhtu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopEqu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 unopNoti2(i2 lhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopAndi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopSubi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopNeu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopShtRhti4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopLeu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 unopNegativei2(i2 lhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = -lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopGti4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopAddi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopAndu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopEqu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 unopPlusi2(i2 lhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopGei4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopShtLfti1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopOru1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopNeu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopMultu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopShtRhti1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopLti4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopAndu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopXOru1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopSubu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopGti1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopLei4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopOru4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopLogicOru1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopAddu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopGei1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopLogicAndu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopEqi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopXOru4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopShtLftu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopNei4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopLti1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 unopNotu1(u1 lhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopLogicOru4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopShtRhtu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopDividu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopDividu2u2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopDividu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopRemainderu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopRemainderu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopRemainderu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
656
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS_BODY.c
Normal file
656
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/BIOPS_BODY.c
Normal file
@ -0,0 +1,656 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
u1 pcode_u1_complexLogic(u1 a, u1 b, u1 c, u1 d, u1 e, u1 f)
|
||||
{
|
||||
u1 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
u2 pcode_u2_complexLogic(u2 a, u2 b, u2 c, u2 d, u2 e, u2 f)
|
||||
{
|
||||
u2 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
u4 pcode_u4_complexLogic(u4 a, u4 b, u4 c, u4 d, u4 e, u4 f)
|
||||
{
|
||||
u4 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
i1 pcode_i1_complexLogic(i1 a, i1 b, i1 c, i1 d, i1 e, i1 f)
|
||||
{
|
||||
i1 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
i2 pcode_i2_complexLogic(i2 a, i2 b, i2 c, i2 d, i2 e, i2 f)
|
||||
{
|
||||
i2 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
i4 pcode_i4_complexLogic(i4 a, i4 b, i4 c, i4 d, i4 e, i4 f)
|
||||
{
|
||||
i4 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
u1 biopCmpu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
if (lhs < rhs)
|
||||
lhs += 2;
|
||||
if (lhs > rhs)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
u2 biopCmpu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
if (lhs < rhs)
|
||||
lhs += 2;
|
||||
if (lhs > rhs)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
u4 biopCmpu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
if (lhs < rhs)
|
||||
lhs += 2;
|
||||
if (lhs > rhs)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
i1 biopCmpi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
if (lhs < 0)
|
||||
lhs += 2;
|
||||
if (lhs > 0)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
i2 biopCmpi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
if (lhs < 0)
|
||||
lhs += 2;
|
||||
if (lhs > 0)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
i4 biopCmpi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
if (lhs < 0)
|
||||
lhs += 2;
|
||||
if (lhs > 0)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
i4 biopAndi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopLei1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopLogicAndu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopGtu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopEqi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopOri4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 unopNotu4(u4 lhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 unopPlusu1(u1 lhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopGeu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopNei1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopXOri4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopDividi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopRemainderi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopLtu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopAndi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopLogicOri4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 unopPlusu4(u4 lhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopLeu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopLogicAndi4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopOri1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopRemainderi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopMulti2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopEqu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopDividi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 unopNoti4(i4 lhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopNeu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopLogicOri1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopXOri1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopRemainderi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopSubi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopDividi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 unopNegativei4(i4 lhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = -lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopAddi2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopAndu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 biopLogicAndi1i1(i1 lhs, i1 rhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 unopPlusi4(i4 lhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopShtLfti2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopOru2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 unopNoti1(i1 lhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopMultu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopShtRhti2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopXOru2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopSubu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 unopNegativei1(i1 lhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = -lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopGti2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopLogicOru2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopAddu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i1 unopPlusi1(i1 lhs)
|
||||
{
|
||||
i1 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopGei2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u2 biopLogicAndu2u2(u2 lhs, u2 rhs)
|
||||
{
|
||||
u2 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopMultu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u1 biopGtu1u1(u1 lhs, u1 rhs)
|
||||
{
|
||||
u1 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u4 biopShtLftu4u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
u4 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopOri2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i2 biopLti2i2(i2 lhs, i2 rhs)
|
||||
{
|
||||
i2 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i4 biopMulti4i4(i4 lhs, i4 rhs)
|
||||
{
|
||||
i4 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
@ -0,0 +1,197 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopEqf8f8_Main()
|
||||
{
|
||||
extern f8 biopEqf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopEqf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 0);
|
||||
ASSERTF8(biopEqf8f8(PI_SHORT, PI_SHORT), 1.0);
|
||||
ASSERTF8(biopEqf8f8(PI_SHORT, 2*PI_SHORT), 0.0);
|
||||
ASSERTF8(biopEqf8f8(2*PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopNef8f8_Main()
|
||||
{
|
||||
extern f8 biopNef8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopNef8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 1);
|
||||
ASSERTF8(biopNef8f8(PI_SHORT, PI_SHORT), 0.0);
|
||||
ASSERTF8(biopNef8f8(PI_SHORT, 2*PI_SHORT), 1.0);
|
||||
ASSERTF8(biopNef8f8(2*PI_SHORT, PI_SHORT), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopLogicOrf8f8_Main()
|
||||
{
|
||||
extern f8 biopLogicOrf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopLogicOrf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 1);
|
||||
ASSERTF8(biopLogicOrf8f8(PI_SHORT, PI_SHORT), 1);
|
||||
ASSERTF8(biopLogicOrf8f8(PI_SHORT, 0), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopLogicAndf8f8_Main()
|
||||
{
|
||||
extern f8 biopLogicAndf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopLogicAndf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 1);
|
||||
ASSERTF8(biopLogicAndf8f8(PI_SHORT, PI_SHORT), 1);
|
||||
ASSERTF8(biopLogicAndf8f8(PI_SHORT, 0), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST unopNotf8_Main()
|
||||
{
|
||||
extern f8 unopNotf8(f8 lhs);
|
||||
f8 lhs = 2;
|
||||
f8 retVal;
|
||||
retVal = unopNotf8(lhs);
|
||||
ASSERTF8(retVal, 0);
|
||||
ASSERTF8(unopNotf8(PI_SHORT), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST unopNegativef8_Main()
|
||||
{
|
||||
extern f8 unopNegativef8(f8 lhs);
|
||||
f8 lhs = 2;
|
||||
f8 retVal;
|
||||
retVal = unopNegativef8(lhs);
|
||||
ASSERTF8(retVal, -2);
|
||||
ASSERTF8(unopNegativef8(PI_SHORT), -3.14);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST unopPlusf8_Main()
|
||||
{
|
||||
extern f8 unopPlusf8(f8 lhs);
|
||||
f8 lhs = 2;
|
||||
f8 retVal;
|
||||
retVal = unopPlusf8(lhs);
|
||||
ASSERTF8(retVal, 2);
|
||||
ASSERTF8(unopPlusf8(PI_SHORT), PI_SHORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopMultf8f8_Main()
|
||||
{
|
||||
extern f8 biopMultf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopMultf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 2);
|
||||
ASSERTF8(biopMultf8f8(PI_SHORT, PI_SHORT), 9.8596);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopSubf8f8_Main()
|
||||
{
|
||||
extern f8 biopSubf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopSubf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 1);
|
||||
ASSERTF8(biopSubf8f8(PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopAddf8f8_Main()
|
||||
{
|
||||
extern f8 biopAddf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopAddf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 3);
|
||||
ASSERTF8(biopAddf8f8(PI_SHORT, PI_SHORT), 6.28);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopGtf8f8_Main()
|
||||
{
|
||||
extern f8 biopGtf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopGtf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 1);
|
||||
ASSERTF8(biopGtf8f8(PI_SHORT, PI_SHORT), 0.0);
|
||||
ASSERTF8(biopGtf8f8(PI_SHORT, 2*PI_SHORT), 0.0);
|
||||
ASSERTF8(biopGtf8f8(2*PI_SHORT, PI_SHORT), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopGef8f8_Main()
|
||||
{
|
||||
extern f8 biopGef8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopGef8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 1);
|
||||
ASSERTF8(biopGef8f8(PI_SHORT, PI_SHORT), 1.0);
|
||||
ASSERTF8(biopGef8f8(PI_SHORT, 2*PI_SHORT), 0.0);
|
||||
ASSERTF8(biopGef8f8(2*PI_SHORT, PI_SHORT), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopLtf8f8_Main()
|
||||
{
|
||||
extern f8 biopLtf8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopLtf8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 0);
|
||||
ASSERTF8(biopLtf8f8(PI_SHORT, PI_SHORT), 0.0);
|
||||
ASSERTF8(biopLtf8f8(PI_SHORT, 2*PI_SHORT), 1.0);
|
||||
ASSERTF8(biopLtf8f8(2*PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopLef8f8_Main()
|
||||
{
|
||||
extern f8 biopLef8f8(f8 lhs, f8 rhs);
|
||||
f8 lhs = 2;
|
||||
f8 rhs = 1;
|
||||
f8 retVal;
|
||||
retVal = biopLef8f8(lhs, rhs);
|
||||
ASSERTF8(retVal, 0);
|
||||
ASSERTF8(biopLef8f8(PI_SHORT, PI_SHORT), 1.0);
|
||||
ASSERTF8(biopLef8f8(PI_SHORT, 2*PI_SHORT), 1.0);
|
||||
ASSERTF8(biopLef8f8(2*PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
MAIN BIOPS_DOUBLE_main() { }
|
||||
|
@ -0,0 +1,131 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 biopEqf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopNef8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopLogicOrf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopLogicAndf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 unopNotf8(f8 lhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 unopNegativef8(f8 lhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = -lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 unopPlusf8(f8 lhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopMultf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopSubf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopAddf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopGtf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopGef8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopLtf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f8 biopLef8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
f8 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
@ -0,0 +1,169 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopCmpf4f4_Main()
|
||||
{
|
||||
extern f4 biopCmpf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopCmpf4f4(0x1, 0x1), 21);
|
||||
ASSERTF4(biopCmpf4f4(0x1, 0x2), 21);
|
||||
ASSERTF4(biopCmpf4f4(0x2, 0x1), 22);
|
||||
ASSERTF4(biopCmpf4f4(-0x1, -0x1), 21);
|
||||
ASSERTF4(biopCmpf4f4(-0x1, -0x2), 21);
|
||||
ASSERTF4(biopCmpf4f4(-0x2, -0x1), 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST biopCmpf8f8_Main()
|
||||
{
|
||||
extern f8 biopCmpf8f8(f8 lhs, f8 rhs);
|
||||
ASSERTF8(biopCmpf8f8(0x1, 0x1), 21);
|
||||
ASSERTF8(biopCmpf8f8(0x1, 0x2), 21);
|
||||
ASSERTF8(biopCmpf8f8(0x2, 0x1), 22);
|
||||
ASSERTF8(biopCmpf8f8(-0x1, -0x1), 21);
|
||||
ASSERTF8(biopCmpf8f8(-0x1, -0x2), 21);
|
||||
ASSERTF8(biopCmpf8f8(-0x2, -0x1), 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopLtf4f4_Main()
|
||||
{
|
||||
extern f4 biopLtf4f4(f4 lhs, f4 rhs);
|
||||
f4 lhs = 2;
|
||||
f4 rhs = 1;
|
||||
f4 retVal;
|
||||
ASSERTF4(biopLtf4f4(lhs, rhs), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopLef4f4_Main()
|
||||
{
|
||||
extern f4 biopLef4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopLef4f4(2, 1), 0);
|
||||
ASSERTF4(biopLef4f4(PI_SHORT, 2*PI_SHORT), 1.0);
|
||||
ASSERTF4(biopLef4f4(PI_SHORT, PI_SHORT), 1.0);
|
||||
ASSERTF4(biopLef4f4(2*PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopEqf4f4_Main()
|
||||
{
|
||||
extern f4 biopEqf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopEqf4f4(2, 1), 0);
|
||||
ASSERTF4(biopEqf4f4(PI_SHORT, PI_SHORT), 1.0);
|
||||
ASSERTF4(biopEqf4f4(PI_SHORT, 2*PI_SHORT), 0.0);
|
||||
ASSERTF4(biopEqf4f4(2*PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopNef4f4_Main()
|
||||
{
|
||||
extern f4 biopNef4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopNef4f4(2, 1), 1);
|
||||
ASSERTF4(biopNef4f4(PI_SHORT, PI_SHORT), 0.0);
|
||||
ASSERTF4(biopNef4f4(PI_SHORT, 2*PI_SHORT), 1.0);
|
||||
ASSERTF4(biopNef4f4(2*PI_SHORT, PI_SHORT), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopLogicOrf4f4_Main()
|
||||
{
|
||||
extern f4 biopLogicOrf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopLogicOrf4f4(2, 1), 1);
|
||||
ASSERTF4(biopLogicOrf4f4(PI_SHORT, PI_SHORT), 1);
|
||||
ASSERTF4(biopLogicOrf4f4(PI_SHORT, 0), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopLogicAndf4f4_Main()
|
||||
{
|
||||
extern f4 biopLogicAndf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopLogicAndf4f4(2, 1), 1);
|
||||
ASSERTF4(biopLogicAndf4f4(PI_SHORT, PI_SHORT), 1);
|
||||
ASSERTF4(biopLogicAndf4f4(PI_SHORT, 0), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST unopNotf4_Main()
|
||||
{
|
||||
extern f4 unopNotf4(f4 lhs);
|
||||
ASSERTF4(unopNotf4(2), 0);
|
||||
ASSERTF4(unopNotf4(PI_SHORT), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST unopNegativef4_Main()
|
||||
{
|
||||
extern f4 unopNegativef4(f4 lhs);
|
||||
ASSERTF4(unopNegativef4(2), -2);
|
||||
ASSERTF4(unopNegativef4(PI_SHORT), -3.14);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST unopPlusf4_Main()
|
||||
{
|
||||
extern f4 unopPlusf4(f4 lhs);
|
||||
ASSERTF4(unopPlusf4(2), 2);
|
||||
ASSERTF4(unopPlusf4(PI_SHORT), PI_SHORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopMultf4f4_Main()
|
||||
{
|
||||
extern f4 biopMultf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopMultf4f4(2, 1), 2);
|
||||
ASSERTF4(biopMultf4f4(PI_SHORT, PI_SHORT), 9.859601);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopSubf4f4_Main()
|
||||
{
|
||||
extern f4 biopSubf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopSubf4f4(2, 1), 1);
|
||||
ASSERTF4(biopSubf4f4(PI_SHORT, PI_SHORT), 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopAddf4f4_Main()
|
||||
{
|
||||
extern f4 biopAddf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopAddf4f4(2, 1), 3);
|
||||
ASSERTF4(biopAddf4f4(PI_SHORT, PI_SHORT), 6.280000);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopGtf4f4_Main()
|
||||
{
|
||||
extern f4 biopGtf4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopGtf4f4(2, 1), 1);
|
||||
ASSERTF4(biopGtf4f4(PI_SHORT, PI_SHORT), 0.0);
|
||||
ASSERTF4(biopGtf4f4(PI_SHORT, 2*PI_SHORT), 0.0);
|
||||
ASSERTF4(biopGtf4f4(2*PI_SHORT, PI_SHORT), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST biopGef4f4_Main()
|
||||
{
|
||||
extern f4 biopGef4f4(f4 lhs, f4 rhs);
|
||||
ASSERTF4(biopGef4f4(2, 1), 1);
|
||||
ASSERTF4(biopGef4f4(PI_SHORT, PI_SHORT), 1.0);
|
||||
ASSERTF4(biopGef4f4(PI_SHORT, 2*PI_SHORT), 0.0);
|
||||
ASSERTF4(biopGef4f4(2*PI_SHORT, PI_SHORT), 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
MAIN BIOPS_FLOAT_main() { }
|
@ -0,0 +1,157 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 biopCmpf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
if (lhs < 0)
|
||||
lhs += 2;
|
||||
if (lhs > 0)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
f8 biopCmpf8f8(f8 lhs, f8 rhs)
|
||||
{
|
||||
if (lhs < 0)
|
||||
lhs += 2;
|
||||
if (lhs > 0)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
f4 biopLtf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopLef4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopEqf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopNef4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopLogicOrf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopLogicAndf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 unopNotf4(f4 lhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 unopNegativef4(f4 lhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = -lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 unopPlusf4(f4 lhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopMultf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopSubf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopAddf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopGtf4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
f4 biopGef4f4(f4 lhs, f4 rhs)
|
||||
{
|
||||
f4 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAS_FLOAT */
|
@ -0,0 +1,532 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_i8_complexLogic_Main()
|
||||
{
|
||||
extern i8 pcode_i8_complexLogic(i8 a, i8 b, i8 c, i8 d, i8 e, i8 f);
|
||||
ASSERTI8(pcode_i8_complexLogic(-1916250774LL, 1528806445LL, -870305000LL, 0, 0, 1799560997LL), 14);
|
||||
ASSERTI8(pcode_i8_complexLogic(-1375179334LL, -1539942439LL, 987987334LL, 0, 1162088421LL, 12548159LL), 15);
|
||||
ASSERTI8(pcode_i8_complexLogic(0, -750167716LL, -1104561852LL, 0, -915711850LL, 737703662LL), 11);
|
||||
ASSERTI8(pcode_i8_complexLogic(0, 386839851LL, -771476364LL, 0, -942724790LL, 1833488263LL), 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_u8_complexLogic_Main()
|
||||
{
|
||||
extern u8 pcode_u8_complexLogic(u8 a, u8 b, u8 c, u8 d, u8 e, u8 f);
|
||||
ASSERTU8(pcode_u8_complexLogic(2016764524ULL, 1717226057ULL, 1748349614ULL, 0, 1276673168ULL, 0), 15);
|
||||
ASSERTU8(pcode_u8_complexLogic(2009726312ULL, 696947386ULL, 0, 0, 1265204346ULL, 1369602726ULL), 11);
|
||||
ASSERTU8(pcode_u8_complexLogic(1665204916ULL, 1707056552ULL, 564325578ULL, 0, 0, 1010528946ULL), 14);
|
||||
ASSERTU8(pcode_u8_complexLogic(0, 1516266761ULL, 1866000081ULL, 0, 1175526309ULL, 1586903190ULL), 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopCmpi8i8_Main()
|
||||
{
|
||||
extern i8 biopCmpi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopCmpi8i8(0x1, 0x1), 21);
|
||||
ASSERTI8(biopCmpi8i8(0x1, 0x2), 21);
|
||||
ASSERTI8(biopCmpi8i8(0x2, 0x1), 22);
|
||||
ASSERTI8(biopCmpi8i8(-0x1, -0x1), 21);
|
||||
ASSERTI8(biopCmpi8i8(-0x1, -0x2), 21);
|
||||
ASSERTI8(biopCmpi8i8(-0x2, -0x1), 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopCmpu8u8_Main()
|
||||
{
|
||||
extern u8 biopCmpu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopCmpu8u8(0x1, 0x1), 1);
|
||||
ASSERTU8(biopCmpu8u8(0x1, 0x2), 23);
|
||||
ASSERTU8(biopCmpu8u8(0x2, 0x1), 22);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopNei8i8_Main()
|
||||
{
|
||||
extern i8 biopNei8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopNei8i8(2, 1), 1);
|
||||
ASSERTI8(biopNei8i8(0x0101010101010101LL, 0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopNei8i8(0x0101010101010101LL, -0x0101010101010101LL), 1);
|
||||
ASSERTI8(biopNei8i8(I8_MAX, I8_MAX), 0);
|
||||
ASSERTI8(biopNei8i8(I8_MAX, I8_MIN), 1);
|
||||
ASSERTI8(biopNei8i8(I8_MIN, I8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopAndu8u8_Main()
|
||||
{
|
||||
extern u8 biopAndu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopAndu8u8(2, 1), 0);
|
||||
ASSERTU8(biopAndu8u8(U8_MAX, U8_MAX), U8_MAX);
|
||||
ASSERTU8(biopAndu8u8(U8_MAX, 0), 0);
|
||||
ASSERTU8(biopAndu8u8(U8_MAX, 1), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopAndi8i8_Main()
|
||||
{
|
||||
extern i8 biopAndi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopAndi8i8(2, 1), 0);
|
||||
ASSERTI8(biopAndi8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x0101010101010101);
|
||||
ASSERTI8(biopAndi8i8(I8_MAX, I8_MAX), I8_MAX);
|
||||
ASSERTI8(biopAndi8i8(I8_MAX, I8_MIN), 0);
|
||||
ASSERTI8(biopAndi8i8(I8_MAX, 0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopOru8u8_Main()
|
||||
{
|
||||
extern u8 biopOru8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopOru8u8(2, 1), 3);
|
||||
ASSERTU8(biopOru8u8(U8_MAX, U8_MAX), U8_MAX);
|
||||
ASSERTU8(biopOru8u8(U8_MAX, U8_MIN), 18446744073709551615ULL);
|
||||
ASSERTU8(biopOru8u8(U8_MAX, 0), 18446744073709551615ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopXOru8u8_Main()
|
||||
{
|
||||
extern u8 biopXOru8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopXOru8u8(2, 1), 3);
|
||||
ASSERTU8(biopXOru8u8(U8_MAX, U8_MAX), 0);
|
||||
ASSERTU8(biopXOru8u8(U8_MAX, 0), U8_MAX);
|
||||
ASSERTU8(biopXOru8u8(U8_MAX, 2), 18446744073709551613ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopOri8i8_Main()
|
||||
{
|
||||
extern i8 biopOri8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopOri8i8(2, 1), 3);
|
||||
ASSERTI8(biopOri8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x0101010101010101LL);
|
||||
ASSERTI8(biopOri8i8(0x0101010101010101LL, 0x0), 0x0101010101010101LL);
|
||||
ASSERTI8(biopOri8i8(U8_MAX, U8_MAX), -1);
|
||||
ASSERTI8(biopOri8i8(U8_MAX, U8_MIN), -1);
|
||||
ASSERTI8(biopOri8i8(U8_MAX, 0), -1);
|
||||
ASSERTI8(biopOri8i8(U8_MAX, 4), -1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLogicOru8u8_Main()
|
||||
{
|
||||
extern u8 biopLogicOru8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopLogicOru8u8(2, 1), 1);
|
||||
ASSERTU8(biopLogicOru8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopLogicOru8u8(U8_MIN, U8_MIN), 0);
|
||||
ASSERTU8(biopLogicOru8u8(U8_MIN, 0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopXOri8i8_Main()
|
||||
{
|
||||
extern i8 biopXOri8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopXOri8i8(2, 1), 3);
|
||||
ASSERTI8(biopXOri8i8(0x0101010101010101LL, 0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopXOri8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x0);
|
||||
ASSERTI8(biopXOri8i8(U8_MAX, U8_MAX), 0x0);
|
||||
ASSERTI8(biopXOri8i8(U8_MAX, U8_MIN), -1);
|
||||
ASSERTI8(biopXOri8i8(U8_MAX, 0), -1);
|
||||
ASSERTI8(biopXOri8i8(U8_MAX, 5), -6);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopRemainderi8i8_Main()
|
||||
{
|
||||
extern i8 biopRemainderi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopRemainderi8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x0);
|
||||
ASSERTI8(biopRemainderi8i8(0x0101010101010101LL, 0x0001010101010101LL), 0x1);
|
||||
ASSERTI8(biopRemainderi8i8(0x0101010101010101LL, 0x0001010101010100LL), 0x101);
|
||||
ASSERTI8(biopRemainderi8i8(I8_MAX, I8_MAX), 0);
|
||||
ASSERTI8(biopRemainderi8i8(I8_MAX, 1), 0);
|
||||
ASSERTI8(biopRemainderi8i8(I8_MAX, I8_MIN), 9223372036854775807);
|
||||
ASSERTI8(biopRemainderi8i8(I8_MAX, 0xFFFF), 32767);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLogicOri8i8_Main()
|
||||
{
|
||||
extern i8 biopLogicOri8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopLogicOri8i8(2, 1), 1);
|
||||
ASSERTI8(biopLogicOri8i8(0x0101010101010101LL, 0x0101010101010101LL), 1);
|
||||
ASSERTI8(biopLogicOri8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopLogicOri8i8(I8_MAX, I8_MIN), 1);
|
||||
ASSERTI8(biopLogicOri8i8(I8_MAX, 0), 1);
|
||||
ASSERTI8(biopLogicOri8i8(I8_MAX, 5), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLogicAndu8u8_Main()
|
||||
{
|
||||
extern u8 biopLogicAndu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopLogicAndu8u8(2, 1), 1);
|
||||
ASSERTU8(biopLogicAndu8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopLogicAndu8u8(U8_MAX, 0), 0);
|
||||
ASSERTU8(biopLogicAndu8u8(U8_MAX, 5), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopDividi8i8_Main()
|
||||
{
|
||||
extern i8 biopDividi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopDividi8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x1);
|
||||
ASSERTI8(biopDividi8i8(-0x0101010101010101LL, 0x0101010101010101LL), -0x1);
|
||||
ASSERTI8(biopDividi8i8(0, 0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopDividi8i8(0x0101010101010101LL, 2), 0x80808080808080);
|
||||
ASSERTI8(biopDividi8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopDividi8i8(I8_MAX, I8_MIN), 0);
|
||||
ASSERTI8(biopDividi8i8(0, I8_MAX), 0);
|
||||
ASSERTI8(biopDividi8i8(I8_MAX, 5), 1844674407370955161LL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopDividu8u8_Main()
|
||||
{
|
||||
extern u8 biopDividu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopDividu8u8(0x0101010101010101ULL, 0x0101010101010101ULL), 0x1);
|
||||
ASSERTU8(biopDividu8u8(-0x0101010101010101ULL, 0x0101010101010101ULL), 254);
|
||||
ASSERTU8(biopDividu8u8(0, 0x0101010101010101ULL), 0);
|
||||
ASSERTU8(biopDividu8u8(0x0101010101010101ULL, 2), 0x80808080808080);
|
||||
ASSERTU8(biopDividu8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopDividu8u8(0, U8_MAX), 0);
|
||||
ASSERTU8(biopDividu8u8(U8_MAX, 5), 3689348814741910323ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLogicAndi8i8_Main()
|
||||
{
|
||||
extern i8 biopLogicAndi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopLogicAndi8i8(0x0101010101010101LL, 0x0101010101010101LL), 1);
|
||||
ASSERTI8(biopLogicAndi8i8(0x0101010101010101LL, 0x0), 0);
|
||||
ASSERTI8(biopLogicAndi8i8(2, 1), 1);
|
||||
ASSERTI8(biopLogicAndi8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopLogicAndi8i8(I8_MAX, I8_MIN), 1);
|
||||
ASSERTI8(biopLogicAndi8i8(I8_MAX, 0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST unopNotu8_Main()
|
||||
{
|
||||
extern u8 unopNotu8(u8 lhs);
|
||||
ASSERTU8(unopNotu8(2), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST unopNoti8_Main()
|
||||
{
|
||||
extern i8 unopNoti8(i8 lhs);
|
||||
ASSERTI8(unopNoti8(0x0101010101010101LL), 0);
|
||||
ASSERTI8(unopNoti8(2), 0);
|
||||
ASSERTI8(unopNoti8(I8_MAX), 0);
|
||||
ASSERTI8(unopNoti8(I8_MIN), 0);
|
||||
ASSERTI8(unopNoti8(0), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST unopPlusu8_Main()
|
||||
{
|
||||
extern u8 unopPlusu8(u8 lhs);
|
||||
ASSERTU8(unopPlusu8(2), 2);
|
||||
ASSERTU8(unopPlusu8(U8_MAX), U8_MAX);
|
||||
ASSERTU8(unopPlusu8(0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST unopNegativei8_Main()
|
||||
{
|
||||
extern i8 unopNegativei8(i8 lhs);
|
||||
ASSERTI8(unopNegativei8(2), -2);
|
||||
ASSERTI8(unopNegativei8(0x0101010101010101LL), -0x0101010101010101LL);
|
||||
ASSERTI8(unopNegativei8(-0x0101010101010101LL), 0x0101010101010101LL);
|
||||
ASSERTI8(unopNegativei8(I8_MAX), I8_MIN+1);
|
||||
ASSERTI8(unopNegativei8(I8_MIN), I8_MIN);
|
||||
ASSERTI8(unopNegativei8(0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST unopPlusi8_Main()
|
||||
{
|
||||
extern i8 unopPlusi8(i8 lhs);
|
||||
ASSERTI8(unopPlusi8(2), 2);
|
||||
ASSERTI8(unopPlusi8(0x0101010101010101LL), 0x0101010101010101LL);
|
||||
ASSERTI8(unopPlusi8(-0x0101010101010101LL), -0x0101010101010101LL);
|
||||
ASSERTI8(unopPlusi8(I8_MAX), I8_MAX);
|
||||
ASSERTI8(unopPlusi8(I8_MIN), I8_MIN);
|
||||
ASSERTI8(unopPlusi8(0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopMultu8u8_Main()
|
||||
{
|
||||
extern u8 biopMultu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopMultu8u8(2, 1), 2);
|
||||
ASSERTU8(biopMultu8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopMultu8u8(U8_MAX, U8_MIN), 0);
|
||||
ASSERTU8(biopMultu8u8(U8_MAX, 0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopMulti8i8_Main()
|
||||
{
|
||||
extern i8 biopMulti8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopMulti8i8(2, 1), 2);
|
||||
ASSERTI8(biopMulti8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x807060504030201LL);
|
||||
ASSERTI8(biopMulti8i8(0, -0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopMulti8i8(0x0101010101010101LL, -0x0101010101010101LL), -0x807060504030201LL);
|
||||
ASSERTI8(biopMulti8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopMulti8i8(I8_MAX, I8_MIN), 0x8000000000000000LL);
|
||||
|
||||
ASSERTI8(biopMulti8i8(I8_MAX, 0), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopSubu8u8_Main()
|
||||
{
|
||||
extern u8 biopSubu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopSubu8u8(2, 1), 1);
|
||||
ASSERTU8(biopSubu8u8(U8_MAX, U8_MAX), 0);
|
||||
ASSERTU8(biopSubu8u8(U8_MAX, 0), U8_MAX);
|
||||
ASSERTU8(biopSubu8u8(0, U8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopSubi8i8_Main()
|
||||
{
|
||||
extern i8 biopSubi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopSubi8i8(0x0101010101010101LL, 0x0101010101010100LL), 0x1);
|
||||
ASSERTI8(biopSubi8i8(0x0001010101010100LL, 0x0101010101010101LL), -72057594037927937LL);
|
||||
ASSERTI8(biopSubi8i8(2, 1), 1);
|
||||
ASSERTI8(biopSubi8i8(0x0101010101010101LL, 0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopSubi8i8(I8_MAX, I8_MAX), 0);
|
||||
ASSERTI8(biopSubi8i8(I8_MAX, I8_MIN), -1);
|
||||
ASSERTI8(biopSubi8i8(I8_MAX, 0), I8_MAX);
|
||||
ASSERTI8(biopSubi8i8(0, I8_MAX), -I8_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopAddu8u8_Main()
|
||||
{
|
||||
extern u8 biopAddu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopAddu8u8(2, 1), 3);
|
||||
ASSERTU8(biopAddu8u8(U8_MAX, U8_MAX), 18446744073709551614ULL);
|
||||
ASSERTU8(biopAddu8u8(U8_MAX, 0), U8_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopShtLftu8u8_Main()
|
||||
{
|
||||
extern u8 biopShtLftu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopShtLftu8u8(2, 1), 4);
|
||||
ASSERTU8(biopShtLftu8u8(U8_MAX, 0), U8_MAX);
|
||||
ASSERTU8(biopShtLftu8u8(0, 4), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopAddi8i8_Main()
|
||||
{
|
||||
extern i8 biopAddi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopAddi8i8(0x0101010101010101LL, 0x0101010101010101LL), 0x202020202020202LL);
|
||||
ASSERTI8(biopAddi8i8(2, 1), 3);
|
||||
ASSERTI8(biopAddi8i8(I8_MAX, I8_MAX), -2);
|
||||
ASSERTI8(biopAddi8i8(I8_MAX, I8_MIN), -1);
|
||||
ASSERTI8(biopAddi8i8(I8_MAX, 0), I8_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopShtRhtu8u8_Main()
|
||||
{
|
||||
extern u8 biopShtRhtu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopShtRhtu8u8(2, 1), 1);
|
||||
ASSERTU8(biopShtRhtu8u8(U8_MAX, 0), U8_MAX);
|
||||
ASSERTU8(biopShtRhtu8u8(0, 2), 0);
|
||||
ASSERTU8(biopShtRhtu8u8(2, 2), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopShtLfti8i8_Main()
|
||||
{
|
||||
extern i8 biopShtLfti8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopShtLfti8i8(0x0101010101010101LL, 16), 0x101010101010000LL);
|
||||
ASSERTI8(biopShtLfti8i8(0x0101010101010101LL, 8), 0x101010101010100LL);
|
||||
ASSERTI8(biopShtLfti8i8(0x0101010101010101LL, 0), 0x101010101010101LL);
|
||||
ASSERTI8(biopShtLfti8i8(2, 1), 4);
|
||||
ASSERTI8(biopShtLfti8i8(I8_MAX, 0), I8_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopShtRhti8i8_Main()
|
||||
{
|
||||
extern i8 biopShtRhti8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopShtRhti8i8(0x0101010101010101LL, 8), 0x1010101010101LL);
|
||||
ASSERTI8(biopShtRhti8i8(0x0101010101010101LL, 16), 0x10101010101LL);
|
||||
ASSERTI8(biopShtRhti8i8(0x0101010101010101LL, 0), 0x0101010101010101LL);
|
||||
ASSERTI8(biopShtRhti8i8(2, 1), 1);
|
||||
ASSERTI8(biopShtRhti8i8(I8_MAX, 0), I8_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopGtu8u8_Main()
|
||||
{
|
||||
extern u8 biopGtu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopGtu8u8(2, 1), 1);
|
||||
ASSERTU8(biopGtu8u8(U8_MAX, 0), 1);
|
||||
ASSERTU8(biopGtu8u8(U8_MAX, U8_MAX), 0);
|
||||
ASSERTU8(biopGtu8u8(0, U8_MAX), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopGti8i8_Main()
|
||||
{
|
||||
extern i8 biopGti8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopGti8i8(0x0101010101010101LL, 0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopGti8i8(0x0101010101010101LL, -0x0101010101010101LL), 1);
|
||||
ASSERTI8(biopGti8i8(2, 1), 1);
|
||||
ASSERTI8(biopGti8i8(I8_MAX, I8_MAX), 0);
|
||||
ASSERTI8(biopGti8i8(I8_MAX, I8_MIN), 1);
|
||||
ASSERTI8(biopGti8i8(I8_MIN, I8_MAX), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopGeu8u8_Main()
|
||||
{
|
||||
extern u8 biopGeu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopGeu8u8(2, 1), 1);
|
||||
ASSERTU8(biopGeu8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopGeu8u8(U8_MAX, U8_MIN), 1);
|
||||
ASSERTU8(biopGeu8u8(U8_MIN, U8_MAX), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopGei8i8_Main()
|
||||
{
|
||||
extern i8 biopGei8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopGei8i8(2, 1), 1);
|
||||
ASSERTI8(biopGei8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopGei8i8(I8_MAX, I8_MIN), 1);
|
||||
ASSERTI8(biopGei8i8(I8_MIN, I8_MAX), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLtu8u8_Main()
|
||||
{
|
||||
extern u8 biopLtu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopLtu8u8(2, 1), 0);
|
||||
ASSERTU8(biopLtu8u8(U8_MAX, U8_MAX), 0);
|
||||
ASSERTU8(biopLtu8u8(U8_MAX, U8_MIN), 0);
|
||||
ASSERTU8(biopLtu8u8(U8_MIN, U8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLeu8u8_Main()
|
||||
{
|
||||
extern u8 biopLeu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopLeu8u8(2, 1), 0);
|
||||
ASSERTU8(biopLeu8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopLeu8u8(U8_MAX, U8_MIN), 0);
|
||||
ASSERTU8(biopLeu8u8(U8_MIN, U8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLti8i8_Main()
|
||||
{
|
||||
extern i8 biopLti8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopLti8i8(0x0101010101010101LL, 0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopLti8i8(0x0101010101010101LL, -0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopLti8i8(2, 1), 0);
|
||||
ASSERTI8(biopLti8i8(I8_MAX, I8_MAX), 0);
|
||||
ASSERTI8(biopLti8i8(I8_MAX, I8_MIN), 0);
|
||||
ASSERTI8(biopLti8i8(I8_MIN, I8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopEqu8u8_Main()
|
||||
{
|
||||
extern u8 biopEqu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopEqu8u8(2, 1), 0);
|
||||
ASSERTU8(biopEqu8u8(U8_MAX, U8_MAX), 1);
|
||||
ASSERTU8(biopEqu8u8(U8_MAX, U8_MIN), 0);
|
||||
ASSERTU8(biopEqu8u8(U8_MIN, U8_MAX), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopLei8i8_Main()
|
||||
{
|
||||
extern i8 biopLei8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopLei8i8(2, 1), 0);
|
||||
ASSERTI8(biopLei8i8(0x0101010101010101LL, 0x0101010101010101LL), 1);
|
||||
ASSERTI8(biopLei8i8(0x0101010101010101LL, -0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopLei8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopLei8i8(I8_MAX, I8_MIN), 0);
|
||||
ASSERTI8(biopLei8i8(I8_MIN, I8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopEqi8i8_Main()
|
||||
{
|
||||
extern i8 biopEqi8i8(i8 lhs, i8 rhs);
|
||||
ASSERTI8(biopEqi8i8(2, 1), 0);
|
||||
ASSERTI8(biopEqi8i8(0x0101010101010101LL, 0x0101010101010101LL), 1);
|
||||
ASSERTI8(biopEqi8i8(0x0101010101010101LL, -0x0101010101010101LL), 0);
|
||||
ASSERTI8(biopEqi8i8(I8_MAX, I8_MAX), 1);
|
||||
ASSERTI8(biopEqi8i8(I8_MAX, I8_MIN), 0);
|
||||
ASSERTI8(biopEqi8i8(I8_MIN, I8_MAX), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST biopNeu8u8_Main()
|
||||
{
|
||||
extern u8 biopNeu8u8(u8 lhs, u8 rhs);
|
||||
ASSERTU8(biopNeu8u8(2, 1), 1);
|
||||
ASSERTU8(biopNeu8u8(U8_MAX, U8_MAX), 0);
|
||||
ASSERTU8(biopNeu8u8(U8_MAX, U8_MIN), 1);
|
||||
ASSERTU8(biopNeu8u8(U8_MIN, U8_MAX), 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
MAIN BIOPS_LONGLONG_main() { }
|
||||
|
@ -0,0 +1,403 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_i8_complexLogic(i8 a, i8 b, i8 c, i8 d, i8 e, i8 f)
|
||||
{
|
||||
i8 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
u8 pcode_u8_complexLogic(u8 a, u8 b, u8 c, u8 d, u8 e, u8 f)
|
||||
{
|
||||
u8 ret = 0;
|
||||
|
||||
if (a > b && b > c || d < e && f < e) {
|
||||
ret += 1;
|
||||
}
|
||||
if (a != b || a != c && d != e || f != e) {
|
||||
ret += 2;
|
||||
}
|
||||
if (a && b && c || d && e && f) {
|
||||
ret += 4;
|
||||
}
|
||||
if (a || b || c && d || e || f) {
|
||||
ret += 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
i8 biopCmpi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
if (lhs < 0)
|
||||
lhs += 2;
|
||||
if (lhs > 0)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
u8 biopCmpu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
if (lhs < rhs)
|
||||
lhs += 2;
|
||||
if (lhs > rhs)
|
||||
lhs += 4;
|
||||
if (lhs == 0)
|
||||
lhs += 8;
|
||||
if (lhs != rhs)
|
||||
lhs += 16;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
i8 biopNei8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopAndu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopAndi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs & rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopOru8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopXOru8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopOri8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs | rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopLogicOru8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopXOri8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs ^ rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopRemainderi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs % rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopLogicOri8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs || rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopLogicAndu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopDividi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopDividu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs / rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopLogicAndi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs && rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 unopNotu8(u8 lhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 unopNoti8(i8 lhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = !lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 unopPlusu8(u8 lhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 unopNegativei8(i8 lhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = -lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 unopPlusi8(i8 lhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = +lhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopMultu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopMulti8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs * rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopSubu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopSubi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs - rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopAddu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopShtLftu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopAddi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs + rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopShtRhtu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopShtLfti8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs << rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopShtRhti8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs >> rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopGtu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopGti8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs > rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopGeu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopGei8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs >= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopLtu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopLeu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopLti8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs < rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopEqu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopLei8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs <= rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
i8 biopEqi8i8(i8 lhs, i8 rhs)
|
||||
{
|
||||
i8 z;
|
||||
|
||||
z = lhs == rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
u8 biopNeu8u8(u8 lhs, u8 rhs)
|
||||
{
|
||||
u8 z;
|
||||
|
||||
z = lhs != rhs;
|
||||
return z;
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
@ -0,0 +1,356 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM1_GetBitLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_BM1_GetBitLongLong(i8 arg, u4 bit);
|
||||
ASSERTI8(pcode_BM1_GetBitLongLong(0xFF, 1), 2);
|
||||
ASSERTI8(pcode_BM1_GetBitLongLong(I8_MAX, 8), 256);
|
||||
ASSERTI8(pcode_BM1_GetBitLongLong(I8_MAX, 16), 65536);
|
||||
ASSERTI8(pcode_BM1_GetBitLongLong(I8_MAX, 32), 4294967296LL);
|
||||
ASSERTI8(pcode_BM1_GetBitLongLong(I8_MAX, 63), 0);
|
||||
ASSERTI8(pcode_BM1_GetBitLongLong(0x0, 1), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM2_GetBitInt_Main()
|
||||
{
|
||||
extern i4 pcode_BM2_GetBitInt(i4 arg, u4 bit);
|
||||
ASSERTI4(pcode_BM2_GetBitInt(0xFF, 1), 2);
|
||||
ASSERTI4(pcode_BM2_GetBitInt(0, 1), 0);
|
||||
ASSERTI4(pcode_BM2_GetBitInt(I4_MAX, 8), 256);
|
||||
ASSERTI4(pcode_BM2_GetBitInt(I4_MAX, 16), 65536);
|
||||
ASSERTI4(pcode_BM2_GetBitInt(I4_MAX, 24), 16777216);
|
||||
ASSERTI4(pcode_BM2_GetBitInt(I4_MAX, 31), 0);
|
||||
}
|
||||
|
||||
TEST pcode_BM3_GetBitShort_Main()
|
||||
{
|
||||
extern i2 pcode_BM3_GetBitShort(i2 arg, u4 bit);
|
||||
ASSERTI2(pcode_BM3_GetBitShort(0xFD, 1), 0);
|
||||
ASSERTI2(pcode_BM3_GetBitShort(0x02, 1), 2);
|
||||
ASSERTI2(pcode_BM3_GetBitShort(I2_MAX, 8), 256);
|
||||
ASSERTI2(pcode_BM3_GetBitShort(I2_MAX, 14), 16384);
|
||||
ASSERTI2(pcode_BM3_GetBitShort(I2_MAX, 15), 0);
|
||||
}
|
||||
|
||||
TEST pcode_BM4_GetBitChar_Main()
|
||||
{
|
||||
extern i1 pcode_BM4_GetBitChar(i1 arg, u4 bit);
|
||||
ASSERTI1(pcode_BM4_GetBitChar(0xFD, 1), 0);
|
||||
ASSERTI1(pcode_BM4_GetBitChar(0x02, 1), 2);
|
||||
ASSERTI1(pcode_BM4_GetBitChar(0xFF, 7), -128);
|
||||
ASSERTI1(pcode_BM4_GetBitChar(0x7F, 7), 0);
|
||||
ASSERTI1(pcode_BM4_GetBitChar(0, 1), 0);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM5_GetBitUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_BM5_GetBitUnsignedLongLong(u8 arg, u8 bit);
|
||||
ASSERTU8(pcode_BM5_GetBitUnsignedLongLong(0x02, 1), 2);
|
||||
ASSERTU8(pcode_BM5_GetBitUnsignedLongLong(0xFFFFFFFFFFFFFFFDULL, 1), 0);
|
||||
ASSERTU8(pcode_BM5_GetBitUnsignedLongLong(U8_MAX, 8), 256);
|
||||
ASSERTU8(pcode_BM5_GetBitUnsignedLongLong(U8_MAX, 16), 65536);
|
||||
ASSERTU8(pcode_BM5_GetBitUnsignedLongLong(U8_MAX, 24), 16777216ULL);
|
||||
ASSERTU8(pcode_BM5_GetBitUnsignedLongLong(U8_MAX, 32), 4294967296ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM6_GetBitUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_BM6_GetBitUnsignedInt(u4 arg, u4 bit);
|
||||
ASSERTU4(pcode_BM6_GetBitUnsignedInt(0x02, 1), 2);
|
||||
ASSERTU4(pcode_BM6_GetBitUnsignedInt(0xFD, 1), 0);
|
||||
ASSERTU4(pcode_BM6_GetBitUnsignedInt(U4_MAX, 8), 256);
|
||||
ASSERTU4(pcode_BM6_GetBitUnsignedInt(U4_MAX, 16), 65536);
|
||||
ASSERTU4(pcode_BM6_GetBitUnsignedInt(U4_MAX, 24), 16777216);
|
||||
ASSERTU4(pcode_BM6_GetBitUnsignedInt(U4_MAX, 31), 2147483648);
|
||||
}
|
||||
|
||||
TEST pcode_BM7_GetBitUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_BM7_GetBitUnsignedShort(u2 arg, u4 bit);
|
||||
ASSERTU2(pcode_BM7_GetBitUnsignedShort(0xFF, 1), 2);
|
||||
ASSERTU2(pcode_BM7_GetBitUnsignedShort(0, 1), 0);
|
||||
ASSERTU2(pcode_BM7_GetBitUnsignedShort(U2_MAX, 8), 256);
|
||||
ASSERTU2(pcode_BM7_GetBitUnsignedShort(U2_MAX, 16), 0);
|
||||
}
|
||||
|
||||
TEST pcode_BM8_GetBitUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_BM8_GetBitUnsignedChar(u1 arg, u4 bit);
|
||||
ASSERTU1(pcode_BM8_GetBitUnsignedChar(0xFF, 1), 2);
|
||||
ASSERTU1(pcode_BM8_GetBitUnsignedChar(0, 1), 0);
|
||||
ASSERTU1(pcode_BM8_GetBitUnsignedChar(U1_MAX, 4), 16);
|
||||
ASSERTU1(pcode_BM8_GetBitUnsignedChar(U1_MAX, 8), 0);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM9_SetBitLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_BM9_SetBitLongLong(i8 arg, u4 bit);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(0xFF, 1), 255);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(0, 1), 2);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(I8_MAX, 8), I8_MAX);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(I8_MAX, 16), I8_MAX);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(I8_MAX, 24), I8_MAX);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(I8_MAX, 32), I8_MAX);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(I8_MAX, 0), I8_MAX);
|
||||
ASSERTI8(pcode_BM9_SetBitLongLong(4, 8), 260);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM10_SetBitInt_Main()
|
||||
{
|
||||
extern i4 pcode_BM10_SetBitInt(i4 arg, u4 bit);
|
||||
ASSERTI4(pcode_BM10_SetBitInt(0xFF, 1), 255);
|
||||
ASSERTI4(pcode_BM10_SetBitInt(0, 1), 2);
|
||||
ASSERTI4(pcode_BM10_SetBitInt(I4_MAX, 31), -1);
|
||||
ASSERTI4(pcode_BM10_SetBitInt(I4_MAX, I4_MIN), I4_MAX);
|
||||
ASSERTI4(pcode_BM10_SetBitInt(4, 8), 260);
|
||||
}
|
||||
|
||||
TEST pcode_BM11_SetBitShort_Main()
|
||||
{
|
||||
extern i2 pcode_BM11_SetBitShort(i2 arg, i2 bit);
|
||||
ASSERTI2(pcode_BM11_SetBitShort(0xFF, 1), 255);
|
||||
ASSERTI2(pcode_BM11_SetBitShort(0, 1), 2);
|
||||
ASSERTI2(pcode_BM11_SetBitShort(I2_MAX, 8), 32767);
|
||||
ASSERTI2(pcode_BM11_SetBitShort(I2_MAX, 15), -1);
|
||||
}
|
||||
|
||||
TEST pcode_BM12_SetBitChar_Main()
|
||||
{
|
||||
extern i1 pcode_BM12_SetBitChar(i1 arg, u1 bit);
|
||||
ASSERTI1(pcode_BM12_SetBitChar(0xFF, 1), -1);
|
||||
ASSERTI1(pcode_BM12_SetBitChar(0, 1), 2);
|
||||
ASSERTI1(pcode_BM12_SetBitChar(I1_MAX, 8), 127);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM12_SetBitUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_BM12_SetBitUnsignedLongLong(u8 arg, u8 bit);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0xFF, 1), 255);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0, 1), 2);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0, 8), 256);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0, 16), 65536);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0, 24), 16777216ULL);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0, 31), 2147483648ULL);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(0, 32), 4294967296ULL);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(U8_MAX, 8), U8_MAX);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(U8_MAX, 16), U8_MAX);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(U8_MAX, 24), U8_MAX);
|
||||
ASSERTU8(pcode_BM12_SetBitUnsignedLongLong(U8_MAX, 32), U8_MAX);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM13_SetLowBitUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_BM13_SetLowBitUnsignedLongLong(u8 arg, u8 bit);
|
||||
ASSERTU8(pcode_BM13_SetLowBitUnsignedLongLong(0xFF, 1), 255);
|
||||
ASSERTU8(pcode_BM13_SetLowBitUnsignedLongLong(0, 1), 2);
|
||||
ASSERTU8(pcode_BM13_SetLowBitUnsignedLongLong(0, 8), 256);
|
||||
ASSERTU8(pcode_BM13_SetLowBitUnsignedLongLong(0, 16), 65536);
|
||||
ASSERTU8(pcode_BM13_SetLowBitUnsignedLongLong(0, 24), 16777216ULL);
|
||||
ASSERTU8(pcode_BM13_SetLowBitUnsignedLongLong(0, 31), 2147483648ULL); // ensure no sign extension occurs
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM14_SetBitUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_BM14_SetBitUnsignedInt(u4 arg, u4 bit);
|
||||
ASSERTU4(pcode_BM14_SetBitUnsignedInt(0xFF, 1), 255);
|
||||
ASSERTU4(pcode_BM14_SetBitUnsignedInt(0, 1), 2);
|
||||
ASSERTU4(pcode_BM14_SetBitUnsignedInt(0, 8), 256);
|
||||
ASSERTU4(pcode_BM14_SetBitUnsignedInt(0, 16), 65536);
|
||||
ASSERTU4(pcode_BM14_SetBitUnsignedInt(0, 24), 16777216);
|
||||
ASSERTU4(pcode_BM14_SetBitUnsignedInt(0, 31), 2147483648);
|
||||
}
|
||||
|
||||
TEST pcode_BM15_SetBitUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_BM15_SetBitUnsignedShort(u2 arg, u4 bit);
|
||||
ASSERTU2(pcode_BM15_SetBitUnsignedShort(0xFF, 1), 255);
|
||||
ASSERTU2(pcode_BM15_SetBitUnsignedShort(0, 1), 2);
|
||||
ASSERTU2(pcode_BM15_SetBitUnsignedShort(0, 8), 256);
|
||||
ASSERTU2(pcode_BM15_SetBitUnsignedShort(0, 15), 32768);
|
||||
}
|
||||
|
||||
TEST pcode_BM16_SetBitUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_BM16_SetBitUnsignedChar(u1 arg, u1 bit);
|
||||
ASSERTU1(pcode_BM16_SetBitUnsignedChar(0xFF, 1), 255);
|
||||
ASSERTU1(pcode_BM16_SetBitUnsignedChar(0, 1), 2);
|
||||
ASSERTU1(pcode_BM16_SetBitUnsignedChar(4, 1), 6);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM17_ClearBitLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_BM17_ClearBitLongLong(i8 arg, i8 bit);
|
||||
ASSERTI8(pcode_BM17_ClearBitLongLong(0xFF, 1), 253);
|
||||
ASSERTI8(pcode_BM17_ClearBitLongLong(0, 1), 0);
|
||||
ASSERTI8(pcode_BM17_ClearBitLongLong(I8_MAX, 8), 9223372036854775551LL);
|
||||
ASSERTI8(pcode_BM17_ClearBitLongLong(I8_MAX, 16), 9223372036854710271LL);
|
||||
ASSERTI8(pcode_BM17_ClearBitLongLong(I8_MAX, 24), 9223372036837998591LL);
|
||||
ASSERTI8(pcode_BM17_ClearBitLongLong(I8_MAX, 32), 9223372032559808511LL);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM18_ClearBitInt_Main()
|
||||
{
|
||||
extern i4 pcode_BM18_ClearBitInt(i4 arg, i4 bit);
|
||||
ASSERTI4(pcode_BM18_ClearBitInt(0xFF, 1), 253);
|
||||
ASSERTI4(pcode_BM18_ClearBitInt(0, 1), 0);
|
||||
ASSERTI4(pcode_BM18_ClearBitInt(I4_MAX, 8), 2147483391);
|
||||
ASSERTI4(pcode_BM18_ClearBitInt(I4_MAX, 16), 2147418111);
|
||||
ASSERTI4(pcode_BM18_ClearBitInt(I4_MAX, 31), 2147483647);
|
||||
}
|
||||
|
||||
TEST pcode_BM19_ClearBitShort_Main()
|
||||
{
|
||||
extern i2 pcode_BM19_ClearBitShort(i2 arg, i2 bit);
|
||||
ASSERTI2(pcode_BM19_ClearBitShort(0xFF, 1), 253);
|
||||
ASSERTI2(pcode_BM19_ClearBitShort(0, 1), 0);
|
||||
ASSERTI2(pcode_BM19_ClearBitShort(I2_MAX, 8), 32511);
|
||||
ASSERTI2(pcode_BM19_ClearBitShort(I2_MAX, 15), 32767);
|
||||
}
|
||||
|
||||
TEST pcode_BM20_ClearBitChar_Main()
|
||||
{
|
||||
extern i1 pcode_BM20_ClearBitChar(i1 arg, u1 bit);
|
||||
ASSERTI1(pcode_BM20_ClearBitChar(0xFF, 1), -3);
|
||||
ASSERTI1(pcode_BM20_ClearBitChar(0, 1), 0);
|
||||
ASSERTI1(pcode_BM20_ClearBitChar(I1_MAX, 4), 111);
|
||||
ASSERTI1(pcode_BM20_ClearBitChar(I1_MAX, 8), 127);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM21_ClearBitUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_BM21_ClearBitUnsignedLongLong(u8 arg, u8 bit);
|
||||
ASSERTU8(pcode_BM21_ClearBitUnsignedLongLong(0xFF, 1), 253);
|
||||
ASSERTU8(pcode_BM21_ClearBitUnsignedLongLong(0, 1), 0);
|
||||
ASSERTU8(pcode_BM21_ClearBitUnsignedLongLong(U8_MAX, 8), 18446744073709551359ULL);
|
||||
ASSERTU8(pcode_BM21_ClearBitUnsignedLongLong(U8_MAX, 16), 18446744073709486079ULL);
|
||||
ASSERTU8(pcode_BM21_ClearBitUnsignedLongLong(U8_MAX, 32), 18446744069414584319ULL);
|
||||
ASSERTU8(pcode_BM21_ClearBitUnsignedLongLong(U8_MAX, 63), 9223372036854775807ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM22_ClearBitUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_BM22_ClearBitUnsignedInt(u4 arg, u4 bit);
|
||||
ASSERTU4(pcode_BM22_ClearBitUnsignedInt(0xFF, 1), 253);
|
||||
ASSERTU4(pcode_BM22_ClearBitUnsignedInt(0, 1), 0);
|
||||
ASSERTU4(pcode_BM22_ClearBitUnsignedInt(U4_MAX, 8), -257);
|
||||
ASSERTU4(pcode_BM22_ClearBitUnsignedInt(U4_MAX, 16), -65537);
|
||||
ASSERTU4(pcode_BM22_ClearBitUnsignedInt(U4_MAX, 24), -16777217);
|
||||
ASSERTU4(pcode_BM22_ClearBitUnsignedInt(U4_MAX, 31), 2147483647);
|
||||
}
|
||||
|
||||
TEST pcode_BM23_ClearBitUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_BM23_ClearBitUnsignedShort(u2 arg, u2 bit);
|
||||
ASSERTU2(pcode_BM23_ClearBitUnsignedShort(0xFF, 1), 253);
|
||||
ASSERTU2(pcode_BM23_ClearBitUnsignedShort(0, 1), 0);
|
||||
ASSERTU2(pcode_BM23_ClearBitUnsignedShort(U2_MAX, 8), 65279);
|
||||
ASSERTU2(pcode_BM23_ClearBitUnsignedShort(U2_MAX, 15), 32767);
|
||||
}
|
||||
|
||||
TEST pcode_BM24_ClearBitUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_BM24_ClearBitUnsignedChar(u1 arg, u1 bit);
|
||||
ASSERTU1(pcode_BM24_ClearBitUnsignedChar(0xFF, 1), 253);
|
||||
ASSERTU1(pcode_BM24_ClearBitUnsignedChar(0, 1), 0);
|
||||
ASSERTU1(pcode_BM24_ClearBitUnsignedChar(U1_MAX, 4), 239);
|
||||
ASSERTU1(pcode_BM24_ClearBitUnsignedChar(U1_MAX, 8), 255);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM25_ToggleBitLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_BM25_ToggleBitLongLong(i8 arg, u4 bit);
|
||||
ASSERTI8(pcode_BM25_ToggleBitLongLong(0xFF, 1), 253);
|
||||
ASSERTI8(pcode_BM25_ToggleBitLongLong(0, 1), 2);
|
||||
ASSERTI8(pcode_BM25_ToggleBitLongLong(I8_MAX, 8), 9223372036854775551LL);
|
||||
ASSERTI8(pcode_BM25_ToggleBitLongLong(I8_MAX, 16), 9223372036854710271LL);
|
||||
ASSERTI8(pcode_BM25_ToggleBitLongLong(I8_MAX, 32), 9223372032559808511LL);
|
||||
ASSERTI8(pcode_BM25_ToggleBitLongLong(I8_MAX, 63), -1LL);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM26_ToggleBitInt_Main()
|
||||
{
|
||||
extern i4 pcode_BM26_ToggleBitInt(i4 arg, i4 bit);
|
||||
ASSERTI4(pcode_BM26_ToggleBitInt(0xFF, 1), 253);
|
||||
ASSERTI4(pcode_BM26_ToggleBitInt(0, 1), 2);
|
||||
ASSERTI4(pcode_BM26_ToggleBitInt(I4_MAX, 8), 2147483391);
|
||||
ASSERTI4(pcode_BM26_ToggleBitInt(I4_MAX, 16), 2147418111);
|
||||
ASSERTI4(pcode_BM26_ToggleBitInt(I4_MAX, 24), 2130706431);
|
||||
ASSERTI4(pcode_BM26_ToggleBitInt(I4_MAX, 31), -1);
|
||||
}
|
||||
|
||||
TEST pcode_BM27_ToggleBitShort_Main()
|
||||
{
|
||||
extern i2 pcode_BM27_ToggleBitShort(i2 arg, i2 bit);
|
||||
ASSERTI2(pcode_BM27_ToggleBitShort(0xFF, 1), 253);
|
||||
ASSERTI2(pcode_BM27_ToggleBitShort(0, 1), 2);
|
||||
ASSERTI2(pcode_BM27_ToggleBitShort(I2_MAX, 8), 32511);
|
||||
ASSERTI2(pcode_BM27_ToggleBitShort(I2_MAX, 15), -1);
|
||||
}
|
||||
|
||||
TEST pcode_BM28_ToggleBitChar_Main()
|
||||
{
|
||||
extern i1 pcode_BM28_ToggleBitChar(i1 arg, u4 bit);
|
||||
ASSERTI1(pcode_BM28_ToggleBitChar(0xFF, 1), -3);
|
||||
ASSERTI1(pcode_BM28_ToggleBitChar(0, 1), 2);
|
||||
ASSERTI1(pcode_BM28_ToggleBitChar(I1_MAX, 4), 111);
|
||||
ASSERTI1(pcode_BM28_ToggleBitChar(I1_MAX, 8), 127);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_BM29_ToggleBitUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_BM29_ToggleBitUnsignedLongLong(u8 arg, u4 bit);
|
||||
ASSERTU8(pcode_BM29_ToggleBitUnsignedLongLong(0xFF, 1), 253);
|
||||
ASSERTU8(pcode_BM29_ToggleBitUnsignedLongLong(0, 1), 2);
|
||||
ASSERTU8(pcode_BM29_ToggleBitUnsignedLongLong(U8_MAX, 8), 18446744073709551359ULL);
|
||||
ASSERTU8(pcode_BM29_ToggleBitUnsignedLongLong(U8_MAX, 16), 18446744073709486079ULL);
|
||||
ASSERTU8(pcode_BM29_ToggleBitUnsignedLongLong(U8_MAX, 32), 18446744069414584319ULL);
|
||||
ASSERTU8(pcode_BM29_ToggleBitUnsignedLongLong(U8_MAX, 63), 9223372036854775807ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_BM30_ToggleBitUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_BM30_ToggleBitUnsignedInt(u4 arg, u4 bit);
|
||||
ASSERTU4(pcode_BM30_ToggleBitUnsignedInt(0xFF, 1), 253);
|
||||
ASSERTU4(pcode_BM30_ToggleBitUnsignedInt(0, 1), 2);
|
||||
ASSERTU4(pcode_BM30_ToggleBitUnsignedInt(U4_MAX, 8), 4294967039);
|
||||
ASSERTU4(pcode_BM30_ToggleBitUnsignedInt(U4_MAX, 16), 4294901759);
|
||||
ASSERTU4(pcode_BM30_ToggleBitUnsignedInt(U4_MAX, 31), 2147483647);
|
||||
}
|
||||
|
||||
TEST pcode_BM31_ToggleBitUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_BM31_ToggleBitUnsignedShort(u2 arg, u4 bit);
|
||||
ASSERTU2(pcode_BM31_ToggleBitUnsignedShort(0xFF, 1), 253);
|
||||
ASSERTU2(pcode_BM31_ToggleBitUnsignedShort(0, 1), 2);
|
||||
ASSERTU2(pcode_BM31_ToggleBitUnsignedShort(U2_MAX, 8), 65279);
|
||||
ASSERTU2(pcode_BM31_ToggleBitUnsignedShort(U2_MAX, 15), 32767);
|
||||
}
|
||||
|
||||
TEST pcode_BM32_ToggleBitUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_BM32_ToggleBitUnsignedChar(u1 arg, u1 bit);
|
||||
ASSERTU1(pcode_BM32_ToggleBitUnsignedChar(0xFF, 1), 253);
|
||||
ASSERTU1(pcode_BM32_ToggleBitUnsignedChar(0, 1), 2);
|
||||
ASSERTU1(pcode_BM32_ToggleBitUnsignedChar(U1_MAX, 4), 239);
|
||||
ASSERTU1(pcode_BM32_ToggleBitUnsignedChar(U1_MAX, 7), 127);
|
||||
}
|
||||
|
||||
MAIN BitManipulation_main() { }
|
@ -0,0 +1,204 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#define GET_BIT(typ, arg, bit) (arg & (((typ)1) << bit))
|
||||
#define SET_BIT(typ, arg, bit) (arg | (((typ)1) << bit))
|
||||
#define CLR_BIT(typ, arg, bit) (arg & (~(((typ)1) << bit)))
|
||||
#define TGL_BIT(typ, arg, bit) (arg ^ (((typ)1) << bit))
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_BM1_GetBitLongLong(i8 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(i8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 pcode_BM2_GetBitInt(i4 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(i4, arg, bit);
|
||||
}
|
||||
|
||||
i2 pcode_BM3_GetBitShort(i2 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(i2, arg, bit);
|
||||
}
|
||||
|
||||
i1 pcode_BM4_GetBitChar(i1 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(i1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_BM5_GetBitUnsignedLongLong(u8 arg, u8 bit)
|
||||
{
|
||||
return GET_BIT(u8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 pcode_BM6_GetBitUnsignedInt(u4 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(u4, arg, bit);
|
||||
}
|
||||
|
||||
u2 pcode_BM7_GetBitUnsignedShort(u2 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(u2, arg, bit);
|
||||
}
|
||||
|
||||
u1 pcode_BM8_GetBitUnsignedChar(u1 arg, u4 bit)
|
||||
{
|
||||
return GET_BIT(u1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_BM9_SetBitLongLong(i8 arg, u4 bit)
|
||||
{
|
||||
return SET_BIT(i8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 pcode_BM10_SetBitInt(i4 arg, u4 bit)
|
||||
{
|
||||
return SET_BIT(i4, arg, bit);
|
||||
}
|
||||
|
||||
i2 pcode_BM11_SetBitShort(i2 arg, i2 bit)
|
||||
{
|
||||
return SET_BIT(i2, arg, bit);
|
||||
}
|
||||
|
||||
i1 pcode_BM12_SetBitChar(i1 arg, u1 bit)
|
||||
{
|
||||
return SET_BIT(i1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_BM12_SetBitUnsignedLongLong(u8 arg, u8 bit)
|
||||
{
|
||||
return SET_BIT(u8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_BM13_SetLowBitUnsignedLongLong(u8 arg, u8 bit)
|
||||
{
|
||||
return SET_BIT(u8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 pcode_BM14_SetBitUnsignedInt(u4 arg, u4 bit)
|
||||
{
|
||||
return SET_BIT(u4, arg, bit);
|
||||
}
|
||||
|
||||
u2 pcode_BM15_SetBitUnsignedShort(u2 arg, u4 bit)
|
||||
{
|
||||
return SET_BIT(u2, arg, bit);
|
||||
}
|
||||
|
||||
u1 pcode_BM16_SetBitUnsignedChar(u1 arg, u1 bit)
|
||||
{
|
||||
return SET_BIT(u1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_BM17_ClearBitLongLong(i8 arg, i8 bit)
|
||||
{
|
||||
return CLR_BIT(i8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 pcode_BM18_ClearBitInt(i4 arg, i4 bit)
|
||||
{
|
||||
return CLR_BIT(i4, arg, bit);
|
||||
}
|
||||
|
||||
i2 pcode_BM19_ClearBitShort(i2 arg, i2 bit)
|
||||
{
|
||||
return CLR_BIT(i2, arg, bit);
|
||||
}
|
||||
|
||||
i1 pcode_BM20_ClearBitChar(i1 arg, u1 bit)
|
||||
{
|
||||
return CLR_BIT(i1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_BM21_ClearBitUnsignedLongLong(u8 arg, u8 bit)
|
||||
{
|
||||
return CLR_BIT(u8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 pcode_BM22_ClearBitUnsignedInt(u4 arg, u4 bit)
|
||||
{
|
||||
return CLR_BIT(u4, arg, bit);
|
||||
}
|
||||
|
||||
u2 pcode_BM23_ClearBitUnsignedShort(u2 arg, u2 bit)
|
||||
{
|
||||
return CLR_BIT(u2, arg, bit);
|
||||
}
|
||||
|
||||
u1 pcode_BM24_ClearBitUnsignedChar(u1 arg, u1 bit)
|
||||
{
|
||||
return CLR_BIT(u1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_BM25_ToggleBitLongLong(i8 arg, u4 bit)
|
||||
{
|
||||
return TGL_BIT(i8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 pcode_BM26_ToggleBitInt(i4 arg, i4 bit)
|
||||
{
|
||||
return TGL_BIT(i4, arg, bit);
|
||||
}
|
||||
|
||||
i2 pcode_BM27_ToggleBitShort(i2 arg, i2 bit)
|
||||
{
|
||||
return TGL_BIT(i2, arg, bit);
|
||||
}
|
||||
|
||||
i1 pcode_BM28_ToggleBitChar(i1 arg, u4 bit)
|
||||
{
|
||||
return TGL_BIT(i1, arg, bit);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_BM29_ToggleBitUnsignedLongLong(u8 arg, u4 bit)
|
||||
{
|
||||
return TGL_BIT(u8, arg, bit);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 pcode_BM30_ToggleBitUnsignedInt(u4 arg, u4 bit)
|
||||
{
|
||||
return TGL_BIT(u4, arg, bit);
|
||||
}
|
||||
|
||||
u2 pcode_BM31_ToggleBitUnsignedShort(u2 arg, u4 bit)
|
||||
{
|
||||
return TGL_BIT(u2, arg, bit);
|
||||
}
|
||||
|
||||
u1 pcode_BM32_ToggleBitUnsignedChar(u1 arg, u1 bit)
|
||||
{
|
||||
return TGL_BIT(u1, arg, bit);
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_DM1_IfElse_Main()
|
||||
{
|
||||
extern i4 pcode_DM1_IfElse(i4 arg1);
|
||||
ASSERTI4(pcode_DM1_IfElse(0), 0);
|
||||
ASSERTI4(pcode_DM1_IfElse(0x42), 1);
|
||||
}
|
||||
|
||||
TEST pcode_DM2_IfElseIfElse_Main()
|
||||
{
|
||||
extern i4 pcode_DM2_IfElseIfElse(i4 arg1);
|
||||
ASSERTI4(pcode_DM2_IfElseIfElse(0), 0);
|
||||
ASSERTI4(pcode_DM2_IfElseIfElse(0x42), 1);
|
||||
ASSERTI4(pcode_DM2_IfElseIfElse(0x69), 2);
|
||||
}
|
||||
|
||||
TEST pcode_DM3_SmallSwitch_Main()
|
||||
{
|
||||
extern i4 pcode_DM3_SmallSwitch(i4 arg1);
|
||||
i4 ret = pcode_DM3_SmallSwitch(0);
|
||||
ASSERTI4(pcode_DM3_SmallSwitch(0), 0);
|
||||
ASSERTI4(pcode_DM3_SmallSwitch(0x42), 1);
|
||||
ASSERTI4(pcode_DM3_SmallSwitch(0x69), 2);
|
||||
}
|
||||
|
||||
TEST pcode_DM4_MediumSwitch_Main()
|
||||
{
|
||||
extern i4 pcode_DM4_MediumSwitch(i4 arg1);
|
||||
ASSERTI4(pcode_DM4_MediumSwitch(0x42), 1);
|
||||
ASSERTI4(pcode_DM4_MediumSwitch(0x69), 2);
|
||||
ASSERTI4(pcode_DM4_MediumSwitch(0x101), 3);
|
||||
ASSERTI4(pcode_DM4_MediumSwitch(-1), 0);
|
||||
}
|
||||
|
||||
TEST pcode_DM5_EQ_TernaryOperator_Main()
|
||||
{
|
||||
extern i4 pcode_DM5_EQ_TernaryOperator(i4 arg1);
|
||||
ASSERTI4(pcode_DM5_EQ_TernaryOperator(0x42), 0);
|
||||
ASSERTI4(pcode_DM5_EQ_TernaryOperator(0x69), 1);
|
||||
}
|
||||
|
||||
TEST pcode_DM6_NE_TernaryOperator_Main()
|
||||
{
|
||||
extern i4 pcode_DM6_NE_TernaryOperator(i4 arg1);
|
||||
ASSERTI4(pcode_DM6_NE_TernaryOperator(0x42), 1);
|
||||
ASSERTI4(pcode_DM6_NE_TernaryOperator(0x69), 0);
|
||||
}
|
||||
|
||||
TEST pcode_DM7_LT_TernaryOperator_Main()
|
||||
{
|
||||
extern i4 pcode_DM7_LT_TernaryOperator(i4 arg1);
|
||||
ASSERTI4(pcode_DM7_LT_TernaryOperator(0x42), 1);
|
||||
ASSERTI4(pcode_DM7_LT_TernaryOperator(0x69), 0);
|
||||
ASSERTI4(pcode_DM7_LT_TernaryOperator(0x72), 0);
|
||||
}
|
||||
|
||||
TEST pcode_DM8_GT_TernaryOperator_Main()
|
||||
{
|
||||
extern i4 pcode_DM8_GT_TernaryOperator(i4 arg1);
|
||||
ASSERTI4(pcode_DM8_GT_TernaryOperator(0x42), 0);
|
||||
ASSERTI4(pcode_DM8_GT_TernaryOperator(0x69), 0);
|
||||
ASSERTI4(pcode_DM8_GT_TernaryOperator(0x82), 1);
|
||||
}
|
||||
|
||||
TEST pcode_DM9_LE_TernaryOperator_Main()
|
||||
{
|
||||
extern i4 pcode_DM9_LE_TernaryOperator(i4 arg1);
|
||||
ASSERTI4(pcode_DM9_LE_TernaryOperator(0x42), 1);
|
||||
ASSERTI4(pcode_DM9_LE_TernaryOperator(0x69), 1);
|
||||
ASSERTI4(pcode_DM9_LE_TernaryOperator(0x72), 0);
|
||||
}
|
||||
|
||||
TEST pcode_DM10_GE_TernaryOperator_Main()
|
||||
{
|
||||
extern i4 pcode_DM10_GE_TernaryOperator(i4 arg1);
|
||||
ASSERTI4(pcode_DM10_GE_TernaryOperator(0x42), 0);
|
||||
ASSERTI4(pcode_DM10_GE_TernaryOperator(0x69), 1);
|
||||
ASSERTI4(pcode_DM10_GE_TernaryOperator(0x72), 1);
|
||||
}
|
||||
|
||||
MAIN DecisionMaking_main() { }
|
@ -0,0 +1,105 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
i4 pcode_DM1_IfElse(i4 arg1)
|
||||
{
|
||||
if (arg1 == 0x42) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
i4 pcode_DM2_IfElseIfElse(i4 arg1)
|
||||
{
|
||||
if (arg1 == 0x42) {
|
||||
return 1;
|
||||
} else if (arg1 == 0x69) {
|
||||
return 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
i4 pcode_DM3_SmallSwitch(i4 arg1)
|
||||
{
|
||||
switch (arg1) {
|
||||
case 0x42:
|
||||
return 1;
|
||||
break;
|
||||
case 0x69:
|
||||
return 2;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i4 pcode_DM4_MediumSwitch(i4 arg1)
|
||||
{
|
||||
switch (arg1) {
|
||||
case 0x42:
|
||||
return 1;
|
||||
break;
|
||||
case 0x69:
|
||||
return 2;
|
||||
break;
|
||||
case 0x101:
|
||||
case 0x102:
|
||||
case 0x103:
|
||||
case 0x104:
|
||||
case 0x105:
|
||||
case 0x106:
|
||||
case 0x107:
|
||||
case 0x108:
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i4 pcode_DM5_EQ_TernaryOperator(i4 arg1)
|
||||
{
|
||||
return arg1 == 0x69 ? 1 : 0;
|
||||
}
|
||||
|
||||
i4 pcode_DM6_NE_TernaryOperator(i4 arg1)
|
||||
{
|
||||
return arg1 != 0x69 ? 1 : 0;
|
||||
}
|
||||
|
||||
i4 pcode_DM7_LT_TernaryOperator(i4 arg1)
|
||||
{
|
||||
return arg1 < 0x69 ? 1 : 0;
|
||||
}
|
||||
|
||||
i4 pcode_DM8_GT_TernaryOperator(i4 arg1)
|
||||
{
|
||||
return arg1 > 0x69 ? 1 : 0;
|
||||
}
|
||||
|
||||
i4 pcode_DM9_LE_TernaryOperator(i4 arg1)
|
||||
{
|
||||
return arg1 <= 0x69 ? 1 : 0;
|
||||
}
|
||||
|
||||
i4 pcode_DM10_GE_TernaryOperator(i4 arg1)
|
||||
{
|
||||
return arg1 >= 0x69 ? 1 : 0;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
extern i4 GLOBAL;
|
||||
|
||||
TEST pcode_ModifyGlobal_Main()
|
||||
{
|
||||
extern void pcode_ModifyGlobal(i4 arg1);
|
||||
pcode_ModifyGlobal(5);
|
||||
ASSERTI4(GLOBAL, 5);
|
||||
}
|
||||
|
||||
TEST pcode_AccessAndModifyGlobal_Main()
|
||||
{
|
||||
extern i4 pcode_AccessAndModifyGlobal(i4 arg1);
|
||||
i4 ret = pcode_AccessAndModifyGlobal(6);
|
||||
ASSERTI4(GLOBAL, 6);
|
||||
}
|
||||
|
||||
TEST pcode_AccessGlobal_Main()
|
||||
{
|
||||
extern i4 pcode_AccessGlobal();
|
||||
i4 ret = pcode_AccessGlobal();
|
||||
ASSERTI4(GLOBAL, GLOBAL);
|
||||
}
|
||||
|
||||
MAIN GlobalVariables_main() { }
|
@ -0,0 +1,37 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
extern i4 GLOBAL = 0;
|
||||
|
||||
void pcode_ModifyGlobal(i4 arg1)
|
||||
{
|
||||
GLOBAL = arg1;
|
||||
}
|
||||
|
||||
i4 pcode_AccessAndModifyGlobal(i4 arg1)
|
||||
{
|
||||
i4 tmp;
|
||||
|
||||
tmp = GLOBAL;
|
||||
GLOBAL = arg1;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
i4 pcode_AccessGlobal()
|
||||
{
|
||||
return GLOBAL;
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_StandardPostIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPostIncDoWhileLoop();
|
||||
ASSERTI4(pcode_StandardPostIncDoWhileLoop(), 30);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPreIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPreIncDoWhileLoop();
|
||||
ASSERTI4(pcode_StandardPreIncDoWhileLoop(), 30);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPostDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPostDecDoWhileLoop();
|
||||
ASSERTI4(pcode_StandardPostDecDoWhileLoop(), 30);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPreDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPreDecDoWhileLoop();
|
||||
ASSERTI4(pcode_StandardPreDecDoWhileLoop(), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPostIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPostIncDoWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPostIncDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPreIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPreIncDoWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPreIncDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPostDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPostDecDoWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPostDecDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPreDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPreDecDoWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPreDecDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPostIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPostIncDoWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPostIncDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPreIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPreIncDoWhileLoop(i4 nn);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPostDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPostDecDoWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPostDecDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPreDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPreDecDoWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPreDecDoWhileLoop(5), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePostIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePostIncDoWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePostIncDoWhileLoop(5, 10), 55);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePreIncDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePreIncDoWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePreIncDoWhileLoop(5, 10), 55);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePostDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePostDecDoWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePostDecDoWhileLoop(5, 10), 55);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePreDecDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePreDecDoWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePreDecDoWhileLoop(5, 10), 55);
|
||||
}
|
||||
|
||||
TEST pcode_SwitchedDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_SwitchedDoWhileLoop(i4 type, i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_SwitchedDoWhileLoop(5, 10, 15, 20), 315);
|
||||
}
|
||||
|
||||
TEST pcode_UnSwitchedDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_UnSwitchedDoWhileLoop(i4 type, i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_UnSwitchedDoWhileLoop(5, 10, 15, 20), 315);
|
||||
}
|
||||
|
||||
TEST pcode_JammedDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_JammedDoWhileLoop(i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_JammedDoWhileLoop(5, 10, 15), 5243040);
|
||||
}
|
||||
|
||||
TEST pcode_UnJammedDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_UnJammedDoWhileLoop(i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_UnJammedDoWhileLoop(5, 10, 15), 5243040);
|
||||
}
|
||||
|
||||
TEST pcode_RolledDoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_RolledDoWhileLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
ASSERTI4(pcode_RolledDoWhileLoop(array, 10), 55);
|
||||
ASSERTI4(pcode_RolledDoWhileLoop(array, 5), 15);
|
||||
ASSERTI4(pcode_RolledDoWhileLoop(array, 1), 1);
|
||||
ASSERTI4(pcode_RolledDoWhileLoop(array, 0), 1);
|
||||
}
|
||||
|
||||
TEST pcode_Unrolled2DoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_Unrolled2DoWhileLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
ASSERTI4(pcode_Unrolled2DoWhileLoop(array, 10), 55);
|
||||
ASSERTI4(pcode_Unrolled2DoWhileLoop(array, 5), 15);
|
||||
ASSERTI4(pcode_Unrolled2DoWhileLoop(array, 1), 6);
|
||||
ASSERTI4(pcode_Unrolled2DoWhileLoop(array, 0), 3);
|
||||
}
|
||||
|
||||
TEST pcode_Unrolled4DoWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_Unrolled4DoWhileLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
ASSERTI4(pcode_Unrolled4DoWhileLoop(array, 10), 55);
|
||||
ASSERTI4(pcode_Unrolled4DoWhileLoop(array, 5), 15);
|
||||
ASSERTI4(pcode_Unrolled4DoWhileLoop(array, 1), 15);
|
||||
ASSERTI4(pcode_Unrolled4DoWhileLoop(array, 0), 10);
|
||||
}
|
||||
|
||||
MAIN IterativeProcessingDoWhile_main() { }
|
@ -0,0 +1,303 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
i4 pcode_StandardPostIncDoWhileLoop()
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (ii++ < 5);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPreIncDoWhileLoop()
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (++ii <= 5);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPostDecDoWhileLoop()
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (ii-- > 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPreDecDoWhileLoop()
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (--ii >= 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPostIncDoWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (ii++ < 5);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPreIncDoWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (++ii <= 5);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPostDecDoWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (ii-- > 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPreDecDoWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (--ii >= 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPostIncDoWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (ii++ < nn);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPreIncDoWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (++ii <= nn);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPostDecDoWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (ii-- > 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPreDecDoWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += 5;
|
||||
} while (--ii >= 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePostIncDoWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (ii++ < nn);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePreIncDoWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (++ii <= nn);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePostDecDoWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (ii-- > 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePreDecDoWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += kk;
|
||||
} while (--ii >= 0);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_SwitchedDoWhileLoop(i4 type, i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
if (type == 10) {
|
||||
accum += kk;
|
||||
} else {
|
||||
accum += jj;
|
||||
}
|
||||
} while (ii++ < nn);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_UnSwitchedDoWhileLoop(i4 type, i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
if (type == 10) {
|
||||
do {
|
||||
accum += kk;
|
||||
} while (ii++ < nn);
|
||||
} else {
|
||||
do {
|
||||
accum += jj;
|
||||
} while (ii++ < nn);
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_JammedDoWhileLoop(i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum1 = 0;
|
||||
i4 accum2 = 0;
|
||||
|
||||
do {
|
||||
accum1 += kk;
|
||||
accum2 += jj;
|
||||
} while (ii++ < nn);
|
||||
return (accum1 << 16) | accum2;
|
||||
}
|
||||
|
||||
i4 pcode_UnJammedDoWhileLoop(i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum1 = 0;
|
||||
i4 accum2 = 0;
|
||||
|
||||
do {
|
||||
accum1 += kk;
|
||||
} while (ii++ < nn);
|
||||
ii = 0;
|
||||
do {
|
||||
accum2 += jj;
|
||||
} while (ii++ < nn);
|
||||
return (accum1 << 16) | accum2;
|
||||
}
|
||||
|
||||
i4 pcode_RolledDoWhileLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
do {
|
||||
accum += array[ii++];
|
||||
} while (ii < nn);
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_Unrolled2DoWhileLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
i4 limit = nn & (~1);
|
||||
|
||||
do {
|
||||
accum += array[ii] + array[ii + 1];
|
||||
ii += 2;
|
||||
} while (ii < limit);
|
||||
if (limit != nn) {
|
||||
accum += array[ii];
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_Unrolled4DoWhileLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
i4 limit = nn & (~3);
|
||||
|
||||
do {
|
||||
accum += array[ii] + array[ii + 1] + array[ii + 2] + array[ii + 3];
|
||||
ii += 4;
|
||||
} while (ii < limit);
|
||||
switch (nn - limit) {
|
||||
case 3:
|
||||
accum += array[ii++];
|
||||
case 2:
|
||||
accum += array[ii++];
|
||||
case 1:
|
||||
accum += array[ii];
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
return accum;
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_StandardPostIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPostIncForLoop();
|
||||
ASSERTI4(pcode_StandardPostIncForLoop(), 25);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPreIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPreIncForLoop();
|
||||
ASSERTI4(pcode_StandardPreIncForLoop(), 30);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPostDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPostDecForLoop();
|
||||
ASSERTI4(pcode_StandardPostDecForLoop(), 25);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPreDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPreDecForLoop();
|
||||
ASSERTI4(pcode_StandardPreDecForLoop(), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPostIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPostIncForLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPostIncForLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPreIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPreIncForLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPreIncForLoop(6), 36);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPreDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPreDecForLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPreDecForLoop(6), 36);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPostDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPostDecForLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPostDecForLoop(6), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPostIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPostIncForLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPostIncForLoop(6), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPreIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPreIncForLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPreIncForLoop(6), 35);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPostDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPostDecForLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPostDecForLoop(6), 30);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPreDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPreDecForLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPreDecForLoop(6), 35);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePostIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePostIncForLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePostIncForLoop(6, 10), 60);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePreIncForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePreIncForLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePreIncForLoop(6, 10), 66);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePostDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePostDecForLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePostDecForLoop(6, 10), 60);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePreDecForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePreDecForLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePreDecForLoop(6, 10), 66);
|
||||
}
|
||||
|
||||
TEST pcode_SwitchedForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_SwitchedForLoop(i4 type, i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_SwitchedForLoop(6, 10, 15, 20), 300);
|
||||
}
|
||||
|
||||
TEST pcode_UnSwitchedForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_UnSwitchedForLoop(i4 type, i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_UnSwitchedForLoop(6, 10, 15, 20), 300);
|
||||
}
|
||||
|
||||
TEST pcode_JammedForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_JammedForLoop(i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_JammedForLoop(6, 10, 15), 5898390);
|
||||
}
|
||||
|
||||
TEST pcode_UnJammedForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_UnJammedForLoop(i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_UnJammedForLoop(6, 10, 15), 5898390);
|
||||
}
|
||||
|
||||
TEST pcode_RolledForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_RolledForLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
|
||||
ASSERTI4(pcode_RolledForLoop(array, 5), 15);
|
||||
ASSERTI4(pcode_RolledForLoop(array, 9), 45);
|
||||
ASSERTI4(pcode_RolledForLoop(array, 1), 1);
|
||||
ASSERTI4(pcode_RolledForLoop(array, 0), 0);
|
||||
}
|
||||
|
||||
TEST pcode_Unrolled2ForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_Unrolled2ForLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
|
||||
ASSERTI4(pcode_Unrolled2ForLoop(array, 5), 15);
|
||||
ASSERTI4(pcode_Unrolled2ForLoop(array, 9), 45);
|
||||
ASSERTI4(pcode_Unrolled2ForLoop(array, 1), 1);
|
||||
ASSERTI4(pcode_Unrolled2ForLoop(array, 0), 0);
|
||||
}
|
||||
|
||||
TEST pcode_Unrolled4ForLoop_Main()
|
||||
{
|
||||
extern i4 pcode_Unrolled4ForLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
|
||||
ASSERTI4(pcode_Unrolled4ForLoop(array, 5), 15);
|
||||
ASSERTI4(pcode_Unrolled4ForLoop(array, 9), 45);
|
||||
ASSERTI4(pcode_Unrolled4ForLoop(array, 1), 1);
|
||||
ASSERTI4(pcode_Unrolled4ForLoop(array, 0), 0);
|
||||
}
|
||||
|
||||
TEST pcode_testNestedLoop1_Main()
|
||||
{
|
||||
extern i4 pcode_testNestedLoop1(i4 a);
|
||||
ASSERTI4(pcode_testNestedLoop1(-1), -80);
|
||||
ASSERTI4(pcode_testNestedLoop1(1), 280);
|
||||
ASSERTI4(pcode_testNestedLoop1(0), 100);
|
||||
ASSERTI4(pcode_testNestedLoop1(2), 460);
|
||||
ASSERTI4(pcode_testNestedLoop1(3), 640);
|
||||
ASSERTI4(pcode_testNestedLoop1(257), 46360);
|
||||
}
|
||||
|
||||
TEST pcode_testNestedLoop2_Main()
|
||||
{
|
||||
extern i4 pcode_testNestedLoop2(i4 a);
|
||||
ASSERTI4(pcode_testNestedLoop2(0), 0);
|
||||
ASSERTI4(pcode_testNestedLoop2(1), 320);
|
||||
ASSERTI4(pcode_testNestedLoop2(2), 640);
|
||||
ASSERTI4(pcode_testNestedLoop2(257), 82240);
|
||||
ASSERTI4(pcode_testNestedLoop2(3), 960);
|
||||
ASSERTI4(pcode_testNestedLoop2(-1), -320);
|
||||
}
|
||||
|
||||
TEST pcode_testNestedLoop3_Main()
|
||||
{
|
||||
extern i4 pcode_testNestedLoop3(i4 a);
|
||||
ASSERTI4(pcode_testNestedLoop3(0), 0);
|
||||
ASSERTI4(pcode_testNestedLoop3(1), 12336);
|
||||
ASSERTI4(pcode_testNestedLoop3(2), 24672);
|
||||
ASSERTI4(pcode_testNestedLoop3(3), 37008);
|
||||
ASSERTI4(pcode_testNestedLoop3(257), 3170352);
|
||||
ASSERTI4(pcode_testNestedLoop3(-1), -12336);
|
||||
}
|
||||
|
||||
MAIN IterativeProcessingFor_main() { }
|
||||
|
@ -0,0 +1,345 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
i4 pcode_StandardPostIncForLoop()
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii < 5; ii++) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPreIncForLoop()
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii <= 5; ++ii) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPostDecForLoop()
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 5; ii > 0; ii--) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPreDecForLoop()
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 5; ii >= 0; --ii) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPostIncForLoop(i4 kk)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii < 5; ii++) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPreIncForLoop(i4 kk)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii <= 5; ++ii) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPreDecForLoop(i4 kk)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 5; ii >= 0; --ii) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPostDecForLoop(i4 kk)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 5; ii > 0; ii--) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPostIncForLoop(i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii < nn; ii++) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPreIncForLoop(i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii <= nn; ++ii) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPostDecForLoop(i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = nn; ii > 0; ii--) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPreDecForLoop(i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = nn; ii >= 0; --ii) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePostIncForLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii < nn; ii++) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePreIncForLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii <= nn; ++ii) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePostDecForLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = nn; ii > 0; ii--) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePreDecForLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = nn; ii >= 0; --ii) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_SwitchedForLoop(i4 type, i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii < nn; ++ii) {
|
||||
if (type == 10) {
|
||||
accum += kk;
|
||||
} else {
|
||||
accum += jj;
|
||||
}
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_UnSwitchedForLoop(i4 type, i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
if (type == 10) {
|
||||
for (ii = 0; ii < nn; ++ii) {
|
||||
accum += kk;
|
||||
}
|
||||
} else {
|
||||
for (ii = 0; ii < nn; ++ii) {
|
||||
accum += jj;
|
||||
}
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_JammedForLoop(i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum1 = 0;
|
||||
i4 accum2 = 0;
|
||||
|
||||
for (ii = 0; ii < nn; ++ii) {
|
||||
accum1 += kk;
|
||||
accum2 += jj;
|
||||
}
|
||||
return (accum1 << 16) | accum2;
|
||||
}
|
||||
|
||||
i4 pcode_UnJammedForLoop(i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum1 = 0;
|
||||
i4 accum2 = 0;
|
||||
|
||||
for (ii = 0; ii < nn; ++ii) {
|
||||
accum1 += kk;
|
||||
}
|
||||
for (ii = 0; ii < nn; ++ii) {
|
||||
accum2 += jj;
|
||||
}
|
||||
return (accum1 << 16) | accum2;
|
||||
}
|
||||
|
||||
i4 pcode_RolledForLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
|
||||
for (ii = 0; ii < nn;) {
|
||||
accum += array[ii++];
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_Unrolled2ForLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
i4 limit = nn & (~1);
|
||||
|
||||
for (ii = 0; ii < limit;) {
|
||||
accum += array[ii] + array[ii + 1];
|
||||
ii += 2;
|
||||
}
|
||||
if (limit != nn) {
|
||||
accum += array[ii];
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_Unrolled4ForLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii;
|
||||
i4 accum = 0;
|
||||
i4 limit = nn & (~3);
|
||||
|
||||
for (ii = 0; ii < limit;) {
|
||||
accum += array[ii] + array[ii + 1] + array[ii + 2] + array[ii + 3];
|
||||
ii += 4;
|
||||
}
|
||||
switch (nn - limit) {
|
||||
case 3:
|
||||
accum += array[ii++];
|
||||
case 2:
|
||||
accum += array[ii++];
|
||||
case 1:
|
||||
accum += array[ii];
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_testNestedLoop1(i4 a)
|
||||
{
|
||||
i4 result = 0;
|
||||
i4 i = 0, j = 0, k = 0;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
k = i * a;
|
||||
for (j = 1; j < 5; j++) {
|
||||
result += k + j;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
i4 pcode_testNestedLoop2(i4 a)
|
||||
{
|
||||
i4 result = 0;
|
||||
i4 i = 0, j = 0, k = 1;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (j = 1; j < 5; j++) {
|
||||
result += a * (k + j);
|
||||
}
|
||||
k = i + 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
i4 pcode_testNestedLoop3(i4 a)
|
||||
{
|
||||
i4 result = 0;
|
||||
i4 i = 0, j = 0, k = 1;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
k += 1;
|
||||
for (j = 1; j < 5; j++) {
|
||||
result += a * (k + j);
|
||||
}
|
||||
k *= 2;
|
||||
}
|
||||
return result;
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_StandardPostIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPostIncWhileLoop();
|
||||
ASSERTI4(pcode_StandardPostIncWhileLoop(), 25);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPreIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPreIncWhileLoop();
|
||||
ASSERTI4(pcode_StandardPreIncWhileLoop(), 25);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPostDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPostDecWhileLoop();
|
||||
ASSERTI4(pcode_StandardPostDecWhileLoop(), 25);
|
||||
}
|
||||
|
||||
TEST pcode_StandardPreDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_StandardPreDecWhileLoop();
|
||||
ASSERTI4(pcode_StandardPreDecWhileLoop(), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPostIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPostIncWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPostIncWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPreIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPreIncWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPreIncWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPostDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPostDecWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPostDecWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPostIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPostIncWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPostIncWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIncrementPreDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIncrementPreDecWhileLoop(i4 kk);
|
||||
ASSERTI4(pcode_VarIncrementPreDecWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPreIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPreIncWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPreIncWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPostDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPostDecWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPostDecWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VarIterationPreDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VarIterationPreDecWhileLoop(i4 nn);
|
||||
ASSERTI4(pcode_VarIterationPreDecWhileLoop(5), 25);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePostIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePostIncWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePostIncWhileLoop(5, 10), 50);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePreIncWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePreIncWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePreIncWhileLoop(5, 10), 50);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePostDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePostDecWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePostDecWhileLoop(5, 10), 50);
|
||||
}
|
||||
|
||||
TEST pcode_VariablePreDecWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_VariablePreDecWhileLoop(i4 kk, i4 nn);
|
||||
ASSERTI4(pcode_VariablePreDecWhileLoop(5, 10), 50);
|
||||
}
|
||||
|
||||
TEST pcode_UnSwitchedWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_UnSwitchedWhileLoop(i4 type, i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_UnSwitchedWhileLoop(5, 10, 15, 20), 300);
|
||||
}
|
||||
|
||||
TEST pcode_SwitchedWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_SwitchedWhileLoop(i4 type, i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_SwitchedWhileLoop(5, 10, 15, 20), 300);
|
||||
}
|
||||
|
||||
TEST pcode_JammedWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_JammedWhileLoop(i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_JammedWhileLoop(5, 10, 15), 4915350);
|
||||
}
|
||||
|
||||
TEST pcode_UnJammedWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_UnJammedWhileLoop(i4 kk, i4 jj, i4 nn);
|
||||
ASSERTI4(pcode_UnJammedWhileLoop(5, 10, 15), 4915350);
|
||||
}
|
||||
|
||||
TEST pcode_RolledWhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_RolledWhileLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
ASSERTI4(pcode_RolledWhileLoop(array, 5), 10);
|
||||
}
|
||||
|
||||
TEST pcode_Unrolled2WhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_Unrolled2WhileLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
ASSERTI4(pcode_Unrolled2WhileLoop(array, 5), 10);
|
||||
}
|
||||
|
||||
TEST pcode_Unrolled4WhileLoop_Main()
|
||||
{
|
||||
extern i4 pcode_Unrolled4WhileLoop(i4 array[], i4 nn);
|
||||
i4 array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
ASSERTI4(pcode_Unrolled4WhileLoop(array, 5), 10);
|
||||
}
|
||||
|
||||
MAIN IterativeProcessingWhile_main() { }
|
||||
|
@ -0,0 +1,303 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
i4 pcode_StandardPostIncWhileLoop()
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii++ < 5) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPreIncWhileLoop()
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (++ii <= 5) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPostDecWhileLoop()
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii-- > 0) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_StandardPreDecWhileLoop()
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
while (--ii >= 0) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPostIncWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii++ < 5) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPreIncWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (++ii <= 5) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPostDecWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii-- > 0) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPostIncWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii++ < nn) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIncrementPreDecWhileLoop(i4 kk)
|
||||
{
|
||||
i4 ii = 5;
|
||||
i4 accum = 0;
|
||||
|
||||
while (--ii >= 0) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPreIncWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (++ii <= nn) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPostDecWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii-- > 0) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VarIterationPreDecWhileLoop(i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
while (--ii >= 0) {
|
||||
accum += 5;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePostIncWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii++ < nn) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePreIncWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (++ii <= nn) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePostDecWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii-- > 0) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_VariablePreDecWhileLoop(i4 kk, i4 nn)
|
||||
{
|
||||
i4 ii = nn;
|
||||
i4 accum = 0;
|
||||
|
||||
while (--ii >= 0) {
|
||||
accum += kk;
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_UnSwitchedWhileLoop(i4 type, i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
if (type == 10) {
|
||||
while (ii++ < nn) {
|
||||
accum += kk;
|
||||
}
|
||||
} else {
|
||||
while (ii++ < nn) {
|
||||
accum += jj;
|
||||
}
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_SwitchedWhileLoop(i4 type, i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii++ < nn) {
|
||||
if (type == 10) {
|
||||
accum += kk;
|
||||
} else {
|
||||
accum += jj;
|
||||
}
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_JammedWhileLoop(i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum1 = 0;
|
||||
i4 accum2 = 0;
|
||||
|
||||
while (ii++ < nn) {
|
||||
accum1 += kk;
|
||||
accum2 += jj;
|
||||
}
|
||||
return (accum1 << 16) | accum2;
|
||||
}
|
||||
|
||||
i4 pcode_UnJammedWhileLoop(i4 kk, i4 jj, i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum1 = 0;
|
||||
i4 accum2 = 0;
|
||||
|
||||
while (ii++ < nn) {
|
||||
accum1 += kk;
|
||||
}
|
||||
ii = 0;
|
||||
while (ii++ < nn) {
|
||||
accum2 += jj;
|
||||
}
|
||||
return (accum1 << 16) | accum2;
|
||||
}
|
||||
|
||||
i4 pcode_RolledWhileLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
|
||||
while (ii < nn) {
|
||||
accum += array[ii++];
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_Unrolled2WhileLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
i4 limit = nn & (~1);
|
||||
|
||||
while (ii < limit) {
|
||||
accum += array[ii] + array[ii + 1];
|
||||
ii += 2;
|
||||
}
|
||||
if (limit != nn) {
|
||||
accum += array[ii];
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
i4 pcode_Unrolled4WhileLoop(i4 array[], i4 nn)
|
||||
{
|
||||
i4 ii = 0;
|
||||
i4 accum = 0;
|
||||
i4 limit = nn & (~3);
|
||||
|
||||
while (ii < limit) {
|
||||
accum += array[ii] + array[ii + 1] + array[ii + 2] + array[ii + 3];
|
||||
ii += 4;
|
||||
}
|
||||
switch (nn - limit) {
|
||||
case 3:
|
||||
accum += array[ii++];
|
||||
case 2:
|
||||
accum += array[ii++];
|
||||
case 1:
|
||||
accum += array[ii];
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
return accum;
|
||||
}
|
@ -0,0 +1,256 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_PP1_12_InferPointerArgumentInt_Main()
|
||||
{
|
||||
extern i4 pcode_PP1_12_InferPointerArgumentInt(i4 * arg1);
|
||||
i4 arg = 5;
|
||||
ASSERTI4(pcode_PP1_12_InferPointerArgumentInt(&arg), -1);
|
||||
arg = sizeof(i4)*8-1;
|
||||
ASSERTI4(pcode_PP1_12_InferPointerArgumentInt(&arg), -1);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_12_InferPointerArgumentInt(&arg), -7);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_13_InferPointerArgumentShort_Main()
|
||||
{
|
||||
extern i2 pcode_PP1_13_InferPointerArgumentShort(i2 * arg1);
|
||||
i2 arg = 5;
|
||||
ASSERTI4(pcode_PP1_13_InferPointerArgumentShort(&arg), -1);
|
||||
arg = sizeof(i2)*8-1;
|
||||
ASSERTI4(pcode_PP1_13_InferPointerArgumentShort(&arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_13_InferPointerArgumentShort(&arg), -4);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_14_InferPointerArgumentChar_Main()
|
||||
{
|
||||
extern i1 pcode_PP1_14_InferPointerArgumentChar(i1 * arg1);
|
||||
i1 arg = 5;
|
||||
ASSERTI4(pcode_PP1_14_InferPointerArgumentChar(&arg), -1);
|
||||
arg = sizeof(i1)*8-1;
|
||||
ASSERTI4(pcode_PP1_14_InferPointerArgumentChar(&arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_14_InferPointerArgumentChar(&arg), -4);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_PP1_15_InferPointerArgumentUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_PP1_15_InferPointerArgumentUnsignedLongLong(u8 * arg1);
|
||||
u8 arg = 5;
|
||||
ASSERTI4(pcode_PP1_15_InferPointerArgumentUnsignedLongLong(&arg), -1);
|
||||
arg = sizeof(u8)*8-1;
|
||||
ASSERTI4(pcode_PP1_15_InferPointerArgumentUnsignedLongLong(&arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_15_InferPointerArgumentUnsignedLongLong(&arg), -4);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_PP1_16_InferPointerArgumentUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_PP1_16_InferPointerArgumentUnsignedInt(u4 * arg1);
|
||||
u4 arg = 5;
|
||||
ASSERTI4(pcode_PP1_16_InferPointerArgumentUnsignedInt(&arg), -1);
|
||||
arg = sizeof(u4)*8-1;
|
||||
ASSERTI4(pcode_PP1_16_InferPointerArgumentUnsignedInt(&arg), -1);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_16_InferPointerArgumentUnsignedInt(&arg), -7);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_17_InferPointerArgumentUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_PP1_17_InferPointerArgumentUnsignedShort(u2 * arg1);
|
||||
u2 arg = 5;
|
||||
ASSERTI4(pcode_PP1_17_InferPointerArgumentUnsignedShort(&arg), 65535);
|
||||
arg = sizeof(u2)*8-1;
|
||||
ASSERTI4(pcode_PP1_17_InferPointerArgumentUnsignedShort(&arg), 65535);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_17_InferPointerArgumentUnsignedShort(&arg), 65529);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_18_InferPointerArgumentUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_PP1_18_InferPointerArgumentUnsignedChar(u1 * arg1);
|
||||
u1 arg = 5;
|
||||
ASSERTI4(pcode_PP1_18_InferPointerArgumentUnsignedChar(&arg), 255);
|
||||
arg = sizeof(u1)*8-1;
|
||||
ASSERTI4(pcode_PP1_18_InferPointerArgumentUnsignedChar(&arg), 255);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_18_InferPointerArgumentUnsignedChar(&arg), 249);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_PP1_19_InferPointerArgumentFloat_Main()
|
||||
{
|
||||
extern f4 pcode_PP1_19_InferPointerArgumentFloat(f4 * arg1);
|
||||
f4 arg = 5;
|
||||
ASSERTF4(pcode_PP1_19_InferPointerArgumentFloat(&arg), -2.0);
|
||||
arg = PI_SHORT;
|
||||
ASSERTF4(pcode_PP1_19_InferPointerArgumentFloat(&arg), -3.860000);
|
||||
arg = -PI_SHORT;
|
||||
ASSERTF4(pcode_PP1_19_InferPointerArgumentFloat(&arg), -10.1400000);
|
||||
arg = 0.0;
|
||||
ASSERTF4(pcode_PP1_19_InferPointerArgumentFloat(&arg), -7.000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_PP1_20_InferPointerArgumentDouble_Main()
|
||||
{
|
||||
extern f8 pcode_PP1_20_InferPointerArgumentDouble(f8 * arg1);
|
||||
f8 arg = 5;
|
||||
ASSERTF8(pcode_PP1_20_InferPointerArgumentDouble(&arg), -2.0);
|
||||
arg = PI_SHORT;
|
||||
ASSERTF8(pcode_PP1_20_InferPointerArgumentDouble(&arg), -3.86);
|
||||
arg = -PI_SHORT;
|
||||
ASSERTF8(pcode_PP1_20_InferPointerArgumentDouble(&arg), -10.14);
|
||||
arg = 0.0;
|
||||
ASSERTF8(pcode_PP1_20_InferPointerArgumentDouble(&arg), -7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_PP1_1_InferArgumentLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_PP1_1_InferArgumentLongLong(i8* arg1);
|
||||
i8 arg = 5;
|
||||
ASSERTI4(pcode_PP1_1_InferArgumentLongLong(&arg), -1);
|
||||
arg = sizeof(i8)*8-1;
|
||||
ASSERTI4(pcode_PP1_1_InferArgumentLongLong(&arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_1_InferArgumentLongLong(&arg), -4);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_PP1_2_InferArgumentInt_Main()
|
||||
{
|
||||
extern i4 pcode_PP1_2_InferArgumentInt(i4 arg1);
|
||||
i4 arg = 5;
|
||||
ASSERTI4(pcode_PP1_2_InferArgumentInt(arg), -1);
|
||||
arg = sizeof(i4)*8-1;
|
||||
ASSERTI4(pcode_PP1_2_InferArgumentInt(arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_2_InferArgumentInt(arg), -4);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_2_InferArgumentInt(arg), -7);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_3_InferArgumentShort_Main()
|
||||
{
|
||||
extern i2 pcode_PP1_3_InferArgumentShort(i2 arg1);
|
||||
i2 arg = 5;
|
||||
ASSERTI4(pcode_PP1_3_InferArgumentShort(arg), -1);
|
||||
arg = sizeof(i2)*8-1;
|
||||
ASSERTI4(pcode_PP1_3_InferArgumentShort(arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_3_InferArgumentShort(arg), -4);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_3_InferArgumentShort(arg), -7);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_4_InferArgumentChar_Main()
|
||||
{
|
||||
extern i1 pcode_PP1_4_InferArgumentChar(i1 arg1);
|
||||
i1 arg = 5;
|
||||
ASSERTI4(pcode_PP1_4_InferArgumentChar(arg), -1);
|
||||
arg = sizeof(i1)*8-1;
|
||||
ASSERTI4(pcode_PP1_4_InferArgumentChar(arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_4_InferArgumentChar(arg), -4);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_4_InferArgumentChar(arg), -7);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_PP1_5_InferArgumentUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_PP1_5_InferArgumentUnsignedLongLong(u8 arg1);
|
||||
u8 arg = 5;
|
||||
ASSERTI4(pcode_PP1_5_InferArgumentUnsignedLongLong(arg), -1);
|
||||
arg = sizeof(u8)*8-1;
|
||||
ASSERTI4(pcode_PP1_5_InferArgumentUnsignedLongLong(arg), -1);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_5_InferArgumentUnsignedLongLong(arg), -7);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_PP1_6_InferArgumentUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_PP1_6_InferArgumentUnsignedInt(u4 arg1);
|
||||
u4 arg = 5;
|
||||
ASSERTI4(pcode_PP1_6_InferArgumentUnsignedInt(arg), -1);
|
||||
arg = sizeof(u4)*8-1;
|
||||
ASSERTI4(pcode_PP1_6_InferArgumentUnsignedInt(arg), -1);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_6_InferArgumentUnsignedInt(arg), -7);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_7_InferArgumentUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_PP1_7_InferArgumentUnsignedShort(u2 arg1);
|
||||
u2 arg = 5;
|
||||
ASSERTI4(pcode_PP1_7_InferArgumentUnsignedShort(arg), 65535);
|
||||
arg = sizeof(u2)*8-1;
|
||||
ASSERTI4(pcode_PP1_7_InferArgumentUnsignedShort(arg), 65535);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_7_InferArgumentUnsignedShort(arg), 65529);
|
||||
}
|
||||
|
||||
TEST pcode_PP1_8_InferArgumentUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_PP1_8_InferArgumentUnsignedChar(u1 arg1);
|
||||
u1 arg = 5;
|
||||
ASSERTI4(pcode_PP1_8_InferArgumentUnsignedChar(arg), 255);
|
||||
arg = sizeof(u2)*8-1;
|
||||
ASSERTI4(pcode_PP1_8_InferArgumentUnsignedChar(arg), 255);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_8_InferArgumentUnsignedChar(arg), 249);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_PP1_9_InferArgumentFloat_Main()
|
||||
{
|
||||
extern f4 pcode_PP1_9_InferArgumentFloat(f4 arg1);
|
||||
f4 arg = 5;
|
||||
ASSERTF4(pcode_PP1_9_InferArgumentFloat(arg), (f4) -2.0);
|
||||
arg = PI_SHORT;
|
||||
ASSERTF4(pcode_PP1_9_InferArgumentFloat(arg), (f4) -3.860000);
|
||||
arg = -PI_SHORT;
|
||||
ASSERTF4(pcode_PP1_9_InferArgumentFloat(arg), (f4) -10.140000);
|
||||
arg = 0.0;
|
||||
ASSERTF4(pcode_PP1_9_InferArgumentFloat(arg), (f4) -7.000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_PP1_10_InferArgumentDouble_Main()
|
||||
{
|
||||
extern f8 pcode_PP1_10_InferArgumentDouble(f8 arg1);
|
||||
f8 arg = 5;
|
||||
ASSERTF8(pcode_PP1_10_InferArgumentDouble(arg), (f8) -2.0);
|
||||
arg = PI_SHORT;
|
||||
ASSERTF8(pcode_PP1_10_InferArgumentDouble(arg), (f8) -3.86);
|
||||
arg = -PI_SHORT;
|
||||
ASSERTF8(pcode_PP1_10_InferArgumentDouble(arg), (f8) -10.14);
|
||||
arg = 0.0;
|
||||
ASSERTF8(pcode_PP1_10_InferArgumentDouble(arg), (f8) -7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_PP1_11_InferPointerArgumentLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_PP1_11_InferPointerArgumentLongLong(i8 * arg1);
|
||||
i8 arg = 5;
|
||||
ASSERTI4(pcode_PP1_11_InferPointerArgumentLongLong(&arg), -1);
|
||||
arg = sizeof(i8)*8-1;
|
||||
ASSERTI4(pcode_PP1_11_InferPointerArgumentLongLong(&arg), -1);
|
||||
arg = 1;
|
||||
ASSERTI4(pcode_PP1_11_InferPointerArgumentLongLong(&arg), -4);
|
||||
arg = 0;
|
||||
ASSERTI4(pcode_PP1_11_InferPointerArgumentLongLong(&arg), -7);
|
||||
}
|
||||
#endif
|
||||
|
||||
MAIN ParameterPassing1_main() { }
|
||||
|
@ -0,0 +1,132 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
i4 pcode_PP1_12_InferPointerArgumentInt(i4 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
|
||||
i2 pcode_PP1_13_InferPointerArgumentShort(i2 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
|
||||
i1 pcode_PP1_14_InferPointerArgumentChar(i1 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_PP1_15_InferPointerArgumentUnsignedLongLong(u8 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 pcode_PP1_16_InferPointerArgumentUnsignedInt(u4 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
|
||||
u2 pcode_PP1_17_InferPointerArgumentUnsignedShort(u2 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
|
||||
u1 pcode_PP1_18_InferPointerArgumentUnsignedChar(u1 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_PP1_19_InferPointerArgumentFloat(f4 * arg1)
|
||||
{
|
||||
return (-7) + (*arg1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_PP1_20_InferPointerArgumentDouble(f8 * arg1)
|
||||
{
|
||||
return (-7) + (*arg1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_PP1_1_InferArgumentLongLong(i8 * arg1)
|
||||
{
|
||||
return (-7) >> *arg1;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 pcode_PP1_2_InferArgumentInt(i4 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
|
||||
i2 pcode_PP1_3_InferArgumentShort(i2 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
|
||||
i1 pcode_PP1_4_InferArgumentChar(i1 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_PP1_5_InferArgumentUnsignedLongLong(u8 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 pcode_PP1_6_InferArgumentUnsignedInt(u4 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
|
||||
u2 pcode_PP1_7_InferArgumentUnsignedShort(u2 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
|
||||
u1 pcode_PP1_8_InferArgumentUnsignedChar(u1 arg1)
|
||||
{
|
||||
return (-7) >> arg1;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_PP1_9_InferArgumentFloat(f4 arg1)
|
||||
{
|
||||
return ((f4) - 7) + arg1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_PP1_10_InferArgumentDouble(f8 arg1)
|
||||
{
|
||||
return ((f8) - 7) + arg1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_PP1_11_InferPointerArgumentLongLong(i8 * arg1)
|
||||
{
|
||||
return (-7) >> (*arg1);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
@ -0,0 +1,52 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_PP2_1_OrderingIntShortChar_Main()
|
||||
{
|
||||
extern i4 pcode_PP2_1_OrderingIntShortChar(i4 i, i2 s, i1 c);
|
||||
ASSERTI4(pcode_PP2_1_OrderingIntShortChar(1, 2, 3), 1);
|
||||
ASSERTI4(pcode_PP2_1_OrderingIntShortChar(I4_MAX, I2_MAX, I1_MAX), -2147450754);
|
||||
ASSERTI4(pcode_PP2_1_OrderingIntShortChar(I4_MIN, I2_MIN, I1_MIN), -128);
|
||||
}
|
||||
|
||||
TEST pcode_PP2_2_OrderingShortIntChar_Main()
|
||||
{
|
||||
extern i4 pcode_PP2_2_OrderingShortIntChar(i2 s, i4 i, i1 c);
|
||||
ASSERTI4(pcode_PP2_2_OrderingShortIntChar(2, 1, 3), 1);
|
||||
ASSERTI4(pcode_PP2_2_OrderingShortIntChar(I2_MAX, I4_MAX, I1_MAX), -2147450754);
|
||||
ASSERTI4(pcode_PP2_2_OrderingShortIntChar(I2_MIN, I4_MIN, I1_MIN), -128);
|
||||
}
|
||||
|
||||
TEST pcode_PP2_3_OrderingIntCharShort_Main()
|
||||
{
|
||||
extern i4 pcode_PP2_3_OrderingIntCharShort(i4 i, i1 c, i2 s);
|
||||
ASSERTI4(pcode_PP2_3_OrderingIntCharShort(1, 3, 2), -1);
|
||||
ASSERTI4(pcode_PP2_3_OrderingIntCharShort(I4_MAX, I1_MAX, I2_MAX), -2147450754);
|
||||
ASSERTI4(pcode_PP2_3_OrderingIntCharShort(I4_MIN, I1_MIN, I2_MIN), -32768);
|
||||
}
|
||||
|
||||
TEST pcode_PP2_4_OrderingShortCharInt_Main()
|
||||
{
|
||||
extern i4 pcode_PP2_4_OrderingShortCharInt(i2 s, i1 c, i4 i);
|
||||
ASSERTI4(pcode_PP2_4_OrderingShortCharInt(2, 3, 1), -5);
|
||||
ASSERTI4(pcode_PP2_4_OrderingShortCharInt(I2_MAX, I1_MAX, I4_MAX), 2143322238);
|
||||
ASSERTI4(pcode_PP2_4_OrderingShortCharInt(I2_MIN, I1_MIN, I4_MIN), 2143289344);
|
||||
}
|
||||
|
||||
TEST pcode_PP2_5_OrderingCharShortInt_Main()
|
||||
{
|
||||
extern i4 pcode_PP2_5_OrderingCharShortInt(i1 c, i2 s, i4 i);
|
||||
ASSERTI4(pcode_PP2_5_OrderingCharShortInt(3, 2, 1), -5);
|
||||
ASSERTI4(pcode_PP2_5_OrderingCharShortInt(I1_MAX, I2_MAX, I4_MAX), 2143322238);
|
||||
ASSERTI4(pcode_PP2_5_OrderingCharShortInt(I1_MIN, I2_MIN, I4_MIN), 2143289344);
|
||||
}
|
||||
|
||||
TEST pcode_PP2_6_OrderingCharIntShort_Main()
|
||||
{
|
||||
extern i4 pcode_PP2_6_OrderingCharIntShort(i1 c, i4 i, i2 s);
|
||||
ASSERTI4(pcode_PP2_6_OrderingCharIntShort(3, 1, 2), -1);
|
||||
ASSERTI4(pcode_PP2_6_OrderingCharIntShort(I1_MAX, I4_MAX, I2_MAX), -2147450754);
|
||||
ASSERTI4(pcode_PP2_6_OrderingCharIntShort(I1_MIN, I4_MIN, I2_MIN), -32768);
|
||||
}
|
||||
|
||||
MAIN ParameterPassing2_main() { }
|
||||
|
@ -0,0 +1,48 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#define PARAMS(typ,a,b,c) (( (-((typ) (a))) * ((typ) (b)) ) + ((typ) (c)))
|
||||
|
||||
i4 pcode_PP2_1_OrderingIntShortChar(i4 i, i2 s, i1 c)
|
||||
{
|
||||
return PARAMS(i4, i, s, c);
|
||||
}
|
||||
|
||||
i4 pcode_PP2_2_OrderingShortIntChar(i2 s, i4 i, i1 c)
|
||||
{
|
||||
return PARAMS(i4, s, i, c);
|
||||
}
|
||||
|
||||
i4 pcode_PP2_3_OrderingIntCharShort(i4 i, i1 c, i2 s)
|
||||
{
|
||||
return PARAMS(i4, i, c, s);
|
||||
}
|
||||
|
||||
i4 pcode_PP2_4_OrderingShortCharInt(i2 s, i1 c, i4 i)
|
||||
{
|
||||
return PARAMS(i4, s, c, i);
|
||||
}
|
||||
|
||||
i4 pcode_PP2_5_OrderingCharShortInt(i1 c, i2 s, i4 i)
|
||||
{
|
||||
return PARAMS(i4, c, s, i);
|
||||
}
|
||||
|
||||
i4 pcode_PP2_6_OrderingCharIntShort(i1 c, i4 i, i2 s)
|
||||
{
|
||||
return PARAMS(i4, c, i, s);
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
#include "pcode_test.h"
|
||||
|
||||
TEST pcode_PP3_5thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_5thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5);
|
||||
ASSERTI4(pcode_PP3_5thMultipleArg(1, 2, 3, 4, 5), 61);
|
||||
ASSERTI4(pcode_PP3_5thMultipleArg(1000, 2000, 3000, 4000, 5000), 55006);
|
||||
ASSERTI4(pcode_PP3_5thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000), 55000006);
|
||||
ASSERTI4(pcode_PP3_5thMultipleArg(-1, -2, -3, -4, -5), -49);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_6thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_6thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6);
|
||||
ASSERTI4(pcode_PP3_6thMultipleArg(1, 2, 3, 4, 5, 6), 98);
|
||||
ASSERTI4(pcode_PP3_6thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000), 91007);
|
||||
ASSERTI4(pcode_PP3_6thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000), 91000007);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_7thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_7thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7);
|
||||
ASSERTI4(pcode_PP3_7thMultipleArg(1, 2, 3, 4, 5, 6, 7), 148);
|
||||
ASSERTI4(pcode_PP3_7thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000), 140008);
|
||||
ASSERTI4(pcode_PP3_7thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000), 140000008);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_8thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_8thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8);
|
||||
ASSERTI4(pcode_PP3_8thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8), 213);
|
||||
ASSERTI4(pcode_PP3_8thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000), 204009);
|
||||
ASSERTI4(pcode_PP3_8thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000), 204000009);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_9thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_9thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9);
|
||||
ASSERTI4(pcode_PP3_9thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9), 295);
|
||||
ASSERTI4(pcode_PP3_9thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000), 285010);
|
||||
ASSERTI4(pcode_PP3_9thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000), 285000010);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_10thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_10thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10);
|
||||
ASSERTI4(pcode_PP3_10thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 396);
|
||||
ASSERTI4(pcode_PP3_10thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000), 385011);
|
||||
ASSERTI4(pcode_PP3_10thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000), 385000011);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_11thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_11thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11);
|
||||
ASSERTI4(pcode_PP3_11thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), 518);
|
||||
ASSERTI4(pcode_PP3_11thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000), 506012);
|
||||
ASSERTI4(pcode_PP3_11thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000), 506000012);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_12thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_12thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12);
|
||||
ASSERTI4(pcode_PP3_12thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), 663);
|
||||
ASSERTI4(pcode_PP3_12thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000), 650013);
|
||||
ASSERTI4(pcode_PP3_12thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000), 650000013);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_13thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_13thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13);
|
||||
ASSERTI4(pcode_PP3_13thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1), 677);
|
||||
ASSERTI4(pcode_PP3_13thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 1000), 663014);
|
||||
ASSERTI4(pcode_PP3_13thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 1000000), 663000014);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_14thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_14thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14);
|
||||
ASSERTI4(pcode_PP3_14thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2), 706);
|
||||
ASSERTI4(pcode_PP3_14thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 1000, 2000), 691015);
|
||||
ASSERTI4(pcode_PP3_14thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 1000000, 2000000), 691000015);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_15thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_15thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15);
|
||||
ASSERTI4(pcode_PP3_15thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 1), 722);
|
||||
ASSERTI4(pcode_PP3_15thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 1000, 2000, 1000), 706016);
|
||||
ASSERTI4(pcode_PP3_15thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 1000000, 2000000, 1000000), 706000016);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_16thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_16thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16);
|
||||
ASSERTI4(pcode_PP3_16thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1), 725);
|
||||
ASSERTI4(pcode_PP3_16thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 1000, 1000, 1000, 1000), 708017);
|
||||
ASSERTI4(pcode_PP3_16thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 1000000, 1000000, 1000000, 1000000), 708000017);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_17thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_17thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17);
|
||||
ASSERTI4(pcode_PP3_17thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1, 1), 743);
|
||||
ASSERTI4(pcode_PP3_17thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 1000, 1000, 1000, 1000, 1000), 725018);
|
||||
ASSERTI4(pcode_PP3_17thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 1000000, 1000000, 1000000, 1000000, 1000000), 725000018);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_18thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_18thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17, i4 arg18);
|
||||
ASSERTI4(pcode_PP3_18thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 1, 1, 1, 1, 1), 762);
|
||||
ASSERTI4(pcode_PP3_18thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 1000, 1000, 1000, 1000, 1000, 1000), 743019);
|
||||
ASSERTI4(pcode_PP3_18thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000), 743000019);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_19thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_19thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17, i4 arg18, i4 arg19);
|
||||
ASSERTI4(pcode_PP3_19thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1), 938);
|
||||
ASSERTI4(pcode_PP3_19thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 1000, 1000, 1000, 1000, 1000, 1000), 918020);
|
||||
ASSERTI4(pcode_PP3_19thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 13000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000), 918000020);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_20thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_20thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17, i4 arg18, i4 arg19, i4 arg20);
|
||||
ASSERTI4(pcode_PP3_20thMultipleArg(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1), 959);
|
||||
ASSERTI4(pcode_PP3_20thMultipleArg(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 1000, 1000, 1000, 1000, 1000, 1000, 1000), 938021);
|
||||
ASSERTI4(pcode_PP3_20thMultipleArg(1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000, 10000000, 11000000, 12000000, 13000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000, 1000000), 938000021);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_0thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_0thMultipleArg();
|
||||
ASSERTI4(pcode_PP3_0thMultipleArg(), 1);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_1stMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_1stMultipleArg(i4 arg1);
|
||||
ASSERTI4(pcode_PP3_1stMultipleArg(1), 3);
|
||||
ASSERTI4(pcode_PP3_1stMultipleArg(I4_MAX), -2147483647);
|
||||
ASSERTI4(pcode_PP3_1stMultipleArg(I4_MIN), -2147483646);
|
||||
ASSERTI4(pcode_PP3_1stMultipleArg(0), 2);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_2ndMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_2ndMultipleArg(i4 arg1, i4 arg2);
|
||||
ASSERTI4(pcode_PP3_2ndMultipleArg(1, 2), 8);
|
||||
ASSERTI4(pcode_PP3_2ndMultipleArg(I4_MAX, I4_MIN), -2147483646);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_3rdMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_3rdMultipleArg(i4 arg1, i4 arg2, i4 arg3);
|
||||
ASSERTI4(pcode_PP3_3rdMultipleArg(1, 2, 3), 18);
|
||||
ASSERTI4(pcode_PP3_3rdMultipleArg(I4_MAX, 2, 3), -2147483632);
|
||||
ASSERTI4(pcode_PP3_3rdMultipleArg(1, I4_MAX, 3), 12);
|
||||
ASSERTI4(pcode_PP3_3rdMultipleArg(1, I4_MAX, I4_MAX), -2147483648);
|
||||
}
|
||||
|
||||
TEST pcode_PP3_4thMultipleArg_Main()
|
||||
{
|
||||
extern i4 pcode_PP3_4thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4);
|
||||
ASSERTI4(pcode_PP3_4thMultipleArg(1, 2, 3, 4), 35);
|
||||
ASSERTI4(pcode_PP3_4thMultipleArg(I4_MAX, 2, 3, 4), -2147483615);
|
||||
ASSERTI4(pcode_PP3_4thMultipleArg(1, I4_MAX, 3, 4), 29);
|
||||
ASSERTI4(pcode_PP3_4thMultipleArg(1, 2, I4_MAX, 4), -2147483625);
|
||||
ASSERTI4(pcode_PP3_4thMultipleArg(1, 2, 3, I4_MAX), 15);
|
||||
}
|
||||
|
||||
MAIN ParameterPassing3_main() { }
|
@ -0,0 +1,122 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
i4 pcode_PP3_5thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5)
|
||||
{
|
||||
return 6 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_6thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6)
|
||||
{
|
||||
return 7 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_7thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7)
|
||||
{
|
||||
return 8 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_8thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8)
|
||||
{
|
||||
return 9 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_9thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9)
|
||||
{
|
||||
return 10 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_10thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10)
|
||||
{
|
||||
return 11 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_11thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11)
|
||||
{
|
||||
return 12 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_12thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12)
|
||||
{
|
||||
return 13 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_13thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13)
|
||||
{
|
||||
return 14 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_14thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14)
|
||||
{
|
||||
return 15 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_15thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15)
|
||||
{
|
||||
return 16 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14 + arg15 * 15;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_16thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16)
|
||||
{
|
||||
return 17 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14 + arg15 * 15 + arg16 * 16;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_17thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17)
|
||||
{
|
||||
return 18 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14 + arg15 * 15 + arg16 * 16 + arg17 * 17;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_18thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17, i4 arg18)
|
||||
{
|
||||
return 19 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14 + arg15 * 15 + arg16 * 16 + arg17 * 17 + arg18 * 18;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_19thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17, i4 arg18, i4 arg19)
|
||||
{
|
||||
return 20 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14 + arg15 * 15 + arg16 * 16 + arg17 * 17 + arg18 * 18 + arg19 * 19;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_20thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4, i4 arg5, i4 arg6, i4 arg7, i4 arg8, i4 arg9, i4 arg10, i4 arg11, i4 arg12, i4 arg13, i4 arg14, i4 arg15, i4 arg16, i4 arg17, i4 arg18, i4 arg19, i4 arg20)
|
||||
{
|
||||
return 21 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4 + arg5 * 5 + arg6 * 6 + arg7 * 7 + arg8 * 8 + arg9 * 9 + arg10 * 10 + arg11 * 11 + arg12 * 12 + arg13 * 13 + arg14 * 14 + arg15 * 15 + arg16 * 16 + arg17 * 17 + arg18 * 18 + arg19 * 19 +
|
||||
arg20 * 20;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_0thMultipleArg()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_1stMultipleArg(i4 arg1)
|
||||
{
|
||||
return 2 + arg1 * 1;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_2ndMultipleArg(i4 arg1, i4 arg2)
|
||||
{
|
||||
return 3 + arg1 * 1 + arg2 * 2;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_3rdMultipleArg(i4 arg1, i4 arg2, i4 arg3)
|
||||
{
|
||||
return 4 + arg1 * 1 + arg2 * 2 + arg3 * 3;
|
||||
}
|
||||
|
||||
i4 pcode_PP3_4thMultipleArg(i4 arg1, i4 arg2, i4 arg3, i4 arg4)
|
||||
{
|
||||
return 5 + arg1 * 1 + arg2 * 2 + arg3 * 3 + arg4 * 4;
|
||||
}
|
@ -0,0 +1,400 @@
|
||||
#include "pcode_test.h"
|
||||
#include "big_struct.h"
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_P30_GetDecrementedDouble_Main()
|
||||
{
|
||||
extern f8 pcode_P30_GetDecrementedDouble(f8 * ptr);
|
||||
f8 arg[2] = { 3.14, 1.18 };
|
||||
f8 *argPtr = &arg[1];
|
||||
ASSERTF8(pcode_P30_GetDecrementedDouble(argPtr), 3.14);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P58_UnionGetAddressOfUnsignedChar_Main()
|
||||
{
|
||||
extern u1 *pcode_P58_UnionGetAddressOfUnsignedChar(big_union_type *ptr, i4 index);
|
||||
big_union_type testUnion[1] = {0};
|
||||
ASSERTU1(* (u1 *) pcode_P58_UnionGetAddressOfUnsignedChar(testUnion, 0), 0);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_P9_GetAddressOfFloat_Main()
|
||||
{
|
||||
extern f4 *pcode_P9_GetAddressOfFloat(f4 *ptr, i4 index);
|
||||
f4 array[] = { 1, 2, 3, 4, 5 };
|
||||
ASSERTF4(*pcode_P9_GetAddressOfFloat(array, 3), 4.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_P59_UnionGetAddressOfFloat_Main()
|
||||
{
|
||||
extern f4 *pcode_P59_UnionGetAddressOfFloat(big_union_type *ptr, i4 index);
|
||||
big_union_type testUnion[1] = {0};
|
||||
f4 *ret = pcode_P59_UnionGetAddressOfFloat(testUnion, 0);
|
||||
ASSERTF4(*ret, 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_P10_GetAddressOfDouble_Main()
|
||||
{
|
||||
extern f8 *pcode_P10_GetAddressOfDouble(f8 * ptr, i4 index);
|
||||
f8 array[] = { 1, 2, 3, 4, 5 };
|
||||
f8 *ret;
|
||||
ret = pcode_P10_GetAddressOfDouble(array, 3);
|
||||
ASSERTF8(*ret, 4.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P32_ModifyContentsOfInt_Main()
|
||||
{
|
||||
extern i4 pcode_P32_ModifyContentsOfInt(i4 * ptr, i4 index, i4 value);
|
||||
i4 array[] = { 1, 2, 3, 4, 5 };
|
||||
i4 ret;
|
||||
ret = pcode_P32_ModifyContentsOfInt (array, 3, 5);
|
||||
ASSERTI4(ret, 5);
|
||||
}
|
||||
|
||||
TEST pcode_P33_ModifyContentsOfShort_Main()
|
||||
{
|
||||
extern i2 pcode_P33_ModifyContentsOfShort(i2 * ptr, i4 index, i2 value);
|
||||
i2 array[] = { 1, 2, 3, 4, 5 };
|
||||
i2 ret;
|
||||
ret = pcode_P33_ModifyContentsOfShort(array, 3, 5);
|
||||
ASSERTI2(ret, 5);
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_P60_UnionGetAddressOfDouble_Main()
|
||||
{
|
||||
extern f8 *pcode_P60_UnionGetAddressOfDouble(big_union_type *ptr, i4 index);
|
||||
big_union_type testUnion[5] = {0};
|
||||
f8 *ret = pcode_P60_UnionGetAddressOfDouble(testUnion, 3);
|
||||
ASSERTF8(*ret, 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P11_GetIncrementedLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_P11_GetIncrementedLongLong(i8 * ptr);
|
||||
i8 array[] = { 1, 2, 3, 4, 5 };
|
||||
i8 ret;
|
||||
ret = pcode_P11_GetIncrementedLongLong(array + 2);
|
||||
ASSERTI8 (ret, 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P34_ModifyContentsOfChar_Main()
|
||||
{
|
||||
extern i1 pcode_P34_ModifyContentsOfChar(i1 * ptr, i4 index, i1 value);
|
||||
i1 array[] = { 1, 2, 3, 4, 5 };
|
||||
i1 ret;
|
||||
ret = pcode_P34_ModifyContentsOfChar(array, 3, 5);
|
||||
ASSERTI1(ret, 5);
|
||||
}
|
||||
|
||||
TEST pcode_P12_GetIncrementedInt_Main()
|
||||
{
|
||||
extern i4 pcode_P12_GetIncrementedInt(i4 * ptr);
|
||||
i4 array[] = { 1, 2, 3, 4, 5 };
|
||||
i4 ret;
|
||||
ret = pcode_P12_GetIncrementedInt(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
|
||||
TEST pcode_P13_GetIncrementedShort_Main()
|
||||
{
|
||||
extern i2 pcode_P13_GetIncrementedShort(i2 * ptr);
|
||||
i2 array[] = { 1, 2, 3, 4, 5 };
|
||||
i2 ret;
|
||||
ret = pcode_P13_GetIncrementedShort(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
|
||||
TEST pcode_P36_ModifyContentsOfUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_P36_ModifyContentsOfUnsignedInt(u4 * ptr, i4 index, u4 value);
|
||||
u4 array[] = { 1, 2, 3, 4, 5 };
|
||||
u4 ret;
|
||||
ret = pcode_P36_ModifyContentsOfUnsignedInt(array, 3, 5);
|
||||
ASSERTU4(ret, 5);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P35_ModifyContentsOfUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_P35_ModifyContentsOfUnsignedLongLong(u8 * ptr, i4 index, u8 value);
|
||||
u8 array[] = { 1, 2, 3, 4, 5 };
|
||||
u8 ret;
|
||||
ret = pcode_P35_ModifyContentsOfUnsignedLongLong(array, 3, 5);
|
||||
ASSERTU8(ret, 5);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P14_GetIncrementedChar_Main()
|
||||
{
|
||||
extern i1 pcode_P14_GetIncrementedChar (i1 * ptr);
|
||||
i1 array[] = { 1, 2, 3, 4, 5 };
|
||||
i1 ret;
|
||||
ret = pcode_P14_GetIncrementedChar(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
|
||||
TEST pcode_P37_ModifyContentsOfUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_P37_ModifyContentsOfUnsignedShort(u2 * ptr, i4 index, u2 value);
|
||||
u2 array[] = { 1, 2, 3, 4, 5 };
|
||||
u2 ret;
|
||||
ret = pcode_P37_ModifyContentsOfUnsignedShort(array, 3, 5);
|
||||
ASSERTU2(ret, 5);
|
||||
}
|
||||
|
||||
TEST pcode_P38_ModifyContentsOfUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_P38_ModifyContentsOfUnsignedChar(u1 * ptr, i4 index, u1 value);
|
||||
u1 array[] = { 1, 2, 3, 4, 5 };
|
||||
u1 ret;
|
||||
ret = pcode_P38_ModifyContentsOfUnsignedChar(array, 3, 5);
|
||||
ASSERTU1(ret, 5);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P15_GetIncrementedUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_P15_GetIncrementedUnsignedLongLong(u8 * ptr);
|
||||
u8 array[] = { 1, 2, 3, 4, 5 };
|
||||
u8 ret;
|
||||
ret = pcode_P15_GetIncrementedUnsignedLongLong(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_P39_ModifyContentsOfFloat_Main()
|
||||
{
|
||||
extern f4 pcode_P39_ModifyContentsOfFloat(f4 * ptr, i4 index, f4 value);
|
||||
f4 array[] = { 1, 2, 3, 4, 5 };
|
||||
f4 ret;
|
||||
ret = pcode_P39_ModifyContentsOfFloat(array, 3, 5.0);
|
||||
ASSERTF4(ret, 5.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P17_GetIncrementedUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_P17_GetIncrementedUnsignedShort(u2 * ptr);
|
||||
u2 array[] = { 1, 2, 3, 4, 5 };
|
||||
u2 ret;
|
||||
ret = pcode_P17_GetIncrementedUnsignedShort(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
|
||||
TEST pcode_P16_GetIncrementedUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_P16_GetIncrementedUnsignedInt(u4 * ptr);
|
||||
u4 array[] = { 1, 2, 3, 4, 5 };
|
||||
u4 ret;
|
||||
ret = pcode_P16_GetIncrementedUnsignedInt(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
|
||||
TEST pcode_P18_GetIncrementedUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_P18_GetIncrementedUnsignedChar(u1 * ptr);
|
||||
u1 array[] = { 1, 2, 3, 4, 5 };
|
||||
u1 ret;
|
||||
ret = pcode_P18_GetIncrementedUnsignedChar(array);
|
||||
ASSERTI4(ret, 2);
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_P40_ModifyContentsOfDouble_Main()
|
||||
{
|
||||
extern f8 pcode_P40_ModifyContentsOfDouble(f8 * ptr, i4 index, f8 value);
|
||||
f8 array[] = { 1, 2, 3, 4, 5 };
|
||||
f8 ret;
|
||||
ret = pcode_P40_ModifyContentsOfDouble(array, 3, 5.0);
|
||||
ASSERTF8(ret, 5.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P41_StructGetAddressOfLongLong_Main()
|
||||
{
|
||||
extern i8 *pcode_P41_StructGetAddressOfLongLong(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
i8 *ret;
|
||||
ret = pcode_P41_StructGetAddressOfLongLong(bst, 3);
|
||||
ASSERTI8(*ret, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_P19_GetIncrementedFloat_Main()
|
||||
{
|
||||
extern f4 pcode_P19_GetIncrementedFloat(f4 * ptr);
|
||||
f4 array[] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||
f4 ret;
|
||||
ret = pcode_P19_GetIncrementedFloat((f4 *) array);
|
||||
ASSERTF4(ret, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P42_StructGetAddressOfInt_Main()
|
||||
{
|
||||
extern i4 *pcode_P42_StructGetAddressOfInt(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
i4 *ret;
|
||||
ret= pcode_P42_StructGetAddressOfInt(bst, 3);
|
||||
ASSERTI4(*ret, 0);
|
||||
}
|
||||
|
||||
TEST pcode_P43_StructGetAddressOfShort_Main()
|
||||
{
|
||||
extern i2 *pcode_P43_StructGetAddressOfShort(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
i2 *ret;
|
||||
ret = pcode_P43_StructGetAddressOfShort(bst, 3);
|
||||
ASSERTI4(*ret, 0);
|
||||
}
|
||||
|
||||
TEST pcode_P44_StructGetAddressOfChar_Main()
|
||||
{
|
||||
extern i1 *pcode_P44_StructGetAddressOfChar(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
i1 *ret;
|
||||
ret = pcode_P44_StructGetAddressOfChar(bst, 3);
|
||||
ASSERTI1(*ret, 0);
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_P20_GetIncrementedDouble_Main()
|
||||
{
|
||||
extern f8 pcode_P20_GetIncrementedDouble(f8 * ptr);
|
||||
f8 array[] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||
f8 ret;
|
||||
ret = pcode_P20_GetIncrementedDouble((f8 *) array);
|
||||
ASSERTF8(ret, 2.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P45_StructGetAddressOfUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 *pcode_P45_StructGetAddressOfUnsignedLongLong(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
u8 *ret;
|
||||
ret = pcode_P45_StructGetAddressOfUnsignedLongLong(bst, 3);
|
||||
ASSERTU8(*ret, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P21_GetDecrementedLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_P21_GetDecrementedLongLong(i8 * ptr);
|
||||
i8 val[] = {100, 200, 300};
|
||||
i8 ret;
|
||||
ret = pcode_P21_GetDecrementedLongLong(&val[1]);
|
||||
ASSERTI8(ret, 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P47_StructGetAddressOfUnsignedShort_Main()
|
||||
{
|
||||
extern u2 *pcode_P47_StructGetAddressOfUnsignedShort(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
u2 *ret;
|
||||
ret = pcode_P47_StructGetAddressOfUnsignedShort(bst, 3);
|
||||
ASSERTU2(*ret, 0);
|
||||
}
|
||||
|
||||
TEST pcode_P46_StructGetAddressOfUnsignedInt_Main()
|
||||
{
|
||||
extern u4 *pcode_P46_StructGetAddressOfUnsignedInt(big_struct_type *ptr, i4 index);
|
||||
big_struct_type bst[5] = {0};
|
||||
u4 *ret;
|
||||
ret = pcode_P46_StructGetAddressOfUnsignedInt(bst, 3);
|
||||
ASSERTU2(*ret, 0);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P1_GetAddressOfLongLong_Main()
|
||||
{
|
||||
extern i8 *pcode_P1_GetAddressOfLongLong(i8 * ptr, i4 index);
|
||||
i8 array[] = { 1, 2, 3, 4, 5 };
|
||||
i8 *ret;
|
||||
ret = pcode_P1_GetAddressOfLongLong(array, 3);
|
||||
ASSERTI8(*ret, 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P2_GetAddressOfInt_Main()
|
||||
{
|
||||
extern i4 *pcode_P2_GetAddressOfInt(i4 * ptr, i4 index);
|
||||
i4 array[] = { 1, 2, 3, 4, 5 };
|
||||
i4 *ret;
|
||||
ret = pcode_P2_GetAddressOfInt(array, 3);
|
||||
ASSERTI4(*ret, 4);
|
||||
}
|
||||
|
||||
TEST pcode_P3_GetAddressOfShort_Main()
|
||||
{
|
||||
extern i2 *pcode_P3_GetAddressOfShort(i2 * ptr, i4 index);
|
||||
i2 array[] = { 1, 2, 3, 4, 5 };
|
||||
i2 *ret;
|
||||
ret = pcode_P3_GetAddressOfShort(array, 3);
|
||||
ASSERTI2(*ret, 4);
|
||||
}
|
||||
|
||||
TEST pcode_P4_GetAddressOfChar_Main()
|
||||
{
|
||||
extern i1 *pcode_P4_GetAddressOfChar(i1 * ptr, i4 index);
|
||||
i1 array[] = { 1, 2, 3, 4, 5 };
|
||||
i1 *ret;
|
||||
ret = pcode_P4_GetAddressOfChar(array, 3);
|
||||
ASSERTI1(*ret, 4);
|
||||
}
|
||||
|
||||
TEST pcode_P6_GetAddressOfUnsignedInt_Main()
|
||||
{
|
||||
extern u4 *pcode_P6_GetAddressOfUnsignedInt(u4 * ptr, i4 index);
|
||||
u4 array[] = { 1, 2, 3, 4, 5 };
|
||||
u4 *ret;
|
||||
ret = pcode_P6_GetAddressOfUnsignedInt(array, 3);
|
||||
ASSERTU4(*ret, 4);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_P5_GetAddressOfUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 *pcode_P5_GetAddressOfUnsignedLongLong(u8 * ptr, i4 index);
|
||||
u8 array[] = { 1, 2, 3, 4, 5 };
|
||||
u8 *ret;
|
||||
ret = pcode_P5_GetAddressOfUnsignedLongLong(array, 3);
|
||||
ASSERTU8(*ret, 4);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_P7_GetAddressOfUnsignedShort_Main()
|
||||
{
|
||||
extern u2 *pcode_P7_GetAddressOfUnsignedShort(u2 * ptr, i4 index);
|
||||
u2 array[] = { 1, 2, 3, 4, 5 };
|
||||
u2 *ret;
|
||||
ret = pcode_P7_GetAddressOfUnsignedShort(array, 3);
|
||||
ASSERTU2(*ret, 4);
|
||||
}
|
||||
|
||||
TEST pcode_P8_GetAddressOfUnsignedChar_Main()
|
||||
{
|
||||
extern u1 *pcode_P8_GetAddressOfUnsignedChar(u1 * ptr, i4 index);
|
||||
u1 array[] = { 1, 2, 3, 4, 5 };
|
||||
u1 *ret;
|
||||
ret = pcode_P8_GetAddressOfUnsignedChar(array, 3);
|
||||
ASSERTU1(*ret, 4);
|
||||
}
|
||||
|
||||
MAIN PointerManipulation_main() { }
|
@ -0,0 +1,442 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
#include "big_struct.h"
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_P30_GetDecrementedDouble(f8 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
u1 *pcode_P58_UnionGetAddressOfUnsignedChar(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (u1 *) & (*(ptr + index)).uc;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 *pcode_P9_GetAddressOfFloat(f4 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 *pcode_P59_UnionGetAddressOfFloat(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (f4 *) & (*(ptr + index)).f;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 *pcode_P10_GetAddressOfDouble(f8 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void pcode_P31_ModifyContentsOfLongLong(i8 * ptr, i4 index, i8 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 pcode_P32_ModifyContentsOfInt(i4 * ptr, i4 index, i4 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
|
||||
i2 pcode_P33_ModifyContentsOfShort(i2 * ptr, i4 index, i2 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 *pcode_P60_UnionGetAddressOfDouble(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (f8 *) & (*(ptr + index)).d;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_P11_GetIncrementedLongLong(i8 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i1 pcode_P34_ModifyContentsOfChar(i1 * ptr, i4 index, i1 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
|
||||
i4 pcode_P12_GetIncrementedInt(i4 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
i2 pcode_P13_GetIncrementedShort(i2 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
u4 pcode_P36_ModifyContentsOfUnsignedInt(u4 * ptr, i4 index, u4 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_P35_ModifyContentsOfUnsignedLongLong(u8 * ptr, i4 index, u8 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i1 pcode_P14_GetIncrementedChar(i1 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
u2 pcode_P37_ModifyContentsOfUnsignedShort(u2 * ptr, i4 index, u2 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 *pcode_P61_GetIndexOfLongLong(i8 * base_ptr, i8 * el_ptr)
|
||||
{
|
||||
return (i8 *) (el_ptr - base_ptr);
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u1 pcode_P38_ModifyContentsOfUnsignedChar(u1 * ptr, i4 index, u1 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_P15_GetIncrementedUnsignedLongLong(u8 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_P39_ModifyContentsOfFloat(f4 * ptr, i4 index, f4 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
i4 pcode_P63_GetIndexOfShort(i2 * base_ptr, i2 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
|
||||
i4 pcode_P62_GetIndexOfInt(i4 * base_ptr, i4 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
|
||||
u2 pcode_P17_GetIncrementedUnsignedShort(u2 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
u4 pcode_P16_GetIncrementedUnsignedInt(u4 * ptr)
|
||||
{
|
||||
++ptr;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
i4 pcode_P64_GetIndexOfChar(i1 * base_ptr, i1 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
|
||||
u1 pcode_P18_GetIncrementedUnsignedChar(u1 * ptr)
|
||||
{
|
||||
++ptr;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_P40_ModifyContentsOfDouble(f8 * ptr, i4 index, f8 value)
|
||||
{
|
||||
*(ptr + index) = value;
|
||||
return *(ptr + index);
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 *pcode_P41_StructGetAddressOfLongLong(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (i8 *) & (*(ptr + index)).ll;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i4 pcode_P65_GetIndexOfUnsignedLongLong(u8 * base_ptr, u8 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_P19_GetIncrementedFloat(f4 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
i4 *pcode_P42_StructGetAddressOfInt(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (i4 *) & (*(ptr + index)).i;
|
||||
}
|
||||
|
||||
i2 *pcode_P43_StructGetAddressOfShort(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (i2 *) & (*(ptr + index)).s;
|
||||
}
|
||||
|
||||
i4 pcode_P66_GetIndexOfUnsignedInt(u4 * base_ptr, u4 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
|
||||
i1 *pcode_P44_StructGetAddressOfChar(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (i1 *) & (*(ptr + index)).c;
|
||||
}
|
||||
|
||||
i4 pcode_P67_GetIndexOfUnsignedShort(u2 * base_ptr, u2 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_P20_GetIncrementedDouble(f8 * ptr)
|
||||
{
|
||||
ptr++;
|
||||
return *ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
i4 pcode_P68_GetIndexOfUnsignedChar(u1 * base_ptr, u1 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 *pcode_P45_StructGetAddressOfUnsignedLongLong(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (u8 *) & (*(ptr + index)).ull;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
i4 pcode_P69_GetIndexOfFloat(f4 * base_ptr, f4 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_P21_GetDecrementedLongLong(i8 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u2 *pcode_P47_StructGetAddressOfUnsignedShort(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (u2 *) & (*(ptr + index)).us;
|
||||
}
|
||||
|
||||
u4 *pcode_P46_StructGetAddressOfUnsignedInt(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (u4 *) & (*(ptr + index)).ui;
|
||||
}
|
||||
|
||||
i4 pcode_P22_GetDecrementedInt(i4 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
|
||||
u1 *pcode_P48_StructGetAddressOfUnsignedChar(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (u1 *) & (*(ptr + index)).uc;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
i4 pcode_P70_GetIndexOfDouble(f8 * base_ptr, f8 * el_ptr)
|
||||
{
|
||||
return el_ptr - base_ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
i2 pcode_P23_GetDecrementedShort(i2 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 *pcode_P51_UnionGetAddressOfLongLong(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (i8 *) & (*(ptr + index)).ll;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i1 pcode_P24_GetDecrementedChar(i1 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 *pcode_P1_GetAddressOfLongLong(i8 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 *pcode_P49_StructGetAddressOfFloat(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (f4 *) & (*(ptr + index)).f;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
i4 *pcode_P2_GetAddressOfInt(i4 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_P25_GetDecrementedUnsignedLongLong(u8 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 *pcode_P52_UnionGetAddressOfInt(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (i4 *) & (*(ptr + index)).i;
|
||||
}
|
||||
|
||||
i2 *pcode_P3_GetAddressOfShort(i2 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
|
||||
u4 pcode_P26_GetDecrementedUnsignedInt(u4 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
|
||||
i2 *pcode_P53_UnionGetAddressOfShort(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (i2 *) & (*(ptr + index)).s;
|
||||
}
|
||||
|
||||
i1 *pcode_P4_GetAddressOfChar(i1 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
|
||||
u2 pcode_P27_GetDecrementedUnsignedShort(u2 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
|
||||
i1 *pcode_P54_UnionGetAddressOfChar(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (i1 *) & (*(ptr + index)).c;
|
||||
}
|
||||
|
||||
u1 pcode_P28_GetDecrementedUnsignedChar(u1 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 *pcode_P50_StructGetAddressOfDouble(big_struct_type *ptr, i4 index)
|
||||
{
|
||||
return (f8 *) & (*(ptr + index)).d;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 *pcode_P55_UnionGetAddressOfUnsignedLongLong(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (u8 *) & (*(ptr + index)).ull;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u4 *pcode_P6_GetAddressOfUnsignedInt(u4 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 *pcode_P5_GetAddressOfUnsignedLongLong(u8 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u2 *pcode_P7_GetAddressOfUnsignedShort(u2 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_P29_GetDecrementedFloat(f4 * ptr)
|
||||
{
|
||||
return *--ptr;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
u1 *pcode_P8_GetAddressOfUnsignedChar(u1 * ptr, i4 index)
|
||||
{
|
||||
return ptr + index;
|
||||
}
|
||||
|
||||
u4 *pcode_P56_UnionGetAddressOfUnsignedInt(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (u4 *) & (*(ptr + index)).ui;
|
||||
}
|
||||
|
||||
u2 *pcode_P57_UnionGetAddressOfUnsignedShort(big_union_type *ptr, i4 index)
|
||||
{
|
||||
return (u2 *) & (*(ptr + index)).us;
|
||||
}
|
@ -0,0 +1,339 @@
|
||||
#include "pcode_test.h"
|
||||
#include "big_struct.h"
|
||||
|
||||
extern void bs_init(big_struct_type *);
|
||||
|
||||
TEST pcode_SUM28_BigStructPtrAccessUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_SUM28_BigStructPtrAccessUnsignedInt(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU4(pcode_SUM28_BigStructPtrAccessUnsignedInt(&bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM29_BigStructPtrAccessUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_SUM29_BigStructPtrAccessUnsignedShort(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU2(pcode_SUM29_BigStructPtrAccessUnsignedShort(&bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM30_BigStructPtrAccessUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_SUM30_BigStructPtrAccessUnsignedChar(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU1(pcode_SUM30_BigStructPtrAccessUnsignedChar(&bs), 8);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_SUM31_BigStructPtrAccessFloat_Main()
|
||||
{
|
||||
extern f4 pcode_SUM31_BigStructPtrAccessFloat(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTF4(pcode_SUM31_BigStructPtrAccessFloat(&bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_SUM32_BigStructPtrAccessDouble_Main()
|
||||
{
|
||||
extern f8 pcode_SUM32_BigStructPtrAccessDouble(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTF8(pcode_SUM32_BigStructPtrAccessDouble(&bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM34_BigUnionPtrAccessLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_SUM34_BigUnionPtrAccessLongLong(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI8(pcode_SUM34_BigUnionPtrAccessLongLong(&bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM35_BigUnionPtrAccessInt_Main()
|
||||
{
|
||||
extern i4 pcode_SUM35_BigUnionPtrAccessInt(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI4(pcode_SUM35_BigUnionPtrAccessInt(&bu), 7);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM1_BigStructAccessLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_SUM1_BigStructAccessLongLong(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI8(pcode_SUM1_BigStructAccessLongLong(bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM36_BigUnionPtrAccessShort_Main()
|
||||
{
|
||||
extern i2 pcode_SUM36_BigUnionPtrAccessShort(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI2(pcode_SUM36_BigUnionPtrAccessShort(&bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM2_BigStructAccessInt_Main()
|
||||
{
|
||||
extern i4 pcode_SUM2_BigStructAccessInt(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI4(pcode_SUM2_BigStructAccessInt(bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM37_BigUnionPtrAccessChar_Main()
|
||||
{
|
||||
extern i1 pcode_SUM37_BigUnionPtrAccessChar(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI1(pcode_SUM37_BigUnionPtrAccessChar(&bu), 7);
|
||||
}
|
||||
|
||||
|
||||
TEST pcode_SUM3_BigStructAccessShort_Main()
|
||||
{
|
||||
extern i2 pcode_SUM3_BigStructAccessShort(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI2(pcode_SUM3_BigStructAccessShort(bs), 8);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM38_BigUnionPtrAccessUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_SUM38_BigUnionPtrAccessUnsignedLongLong(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU8(pcode_SUM38_BigUnionPtrAccessUnsignedLongLong(&bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM4_BigStructAccessChar_Main()
|
||||
{
|
||||
extern i1 pcode_SUM4_BigStructAccessChar(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI1(pcode_SUM4_BigStructAccessChar(bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM39_BigUnionPtrAccessUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_SUM39_BigUnionPtrAccessUnsignedInt(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU4(pcode_SUM39_BigUnionPtrAccessUnsignedInt(&bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM40_BigUnionPtrAccessUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_SUM40_BigUnionPtrAccessUnsignedShort(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU2(pcode_SUM40_BigUnionPtrAccessUnsignedShort(&bu), 7);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM5_BigStructAccessUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_SUM5_BigStructAccessUnsignedLongLong(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU8(pcode_SUM5_BigStructAccessUnsignedLongLong(bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM41_BigUnionPtrAccessUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_SUM41_BigUnionPtrAccessUnsignedChar(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU1(pcode_SUM41_BigUnionPtrAccessUnsignedChar(&bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM6_BigStructAccessUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_SUM6_BigStructAccessUnsignedInt(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU4(pcode_SUM6_BigStructAccessUnsignedInt(bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM8_BigStructAccessUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_SUM8_BigStructAccessUnsignedChar(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU1(pcode_SUM8_BigStructAccessUnsignedChar(bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM7_BigStructAccessUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_SUM7_BigStructAccessUnsignedShort(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU2(pcode_SUM7_BigStructAccessUnsignedShort(bs), 8);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_SUM42_BigUnionPtrAccessFloat_Main()
|
||||
{
|
||||
extern f4 pcode_SUM42_BigUnionPtrAccessFloat(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTF4(pcode_SUM42_BigUnionPtrAccessFloat(&bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_SUM43_BigUnionPtrAccessDouble_Main()
|
||||
{
|
||||
extern f8 pcode_SUM43_BigUnionPtrAccessDouble(big_union_type *arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTF8(pcode_SUM43_BigUnionPtrAccessDouble(&bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_SUM9_BigStructAccessFloat_Main()
|
||||
{
|
||||
extern f4 pcode_SUM9_BigStructAccessFloat(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTF4(pcode_SUM9_BigStructAccessFloat(bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_SUM10_BigStructAccessDouble_Main()
|
||||
{
|
||||
extern f8 pcode_SUM10_BigStructAccessDouble(big_struct_type arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTF8(pcode_SUM10_BigStructAccessDouble(bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM12_BigUnionAccessLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_SUM12_BigUnionAccessLongLong(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI8(pcode_SUM12_BigUnionAccessLongLong(bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM13_BigUnionAccessInt_Main()
|
||||
{
|
||||
extern i4 pcode_SUM13_BigUnionAccessInt(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI4(pcode_SUM13_BigUnionAccessInt(bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM14_BigUnionAccessShort_Main()
|
||||
{
|
||||
extern i2 pcode_SUM14_BigUnionAccessShort(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI2(pcode_SUM14_BigUnionAccessShort(bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM15_BigUnionAccessChar_Main()
|
||||
{
|
||||
extern i1 pcode_SUM15_BigUnionAccessChar(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTI1(pcode_SUM15_BigUnionAccessChar(bu), 7);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM16_BigUnionAccessUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_SUM16_BigUnionAccessUnsignedLongLong(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU8(pcode_SUM16_BigUnionAccessUnsignedLongLong(bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM17_BigUnionAccessUnsignedInt_Main()
|
||||
{
|
||||
extern u4 pcode_SUM17_BigUnionAccessUnsignedInt(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU4(pcode_SUM17_BigUnionAccessUnsignedInt(bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM18_BigUnionAccessUnsignedShort_Main()
|
||||
{
|
||||
extern u2 pcode_SUM18_BigUnionAccessUnsignedShort(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU2(pcode_SUM18_BigUnionAccessUnsignedShort(bu), 7);
|
||||
}
|
||||
|
||||
TEST pcode_SUM19_BigUnionAccessUnsignedChar_Main()
|
||||
{
|
||||
extern u1 pcode_SUM19_BigUnionAccessUnsignedChar(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTU1(pcode_SUM19_BigUnionAccessUnsignedChar(bu), 7);
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
TEST pcode_SUM20_BigUnionAccessFloat_Main()
|
||||
{
|
||||
extern f4 pcode_SUM20_BigUnionAccessFloat(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTF4(pcode_SUM20_BigUnionAccessFloat(bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
TEST pcode_SUM21_BigUnionAccessDouble_Main()
|
||||
{
|
||||
extern f8 pcode_SUM21_BigUnionAccessDouble(big_union_type arg);
|
||||
big_union_type bu = { 0 };
|
||||
ASSERTF8(pcode_SUM21_BigUnionAccessDouble(bu), 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM23_BigStructPtrAccessLongLong_Main()
|
||||
{
|
||||
extern i8 pcode_SUM23_BigStructPtrAccessLongLong(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI8(pcode_SUM23_BigStructPtrAccessLongLong(&bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_SUM24_BigStructPtrAccessInt_Main()
|
||||
{
|
||||
extern i4 pcode_SUM24_BigStructPtrAccessInt(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI4(pcode_SUM24_BigStructPtrAccessInt(&bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM25_BigStructPtrAccessShort_Main()
|
||||
{
|
||||
extern i2 pcode_SUM25_BigStructPtrAccessShort(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI2(pcode_SUM25_BigStructPtrAccessShort(&bs), 8);
|
||||
}
|
||||
|
||||
TEST pcode_SUM26_BigStructPtrAccessChar_Main()
|
||||
{
|
||||
extern i1 pcode_SUM26_BigStructPtrAccessChar(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTI1(pcode_SUM26_BigStructPtrAccessChar(&bs), 8);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST pcode_SUM27_BigStructPtrAccessUnsignedLongLong_Main()
|
||||
{
|
||||
extern u8 pcode_SUM27_BigStructPtrAccessUnsignedLongLong(big_struct_type *arg);
|
||||
big_struct_type bs;
|
||||
bs_init(&bs);
|
||||
ASSERTU8(pcode_SUM27_BigStructPtrAccessUnsignedLongLong(&bs), 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
MAIN StructUnionManipulation_main() { }
|
@ -0,0 +1,675 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
#include "big_struct.h"
|
||||
|
||||
void bs_init(big_struct_type * bs)
|
||||
{
|
||||
#ifdef HAS_LONGLONG
|
||||
bs->ull = 1;
|
||||
bs->ll = 1;
|
||||
#endif
|
||||
bs->i = 1;
|
||||
bs->s = 1;
|
||||
bs->c = 1;
|
||||
bs->ui = 1;
|
||||
bs->us = 1;
|
||||
bs->uc = 1;
|
||||
#ifdef HAS_FLOAT
|
||||
bs->f = 1;
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
bs->d = 1;
|
||||
#endif
|
||||
bs->b = bs;
|
||||
}
|
||||
|
||||
u4 pcode_SUM28_BigStructPtrAccessUnsignedInt(big_struct_type *arg)
|
||||
{
|
||||
u4 local_var;
|
||||
|
||||
local_var = (u4) 7;
|
||||
return arg->ui + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
big_union_type pcode_SUM64_BigUnionModifyFloat(big_union_type arg, f4 field)
|
||||
{
|
||||
arg.f = field;
|
||||
return arg;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
u2 pcode_SUM29_BigStructPtrAccessUnsignedShort(big_struct_type *arg)
|
||||
{
|
||||
u2 local_var;
|
||||
|
||||
local_var = (u2) 7;
|
||||
return arg->us + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
big_union_type pcode_SUM65_BigUnionModifyDouble(big_union_type arg, f8 field)
|
||||
{
|
||||
arg.d = field;
|
||||
return arg;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
u1 pcode_SUM30_BigStructPtrAccessUnsignedChar(big_struct_type *arg)
|
||||
{
|
||||
u1 local_var;
|
||||
|
||||
local_var = (u1) 7;
|
||||
return arg->uc + local_var;
|
||||
}
|
||||
|
||||
big_union_type pcode_SUM66_BigUnionModifyBig_union_type_ptr(big_union_type arg, big_union_type *field)
|
||||
{
|
||||
arg.b = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_SUM31_BigStructPtrAccessFloat(big_struct_type *arg)
|
||||
{
|
||||
f4 local_var;
|
||||
|
||||
local_var = (f4) 7;
|
||||
return arg->f + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_SUM32_BigStructPtrAccessDouble(big_struct_type *arg)
|
||||
{
|
||||
f8 local_var;
|
||||
|
||||
local_var = (f8) 7;
|
||||
return arg->d + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void pcode_SUM67_BigStructPtrModifyLongLong(big_struct_type *arg, i8 field)
|
||||
{
|
||||
arg->ll = field;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
void pcode_SUM68_BigStructPtrModifyInt(big_struct_type *arg, i4 field)
|
||||
{
|
||||
arg->i = field;
|
||||
}
|
||||
|
||||
big_struct_type *pcode_SUM33_BigStructPtrAccessBig_struct_type_ptr(big_struct_type *arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg->b + local_var;
|
||||
}
|
||||
|
||||
void pcode_SUM69_BigStructPtrModifyShort(big_struct_type *arg, i2 field)
|
||||
{
|
||||
arg->s = field;
|
||||
}
|
||||
|
||||
void pcode_SUM81_BigUnionPtrModifyChar(big_union_type *arg, i1 field)
|
||||
{
|
||||
arg->c = field;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void pcode_SUM71_BigStructPtrModifyUnsignedLongLong(big_struct_type *arg, u8 field)
|
||||
{
|
||||
arg->ull = field;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
void pcode_SUM70_BigStructPtrModifyChar(big_struct_type *arg, i1 field)
|
||||
{
|
||||
arg->c = field;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_SUM34_BigUnionPtrAccessLongLong(big_union_type *arg)
|
||||
{
|
||||
i8 local_var;
|
||||
|
||||
local_var = (i8) 7;
|
||||
return arg->ll + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void pcode_SUM82_BigUnionPtrModifyUnsignedLongLong(big_union_type *arg, u8 field)
|
||||
{
|
||||
arg->ull = field;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
void pcode_SUM72_BigStructPtrModifyUnsignedInt(big_struct_type *arg, u4 field)
|
||||
{
|
||||
arg->ui = field;
|
||||
}
|
||||
|
||||
i4 pcode_SUM35_BigUnionPtrAccessInt(big_union_type *arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg->i + local_var;
|
||||
}
|
||||
|
||||
void pcode_SUM73_BigStructPtrModifyUnsignedShort(big_struct_type *arg, u2 field)
|
||||
{
|
||||
arg->us = field;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_SUM1_BigStructAccessLongLong(big_struct_type arg)
|
||||
{
|
||||
i8 local_var;
|
||||
|
||||
local_var = (i8) 7;
|
||||
return arg.ll + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i2 pcode_SUM36_BigUnionPtrAccessShort(big_union_type *arg)
|
||||
{
|
||||
i2 local_var;
|
||||
|
||||
local_var = (i2) 7;
|
||||
return arg->s + local_var;
|
||||
}
|
||||
|
||||
void pcode_SUM85_BigUnionPtrModifyUnsignedChar(big_union_type *arg, u1 field)
|
||||
{
|
||||
arg->uc = field;
|
||||
}
|
||||
|
||||
void pcode_SUM74_BigStructPtrModifyUnsignedChar(big_struct_type *arg, u1 field)
|
||||
{
|
||||
arg->uc = field;
|
||||
}
|
||||
|
||||
i4 pcode_SUM2_BigStructAccessInt(big_struct_type arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg.i + local_var;
|
||||
}
|
||||
|
||||
i1 pcode_SUM37_BigUnionPtrAccessChar(big_union_type *arg)
|
||||
{
|
||||
i1 local_var;
|
||||
|
||||
local_var = (i1) 7;
|
||||
return arg->c + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
void pcode_SUM86_BigUnionPtrModifyFloat(big_union_type *arg, f4 field)
|
||||
{
|
||||
arg->f = field;
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
void pcode_SUM75_BigStructPtrModifyFloat(big_struct_type *arg, f4 field)
|
||||
{
|
||||
arg->f = field;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
i2 pcode_SUM3_BigStructAccessShort(big_struct_type arg)
|
||||
{
|
||||
i2 local_var;
|
||||
|
||||
local_var = (i2) 7;
|
||||
return arg.s + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_SUM38_BigUnionPtrAccessUnsignedLongLong(big_union_type *arg)
|
||||
{
|
||||
u8 local_var;
|
||||
|
||||
local_var = (u8) 7;
|
||||
return arg->ull + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
void pcode_SUM87_BigUnionPtrModifyDouble(big_union_type *arg, f8 field)
|
||||
{
|
||||
arg->d = field;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
void pcode_SUM76_BigStructPtrModifyDouble(big_struct_type *arg, f8 field)
|
||||
{
|
||||
arg->d = field;
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
i1 pcode_SUM4_BigStructAccessChar(big_struct_type arg)
|
||||
{
|
||||
i1 local_var;
|
||||
|
||||
local_var = (i1) 7;
|
||||
return arg.c + local_var;
|
||||
}
|
||||
|
||||
u4 pcode_SUM39_BigUnionPtrAccessUnsignedInt(big_union_type *arg)
|
||||
{
|
||||
u4 local_var;
|
||||
|
||||
local_var = (u4) 7;
|
||||
return arg->ui + local_var;
|
||||
}
|
||||
|
||||
void pcode_SUM88_BigUnionPtrModifyBig_union_type_ptr(big_union_type *arg, big_union_type *field)
|
||||
{
|
||||
arg->b = field;
|
||||
}
|
||||
|
||||
void pcode_SUM77_BigStructPtrModifyBig_struct_type_ptr(big_struct_type *arg, big_struct_type *field)
|
||||
{
|
||||
arg->b = field;
|
||||
}
|
||||
|
||||
u2 pcode_SUM40_BigUnionPtrAccessUnsignedShort(big_union_type *arg)
|
||||
{
|
||||
u2 local_var;
|
||||
|
||||
local_var = (u2) 7;
|
||||
return arg->us + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void pcode_SUM78_BigUnionPtrModifyLongLong(big_union_type *arg, i8 field)
|
||||
{
|
||||
arg->ll = field;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_SUM5_BigStructAccessUnsignedLongLong(big_struct_type arg)
|
||||
{
|
||||
u8 local_var;
|
||||
|
||||
local_var = (u8) 7;
|
||||
return arg.ull + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
u1 pcode_SUM41_BigUnionPtrAccessUnsignedChar(big_union_type *arg)
|
||||
{
|
||||
u1 local_var;
|
||||
|
||||
local_var = (u1) 7;
|
||||
return arg->uc + local_var;
|
||||
}
|
||||
|
||||
void pcode_SUM79_BigUnionPtrModifyInt(big_union_type *arg, i4 field)
|
||||
{
|
||||
arg->i = field;
|
||||
}
|
||||
|
||||
u4 pcode_SUM6_BigStructAccessUnsignedInt(big_struct_type arg)
|
||||
{
|
||||
u4 local_var;
|
||||
|
||||
local_var = (u4) 7;
|
||||
return arg.ui + local_var;
|
||||
}
|
||||
|
||||
void pcode_SUM80_BigUnionPtrModifyShort(big_union_type *arg, i2 field)
|
||||
{
|
||||
arg->s = field;
|
||||
}
|
||||
|
||||
u1 pcode_SUM8_BigStructAccessUnsignedChar(big_struct_type arg)
|
||||
{
|
||||
u1 local_var;
|
||||
|
||||
local_var = (u1) 7;
|
||||
return arg.uc + local_var;
|
||||
}
|
||||
|
||||
u2 pcode_SUM7_BigStructAccessUnsignedShort(big_struct_type arg)
|
||||
{
|
||||
u2 local_var;
|
||||
|
||||
local_var = (u2) 7;
|
||||
return arg.us + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_SUM42_BigUnionPtrAccessFloat(big_union_type *arg)
|
||||
{
|
||||
f4 local_var;
|
||||
|
||||
local_var = (f4) 7;
|
||||
return arg->f + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_SUM43_BigUnionPtrAccessDouble(big_union_type *arg)
|
||||
{
|
||||
f8 local_var;
|
||||
|
||||
local_var = (f8) 7;
|
||||
return arg->d + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_SUM9_BigStructAccessFloat(big_struct_type arg)
|
||||
{
|
||||
f4 local_var;
|
||||
|
||||
local_var = (f4) 7;
|
||||
return arg.f + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
big_union_type *pcode_SUM44_BigUnionPtrAccessBig_union_type_ptr(big_union_type *arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg->b + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_SUM10_BigStructAccessDouble(big_struct_type arg)
|
||||
{
|
||||
f8 local_var;
|
||||
|
||||
local_var = (f8) 7;
|
||||
return arg.d + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
big_struct_type *pcode_SUM11_BigStructAccessBig_struct_type_ptr(big_struct_type arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg.b + local_var;
|
||||
}
|
||||
|
||||
big_struct_type pcode_SUM46_BigStructModifyInt(big_struct_type arg, i4 field)
|
||||
{
|
||||
arg.i = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
big_struct_type pcode_SUM45_BigStructModifyLongLong(big_struct_type arg, i8 field)
|
||||
{
|
||||
arg.ll = field;
|
||||
return arg;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
big_struct_type pcode_SUM47_BigStructModifyShort(big_struct_type arg, i2 field)
|
||||
{
|
||||
arg.s = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_SUM12_BigUnionAccessLongLong(big_union_type arg)
|
||||
{
|
||||
i8 local_var;
|
||||
|
||||
local_var = (i8) 7;
|
||||
return arg.ll + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
big_struct_type pcode_SUM48_BigStructModifyChar(big_struct_type arg, i1 field)
|
||||
{
|
||||
arg.c = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
i4 pcode_SUM13_BigUnionAccessInt(big_union_type arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg.i + local_var;
|
||||
}
|
||||
|
||||
i2 pcode_SUM14_BigUnionAccessShort(big_union_type arg)
|
||||
{
|
||||
i2 local_var;
|
||||
|
||||
local_var = (i2) 7;
|
||||
return arg.s + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
big_struct_type pcode_SUM49_BigStructModifyUnsignedLongLong(big_struct_type arg, u8 field)
|
||||
{
|
||||
arg.ull = field;
|
||||
return arg;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i1 pcode_SUM15_BigUnionAccessChar(big_union_type arg)
|
||||
{
|
||||
i1 local_var;
|
||||
|
||||
local_var = (i1) 7;
|
||||
return arg.c + local_var;
|
||||
}
|
||||
|
||||
big_struct_type pcode_SUM50_BigStructModifyUnsignedInt(big_struct_type arg, u4 field)
|
||||
{
|
||||
arg.ui = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_SUM16_BigUnionAccessUnsignedLongLong(big_union_type arg)
|
||||
{
|
||||
u8 local_var;
|
||||
|
||||
local_var = (u8) 7;
|
||||
return arg.ull + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
big_struct_type pcode_SUM51_BigStructModifyUnsignedShort(big_struct_type arg, u2 field)
|
||||
{
|
||||
arg.us = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
u4 pcode_SUM17_BigUnionAccessUnsignedInt(big_union_type arg)
|
||||
{
|
||||
u4 local_var;
|
||||
|
||||
local_var = (u4) 7;
|
||||
return arg.ui + local_var;
|
||||
}
|
||||
|
||||
big_struct_type pcode_SUM52_BigStructModifyUnsignedChar(big_struct_type arg, u1 field)
|
||||
{
|
||||
arg.uc = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
u2 pcode_SUM18_BigUnionAccessUnsignedShort(big_union_type arg)
|
||||
{
|
||||
u2 local_var;
|
||||
|
||||
local_var = (u2) 7;
|
||||
return arg.us + local_var;
|
||||
}
|
||||
|
||||
u1 pcode_SUM19_BigUnionAccessUnsignedChar(big_union_type arg)
|
||||
{
|
||||
u1 local_var;
|
||||
|
||||
local_var = (u1) 7;
|
||||
return arg.uc + local_var;
|
||||
}
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
big_struct_type pcode_SUM54_BigStructModifyDouble(big_struct_type arg, f8 field)
|
||||
{
|
||||
arg.d = field;
|
||||
return arg;
|
||||
}
|
||||
#endif /* #ifdef HAS_DOUBLE */
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
big_struct_type pcode_SUM53_BigStructModifyFloat(big_struct_type arg, f4 field)
|
||||
{
|
||||
arg.f = field;
|
||||
return arg;
|
||||
}
|
||||
#endif /* #ifdef HAS_FLOAT */
|
||||
|
||||
big_struct_type pcode_SUM55_BigStructModifyBig_struct_type_ptr(big_struct_type arg, big_struct_type *field)
|
||||
{
|
||||
arg.b = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
f4 pcode_SUM20_BigUnionAccessFloat(big_union_type arg)
|
||||
{
|
||||
f4 local_var;
|
||||
|
||||
local_var = (f4) 7;
|
||||
return arg.f + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
f8 pcode_SUM21_BigUnionAccessDouble(big_union_type arg)
|
||||
{
|
||||
f8 local_var;
|
||||
|
||||
local_var = (f8) 7;
|
||||
return arg.d + local_var;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
big_union_type pcode_SUM56_BigUnionModifyLongLong(big_union_type arg, i8 field)
|
||||
{
|
||||
arg.ll = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
big_union_type *pcode_SUM22_BigUnionAccessBig_union_type_ptr(big_union_type arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg.b + local_var;
|
||||
}
|
||||
|
||||
big_union_type pcode_SUM57_BigUnionModifyInt(big_union_type arg, i4 field)
|
||||
{
|
||||
arg.i = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 pcode_SUM23_BigStructPtrAccessLongLong(big_struct_type *arg)
|
||||
{
|
||||
i8 local_var;
|
||||
|
||||
local_var = (i8) 7;
|
||||
return arg->ll + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
big_union_type pcode_SUM58_BigUnionModifyShort(big_union_type arg, i2 field)
|
||||
{
|
||||
arg.s = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
i4 pcode_SUM24_BigStructPtrAccessInt(big_struct_type *arg)
|
||||
{
|
||||
i4 local_var;
|
||||
|
||||
local_var = (i4) 7;
|
||||
return arg->i + local_var;
|
||||
}
|
||||
|
||||
big_union_type pcode_SUM59_BigUnionModifyChar(big_union_type arg, i1 field)
|
||||
{
|
||||
arg.c = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
i2 pcode_SUM25_BigStructPtrAccessShort(big_struct_type *arg)
|
||||
{
|
||||
i2 local_var;
|
||||
|
||||
local_var = (i2) 7;
|
||||
return arg->s + local_var;
|
||||
}
|
||||
|
||||
i1 pcode_SUM26_BigStructPtrAccessChar(big_struct_type *arg)
|
||||
{
|
||||
i1 local_var;
|
||||
|
||||
local_var = (i1) 7;
|
||||
return arg->c + local_var;
|
||||
}
|
||||
|
||||
big_union_type pcode_SUM63_BigUnionModifyUnsignedChar(big_union_type arg, u1 field)
|
||||
{
|
||||
arg.uc = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
big_union_type pcode_SUM62_BigUnionModifyUnsignedShort(big_union_type arg, u2 field)
|
||||
{
|
||||
arg.us = field;
|
||||
return arg;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
u8 pcode_SUM27_BigStructPtrAccessUnsignedLongLong(big_struct_type *arg)
|
||||
{
|
||||
u8 local_var;
|
||||
|
||||
local_var = (u8) 7;
|
||||
return arg->ull + local_var;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
@ -0,0 +1,81 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
/* A struct to use in testing */
|
||||
|
||||
typedef struct big_struct
|
||||
{
|
||||
#ifdef HAS_LONGLONG
|
||||
long long ll;
|
||||
#else
|
||||
char ll[8];
|
||||
#endif
|
||||
int i;
|
||||
short s;
|
||||
char c;
|
||||
#ifdef HAS_LONGLONG
|
||||
unsigned long long ull;
|
||||
#else
|
||||
char ull[8];
|
||||
#endif
|
||||
unsigned int ui;
|
||||
unsigned short us;
|
||||
unsigned char uc;
|
||||
#ifdef HAS_FLOAT
|
||||
float f;
|
||||
#else
|
||||
char f[4];
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
double d;
|
||||
#else
|
||||
char d[8];
|
||||
#endif
|
||||
struct big_struct *b;
|
||||
} big_struct_type;
|
||||
|
||||
typedef union big_union
|
||||
{
|
||||
#ifdef HAS_LONGLONG
|
||||
long long ll;
|
||||
#else
|
||||
char ll[8];
|
||||
#endif
|
||||
int i;
|
||||
short s;
|
||||
char c;
|
||||
#ifdef HAS_LONGLONG
|
||||
unsigned long long ull;
|
||||
#else
|
||||
char ull[8];
|
||||
#endif
|
||||
unsigned int ui;
|
||||
unsigned short us;
|
||||
unsigned char uc;
|
||||
#ifdef HAS_FLOAT
|
||||
float f;
|
||||
#else
|
||||
char f[4];
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
double d;
|
||||
#else
|
||||
char d[8];
|
||||
#endif
|
||||
union big_union *b;
|
||||
} big_union_type;
|
||||
|
583
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/builtin.c
Normal file
583
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/builtin.c
Normal file
@ -0,0 +1,583 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < n; i++)
|
||||
((unsigned char *) dest)[i] = ((unsigned char *) src)[i];
|
||||
return dest;
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *dst = s;
|
||||
for (; n > 0; n--, dst++)
|
||||
*dst = (unsigned char) c;
|
||||
return s;
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
int memcmp(void *s1, void *s2, size_t n)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < n; i++, s1++, s2++) {
|
||||
if (* (unsigned char *) s1 < * (unsigned char *) s2) return -1;
|
||||
else if (* (unsigned char *) s1 > * (unsigned char *) s2) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#if defined(BUILD_EXE)
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
void write(int fd, char *buf, int count)
|
||||
{
|
||||
#if defined(__AARCH64EL__) || defined(__AARCH64EB__)
|
||||
asm( "mov x0,%[fd]\n\t"
|
||||
"mov x1,%[msgstr]\n\t"
|
||||
"mov x2,%[msglen]\n\t"
|
||||
"mov x8,#64\n\t"
|
||||
"svc #0\n\t"
|
||||
:
|
||||
: [fd] "r" (fd),
|
||||
[msgstr] "r" (buf),
|
||||
[msglen] "r" (count)
|
||||
: "x0", "x1", "x2", "x8"
|
||||
);
|
||||
|
||||
#elif defined(__ARM_ARCH_ISA_THUMB)
|
||||
asm( "push {r7}\n\t"
|
||||
"mov r0,%[fd]\n\t"
|
||||
"mov r1,%[msgstr]\n\t"
|
||||
"mov r2,%[msglen]\n\t"
|
||||
"mov r7,#4\n\t"
|
||||
"swi #0\n\t"
|
||||
"pop {r7}\n\t"
|
||||
:
|
||||
: [fd] "r" (fd),
|
||||
[msgstr] "r" (buf),
|
||||
[msglen] "r" (count)
|
||||
: "r0", "r1", "r2"
|
||||
);
|
||||
|
||||
|
||||
#elif defined(__ARMEL__) || defined(__ARMEB__)
|
||||
asm( "mov %%r0,%[fd]\n\t"
|
||||
"mov %%r1,%[msgstr]\n\t"
|
||||
"mov %%r2,%[msglen]\n\t"
|
||||
"mov %%r7,#4\n\t"
|
||||
"swi $0\n\t"
|
||||
:
|
||||
: [fd] "r" (fd),
|
||||
[msgstr] "r" (buf),
|
||||
[msglen] "r" (count)
|
||||
: "r0", "%r1", "r2", "r7"
|
||||
);
|
||||
|
||||
#elif defined(__m68k__)
|
||||
asm( "moveq #4,%%d0\n\t"
|
||||
"move %[fd],%%d1\n\t"
|
||||
"move %[msgstr],%%d2\n\t"
|
||||
"move %[msglen],%%d3\n\t"
|
||||
"trap #0\n\t"
|
||||
:
|
||||
: [fd] "r" (fd),
|
||||
[msgstr] "r" (buf),
|
||||
[msglen] "r" (count)
|
||||
: "d0", "d1", "d2", "d3"
|
||||
);
|
||||
|
||||
#elif defined(__MIPSEB__)
|
||||
asm( "move $a0, %[fd]\n\t"
|
||||
"move $a1, %[msgstr]\n\t"
|
||||
"move $a2, %[msglen]\n\t"
|
||||
"li $v0, 4004\n\t"
|
||||
"syscall\n\t"
|
||||
:
|
||||
: [fd] "r" (fd),
|
||||
[msgstr] "r" (buf),
|
||||
[msglen] "r" (count)
|
||||
: "v0", "a0", "a1", "a2"
|
||||
);
|
||||
|
||||
#elif defined(__PPC__)
|
||||
asm( "li 0,4\n\t"
|
||||
"lwz 3,%[fd]\n\t"
|
||||
#ifdef __PPC64__
|
||||
"ld 4,%[msgstr]\n\t"
|
||||
#else
|
||||
"lwz 4,%[msgstr]\n\t"
|
||||
#endif
|
||||
"lwz 5,%[msglen]\n\t"
|
||||
"sc\n\t"
|
||||
:
|
||||
: [fd] "" (fd),
|
||||
[msgstr] "" (buf),
|
||||
[msglen] "" (count)
|
||||
: "r0", "r3", "r4", "r5"
|
||||
);
|
||||
|
||||
#elif defined(__pentium__)
|
||||
asm( "mov %[msglen],%%edx\n\t"
|
||||
"mov %[msgstr],%%ecx\n\t"
|
||||
"mov %[fd],%%ebx\n\t"
|
||||
"mov $4,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
:
|
||||
: [fd] "" (fd),
|
||||
[msgstr] "" (buf),
|
||||
[msglen] "" (count)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
|
||||
#elif defined(__SH4__)
|
||||
asm( "mov #4,r3\n\t"
|
||||
"mov %[fd],r4\n\t"
|
||||
"mov %[msgstr],r5\n\t"
|
||||
"mov %[msglen],r6\n\t"
|
||||
"trapa #17\n\t"
|
||||
:
|
||||
: [fd] "r" (fd),
|
||||
[msgstr] "r" (buf),
|
||||
[msglen] "r" (count)
|
||||
: "r3", "r4", "r5", "r6"
|
||||
);
|
||||
|
||||
#elif defined(__sparc__)
|
||||
asm( "mov 1,%%o0\n\t"
|
||||
// "sethi %%hi(%[msgstr]), %%g1\n\t"
|
||||
// "or %%g1, %%lo(%[msgstr]), %%o1\n\t"
|
||||
"ld %[msgstr], %%o1\n\t"
|
||||
"mov 4,%%g1\n\t"
|
||||
"ld %[msglen],%%o2\n\t"
|
||||
"t 0x6d\n\t"
|
||||
:
|
||||
: [fd] "" (fd),
|
||||
[msgstr] "" (buf),
|
||||
[msglen] "" (count)
|
||||
: "o0", "g1", "o1", "o2"
|
||||
);
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
asm( "mov %[msglen],%%edx\n\t"
|
||||
"movq %[msgstr],%%rsi\n\t"
|
||||
"movq %[fd],%%rdi\n\t"
|
||||
"movq $1,%%rax\n\t"
|
||||
"syscall\n\t"
|
||||
:
|
||||
: [fd] "" (fd),
|
||||
[msgstr] "" (buf),
|
||||
[msglen] "" (count)
|
||||
: "rax", "rdi", "rsi", "rdx"
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
void exit(int stat)
|
||||
{
|
||||
#if defined(__AARCH64EL__) || defined(__AARCH64EB__)
|
||||
asm( "mov x0,%[status]\n\t"
|
||||
"mov x8,#93\n\t"
|
||||
"svc #0\n\t"
|
||||
:
|
||||
: [status] "r" (stat)
|
||||
: "x0", "x8"
|
||||
);
|
||||
|
||||
#elif defined(__ARM_ARCH_ISA_THUMB)
|
||||
asm( "push {r7}\n\t"
|
||||
"mov r0,%[status]\n\t"
|
||||
"mov r7,#1\n\t"
|
||||
"swi #0\n\t"
|
||||
"pop {r7}\n\t"
|
||||
:
|
||||
: [status] "r" (stat)
|
||||
: "r0"
|
||||
);
|
||||
|
||||
#elif defined(__ARMEL__) || defined(__ARMEB__)
|
||||
asm( "mov %%r0,%[status]\n\t"
|
||||
"mov %%r7,#1\n\t"
|
||||
"swi $0\n\t"
|
||||
:
|
||||
: [status] "r" (stat)
|
||||
: "r0", "r7"
|
||||
);
|
||||
|
||||
#elif defined(__m68k__)
|
||||
asm( "moveq #1,%%d0\n\t"
|
||||
"move %[status],%%d1\n\t"
|
||||
"trap #0\n\t"
|
||||
:
|
||||
: [status] "" (stat)
|
||||
: "d0", "d1"
|
||||
);
|
||||
|
||||
#elif defined(__MIPSEB__)
|
||||
asm( "move $a0,%[status]\n\t"
|
||||
"li $v0, 4001\n\t"
|
||||
"syscall\n\t"
|
||||
:
|
||||
: [status] "r" (stat)
|
||||
: "v0", "a0"
|
||||
);
|
||||
|
||||
#elif defined(__PPC__)
|
||||
asm( " li 0,1 \n"
|
||||
" lwz 3,%[status] \n"
|
||||
" sc \n"
|
||||
:
|
||||
: [status] "" (stat)
|
||||
: "r0", "r3"
|
||||
);
|
||||
|
||||
#elif defined(__pentium__)
|
||||
asm( "mov %[status],%%ebx\n\t"
|
||||
"mov $1,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
:
|
||||
: [status] "" (stat)
|
||||
: "eax", "ebx"
|
||||
);
|
||||
|
||||
#elif defined(__SH4__)
|
||||
asm( "mov #1,r3\n\t"
|
||||
"mov %[status],r4\n\t"
|
||||
"trapa #17\n\t"
|
||||
:
|
||||
: [status] "r" (stat)
|
||||
: "r3", "r4"
|
||||
);
|
||||
|
||||
#elif defined(__sparc__)
|
||||
asm( "mov 1,%%g1\n\t"
|
||||
"mov %[status],%%o0\n\t"
|
||||
"t 0x6d\n\t"
|
||||
"nop\n\t"
|
||||
:
|
||||
: [status] "r" (stat)
|
||||
: "g1", "o0"
|
||||
);
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
asm( "mov %[status],%%rdi\n\t"
|
||||
"mov $60,%%rax\n\t"
|
||||
"syscall\n\t"
|
||||
:
|
||||
: [status] "" (stat)
|
||||
: "rax", "rdi"
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
static int strlen(char *str)
|
||||
{
|
||||
int len;
|
||||
for (len = 0; str[len]; len++) ;
|
||||
return len;
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
static void strcpy(char *dst, char *src)
|
||||
{
|
||||
while (*src) *dst++ = *src++;
|
||||
*dst = *src;
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
static void put(char *str)
|
||||
{
|
||||
write(1, str, strlen(str));
|
||||
}
|
||||
#endif // !HAS_LIBC
|
||||
|
||||
// utoa, itoa and ftoa
|
||||
|
||||
// Convert unsigned u to decimal.
|
||||
// if dflag is set, insert a decimal point after the first nonzero
|
||||
// digit, and return the number of decimal places
|
||||
|
||||
static int utoa(unsigned long u, char *buff, int len, int dflag)
|
||||
{
|
||||
int i = len - 1;
|
||||
int ret = 0;
|
||||
int j;
|
||||
|
||||
if (dflag) dflag = 1;
|
||||
|
||||
if (u == 0) {
|
||||
if (dflag) {
|
||||
strcpy(buff, "0.0");
|
||||
return 1;
|
||||
} else {
|
||||
strcpy(buff, "0");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Put in ascii at the end of the buffer
|
||||
|
||||
buff[i] = '\0';
|
||||
i = i - 1;
|
||||
while (u > 0 && i >= 0) {
|
||||
buff[i] = '0' + (u % 10);
|
||||
u = u / 10;
|
||||
i = i - 1;
|
||||
}
|
||||
|
||||
// Now move the string to the front of the buffer, optionally
|
||||
// inserting a decimal point
|
||||
|
||||
j = 0;
|
||||
i = i + 1;
|
||||
while (i < len && j < i) {
|
||||
if (j == 1 && dflag) {
|
||||
buff[j] = '.';
|
||||
j = j + 1;
|
||||
}
|
||||
buff[j] = buff[i];
|
||||
if (dflag && j > 1 && buff[j]) ret = ret + 1;
|
||||
j = j + 1;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int itoa(long u, char *buff, int len, int dflag)
|
||||
{
|
||||
if (u < 0) {
|
||||
*buff = '-';
|
||||
len = len - 1;
|
||||
buff = buff + 1;
|
||||
u = - u;
|
||||
}
|
||||
utoa(u, buff, len, dflag);
|
||||
}
|
||||
|
||||
static void ftoa(float f, char *buff, int len)
|
||||
{
|
||||
unsigned int fi;
|
||||
int sig;
|
||||
unsigned int f2, fa;
|
||||
int e2, ea;
|
||||
int ra;
|
||||
|
||||
*buff = '\0';
|
||||
|
||||
// find fa and ea such that
|
||||
// f = f2 2^(e2-23) = fa 10^ea
|
||||
|
||||
if (sizeof(f) == 4) {
|
||||
fi = * (int *) &f;
|
||||
sig = (fi & 0x80000000) ? 1 : 0;
|
||||
e2 = ((fi >> 23) & 0xff);
|
||||
f2 = (fi & 0x7fffff);
|
||||
|
||||
// Handle normalized numbers
|
||||
|
||||
if (e2 != 0) {
|
||||
f2 = f2 | 0x800000;
|
||||
e2 = e2 - 127;
|
||||
e2 = e2 - 23;
|
||||
}
|
||||
|
||||
if (e2 == 0 && f2 == 0) {
|
||||
strcpy(buff, "0.0");
|
||||
return;
|
||||
}
|
||||
|
||||
// determine ea, fa iteratively
|
||||
// by reducing e2 to 0
|
||||
|
||||
ea = 0;
|
||||
fa = f2;
|
||||
// printf("%f = %u 2^%d 10^%d?\n", f, fa, e2, ea);
|
||||
while (e2 > 0) {
|
||||
// If the the high bit is set
|
||||
// then we can't multiply by 2
|
||||
// without losing it, so divide by 10
|
||||
// and round off
|
||||
if (fa & (1 << 31)) {
|
||||
ra = ((fa % 5) > 2) ? 1 : 0;
|
||||
fa = (fa / 5) + ra;
|
||||
ea = ea + 1;
|
||||
} else {
|
||||
fa = fa * 2;
|
||||
}
|
||||
e2 = e2 - 1;
|
||||
// printf("%f = %u 2^%d 10^%d?\n", f, fa, e2, ea);
|
||||
}
|
||||
while (e2 < 0) {
|
||||
// If the top 3 bits are zero
|
||||
// then we can multiply by 10
|
||||
// and preserve the precision
|
||||
if ((fa & (7 << 29)) == 0) {
|
||||
fa = fa * 5;
|
||||
ea = ea - 1;
|
||||
} else {
|
||||
ra = (fa % 2) ? 1 : 0;
|
||||
fa = (fa / 2) + ra;
|
||||
}
|
||||
e2 = e2 + 1;
|
||||
// printf("%f = %u 2^%d 10^%d?\n", f, fa, e2, ea);
|
||||
}
|
||||
|
||||
// Now we have what we want, f = fa 10^ea
|
||||
// it remains to convert this to ascii
|
||||
// and move the decimal point
|
||||
|
||||
if (sig) {
|
||||
*buff = '-';
|
||||
len = len - 1;
|
||||
buff = buff + 1;
|
||||
}
|
||||
ea = ea + utoa(fa, buff, len, 1);
|
||||
len = len - strlen(buff);
|
||||
buff = buff + strlen(buff);
|
||||
if (ea == 0) return;
|
||||
|
||||
*buff = 'e';
|
||||
len = len - 1;
|
||||
buff = buff + 1;
|
||||
|
||||
if (ea < 0) {
|
||||
*buff = '-';
|
||||
len = len - 1;
|
||||
buff = buff + 1;
|
||||
ea = -ea;
|
||||
} else {
|
||||
*buff = '+';
|
||||
len = len - 1;
|
||||
buff = buff + 1;
|
||||
}
|
||||
utoa(ea, buff, len, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_info(char *file, int line, char *func, char *type, char *expected, char *val, char *ok)
|
||||
{
|
||||
#ifndef HAS_LIBC
|
||||
char lbuff[100];
|
||||
utoa(line, lbuff, 100, 0);
|
||||
|
||||
put("File "); put(file);
|
||||
put(" line "); put(lbuff);
|
||||
put(" function "); put(func);
|
||||
put(" expected "); put(type);
|
||||
put(" "); put(expected);
|
||||
put(" got "); put(val);
|
||||
put(" "); put(ok);
|
||||
put("\n");
|
||||
#else
|
||||
printf("File %s line %d function %s expected %s %s got %s %s\n", file, line, func, type, expected, val, ok);
|
||||
#endif // HAS_LIBC
|
||||
}
|
||||
|
||||
void print_int(char *file, int line, char *func, int expected, int val, char *ok)
|
||||
{
|
||||
#ifdef HAS_PRINTF
|
||||
printf("File %s line %d function %s expected %s %d got %d %s\n", file, line, func, "int", expected, val, ok);
|
||||
#else
|
||||
char ebuff[100];
|
||||
itoa(expected, ebuff, 100, 0);
|
||||
char vbuff[100];
|
||||
itoa(val, vbuff, 100, 0);
|
||||
print_info(file, line, func, "int", ebuff, vbuff, ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_long(char *file, int line, char *func, long expected, long val, char *ok)
|
||||
{
|
||||
#ifdef HAS_PRINTF
|
||||
printf("File %s line %d function %s expected %s %ld got %ld %s\n", file, line, func, "long", expected, val, ok);
|
||||
#else
|
||||
char ebuff[100];
|
||||
itoa(expected, ebuff, 100, 0);
|
||||
char vbuff[100];
|
||||
itoa(val, vbuff, 100, 0);
|
||||
print_info(file, line, func, "long", ebuff, vbuff, ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_uint(char *file, int line, char *func, unsigned int expected, unsigned int val, char *ok)
|
||||
{
|
||||
#ifdef HAS_PRINTF
|
||||
printf("File %s line %d function %s expected %s %u got %u %s\n", file, line, func, "uint", expected, val, ok);
|
||||
#else
|
||||
char ebuff[100];
|
||||
utoa(expected, ebuff, 100, 0);
|
||||
char vbuff[100];
|
||||
utoa(val, vbuff, 100, 0);
|
||||
print_info(file, line, func, "uint", ebuff, vbuff, ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_ulong(char *file, int line, char *func, unsigned long expected, unsigned long val, char *ok)
|
||||
{
|
||||
#ifdef HAS_PRINTF
|
||||
printf("File %s line %d function %s expected %s %lu got %lu %s\n", file, line, func, "ulong", expected, val, ok);
|
||||
#else
|
||||
char ebuff[100];
|
||||
utoa(expected, ebuff, 100, 0);
|
||||
char vbuff[100];
|
||||
utoa(val, vbuff, 100, 0);
|
||||
print_info(file, line, func, "ulong", ebuff, vbuff, ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_float(char *file, int line, char *func, float expected, float val, char *ok)
|
||||
{
|
||||
#ifdef HAS_PRINTF
|
||||
printf("File %s line %d function %s expected %s %.9e got %.9e %s\n", file, line, func, "float", expected, val, ok);
|
||||
#else
|
||||
char ebuff[100];
|
||||
char vbuff[100];
|
||||
ftoa(expected, ebuff, 100);
|
||||
ftoa(val, vbuff, 100);
|
||||
print_info(file, line, func, "float", ebuff, vbuff, ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
void print_val(char *name, int val)
|
||||
{
|
||||
#ifdef HAS_PRINTF
|
||||
printf("%s %d\n", name, val);
|
||||
#else
|
||||
char vbuff[100];
|
||||
itoa(val, vbuff, 100, 0);
|
||||
put(name); put(" "); put(vbuff); put("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
||||
#endif // BUILD_EXE
|
90
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc.test
Normal file
90
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc.test
Normal file
@ -0,0 +1,90 @@
|
||||
#include "pcode_test.h"
|
||||
#include "big_struct.h"
|
||||
|
||||
TEST recursionTestLevel_Main()
|
||||
{
|
||||
extern i4 recursionTestLevel (i4 level, u1 * array, i4 len);
|
||||
i4 i;
|
||||
u1 localArray[128];
|
||||
i4 level = 0;
|
||||
for (i = 0; i < sizeof(localArray); i++) localArray[i] = (8 * level) + i;
|
||||
ASSERTI4(recursionTestLevel(1, localArray, sizeof(localArray)), 0);
|
||||
}
|
||||
|
||||
TEST nalign_i2_Main()
|
||||
{
|
||||
extern i2 nalign_i2(i2 in);
|
||||
ASSERTI2(nalign_i2(1), 16);
|
||||
ASSERTI2(nalign_i2(128), 2048);
|
||||
}
|
||||
|
||||
TEST nalign_i4_Main()
|
||||
{
|
||||
extern i4 nalign_i4(i4 in);
|
||||
ASSERTI4(nalign_i4(1), 16);
|
||||
ASSERTI4(nalign_i4(1000), 16000);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
TEST nalign_i8_Main()
|
||||
{
|
||||
extern i8 nalign_i8(i8 in);
|
||||
ASSERTI8(nalign_i8(1), 16);
|
||||
ASSERTI8(nalign_i8(128), 2048);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST nalign_struct_Main()
|
||||
{
|
||||
extern i4 nalign_struct(big_struct_type * in);
|
||||
big_struct_type bstruct;
|
||||
ASSERTI4(nalign_struct(&bstruct), 0);
|
||||
}
|
||||
|
||||
#if defined(HAS_FLOAT) && defined(HAS_DOUBLE) && defined(HAS_LONGLONG)
|
||||
TEST pcode_conversions_Main()
|
||||
{
|
||||
extern i4 pcode_conversions(int argc);
|
||||
ASSERTI4(pcode_conversions(0), 0 );
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST pcode_memcpy_Main()
|
||||
{
|
||||
extern void *pcode_memcpy(u1* lhs, u1* rhs, u4 len);
|
||||
char buff1[32] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
char buff2[32] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
|
||||
char ret[32];
|
||||
ASSERTU4(* (u4 *) pcode_memcpy((u1*) ret, (u1*) buff1, 32), 0x01010101);
|
||||
ASSERTU4(* (u4 *) pcode_memcpy((u1*) ret, (u1*) buff2, 32), 0x02020202);
|
||||
}
|
||||
|
||||
TEST pcode_memcmp_u4_Main()
|
||||
{
|
||||
extern u4 pcode_memcmp_u4(u4 lhs, u4 rhs);
|
||||
u1 buff1[] = "this is a test string1";
|
||||
u1 buff2[] = "this is a test string1";
|
||||
u1 buff3[] = "this is a test string2";
|
||||
ASSERTU4(pcode_memcmp_u4(0x1F1F1F1F, 0x1F1F1F1F), 0);
|
||||
ASSERTU4(pcode_memcmp_u4(0x1F1F1F1F, 0x1F1E1F1F), 1);
|
||||
}
|
||||
|
||||
TEST pcode_memcmp_n_Main()
|
||||
{
|
||||
extern u4 pcode_memcmp_n(u1* lhs, u1* rhs, u4 len);
|
||||
u1 buff1[] = "this is a test string1";
|
||||
u1 buff2[] = "this is a test string1";
|
||||
u1 buff3[] = "this is a test string2";
|
||||
ASSERTU4(pcode_memcmp_n(buff1, buff2, 22), 0);
|
||||
ASSERTU4(pcode_memcmp_n(buff1, buff3, 22), 1);
|
||||
}
|
||||
|
||||
TEST pcode_memset_Main()
|
||||
{
|
||||
extern u4 pcode_memset(u1* lhs, u1 val, u4 len);
|
||||
u1 buff[32];
|
||||
ASSERTU4(pcode_memset(buff, 1, 4), 0x01010101);
|
||||
ASSERTU4(pcode_memset(buff, 2, 4), 0x02020202);
|
||||
}
|
||||
|
||||
MAIN misc_main() { }
|
260
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.c
Normal file
260
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.c
Normal file
@ -0,0 +1,260 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
#include "big_struct.h"
|
||||
|
||||
static i4 int_expectedValue;
|
||||
static i4 int_actualValue;
|
||||
|
||||
static i4 breakPointHere(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
i4 recursionTestLevel(i4 level, u1 * array, i4 len)
|
||||
{
|
||||
i4 i, ret = 0;
|
||||
u1 localArray[128];
|
||||
|
||||
for (i = 0; i < sizeof(localArray); i++) {
|
||||
localArray[i] = (8 * level) + i;
|
||||
}
|
||||
|
||||
if (level < 4 && (ret = recursionTestLevel(level + 1, localArray, len))) {
|
||||
return 1;
|
||||
}
|
||||
/* verify array integrity */
|
||||
for (i = 0; i < sizeof(localArray); i++) {
|
||||
if (localArray[i] != ((8 * level) + i)) {
|
||||
return ret + 1;
|
||||
}
|
||||
}
|
||||
/* verify array integrity */
|
||||
for (i = 0; i < sizeof(localArray); i++) {
|
||||
if (array[i] != ((8 * (level - 1)) + i)) {
|
||||
return ret + 1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
i2 nalign_i2(i2 in)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
*(i2 *) (buffer + 1) = in;
|
||||
in += *(i2 *) (buffer + 1);
|
||||
*(i2 *) (buffer + 2) = in;
|
||||
in += *(i2 *) (buffer + 2);
|
||||
*(i2 *) (buffer + 3) = in;
|
||||
in += *(i2 *) (buffer + 3);
|
||||
*(i2 *) (buffer + 4) = in;
|
||||
in += *(i2 *) (buffer + 4);
|
||||
return in;
|
||||
}
|
||||
|
||||
i4 nalign_i4(i4 in)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
*(i4 *) (buffer + 1) = in;
|
||||
in += *(i4 *) (buffer + 1);
|
||||
*(i4 *) (buffer + 2) = in;
|
||||
in += *(i4 *) (buffer + 2);
|
||||
*(i4 *) (buffer + 3) = in;
|
||||
in += *(i4 *) (buffer + 3);
|
||||
*(i4 *) (buffer + 4) = in;
|
||||
in += *(i4 *) (buffer + 4);
|
||||
return in;
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
i8 nalign_i8(i8 in)
|
||||
{
|
||||
char buffer[128];
|
||||
*(i8 *) (buffer + 1) = in;
|
||||
in += *(i8 *) (buffer + 1);
|
||||
*(i8 *) (buffer + 2) = in;
|
||||
in += *(i8 *) (buffer + 2);
|
||||
*(i8 *) (buffer + 3) = in;
|
||||
in += *(i8 *) (buffer + 3);
|
||||
*(i8 *) (buffer + 4) = in;
|
||||
in += *(i8 *) (buffer + 4);
|
||||
return in;
|
||||
}
|
||||
#endif /* #ifdef HAS_LONGLONG */
|
||||
|
||||
i4 nalign_struct(big_struct_type * in)
|
||||
{
|
||||
i4 ret = 0;
|
||||
char buffer[128];
|
||||
|
||||
in->i = 0x5;
|
||||
if (in->i != 0x5)
|
||||
ret++;
|
||||
in->s = 0x6;
|
||||
if (in->s != 0x6)
|
||||
ret++;
|
||||
in->c = 0x7;
|
||||
if (in->c != 0x7)
|
||||
ret++;
|
||||
#ifdef HAS_LONGLONG
|
||||
in->ll = 0x8;
|
||||
if (in->ll != 0x8)
|
||||
ret++;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
u4 pcode_memset(u1 *lhs, u1 val, u4 len)
|
||||
{
|
||||
memset(lhs, val, len);
|
||||
return *(u4 *) lhs;
|
||||
}
|
||||
|
||||
void *pcode_memcpy(u1 * lhs, u1 * rhs, u4 len)
|
||||
{
|
||||
return memcpy(lhs, rhs, len);
|
||||
}
|
||||
|
||||
u4 pcode_memcmp_u4(u4 lhs, u4 rhs)
|
||||
{
|
||||
return (u4) (memcmp(&lhs, &rhs, 4) == 0 ? 0 : 1);
|
||||
}
|
||||
|
||||
u4 pcode_memcmp_n(u1 * lhs, u1 * rhs, u4 len)
|
||||
{
|
||||
return (u4) (memcmp(lhs, rhs, len) == 0 ? 0 : 1);
|
||||
}
|
||||
|
||||
#if defined(HAS_FLOAT) && defined(HAS_DOUBLE) && defined(HAS_LONGLONG)
|
||||
|
||||
/* Almost equal here means a difference between f1 and f2 that is less
|
||||
* than 1% of f2. Naturally, f2 != 0. Implement it without calling
|
||||
* fabs, which would cast everything to double anyway.
|
||||
*/
|
||||
|
||||
static int FLOAT_ALMOST_EQUAL(double f1, double f2)
|
||||
{
|
||||
double d = (f1 >= f2 ? f1 - f2 : f2 - f1);
|
||||
double m = (f2 >= 0.0 ? f2 : -f2) * 0.01;
|
||||
return d < m;
|
||||
}
|
||||
|
||||
i4 pcode_conversions(int argc)
|
||||
{
|
||||
i1 u1buff[8];
|
||||
u2 u2buff[8];
|
||||
u4 u4buff[8];
|
||||
u8 u8buff[8];
|
||||
f4 f4buff[8];
|
||||
f8 f8buff[8];
|
||||
u8 ret = 0;
|
||||
i4 i = 0;
|
||||
|
||||
f4 f4_1 = argc;
|
||||
f4 f4_2 = 4.0 - f4_1;
|
||||
if (f4_2 != 4.0)
|
||||
return 101;
|
||||
|
||||
f4 f4_3 = f4_1 + 5.0;
|
||||
if (f4_3 != 5.0)
|
||||
return 102;
|
||||
|
||||
f8 f8_1 = argc;
|
||||
f8 f8_2 = 4.0 - f8_1;
|
||||
if (f8_2 != 4.0)
|
||||
return 103;
|
||||
|
||||
f8 f8_3 = f8_1 + 5.0;
|
||||
if (f8_3 != 5.0)
|
||||
return 104;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
u1buff[i] = 0;
|
||||
u2buff[i] = 0;
|
||||
u4buff[i] = 0;
|
||||
u8buff[i] = 0;
|
||||
f4buff[i] = 0;
|
||||
f8buff[i] = 0;
|
||||
}
|
||||
u8buff[0] = 0x0FFFFFFFFFFFFFFFULL;
|
||||
|
||||
u4buff[0] = u8buff[0] + argc;
|
||||
|
||||
u2buff[0] = u8buff[0] + argc;
|
||||
u2buff[1] = u4buff[0] + argc;
|
||||
|
||||
u1buff[0] = u8buff[0] + argc;
|
||||
u1buff[1] = u4buff[0] + argc;
|
||||
u1buff[2] = u2buff[0] + argc;
|
||||
|
||||
if (u1buff[0] != (i1) 0xff || u1buff[1] != (i1) 0xff || u1buff[2] != (i1) 0xff || u2buff[0] != 0xffff || u2buff[1] != 0xffff || u4buff[0] != 0xffffffff || u8buff[0] != 0x0fffffffffffffffULL)
|
||||
return 1;
|
||||
|
||||
f4buff[0] = 1.0 + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f4buff[0], 1.0))
|
||||
return 21;
|
||||
|
||||
f4buff[0] = u8buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f4buff[0], 1.152921504606846976e+18))
|
||||
return 2;
|
||||
|
||||
f4buff[1] = u4buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f4buff[1], 4.294967296e+09))
|
||||
return 3;
|
||||
|
||||
f4buff[2] = u2buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f4buff[2], 6.5535e+04))
|
||||
return 4;
|
||||
|
||||
f4buff[3] = u1buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f4buff[3], -1.0e+00))
|
||||
return 5;
|
||||
|
||||
f8buff[0] = u8buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f8buff[0], 1.152921504606846976e+18))
|
||||
return 6;
|
||||
|
||||
f8buff[1] = u4buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f8buff[1], 4.294967295e+09))
|
||||
return 7;
|
||||
f8buff[2] = u2buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f8buff[2], 6.5535e+04))
|
||||
return 8;
|
||||
|
||||
f8buff[3] = u1buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f8buff[3], -1.0e+00))
|
||||
return 9;
|
||||
|
||||
f8buff[4] = f4buff[0] + argc;
|
||||
if (!FLOAT_ALMOST_EQUAL(f8buff[4], 1.152921504606846976e+18))
|
||||
return 10;
|
||||
|
||||
f8 tmpf8 = f8buff[4] + f8buff[3] - f8buff[2] + f8buff[1] - f8buff[0]
|
||||
+ f4buff[4] + f4buff[3] - f4buff[2] + f4buff[1] - f4buff[0];
|
||||
|
||||
if (!FLOAT_ALMOST_EQUAL(tmpf8, -1.15292149601704345600e+18))
|
||||
return 11;
|
||||
|
||||
u8 retll = u1buff[0] + u1buff[1] - u1buff[2] + u4buff[0] + u8buff[0];
|
||||
|
||||
if (retll != 0x10000000fffffffdULL)
|
||||
return 12;
|
||||
|
||||
return 0; // OK
|
||||
}
|
||||
#endif /* #if defined(HAS_FLOAT) && defined(HAS_DOUBLE) && defined(HAS_LONGLONG) */
|
10
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/msp430x.ld
Normal file
10
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/msp430x.ld
Normal file
@ -0,0 +1,10 @@
|
||||
MEMORY {
|
||||
RAM : ORIGIN = 0, LENGTH = 0x4000
|
||||
ROM (rx) : ORIGIN = 0x4000, LENGTH = 32k
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
.rodata : { *(.eh_frame) } >ROM
|
||||
.data : { } >RAM
|
||||
.bss : { } >RAM
|
||||
}
|
300
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.c
Normal file
300
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.c
Normal file
@ -0,0 +1,300 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pcode_test.h"
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
NOINLINE i4 breakOnPass(void);
|
||||
NOINLINE i4 breakOnError(void);
|
||||
void nosprintf5() { } /* sprintf5 function was removed, but java is still looking for it. */
|
||||
|
||||
FunctionInfo mainFunctionInfoTable[] = {
|
||||
#ifdef HAS_FLOAT
|
||||
{"assertF4", (testFuncPtr) assertF4, 0},
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
{"assertF8", (testFuncPtr) assertF8, 0},
|
||||
#endif
|
||||
{"assertI1", (testFuncPtr) assertI1, 0},
|
||||
{"assertI2", (testFuncPtr) assertI2, 0},
|
||||
{"assertI4", (testFuncPtr) assertI4, 0},
|
||||
#ifdef HAS_LONGLONG
|
||||
{"assertI8", (testFuncPtr) assertI8, 0},
|
||||
#endif
|
||||
{"assertU1", (testFuncPtr) assertU1, 0},
|
||||
{"assertU2", (testFuncPtr) assertU2, 0},
|
||||
{"assertU4", (testFuncPtr) assertU4, 0},
|
||||
#ifdef HAS_LONGLONG
|
||||
{"assertU8", (testFuncPtr) assertU8, 0},
|
||||
#endif
|
||||
{"breakOnDone", (testFuncPtr) breakOnDone, 0},
|
||||
{"breakOnError", (testFuncPtr) breakOnError, 0},
|
||||
{"breakOnPass", (testFuncPtr) breakOnPass, 0},
|
||||
{"breakOnSubDone", (testFuncPtr) breakOnSubDone, 0},
|
||||
{"noteTestMain", (testFuncPtr) noteTestMain, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
static TestInfo MainInfo = {
|
||||
{'A', 'b', 'C', 'd', 'E', 'F', 'g', 'H'},
|
||||
sizeof(i1 *), /* ptrSz */
|
||||
0x01020304, /* byteOrder */
|
||||
breakOnPass, /* onPass function ptr */
|
||||
breakOnError, /* onError function ptr */
|
||||
breakOnDone, /* onDone function ptr */
|
||||
0, /* numpass */
|
||||
0, /* numfail */
|
||||
0, /* lastTestPos */
|
||||
0, /* lastErrorLine */
|
||||
"none", /* lastErrorFile */
|
||||
"none", /* lasFunc */
|
||||
nosprintf5, /* sprintf5 function ptr */
|
||||
0, /* sprintf5 buffer */
|
||||
0, /* sprintf5 enabled flag */
|
||||
__VERSION__, /* compiler version */
|
||||
TOSTRING(NAME), /* value of name symbol */
|
||||
TOSTRING(THECCFLAGS), /* value of THECCFLAGS symbol */
|
||||
"BUILDDATE: " __DATE__, /* build date */
|
||||
mainFunctionInfoTable, /* function table */
|
||||
};
|
||||
|
||||
NOINLINE void TestInfo_reset(void)
|
||||
{
|
||||
MainInfo.numpass = 0;
|
||||
MainInfo.numfail = 0;
|
||||
MainInfo.lastTestPos = 0;
|
||||
MainInfo.lastErrorFile = "none";
|
||||
MainInfo.lastFunc = "none";
|
||||
}
|
||||
|
||||
/* Injected call when a test is done */
|
||||
|
||||
NOINLINE i4 breakOnDone(const char *file, int line, const char *func)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called from assert when a test passes */
|
||||
|
||||
NOINLINE i4 breakOnPass(void)
|
||||
{
|
||||
MainInfo.numpass++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called from assert when a test fails */
|
||||
|
||||
NOINLINE i4 breakOnError(void)
|
||||
{
|
||||
MainInfo.numfail++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Injected call when a subtest is done */
|
||||
|
||||
NOINLINE i4 breakOnSubDone(const char *file, int line, const char *func)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Injected at start of a test to record file position */
|
||||
|
||||
void noteTestMain(const char *file, int line, const char *func)
|
||||
{
|
||||
MainInfo.lastFunc = (char *) func;
|
||||
MainInfo.lastTestPos = line;
|
||||
}
|
||||
|
||||
#if defined(BUILD_EXE)
|
||||
#define DO_PRINT_INT(ok) print_int(file, line, MainInfo.lastFunc, expected, val, (ok) ? "OK" : "ERROR");
|
||||
#define DO_PRINT_LONG(ok) print_long(file, line, MainInfo.lastFunc, expected, val, (ok) ? "OK" : "ERROR");
|
||||
/* for ARM platform, and possibly others, printf does not properly handle long long args */
|
||||
#define DO_PRINT_LONGLONG(ok) print_long(file, line, MainInfo.lastFunc, (long) expected, (long) val, (ok) ? "OK" : "ERROR");
|
||||
#define DO_PRINT_UINT(ok) print_uint(file, line, MainInfo.lastFunc, expected, val, (ok) ? "OK" : "ERROR");
|
||||
#define DO_PRINT_ULONG(ok) print_ulong(file, line, MainInfo.lastFunc, expected, val, (ok) ? "OK" : "ERROR");
|
||||
#define DO_PRINT_ULONGLONG(ok) print_ulong(file, line, MainInfo.lastFunc, (long) expected, (long) val, (ok) ? "OK" : "ERROR");
|
||||
#define DO_PRINT_FLOAT(ok) print_float(file, line, MainInfo.lastFunc, expected, val, (ok) ? "OK" : "ERROR");
|
||||
#else
|
||||
#define DO_PRINT_INT(ok)
|
||||
#define DO_PRINT_LONG(ok)
|
||||
#define DO_PRINT_LONGLONG(ok)
|
||||
#define DO_PRINT_UINT(ok)
|
||||
#define DO_PRINT_ULONG(ok)
|
||||
#define DO_PRINT_ULONGLONG(ok)
|
||||
#define DO_PRINT_FLOAT(ok)
|
||||
#endif
|
||||
|
||||
/* The remaining functions are asserts. Assert functions perform
|
||||
* comparison of expected and actual values, record location of
|
||||
* errors, and call breakOnPass or breakOnError.
|
||||
*/
|
||||
|
||||
void assertI1(const char *file, int line, const char *func, i1 val, i1 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_INT(val == expected);
|
||||
}
|
||||
|
||||
void assertI2(const char *file, int line, const char *func, i2 val, i2 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_INT(val == expected);
|
||||
}
|
||||
|
||||
void assertI4(const char *file, int line, const char *func, i4 val, i4 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_INT(val == expected);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void assertI8(const char *file, int line, const char *func, i8 val, i8 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_LONGLONG(val == expected);
|
||||
}
|
||||
#endif
|
||||
|
||||
void assertU1(const char *file, int line, const char *func, u1 val, u1 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_UINT(val == expected);
|
||||
}
|
||||
|
||||
void assertU2(const char *file, int line, const char *func, u2 val, u2 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_UINT(val == expected);
|
||||
}
|
||||
|
||||
void assertU4(const char *file, int line, const char *func, u4 val, u4 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
MainInfo.numfail++;
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_UINT(val == expected);
|
||||
}
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
void assertU8(const char *file, int line, const char *func, u8 val, u8 expected)
|
||||
{
|
||||
if (val == expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_ULONGLONG(val == expected);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FLOAT
|
||||
void assertF4(const char *file, int line, const char *func, f4 val, f4 expected)
|
||||
{
|
||||
u4 u4Val = *(u4 *) & val;
|
||||
u4 u4Expected = *(u4 *) & expected;
|
||||
|
||||
/* Mask off last byte from value and expected */
|
||||
u4Val &= 0xFFFFFF00;
|
||||
u4Expected &= 0xFFFFFF00;
|
||||
|
||||
/* Should fail if diff in sign/exponent/or more than (0xFF * eplison) */
|
||||
if (u4Val == u4Expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_FLOAT(u4Val == u4Expected);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE
|
||||
void assertF8(const char *file, int line, const char *func, f8 val, f8 expected)
|
||||
{
|
||||
u8 u8Val = *(u8 *) & val;
|
||||
u8 u8Expected = *(u8 *) & expected;
|
||||
|
||||
/* Mask off last 2 bytes from value and expected */
|
||||
u8Val &= 0xFFFFFFFFFFFF0000ULL;
|
||||
u8Expected &= 0xFFFFFFFFFFFF0000ULL;
|
||||
|
||||
/* Should fail if diff in sign/exponent/or more than (0xFFFF * eplison) */
|
||||
if (u8Val == u8Expected) {
|
||||
breakOnPass();
|
||||
} else {
|
||||
MainInfo.lastErrorLine = line;
|
||||
MainInfo.lastErrorFile = (char *) file;
|
||||
breakOnError();
|
||||
}
|
||||
MainInfo.lastTestPos = line;
|
||||
DO_PRINT_FLOAT(u8Val == u8Expected);
|
||||
}
|
||||
#endif
|
||||
|
109
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.h
Normal file
109
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/pcode_test.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef PCODE_TEST_H
|
||||
#define PCODE_TEST_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define TEST void
|
||||
#define MAIN void
|
||||
|
||||
#ifdef HAS_GNU_ATTRIBUTES
|
||||
#define NOINLINE __attribute__ ((__noinline__))
|
||||
#define PACKED_STRUCTURE __attribute__((__packed__))
|
||||
#else
|
||||
#define NOINLINE
|
||||
#define PACKED_STRUCTURE
|
||||
#endif
|
||||
|
||||
typedef i4 (*entryFunc)(i4 * val);
|
||||
typedef i4 (*breakOn)(void);
|
||||
typedef i4 (*testFuncPtr)(void);
|
||||
|
||||
typedef struct PACKED_STRUCTURE FunctionInfo
|
||||
{
|
||||
char *name; /* Name of function, used in pcode test reporting */
|
||||
testFuncPtr func; /* Pointer to function */
|
||||
i4 numTest; /* Number of expected tests */
|
||||
} FunctionInfo;
|
||||
|
||||
typedef struct PACKED_STRUCTURE TestInfo
|
||||
{
|
||||
char id[8]; /* id constains a "Magic Number" which will allow us to find this in a binary */
|
||||
u4 ptrSz; /* how many bytes in a pointer? */
|
||||
u4 byteOrder; /* value 0x01020304 used to detect endianess */
|
||||
breakOn onPass; /* address of breakOnPass function, (where it goes on test pass) */
|
||||
breakOn onError; /* address of breakOnError function, (where it goes on test failure) */
|
||||
breakOn onDone; /* address of breakOnDone function, (where it goes when all test done) */
|
||||
u4 numpass; /* How many test passed */
|
||||
u4 numfail; /* How many test failed */
|
||||
u4 lastTestPos; /* Last test index number */
|
||||
u4 lastErrorLine; /* Line number of last error. */
|
||||
char *lastErrorFile; /* File name of last error. */
|
||||
char *lastFunc; /* Last function ran. */
|
||||
void *sprintf5; /* Our embedded sprintf function */
|
||||
void *sprintf5buffer; /* Buffer where our embedded sprintf write to */
|
||||
u4 sprintf5Enabled; /* Turn on off our embedded sprintf */
|
||||
char *compilerVersion; /* Compiler version info (gcc specific) */
|
||||
char *name; /* Test binary name */
|
||||
char *ccflags; /* Flags used to compile this */
|
||||
char *buildDate; /* when this was compiled */
|
||||
FunctionInfo *funcTable; /* a function table */
|
||||
} TestInfo;
|
||||
|
||||
typedef struct PACKED_STRUCTURE GroupInfo
|
||||
{
|
||||
char id[8]; /* id constains a "Magic Number" which will allow us to find this in a binary */
|
||||
FunctionInfo *funcTable; /* Table of test functions in this group */
|
||||
} GroupInfo;
|
||||
|
||||
void noteTestMain(const char *file, int line, const char *func);
|
||||
void assertI1(const char *file, int line, const char *func, i1 val, i1 expected);
|
||||
void assertI2(const char *file, int line, const char *func, i2 val, i2 expected);
|
||||
void assertI4(const char *file, int line, const char *func, i4 val, i4 expected);
|
||||
#ifdef HAS_LONGLONG
|
||||
void assertI8(const char *file, int line, const char *func, i8 val, i8 expected);
|
||||
#endif
|
||||
void assertU1(const char *file, int line, const char *func, u1 val, u1 expected);
|
||||
void assertU2(const char *file, int line, const char *func, u2 val, u2 expected);
|
||||
void assertU4(const char *file, int line, const char *func, u4 val, u4 expected);
|
||||
#ifdef HAS_LONGLONG
|
||||
void assertU8(const char *file, int line, const char *func, u8 val, u8 expected);
|
||||
#endif
|
||||
#ifdef HAS_FLOAT
|
||||
void assertF4(const char *file, int line, const char *func, f4 val, f4 expected);
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
void assertF8(const char *file, int line, const char *func, f8 val, f8 expected);
|
||||
#endif
|
||||
NOINLINE i4 breakOnDone(const char *file, int line, const char *func);
|
||||
// NOINLINE void TestInfo_register(void); /* Register a TestInfo */
|
||||
NOINLINE void TestInfo_reset(void);
|
||||
NOINLINE i4 breakOnSubDone(const char *file, int line, const char *func);
|
||||
|
||||
#define ASSERTI1(val, exp) assertI1(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTI2(val, exp) assertI2(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTI4(val, exp) assertI4(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTI8(val, exp) assertI8(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTU1(val, exp) assertU1(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTU2(val, exp) assertU2(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTU4(val, exp) assertU4(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTU8(val, exp) assertU8(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTF4(val, exp) assertF4(__FILE__, __LINE__, 0, val, exp);
|
||||
#define ASSERTF8(val, exp) assertF8(__FILE__, __LINE__, 0, val, exp);
|
||||
|
||||
#endif /* PCODE_TEST_H */
|
||||
|
364
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/types.h
Normal file
364
Ghidra/Extensions/SleighDevTools/pcodetest/c_src/types.h
Normal file
@ -0,0 +1,364 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
#define HAS_GNU_ATTRIBUTES 1
|
||||
#define FUNCNAME __FUNCTION__
|
||||
|
||||
#define NO_OPTIMIZE __attribute__((optimize("O0")))
|
||||
#elif defined(__llvm__)
|
||||
#define HAS_GNU_ATTRIBUTES 1
|
||||
#define FUNCNAME __FUNCTION__
|
||||
#define NO_OPTIMIZE __attribute__((optimize("O0")))
|
||||
#elif defined(__SDCC)
|
||||
#define FUNCNAME __func__
|
||||
#define NO_OPTIMIZE
|
||||
#else
|
||||
#if !defined(__MSP430__)
|
||||
#define __VERSION__ "version"
|
||||
#endif
|
||||
#define FUNCNAME __FUNCTION__
|
||||
#define NO_OPTIMIZE
|
||||
#endif
|
||||
|
||||
/* Make the default to have float double and long long types defined
|
||||
*/
|
||||
|
||||
#define HAS_FLOAT 1
|
||||
#define HAS_DOUBLE 1
|
||||
#define HAS_LONGLONG 1
|
||||
|
||||
#ifdef HAS_FLOAT_OVERRIDE
|
||||
#undef HAS_FLOAT
|
||||
#endif
|
||||
|
||||
#ifdef HAS_DOUBLE_OVERRIDE
|
||||
#undef HAS_DOUBLE
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG_OVERRIDE
|
||||
#undef HAS_LONGLONG
|
||||
#endif
|
||||
|
||||
/* Define some standard types, these are defined to be the same on
|
||||
* different platforms and compilers
|
||||
*/
|
||||
|
||||
#if defined(_MSV_VER)
|
||||
#define IS_COMPILER_MSVC 1
|
||||
#elif defined(__TI_COMPILER_VERSION__)
|
||||
#define IS_COMPILER_CODECOMPOSERSTUDIO 1
|
||||
#elif defined(__GNUC__) && !defined(__INT8_TYPE__) && !defined(__llvm__)
|
||||
#define IS_COMPILER_PRE48_GCC
|
||||
#elif defined(__GNUC__) && defined(__INT8_TYPE__) && !defined(__llvm__)
|
||||
#define IS_COMPILER_POST48_GCC
|
||||
#elif defined(__llvm__)
|
||||
#if !defined(__INT8_TYPE__)
|
||||
#define IS_COMPILER_PRE48_GCC
|
||||
#else
|
||||
#define IS_COMPILER_LLVM
|
||||
#endif
|
||||
#else /* defined(MSV_VER) */
|
||||
#define IS_COMPILER_UNKNOWN
|
||||
#endif
|
||||
|
||||
#if defined(IS_COMPILER_UNKNOWN) || defined(IS_COMPILER_PRE48_GCC)
|
||||
|
||||
/* Catch specific platforms */
|
||||
#ifdef __AVR_ARCH__ /* defined(IS_COMPILER_UNKNOWN) || defined(IS_COMPILER_PRE48_GCC) && defined(__AVR_ARCH__) */
|
||||
typedef unsigned char u1;
|
||||
typedef signed char i1;
|
||||
typedef unsigned short u2;
|
||||
typedef signed short i2;
|
||||
typedef unsigned long u4;
|
||||
typedef signed long i4;
|
||||
typedef long long i8;
|
||||
typedef unsigned long long u8;
|
||||
typedef float f4;
|
||||
#ifdef HAS_DOUBLE
|
||||
#endif
|
||||
typedef i4 size_t;
|
||||
#elif __AVR32__
|
||||
typedef unsigned char u1;
|
||||
typedef signed char i1;
|
||||
typedef unsigned short u2;
|
||||
typedef signed short i2;
|
||||
typedef unsigned int u4;
|
||||
typedef signed int i4;
|
||||
#ifdef HAS_LONGLONG
|
||||
typedef long long i8;
|
||||
typedef unsigned long long u8;
|
||||
#endif
|
||||
#ifdef HAS_FLOAT
|
||||
typedef float f4;
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
typedef double f8;
|
||||
#endif
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
#else /* defined(IS_COMPILER_UNKNOWN) || defined(IS_COMPILER_PRE48_GCC) && !defined(__AVR_ARCH__) */
|
||||
/* This is for non-GNU non CodeComposerStudio generic case. */
|
||||
typedef unsigned char u1;
|
||||
typedef signed char i1;
|
||||
typedef unsigned short u2;
|
||||
typedef signed short i2;
|
||||
#ifdef INT4_IS_LONG
|
||||
typedef unsigned long u4;
|
||||
typedef signed long i4;
|
||||
#else
|
||||
typedef unsigned int u4;
|
||||
typedef signed int i4;
|
||||
#endif
|
||||
#ifdef HAS_LONGLONG
|
||||
typedef long long i8;
|
||||
typedef unsigned long long u8;
|
||||
#endif
|
||||
#ifdef HAS_FLOAT
|
||||
typedef float f4;
|
||||
#endif
|
||||
#ifdef HAS_DOUBLE
|
||||
#ifdef dsPIC30
|
||||
typedef long double f8;
|
||||
#else
|
||||
typedef double f8;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAS_LONGLONG
|
||||
typedef i8 size_t;
|
||||
#else
|
||||
typedef i4 size_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* #if defined(IS_COMPILER_UNKNOWN) || defined(IS_COMPILER_PRE48_GCC) */
|
||||
|
||||
/* For CodeComposerStudio */
|
||||
#if defined(IS_COMPILER_CODECOMPOSERSTUDIO)
|
||||
|
||||
#if defined(__MSP430__) /* defined(IS_COMPILER_CODECOMPOSERSTUDIO) && defined(__MSP430__) */
|
||||
|
||||
typedef unsigned char u1;
|
||||
typedef signed char i1;
|
||||
typedef unsigned short u2;
|
||||
typedef signed short i2;
|
||||
typedef unsigned long u4;
|
||||
typedef signed long i4;
|
||||
|
||||
#undef HAS_FLOAT
|
||||
#undef HAS_DOUBLE
|
||||
#undef HAS_LONGLONG
|
||||
#undef HAS_GNU_ATTRIBUTES
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#endif /* #if defined(__MSP430__) */
|
||||
|
||||
#endif /* #if defined(IS_COMPILER_CODECOMPOSERSTUDIO) */
|
||||
|
||||
/* For GNU compilers */
|
||||
/* Modern GNU compilers > 4.7 have size macros to uses to give us definitions. */
|
||||
|
||||
#if defined(IS_COMPILER_POST48_GCC)
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
|
||||
typedef __INT8_TYPE__ i1;
|
||||
typedef __INT16_TYPE__ i2;
|
||||
typedef __INT32_TYPE__ i4;
|
||||
#if defined(__INT64_TYPE__)
|
||||
#ifdef HAS_LONGLONG
|
||||
typedef __INT64_TYPE__ i8;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef __UINT8_TYPE__ u1;
|
||||
typedef __UINT16_TYPE__ u2;
|
||||
typedef __UINT32_TYPE__ u4;
|
||||
#if defined(__UINT64_TYPE__)
|
||||
#ifdef HAS_LONGLONG
|
||||
typedef __UINT64_TYPE__ u8;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SIZEOF_FLOAT__
|
||||
#ifdef HAS_FLOAT
|
||||
typedef float f4;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __SIZEOF_DOUBLE__
|
||||
#ifdef HAS_DOUBLE
|
||||
typedef double f8;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define TYPES_ARE_DEFINED 1
|
||||
#endif /* #if defined(IS_COMPILER_POST48_GCC) */
|
||||
|
||||
/* Microsoft VisualC++ compiler */
|
||||
#if defined(IS_COMPILER_MSVC)
|
||||
|
||||
/* ARM on Visual C++ */
|
||||
#if defined(_M_ARM_FP) /* defined(IS_COMPILER_MSVC) && defined(_M_ARM_FP) */
|
||||
typedef unsigned char u1;
|
||||
typedef signed char i1;
|
||||
typedef unsigned short u2;
|
||||
typedef signed short i2;
|
||||
typedef unsigned long u4;
|
||||
typedef signed long i4;
|
||||
|
||||
#undef HAS_FLOAT
|
||||
#undef HAS_DOUBLE
|
||||
#undef HAS_LONGLONG
|
||||
#undef HAS_GNU_ATTRIBUTES
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
#endif /* #if defined(IS_COMPILER_MSVC) */
|
||||
|
||||
#endif /* #if defined(_M_ARM_FP) */
|
||||
|
||||
#ifdef IS_COMPILER_LLVM
|
||||
typedef unsigned char u1;
|
||||
typedef signed char i1;
|
||||
typedef unsigned short u2;
|
||||
typedef signed short i2;
|
||||
typedef unsigned __INT32_TYPE__ u4;
|
||||
typedef signed __INT32_TYPE__ i4;
|
||||
#ifdef __INT64_TYPE__
|
||||
typedef unsigned long long u8;
|
||||
typedef signed long long i8;
|
||||
#define HAS_LONGLONG
|
||||
#else
|
||||
#undef HAS_LONGLONG
|
||||
#endif /* LONGLONG */
|
||||
#ifdef __SIZEOF_FLOAT__
|
||||
typedef float f4;
|
||||
#define HAS_FLOAT
|
||||
#else
|
||||
#undef HAS_FLOAT
|
||||
#endif /* FLOAT */
|
||||
#ifdef __SIZEOF_DOUBLE__
|
||||
typedef double f8;
|
||||
#define HAS_DOUBLE
|
||||
#else
|
||||
#undef HAS_DOUBLE
|
||||
#endif /* DOUBLE */
|
||||
|
||||
/* __is_identifier __has_feature */
|
||||
#ifdef __has_feature /* LLVM clang magic (see clang docs) */
|
||||
#pragma message "has __has_feature"
|
||||
#if __has_feature(size_t)
|
||||
#pragma message "has size_t"
|
||||
#else
|
||||
#pragma message "define size_t"
|
||||
#if __SIZEOF_SIZE_T__ == 8
|
||||
typedef u8 size_t;
|
||||
#elif __SIZEOF_SIZE_T__== 4
|
||||
typedef u4 size_t;
|
||||
#elif __SIZEOF_SIZE_T__ == 2
|
||||
typedef u2 size_t;
|
||||
#elif __SIZEOF_SIZE_T__ == 1
|
||||
typedef i1 size_t;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#pragma message "has NOT __has_feature"
|
||||
#endif /* #ifdef __has_feature */
|
||||
|
||||
#endif /* #ifdef IS_COMPILER_LLVM */
|
||||
|
||||
/* Simulated limit.h */
|
||||
#define U1_MAX 0xFF
|
||||
#define U1_MIN 0
|
||||
#define U2_MAX 0xFFFF
|
||||
#define U2_MIN 0
|
||||
#define U4_MAX 0xFFFFFFFFU
|
||||
#define U4_MIN 0
|
||||
#define U8_MAX 0xFFFFFFFFFFFFFFFFULL
|
||||
#define U8_MIN 0
|
||||
#define I1_MAX 0x7F
|
||||
#define I1_MIN (-128)
|
||||
#define I2_MAX 0x7FFF
|
||||
#define I2_MIN (-32768)
|
||||
#define I4_MAX 0x7FFFFFFF
|
||||
#define I4_MIN (-I4_MAX - 1)
|
||||
#define I8_MAX 9223372036854775807LL
|
||||
#define I8_MIN (-I8_MAX - 1LL)
|
||||
|
||||
/* Simulate float.h assumes IEEE standard format and 4 8 10 byte formats (FLT_, DBL_, LDBL_) (FLT_ maps to F4, DBL_ maps to F8) */
|
||||
|
||||
#define DBL_DIG 15
|
||||
#define DBL_EPSILON 2.2204460492503131e-16
|
||||
#define DBL_MANT_DIG 53
|
||||
#define DBL_MAX_10_EXP 308
|
||||
#define DBL_MAX 1.7976931348623157e+308
|
||||
|
||||
#define DBL_MAX_EXP 1024
|
||||
#define DBL_MIN_10_EXP (-307)
|
||||
#define DBL_MIN 2.2250738585072014e-308
|
||||
#define DBL_MIN_EXP (-1021)
|
||||
|
||||
#define LDBL_DIG 18
|
||||
#define LDBL_EPSILON 1.08420217248550443401e-19L
|
||||
#define LDBL_MANT_DIG 64
|
||||
#define LDBL_MAX_10_EXP 4932
|
||||
#define LDBL_MAX_EXP 16384
|
||||
|
||||
#define LDBL_MAX 1.18973149535723176502e+4932L
|
||||
#define LDBL_MIN_10_EXP (-4931)
|
||||
#define LDBL_MIN_EXP (-16381)
|
||||
#define LDBL_MIN 3.36210314311209350626e-4932L
|
||||
|
||||
#define FLT_DIG 6
|
||||
#define FLT_EPSILON 1.19209290e-7F
|
||||
#define FLT_MANT_DIG 24
|
||||
#define FLT_MAX_10_EXP 38
|
||||
#define FLT_MAX_EXP 128
|
||||
|
||||
#define FLT_MAX 3.40282347e+38F
|
||||
#define FLT_MIN_10_EXP (-37)
|
||||
#define FLT_MIN_EXP (-125)
|
||||
#define FLT_MIN 1.17549435e-38F
|
||||
#define FLT_RADIX 2
|
||||
|
||||
#define FLT_ROUNDS 1
|
||||
|
||||
#define PI_SHORT 3.14
|
||||
|
||||
#ifdef HAS_LIBC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAS_LIBC
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
int memcmp(void *s1, void *s2, size_t n);
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_EXE
|
||||
#ifndef HAS_LIBC
|
||||
void write(int fd, char *buf, int count);
|
||||
void exit(int stat);
|
||||
#endif
|
||||
void print_int(char *file, int line, char *func, int expected, int val, char *ok);
|
||||
void print_long(char *file, int line, char *func, long expected, long val, char *ok);
|
||||
void print_uint(char *file, int line, char *func, unsigned int expected, unsigned int val, char *ok);
|
||||
void print_ulong(char *file, int line, char *func, unsigned long expected, unsigned long val, char *ok);
|
||||
void print_float(char *file, int line, char *func, float expected, float val, char *ok);
|
||||
void print_val(char *name, int val);
|
||||
#endif
|
38
Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py
Normal file
38
Ghidra/Extensions/SleighDevTools/pcodetest/defaults.py
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
# Default values can be modified here, or (in
|
||||
# some cases) on the build command line (see ./build --help)
|
||||
|
||||
# PCodeTest.defaults that can be overridden on command line
|
||||
|
||||
PCodeTest.defaults.toolchain_root = '/local/ToolChains'
|
||||
PCodeTest.defaults.build_root = '/local/build-pcodetest'
|
||||
PCodeTest.defaults.gcc_version = '7.3.0'
|
||||
PCodeTest.defaults.skip_files = []
|
||||
PCodeTest.defaults.export_root = os.getcwd() + '/../../../../../../ghidra.bin/Ghidra/Test/TestResources/data/pcodetests/'
|
||||
PCodeTest.defaults.pcodetest_src = os.getcwd() + '/c_src'
|
||||
|
||||
# PCodeTest.defaults that cannot be overridden on the command line
|
||||
|
||||
PCodeTest.defaults.build_all = 0
|
||||
PCodeTest.defaults.ccflags = ''
|
||||
PCodeTest.defaults.has_decimal128 = 0
|
||||
PCodeTest.defaults.has_decimal32 = 0
|
||||
|
||||
|
||||
PCodeTest.defaults.has_decimal64 = 0
|
||||
PCodeTest.defaults.has_double = 1
|
||||
PCodeTest.defaults.has_float = 1
|
||||
PCodeTest.defaults.has_longlong = 1
|
||||
PCodeTest.defaults.has_shortfloat = 0
|
||||
PCodeTest.defaults.has_vector = 0
|
||||
PCodeTest.defaults.small_build = 0
|
||||
PCodeTest.defaults.ld_library_path = ''
|
||||
PCodeTest.defaults.toolchain_type = 'gcc'
|
||||
PCodeTest.defaults.compile_exe = 'bin/gcc'
|
||||
PCodeTest.defaults.objdump_exe = 'bin/objdump'
|
||||
PCodeTest.defaults.objdump_option = ''
|
||||
PCodeTest.defaults.readelf_exe = 'bin/readelf'
|
||||
PCodeTest.defaults.nm_exe = 'bin/nm'
|
||||
PCodeTest.defaults.strip_exe = 'bin/strip'
|
||||
PCodeTest.defaults.variants = {'O0': '-O0', 'O3': '-O3'}
|
||||
|
611
Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py
Normal file
611
Ghidra/Extensions/SleighDevTools/pcodetest/pcode_defs.py
Normal file
@ -0,0 +1,611 @@
|
||||
|
||||
# The available pcode tests are recorded here as instances of the 'name'
|
||||
# python class.
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-arm',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
'ccflags': '-L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM_BE',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-armbe',
|
||||
'toolchain': 'ARM/armbe-eabi',
|
||||
'language_id': 'ARM:BE:32:v7',
|
||||
'ccflags': '-mbig-endian -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM2',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mcpu=arm2 -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM7',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mcpu=arm7 -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM8',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mcpu=arm8 -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM9',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mcpu=arm9 -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM10e',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-arm',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mcpu=arm10e -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM_thumb',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-arm -cpu cortex-a8',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mthumb -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s/thumb -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM_BE_thumb',
|
||||
'build_all': 1,
|
||||
'toolchain': 'ARM/armbe-eabi',
|
||||
'ccflags': '-mthumb -mbig-endian -L %(toolchain_dir)s/lib/gcc/armbe-eabi/%(gcc_version)s/thumb -lgcc',
|
||||
'language_id': 'ARM:BE:32:v7',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ARM_cortex',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-arm -cpu cortex-a8',
|
||||
'toolchain': 'ARM/arm-eabi',
|
||||
'ccflags': '-mthumb -mcpu=cortex-a8 -mfloat-abi=softfp -L %(toolchain_dir)s/lib/gcc/arm-eabi/%(gcc_version)s/thumb -lgcc',
|
||||
'language_id': 'ARM:LE:32:v7',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AARCH64',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-aarch64',
|
||||
'toolchain': 'ARM/aarch64-elf',
|
||||
'language_id': 'AARCH64:LE:64:v8A',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AARCH64_ILP32',
|
||||
'toolchain': 'ARM/aarch64-elf',
|
||||
'ccflags': '-mabi=ilp32',
|
||||
'language_id': 'AARCH64:LE:64:v8A',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AARCH64_BE',
|
||||
'build_all': 1,
|
||||
'toolchain': 'ARM/aarch64_be-elf',
|
||||
'language_id': 'AARCH64:BE:64:v8A',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AARCH64_BE_ILP32',
|
||||
'toolchain': 'ARM/aarch64_be-elf',
|
||||
'ccflags': '-mabi=ilp32',
|
||||
'language_id': 'AARCH64:BE:64:v8A',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AVR',
|
||||
'build_all': 1,
|
||||
'toolchain': 'AVR/avr-elf',
|
||||
'ccflags': '-mmcu=avr6 -lgcc',
|
||||
'language_id': 'avr32:BE:32:default',
|
||||
'processor': 'Atmel',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AVR8_31',
|
||||
'toolchain': 'AVR/avr-elf',
|
||||
'ccflags': '-mmcu=avr31 -lgcc',
|
||||
'language_id': 'avr8:LE:16:default',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
'small_build': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AVR8_51',
|
||||
'toolchain': 'AVR/avr-elf',
|
||||
'ccflags': '-mmcu=avr51 -lgcc',
|
||||
'language_id': 'avr8:LE:16:extended',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
'small_build': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AVR8_X5',
|
||||
'toolchain': 'AVR/avr-elf',
|
||||
'ccflags': '-mmcu=avrxmega5 -lgcc',
|
||||
'language_id': 'avr8:LE:16:atmega256',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
'small_build': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'HCS12',
|
||||
'toolchain': 'HCS12/m6812',
|
||||
'language_id': 'HCS12:BE:16:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'HPPA1.1',
|
||||
'build_all': 1,
|
||||
'toolchain': 'HPPA/hppa-linux',
|
||||
'ccflags': '-march=1.1 -static -mlong-calls -L %(toolchain_dir)s/lib/gcc/hppa-linux/%(gcc_version)s -lgcc',
|
||||
'language_id': 'pa-risc:BE:32:default',
|
||||
'processor': 'PA-RISC',
|
||||
'architecture_test': 'PARISC',
|
||||
})
|
||||
|
||||
|
||||
# Note that libgcc.a was built for m68020 which has a different function calling convention from pre-68020
|
||||
|
||||
PCodeTest({
|
||||
'name': 'm68000',
|
||||
'build_all': 1,
|
||||
'build_exe': 0,
|
||||
'qemu_command': 'qemu-m68k', # qemu: fatal: Illegal instruction
|
||||
'toolchain': 'm68k/m68k-elf',
|
||||
'ccflags': '-mcpu=68020 -m68020 -L %(toolchain_dir)s/lib/gcc/m68k-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': '68000:BE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-mips',
|
||||
'toolchain': 'MIPS/mips-elf',
|
||||
'ccflags': '-L %(toolchain_dir)s/lib/gcc/mips-mti-elf/%(gcc_version)s -lgcc -mno-gpopt',
|
||||
'language_id': 'MIPS:BE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPSEL',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'toolchain': 'MIPS/mips-elf',
|
||||
'ccflags': '-L %(toolchain_dir)s/lib/gcc/mips-mti-elf/%(gcc_version)s/el -lgcc -mno-gpopt -mel',
|
||||
'language_id': 'MIPS:LE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS16',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-mips',
|
||||
'toolchain': 'MIPS/mips-elf',
|
||||
'ccflags': '-mno-gpopt',
|
||||
'language_id': 'MIPS:BE:32:default',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS16MIX',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-mips',
|
||||
'toolchain': 'MIPS/mips-elf',
|
||||
'ccflags': '-mno-gpopt',
|
||||
'language_id': 'MIPS:BE:32:default',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPSMIC',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mips-elf',
|
||||
'ccflags': '-mmicromips -L %(toolchain_dir)s/lib/gcc/mips-mti-elf/%(gcc_version)s/micromips -lgcc',
|
||||
'language_id': 'MIPS:BE:32:micro',
|
||||
'architecture_test': 'MIPSMICRO',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPSMICMIX',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mips-elf',
|
||||
'ccflags': '-minterlink-compressed -D BODYNEW=micromips -L %(toolchain_dir)s/lib/gcc/mips-mti-elf/%(gcc_version)s/micromips -lgcc',
|
||||
'language_id': 'MIPS:BE:32:micro',
|
||||
'architecture_test': 'MIPSMICROMIX',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPSMIC64',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mipsr6-elf',
|
||||
'ccflags': '-mips64r5 -mmicromips -minterlink-compressed',
|
||||
'language_id': 'MIPS:BE:64:micro',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS64_32addr',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mipsr6-elf',
|
||||
'ccflags': '-mips64r2',
|
||||
'language_id': 'MIPS:BE:64:64-32addr',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS64_64addr',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mipsr6-elf',
|
||||
'ccflags': '-mips64r2 -mabi=64',
|
||||
'language_id': 'MIPS:BE:64:64-64addr',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS64_64addrLE',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mipsr6-elf',
|
||||
'ccflags': '-mips64r2 -mabi=64 -EL',
|
||||
'language_id': 'MIPS:LE:64:64-64addr',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPSR6',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mipsr6-elf',
|
||||
'ccflags': '-mips32r6 -L %(toolchain_dir)s/lib/gcc/mips-mti-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'MIPS:BE:32:R6',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'MIPS64R6',
|
||||
'build_all': 1,
|
||||
'toolchain': 'MIPS/mipsr6-elf',
|
||||
'ccflags': '-mips64r6 -mabi=64',
|
||||
'language_id': 'MIPS:BE:64:R6',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'NDS32BE',
|
||||
'build_all': 1,
|
||||
'toolchain': 'NDS32/nds32be-elf',
|
||||
'ccflags': '-L %(toolchain_dir)s/lib/gcc/nds32be-linux-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'NDS32:BE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'NDS32LE',
|
||||
'build_all': 1,
|
||||
'toolchain': 'NDS32/nds32le-elf',
|
||||
'ccflags': '-L %(toolchain_dir)s/lib/gcc/nds32le-linux-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'NDS32:LE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'power6',
|
||||
'toolchain': 'PPC/powerpc-elf',
|
||||
'ccflags': '-mcpu=G5 -m32 -mno-relocatable -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'powerpc32',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-ppc64abi32',
|
||||
'toolchain': 'PPC/powerpc-elf',
|
||||
'ccflags': '-mcpu=powerpc -m32 -maltivec -mno-relocatable -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:32:default',
|
||||
'architecture_test': 'PPC',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'powerpc64',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-ppc64',
|
||||
'toolchain': 'PPC/powerpc64-linux',
|
||||
'ccflags': '-mabi=elfv1 -maltivec -mno-relocatable -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:64:default',
|
||||
'architecture_test': 'PPC64',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'powerpc64v2',
|
||||
'toolchain': 'PPC/powerpc64-linux',
|
||||
'ccflags': '-mabi=elfv2 -maltivec -mno-relocatable -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:64:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ppcA2',
|
||||
'build_all': 1,
|
||||
'toolchain': 'PPC/powerpc-elf',
|
||||
'ccflags': '-mcpu=a2 -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:32:A2',
|
||||
'architecture_test': 'PPCA2',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ppcA2Alt',
|
||||
'build_all': 1,
|
||||
'toolchain': 'PPC/powerpc-elf',
|
||||
'ccflags': '-mcpu=a2 -maltivec -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:32:A2ALT',
|
||||
'architecture_test': 'PPCA2Alt',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ppcP8Alt',
|
||||
'build_all': 1,
|
||||
'toolchain': 'PPC/powerpc-elf',
|
||||
'ccflags': '-mcpu=power8 -mvsx -maltivec -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:32:A2ALT',
|
||||
'architecture_test': 'PPCP8Alt',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'ppcP9Alt',
|
||||
'build_all': 1,
|
||||
'toolchain': 'PPC/powerpc-elf',
|
||||
'ccflags': '-mcpu=power9 -mvsx -maltivec -L %(toolchain_dir)s/lib/gcc/powerpc-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'PowerPC:BE:32:A2ALT',
|
||||
'architecture_test': 'PPCP9Alt',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'msp430x',
|
||||
'build_all': 1,
|
||||
'toolchain': 'TI/msp430-elf',
|
||||
'ccflags': '-g -mmcu=msp430x -mlarge -mhwmult=none -fno-builtin -Wl,-T,msp430x.ld -L %(toolchain_dir)s/lib/gcc/msp430-elf/%(gcc_version)s/large/ -lgcc -lmul_none',
|
||||
'language_id': 'TI_MSP430X:LE:32:default',
|
||||
'processor': 'TI',
|
||||
'architecture_test': 'MSP430X',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
'small_build': 1,
|
||||
'skip_files': ['PointerManipulation.test', 'misc.test'],
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'SH4',
|
||||
'build_all': 1,
|
||||
'build_exe': 0,
|
||||
'qemu_command': 'qemu-sh4eb', # qemu gets "Invalid argument" error
|
||||
'toolchain': 'SuperH4/sh4-elf',
|
||||
'ccflags': '-mb -mrenesas -m4 -L %(toolchain_dir)s/lib/gcc/sh4-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'SuperH4:BE:32:default',
|
||||
'architecture_test': 'SuperH4_BE',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'SH4_LE',
|
||||
'build_all': 1,
|
||||
'toolchain': 'SuperH4/sh4le-elf',
|
||||
'ccflags': '-ml -mrenesas -m4 -L %(toolchain_dir)s/lib/gcc/sh4le-elf/%(gcc_version)s -lgcc',
|
||||
'language_id': 'SuperH4:LE:32:default',
|
||||
'architecture_test': 'SuperH4',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'sparcV9_32',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'can_run': 0, # instruction error causes infinite loop
|
||||
'qemu_command': 'qemu-sparc32plus',
|
||||
'toolchain': 'SparcV9/sparc-elf',
|
||||
'ccflags': '-mcpu=v9 -m32',
|
||||
'language_id': 'sparc:BE:32:default',
|
||||
'processor': 'Sparc',
|
||||
'architecture_test': 'SparcV9_m32',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
# to suppress usage of application registers g2 and g3, add -mno-app-regs here
|
||||
|
||||
PCodeTest({
|
||||
'name': 'sparcV9_64',
|
||||
'build_all': 1,
|
||||
'toolchain': 'SparcV9/sparc64-elf',
|
||||
'ccflags': '-mcpu=v9 -m64',
|
||||
'language_id': 'sparc:BE:64:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'pentium',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-i386',
|
||||
'toolchain': 'x86/i386-elf-linux',
|
||||
'ccflags': '-march=pentium -m32 -L %(toolchain_dir)s/lib/gcc/i386-elf-linux/%(gcc_version)s -lgcc',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:32:default',
|
||||
'architecture_test': 'X86m32',
|
||||
'has_vector': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'i386_CLANG',
|
||||
'toolchain': 'LLVM/llvm',
|
||||
'toolchain_type': 'llvm',
|
||||
'ccflags': '--target=i386',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'i686_CLANG',
|
||||
'toolchain': 'LLVM/llvm',
|
||||
'toolchain_type': 'llvm',
|
||||
'ccflags': '--target=i686',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:32:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AVX2',
|
||||
'build_all': 1,
|
||||
'toolchain': 'x86/x86_64-elf',
|
||||
'ccflags': '-march=core-avx2',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:64:default',
|
||||
'has_vector': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'AVXi',
|
||||
'toolchain': 'x86/x86_64-elf',
|
||||
'ccflags': '-march=core-avx-i',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:64:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'bdver2',
|
||||
'toolchain': 'x86/x86_64-elf',
|
||||
'ccflags': '-march=bdver2',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:64:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'core2',
|
||||
'toolchain': 'x86/x86_64-elf',
|
||||
'ccflags': '-march=bdver2',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:64:default',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'x86_m64',
|
||||
'build_all': 1,
|
||||
'build_exe': 1,
|
||||
'qemu_command': 'qemu-x86_64',
|
||||
'toolchain': 'x86/x86_64-elf',
|
||||
'ccflags': '-static -m64',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:64:default',
|
||||
'architecture_test': 'X86m64',
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'x86_fma4',
|
||||
'toolchain': 'x86/x86_64-elf',
|
||||
'ccflags': '-mfma',
|
||||
'objdump_option': '-M intel',
|
||||
'language_id': 'x86:LE:64:default',
|
||||
})
|
||||
|
||||
# the PIC30 toolchain is distributed by mchp. So when making the
|
||||
# toolchain, specify toolchain_type to be mchp. But it is based on
|
||||
# gcc, and after it's installed, it behaves exactly like gcc. So, when
|
||||
# making a pcode test, specify toolchain_type to be gcc.
|
||||
|
||||
PCodeTest({
|
||||
'name': 'PIC30',
|
||||
'build_all': 1,
|
||||
'toolchain': 'PIC/xc16',
|
||||
'compile_exe': 'bin/xc16-gcc',
|
||||
'objdump_exe': 'bin/xc16-objdump',
|
||||
'readelf_exe': 'bin/xc16-readelf',
|
||||
'nm_exe': 'bin/xc16-nm',
|
||||
'ccflags': '-mcpu=30F2011 -DINT4_IS_LONG -Xlinker --defsym -Xlinker _main=0x0 -L %(toolchain_dir)s/lib -lpic30 -lc -lm',
|
||||
'language_id': 'dsPIC30F:LE:24:default',
|
||||
'skip_files': ['misc.test'],
|
||||
'variants': {'O0': '-O0'},
|
||||
'small_build': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'PIC16',
|
||||
'toolchain': 'PIC/xc8',
|
||||
'compile_exe': 'bin/xc8',
|
||||
'objdump_exe': 'bin/dump',
|
||||
'ccflags': '-chip=16C57 -DINT4_IS_LONG -DSTATIC_MAIN -L %(toolchain_dir)s/lib -lpic30 -lc -lm',
|
||||
'language_id': 'dsPIC16F:LE:24:default',
|
||||
'small_build': 1,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'HCS08',
|
||||
'toolchain': 'SDCC/s08',
|
||||
'toolchain_type': 'sdcc',
|
||||
'compile_exe': 'bin/sdcc',
|
||||
'ccflags': '--out-fmt-elf --std-sdcc11',
|
||||
'language_id': 'HCS08:BE:16:MC9S08GB60',
|
||||
'variants': {'OX': ''},
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'CR16C',
|
||||
'build_all': 1,
|
||||
'toolchain': 'NS/cr16-elf',
|
||||
'language_id': 'CR16C:LE:16:default',
|
||||
'processor': 'CR16',
|
||||
'architecture_test': 'CRC16C',
|
||||
'ccflags': '-lgcc',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
||||
|
||||
PCodeTest({
|
||||
'name': 'RISCV',
|
||||
'build_all': 1,
|
||||
'toolchain': 'RISCV/riscv32-elf',
|
||||
'language_id': 'RISCV:BE:32:default',
|
||||
'architecture_test': 'RISCV',
|
||||
'ccflags': '-lgcc',
|
||||
'has_float': 0,
|
||||
'has_double': 0,
|
||||
'has_longlong': 0,
|
||||
})
|
443
Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py
Normal file
443
Ghidra/Extensions/SleighDevTools/pcodetest/pcodetest.py
Normal file
@ -0,0 +1,443 @@
|
||||
import os
|
||||
import glob
|
||||
import re
|
||||
import fnmatch
|
||||
|
||||
from build import Config, BuildUtil
|
||||
|
||||
class PCodeTest(BuildUtil):
|
||||
|
||||
defaults = Config()
|
||||
list = { }
|
||||
|
||||
def __init__(self, conf):
|
||||
super(PCodeTest, self).__init__()
|
||||
self.config = Config(PCodeTest.defaults, conf)
|
||||
|
||||
# calculate the toolchain_dir
|
||||
self.config.toolchain_dir = self.config.format('%(toolchain_root)s/%(toolchain)s-gcc-%(gcc_version)s')
|
||||
if not self.isdir(self.config.toolchain_dir):
|
||||
self.config.toolchain_dir = self.config.format('%(toolchain_root)s/%(toolchain)s')
|
||||
|
||||
(self.config.toolchain_family, self.config.install_target) = self.config.toolchain.split('/')
|
||||
if not self.config.target: self.config.target = self.config.install_target
|
||||
|
||||
# can default the Processor directory name, usually the
|
||||
# initial string of 'language_id' (otherwise unused).
|
||||
|
||||
if self.config.language_id:
|
||||
self.config.processor = self.config.language_id.split(':')[0]
|
||||
|
||||
# expand all of the variables with printf escapes
|
||||
|
||||
self.config.expand()
|
||||
|
||||
# save the new PCodeTest in a dictionary for auto-enumeration
|
||||
|
||||
PCodeTest.list[self.config.name] = self
|
||||
|
||||
@classmethod
|
||||
def print_all(cls):
|
||||
pct = sorted(cls.list.iteritems(), key=lambda x: x[0].lower())
|
||||
|
||||
for t,pcodetest in sorted(cls.list.iteritems(), key=lambda x: x[0].lower()):
|
||||
print str(pcodetest)
|
||||
if pcodetest.config.verbose: print pcodetest.config.dump()
|
||||
|
||||
def __str__(self):
|
||||
cb = 'build-all:%-5s' % ('yes' if self.config.build_all else 'no')
|
||||
ce = 'can-export:%-5s' % ('yes' if self.config.can_export else 'no')
|
||||
ct = 'compiler-type:%-5s' % self.config.toolchain_type
|
||||
tc = 'Toolchain:%s' % self.config.toolchain
|
||||
return self.config.architecture.ljust(20) + cb + ce + ct + tc
|
||||
|
||||
class PCodeTestBuild(BuildUtil):
|
||||
def __init__(self, pcode_test):
|
||||
super(PCodeTestBuild, self).__init__()
|
||||
self.config = Config(pcode_test.config)
|
||||
self.config.cwd = self.getcwd()
|
||||
|
||||
@classmethod
|
||||
def factory(cls, pcode_test):
|
||||
if pcode_test.config.toolchain_type == 'gcc':
|
||||
return PCodeBuildGCC(pcode_test)
|
||||
elif pcode_test.config.toolchain_type == 'ccs':
|
||||
return PCodeBuildCCS(pcode_test)
|
||||
elif pcode_test.config.toolchain_type == 'sdcc':
|
||||
return PCodeBuildSDCC(pcode_test)
|
||||
else:
|
||||
raise Exception(self.config.format('Toolchain type %(toolchain_type)s not known'))
|
||||
|
||||
def which(self, what):
|
||||
return self.config.format('%(toolchain_dir)s/%(' + what + ')s')
|
||||
|
||||
def compile(self, input_files, opt_cflag, output_base):
|
||||
self.log_err(self.config.format('compile not implemented for %(toolchain_type)s'))
|
||||
|
||||
# generic build a single PCodeTest for all variants
|
||||
def main(self):
|
||||
|
||||
# make sure compiler exists and runnable
|
||||
|
||||
if not self.is_executable_file(self.which('compile_exe')):
|
||||
self.log_err(self.config.format('build the Toolchain before compilation'))
|
||||
return
|
||||
|
||||
# save path to tpp
|
||||
tpp_py = os.getcwd() + '/tpp.py'
|
||||
|
||||
# Get a list of strings to filter input files
|
||||
available_files = sorted(glob.glob(self.config.format('%(pcodetest_src)s/*')))
|
||||
|
||||
# skip any?
|
||||
skip_files = self.config.skip_files
|
||||
if len(skip_files) > 0:
|
||||
toskip = [x for x in available_files if self.basename(x) in skip_files]
|
||||
if len(toskip) != len(skip_files):
|
||||
self.log_warn('These files will not be skipped because they are not in the build: %s'
|
||||
% ' '.join([x for x in skip_files if not x in toskip]))
|
||||
available_files = [x for x in available_files if not x in toskip]
|
||||
|
||||
# remove float/double/longlong files if not supported
|
||||
if not self.config.has_float: available_files = [x for x in available_files if not fnmatch.fnmatch(x, '*FLOAT*')]
|
||||
if not self.config.has_double: available_files = [x for x in available_files if not fnmatch.fnmatch(x, '*DOUBLE*')]
|
||||
if not self.config.has_longlong: available_files = [x for x in available_files if not fnmatch.fnmatch(x, '*LONGLONG*')]
|
||||
|
||||
# compile for each optimization
|
||||
for opt_name,opt_cflag in sorted(self.config.variants.iteritems()):
|
||||
|
||||
kind = 'PCodeTest'
|
||||
|
||||
# This is the base name of the binary file, or for small
|
||||
# build, the directory name that will hold the small
|
||||
# binaries
|
||||
|
||||
out_name = '%s_%s_%s_pcodetest' % (self.config.name, self.config.toolchain_type.upper(), opt_name)
|
||||
if self.config.architecture_test: pcodetest_base_name = self.config.architecture_test
|
||||
else: pcodetest_base_name = self.config.architecture
|
||||
pcodetest_test = '%s_%s_EmulatorTest' % (pcodetest_base_name, opt_name)
|
||||
|
||||
# GNUMake like rule to prevent un-required builds of pcodetests files
|
||||
# This does not rebuild if the output directory is newer than the
|
||||
# input files. So it needs to know where the build
|
||||
# directory would be, before it is recreated.
|
||||
|
||||
build_dir = self.build_dir(self.config.build_root, kind, out_name)
|
||||
need_to_build = self.config.force or not self.isdir(build_dir)
|
||||
if not need_to_build:
|
||||
mtime = self.getmtime(build_dir)
|
||||
for f in available_files:
|
||||
if mtime < self.getmtime(f):
|
||||
need_to_build = True
|
||||
break
|
||||
|
||||
if not need_to_build:
|
||||
self.log_info('%s up to date (call with --force to force build)' % self.log_prefix(kind, out_name))
|
||||
continue
|
||||
|
||||
self.open_log(self.config.build_root, kind, out_name, chdir=True)
|
||||
|
||||
# copy source files to build directory, and go there
|
||||
for f in available_files: self.copy(f, '.', verbose=False)
|
||||
|
||||
# if requested, add an info file
|
||||
|
||||
if self.config.add_info: self.mkinfo('INFO.c')
|
||||
|
||||
# make tests, if needed
|
||||
|
||||
for f_test in glob.glob('*.test'):
|
||||
f_h = re.sub(r'[.]test', '.h', f_test)
|
||||
if self.isfile(f_h) and self.getmtime(f_test) <= self.getmtime(f_h): continue
|
||||
out, err = self.run(['python', tpp_py, f_test])
|
||||
if err:
|
||||
self.log_err(err)
|
||||
out, err = self.run(['python', tpp_py, '--entry', 'pcode_main.c'])
|
||||
if err:
|
||||
self.log_err(err)
|
||||
|
||||
if self.num_errors > 0:
|
||||
self.chdir(self.config.cwd)
|
||||
self.log_close()
|
||||
continue
|
||||
|
||||
if self.config.small_build:
|
||||
# For a small build, build a binary for every
|
||||
# _BODY.c file in the smallFiles list.
|
||||
smallFiles = sorted(glob.glob('*_BODY.c'))
|
||||
self.log_info('**** SMALL BUILD ****')
|
||||
|
||||
# Remove the previous directory, if it was there
|
||||
|
||||
build_dir = '%s/build-PCodeTest-%s/%s' % (self.config.build_root, out_name, out_name)
|
||||
try: self.rmtree(build_dir)
|
||||
except: pass
|
||||
|
||||
# Each small file ends with _BODY.c and it has a
|
||||
# companion without _BODY.
|
||||
|
||||
for body_file in smallFiles:
|
||||
small_name = body_file.replace('_BODY.c', '')
|
||||
companion_file = small_name + '.c'
|
||||
if not self.isfile(companion_file) or not self.isfile(body_file):
|
||||
self.log_info('Skipping %s %s build' % (companion_file, body_file))
|
||||
continue
|
||||
input_files = ['pcode_test.c', 'pcode_main.c', companion_file, body_file]
|
||||
self.compile(input_files, opt_cflag, small_name)
|
||||
self.export_file(small_name+'.out', build_dir)
|
||||
|
||||
# export the directory
|
||||
target_dir = self.config.export_root+'%s'%out_name
|
||||
self.log_info("Exporting %s directory to %s" % (build_dir, target_dir) )
|
||||
self.export_file(build_dir, target_dir)
|
||||
|
||||
else:
|
||||
# compile all the c and h files here
|
||||
input_files = sorted(glob.glob('*.[c]'))
|
||||
self.compile(input_files, opt_cflag, out_name)
|
||||
|
||||
# export the file
|
||||
target_dir = self.config.export_root
|
||||
self.log_info("Exporting file to %s" % target_dir)
|
||||
output_file = '%s.out' % (out_name)
|
||||
self.export_file(output_file, target_dir)
|
||||
|
||||
self.chdir(self.config.cwd)
|
||||
self.log_close()
|
||||
|
||||
class PCodeBuildSDCC(PCodeTestBuild):
|
||||
|
||||
def __init__(self, PCodeTest):
|
||||
super(PCodeBuildSDCC, self).__init__(PCodeTest)
|
||||
|
||||
# Set options for compiler depending on needs.
|
||||
def cflags(self, output_file):
|
||||
f = []
|
||||
f += ['-DHAS_FLOAT=1' if self.config.has_float else '-DHAS_FLOAT_OVERRIDE=1']
|
||||
f += ['-DHAS_DOUBLE=1' if self.config.has_double else '-DHAS_DOUBLE_OVERRIDE=1']
|
||||
f += ['-DHAS_LONGLONG=1' if self.config.has_longlong else '-DHAS_LONGLONG_OVERRIDE=1']
|
||||
if self.config.has_shortfloat: f += ['-DHAS_SHORTFLOAT=1']
|
||||
if self.config.has_vector: f += ['-DHAS_VECTOR=1']
|
||||
if self.config.has_decimal128: f += ['-DHAS_DECIMAL128=1']
|
||||
if self.config.has_decimal32: f += ['-DHAS_DECIMAL32=1']
|
||||
if self.config.has_decimal64: f += ['-DHAS_DECIMAL64=1']
|
||||
|
||||
f += ['-DNAME=NAME:%s' % output_file]
|
||||
|
||||
f += self.config.ccflags.split()
|
||||
f += self.config.add_ccflags.split()
|
||||
|
||||
return f
|
||||
|
||||
def compile(self, input_files, opt_cflag, output_base):
|
||||
|
||||
# Name the output file, and delete it if it exists
|
||||
|
||||
output_file = '%s.out' % (output_base)
|
||||
self.remove(output_file)
|
||||
|
||||
# Construct the compile command line and execute it
|
||||
|
||||
cmp = self.which('compile_exe')
|
||||
cmd = [cmp] + input_files + self.cflags(output_file)
|
||||
if opt_cflag: cmd += [opt_cflag]
|
||||
cmd += ['-o', output_file]
|
||||
out, err = self.run(cmd)
|
||||
if out: self.log_info(out)
|
||||
|
||||
# print error messages, which may just be warnings
|
||||
if err: self.log_warn(err)
|
||||
|
||||
# return now if the error preempted the binary
|
||||
|
||||
if not self.is_readable_file(output_file):
|
||||
self.log_err('output not created %s' % output_file)
|
||||
return
|
||||
|
||||
class PCodeBuildCCS(PCodeTestBuild):
|
||||
|
||||
def __init__(self, PCodeTest):
|
||||
super(PCodeBuildCCS, self).__init__(PCodeTest)
|
||||
|
||||
# Set options for compiler depending on needs.
|
||||
def cflags(self, output_file):
|
||||
f = []
|
||||
f += ['-DHAS_FLOAT=1' if self.config.has_float else '-DHAS_FLOAT_OVERRIDE=1']
|
||||
f += ['-DHAS_DOUBLE=1' if self.config.has_double else '-DHAS_DOUBLE_OVERRIDE=1']
|
||||
f += ['-DHAS_LONGLONG=1' if self.config.has_longlong else '-DHAS_LONGLONG_OVERRIDE=1']
|
||||
if self.config.has_shortfloat: f += ['-DHAS_SHORTFLOAT=1']
|
||||
if self.config.has_vector: f += ['-DHAS_VECTOR=1']
|
||||
if self.config.has_decimal128: f += ['-DHAS_DECIMAL128=1']
|
||||
if self.config.has_decimal32: f += ['-DHAS_DECIMAL32=1']
|
||||
if self.config.has_decimal64: f += ['-DHAS_DECIMAL64=1']
|
||||
|
||||
f += ['-DNAME=NAME:%s' % output_file]
|
||||
|
||||
f += self.config.ccflags.split()
|
||||
f += self.config.add_ccflags.split()
|
||||
|
||||
return f
|
||||
|
||||
def compile(self, input_files, opt_cflag, output_base):
|
||||
|
||||
# Name the output file, and delete it if it exists
|
||||
|
||||
output_file = '%s.out' % (output_base)
|
||||
self.remove(output_file)
|
||||
|
||||
# Construct the compile command line and execute it
|
||||
|
||||
cmp = self.which('compile_exe')
|
||||
cmd = [cmp] + input_files + self.cflags(output_file) + [opt_cflag]
|
||||
cmd += ['-z', '-h', '-e', 'printf5']
|
||||
cmd += [self.config.format('%(toolchain_dir)s/tools/compiler/ti-cgt-msp430_16.9.0.LTS/lib/libc.a')]
|
||||
cmd += ['-o', output_file]
|
||||
out, err = self.run(cmd)
|
||||
if out: self.log_info(out)
|
||||
|
||||
# print error messages, which may just be warnings
|
||||
if err: self.log_warn(err)
|
||||
|
||||
# return now if the error preempted the binary
|
||||
|
||||
if not self.is_readable_file(output_file):
|
||||
self.log_err('output not created %s' % output_file)
|
||||
return
|
||||
|
||||
class PCodeBuildGCC(PCodeTestBuild):
|
||||
|
||||
def __init__(self, PCodeTest):
|
||||
super(PCodeBuildGCC, self).__init__(PCodeTest)
|
||||
self.saved_ld_library_path = self.getenv('LD_LIBRARY_PATH', '')
|
||||
|
||||
# add a new option to library path, or reset to saved value
|
||||
def set_library_path(self, add):
|
||||
if add and self.saved_ld_library_path:
|
||||
self.environment('LD_LIBRARY_PATH', '%s:%s' % (self.config.ld_library_path, add))
|
||||
elif add:
|
||||
self.environment('LD_LIBRARY_PATH', add)
|
||||
elif self.saved_ld_library_path:
|
||||
self.environment('LD_LIBRARY_PATH', self.saved_ld_library_path)
|
||||
|
||||
# Create all the associated files for a output.
|
||||
def associated_info(self, bin, base):
|
||||
|
||||
out, err = self.run(['file', bin])
|
||||
if out: self.log_info(out)
|
||||
if err:
|
||||
self.log_err(err)
|
||||
|
||||
out, err = self.run([self.which('objdump_exe')]
|
||||
+ self.config.objdump_option.split()
|
||||
+ ['-d', bin], stdout=('%s.d' % base))
|
||||
if err: self.log_warn(err)
|
||||
|
||||
out, err = self.run([self.which('objdump_exe')]
|
||||
+ self.config.objdump_option.split()
|
||||
+ ['-s', '--section', '.comment', bin],
|
||||
stdout=('%s.comment' % base))
|
||||
if err: self.log_warn(err)
|
||||
|
||||
out, err = self.run([self.which('objdump_exe')]
|
||||
+ self.config.objdump_option.split()
|
||||
+ ['-x', '-s', '-j', '.data', '-j', '.rodata', '-t' , bin],
|
||||
stdout=('%s.mem' % base))
|
||||
if err: self.log_warn(err)
|
||||
|
||||
out, err = self.run([self.which('readelf_exe'),
|
||||
'--debug-dump=decodedline', bin],
|
||||
stdout=('%s.li' % base))
|
||||
if err: self.log_warn(err)
|
||||
|
||||
out, err = self.run([self.which('nm_exe'), '-a', bin],
|
||||
stdout=('%s.nm' % base))
|
||||
if err: self.log_warn(err)
|
||||
|
||||
out, err = self.run([self.which('readelf_exe'), '-a', bin],
|
||||
stdout=('%s.readelf' % base))
|
||||
if err: self.log_warn(err)
|
||||
|
||||
out, err = self.run(['grep', ' U ', '%s.nm' % base])
|
||||
if out: self.log_warn('** UNRESOLVED:\n' + out + '**END')
|
||||
if err: self.log_warn(err)
|
||||
|
||||
# Set options for compiler depending on needs.
|
||||
def cflags(self, output_file):
|
||||
f = []
|
||||
f += ['-DHAS_FLOAT=1' if self.config.has_float else '-DHAS_FLOAT_OVERRIDE=1']
|
||||
f += ['-DHAS_DOUBLE=1' if self.config.has_double else '-DHAS_DOUBLE_OVERRIDE=1']
|
||||
f += ['-DHAS_LONGLONG=1' if self.config.has_longlong else '-DHAS_LONGLONG_OVERRIDE=1']
|
||||
if self.config.has_shortfloat: f += ['-DHAS_SHORTFLOAT=1']
|
||||
if self.config.has_vector: f += ['-DHAS_VECTOR=1']
|
||||
if self.config.has_decimal128: f += ['-DHAS_DECIMAL128=1']
|
||||
if self.config.has_decimal32: f += ['-DHAS_DECIMAL32=1']
|
||||
if self.config.has_decimal64: f += ['-DHAS_DECIMAL64=1']
|
||||
|
||||
f += ['-DNAME=NAME:%s' % output_file]
|
||||
# turn off -g because dwarf, not needed
|
||||
f += ['-dA', '-w']
|
||||
# for xc26: f += ['--no-data-init']
|
||||
# or maybe f += ['-Xlinker', '--no-data-init']
|
||||
# This helps to alleviate undefined main, etc
|
||||
f += ['--entry', 'main']
|
||||
f += ['-static', '-Wno-unused-macros', '-nodefaultlibs', '-nostartfiles', '-fno-builtin']
|
||||
# can pass this if weak symbols aren't defined
|
||||
# f += ['-Xlinker', '--unresolved-symbols=ignore-all']
|
||||
|
||||
f += self.config.ccflags.split()
|
||||
f += self.config.add_ccflags.split()
|
||||
|
||||
return f
|
||||
|
||||
def compile(self, input_files, opt_cflag, output_base):
|
||||
|
||||
# Name the output file, and delete it if it exists
|
||||
|
||||
output_file = '%s.out' % (output_base)
|
||||
self.remove(output_file)
|
||||
|
||||
# set the library path
|
||||
|
||||
self.set_library_path(self.config.ld_library_path)
|
||||
|
||||
# Construct the compile/link command line and execute it
|
||||
|
||||
cmp = self.which('compile_exe')
|
||||
cmd = [cmp] + input_files + self.cflags(output_file) + [opt_cflag, '-B', self.dirname(cmp), '-o', output_file]
|
||||
out, err = self.run(cmd)
|
||||
if out: self.log_info(out)
|
||||
|
||||
# print error messages, which may just be warnings
|
||||
if err: self.log_warn(err)
|
||||
|
||||
# but return now if the error preempted the binary
|
||||
|
||||
if not self.is_readable_file(output_file):
|
||||
self.log_err('output not created %s' % output_file)
|
||||
return
|
||||
|
||||
# strip
|
||||
|
||||
if self.config.strip_symbols:
|
||||
str = self.which('strip_exe')
|
||||
cmd = [str, '-s', output_file]
|
||||
out, err = self.run(cmd)
|
||||
if out: self.log_info(out)
|
||||
|
||||
# Get associated information (identify file, output-file.d,
|
||||
# .li, .nm, and .readelf, identify file, unresolves symbols)
|
||||
|
||||
self.associated_info(output_file, output_base)
|
||||
|
||||
# build a BUILD_EXE version
|
||||
|
||||
if self.config.build_exe:
|
||||
cmp = self.which('compile_exe')
|
||||
cmd = [cmp] + input_files + self.cflags(output_file)\
|
||||
+ ['-DBUILD_EXE', opt_cflag, '-B', self.dirname(cmp), '-o', '%s.exe' % output_base]
|
||||
out, err = self.run(cmd)
|
||||
if err: self.log_warn(err)
|
||||
if out: self.log_info(out)
|
||||
if self.config.qemu_command:
|
||||
build_dir = self.build_dir(self.config.build_root, "pcodetest", output_base)
|
||||
self.log_info(self.config.format('%s %s/%s.exe' %(self.config.qemu_command, build_dir, output_base)))
|
212
Ghidra/Extensions/SleighDevTools/pcodetest/tpp.py
Normal file
212
Ghidra/Extensions/SleighDevTools/pcodetest/tpp.py
Normal file
@ -0,0 +1,212 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import glob
|
||||
import argparse
|
||||
|
||||
class tpp:
|
||||
|
||||
def __init__(self, fname):
|
||||
self.data = {'name':'', 'ifdef':'', 'main':'', 'body':'', 'num':''}
|
||||
self.info = []
|
||||
self.c_file = None
|
||||
self.line_num = 0
|
||||
self.fname = fname
|
||||
|
||||
def c_write(self, line):
|
||||
if not self.c_file: self.c_write(line)
|
||||
else: self.c_file.write(line + '\n')
|
||||
|
||||
def test_hdr(self, line):
|
||||
self.c_write(line);
|
||||
|
||||
def test_test(self, name):
|
||||
self.data['name'] = name
|
||||
|
||||
def test_if(self, line):
|
||||
if self.data['name']: self.test_body(line)
|
||||
elif self.data['ifdef']:
|
||||
sys.stderr.write('ERROR: nested ifdef not allowed in file %s at line %d\n' % (self.fname, self.line_num))
|
||||
sys.exit(1);
|
||||
else: self.data['ifdef'] = line.strip()
|
||||
|
||||
def test_endif(self, line):
|
||||
if self.data['name']: self.test_body(line)
|
||||
|
||||
def test_open_brace(self):
|
||||
self.data['body'] = ''
|
||||
|
||||
def test_main(self, main):
|
||||
self.data['main'] = main
|
||||
self.c_write('''
|
||||
extern void %(main)s(TestInfo*);
|
||||
#define %(main)s_NUMB 0
|
||||
static const char %(main)s_NAME [] = "%(main)s";
|
||||
''' % self.data)
|
||||
self.data['name'] = ''
|
||||
self.data['ifdef'] = ''
|
||||
self.data['body'] = ''
|
||||
self.data['num'] = ''
|
||||
|
||||
def test_close_brace(self):
|
||||
if not self.data['name']: return
|
||||
self.c_write('')
|
||||
if self.data['ifdef']: self.c_write(self.data['ifdef'])
|
||||
self.data['num'] = str(len(re.findall(r'^\s+ASSERT', self.data['body'], flags=re.MULTILINE)))
|
||||
self.c_write('''#define %(name)s_NUMB %(num)s
|
||||
static const char %(name)s_NAME [] = "%(name)s";
|
||||
static void %(name)s()
|
||||
{
|
||||
noteTestMain(__FILE__, __LINE__, %(name)s_NAME);
|
||||
{
|
||||
%(body)s\t}
|
||||
breakOnSubDone(__FILE__, __LINE__, %(name)s_NAME);
|
||||
}''' % self.data)
|
||||
|
||||
if self.data['ifdef']: self.c_write('#endif /* %(ifdef)s */\n' % self.data)
|
||||
self.info += [(self.data['name'], self.data['ifdef'])]
|
||||
|
||||
# clear this test
|
||||
self.data['name'] = ''
|
||||
self.data['ifdef'] = ''
|
||||
self.data['body'] = ''
|
||||
|
||||
def test_body(self, line):
|
||||
if self.data['name']:
|
||||
# add an indentation
|
||||
if line[0] == '\t': line = '\t' + line
|
||||
self.data['body'] += line
|
||||
else:
|
||||
self.c_write(line)
|
||||
|
||||
def test_fi(self):
|
||||
self.c_write('static FunctionInfo fi[] = {')
|
||||
|
||||
if self.data['main']: self.c_write('\t{ %(main)s_NAME, (testFuncPtr) &%(main)s, %(main)s_NUMB },' % self.data)
|
||||
|
||||
for (e, f) in self.info:
|
||||
if f: self.c_write(f)
|
||||
self.c_write('\t{ %s_NAME, (testFuncPtr) &%s, %s_NUMB },' % (e, e, e))
|
||||
if f: self.c_write('#endif /* %s */' % f)
|
||||
|
||||
self.c_write('\t{ 0, 0, 0 }')
|
||||
self.c_write('};')
|
||||
|
||||
# This is boilerplate, supplying the main, etc
|
||||
|
||||
def test_boilerplate(self):
|
||||
self.c_write('''
|
||||
static GroupInfo Info = {
|
||||
{\'a\', \'B\', \'c\', \'D\', \'e\', \'f\', \'G\', \'h\'},
|
||||
fi
|
||||
};
|
||||
|
||||
/* Function exists to make sure that the GroupInfo structure does not
|
||||
* get optimized away.
|
||||
**/
|
||||
|
||||
GroupInfo *%(main)s_Force() {
|
||||
return &Info;
|
||||
}
|
||||
|
||||
void %(main)s(TestInfo* not_used) {
|
||||
i4 i = 0;
|
||||
int numTest = 0;
|
||||
|
||||
TestInfo_reset();
|
||||
|
||||
for (i = 1; Info.funcTable[i].name; i++) Info.funcTable[i].func();
|
||||
|
||||
breakOnDone(__FILE__, __LINE__, %(main)s_NAME);
|
||||
}''' % self.data)
|
||||
|
||||
def match(self, rexp, line):
|
||||
self.m = re.match(rexp, line)
|
||||
return self.m
|
||||
|
||||
# parse the test file
|
||||
|
||||
def parse(self):
|
||||
|
||||
if not self.fname.endswith('.test'):
|
||||
sys.stderr.write('ERROR: filename %s must end with .test\n' % self.fname)
|
||||
sys.exit(1);
|
||||
|
||||
self.c_file = open(re.sub('[.]test', '.c', self.fname), "w")
|
||||
|
||||
self.line_num = 0
|
||||
for line in open(self.fname):
|
||||
self.line_num += 1
|
||||
if self.match(r'TEST\s+(\w*).*', line):
|
||||
self.test_test(self.m.group(1))
|
||||
elif self.match(r'(?:#include)\s+.*', line):
|
||||
self.test_hdr(line)
|
||||
elif self.match(r'(?:#if|#ifdef)\s+.*', line):
|
||||
self.test_if(line)
|
||||
elif self.match(r'#endif.*', line):
|
||||
self.test_endif(line)
|
||||
elif self.match(r'{\s*(.*)', line):
|
||||
self.test_open_brace()
|
||||
elif self.match(r'MAIN\s+(\w*).*', line):
|
||||
self.test_main(self.m.group(1))
|
||||
elif self.match(r'}.*', line):
|
||||
self.test_close_brace()
|
||||
else:
|
||||
self.test_body(line)
|
||||
|
||||
self.test_fi()
|
||||
self.test_boilerplate()
|
||||
self.c_file.close()
|
||||
self.c_file = False
|
||||
|
||||
# the ENTRY function will contain a call to all of the MAIN
|
||||
# functions found in .test files in the current directory
|
||||
|
||||
def create_entry(self):
|
||||
if os.path.exists(self.fname):
|
||||
sys.stderr.write('WARNING: entry filename %s exists\n' % self.fname)
|
||||
return;
|
||||
|
||||
extern_lines = []
|
||||
main_lines = []
|
||||
for tname in glob.glob(re.sub(r'[^/]*$', '*.test', self.fname)):
|
||||
with open(tname) as tfile:
|
||||
for line in tfile:
|
||||
if self.match(r'MAIN\s+(\w*).*', line):
|
||||
extern_lines.append('\textern void %s(TestInfo* not_used);' % self.m.group(1))
|
||||
main_lines.append('\t%s(&info);' % self.m.group(1))
|
||||
self.c_file = open(self.fname, "w")
|
||||
self.c_write('#include "pcode_test.h"')
|
||||
self.c_write('')
|
||||
#for l in extern_lines:
|
||||
# self.c_write(l)
|
||||
self.c_write('void main(void) {')
|
||||
self.c_write('\tTestInfo info;')
|
||||
#for l in main_lines:
|
||||
# self.c_write(l)
|
||||
self.c_write('#ifdef BUILD_EXE')
|
||||
self.c_write('\texit(0);')
|
||||
self.c_write('#endif')
|
||||
self.c_write('}')
|
||||
self.c_file.close()
|
||||
self.c_file = False
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Precompile test file',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
|
||||
parser.add_argument('test_file', nargs='*', help='Test file to preprocess, must end with .test')
|
||||
parser.add_argument('--entry', default='', help='Create file ENTRY contianing a main function that calls all MAIN functions')
|
||||
|
||||
sys.argv.pop(0)
|
||||
args = parser.parse_args(sys.argv)
|
||||
|
||||
if args.test_file:
|
||||
for test_file in args.test_file:
|
||||
tpp(test_file).parse()
|
||||
|
||||
if args.entry:
|
||||
tpp(args.entry).create_entry()
|
||||
|
@ -0,0 +1,32 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.disassemble;
|
||||
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.util.classfinder.ExtensionPoint;
|
||||
|
||||
public interface ExternalDisassembler extends ExtensionPoint {
|
||||
|
||||
public String getDisassembly(CodeUnit cu) throws Exception;
|
||||
|
||||
public String getDisassemblyOfBytes(Language language, boolean isBigEndian, long address,
|
||||
byte[] byteString) throws Exception;
|
||||
|
||||
public boolean isSupportedLanguage(Language language);
|
||||
|
||||
public void destroy();
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.disassemble;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
import docking.widgets.fieldpanel.field.*;
|
||||
import docking.widgets.fieldpanel.support.FieldLocation;
|
||||
import ghidra.app.util.HighlightProvider;
|
||||
import ghidra.app.util.viewer.field.*;
|
||||
import ghidra.app.util.viewer.format.FieldFormatModel;
|
||||
import ghidra.app.util.viewer.proxy.ProxyObj;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.options.ToolOptions;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
|
||||
public class ExternalDisassemblyFieldFactory extends FieldFactory {
|
||||
|
||||
private static List<ExternalDisassembler> availableDisassemblers;
|
||||
|
||||
private static synchronized List<ExternalDisassembler> getAvailableDisassemblers() {
|
||||
if (availableDisassemblers != null) {
|
||||
return availableDisassemblers;
|
||||
}
|
||||
availableDisassemblers = new ArrayList<>();
|
||||
|
||||
// find the available external disassemblers
|
||||
Set<ExternalDisassembler> extDisassemblers =
|
||||
ClassSearcher.getInstances(ExternalDisassembler.class);
|
||||
|
||||
for (ExternalDisassembler disassember : extDisassemblers) {
|
||||
availableDisassemblers.add(disassember);
|
||||
}
|
||||
return availableDisassemblers;
|
||||
}
|
||||
|
||||
public static final String FIELD_NAME = "External Disassembly";
|
||||
|
||||
public ExternalDisassemblyFieldFactory() {
|
||||
super(FIELD_NAME);
|
||||
}
|
||||
|
||||
private ExternalDisassemblyFieldFactory(FieldFormatModel model, HighlightProvider hlProvider,
|
||||
Options displayOptions, Options fieldOptions) {
|
||||
super(FIELD_NAME, model, hlProvider, displayOptions, fieldOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fieldOptionsChanged(Options options, String optionName, Object oldValue,
|
||||
Object newValue) {
|
||||
// have no options
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptsType(int category, Class<?> proxyObjectClass) {
|
||||
return (category == FieldFormatModel.INSTRUCTION_OR_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldLocation getFieldLocation(ListingField bf, BigInteger index, int fieldNum,
|
||||
ProgramLocation loc) {
|
||||
if (loc instanceof ExternalDisassemblyFieldLocation) {
|
||||
return new FieldLocation(index, fieldNum,
|
||||
((ExternalDisassemblyFieldLocation) loc).getRow(),
|
||||
((ExternalDisassemblyFieldLocation) loc).getCharOffset());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProgramLocation getProgramLocation(int row, int col, ListingField bf) {
|
||||
ProxyObj<?> proxy = bf.getProxy();
|
||||
Object obj = proxy.getObject();
|
||||
if (!(obj instanceof CodeUnit)) {
|
||||
return null;
|
||||
}
|
||||
CodeUnit cu = (CodeUnit) obj;
|
||||
|
||||
return new ExternalDisassemblyFieldLocation(cu.getProgram(), cu.getMinAddress(), row, col);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldFactory newInstance(FieldFormatModel formatModel,
|
||||
HighlightProvider highlightProvider, ToolOptions options, ToolOptions fieldOptions) {
|
||||
return new ExternalDisassemblyFieldFactory(formatModel, highlightProvider, options,
|
||||
fieldOptions);
|
||||
}
|
||||
|
||||
private ExternalDisassembler getDisassembler(Language language) {
|
||||
for (ExternalDisassembler disassembler : getAvailableDisassemblers()) {
|
||||
if (disassembler.isSupportedLanguage(language)) {
|
||||
return disassembler;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListingField getField(ProxyObj<?> proxy, int varWidth) {
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
Object obj = proxy.getObject();
|
||||
if (!(obj instanceof CodeUnit)) {
|
||||
return null;
|
||||
}
|
||||
CodeUnit cu = (CodeUnit) obj;
|
||||
|
||||
try {
|
||||
String disassembly = getDisassemblyText(cu);
|
||||
if (disassembly == null) {
|
||||
return null;
|
||||
}
|
||||
AttributedString text = new AttributedString(disassembly, Color.black, getMetrics());
|
||||
FieldElement fieldElement = new TextFieldElement(text, 0, 0);
|
||||
return ListingTextField.createSingleLineTextField(this, proxy, fieldElement,
|
||||
startX + varWidth, width, hlProvider);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return getErrorText(proxy, varWidth, e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDisassemblyText(CodeUnit cu) throws Exception {
|
||||
Language language = cu.getProgram().getLanguage();
|
||||
ExternalDisassembler disassembler = getDisassembler(language);
|
||||
if (disassembler == null) {
|
||||
return null;
|
||||
}
|
||||
String disassembly = disassembler.getDisassembly(cu);
|
||||
if (disassembly == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return disassembly;
|
||||
}
|
||||
|
||||
private ListingTextField getErrorText(ProxyObj<?> proxy, int varWidth, Exception e) {
|
||||
String message = e.getMessage();
|
||||
if (message == null) {
|
||||
message = e.toString();
|
||||
}
|
||||
AttributedString errorText = new AttributedString(message, Color.red, getMetrics());
|
||||
FieldElement fieldElement = new TextFieldElement(errorText, 0, 0);
|
||||
return ListingTextField.createSingleLineTextField(this, proxy, fieldElement,
|
||||
startX + varWidth, width, hlProvider);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.disassemble;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
|
||||
public class ExternalDisassemblyFieldLocation extends ProgramLocation {
|
||||
|
||||
public ExternalDisassemblyFieldLocation(Program program, Address addr, int row, int charOffset) {
|
||||
super(program, addr, row, 0, charOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the row within a group of pcode strings.
|
||||
*/
|
||||
public ExternalDisassemblyFieldLocation() {
|
||||
// for deserialization
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.disassemble;
|
||||
|
||||
import ghidra.util.Msg;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class ExternalStreamHandler extends Thread {
|
||||
private InputStream inStream;
|
||||
|
||||
ExternalStreamHandler(InputStream inStream) {
|
||||
this.inStream = inStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
InputStreamReader inStreamReader = new InputStreamReader(inStream);
|
||||
BufferedReader buffReader = new BufferedReader(inStreamReader);
|
||||
String line;
|
||||
while ((line = buffReader.readLine()) != null) {
|
||||
Msg.error(ExternalDisassemblyFieldFactory.class, "Error in Disassembler: " + line);
|
||||
}
|
||||
}
|
||||
catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,646 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.disassemble;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import generic.jar.ResourceFile;
|
||||
import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.bin.MemoryByteProvider;
|
||||
import ghidra.framework.*;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.lang.Language;
|
||||
import ghidra.program.model.lang.LanguageID;
|
||||
import ghidra.program.model.listing.CodeUnit;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.MemBuffer;
|
||||
import ghidra.program.model.mem.MemoryAccessException;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class GNUExternalDisassembler implements ExternalDisassembler {
|
||||
|
||||
private static final String UNSUPPORTED = "UNSUPPORTED";
|
||||
|
||||
// magic values for gdis that direct it to read bytes from stdin
|
||||
private static final String READ_FROM_STDIN_PARAMETER = "stdin";
|
||||
private static final String SEPARATOR_CHARACTER = "\n";
|
||||
private static final String ADDRESS_OUT_OF_BOUNDS = "is out of bounds.";
|
||||
private static final String ENDING_STRING = "EOF";
|
||||
private static final int NUM_BYTES = 32;
|
||||
|
||||
private static final String MAP_FILENAME = "LanguageMap.txt";
|
||||
private static final String GNU_DISASSEMBLER_MODULE_NAME = "GnuDisassembler";
|
||||
private static final String GDIS_EXE =
|
||||
Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.WINDOWS ? "gdis.exe"
|
||||
: "gdis";
|
||||
|
||||
private static HashMap<String, File> languageGdisMap;
|
||||
private static File defaultGdisExecFile;
|
||||
private static File gdisDataDirectory;
|
||||
|
||||
private static Map<LanguageID, GdisConfig> configCache = new HashMap<>();
|
||||
private static boolean missingExtensionReported;
|
||||
|
||||
private GdisConfig currentConfig;
|
||||
private boolean hadFailure;
|
||||
|
||||
private Process disassemblerProcess;
|
||||
private BufferedReader buffReader;
|
||||
private OutputStreamWriter outputWriter;
|
||||
|
||||
// private LanguageID lastLanguageWarnedAbout;
|
||||
|
||||
public GNUExternalDisassembler() throws Exception {
|
||||
initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (disassemblerProcess != null) {
|
||||
disassemblerProcess.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedLanguage(Language language) {
|
||||
GdisConfig gdisConfig = checkLanguage(language);
|
||||
return gdisConfig != null && gdisConfig.architecture != UNSUPPORTED;
|
||||
}
|
||||
|
||||
private static void reportMultipleMappings(Language language) {
|
||||
List<String> externalNames = language.getLanguageDescription().getExternalNames("gnu");
|
||||
if (externalNames != null && externalNames.size() > 1) {
|
||||
LanguageID currentLanguageID = language.getLanguageID();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean prependSeparator = false;
|
||||
for (String name : externalNames) {
|
||||
if (prependSeparator)
|
||||
sb.append(", ");
|
||||
sb.append(name);
|
||||
prependSeparator = true;
|
||||
}
|
||||
Msg.warn(GNUExternalDisassembler.class,
|
||||
"Language " + currentLanguageID + " illegally maps to multiple (" +
|
||||
externalNames.size() + ") external gnu names: " + sb.toString() +
|
||||
". The first external name will be used.");
|
||||
}
|
||||
}
|
||||
|
||||
private static class GdisConfig {
|
||||
|
||||
String languageId;
|
||||
boolean isBigEndian;
|
||||
|
||||
String architecture;
|
||||
String machineId;
|
||||
File gdisExecFile;
|
||||
boolean usingDefault;
|
||||
|
||||
GdisConfig(Language language, boolean isBigEndian) {
|
||||
|
||||
this.languageId = language.getLanguageID().toString();
|
||||
this.isBigEndian = isBigEndian;
|
||||
|
||||
List<String> architectures = language.getLanguageDescription().getExternalNames("gnu");
|
||||
//get first non-null
|
||||
if (architectures != null && architectures.size() > 0) {
|
||||
architecture = architectures.get(0);
|
||||
if (architectures.size() > 1) {
|
||||
reportMultipleMappings(language);
|
||||
}
|
||||
}
|
||||
if (architecture == null) {
|
||||
architecture = UNSUPPORTED;
|
||||
return;
|
||||
}
|
||||
|
||||
machineId = "0x0";
|
||||
|
||||
// handle numeric entry which combines architecture and machineId
|
||||
if (architecture.startsWith("0x")) {
|
||||
String[] parts = architecture.split(":");
|
||||
architecture = parts[0];
|
||||
machineId = parts[1];
|
||||
}
|
||||
|
||||
gdisExecFile = languageGdisMap.get(languageId);
|
||||
if (gdisExecFile == null) {
|
||||
gdisExecFile = defaultGdisExecFile;
|
||||
usingDefault = true;
|
||||
}
|
||||
}
|
||||
|
||||
GdisConfig(Language lang) {
|
||||
this(lang, lang.isBigEndian());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof GdisConfig)) {
|
||||
return false;
|
||||
}
|
||||
// assume config will match for a given language
|
||||
return languageId.equals(((GdisConfig) obj).languageId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return languageId.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized GdisConfig checkLanguage(Language lang) {
|
||||
LanguageID languageId = lang.getLanguageID();
|
||||
if (configCache.containsKey(languageId)) {
|
||||
return configCache.get(languageId);
|
||||
}
|
||||
GdisConfig config = new GdisConfig(lang);
|
||||
if (config.architecture == UNSUPPORTED) {
|
||||
Msg.warn(GNUExternalDisassembler.class,
|
||||
"Language not supported (ldefs 'gnu' map entry not found): " + languageId);
|
||||
}
|
||||
else if (gdisDataDirectory == null) {
|
||||
config = null;
|
||||
if (!missingExtensionReported) {
|
||||
missingExtensionReported = true;
|
||||
Msg.showError(GNUExternalDisassembler.class, null, "GNU Disassembler Not Found",
|
||||
"External Disassembler extension module not installed: " +
|
||||
GNU_DISASSEMBLER_MODULE_NAME);
|
||||
}
|
||||
}
|
||||
else if (config.gdisExecFile == null) {
|
||||
boolean usingDefault = config.usingDefault;
|
||||
config = null;
|
||||
if (usingDefault) {
|
||||
if (!missingExtensionReported) {
|
||||
missingExtensionReported = true;
|
||||
Msg.showError(GNUExternalDisassembler.class, null, "GNU Disassembler Not Found",
|
||||
"External GNU Disassembler not found (requires install and build of " +
|
||||
GNU_DISASSEMBLER_MODULE_NAME + " extension): " + GDIS_EXE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Msg.showError(GNUExternalDisassembler.class, null, "GNU Disassembler Not Found",
|
||||
"External GNU Disassembler not found for language (" + lang.getLanguageID() +
|
||||
", see LanguageMap.txt)");
|
||||
}
|
||||
}
|
||||
configCache.put(languageId, config);
|
||||
return config;
|
||||
}
|
||||
|
||||
private int pow2(int pow) {
|
||||
int r = 1;
|
||||
for (int i = 1; i <= pow; i++) {
|
||||
r *= 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get detailed instruction list for a block of instructions.
|
||||
*
|
||||
* @param lang
|
||||
* processor language (corresponding LanguageID must be defined
|
||||
* within LanguageMap.txt)
|
||||
* @param blockAddr
|
||||
* start of block ( must be true: (offset & -(2^blockSizeFactor)
|
||||
* == offset)
|
||||
* @param blockSizeFactor
|
||||
* the block size factor where blockSize = 2^blockSizeFactor
|
||||
* (must be > 0)
|
||||
* @param byteProvider
|
||||
* provider for block of bytes to be disassembled starting at
|
||||
* offset 0
|
||||
* @return list of instructions or null if language not supported by GNU
|
||||
* Disassembler
|
||||
* @throws Exception
|
||||
*/
|
||||
public List<GnuDisassembledInstruction> getBlockDisassembly(Language lang, Address blockAddr,
|
||||
int blockSizeFactor, ByteProvider byteProvider) throws Exception {
|
||||
|
||||
GdisConfig gdisConfig = checkLanguage(lang);
|
||||
if (gdisConfig == null || gdisConfig.architecture == UNSUPPORTED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (blockSizeFactor < 0 || blockSizeFactor > 8) {
|
||||
throw new IllegalArgumentException("blockSizeFactor must be > 0 and <= 8");
|
||||
}
|
||||
int blockSize = pow2(blockSizeFactor);
|
||||
|
||||
if ((blockAddr.getOffset() & -blockSize) != blockAddr.getOffset()) {
|
||||
throw new IllegalArgumentException("Address must be block aligned");
|
||||
}
|
||||
|
||||
long addressOffset = blockAddr.getAddressableWordOffset();
|
||||
String address = "0x" + Long.toHexString(addressOffset);
|
||||
|
||||
// for aligned languages, don't try on non-aligned block addr/size.
|
||||
int alignment = lang.getInstructionAlignment();
|
||||
if (blockAddr.getOffset() % alignment != 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Address does not satisfy instruction alignment constraint: " + alignment);
|
||||
}
|
||||
|
||||
String bytes = getBytes(byteProvider, blockSize);
|
||||
|
||||
return runDisassembler(gdisConfig, address, bytes);
|
||||
}
|
||||
|
||||
public List<GnuDisassembledInstruction> getBlockDisassembly(Program program, Address addr,
|
||||
int blockSizeFactor) throws Exception {
|
||||
|
||||
if (blockSizeFactor < 0 || blockSizeFactor > 8) {
|
||||
throw new IllegalArgumentException("blockSizeFactor must be > 0 and <= 8");
|
||||
}
|
||||
int blockSize = pow2(blockSizeFactor);
|
||||
|
||||
Address blockAddr = addr.getNewAddress(addr.getOffset() & -blockSize); // block
|
||||
// aligned
|
||||
// address
|
||||
|
||||
return getBlockDisassembly(program.getLanguage(), blockAddr, blockSizeFactor,
|
||||
new MemoryByteProvider(program.getMemory(), blockAddr));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisassembly(CodeUnit cu) throws Exception {
|
||||
|
||||
GdisConfig gdisConfig = checkLanguage(cu.getProgram().getLanguage());
|
||||
if (gdisConfig == null || gdisConfig.architecture == UNSUPPORTED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long addressOffset = cu.getAddress().getAddressableWordOffset();
|
||||
String address = "0x" + Long.toHexString(addressOffset);
|
||||
|
||||
// for aligned languages, don't try on non-aligned locations.
|
||||
if (cu.getMinAddress().getOffset() %
|
||||
cu.getProgram().getLanguage().getInstructionAlignment() != 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String bytes = getBytes(cu, NUM_BYTES);
|
||||
if (bytes == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
List<GnuDisassembledInstruction> disassembly = runDisassembler(gdisConfig, address, bytes);
|
||||
|
||||
if (disassembly == null || disassembly.size() == 0 || disassembly.get(0) == null) {
|
||||
return "(bad)";
|
||||
}
|
||||
return disassembly.get(0).toString();
|
||||
}
|
||||
|
||||
// disassembler without having to have a code unit
|
||||
@Override
|
||||
public String getDisassemblyOfBytes(Language language, boolean isBigEndian, long addressOffset,
|
||||
byte[] bytes) throws Exception {
|
||||
|
||||
GdisConfig gdisConfig = new GdisConfig(language, isBigEndian);
|
||||
if (gdisConfig.architecture == UNSUPPORTED || gdisConfig.gdisExecFile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String bytesString = converBytesToString(bytes);
|
||||
|
||||
String address = "0x" + Long.toHexString(addressOffset);
|
||||
|
||||
List<GnuDisassembledInstruction> disassembly =
|
||||
runDisassembler(gdisConfig, address, bytesString);
|
||||
|
||||
if (disassembly == null || disassembly.isEmpty() || disassembly.get(0) == null) {
|
||||
return "(bad)";
|
||||
}
|
||||
return disassembly.get(0).toString();
|
||||
}
|
||||
|
||||
private String converBytesToString(byte[] bytes) {
|
||||
String byteString = null;
|
||||
for (byte thisByte : bytes) {
|
||||
String thisByteString = Integer.toHexString(thisByte);
|
||||
if (thisByteString.length() == 1)
|
||||
thisByteString = "0" + thisByteString; // pad single digits
|
||||
if (thisByteString.length() > 2)
|
||||
thisByteString = thisByteString.substring(thisByteString.length() - 2);
|
||||
// append this byte's hex string to the larger word length string
|
||||
byteString = byteString + thisByteString;
|
||||
}
|
||||
|
||||
return byteString;
|
||||
}
|
||||
|
||||
private boolean setupDisassembler(GdisConfig gdisConfig) {
|
||||
|
||||
if (disassemblerProcess != null) {
|
||||
disassemblerProcess.destroy();
|
||||
disassemblerProcess = null;
|
||||
outputWriter = null;
|
||||
buffReader = null;
|
||||
}
|
||||
|
||||
this.currentConfig = gdisConfig;
|
||||
hadFailure = false;
|
||||
|
||||
String endianString = gdisConfig.isBigEndian ? "0x00" : "0x01"; // 0x0 is big, 0x1 is little endian
|
||||
|
||||
// NOTE: valid target must be specified but has no effect on results
|
||||
String cmds[] = { gdisConfig.gdisExecFile.getAbsolutePath(), "pef", gdisConfig.architecture,
|
||||
gdisConfig.machineId, endianString, "0x0",
|
||||
gdisDataDirectory.getAbsolutePath() + File.separator,
|
||||
GNUExternalDisassembler.READ_FROM_STDIN_PARAMETER };
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (String str : cmds) {
|
||||
boolean addQuotes = str.indexOf(' ') >= 0;
|
||||
if (addQuotes) {
|
||||
buf.append('\"');
|
||||
}
|
||||
buf.append(str);
|
||||
if (addQuotes) {
|
||||
buf.append('\"');
|
||||
}
|
||||
buf.append(' ');
|
||||
}
|
||||
Msg.debug(this, "Starting gdis: " + buf.toString());
|
||||
|
||||
try {
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
disassemblerProcess = rt.exec(cmds, null, gdisConfig.gdisExecFile.getParentFile());
|
||||
}
|
||||
catch (IOException e) {
|
||||
buf = new StringBuilder();
|
||||
for (String arg : cmds) {
|
||||
buf.append("\"");
|
||||
buf.append(arg);
|
||||
buf.append("\" ");
|
||||
}
|
||||
Msg.debug(this, "GNU Disassembly setup failed, exec command: " + buf);
|
||||
Msg.showError(this, null, "GNU Disassembler Error",
|
||||
"Disassembler setup execution error: " + e.getMessage(), e);
|
||||
hadFailure = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<GnuDisassembledInstruction> runDisassembler(GdisConfig gdisConfig,
|
||||
String addrString, String bytes) throws IOException {
|
||||
|
||||
// if this is the first time running the disassembler process, or a
|
||||
// parameter has changed (notably, not the address--we pass that in
|
||||
// every time)
|
||||
boolean sameConfig = gdisConfig.equals(currentConfig);
|
||||
if (sameConfig && hadFailure) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (disassemblerProcess == null || !sameConfig) {
|
||||
|
||||
if (!setupDisassembler(gdisConfig))
|
||||
return null;
|
||||
|
||||
outputWriter = new OutputStreamWriter(disassemblerProcess.getOutputStream());
|
||||
|
||||
InputStreamReader inStreamReader =
|
||||
new InputStreamReader(disassemblerProcess.getInputStream());
|
||||
buffReader = new BufferedReader(inStreamReader);
|
||||
|
||||
ExternalStreamHandler errorHandler =
|
||||
new ExternalStreamHandler(disassemblerProcess.getErrorStream());
|
||||
errorHandler.start();
|
||||
}
|
||||
|
||||
if (!disassemblerProcess.isAlive()) {
|
||||
return null; // if process previously died return nothing - quickly
|
||||
}
|
||||
|
||||
String disassemblyRequest = addrString + SEPARATOR_CHARACTER + bytes + SEPARATOR_CHARACTER;
|
||||
try {
|
||||
outputWriter.write(disassemblyRequest);
|
||||
outputWriter.flush();
|
||||
return getDisassembledInstruction();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// force a restart of the disassembler on next call to this function
|
||||
// TODO: Should we not do this to avoid repeated failure and severe slowdown?
|
||||
// User must exit or switch configs/programs to retry after failure
|
||||
//disassemblerProcess.destroy();
|
||||
//disassemblerProcess = null; // assumes process exit
|
||||
Msg.error(this, "Last gdis request failed: " + disassemblyRequest);
|
||||
throw new IOException("gdis execution error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<GnuDisassembledInstruction> getDisassembledInstruction() throws IOException {
|
||||
|
||||
List<GnuDisassembledInstruction> results = new ArrayList<>();
|
||||
String instructionLine;
|
||||
|
||||
boolean error = false;
|
||||
do {
|
||||
instructionLine = buffReader.readLine();
|
||||
if (!error && instructionLine != null && !instructionLine.equals(ENDING_STRING) &&
|
||||
(instructionLine.indexOf(ADDRESS_OUT_OF_BOUNDS) < 0) &&
|
||||
!instructionLine.startsWith("Usage:") && !instructionLine.startsWith("Debug:")) {
|
||||
|
||||
String instructionMetadataLine = buffReader.readLine();
|
||||
if (!instructionMetadataLine.startsWith("Info: ")) {
|
||||
// TODO, throw an "ExternalDisassemblerInterfaceException"
|
||||
// or some such
|
||||
error = true; // still need to consume remainder of input
|
||||
continue;
|
||||
}
|
||||
String[] metadata = instructionMetadataLine.substring("Info: ".length()).split(",");
|
||||
results.add(new GnuDisassembledInstruction(instructionLine.replace('\t', ' '),
|
||||
Integer.parseInt(metadata[0]), "1".equals(metadata[1]),
|
||||
Integer.parseInt(metadata[2]), Integer.parseInt(metadata[3]),
|
||||
Integer.parseInt(metadata[4])));
|
||||
}
|
||||
}
|
||||
while (instructionLine != null && !instructionLine.equals(ENDING_STRING));
|
||||
|
||||
if (!disassemblerProcess.isAlive()) {
|
||||
throw new IOException("GNU disassembler process died unexpectedly.");
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private String getBytes(ByteProvider byteProvider, int size) throws IOException {
|
||||
StringBuffer byteString = new StringBuffer();
|
||||
for (int i = 0; i < size; i++) {
|
||||
byteString.append(formatHexString(byteProvider.readByte(i)));
|
||||
}
|
||||
return byteString.toString();
|
||||
}
|
||||
|
||||
private String getBytes(MemBuffer mem, int size) {
|
||||
StringBuffer byteString = new StringBuffer();
|
||||
for (int i = 0; i < size; i++) {
|
||||
try {
|
||||
byteString.append(formatHexString(mem.getByte(i)));
|
||||
}
|
||||
catch (AddressOutOfBoundsException e) {
|
||||
break;
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
if (i > 0) {
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return byteString.toString();
|
||||
}
|
||||
|
||||
private String formatHexString(byte byteToFix) {
|
||||
String byteString = "";
|
||||
String singleByte = "";
|
||||
if (byteToFix < 0) {
|
||||
singleByte = Integer.toHexString(byteToFix + 256);
|
||||
}
|
||||
else {
|
||||
singleByte = Integer.toHexString(byteToFix);
|
||||
}
|
||||
if (singleByte.length() == 1) {
|
||||
byteString += '0';
|
||||
}
|
||||
byteString += singleByte;
|
||||
return byteString;
|
||||
}
|
||||
|
||||
private static synchronized void initialize() throws Exception {
|
||||
if (languageGdisMap != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
languageGdisMap = new HashMap<>();
|
||||
|
||||
try {
|
||||
// sample elf files located in data directory
|
||||
ResourceFile dataDir =
|
||||
Application.getModuleSubDirectory(GNU_DISASSEMBLER_MODULE_NAME, "data");
|
||||
gdisDataDirectory = dataDir.getFile(false);
|
||||
defaultGdisExecFile = Application.getOSFile(GNU_DISASSEMBLER_MODULE_NAME, GDIS_EXE);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
if (gdisDataDirectory == null) {
|
||||
Msg.warn(GNUExternalDisassembler.class,
|
||||
"Use of External GNU Disassembler requires installation of extension: " +
|
||||
GNU_DISASSEMBLER_MODULE_NAME);
|
||||
}
|
||||
|
||||
initializeMaps();
|
||||
|
||||
if (defaultGdisExecFile == null || !defaultGdisExecFile.canExecute()) {
|
||||
Msg.warn(GNUExternalDisassembler.class,
|
||||
"External GNU Disassembler not found: " + GDIS_EXE);
|
||||
defaultGdisExecFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all language maps defined by any module. Any alternate external disassembler
|
||||
* executable will be looked for within the os directory of the contributing module or
|
||||
* within the gdis module
|
||||
* @throws Exception
|
||||
*/
|
||||
private static void initializeMaps() {
|
||||
for (ResourceFile file : Application.findFilesByExtensionInApplication(".txt")) {
|
||||
if (MAP_FILENAME.equals(file.getName())) {
|
||||
initializeMap(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeMap(ResourceFile mapFile) {
|
||||
|
||||
ResourceFile moduleForResourceFile = Application.getModuleContainingResourceFile(mapFile);
|
||||
if (moduleForResourceFile == null) {
|
||||
Msg.error(GNUExternalDisassembler.class,
|
||||
"Failed to identify module containing file: " + mapFile);
|
||||
return;
|
||||
}
|
||||
|
||||
Reader mapFileReader = null;
|
||||
try {
|
||||
mapFileReader = new InputStreamReader(mapFile.getInputStream());
|
||||
BufferedReader reader = new BufferedReader(mapFileReader);
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.startsWith("//") || line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
String[] parts = line.split("#");
|
||||
if (parts.length > 1) {
|
||||
|
||||
//System.out.println("found: " + parts[0] + " . " + parts[1]);
|
||||
|
||||
// TODO: should probably store exe module/name in map and defer search
|
||||
// until GdisConfig is created. This will allow us to complain about a
|
||||
// missing exe when it is needed/used.
|
||||
|
||||
String gdisExe = parts[1];
|
||||
if (Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.WINDOWS) {
|
||||
gdisExe = gdisExe + ".exe";
|
||||
}
|
||||
try {
|
||||
File customGdisExecFile;
|
||||
try {
|
||||
customGdisExecFile =
|
||||
Application.getOSFile(moduleForResourceFile.getName(), gdisExe);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
customGdisExecFile = Application.getOSFile(gdisExe);
|
||||
}
|
||||
languageGdisMap.put(parts[0], customGdisExecFile);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
Msg.error(GNUExternalDisassembler.class,
|
||||
"External disassembler not found (" + parts[0] + "): " + gdisExe);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Msg.error(GNUExternalDisassembler.class,
|
||||
"Error reading from language mapping file: " + mapFile, e);
|
||||
}
|
||||
finally {
|
||||
if (mapFileReader != null) {
|
||||
try {
|
||||
mapFileReader.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// we tried
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.disassemble;
|
||||
|
||||
/**
|
||||
* Holds the disassembled string of an instruction and the extra information
|
||||
* (type, number of bytes disassembled to produce instruction, etc.) of bytes
|
||||
* disassembled by the GNU disassembler.
|
||||
*/
|
||||
public class GnuDisassembledInstruction {
|
||||
|
||||
private final String instruction;
|
||||
private final int bytesInInstruction;
|
||||
|
||||
private final int branchDelayInstructions;
|
||||
private final int dataSize;
|
||||
private final DIS_INSN_TYPE instructionType;
|
||||
private final boolean isValid;
|
||||
|
||||
// from GNU binutils include/dis-asm.h
|
||||
enum DIS_INSN_TYPE {
|
||||
dis_noninsn, /* Not a valid instruction. */
|
||||
dis_nonbranch, /* Not a branch instruction. */
|
||||
dis_branch, /* Unconditional branch. */
|
||||
dis_condbranch, /* Conditional branch. */
|
||||
dis_jsr, /* Jump to subroutine. */
|
||||
dis_condjsr, /* Conditional jump to subroutine. */
|
||||
dis_dref, /* Data reference instruction. */
|
||||
dis_dref2 /* Two data references in instruction. */
|
||||
}
|
||||
|
||||
public GnuDisassembledInstruction(String instructionLine, int bytesInInstruction,
|
||||
boolean isValid, int branchDelayInstructions, int dataSize, int disInsnTypeOrdinal) {
|
||||
|
||||
this.instruction = instructionLine.trim();
|
||||
this.bytesInInstruction = bytesInInstruction;
|
||||
|
||||
this.isValid = isValid;
|
||||
this.branchDelayInstructions = branchDelayInstructions;
|
||||
this.dataSize = dataSize;
|
||||
this.instructionType = DIS_INSN_TYPE.values()[disInsnTypeOrdinal];
|
||||
}
|
||||
|
||||
public int getNumberOfBytesInInstruction() {
|
||||
return bytesInInstruction;
|
||||
}
|
||||
|
||||
public DIS_INSN_TYPE getInstructionType() {
|
||||
return isValid ? instructionType : null;
|
||||
}
|
||||
|
||||
public int getBranchDelayInstructions() {
|
||||
return isValid ? branchDelayInstructions : null;
|
||||
}
|
||||
|
||||
public int getDataSize() {
|
||||
return isValid ? dataSize : null;
|
||||
}
|
||||
|
||||
public String getInstruction() {
|
||||
return instruction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return instruction;
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,7 @@ data/parserprofiles/linux_32.prf||GHIDRA||||END|
|
||||
data/parserprofiles/linux_64.prf||GHIDRA||||END|
|
||||
data/parserprofiles/objc_mac_carbon.prf||GHIDRA||reviewed||END|
|
||||
data/parserprofiles/vs12Local.prf||GHIDRA||||END|
|
||||
data/pcodetest/EmuTesting.gdt||GHIDRA||||END|
|
||||
data/stringngrams/StringModel.sng||GHIDRA||reviewed||END|
|
||||
data/symbols/win32/kernel32.hints||GHIDRA||||END|
|
||||
data/symbols/win32/mfc100.exports||GHIDRA||||END|
|
||||
@ -1179,6 +1180,10 @@ src/main/resources/images/xor.png||GHIDRA||||END|
|
||||
src/main/resources/images/zoom.png||FAMFAMFAM Icons - CC 2.5|||silk|END|
|
||||
src/main/resources/images/zoom_in.png||FAMFAMFAM Icons - CC 2.5|||silk|END|
|
||||
src/main/resources/images/zoom_out.png||FAMFAMFAM Icons - CC 2.5|||silk|END|
|
||||
src/main/resources/pcodetest/chunk1.hinc||GHIDRA||||END|
|
||||
src/main/resources/pcodetest/chunk2.hinc||GHIDRA||||END|
|
||||
src/main/resources/pcodetest/chunk3.hinc||GHIDRA||||END|
|
||||
src/main/resources/pcodetest/chunk4.hinc||GHIDRA||||END|
|
||||
src/test.slow/resources/dirlist.txt||GHIDRA||reviewed||END|
|
||||
src/test.slow/resources/filterTestDirList.txt||GHIDRA||||END|
|
||||
src/test.slow/resources/ghidra/app/plugin/core/datamgr/TestDataType.txt||GHIDRA||||END|
|
||||
|
BIN
Ghidra/Features/Base/data/pcodetest/EmuTesting.gdt
Normal file
BIN
Ghidra/Features/Base/data/pcodetest/EmuTesting.gdt
Normal file
Binary file not shown.
@ -0,0 +1,207 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// An example script demonstrating the ability to emulate a specific portion of code within
|
||||
// a disassembled program to extract return values of interest (deobfuscated data in this case)
|
||||
// and generate program listing comments.
|
||||
// This script emulates the "main" function within the deobExample program
|
||||
// (see docs/GhidraClass/ExerciseFiles/Emulation/Source) built with gcc for x86-64.
|
||||
// The program's "data" array contains simple obfuscated data and has a function "deobfuscate"
|
||||
// which is called for each piece of obfuscated data. The "main" function loops through all
|
||||
// the data and deobfuscates each one invoking the "use_string" function for each deobfuscated
|
||||
// data. Breakpoints are placed on the call (and just after the call)
|
||||
// to the function "deobfuscate" so that the various return values can be recorded with a comment
|
||||
// placed just after the call.
|
||||
//@category Examples.Emulation
|
||||
import ghidra.app.emulator.EmulatorHelper;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.opinion.ElfLoader;
|
||||
import ghidra.pcode.emulate.EmulateExecutionState;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.NotFoundException;
|
||||
|
||||
public class EmuX86DeobfuscateExampleScript extends GhidraScript {
|
||||
|
||||
private static String PROGRAM_NAME = "deobExample";
|
||||
|
||||
private EmulatorHelper emuHelper;
|
||||
|
||||
// Important breakpoint locations
|
||||
private Address deobfuscateCall;
|
||||
private Address deobfuscateReturn;
|
||||
|
||||
// Function locations
|
||||
private Address mainFunctionEntry; // start of emulation address
|
||||
|
||||
// Address used as final return location
|
||||
// A breakpoint will be set here so we can determine when function execution
|
||||
// has completed.
|
||||
private static final long CONTROLLED_RETURN_OFFSET = 0;
|
||||
private Address controlledReturnAddr; // end of emulation address
|
||||
|
||||
// First argument passed to deobfuscate function on last call (used for comment generation)
|
||||
private long lastDeobfuscateArg0;
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
|
||||
String format =
|
||||
currentProgram.getOptions(Program.PROGRAM_INFO).getString("Executable Format", null);
|
||||
|
||||
if (currentProgram == null || !currentProgram.getName().startsWith(PROGRAM_NAME) ||
|
||||
!"x86:LE:64:default".equals(currentProgram.getLanguageID().toString()) ||
|
||||
!ElfLoader.ELF_NAME.equals(format)) {
|
||||
|
||||
printerr(
|
||||
"This emulation example script is specifically intended to be executed against the\n" +
|
||||
PROGRAM_NAME +
|
||||
" program whose source is contained within the GhidraClass exercise files\n" +
|
||||
"(see docs/GhidraClass/ExerciseFiles/Emulation/" + PROGRAM_NAME + ".c).\n" +
|
||||
"This program should be compiled using gcc for x86 64-bit, imported into your project, \n" +
|
||||
"analyzed and open as the active program before running ths script.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Identify function to be emulated
|
||||
mainFunctionEntry = getSymbolAddress("main");
|
||||
|
||||
// Obtain entry instruction in order to establish initial processor context
|
||||
Instruction entryInstr = getInstructionAt(mainFunctionEntry);
|
||||
if (entryInstr == null) {
|
||||
printerr("Instruction not found at main entry point: " + mainFunctionEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
// Identify important symbol addresses
|
||||
// NOTE: If the sample is recompiled the following addresses may need to be adjusted
|
||||
Instruction callSite = getCalledFromInstruction("deobfuscate");
|
||||
if (callSite == null) {
|
||||
printerr("Instruction not found at call site for: deobfuscate");
|
||||
return;
|
||||
}
|
||||
|
||||
deobfuscateCall = callSite.getAddress();
|
||||
deobfuscateReturn = callSite.getFallThrough(); // instruction address immediately after deobfuscate call
|
||||
|
||||
// Remove prior pre-comment
|
||||
setPreComment(deobfuscateReturn, null);
|
||||
|
||||
// Establish emulation helper
|
||||
emuHelper = new EmulatorHelper(currentProgram);
|
||||
try {
|
||||
|
||||
// Initialize stack pointer (not used by this example)
|
||||
long stackOffset =
|
||||
(entryInstr.getAddress().getAddressSpace().getMaxAddress().getOffset() >>> 1) -
|
||||
0x7fff;
|
||||
emuHelper.writeRegister(emuHelper.getStackPointerRegister(), stackOffset);
|
||||
|
||||
// Setup breakpoints
|
||||
emuHelper.setBreakpoint(deobfuscateCall);
|
||||
emuHelper.setBreakpoint(deobfuscateReturn);
|
||||
|
||||
// Set controlled return location so we can identify return from emulated function
|
||||
controlledReturnAddr = getAddress(CONTROLLED_RETURN_OFFSET);
|
||||
emuHelper.writeStackValue(0, 8, CONTROLLED_RETURN_OFFSET);
|
||||
emuHelper.setBreakpoint(controlledReturnAddr);
|
||||
|
||||
Msg.debug(this, "EMU starting at " + mainFunctionEntry);
|
||||
|
||||
// Execution loop until return from function or error occurs
|
||||
while (!monitor.isCancelled()) {
|
||||
boolean success =
|
||||
(emuHelper.getEmulateExecutionState() == EmulateExecutionState.BREAKPOINT)
|
||||
? emuHelper.run(monitor)
|
||||
: emuHelper.run(mainFunctionEntry, entryInstr, monitor);
|
||||
Address executionAddress = emuHelper.getExecutionAddress();
|
||||
if (monitor.isCancelled()) {
|
||||
println("Emulation cancelled");
|
||||
return;
|
||||
}
|
||||
if (executionAddress.equals(controlledReturnAddr)) {
|
||||
println("Returned from function");
|
||||
return;
|
||||
}
|
||||
if (!success) {
|
||||
String lastError = emuHelper.getLastError();
|
||||
printerr("Emulation Error: " + lastError);
|
||||
return;
|
||||
}
|
||||
processBreakpoint(executionAddress);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// cleanup resources and release hold on currentProgram
|
||||
emuHelper.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private Address getAddress(long offset) {
|
||||
return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform processing for the various breakpoints.
|
||||
* @param addr current execute address where emulation has been suspended
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
private void processBreakpoint(Address addr) throws Exception {
|
||||
|
||||
if (addr.equals(deobfuscateCall)) {
|
||||
lastDeobfuscateArg0 = emuHelper.readRegister("RDI").longValue();
|
||||
}
|
||||
|
||||
else if (addr.equals(deobfuscateReturn)) {
|
||||
long deobfuscateReturnValue = emuHelper.readRegister("RAX").longValue();
|
||||
String str = "deobfuscate(src=0x" + Long.toHexString(lastDeobfuscateArg0) + ") -> \"" +
|
||||
emuHelper.readNullTerminatedString(getAddress(deobfuscateReturnValue), 32) + "\"";
|
||||
String comment = getPreComment(deobfuscateReturn);
|
||||
if (comment == null) {
|
||||
comment = "";
|
||||
}
|
||||
else {
|
||||
comment += "\n";
|
||||
}
|
||||
comment += str;
|
||||
println("Updated pre-comment at " + deobfuscateReturn);
|
||||
setPreComment(deobfuscateReturn, comment);
|
||||
}
|
||||
}
|
||||
|
||||
private Instruction getCalledFromInstruction(String functionName) {
|
||||
Symbol s = SymbolUtilities.getExpectedLabelOrFunctionSymbol(currentProgram, functionName,
|
||||
m -> printerr(m));
|
||||
for (Reference ref : s.getReferences(monitor)) {
|
||||
if (ref.getReferenceType().isCall()) {
|
||||
return currentProgram.getListing().getInstructionAt(ref.getFromAddress());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Address getSymbolAddress(String symbolName) throws NotFoundException {
|
||||
Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName,
|
||||
err -> Msg.error(this, err));
|
||||
if (symbol != null) {
|
||||
return symbol.getAddress();
|
||||
}
|
||||
throw new NotFoundException("Failed to locate label: " + symbolName);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,288 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// An example script demonstrating the ability to emulate a specific portion of code within
|
||||
// a disassembled program to dump data of interest (deobfuscated data in this case).
|
||||
// This script emulates the "main" function within the deobHookExampleX86 program
|
||||
// (see docs/GhidraClass/ExerciseFiles/Emulation/Source) built with gcc for x86-64.
|
||||
// The program's "data" array contains simple obfuscated data and has a function "deobfuscate"
|
||||
// which is called for each piece of ofuscated data. The "main" function loops through all
|
||||
// the data and deobfuscates each one invoking the "use_string" function for each deobfuscated
|
||||
// data. This script hooks the functions "malloc", "free" and "use_string" where the later
|
||||
// simply prints the deobfuscated string passed as an argument.
|
||||
//@category Examples.Emulation
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ghidra.app.emulator.EmulatorHelper;
|
||||
import ghidra.app.script.GhidraScript;
|
||||
import ghidra.app.util.opinion.ElfLoader;
|
||||
import ghidra.pcode.emulate.EmulateExecutionState;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.lang.InsufficientBytesException;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.NotFoundException;
|
||||
|
||||
public class EmuX86GccDeobfuscateHookExampleScript extends GhidraScript {
|
||||
|
||||
private static String PROGRAM_NAME = "deobHookExample";
|
||||
|
||||
// Heap allocation area
|
||||
private static final int MALLOC_REGION_SIZE = 0x1000;
|
||||
|
||||
// Address used as final return location
|
||||
private static final long CONTROLLED_RETURN_OFFSET = 0;
|
||||
|
||||
private EmulatorHelper emuHelper;
|
||||
private SimpleMallocMgr mallocMgr;
|
||||
|
||||
// Important breakpoint locations for hooking behavior not contained with binary (e.g., dynamic library)
|
||||
private Address mallocEntry;
|
||||
private Address freeEntry;
|
||||
private Address strlenEntry;
|
||||
private Address useStringEntry;
|
||||
|
||||
// Function locations
|
||||
private Address mainFunctionEntry; // start of emulation
|
||||
private Address controlledReturnAddr; // end of emulation
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
|
||||
String format =
|
||||
currentProgram.getOptions(Program.PROGRAM_INFO).getString("Executable Format", null);
|
||||
|
||||
if (currentProgram == null || !currentProgram.getName().startsWith(PROGRAM_NAME) ||
|
||||
!"x86:LE:64:default".equals(currentProgram.getLanguageID().toString()) ||
|
||||
!ElfLoader.ELF_NAME.equals(format)) {
|
||||
|
||||
printerr(
|
||||
"This emulation example script is specifically intended to be executed against the\n" +
|
||||
PROGRAM_NAME +
|
||||
" program whose source is contained within the GhidraClass exercise files\n" +
|
||||
"(see docs/GhidraClass/ExerciseFiles/Emulation/" + PROGRAM_NAME + ".c).\n" +
|
||||
"This program should be compiled using gcc for x86 64-bit, imported into your project, \n" +
|
||||
"analyzed and open as the active program before running ths script.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Identify function be emulated
|
||||
mainFunctionEntry = getSymbolAddress("main");
|
||||
useStringEntry = getSymbolAddress("use_string");
|
||||
|
||||
// Identify important symbol addresses
|
||||
mallocEntry = getExternalThunkAddress("malloc");
|
||||
freeEntry = getExternalThunkAddress("free");
|
||||
strlenEntry = getExternalThunkAddress("strlen");
|
||||
|
||||
// Establish emulation helper
|
||||
emuHelper = new EmulatorHelper(currentProgram);
|
||||
try {
|
||||
// Initialize stack pointer (not used by this example)
|
||||
long stackOffset =
|
||||
(mainFunctionEntry.getAddressSpace().getMaxAddress().getOffset() >>> 1) - 0x7fff;
|
||||
emuHelper.writeRegister(emuHelper.getStackPointerRegister(), stackOffset);
|
||||
|
||||
// Establish simple malloc memory manager with memory region spaced relative to stack pointer
|
||||
mallocMgr = new SimpleMallocMgr(getAddress(stackOffset - 0x10000), MALLOC_REGION_SIZE);
|
||||
|
||||
// Setup hook breakpoints
|
||||
emuHelper.setBreakpoint(mallocEntry);
|
||||
emuHelper.setBreakpoint(freeEntry);
|
||||
emuHelper.setBreakpoint(strlenEntry);
|
||||
emuHelper.setBreakpoint(useStringEntry);
|
||||
|
||||
// Set controlled return location so we can identify return from emulated function
|
||||
controlledReturnAddr = getAddress(CONTROLLED_RETURN_OFFSET);
|
||||
emuHelper.writeStackValue(0, 8, CONTROLLED_RETURN_OFFSET);
|
||||
emuHelper.setBreakpoint(controlledReturnAddr);
|
||||
|
||||
// This example directly manipulates the PC register to facilitate hooking
|
||||
// which must alter the PC during a breakpoint, and optional stepping which does not
|
||||
// permit an initial address to be specified.
|
||||
emuHelper.writeRegister(emuHelper.getPCRegister(), mainFunctionEntry.getOffset());
|
||||
Msg.debug(this, "EMU starting at " + emuHelper.getExecutionAddress());
|
||||
|
||||
// Execution loop until return from function or error occurs
|
||||
while (!monitor.isCancelled()) {
|
||||
// Use stepping if needed for troubleshooting - although it runs much slower
|
||||
//boolean success = emuHelper.step();
|
||||
boolean success = emuHelper.run(monitor);
|
||||
Address executionAddress = emuHelper.getExecutionAddress();
|
||||
if (monitor.isCancelled()) {
|
||||
println("Emulation cancelled");
|
||||
return;
|
||||
}
|
||||
if (executionAddress.equals(controlledReturnAddr)) {
|
||||
println("Returned from function");
|
||||
return;
|
||||
}
|
||||
if (!success) {
|
||||
String lastError = emuHelper.getLastError();
|
||||
printerr("Emulation Error: " + lastError);
|
||||
return;
|
||||
}
|
||||
processBreakpoint(executionAddress);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
// cleanup resources and release hold on currentProgram
|
||||
emuHelper.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private Address getAddress(long offset) {
|
||||
return currentProgram.getAddressFactory().getDefaultAddressSpace().getAddress(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform processing for the various hook points where breakpoints have been set.
|
||||
* @param addr current execute address where emulation has been suspended
|
||||
* @throws Exception if an error occurs
|
||||
*/
|
||||
private void processBreakpoint(Address addr) throws Exception {
|
||||
|
||||
// malloc hook
|
||||
if (addr.equals(mallocEntry)) {
|
||||
int size = emuHelper.readRegister("RDI").intValue();
|
||||
Address memAddr = mallocMgr.malloc(size);
|
||||
emuHelper.writeRegister("RAX", memAddr.getOffset());
|
||||
}
|
||||
|
||||
// free hook
|
||||
else if (addr.equals(freeEntry)) {
|
||||
Address freeAddr = getAddress(emuHelper.readRegister("RDI").longValue());
|
||||
mallocMgr.free(freeAddr);
|
||||
}
|
||||
|
||||
// strlen hook
|
||||
else if (addr.equals(strlenEntry)) {
|
||||
Address ptr = getAddress(emuHelper.readRegister("RDI").longValue());
|
||||
int len = 0;
|
||||
while (emuHelper.readMemoryByte(ptr) != 0) {
|
||||
++len;
|
||||
ptr = ptr.next();
|
||||
}
|
||||
emuHelper.writeRegister("RAX", len);
|
||||
}
|
||||
|
||||
// use_string hook - print string
|
||||
else if (addr.equals(useStringEntry)) {
|
||||
Address stringAddr = getAddress(emuHelper.readRegister("RDI").longValue());
|
||||
String str = emuHelper.readNullTerminatedString(stringAddr, 32);
|
||||
println("use_string: " + str); // output string argument to consoles
|
||||
}
|
||||
|
||||
// unexpected
|
||||
else {
|
||||
if (emuHelper.getEmulateExecutionState() != EmulateExecutionState.BREAKPOINT) {
|
||||
// assume we are stepping and simply return
|
||||
return;
|
||||
}
|
||||
throw new NotFoundException("Unhandled breakpoint at " + addr);
|
||||
}
|
||||
|
||||
// force early return
|
||||
long returnOffset = emuHelper.readStackValue(0, 8, false).longValue();
|
||||
|
||||
emuHelper.writeRegister(emuHelper.getPCRegister(), returnOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thunk function corresponding to an external function. Such thunks
|
||||
* should reside within the EXTERNAL block. (Note: this is specific to the ELF import)
|
||||
* @param symbolName external function name
|
||||
* @return address of thunk function which corresponds to an external function
|
||||
* @throws NotFoundException if thunk not found
|
||||
*/
|
||||
private Address getExternalThunkAddress(String symbolName) throws NotFoundException {
|
||||
Symbol externalSymbol = currentProgram.getSymbolTable().getExternalSymbol(symbolName);
|
||||
if (externalSymbol != null && externalSymbol.getSymbolType() == SymbolType.FUNCTION) {
|
||||
Function f = (Function) externalSymbol.getObject();
|
||||
Address[] thunkAddrs = f.getFunctionThunkAddresses();
|
||||
if (thunkAddrs.length == 1) {
|
||||
return thunkAddrs[0];
|
||||
}
|
||||
}
|
||||
throw new NotFoundException("Failed to locate label: " + symbolName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global namespace symbol address which corresponds to the specified name.
|
||||
* @param symbolName global symbol name
|
||||
* @return symbol address
|
||||
* @throws NotFoundException if symbol not found
|
||||
*/
|
||||
private Address getSymbolAddress(String symbolName) throws NotFoundException {
|
||||
Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName,
|
||||
err -> Msg.error(this, err));
|
||||
if (symbol != null) {
|
||||
return symbol.getAddress();
|
||||
}
|
||||
throw new NotFoundException("Failed to locate label: " + symbolName);
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>SimpleMallocMgr</code> provides a simple malloc memory manager to be used by the
|
||||
* malloc/free hooked implementations.
|
||||
*/
|
||||
private class SimpleMallocMgr {
|
||||
|
||||
private AddressSet allocSet;
|
||||
private Map<Address, AddressRange> mallocMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* <code>SimpleMallocMgr</code> constructor.
|
||||
* @param rangeStart start of the free malloc region (i.e., Heap) which has been
|
||||
* deemed a safe
|
||||
* @param byteSize
|
||||
* @throws AddressOverflowException
|
||||
*/
|
||||
SimpleMallocMgr(Address rangeStart, int byteSize) throws AddressOverflowException {
|
||||
allocSet = new AddressSet(
|
||||
new AddressRangeImpl(rangeStart, rangeStart.addNoWrap(byteSize - 1)));
|
||||
}
|
||||
|
||||
synchronized Address malloc(int byteLength) throws InsufficientBytesException {
|
||||
if (byteLength <= 0) {
|
||||
throw new IllegalArgumentException("malloc request for " + byteLength);
|
||||
}
|
||||
for (AddressRange range : allocSet.getAddressRanges()) {
|
||||
if (range.getLength() >= byteLength) {
|
||||
AddressRange mallocRange = new AddressRangeImpl(range.getMinAddress(),
|
||||
range.getMinAddress().add(byteLength - 1));
|
||||
mallocMap.put(mallocRange.getMinAddress(), mallocRange);
|
||||
allocSet.delete(mallocRange);
|
||||
return mallocRange.getMinAddress();
|
||||
}
|
||||
}
|
||||
throw new InsufficientBytesException(
|
||||
"SimpleMallocMgr failed to allocate " + byteLength + " bytes");
|
||||
}
|
||||
|
||||
synchronized void free(Address mallocRangeAddr) {
|
||||
AddressRange range = mallocMap.remove(mallocRangeAddr);
|
||||
if (range == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"free request for unallocated block at " + mallocRangeAddr);
|
||||
}
|
||||
allocSet.add(range);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -34,7 +34,7 @@ import ghidra.program.model.mem.Memory;
|
||||
public class SearchBaseExtended extends GhidraScript {
|
||||
|
||||
//holds the mask and value for all the mnemonics, or commands like cmp, jmp, jnz etc
|
||||
ArrayList<Case> mnemonics = new ArrayList<Case>();
|
||||
ArrayList<Case> mnemonics = new ArrayList<>();
|
||||
|
||||
/*
|
||||
* Holds the masks and values for all the operands. The arraylist portion will correspond to the operand number. An example is
|
||||
@ -44,13 +44,13 @@ public class SearchBaseExtended extends GhidraScript {
|
||||
* operand. I set it up this was to conserve memory and allow for a dynamically growing collection.
|
||||
*/
|
||||
ArrayList<LinkedHashMap<Case, OperandCase>> ops =
|
||||
new ArrayList<LinkedHashMap<Case, OperandCase>>();//holds masks and values for all operands.
|
||||
new ArrayList<>();//holds masks and values for all operands.
|
||||
|
||||
ArrayList<Case> db = new ArrayList<Case>();//holds the search results.
|
||||
ArrayList<Case> db = new ArrayList<>();//holds the search results.
|
||||
|
||||
//These control the detail at which a scan is performed.
|
||||
//They determine how specific the instructions must match the currently selected ones
|
||||
ArrayList<SLMaskControl> controlList = new ArrayList<SLMaskControl>();
|
||||
ArrayList<SLMaskControl> controlList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
@ -59,7 +59,7 @@ public class SearchBaseExtended extends GhidraScript {
|
||||
}
|
||||
|
||||
public void run(boolean mneonics, boolean op1, boolean op2, boolean constants) {
|
||||
controlList = new ArrayList<SLMaskControl>();
|
||||
controlList = new ArrayList<>();
|
||||
controlList.add(new SLMaskControl(mneonics, op1, op2, constants));
|
||||
loadSelectedInstructions();
|
||||
executeSearch();
|
||||
@ -72,11 +72,11 @@ public class SearchBaseExtended extends GhidraScript {
|
||||
}
|
||||
|
||||
public void clearResults() {
|
||||
db = new ArrayList<Case>();
|
||||
db = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setState(SLMaskControl newState) {
|
||||
controlList = new ArrayList<SLMaskControl>();
|
||||
controlList = new ArrayList<>();
|
||||
controlList.add(newState);
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ public class SearchBaseExtended extends GhidraScript {
|
||||
mnemonics.add(tCase); //adds the mnemonic mask and value to the arraylist
|
||||
|
||||
//Gets a code unit which can be used to determine if the operands are constants.
|
||||
CodeUnit cUnit = list.getCodeUnitAt(tempAddr);
|
||||
CodeUnit cu = list.getCodeUnitAt(tempAddr);
|
||||
|
||||
//Iterates through all the operands for the currently selected instruction and stores them accordingly
|
||||
for (int x = 1; x <= logger.getNumOperands(); x++) {
|
||||
@ -156,7 +156,7 @@ public class SearchBaseExtended extends GhidraScript {
|
||||
otCase.textRep = tempIns.getDefaultOperandRepresentation(x - 1);
|
||||
|
||||
//Determines if the given operand is a constant value. If it is a constant then proper flag is set.
|
||||
if (cUnit.getScalar(x - 1) != null) {
|
||||
if (cu.getScalar(x - 1) != null) {
|
||||
otCase.constant = true;
|
||||
}
|
||||
|
||||
@ -321,8 +321,8 @@ public class SearchBaseExtended extends GhidraScript {
|
||||
ArrayList<LinkedHashMap<Case, OperandCase>> localOperands,
|
||||
ArrayList<SLMaskControl> control) {
|
||||
|
||||
ArrayList<byte[]> masks = new ArrayList<byte[]>();
|
||||
ArrayList<byte[]> values = new ArrayList<byte[]>();
|
||||
ArrayList<byte[]> masks = new ArrayList<>();
|
||||
ArrayList<byte[]> values = new ArrayList<>();
|
||||
|
||||
//used for storing the byte stream currently being work on prior to being added to final data structure
|
||||
int totalLength = 0;
|
||||
|
@ -770,7 +770,7 @@ public class TestEnv {
|
||||
* Open a read-only test program from the test data directory.
|
||||
* This program must be released prior to disposing this test environment.
|
||||
* NOTE: Some tests rely on this method returning null when file does
|
||||
* not yet exist within the resource area (e.g., CUnit binaries for Processor Tests)
|
||||
* not yet exist within the resource area (e.g., test binaries for P-Code Tests)
|
||||
*
|
||||
* @param programName name of program database within the test data directory.
|
||||
* @return program or null if program file not found
|
||||
|
@ -57,7 +57,7 @@ public class TestProgramManager {
|
||||
* Open a read-only test program from the test data directory.
|
||||
* This program must be released prior to disposing this test environment.
|
||||
* NOTE: Some tests rely on this method returning null when file does
|
||||
* not yet exist within the resource area (e.g., CUnit binaries for Processor Tests)
|
||||
* not yet exist within the resource area (e.g., test binaries for P-Code Tests)
|
||||
*
|
||||
* @param progName name of program database within the test data directory.
|
||||
* @return program or null if program file not found
|
||||
|
@ -0,0 +1,704 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors.support;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
import generic.timer.GhidraSwinglessTimer;
|
||||
import generic.timer.TimerCallback;
|
||||
import ghidra.app.emulator.*;
|
||||
import ghidra.pcode.emulate.BreakCallBack;
|
||||
import ghidra.pcode.emulate.EmulateExecutionState;
|
||||
import ghidra.pcode.error.LowlevelError;
|
||||
import ghidra.pcode.memstate.MemoryFaultHandler;
|
||||
import ghidra.pcode.pcoderaw.PcodeOpRaw;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSpace;
|
||||
import ghidra.program.model.lang.Register;
|
||||
import ghidra.program.model.lang.RegisterValue;
|
||||
import ghidra.program.model.listing.Instruction;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.pcode.Varnode;
|
||||
import ghidra.test.processors.support.PCodeTestAbstractControlBlock.FunctionInfo;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
public class EmulatorTestRunner {
|
||||
|
||||
private Program program;
|
||||
private PCodeTestGroup testGroup;
|
||||
|
||||
private EmulatorHelper emuHelper;
|
||||
private Emulator emu;
|
||||
private ExecutionListener executionListener;
|
||||
|
||||
private volatile boolean haltedOnTimer = false;
|
||||
private String lastError;
|
||||
private int callOtherErrors; // only incremented on pass with callOtherCount != 0
|
||||
private int callOtherCount;
|
||||
|
||||
private TreeSet<String> unimplementedSet = new TreeSet<>();
|
||||
|
||||
private HashMap<Address, List<DumpPoint>> dumpPointMap = new HashMap<>();
|
||||
|
||||
public EmulatorTestRunner(Program program, PCodeTestGroup testGroup,
|
||||
ExecutionListener executionListener) {
|
||||
this.program = program;
|
||||
this.testGroup = testGroup;
|
||||
this.executionListener = executionListener;
|
||||
emuHelper = new EmulatorHelper(program);
|
||||
emu = emuHelper.getEmulator();
|
||||
emuHelper.setMemoryFaultHandler(new MyMemoryFaultHandler(executionListener));
|
||||
|
||||
emuHelper.registerDefaultCallOtherCallback(new BreakCallBack() {
|
||||
@Override
|
||||
public boolean pcodeCallback(PcodeOpRaw op) throws LowlevelError {
|
||||
int userOp = (int) op.getInput(0).getOffset();
|
||||
String pcodeOpName = emulate.getLanguage().getUserDefinedOpName(userOp);
|
||||
unimplementedSet.add(pcodeOpName);
|
||||
String outStr = "";
|
||||
Varnode output = op.getOutput();
|
||||
if (output != null) {
|
||||
outStr = ", unable to set output " + output.toString(program.getLanguage());
|
||||
}
|
||||
EmulatorTestRunner.this.executionListener.log(testGroup, "Unimplemented pcodeop '" +
|
||||
pcodeOpName + "' at: " + emu.getExecuteAddress() + outStr);
|
||||
++callOtherCount;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
emuHelper.dispose();
|
||||
emu = null;
|
||||
program = null;
|
||||
executionListener = null;
|
||||
testGroup = null;
|
||||
}
|
||||
|
||||
Set<String> getUnimplementedPcodeops() {
|
||||
return unimplementedSet;
|
||||
}
|
||||
|
||||
public PCodeTestGroup getTestGroup() {
|
||||
return testGroup;
|
||||
}
|
||||
|
||||
public Program getProgram() {
|
||||
return program;
|
||||
}
|
||||
|
||||
public EmulatorHelper getEmulatorHelper() {
|
||||
return emuHelper;
|
||||
}
|
||||
|
||||
public void setContextRegister(RegisterValue ctxRegValue) {
|
||||
emuHelper.setContextRegister(ctxRegValue);
|
||||
}
|
||||
|
||||
public Address getCurrentAddress() {
|
||||
return emuHelper.getExecutionAddress();
|
||||
}
|
||||
|
||||
public Instruction getCurrentInstruction() {
|
||||
// TODO: Pull instruction from emulator instead of program after
|
||||
// merge with SleighRefactor branch
|
||||
return program.getListing().getInstructionAt(emu.getExecuteAddress());
|
||||
}
|
||||
|
||||
private void flipBytes(byte[] bytes) {
|
||||
for (int i = 0; i < bytes.length / 2; i++) {
|
||||
byte b = bytes[i];
|
||||
int otherIndex = bytes.length - i - 1;
|
||||
bytes[i] = bytes[otherIndex];
|
||||
bytes[otherIndex] = b;
|
||||
}
|
||||
}
|
||||
|
||||
public RegisterValue getRegisterValue(Register reg) {
|
||||
Register baseReg = reg.getBaseRegister();
|
||||
byte[] bytes = emuHelper.readMemory(baseReg.getAddress(), baseReg.getMinimumByteSize());
|
||||
if (!reg.isBigEndian()) {
|
||||
flipBytes(bytes);
|
||||
}
|
||||
byte[] maskValue = new byte[2 * bytes.length];
|
||||
Arrays.fill(maskValue, (byte) 0xff);
|
||||
System.arraycopy(bytes, 0, maskValue, bytes.length, bytes.length);
|
||||
RegisterValue baseValue = new RegisterValue(baseReg, maskValue);
|
||||
return baseValue.getRegisterValue(reg);
|
||||
}
|
||||
|
||||
public String getRegisterValueString(Register reg) {
|
||||
String valStr = getRegisterValue(reg).getUnsignedValue().toString(16);
|
||||
return StringUtilities.pad(valStr, '0', reg.getMinimumByteSize() * 2);
|
||||
}
|
||||
|
||||
public void setRegister(String regName, long value) {
|
||||
Register reg = program.getRegister(regName);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("Undefined register: " + regName);
|
||||
}
|
||||
emuHelper.writeRegister(reg, value);
|
||||
}
|
||||
|
||||
public void setRegister(String regName, BigInteger value) {
|
||||
Register reg = program.getRegister(regName);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("Undefined register: " + regName);
|
||||
}
|
||||
emuHelper.writeRegister(reg, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add memory dump point
|
||||
* @param breakAddr instruction address at which execution should pause (before it is executed)
|
||||
* so that the specified memory may be dumped to the log during trace execution mode.
|
||||
* @param dumpAddr memory address which should be dumped
|
||||
* @param dumpSize number elements which should be dumped
|
||||
* @param elementSize size of each element in bytes (be reasonable!)
|
||||
* @param elementFormat HEX, DECIMAL or FLOAT
|
||||
* @param comment dump comment
|
||||
*/
|
||||
public void addDumpPoint(Address breakAddr, Address dumpAddr, int dumpSize, int elementSize,
|
||||
DumpFormat elementFormat, String comment) {
|
||||
List<DumpPoint> list = dumpPointMap.get(breakAddr);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
dumpPointMap.put(breakAddr, list);
|
||||
}
|
||||
list.add(new AddressDumpPoint(breakAddr, dumpAddr, dumpSize, elementSize, elementFormat,
|
||||
comment));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add memory dump point
|
||||
* @param breakAddr instruction address at which execution should pause (before it is executed)
|
||||
* so that the specified memory may be dumped to the log during trace execution mode.
|
||||
* @param dumpAddrReg register containing the memory address offset which should be dumped
|
||||
* @param relativeOffset dump register relative offset
|
||||
* @param dumpAddrSpace address space to which memory offset should be applied
|
||||
* @param dumpSize number elements which should be dumped
|
||||
* @param elementSize size of each element in bytes (be reasonable!)
|
||||
* @param elementFormat HEX, DECIMAL or FLOAT
|
||||
* @param comment dump comment
|
||||
*/
|
||||
public void addDumpPoint(Address breakAddr, Register dumpAddrReg, int relativeOffset,
|
||||
AddressSpace dumpAddrSpace, int dumpSize, int elementSize, DumpFormat elementFormat,
|
||||
String comment) {
|
||||
List<DumpPoint> list = dumpPointMap.get(breakAddr);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
dumpPointMap.put(breakAddr, list);
|
||||
}
|
||||
list.add(new RegisterRelativeDumpPoint(breakAddr, dumpAddrReg, relativeOffset,
|
||||
dumpAddrSpace, dumpSize, elementSize, elementFormat, comment));
|
||||
}
|
||||
|
||||
private void dump(List<DumpPoint> dumpList) {
|
||||
for (DumpPoint dumpPoint : dumpList) {
|
||||
Address dumpAddr = dumpPoint.getDumpAddress();
|
||||
executionListener.logState(this, dumpAddr, dumpPoint.dumpSize, dumpPoint.elementSize,
|
||||
dumpPoint.elementFormat, dumpPoint.comment);
|
||||
}
|
||||
}
|
||||
|
||||
private String getLastFunctionName(PCodeTestGroup testGroup, boolean logError) {
|
||||
return testGroup.mainTestControlBlock.getLastFunctionName(this,
|
||||
logError ? executionListener : null, testGroup);
|
||||
}
|
||||
|
||||
public String getEmuError() {
|
||||
return lastError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of CALLOTHER errors detected when a test pass was registered.
|
||||
* This number should be subtracted from the pass count and possibly added
|
||||
* to the failure count. Number does not reflect total number of CALLOTHER
|
||||
* pcodeops encountered but only the number of passed tests affected.
|
||||
* See log for all CALLOTHER executions detected.
|
||||
* @return number of CALLOTHER errors
|
||||
*/
|
||||
public int getCallOtherErrors() {
|
||||
return callOtherErrors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute test group without instruction stepping/tracing
|
||||
* @param timeLimitMS
|
||||
* @param monitor
|
||||
* @return
|
||||
* @throws CancelledException
|
||||
*/
|
||||
public boolean execute(int timeLimitMS, TaskMonitor monitor) throws CancelledException {
|
||||
|
||||
testGroup.clearFailures();
|
||||
lastError = null;
|
||||
callOtherErrors = 0;
|
||||
|
||||
// Disable sprintf use
|
||||
testGroup.mainTestControlBlock.setSprintfEnabled(this, false);
|
||||
|
||||
int alignment = program.getLanguage().getInstructionAlignment();
|
||||
|
||||
Address breakOnDoneAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getBreakOnDoneAddress(), alignment);
|
||||
Address breakOnPassAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getBreakOnPassAddress(), alignment);
|
||||
Address breakOnErrorAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getBreakOnErrorAddress(), alignment);
|
||||
|
||||
emuHelper.setBreakpoint(breakOnDoneAddr);
|
||||
emuHelper.setBreakpoint(breakOnPassAddr);
|
||||
emuHelper.setBreakpoint(breakOnErrorAddr);
|
||||
|
||||
GhidraSwinglessTimer safetyTimer = null;
|
||||
haltedOnTimer = false;
|
||||
boolean atBreakpoint = false;
|
||||
try {
|
||||
if (timeLimitMS > 0) {
|
||||
safetyTimer = new GhidraSwinglessTimer(timeLimitMS, new TimerCallback() {
|
||||
@Override
|
||||
public synchronized void timerFired() {
|
||||
haltedOnTimer = true;
|
||||
emuHelper.getEmulator().setHalt(true);
|
||||
}
|
||||
});
|
||||
safetyTimer.setRepeats(false);
|
||||
safetyTimer.start();
|
||||
}
|
||||
while (true) {
|
||||
callOtherCount = 0;
|
||||
|
||||
boolean success;
|
||||
if (atBreakpoint) {
|
||||
success = emuHelper.run(monitor);
|
||||
}
|
||||
else {
|
||||
success = emuHelper.run(alignAddress(testGroup.functionEntryPtr, alignment),
|
||||
null, monitor);
|
||||
}
|
||||
|
||||
String lastFuncName = getLastFunctionName(testGroup, false);
|
||||
String errFileName = testGroup.mainTestControlBlock.getLastErrorFile(this);
|
||||
int errLineNum = testGroup.mainTestControlBlock.getLastErrorLine(this);
|
||||
|
||||
Address executeAddr = emuHelper.getExecutionAddress();
|
||||
if (!success) {
|
||||
lastError = emuHelper.getLastError();
|
||||
testGroup.severeTestFailure(lastFuncName, errFileName, errLineNum, program,
|
||||
executionListener);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (haltedOnTimer) {
|
||||
lastError = "Emulation halted due to execution timeout";
|
||||
testGroup.severeTestFailure(lastFuncName, errFileName, errLineNum, program,
|
||||
executionListener);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (executeAddr.equals(breakOnDoneAddr)) {
|
||||
return true; // done
|
||||
}
|
||||
|
||||
if (executeAddr.equals(breakOnPassAddr)) {
|
||||
if (callOtherCount != 0) {
|
||||
// force error even if test passed - need to adjust pass count
|
||||
testGroup.testFailed(lastFuncName, errFileName, errLineNum, true, program,
|
||||
executionListener);
|
||||
++callOtherErrors;
|
||||
}
|
||||
else {
|
||||
testGroup.testPassed(lastFuncName, errFileName, errLineNum, program,
|
||||
executionListener);
|
||||
}
|
||||
atBreakpoint = true;
|
||||
continue;
|
||||
}
|
||||
else if (executeAddr.equals(breakOnErrorAddr)) {
|
||||
testGroup.testFailed(lastFuncName, errFileName, errLineNum, false, program,
|
||||
executionListener);
|
||||
atBreakpoint = true;
|
||||
continue; // resume from breakpoint
|
||||
}
|
||||
|
||||
throw new AssertException("Unexpected condition (executeAddr=" + executeAddr + ")");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (safetyTimer != null) {
|
||||
synchronized (safetyTimer) {
|
||||
safetyTimer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean executeSingleStep(int stepLimit) {
|
||||
|
||||
testGroup.clearFailures();
|
||||
lastError = null;
|
||||
callOtherErrors = 0;
|
||||
callOtherCount = 0;
|
||||
|
||||
// force function address alignment to compensate for address encoding (e.g., Thumb mode)
|
||||
int alignment = program.getLanguage().getInstructionAlignment();
|
||||
|
||||
HashMap<Address, FunctionInfo> subFunctionMap = new HashMap<>();
|
||||
int subFunctionCnt = testGroup.controlBlock.getNumberFunctions();
|
||||
for (int i = 1; i < subFunctionCnt; i++) {
|
||||
FunctionInfo functionInfo = testGroup.controlBlock.getFunctionInfo(i);
|
||||
subFunctionMap.put(alignAddress(functionInfo.functionAddr, alignment), functionInfo);
|
||||
}
|
||||
|
||||
Address executeAddr = alignAddress(testGroup.functionEntryPtr, alignment);
|
||||
|
||||
emuHelper.writeRegister(program.getLanguage().getProgramCounter(),
|
||||
executeAddr.getAddressableWordOffset());
|
||||
|
||||
// Enable sprintf use
|
||||
testGroup.mainTestControlBlock.setSprintfEnabled(this, true);
|
||||
|
||||
Address breakOnDoneAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getBreakOnDoneAddress(), alignment);
|
||||
Address breakOnPassAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getBreakOnPassAddress(), alignment);
|
||||
Address breakOnErrorAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getBreakOnErrorAddress(), alignment);
|
||||
Address printfAddr =
|
||||
alignAddress(testGroup.mainTestControlBlock.getSprintf5Address(), alignment);
|
||||
|
||||
executionListener.log(testGroup, "TestInfo pointers of interest:");
|
||||
executionListener.log(testGroup, " onDone -> " + breakOnDoneAddr);
|
||||
executionListener.log(testGroup, " onPass -> " + breakOnPassAddr);
|
||||
executionListener.log(testGroup, " onError -> " + breakOnErrorAddr);
|
||||
executionListener.log(testGroup, " printf5 -> " + printfAddr);
|
||||
|
||||
if (!dumpPointMap.isEmpty()) {
|
||||
executionListener.log(testGroup, "Dump points:");
|
||||
List<Address> addressList = new ArrayList<>(dumpPointMap.keySet());
|
||||
Collections.sort(addressList);
|
||||
for (Address addr : addressList) {
|
||||
List<DumpPoint> dumpList = dumpPointMap.get(addr);
|
||||
for (DumpPoint dumpPoint : dumpList) {
|
||||
executionListener.log(testGroup, " " + dumpPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
executionListener.logState(this);
|
||||
|
||||
int stepCount = 0;
|
||||
Address lastAddress = null;
|
||||
Address printfCallAddr = null;
|
||||
boolean assertTriggered = false;
|
||||
FunctionInfo currentFunction = null;
|
||||
|
||||
MyMemoryAccessFilter memoryFilter = new MyMemoryAccessFilter();
|
||||
emu.addMemoryAccessFilter(memoryFilter);
|
||||
try {
|
||||
|
||||
while (true) {
|
||||
if (!emuHelper.step(TaskMonitor.DUMMY)) {
|
||||
lastError = emuHelper.getLastError();
|
||||
|
||||
String lastFuncName = getLastFunctionName(testGroup, true);
|
||||
String errFileName = testGroup.mainTestControlBlock.getLastErrorFile(this);
|
||||
int errLineNum = testGroup.mainTestControlBlock.getLastErrorLine(this);
|
||||
|
||||
testGroup.severeTestFailure(lastFuncName, errFileName, errLineNum, program,
|
||||
executionListener);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
executeAddr = emuHelper.getExecutionAddress();
|
||||
|
||||
List<DumpPoint> dumpList = dumpPointMap.get(executeAddr);
|
||||
if (dumpList != null) {
|
||||
dump(dumpList);
|
||||
}
|
||||
|
||||
if (executeAddr.equals(breakOnDoneAddr)) {
|
||||
return true; // done
|
||||
}
|
||||
|
||||
boolean onPass = executeAddr.equals(breakOnPassAddr);
|
||||
if (onPass || executeAddr.equals(breakOnErrorAddr)) {
|
||||
assertTriggered = true;
|
||||
String lastFuncName = getLastFunctionName(testGroup, true);
|
||||
String errFileName = testGroup.mainTestControlBlock.getLastErrorFile(this);
|
||||
int errLineNum = testGroup.mainTestControlBlock.getLastErrorLine(this);
|
||||
if (onPass) {
|
||||
if (callOtherCount != 0) {
|
||||
// force error even if test passed - need to adjust pass count
|
||||
testGroup.testFailed(lastFuncName, errFileName, errLineNum, true,
|
||||
program, executionListener);
|
||||
++callOtherErrors;
|
||||
callOtherCount = 0;
|
||||
}
|
||||
else {
|
||||
testGroup.testPassed(lastFuncName, errFileName, errLineNum, program,
|
||||
executionListener);
|
||||
}
|
||||
}
|
||||
else {
|
||||
testGroup.testFailed(lastFuncName, errFileName, errLineNum, false, program,
|
||||
executionListener);
|
||||
}
|
||||
}
|
||||
else if (executeAddr.equals(printfAddr)) {
|
||||
// enter printf function
|
||||
printfCallAddr = lastAddress;
|
||||
memoryFilter.enabled = false;
|
||||
executionListener.log(testGroup, "printf invocation (log supressed) ...");
|
||||
}
|
||||
else if (printfCallAddr != null && isPrintfReturn(executeAddr, printfCallAddr)) {
|
||||
// return from printf function
|
||||
printfCallAddr = null;
|
||||
memoryFilter.enabled = true;
|
||||
|
||||
String str = testGroup.controlBlock.emuReadString(emuHelper,
|
||||
testGroup.mainTestControlBlock.getPrintfBufferAddress());
|
||||
executionListener.log(testGroup, " " + str);
|
||||
}
|
||||
else {
|
||||
// detect start of new group test and remove from map
|
||||
FunctionInfo functionInfo = subFunctionMap.remove(executeAddr);
|
||||
if (functionInfo != null) {
|
||||
if (currentFunction != null && !assertTriggered) {
|
||||
executionListener.log(testGroup,
|
||||
"ERROR! Group test never executed pass/fail: " + currentFunction);
|
||||
}
|
||||
currentFunction = functionInfo;
|
||||
assertTriggered = (functionInfo.numberOfAsserts == 0);
|
||||
executionListener.log(testGroup,
|
||||
"-------- " + functionInfo.functionName + " (" +
|
||||
functionInfo.numberOfAsserts + functionInfo.numberOfAsserts +
|
||||
"-Asserts) --------");
|
||||
}
|
||||
}
|
||||
|
||||
if (++stepCount > stepLimit) {
|
||||
executionListener.log(testGroup,
|
||||
"Emulation halted due to excessive execution steps");
|
||||
|
||||
String lastFuncName = getLastFunctionName(testGroup, true);
|
||||
String errFileName = testGroup.mainTestControlBlock.getLastErrorFile(this);
|
||||
int errLineNum = testGroup.mainTestControlBlock.getLastErrorLine(this);
|
||||
|
||||
testGroup.severeTestFailure(lastFuncName, errFileName, errLineNum, program,
|
||||
executionListener);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memoryFilter.enabled) {
|
||||
executionListener.logState(this);
|
||||
}
|
||||
|
||||
lastAddress = executeAddr;
|
||||
}
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Msg.error(this, "Unexpected Exception", t);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
memoryFilter.dispose();
|
||||
|
||||
List<FunctionInfo> list = new ArrayList<>(subFunctionMap.values());
|
||||
if (!list.isEmpty()) {
|
||||
// Show list of sub-functions which were never executed
|
||||
Collections.sort(list);
|
||||
executionListener.log(testGroup,
|
||||
"The following sub-functions were never executed:");
|
||||
for (FunctionInfo functionInfo : list) {
|
||||
executionListener.log(testGroup, " " + functionInfo);
|
||||
}
|
||||
}
|
||||
else {
|
||||
executionListener.log(testGroup,
|
||||
"All " + (testGroup.controlBlock.getNumberFunctions() - 1) +
|
||||
" sub-functions were executed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static long alignAddressOffset(long offset, int alignment) {
|
||||
return (offset / alignment) * alignment;
|
||||
}
|
||||
|
||||
static Address alignAddress(Address addr, int alignment) {
|
||||
Address alignedAddr = addr;
|
||||
long offset = addr.getOffset();
|
||||
long alignedOffset = alignAddressOffset(offset, alignment);
|
||||
if (offset != alignedOffset) {
|
||||
alignedAddr = addr.getNewAddress(alignedOffset);
|
||||
}
|
||||
return alignedAddr;
|
||||
}
|
||||
|
||||
private boolean isPrintfReturn(Address executeAddr, Address printfCallAddr) {
|
||||
// look for approximate return relative to address of printf call
|
||||
long offset = executeAddr.getOffset();
|
||||
long maxEnd = printfCallAddr.getOffset() + 32;
|
||||
return (offset > printfCallAddr.getOffset() && offset <= maxEnd);
|
||||
}
|
||||
|
||||
private class MyMemoryAccessFilter extends MemoryAccessFilter {
|
||||
|
||||
boolean enabled = true;
|
||||
|
||||
@Override
|
||||
protected void processWrite(AddressSpace spc, long off, int size, byte[] values) {
|
||||
if (enabled) {
|
||||
executionListener.logWrite(EmulatorTestRunner.this, spc.getAddress(off), size,
|
||||
values);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processRead(AddressSpace spc, long off, int size, byte[] values) {
|
||||
if (enabled &&
|
||||
emu.getEmulateExecutionState() != EmulateExecutionState.INSTRUCTION_DECODE) {
|
||||
executionListener.logRead(EmulatorTestRunner.this, spc.getAddress(off), size,
|
||||
values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyMemoryFaultHandler implements MemoryFaultHandler {
|
||||
|
||||
private ExecutionListener executionListener;
|
||||
|
||||
public MyMemoryFaultHandler(ExecutionListener executionListener) {
|
||||
this.executionListener = executionListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unknownAddress(Address address, boolean write) {
|
||||
Address pc = emuHelper.getExecutionAddress();
|
||||
String access = write ? "written" : "read";
|
||||
executionListener.log(testGroup,
|
||||
"Unknown address " + access + " at " + pc + ": " + address);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean uninitializedRead(Address address, int size, byte[] buf, int bufOffset) {
|
||||
if (emu.getEmulateExecutionState() == EmulateExecutionState.INSTRUCTION_DECODE) {
|
||||
return false;
|
||||
}
|
||||
Address pc = emuHelper.getExecutionAddress();
|
||||
if (!address.isUniqueAddress()) {
|
||||
Register reg = program.getRegister(address, size);
|
||||
if (reg != null) {
|
||||
executionListener.log(testGroup,
|
||||
"Uninitialized register read at " + pc + ": " + reg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
executionListener.log(testGroup,
|
||||
"Uninitialized read at " + pc + ": " + address.toString(true) + ":" + size);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum DumpFormat {
|
||||
HEX, DECIMAL, FLOAT;
|
||||
}
|
||||
|
||||
private abstract class DumpPoint {
|
||||
final Address breakAddr;
|
||||
final int dumpSize;
|
||||
final int elementSize;
|
||||
final DumpFormat elementFormat;
|
||||
final String comment;
|
||||
|
||||
DumpPoint(Address breakAddr, int dumpSize, int elementSize, DumpFormat elementFormat,
|
||||
String comment) {
|
||||
this.breakAddr = breakAddr;
|
||||
this.dumpSize = dumpSize;
|
||||
this.elementSize = elementSize;
|
||||
this.elementFormat = elementFormat;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
abstract Address getDumpAddress();
|
||||
|
||||
public String toString(String addrStr) {
|
||||
return getClass().getSimpleName() + ": " + dumpSize + " " + elementSize +
|
||||
"-byte elements at " + addrStr;
|
||||
}
|
||||
}
|
||||
|
||||
private class AddressDumpPoint extends DumpPoint {
|
||||
final Address dumpAddr;
|
||||
|
||||
AddressDumpPoint(Address breakAddr, Address dumpAddr, int dumpSize, int elementSize,
|
||||
DumpFormat elementFormat, String comment) {
|
||||
super(breakAddr, dumpSize, elementSize, elementFormat, comment);
|
||||
this.dumpAddr = dumpAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
Address getDumpAddress() {
|
||||
return dumpAddr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(dumpAddr.toString(true));
|
||||
}
|
||||
}
|
||||
|
||||
private class RegisterRelativeDumpPoint extends DumpPoint {
|
||||
final Register dumpAddrReg;
|
||||
final int relativeOffset;
|
||||
final AddressSpace dumpAddrSpace;
|
||||
|
||||
RegisterRelativeDumpPoint(Address breakAddr, Register dumpAddrReg, int relativeOffset,
|
||||
AddressSpace dumpAddrSpace, int dumpSize, int elementSize, DumpFormat elementFormat,
|
||||
String comment) {
|
||||
super(breakAddr, dumpSize, elementSize, elementFormat, comment);
|
||||
this.dumpAddrReg = dumpAddrReg;
|
||||
this.relativeOffset = relativeOffset;
|
||||
this.dumpAddrSpace = dumpAddrSpace;
|
||||
}
|
||||
|
||||
@Override
|
||||
Address getDumpAddress() {
|
||||
RegisterValue regVal = getRegisterValue(dumpAddrReg);
|
||||
return dumpAddrSpace.getAddress(regVal.getUnsignedValue().longValue()).add(
|
||||
relativeOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString("0x" + Integer.toHexString(relativeOffset) + "[" + dumpAddrReg + "]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors.support;
|
||||
|
||||
import ghidra.program.model.address.Address;
|
||||
|
||||
public interface ExecutionListener extends TestLogger {
|
||||
|
||||
public void stepCompleted(EmulatorTestRunner testRunner);
|
||||
|
||||
public void logWrite(EmulatorTestRunner testRunner, Address address, int size, byte[] values);
|
||||
|
||||
public void logRead(EmulatorTestRunner testRunner, Address address, int size, byte[] values);
|
||||
|
||||
}
|
@ -0,0 +1,477 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors.support;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import ghidra.app.emulator.EmulatorHelper;
|
||||
import ghidra.docking.settings.SettingsImpl;
|
||||
import ghidra.pcode.memstate.MemoryState;
|
||||
import ghidra.pcode.utils.Utils;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.*;
|
||||
import ghidra.program.model.data.DataUtilities.ClearDataMode;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* <code>PCodeTestAbstractControlBlock</code> data is models the general capabilities
|
||||
* of the TestInfo data structure which is used for different puposes as handled
|
||||
* by extensions of this class.
|
||||
*/
|
||||
public abstract class PCodeTestAbstractControlBlock {
|
||||
|
||||
static final int SIZEOF_U4 = 4;
|
||||
|
||||
protected final Program program;
|
||||
protected final AddressSpace codeSpace;
|
||||
protected final AddressSpace dataSpace;
|
||||
|
||||
protected final int pointerSize;
|
||||
|
||||
protected final Address infoStructAddr;
|
||||
protected final Structure infoProgramStruct;
|
||||
|
||||
private List<FunctionInfo> functions = new ArrayList<>();
|
||||
private HashMap<String, FunctionInfo> functionMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Construct test control block instance for the specified program.
|
||||
* @param program program containing control block structure
|
||||
* @param infoStructAddr program address where structure resides
|
||||
* @param infoStruct appropriate Info structure definition which will have array
|
||||
* of FunctionInfo immediately following.
|
||||
*/
|
||||
PCodeTestAbstractControlBlock(Program program, Address infoStructAddr, Structure infoStruct) {
|
||||
this.program = program;
|
||||
this.pointerSize = program.getDataTypeManager().getDataOrganization().getPointerSize();
|
||||
this.infoStructAddr = infoStructAddr;
|
||||
this.infoProgramStruct = (Structure) infoStruct.clone(program.getDataTypeManager());
|
||||
|
||||
codeSpace = program.getAddressFactory().getDefaultAddressSpace();
|
||||
dataSpace = program.getLanguage().getDefaultDataSpace();
|
||||
}
|
||||
|
||||
public Address getInfoStructureAddress() {
|
||||
return infoStructAddr;
|
||||
}
|
||||
|
||||
public FunctionInfo getFunctionInfo(String functionName) {
|
||||
return functionMap.get(functionName);
|
||||
}
|
||||
|
||||
public FunctionInfo getFunctionInfo(int functionIndex) {
|
||||
return functions.get(functionIndex);
|
||||
}
|
||||
|
||||
public int getNumberFunctions() {
|
||||
return functions.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force an existing reference to refer to the code space. Pointers
|
||||
* created in the data space refer to the data space by default, this method
|
||||
* is used to change these pointers in the data space to refer to
|
||||
* code.
|
||||
* @param addr location with data space which contains code reference
|
||||
*/
|
||||
void forceCodePointer(Address addr) {
|
||||
if (codeSpace == dataSpace) {
|
||||
return;
|
||||
}
|
||||
ReferenceManager refMgr = program.getReferenceManager();
|
||||
Reference ref = refMgr.getPrimaryReferenceFrom(addr, 0);
|
||||
if (ref == null) {
|
||||
return;
|
||||
}
|
||||
Address toAddr = ref.getToAddress();
|
||||
if (!toAddr.getAddressSpace().equals(codeSpace)) {
|
||||
toAddr = codeSpace.getAddress(toAddr.getAddressableWordOffset(), true);
|
||||
Reference newRef =
|
||||
refMgr.addMemoryReference(addr, toAddr, RefType.DATA, SourceType.ANALYSIS, 0);
|
||||
refMgr.setPrimary(newRef, true);
|
||||
refMgr.delete(ref);
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] getCharArrayBytes(Program program, String string) {
|
||||
DataOrganization dataOrganization = program.getDataTypeManager().getDataOrganization();
|
||||
int charSize = dataOrganization.getCharSize();
|
||||
byte[] strBytes = string.getBytes();
|
||||
if (charSize == 1) {
|
||||
return strBytes;
|
||||
}
|
||||
|
||||
// generate aligned byte array
|
||||
int len = charSize * strBytes.length;
|
||||
byte[] bytes = new byte[len];
|
||||
boolean bigEndian = program.getMemory().isBigEndian();
|
||||
int index = 0;
|
||||
int pad = charSize - 1;
|
||||
for (byte strByte : strBytes) {
|
||||
if (bigEndian) {
|
||||
index += pad;
|
||||
}
|
||||
bytes[index++] = strByte;
|
||||
if (!bigEndian) {
|
||||
index += pad;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private Address readPointer(MemBuffer buffer, int bufferOffset, AddressSpace addrSpace,
|
||||
boolean updateReference) {
|
||||
byte[] bytes = new byte[pointerSize];
|
||||
buffer.getBytes(bytes, bufferOffset);
|
||||
long offset = Utils.bytesToLong(bytes, pointerSize, buffer.isBigEndian()) *
|
||||
addrSpace.getAddressableUnitSize();
|
||||
Address addr = addrSpace.getAddress(offset);
|
||||
if (updateReference) {
|
||||
ReferenceManager refMgr = program.getReferenceManager();
|
||||
Address fromAddr = buffer.getAddress().add(bufferOffset);
|
||||
Reference ref = refMgr.getPrimaryReferenceFrom(fromAddr, 0);
|
||||
if (ref != null && !ref.getToAddress().equals(addr)) {
|
||||
refMgr.delete(ref);
|
||||
ref = null;
|
||||
}
|
||||
if (ref == null) {
|
||||
refMgr.addMemoryReference(fromAddr, addr, RefType.DATA, SourceType.USER_DEFINED, 0);
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a Data pointer at the specified address and return the referenced
|
||||
* address.
|
||||
* @param addr address of stored pointer
|
||||
* @return pointer referenced address or null if no pointer found
|
||||
*/
|
||||
protected Address readDefinedDataPointer(Address addr) {
|
||||
Data data = program.getListing().getDefinedDataAt(addr);
|
||||
if (data == null || !(data.getDataType() instanceof Pointer)) {
|
||||
return null;
|
||||
}
|
||||
return (Address) data.getValue();
|
||||
}
|
||||
|
||||
protected Address readCodePointer(MemBuffer buffer, int bufferOffset, boolean updateReference) {
|
||||
Address codePtr = readPointer(buffer, bufferOffset, codeSpace, updateReference);
|
||||
|
||||
// shift the pointer if code pointers are stored in memory shifted.
|
||||
int ptrShift = program.getDataTypeManager().getDataOrganization().getPointerShift();
|
||||
if (ptrShift != 0) {
|
||||
codePtr = codePtr.getNewAddress(codePtr.getOffset() << ptrShift);
|
||||
}
|
||||
|
||||
// Check for potential procedure descriptor indirection (e.g., PPC64 .opd)
|
||||
// in which case a function pointer may refer to a procedure descriptor
|
||||
// record (we assume here that the first entry has been marked-up by the importer
|
||||
// and corresponds to the true function address
|
||||
|
||||
Address ptr = readDefinedDataPointer(codePtr);
|
||||
if (ptr != null) {
|
||||
codePtr = ptr;
|
||||
}
|
||||
|
||||
return codePtr;
|
||||
}
|
||||
|
||||
protected Address readDataPointer(MemBuffer buffer, int bufferOffset, boolean updateReference) {
|
||||
return readPointer(buffer, bufferOffset, dataSpace, updateReference);
|
||||
}
|
||||
|
||||
protected Address readPointer(int controlBlockOffset) throws MemoryAccessException {
|
||||
Address addr = infoStructAddr.add(controlBlockOffset);
|
||||
byte[] bytes = new byte[pointerSize];
|
||||
Memory memory = program.getMemory();
|
||||
if (memory.getBytes(addr, bytes) != pointerSize) {
|
||||
throw new MemoryAccessException(
|
||||
"Failed to read program memory: " + pointerSize + " bytes at " + addr);
|
||||
}
|
||||
long offset = Utils.bytesToLong(bytes, pointerSize, memory.isBigEndian());
|
||||
return infoStructAddr.getNewAddress(offset);
|
||||
}
|
||||
|
||||
// protected void applyPointerData(Program program, Address addr) {
|
||||
// Pointer dt = new PointerDataType(program.getDataTypeManager());
|
||||
// if (dt.getLength() != pointerSize) {
|
||||
// switch (pointerSize) {
|
||||
// case 2:
|
||||
// dt = new Pointer16DataType();
|
||||
// break;
|
||||
// case 3:
|
||||
// dt = new Pointer24DataType();
|
||||
// break;
|
||||
// case 4:
|
||||
// dt = new Pointer32DataType();
|
||||
// break;
|
||||
// case 5:
|
||||
// dt = new Pointer40DataType();
|
||||
// break;
|
||||
// case 6:
|
||||
// dt = new Pointer48DataType();
|
||||
// break;
|
||||
// case 7:
|
||||
// dt = new Pointer56DataType();
|
||||
// break;
|
||||
// case 8:
|
||||
// dt = new Pointer64DataType();
|
||||
// break;
|
||||
// default:
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// try {
|
||||
// program.getListing().createData(addr, dt);
|
||||
// }
|
||||
// catch (CodeUnitInsertionException e) {
|
||||
// // ignore
|
||||
// }
|
||||
// catch (DataTypeConflictException e) {
|
||||
// // ignore
|
||||
// }
|
||||
// }
|
||||
|
||||
protected void applyU4Data(Address addr) {
|
||||
try {
|
||||
program.getListing().createData(addr, DWordDataType.dataType);
|
||||
}
|
||||
catch (CodeUnitInsertionException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (DataTypeConflictException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
protected int getStructureComponent(Structure testInfoStruct, String fieldName) {
|
||||
for (DataTypeComponent component : testInfoStruct.getComponents()) {
|
||||
if (fieldName.equals(component.getFieldName())) {
|
||||
return component.getOffset();
|
||||
}
|
||||
}
|
||||
throw new RuntimeException(fieldName + " field not found within " +
|
||||
testInfoStruct.getName() + " structure definition at " + infoStructAddr.toString(true));
|
||||
}
|
||||
|
||||
protected void readControlBlock(boolean applyStruct)
|
||||
throws InvalidControlBlockException, CodeUnitInsertionException {
|
||||
|
||||
if (applyStruct) {
|
||||
DataUtilities.createData(program, infoStructAddr, infoProgramStruct, -1, false,
|
||||
ClearDataMode.CLEAR_ALL_CONFLICT_DATA);
|
||||
}
|
||||
|
||||
TerminatedStringDataType stringType =
|
||||
new TerminatedStringDataType(program.getDataTypeManager());
|
||||
|
||||
Structure functionInfoStruct =
|
||||
(Structure) infoProgramStruct.getDataTypeManager().getDataType(CategoryPath.ROOT,
|
||||
"FunctionInfo");
|
||||
if (functionInfoStruct == null) {
|
||||
throw new AssertException("FunctionInfo structure not yet resolved");
|
||||
}
|
||||
|
||||
int nameOffset = getStructureComponent(functionInfoStruct, "name");
|
||||
int funcOffset = getStructureComponent(functionInfoStruct, "func");
|
||||
int numTestOffset = getStructureComponent(functionInfoStruct, "numTest");
|
||||
|
||||
try {
|
||||
|
||||
DumbMemBufferImpl memBuffer =
|
||||
new DumbMemBufferImpl(program.getMemory(), infoStructAddr);
|
||||
int functionArrayPtrOffset =
|
||||
getStructureComponent(infoProgramStruct, "funcInfoArrayPtr");
|
||||
Address functionInfoAddress =
|
||||
readDataPointer(memBuffer, functionArrayPtrOffset, applyStruct);
|
||||
|
||||
Msg.info(this, "Loading FunctionInfo array at " + functionInfoAddress);
|
||||
|
||||
while (true) {
|
||||
// Read function table
|
||||
memBuffer.setPosition(functionInfoAddress);
|
||||
|
||||
if (applyStruct) {
|
||||
DataUtilities.createData(program, functionInfoAddress, functionInfoStruct, -1,
|
||||
false, ClearDataMode.CLEAR_ALL_CONFLICT_DATA);
|
||||
forceCodePointer(functionInfoAddress.add(funcOffset));
|
||||
}
|
||||
|
||||
Address funcNamePtr = readDataPointer(memBuffer, nameOffset, applyStruct);
|
||||
Address funcPtr = readCodePointer(memBuffer, funcOffset, applyStruct);
|
||||
int numTest = memBuffer.getInt(numTestOffset);
|
||||
|
||||
if (funcNamePtr.getOffset() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
memBuffer.setPosition(funcNamePtr);
|
||||
String functionName =
|
||||
(String) stringType.getValue(memBuffer, SettingsImpl.NO_SETTINGS, 0);
|
||||
|
||||
if (funcPtr.getOffset() != 0) {
|
||||
MemoryBlock block = program.getMemory().getBlock(funcPtr);
|
||||
if (block == null || !block.isInitialized()) {
|
||||
throw new InvalidControlBlockException(
|
||||
infoProgramStruct.getName() + " @ " + infoStructAddr.toString(true) +
|
||||
" has invalid pointer offset for function: " + functionName +
|
||||
" -> " + funcPtr);
|
||||
}
|
||||
}
|
||||
|
||||
if (funcPtr.getOffset() != 0) {
|
||||
FunctionInfo info = new FunctionInfo(functionName, funcPtr, numTest);
|
||||
functions.add(info);
|
||||
functionMap.put(functionName, info);
|
||||
}
|
||||
|
||||
functionInfoAddress = functionInfoAddress.add(functionInfoStruct.getLength());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
throw new InvalidControlBlockException(
|
||||
infoProgramStruct.getName() + " program read error", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String emuReadString(EmulatorHelper emu, Address strPtrAddr) {
|
||||
|
||||
DataOrganization dataOrganization =
|
||||
emu.getProgram().getDataTypeManager().getDataOrganization();
|
||||
int charSize = dataOrganization.getCharSize();
|
||||
boolean isBigEndian = emu.getProgram().getMemory().isBigEndian();
|
||||
|
||||
MemoryState memState = emu.getEmulator().getMemState();
|
||||
long offset = strPtrAddr.getOffset();
|
||||
if (isBigEndian) {
|
||||
offset += (charSize - 1);
|
||||
}
|
||||
char[] buffer = new char[128];
|
||||
int index = 0;
|
||||
while (index < buffer.length) {
|
||||
buffer[index] =
|
||||
(char) (memState.getValue(strPtrAddr.getAddressSpace(), offset, 1) & 0xff);
|
||||
if (buffer[index] == 0) {
|
||||
break;
|
||||
}
|
||||
offset += charSize;
|
||||
++index;
|
||||
}
|
||||
return new String(buffer, 0, index);
|
||||
}
|
||||
|
||||
protected long emuRead(EmulatorHelper emu, Address addr, int size) {
|
||||
if (size < 1 || size > 8) {
|
||||
throw new IllegalArgumentException("Unsupported EMU read size: " + size);
|
||||
}
|
||||
MemoryState memState = emu.getEmulator().getMemState();
|
||||
return memState.getValue(addr.getAddressSpace(), addr.getOffset(), size);
|
||||
}
|
||||
|
||||
protected void emuWrite(EmulatorHelper emu, Address addr, int size, long value) {
|
||||
if (size < 1 || size > 8) {
|
||||
throw new IllegalArgumentException("Unsupported EMU read size: " + size);
|
||||
}
|
||||
MemoryState memState = emu.getEmulator().getMemState();
|
||||
memState.setValue(addr.getAddressSpace(), addr.getOffset(), size, value);
|
||||
}
|
||||
|
||||
protected Address getMirroredDataAddress(EmulatorTestRunner emuTestRunner, Address addr) {
|
||||
AddressSpace defaultDataSpace =
|
||||
emuTestRunner.getProgram().getLanguage().getDefaultDataSpace();
|
||||
if (defaultDataSpace != null && !addr.getAddressSpace().equals(defaultDataSpace)) {
|
||||
addr = defaultDataSpace.getAddress(addr.getOffset());
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
static Address findBytes(Memory memory, AddressSetView set, byte[] bytes) {
|
||||
for (AddressRange range : set.getAddressRanges()) {
|
||||
Address addr = memory.findBytes(range.getMinAddress(), range.getMaxAddress(), bytes,
|
||||
null, true, TaskMonitor.DUMMY);
|
||||
if (addr != null) {
|
||||
// ignore overlay blocks which may have been created by the importer
|
||||
if (addr.getAddressSpace().isOverlaySpace()) {
|
||||
continue;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class InvalidControlBlockException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 9137869694955008327L;
|
||||
|
||||
public InvalidControlBlockException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public InvalidControlBlockException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FunctionInfo implements Comparable<FunctionInfo> {
|
||||
|
||||
public final String functionName;
|
||||
public final Address functionAddr;
|
||||
public final int numberOfAsserts;
|
||||
|
||||
FunctionInfo(String functionName, Address functionAddr, int numberOfAsserts) {
|
||||
this.functionName = functionName;
|
||||
this.functionAddr = functionAddr;
|
||||
this.numberOfAsserts = numberOfAsserts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FunctionInfo other) {
|
||||
return functionName.compareTo(other.functionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof FunctionInfo)) {
|
||||
return false;
|
||||
}
|
||||
FunctionInfo other = (FunctionInfo) obj;
|
||||
return functionName.equals(other.functionName) &
|
||||
functionAddr.equals(other.functionAddr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return functionAddr.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return functionName + "@" + functionAddr.toString(true);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,528 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors.support;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
|
||||
import ghidra.test.processors.support.PCodeTestResults.TestResults;
|
||||
import ghidra.util.HTMLUtilities;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.xml.GenericXMLOutputter;
|
||||
import ghidra.util.xml.XmlUtilities;
|
||||
import resources.ResourceManager;
|
||||
|
||||
public class PCodeTestCombinedTestResults {
|
||||
|
||||
public static final String FILENAME = "pcode_test_results";
|
||||
|
||||
private static String XML_VERSION = "1";
|
||||
|
||||
// char width used when computing result column width
|
||||
private static int CHAR_WIDTH = 6;
|
||||
|
||||
private File xmlFile;
|
||||
private File htmlFile;
|
||||
|
||||
private Map<String, PCodeTestResults> combinedResults = new HashMap<>();
|
||||
|
||||
PCodeTestCombinedTestResults(File reportsDir, boolean readExisting) throws IOException {
|
||||
this.xmlFile = new File(reportsDir, FILENAME + ".xml");
|
||||
this.htmlFile = new File(reportsDir, FILENAME + ".html");
|
||||
if (readExisting && xmlFile.exists()) {
|
||||
restoreFromXml();
|
||||
}
|
||||
}
|
||||
|
||||
public PCodeTestResults getTestResults(String jUnitName, boolean create) {
|
||||
PCodeTestResults testResults = combinedResults.get(jUnitName);
|
||||
if (testResults == null && create) {
|
||||
testResults = new PCodeTestResults(jUnitName);
|
||||
combinedResults.put(jUnitName, testResults);
|
||||
}
|
||||
return testResults;
|
||||
}
|
||||
|
||||
private void restoreFromXml() throws IOException {
|
||||
|
||||
FileInputStream istream = new FileInputStream(xmlFile);
|
||||
BufferedInputStream bis = new BufferedInputStream(istream);
|
||||
try {
|
||||
SAXBuilder sax = XmlUtilities.createSecureSAXBuilder(false, false);
|
||||
Document doc = sax.build(bis);
|
||||
Element root = doc.getRootElement();
|
||||
|
||||
if (!"PCODE_TESTS".equals(root.getName()) ||
|
||||
!XML_VERSION.equals(root.getAttributeValue("VERSION"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Element> elementList = root.getChildren(PCodeTestResults.TAG_NAME);
|
||||
for (Element element : elementList) {
|
||||
PCodeTestResults testResults = new PCodeTestResults(element);
|
||||
combinedResults.put(testResults.getJUnitName(), testResults);
|
||||
}
|
||||
}
|
||||
catch (org.jdom.JDOMException je) {
|
||||
throw new IOException("Invalid P-Code test results xml file: " + xmlFile, je);
|
||||
}
|
||||
finally {
|
||||
istream.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void saveToXml() throws IOException {
|
||||
|
||||
File dir = xmlFile.getParentFile();
|
||||
if (!dir.exists() && !dir.mkdir()) {
|
||||
throw new IOException("Failed to created directory: " + dir);
|
||||
}
|
||||
|
||||
Element root = new Element("PCODE_TESTS");
|
||||
root.setAttribute("VERSION", XML_VERSION);
|
||||
|
||||
for (String name : combinedResults.keySet()) {
|
||||
PCodeTestResults testResults = combinedResults.get(name);
|
||||
root.addContent(testResults.saveToXml());
|
||||
}
|
||||
|
||||
// Store checkout data in temporary file
|
||||
File tmpFile = new File(xmlFile.getParentFile(), xmlFile.getName() + ".new");
|
||||
tmpFile.delete();
|
||||
FileOutputStream ostream = new FileOutputStream(tmpFile);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(ostream);
|
||||
|
||||
try {
|
||||
Document doc = new Document(root);
|
||||
XMLOutputter xmlout = new GenericXMLOutputter();
|
||||
xmlout.output(doc, bos);
|
||||
}
|
||||
finally {
|
||||
bos.close();
|
||||
}
|
||||
|
||||
// Rename files
|
||||
File oldFile = null;
|
||||
if (xmlFile.exists()) {
|
||||
oldFile = new File(xmlFile.getParentFile(), xmlFile.getName() + ".bak");
|
||||
oldFile.delete();
|
||||
if (!xmlFile.renameTo(oldFile)) {
|
||||
throw new IOException("Failed to update: " + xmlFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
if (!tmpFile.renameTo(xmlFile)) {
|
||||
if (oldFile != null) {
|
||||
oldFile.renameTo(xmlFile);
|
||||
}
|
||||
throw new IOException("Failed to update: " + xmlFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
Msg.info(this, "XML results file updated: " + xmlFile.getAbsolutePath());
|
||||
|
||||
if (oldFile != null) {
|
||||
oldFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
void copyResourceFile(String resourceName, PrintWriter w) throws IOException {
|
||||
InputStream in = ResourceManager.getResourceAsStream(resourceName);
|
||||
if (in == null) {
|
||||
throw new FileNotFoundException("Resource not found: " + resourceName);
|
||||
}
|
||||
in = new BufferedInputStream(in);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
w.println(line);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
|
||||
private static class NamedTestColumn implements Comparable<NamedTestColumn> {
|
||||
private final String groupTestName;
|
||||
//String groupName;
|
||||
private final String testName;
|
||||
int charCount = 5; // char-count (minimum: -/-/-)
|
||||
|
||||
/**
|
||||
*
|
||||
* @param groupTestName <group-name>.<test-name>
|
||||
*/
|
||||
NamedTestColumn(String groupTestName) {
|
||||
this.groupTestName = groupTestName;
|
||||
|
||||
int index = groupTestName.indexOf('.');
|
||||
//String groupName = "";
|
||||
String testName = groupTestName;
|
||||
if (index >= 0) {
|
||||
//groupName = groupTestName.substring(0, index);
|
||||
testName = groupTestName.substring(index + 1);
|
||||
}
|
||||
|
||||
this.testName = testName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <group-name>.<test-name>
|
||||
*/
|
||||
public String getGroupTestName() {
|
||||
return groupTestName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <test-name>
|
||||
*/
|
||||
public String getTestName() {
|
||||
return testName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(NamedTestColumn o) {
|
||||
return testName.compareTo(o.testName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return testName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NamedTestColumn)) {
|
||||
return false;
|
||||
}
|
||||
NamedTestColumn other = (NamedTestColumn) obj;
|
||||
return testName.equals(other.testName);
|
||||
}
|
||||
|
||||
public int getColumnWidth() {
|
||||
return (charCount + 2) * CHAR_WIDTH;
|
||||
}
|
||||
|
||||
public void adjustWidth(TestResults testResults) {
|
||||
if (testResults == null) {
|
||||
return;
|
||||
}
|
||||
int count =
|
||||
computeCharCount(testResults.passCount) + computeCharCount(testResults.failCount) +
|
||||
computeCharCount(testResults.callOtherCount) + 2;
|
||||
charCount = Math.max(count, charCount);
|
||||
}
|
||||
|
||||
private static int computeCharCount(int value) {
|
||||
int count = 1;
|
||||
while (value > 9) {
|
||||
++count;
|
||||
value /= 10;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
void saveToHTML() throws IOException {
|
||||
File dir = htmlFile.getParentFile();
|
||||
if (!dir.exists() && !dir.mkdir()) {
|
||||
throw new IOException("Failed to created directory: " + dir);
|
||||
}
|
||||
|
||||
List<String> sortedJUnitTestNames = new ArrayList<>();
|
||||
Map<String, Set<NamedTestColumn>> allTestNamesMap = new HashMap<>(); // mapped by <group-name>
|
||||
Map<String, NamedTestColumn> namedTestColumnMap = new HashMap<>(); // mapped by <group-name>.<test-name> key
|
||||
for (PCodeTestResults unitTestResults : combinedResults.values()) {
|
||||
sortedJUnitTestNames.add(unitTestResults.getJUnitName());
|
||||
for (String groupTestName : unitTestResults.getGroupTestNames()) {
|
||||
|
||||
int index = groupTestName.indexOf('.');
|
||||
String groupName = "";
|
||||
if (index >= 0) {
|
||||
groupName = groupTestName.substring(0, index);
|
||||
}
|
||||
|
||||
Set<NamedTestColumn> set = allTestNamesMap.get(groupName);
|
||||
if (set == null) {
|
||||
set = new HashSet<>();
|
||||
allTestNamesMap.put(groupName, set);
|
||||
}
|
||||
|
||||
NamedTestColumn namedTestColumn = namedTestColumnMap.get(groupTestName);
|
||||
if (namedTestColumn == null) {
|
||||
namedTestColumn = new NamedTestColumn(groupTestName);
|
||||
namedTestColumnMap.put(groupTestName, namedTestColumn);
|
||||
set.add(namedTestColumn);
|
||||
}
|
||||
|
||||
namedTestColumn.adjustWidth(unitTestResults.getTestResults(groupTestName, false));
|
||||
}
|
||||
}
|
||||
|
||||
String[] groupNames = allTestNamesMap.keySet().toArray(new String[allTestNamesMap.size()]);
|
||||
Arrays.sort(groupNames);
|
||||
|
||||
Map<String, NamedTestColumn[]> allTestNamesByGroup = new HashMap<>();
|
||||
for (String groupName : groupNames) {
|
||||
Set<NamedTestColumn> set = allTestNamesMap.get(groupName);
|
||||
NamedTestColumn[] namedTestColumns = set.toArray(new NamedTestColumn[set.size()]);
|
||||
Arrays.sort(namedTestColumns);
|
||||
allTestNamesByGroup.put(groupName, namedTestColumns);
|
||||
}
|
||||
|
||||
Collections.sort(sortedJUnitTestNames);
|
||||
|
||||
// Store checkout data in temporary file
|
||||
File tmpFile = new File(xmlFile.getParentFile(), xmlFile.getName() + ".new");
|
||||
tmpFile.delete();
|
||||
|
||||
PrintWriter w = new PrintWriter(tmpFile);
|
||||
try {
|
||||
copyResourceFile("pcodetest/chunk1.hinc", w);
|
||||
|
||||
writeTableHeader(w, groupNames, allTestNamesByGroup);
|
||||
|
||||
copyResourceFile("pcodetest/chunk2.hinc", w);
|
||||
|
||||
int rownum = 1;
|
||||
for (String name : sortedJUnitTestNames) {
|
||||
PCodeTestResults testResults = combinedResults.get(name);
|
||||
writeTestSummaryRow(w, testResults, (rownum++ % 2) == 1);
|
||||
}
|
||||
|
||||
copyResourceFile("pcodetest/chunk3.hinc", w);
|
||||
|
||||
boolean firstRow = true;
|
||||
for (String name : sortedJUnitTestNames) {
|
||||
PCodeTestResults testResults = combinedResults.get(name);
|
||||
writeTestResultsRow(w, groupNames, allTestNamesByGroup, testResults,
|
||||
(rownum++ % 2) == 1, firstRow);
|
||||
firstRow = false;
|
||||
}
|
||||
|
||||
copyResourceFile("pcodetest/chunk4.hinc", w);
|
||||
}
|
||||
finally {
|
||||
w.flush();
|
||||
w.close();
|
||||
}
|
||||
|
||||
// Rename files
|
||||
File oldFile = null;
|
||||
if (htmlFile.exists()) {
|
||||
oldFile = new File(htmlFile.getParentFile(), htmlFile.getName() + ".bak");
|
||||
oldFile.delete();
|
||||
if (!htmlFile.renameTo(oldFile)) {
|
||||
throw new IOException("Failed to update: " + htmlFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
if (!tmpFile.renameTo(htmlFile)) {
|
||||
if (oldFile != null) {
|
||||
oldFile.renameTo(htmlFile);
|
||||
}
|
||||
throw new IOException("Failed to update: " + htmlFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
Msg.info(this, "HTML results file updated: " + htmlFile.getAbsolutePath());
|
||||
|
||||
if (oldFile != null) {
|
||||
oldFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTableHeader(PrintWriter w, String[] groupNames,
|
||||
Map<String, NamedTestColumn[]> allTestNamesByGroup) {
|
||||
|
||||
int[] groupWidth = new int[groupNames.length];
|
||||
|
||||
w.println("<tr>");
|
||||
for (int groupIndex = 0; groupIndex < groupNames.length; groupIndex++) {
|
||||
String groupName = groupNames[groupIndex];
|
||||
NamedTestColumn[] namedTestColumns = allTestNamesByGroup.get(groupName);
|
||||
for (NamedTestColumn namedTestColumn : namedTestColumns) {
|
||||
int columnWidth = namedTestColumn.getColumnWidth();
|
||||
w.print("<td class=\"ResultHead\" align=\"center\" valign=\"bottom\">");
|
||||
w.print("<img src=\"X\" border=0 height=1 width=" + columnWidth + "><br>");
|
||||
w.print("<div class=\"r90\">");
|
||||
w.print(HTMLUtilities.friendlyEncodeHTML(namedTestColumn.getTestName()));
|
||||
w.println("</div></td>");
|
||||
groupWidth[groupIndex] += columnWidth;
|
||||
}
|
||||
}
|
||||
|
||||
w.println("</tr><tr>");
|
||||
|
||||
for (int groupIndex = 0; groupIndex < groupNames.length; groupIndex++) {
|
||||
String groupName = groupNames[groupIndex];
|
||||
NamedTestColumn[] namedTestColumns = allTestNamesByGroup.get(groupName);
|
||||
w.print(
|
||||
"<td class=\"GroupHead\" valign=\"middle\" colspan=\"" + namedTestColumns.length +
|
||||
"\" style=\"max-width:" + groupWidth[groupIndex] + ";\"> ");
|
||||
if (groupName.length() != 0) {
|
||||
w.print(HTMLUtilities.friendlyEncodeHTML(groupName));
|
||||
}
|
||||
w.println("</td>");
|
||||
}
|
||||
|
||||
w.println("</tr>");
|
||||
}
|
||||
|
||||
private void writeResultCount(PrintWriter w, int count, String color) {
|
||||
if (count == 0) {
|
||||
w.print("<font color=\"gray\">-</font>");
|
||||
}
|
||||
else {
|
||||
w.print("<font color=\"" + color + "\">" + Integer.toString(count) + "</font>");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTestSummaryRow(PrintWriter w, PCodeTestResults testResults, boolean shaded) {
|
||||
String shadeStyle = "";
|
||||
if (shaded) {
|
||||
shadeStyle = " class=\"shade\"";
|
||||
}
|
||||
w.println("<tr" + shadeStyle + ">");
|
||||
|
||||
w.print(" <td class=\"TestName\"><a href=\"../logs/" + testResults.getJUnitName() +
|
||||
".log\" target=\"_log\">");
|
||||
w.print(testResults.getJUnitName());
|
||||
w.println("</a></td><td class=\"DateTime\">");
|
||||
|
||||
String time = testResults.getTime();
|
||||
if (time == null) {
|
||||
time = " ";
|
||||
}
|
||||
w.print(time);
|
||||
w.println("</td>");
|
||||
|
||||
// Summary result
|
||||
if (testResults.summaryHasIngestErrors || testResults.summaryHasRelocationErrors ||
|
||||
testResults.summaryHasDisassemblyErrors) {
|
||||
// analyzed program has relocation or disassembly errors
|
||||
w.print("<td align=\"center\" class=\"ResultSummary bad\">");
|
||||
if (testResults.summaryHasIngestErrors) {
|
||||
w.print("<font color=\"red\">Ingest-Err</font><br>");
|
||||
}
|
||||
if (testResults.summaryHasRelocationErrors) {
|
||||
w.print("<font color=\"red\">Reloc-Err</font><br>");
|
||||
}
|
||||
if (testResults.summaryHasDisassemblyErrors) {
|
||||
w.print("<font color=\"red\">Dis-Err</font>");
|
||||
}
|
||||
}
|
||||
else {
|
||||
w.print("<td align=\"center\" class=\"ResultSummary " +
|
||||
getSummaryHighlightColorClass(testResults) + "\">");
|
||||
writeResultCount(w, testResults.summaryPassCount, "green");
|
||||
w.print("/");
|
||||
writeResultCount(w, testResults.summaryFailCount, "red");
|
||||
w.print("/");
|
||||
writeResultCount(w, testResults.summaryCallOtherCount, "orange");
|
||||
if (testResults.summarySevereFailures != 0) {
|
||||
w.print("<br><font color=\"red\">ERR: " + testResults.summarySevereFailures +
|
||||
"</font>");
|
||||
}
|
||||
}
|
||||
|
||||
w.println("</td>");
|
||||
|
||||
w.println("</tr>");
|
||||
}
|
||||
|
||||
private String getSummaryHighlightColorClass(PCodeTestResults testResults) {
|
||||
int failCount = testResults.summaryFailCount;
|
||||
String summaryHighlight = "";
|
||||
int totalAsserts =
|
||||
testResults.summaryPassCount + failCount + testResults.summaryCallOtherCount;
|
||||
if (testResults.summarySevereFailures != 0 ||
|
||||
totalAsserts != testResults.summaryTotalAsserts) {
|
||||
summaryHighlight = "bad";
|
||||
// bump-up failure count to reflect expected number of assertions
|
||||
int diff =
|
||||
totalAsserts - (testResults.summaryPassCount + testResults.summaryCallOtherCount);
|
||||
if (diff > 0) {
|
||||
failCount = diff;
|
||||
}
|
||||
}
|
||||
else if ((testResults.summaryPassCount != 0) && (failCount == 0) &&
|
||||
(testResults.summaryCallOtherCount == 0)) {
|
||||
summaryHighlight = "good";
|
||||
}
|
||||
return summaryHighlight;
|
||||
}
|
||||
|
||||
private void writeTestResultsRow(PrintWriter w, String[] groupNames,
|
||||
Map<String, NamedTestColumn[]> allTestNamesByGroup, PCodeTestResults testResults,
|
||||
boolean shaded, boolean firstRow) {
|
||||
|
||||
String shadeStyle = "";
|
||||
if (shaded) {
|
||||
shadeStyle = " class=\"shade\"";
|
||||
}
|
||||
w.println("<tr" + shadeStyle + ">");
|
||||
|
||||
for (String groupName : groupNames) {
|
||||
NamedTestColumn[] namedTestColumns = allTestNamesByGroup.get(groupName);
|
||||
for (NamedTestColumn namedTestColumn : namedTestColumns) {
|
||||
String testName = namedTestColumn.getTestName();
|
||||
int pass = testResults.getPassResult(groupName, testName);
|
||||
int fail = testResults.getFailResult(groupName, testName);
|
||||
int callother = testResults.getCallOtherResult(groupName, testName);
|
||||
int total = pass + fail + callother;
|
||||
int totalAsserts = testResults.getTotalAsserts(groupName, testName);
|
||||
|
||||
boolean severeFailure = testResults.hadSevereFailure(groupName, testName);
|
||||
|
||||
boolean highlightBad = !severeFailure && (total != 0) && (total != totalAsserts);
|
||||
|
||||
w.print(
|
||||
" <td align=\"center\" class=\"Result" + (highlightBad ? " bad" : "") + "\">");
|
||||
if (firstRow) {
|
||||
w.print("<img src=\"X\" border=0 height=1 width=" +
|
||||
namedTestColumn.getColumnWidth() + "><br>");
|
||||
}
|
||||
if (severeFailure) {
|
||||
w.print("<font color=\"red\">ERR</font>");
|
||||
}
|
||||
else {
|
||||
if (total == 0) {
|
||||
if (totalAsserts == 0) {
|
||||
w.print("<font color=\"gray\">-</font>");
|
||||
}
|
||||
else {
|
||||
w.print("<font color=\"red\">x</font>");
|
||||
}
|
||||
}
|
||||
else {
|
||||
writeResultCount(w, pass, "green");
|
||||
w.print("/");
|
||||
writeResultCount(w, fail, "red");
|
||||
w.print("/");
|
||||
writeResultCount(w, callother, "orange");
|
||||
if (total != totalAsserts) {
|
||||
w.print("<br><font color=\"red\">(!=" + totalAsserts + ")</font>");
|
||||
}
|
||||
}
|
||||
}
|
||||
w.println("</td>");
|
||||
}
|
||||
}
|
||||
w.println("</tr>");
|
||||
}
|
||||
}
|
@ -0,0 +1,418 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.DataOrganization;
|
||||
import ghidra.program.model.data.Structure;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
/**
|
||||
* <code>PCodeTestControlBlock</code> data is read from each binary test file and
|
||||
* identified by the MAIN_CONTROL_BLOCK_MAGIC 64-bit character field value at the start of the
|
||||
* data structure. Only one instance of this should exist within the binary.
|
||||
*/
|
||||
public class PCodeTestControlBlock extends PCodeTestAbstractControlBlock {
|
||||
|
||||
static final String INITIAL_FUNCTION_NAME = "<NONE>";
|
||||
static final String UNKNOWN_FUNCTION_NAME = "<UNKNOWN>";
|
||||
|
||||
private static final String MAIN_CONTROL_BLOCK_MAGIC = "AbCdEFgH";
|
||||
|
||||
private static Structure testInfoStruct; // TestInfo structure
|
||||
private static Structure groupInfoStruct; // GroupInfo structure
|
||||
|
||||
private final AddressSetView restrictedSet;
|
||||
|
||||
public final PCodeTestFile testFile;
|
||||
public final String cachedProgramPath;
|
||||
|
||||
private List<PCodeTestGroup> testGroups; // test group data
|
||||
|
||||
// TestInfo data read from program memory
|
||||
private Address onPassFunctionAddress;
|
||||
private Address onErrorFunctionAddress;
|
||||
private Address onDoneFunctionAddress;
|
||||
private Address sprintfFunctionAddress;
|
||||
private Address sprintfBufferAddress;
|
||||
|
||||
// TestInfo structure offsets for runtime use
|
||||
private int numPassOffset;
|
||||
private int numFailOffset;
|
||||
private int lastTestPosOffset;
|
||||
private int lastErrorLineOffset;
|
||||
private int lastErrorFileOffset;
|
||||
private int lastFuncOffset;
|
||||
|
||||
private int sprintfEnableOffset;
|
||||
|
||||
private final PCodeTestResults testResults;
|
||||
|
||||
/**
|
||||
* Construct test control block instance for the specified
|
||||
* program. Create TestInfo structure data within program if requested.
|
||||
* @param program program containing control block structure
|
||||
* @param restrictedSet the restricted memory area which should be searched
|
||||
* for control structures
|
||||
* @param testInfoStructAddr address of Main TestInfo structure
|
||||
* @param testFile original binary test file
|
||||
* @param cachedProgramPath program path within program file cache
|
||||
* @param applyStruct create structure Data within program if true
|
||||
* @throws InvalidControlBlockException
|
||||
* @throws CodeUnitInsertionException if applyStruct failed
|
||||
*/
|
||||
private PCodeTestControlBlock(Program program, AddressSetView restrictedSet,
|
||||
Address testInfoStructAddr, PCodeTestFile testFile, String cachedProgramPath,
|
||||
boolean applyStruct, PCodeTestResults testResults)
|
||||
throws InvalidControlBlockException, CodeUnitInsertionException {
|
||||
super(program, testInfoStructAddr, testInfoStruct);
|
||||
|
||||
this.restrictedSet = restrictedSet;
|
||||
this.testFile = testFile;
|
||||
this.cachedProgramPath = cachedProgramPath;
|
||||
this.testResults = testResults;
|
||||
|
||||
readControlBlock(applyStruct);
|
||||
|
||||
numPassOffset = getStructureComponent(infoProgramStruct, "numpass");
|
||||
numFailOffset = getStructureComponent(infoProgramStruct, "numfail");
|
||||
lastTestPosOffset = getStructureComponent(infoProgramStruct, "lastTestPos");
|
||||
lastErrorLineOffset = getStructureComponent(infoProgramStruct, "lastErrorLine");
|
||||
lastErrorFileOffset = getStructureComponent(infoProgramStruct, "lastErrorFile");
|
||||
lastFuncOffset = getStructureComponent(infoProgramStruct, "lastFunc");
|
||||
|
||||
sprintfEnableOffset = getStructureComponent(infoProgramStruct, "sprintf5Enabled");
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Main TestInfo structure within memory and return instance of PCodeTestControlBlock
|
||||
* @param program
|
||||
* @param testFile original binary test file
|
||||
* @param restrictedSet a restricted set to be searched for control structures
|
||||
* @param cachedProgramPath program path within program file cache
|
||||
* @param testInfoStruct TestInfo structure definition
|
||||
* @param groupInfoStruct GroupInfo structure definition
|
||||
* @param applyStruct create structure Data within program if true
|
||||
* @param testResults test results storage object
|
||||
* @return instance of PCodeTestControlBlock
|
||||
* @throws InvalidControlBlockException
|
||||
* @throws CodeUnitInsertionException
|
||||
*/
|
||||
static PCodeTestControlBlock getMainControlBlock(Program program, PCodeTestFile testFile,
|
||||
AddressSetView restrictedSet, String cachedProgramPath, Structure testInfoStruct,
|
||||
Structure groupInfoStruct, boolean applyStruct, PCodeTestResults testResults)
|
||||
throws InvalidControlBlockException, CodeUnitInsertionException {
|
||||
|
||||
PCodeTestControlBlock.testInfoStruct = testInfoStruct;
|
||||
PCodeTestControlBlock.groupInfoStruct = groupInfoStruct;
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
byte[] magicBytes = getCharArrayBytes(program, MAIN_CONTROL_BLOCK_MAGIC);
|
||||
|
||||
Address startOfControlBlock = findBytes(memory, restrictedSet, magicBytes);
|
||||
if (startOfControlBlock == null) {
|
||||
throw new InvalidControlBlockException("TestInfo structure not found");
|
||||
}
|
||||
|
||||
return new PCodeTestControlBlock(program, restrictedSet, startOfControlBlock, testFile,
|
||||
cachedProgramPath, applyStruct, testResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ":" + testFile;
|
||||
}
|
||||
|
||||
public List<PCodeTestGroup> getTestGroups() {
|
||||
return testGroups;
|
||||
}
|
||||
|
||||
public Address getBreakOnDoneAddress() {
|
||||
return onDoneFunctionAddress;
|
||||
}
|
||||
|
||||
public Address getBreakOnPassAddress() {
|
||||
return onPassFunctionAddress;
|
||||
}
|
||||
|
||||
public Address getBreakOnErrorAddress() {
|
||||
return onErrorFunctionAddress;
|
||||
}
|
||||
|
||||
public Address getSprintf5Address() {
|
||||
return sprintfFunctionAddress;
|
||||
}
|
||||
|
||||
public Address getPrintfBufferAddress() {
|
||||
return sprintfBufferAddress;
|
||||
}
|
||||
|
||||
public PCodeTestResults getTestResults() {
|
||||
return testResults;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readControlBlock(boolean applyStruct)
|
||||
throws InvalidControlBlockException, CodeUnitInsertionException {
|
||||
|
||||
super.readControlBlock(applyStruct);
|
||||
|
||||
int ptrSzOffset = getStructureComponent(infoProgramStruct, "ptrSz");
|
||||
int byteOrderOffset = getStructureComponent(infoProgramStruct, "byteOrder");
|
||||
int onPassPtrOffset = getStructureComponent(infoProgramStruct, "onPass");
|
||||
int onErrorPtrOffset = getStructureComponent(infoProgramStruct, "onError");
|
||||
int onDonePtrOffset = getStructureComponent(infoProgramStruct, "onDone");
|
||||
|
||||
int sprintfPtrOffset = getStructureComponent(infoProgramStruct, "sprintf5");
|
||||
int sprintfBufferPtrOffset = getStructureComponent(infoProgramStruct, "sprintf5buffer");
|
||||
|
||||
if (applyStruct) {
|
||||
forceCodePointer(infoStructAddr.add(onPassPtrOffset));
|
||||
forceCodePointer(infoStructAddr.add(onErrorPtrOffset));
|
||||
forceCodePointer(infoStructAddr.add(onDonePtrOffset));
|
||||
forceCodePointer(infoStructAddr.add(sprintfBufferPtrOffset));
|
||||
}
|
||||
|
||||
DumbMemBufferImpl memBuffer = new DumbMemBufferImpl(program.getMemory(), infoStructAddr);
|
||||
try {
|
||||
|
||||
// Check byte-order
|
||||
int byteOrder = memBuffer.getInt(byteOrderOffset);
|
||||
if (byteOrder != 0x1020304) {
|
||||
throw new InvalidControlBlockException(
|
||||
"TestInfo @ " + infoStructAddr.toString(true) +
|
||||
" has invalid byteOrder - language endianess may be incorrect (" +
|
||||
Integer.toHexString(byteOrder) + ")");
|
||||
}
|
||||
|
||||
// Check pointer size
|
||||
// Must adjust size recorded by compiler
|
||||
int ptrSize = memBuffer.getInt(ptrSzOffset);
|
||||
DataOrganization dataOrganization = program.getDataTypeManager().getDataOrganization();
|
||||
ptrSize *= dataOrganization.getCharSize();
|
||||
if (ptrSize < 2 || ptrSize > 8) {
|
||||
throw new InvalidControlBlockException("TestInfo @ " +
|
||||
infoStructAddr.toString(true) + " has unsupported pointer size: " + ptrSize);
|
||||
}
|
||||
if (ptrSize != pointerSize) {
|
||||
String id =
|
||||
program.getLanguageID() + ":" + program.getCompilerSpec().getCompilerSpecID();
|
||||
Msg.warn(this, "TestInfo @ " + infoStructAddr.toString(true) + " ptrSz=" + ptrSize +
|
||||
" differs from data-organization size of " + pointerSize + " (" + id + ")");
|
||||
}
|
||||
|
||||
// get onPass function pointer
|
||||
onPassFunctionAddress = readCodePointer(memBuffer, onPassPtrOffset, applyStruct);
|
||||
|
||||
// get onError function pointer
|
||||
onErrorFunctionAddress = readCodePointer(memBuffer, onErrorPtrOffset, applyStruct);
|
||||
|
||||
// get onDone function pointer
|
||||
onDoneFunctionAddress = readCodePointer(memBuffer, onDonePtrOffset, applyStruct);
|
||||
|
||||
// get sprintf function pointer
|
||||
sprintfFunctionAddress = readCodePointer(memBuffer, sprintfPtrOffset, applyStruct);
|
||||
|
||||
// get sprintf buffer pointer
|
||||
sprintfBufferAddress = readCodePointer(memBuffer, sprintfBufferPtrOffset, applyStruct);
|
||||
|
||||
}
|
||||
catch (MemoryAccessException e) {
|
||||
throw new InvalidControlBlockException("TestInfo program read error", e);
|
||||
}
|
||||
|
||||
// Find all test groups by locating corresponding TestInfo structure
|
||||
findTestGroups(applyStruct);
|
||||
|
||||
}
|
||||
|
||||
private void findTestGroups(boolean applyStruct)
|
||||
throws InvalidControlBlockException, CodeUnitInsertionException {
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
|
||||
byte[] groupStructMagicBytes =
|
||||
getCharArrayBytes(program, PCodeTestGroupControlBlock.GROUP_CONTROL_BLOCK_MAGIC);
|
||||
|
||||
testGroups = new ArrayList<>();
|
||||
|
||||
AddressSet set = new AddressSet(restrictedSet);
|
||||
while (true) {
|
||||
|
||||
Address startOfControlBlock = findBytes(memory, set, groupStructMagicBytes);
|
||||
if (startOfControlBlock == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
PCodeTestGroupControlBlock controlBlock = new PCodeTestGroupControlBlock(program,
|
||||
startOfControlBlock, groupInfoStruct, applyStruct, this);
|
||||
PCodeTestGroup testGroup = new PCodeTestGroup(controlBlock);
|
||||
testGroups.add(testGroup);
|
||||
|
||||
// Remove previously searched addresses from search address set
|
||||
Address endAddr = startOfControlBlock.add(groupInfoStruct.getLength()).previous();
|
||||
AddressRange nextRange = set.getFirstRange();
|
||||
while (nextRange != null && !nextRange.contains(endAddr)) {
|
||||
set.delete(nextRange);
|
||||
nextRange = set.getFirstRange();
|
||||
}
|
||||
if (set.contains(endAddr)) {
|
||||
set = set.subtract(new AddressSet(set.getMinAddress(),
|
||||
startOfControlBlock.add(groupInfoStruct.getLength()).previous()));
|
||||
}
|
||||
}
|
||||
|
||||
if (testGroups.size() == 0) {
|
||||
throw new InvalidControlBlockException(
|
||||
"P-Code test binary does not define any test groups");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Diable sprintf use within P-Code test emulation.
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @param enable sprintf enablement
|
||||
*/
|
||||
void setSprintfEnabled(EmulatorTestRunner emuTestRunner, boolean enable) {
|
||||
Address addr =
|
||||
getMirroredDataAddress(emuTestRunner, infoStructAddr.add(sprintfEnableOffset));
|
||||
emuWrite(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'numpass' field value from emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @return 'numpass' field value
|
||||
*/
|
||||
int getNumberPassed(EmulatorTestRunner emuTestRunner) {
|
||||
Address addr = getMirroredDataAddress(emuTestRunner, infoStructAddr.add(numPassOffset));
|
||||
return (int) emuRead(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 'numpass' field value within emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @param value field value
|
||||
*/
|
||||
void setNumberPassed(EmulatorTestRunner emuTestRunner, int value) {
|
||||
Address addr = getMirroredDataAddress(emuTestRunner, infoStructAddr.add(numPassOffset));
|
||||
emuWrite(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'numfail' field value from emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @return 'numfail' field value
|
||||
*/
|
||||
int getNumberFailed(EmulatorTestRunner emuTestRunner) {
|
||||
Address addr = getMirroredDataAddress(emuTestRunner, infoStructAddr.add(numFailOffset));
|
||||
return (int) emuRead(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set 'numfail' field value within emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @param value field value
|
||||
*/
|
||||
void setNumberFailed(EmulatorTestRunner emuTestRunner, int value) {
|
||||
Address addr = getMirroredDataAddress(emuTestRunner, infoStructAddr.add(numFailOffset));
|
||||
emuWrite(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'lastTestPos' field value from emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @return 'lastTestPos' field value
|
||||
*/
|
||||
int getLastTestIndex(EmulatorTestRunner emuTestRunner) {
|
||||
Address addr = getMirroredDataAddress(emuTestRunner, infoStructAddr.add(lastTestPosOffset));
|
||||
return (int) emuRead(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'lastErrorLine' field value from emulation memory state
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @return 'lastErrorLine' field value
|
||||
*/
|
||||
int getLastErrorLine(EmulatorTestRunner emuTestRunner) {
|
||||
Address addr =
|
||||
getMirroredDataAddress(emuTestRunner, infoStructAddr.add(lastErrorLineOffset));
|
||||
return (int) emuRead(emuTestRunner.getEmulatorHelper(), addr, SIZEOF_U4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 'lastErrorFile' string value from emulation memory state. Must follow string
|
||||
* pointer contained within lastErrorFile field.
|
||||
* @param emuTestRunner emulator test runner
|
||||
* @return 'lastErrorLine' field value
|
||||
*/
|
||||
String getLastErrorFile(EmulatorTestRunner emuTestRunner) {
|
||||
Address addr =
|
||||
getMirroredDataAddress(emuTestRunner, infoStructAddr.add(lastErrorFileOffset));
|
||||
long fileNameOffset = emuRead(emuTestRunner.getEmulatorHelper(), addr, pointerSize);
|
||||
addr = addr.getNewAddress(fileNameOffset, true);
|
||||
addr = getMirroredDataAddress(emuTestRunner, addr);
|
||||
return emuReadString(emuTestRunner.getEmulatorHelper(), addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the last test function to be run
|
||||
* @param emuTestRunner
|
||||
* @return last test function name
|
||||
*/
|
||||
String getLastFunctionName(EmulatorTestRunner emuTestRunner, TestLogger logger,
|
||||
PCodeTestGroup activeGroup) {
|
||||
Address ptrStorageAddr = infoStructAddr.add(lastFuncOffset);
|
||||
Address ptrAddr = getMirroredDataAddress(emuTestRunner, ptrStorageAddr);
|
||||
long funcNameOffset = emuRead(emuTestRunner.getEmulatorHelper(), ptrAddr, pointerSize);
|
||||
Address strAddr = ptrAddr.getNewAddress(funcNameOffset, true);
|
||||
strAddr = getMirroredDataAddress(emuTestRunner, strAddr);
|
||||
String fnName = emuReadString(emuTestRunner.getEmulatorHelper(), strAddr);
|
||||
if ("none".equals(fnName)) {
|
||||
if (logger != null) {
|
||||
logger.log(activeGroup, "ERROR last executed function name pointer stored at " +
|
||||
ptrStorageAddr + " has not been set (reported as <NONE>)");
|
||||
}
|
||||
return INITIAL_FUNCTION_NAME;
|
||||
}
|
||||
String altName = null;
|
||||
if (!fnName.endsWith(PCodeTestGroupControlBlock.TEST_GROUP_FUNCTION_SUFFIX)) {
|
||||
altName = fnName + PCodeTestGroupControlBlock.TEST_GROUP_FUNCTION_SUFFIX;
|
||||
}
|
||||
if (activeGroup != null) {
|
||||
if (activeGroup.controlBlock.getFunctionInfo(fnName) != null) {
|
||||
return fnName;
|
||||
}
|
||||
if (altName != null && activeGroup.controlBlock.getFunctionInfo(altName) != null) {
|
||||
return fnName;
|
||||
}
|
||||
}
|
||||
if (logger != null) {
|
||||
logger.log(activeGroup,
|
||||
"ERROR last executed function name pointer stored at " + ptrStorageAddr +
|
||||
" was improperly set (reported as <UNKNOWN>, pointer=" + strAddr + ")");
|
||||
}
|
||||
return UNKNOWN_FUNCTION_NAME;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.test.processors.support;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class PCodeTestFile {
|
||||
|
||||
public final File file;
|
||||
public final String fileReferencePath;
|
||||
|
||||
public PCodeTestFile(File f, String fileReferencePath) {
|
||||
this.file = f;
|
||||
this.fileReferencePath = fileReferencePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fileReferencePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((file == null) ? 0 : file.hashCode());
|
||||
result = prime * result + ((fileReferencePath == null) ? 0 : fileReferencePath.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
PCodeTestFile other = (PCodeTestFile) obj;
|
||||
if (file == null) {
|
||||
if (other.file != null)
|
||||
return false;
|
||||
}
|
||||
else if (!file.equals(other.file))
|
||||
return false;
|
||||
if (fileReferencePath == null) {
|
||||
if (other.fileReferencePath != null)
|
||||
return false;
|
||||
}
|
||||
else if (!fileReferencePath.equals(other.fileReferencePath))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user