Merge remote-tracking branch 'origin/ghidra1_Emulator'

Conflicts:
	gradle/root/eclipse.gradle
This commit is contained in:
ghidra1 2019-07-12 16:14:17 -04:00
commit e0e2c58eb7
257 changed files with 32702 additions and 232 deletions

6
.gitignore vendored
View File

@ -63,3 +63,9 @@ Release
.project .project
.classpath .classpath
.settings/ .settings/
# Ignore XTEXT generated dirs/files
*/*/*/*/xtend-gen
*/*/*/*/src-gen
*/*/*/*/model/generated
*/*/*/*/test-bin

View File

@ -1,3 +1,5 @@
apply from: file("../gpl.gradle").getCanonicalPath()
if (findProject(':Generic') != null) { if (findProject(':Generic') != null) {
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle" apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"
apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle" apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle"

View File

@ -4,3 +4,4 @@
Module.manifest||Public Domain||||END| Module.manifest||Public Domain||||END|
build.gradle||Public Domain||||END| build.gradle||Public Domain||||END|
data/cabextract-1.6.tar.gz||GPL 3||||END| data/cabextract-1.6.tar.gz||GPL 3||||END|
settings.gradle||Public Domain||||END|

View File

View File

@ -1,13 +1,13 @@
apply from: file("../gpl.gradle").getCanonicalPath()
if (findProject(':Generic') != null) { if (findProject(':Generic') != null) {
apply from: "$rootProject.projectDir/gradle/javaProject.gradle" apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle" apply from: "$rootProject.projectDir/gradle/distributableGPLModule.gradle"
rootProject.assembleDistribution { rootProject.assembleDistribution {
doLast { doLast {
// eliminate standard module lib directory // eliminate standard module lib directory
def assemblePath = destinationDir.path + "/" + getZipPath(this.project) def assemblePath = destinationDir.path + "/" + getZipPath(this.project)
println "DELETE: ${assemblePath}/lib"
delete assemblePath + "/lib" delete assemblePath + "/lib"
} }
} }
@ -28,6 +28,7 @@ eclipse.project.name = 'GPL DMG'
* *
*********************************************************************************/ *********************************************************************************/
sourceSets { sourceSets {
dmg { dmg {
java { java {
srcDir 'src/dmg/java' srcDir 'src/dmg/java'

View File

@ -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_i386.dll||GPL 3||||END|
data/os/win64/llio_ia64.dll||GPL 3||||END| data/os/win64/llio_ia64.dll||GPL 3||||END|
data/server_memory.cfg||Public Domain||||END| data/server_memory.cfg||Public Domain||||END|
settings.gradle||Public Domain||||END|

0
GPL/DMG/settings.gradle Normal file
View File

View File

@ -1,3 +1,4 @@
apply from: file("../gpl.gradle").getCanonicalPath()
if (findProject(':Generic') != null) { if (findProject(':Generic') != null) {
apply from: "$rootProject.projectDir/gradle/nativeProject.gradle" apply from: "$rootProject.projectDir/gradle/nativeProject.gradle"

View File

@ -6,4 +6,5 @@
##MODULE IP: Public Domain ##MODULE IP: Public Domain
Module.manifest||Public Domain||||END| Module.manifest||Public Domain||||END|
build.gradle||Public Domain||||END| build.gradle||Public Domain||||END|
settings.gradle||Public Domain||||END|
src/demangler_gnu/README.txt||Public Domain||||END| src/demangler_gnu/README.txt||Public Domain||||END|

View File

View File

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

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

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

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

View File

@ -0,0 +1,7 @@
.text
__start:
lw $t0, #4
li $t1, #0
add $t2, $t0, $t1
done

Binary file not shown.

Binary file not shown.

View 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

View File

View 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;
}

View 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

View File

@ -1,5 +1,4 @@
##VERSION: 2.0 ##VERSION: 2.0
##MODULE IP: Public Domain ##MODULE IP: Public Domain
build.gradle||Public Domain||||END| gpl.gradle||Public Domain||||END|
nativeBuildProperties.gradle||Public Domain||||END| nativeBuildProperties.gradle||Public Domain||||END|
settings.gradle||Public Domain||||END|

View File

@ -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"]) project.ext.set("OS_NAMES", ["osx64", "win32", "win64", "linux64"])
/********************************************************************************* /*********************************************************************************
* Returns the local platform name. * Returns the local platform name.
*********************************************************************************/ *********************************************************************************/
String getCurrentPlatformName() { ext.getCurrentPlatformName = {
String osName = System.getProperty("os.name") String osName = System.getProperty("os.name")
String archName = System.getProperty("os.arch") 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 * Helper method that returns a file that is the same relative location in the bin repo
* as the given project is in its repo. * as the given project is in its repo.
******************************************************************************************/ ******************************************************************************************/
File getProjectLocationInBinRepo(Project p) { ext.getProjectLocationInBinRepo = {
String relativePath = getGhidraRelativePath(p) String relativePath = getGhidraRelativePath(this.project)
println("RELATIVE: $relativePath")
File binRepoRootProject = new File("${BIN_REPO}") File binRepoRootProject = new File("${BIN_REPO}")
if (!binRepoRootProject.isDirectory()) {
throw new GradleException("Task requires Ghidra source and ghidra.bin")
}
return new File(binRepoRootProject, relativePath) return new File(binRepoRootProject, relativePath)
} }
/**************************************************************************************** /****************************************************************************************

View File

@ -1,4 +0,0 @@
include "DemanglerGnu"
include "DMG"
include "CabExtract"

View 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')
}

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

View File

@ -0,0 +1 @@
ExternalDisassembler

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

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

View File

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

View File

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

View File

@ -0,0 +1 @@
*.pyc

View 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

View 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()

View 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

View 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() { }

View 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()
{
}

View 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;
}

View 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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View 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() { }

View 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) */

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

View 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

View 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 */

View 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

View 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'}

View 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,
})

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

View 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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -33,6 +33,7 @@ data/parserprofiles/linux_32.prf||GHIDRA||||END|
data/parserprofiles/linux_64.prf||GHIDRA||||END| data/parserprofiles/linux_64.prf||GHIDRA||||END|
data/parserprofiles/objc_mac_carbon.prf||GHIDRA||reviewed||END| data/parserprofiles/objc_mac_carbon.prf||GHIDRA||reviewed||END|
data/parserprofiles/vs12Local.prf||GHIDRA||||END| data/parserprofiles/vs12Local.prf||GHIDRA||||END|
data/pcodetest/EmuTesting.gdt||GHIDRA||||END|
data/stringngrams/StringModel.sng||GHIDRA||reviewed||END| data/stringngrams/StringModel.sng||GHIDRA||reviewed||END|
data/symbols/win32/kernel32.hints||GHIDRA||||END| data/symbols/win32/kernel32.hints||GHIDRA||||END|
data/symbols/win32/mfc100.exports||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.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_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/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/dirlist.txt||GHIDRA||reviewed||END|
src/test.slow/resources/filterTestDirList.txt||GHIDRA||||END| src/test.slow/resources/filterTestDirList.txt||GHIDRA||||END|
src/test.slow/resources/ghidra/app/plugin/core/datamgr/TestDataType.txt||GHIDRA||||END| src/test.slow/resources/ghidra/app/plugin/core/datamgr/TestDataType.txt||GHIDRA||||END|

Binary file not shown.

View File

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

View File

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

View File

@ -34,7 +34,7 @@ import ghidra.program.model.mem.Memory;
public class SearchBaseExtended extends GhidraScript { public class SearchBaseExtended extends GhidraScript {
//holds the mask and value for all the mnemonics, or commands like cmp, jmp, jnz etc //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 * 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. * operand. I set it up this was to conserve memory and allow for a dynamically growing collection.
*/ */
ArrayList<LinkedHashMap<Case, OperandCase>> ops = 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. //These control the detail at which a scan is performed.
//They determine how specific the instructions must match the currently selected ones //They determine how specific the instructions must match the currently selected ones
ArrayList<SLMaskControl> controlList = new ArrayList<SLMaskControl>(); ArrayList<SLMaskControl> controlList = new ArrayList<>();
@Override @Override
public void run() throws Exception { 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) { 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)); controlList.add(new SLMaskControl(mneonics, op1, op2, constants));
loadSelectedInstructions(); loadSelectedInstructions();
executeSearch(); executeSearch();
@ -72,11 +72,11 @@ public class SearchBaseExtended extends GhidraScript {
} }
public void clearResults() { public void clearResults() {
db = new ArrayList<Case>(); db = new ArrayList<>();
} }
public void setState(SLMaskControl newState) { public void setState(SLMaskControl newState) {
controlList = new ArrayList<SLMaskControl>(); controlList = new ArrayList<>();
controlList.add(newState); controlList.add(newState);
} }
@ -137,7 +137,7 @@ public class SearchBaseExtended extends GhidraScript {
mnemonics.add(tCase); //adds the mnemonic mask and value to the arraylist 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. //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 //Iterates through all the operands for the currently selected instruction and stores them accordingly
for (int x = 1; x <= logger.getNumOperands(); x++) { for (int x = 1; x <= logger.getNumOperands(); x++) {
@ -156,7 +156,7 @@ public class SearchBaseExtended extends GhidraScript {
otCase.textRep = tempIns.getDefaultOperandRepresentation(x - 1); 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. //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; otCase.constant = true;
} }
@ -321,8 +321,8 @@ public class SearchBaseExtended extends GhidraScript {
ArrayList<LinkedHashMap<Case, OperandCase>> localOperands, ArrayList<LinkedHashMap<Case, OperandCase>> localOperands,
ArrayList<SLMaskControl> control) { ArrayList<SLMaskControl> control) {
ArrayList<byte[]> masks = new ArrayList<byte[]>(); ArrayList<byte[]> masks = new ArrayList<>();
ArrayList<byte[]> values = new ArrayList<byte[]>(); ArrayList<byte[]> values = new ArrayList<>();
//used for storing the byte stream currently being work on prior to being added to final data structure //used for storing the byte stream currently being work on prior to being added to final data structure
int totalLength = 0; int totalLength = 0;

View File

@ -770,7 +770,7 @@ public class TestEnv {
* Open a read-only test program from the test data directory. * Open a read-only test program from the test data directory.
* This program must be released prior to disposing this test environment. * This program must be released prior to disposing this test environment.
* NOTE: Some tests rely on this method returning null when file does * 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. * @param programName name of program database within the test data directory.
* @return program or null if program file not found * @return program or null if program file not found

View File

@ -57,7 +57,7 @@ public class TestProgramManager {
* Open a read-only test program from the test data directory. * Open a read-only test program from the test data directory.
* This program must be released prior to disposing this test environment. * This program must be released prior to disposing this test environment.
* NOTE: Some tests rely on this method returning null when file does * 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. * @param progName name of program database within the test data directory.
* @return program or null if program file not found * @return program or null if program file not found

View File

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

View File

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

View File

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

View File

@ -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] + ";\">&nbsp;");
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 = "&nbsp;";
}
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:&nbsp;" + 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>");
}
}

View File

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

View File

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