Skip to content
This repository has been archived by the owner on Dec 18, 2022. It is now read-only.

Commit

Permalink
Release first version
Browse files Browse the repository at this point in the history
  • Loading branch information
0xBEEEF committed Apr 7, 2021
1 parent f7c638a commit 14381dc
Show file tree
Hide file tree
Showing 12 changed files with 1,160 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.obj
*.lib
*.exe
*.elf
*.lb1
*.ERR
*.err
*.mk
*.mk1
*.lk1
*.map
*.sym
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# GhiOWat
Contains tools to make working with the Open Watcom compiler in Ghidra easier

# About
In the 90s, the Watcom compiler was a quasi-industry standard. It was used for both ordinary applications and games. Because of this fact there is still a lot of old software written with it. So far the support in Ghidra for the Open Watcom compiler is rather poor. This is why this repository was originally created, with the idea to support the standard calling conventions of this old compiler.

So far only the x86 calling conventions are supported.

Please note: All specifications refer purely to the Open Watcom compiler. It is possible that it also works with older versions, which exist before the open source release. However, this is not guaranteed. Just try it out, maybe it will work.

# License
Licensed under the GPL-3.0 License.
Empty file added src/Module.manifest
Empty file.
185 changes: 185 additions & 0 deletions src/data/languages/x86openwatcom.cspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="8" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<wchar_size value="2" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="4" />
<long_long_size value="8" />
<float_size value="4" />
<double_size value="8" />
<long_double_size value="12" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="4" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
</global>
<stackpointer register="ESP" space="ram"/>
<returnaddress>
<varnode space="stack" offset="0" size="4"/>
</returnaddress>
<default_proto>
<prototype name="__watcallRegister" extrapop="unknown" stackshift="4">
<input>
<pentry minsize="1" maxsize="4">
<register name="EAX"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="EDX"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="EBX"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="ECX"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="4" space="stack"/>
</pentry>
</input>
<output killedbycall="true">
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
<register name="ST0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="EAX"/>
</pentry>
</output>
<killedbycall>
<register name="EAX"/>
<register name="ST0"/>
</killedbycall>
<unaffected>
<register name="EDI"/>
<register name="ESP"/>
<register name="EBP"/>
<register name="ESI"/>
<register name="ECX"/>
<register name="EBX"/>
<register name="EDX"/>
</unaffected>
</prototype>
</default_proto>
<prototype name="__watcallStack" extrapop="unknown" stackshift="4">
<input>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="4" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
<register name="ST0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="EAX"/>
</pentry>
</output>
<unaffected>
<varnode space="ram" offset="0" size="4"/>
<register name="ESP"/>
<register name="EBP"/>
<register name="ESI"/>
<register name="EDI"/>
<register name="EBX"/>
<register name="DF"/>
</unaffected>
<killedbycall>
<register name="ECX"/>
<register name="EDX"/>
<register name="EAX"/>
</killedbycall>
</prototype>
<prototype name="__stdcall" extrapop="unknown" stackshift="4">
<input>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="4" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
<register name="ST0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="EAX"/>
</pentry>
</output>
<unaffected>
<varnode space="ram" offset="0" size="4"/>
<register name="ESP"/>
<register name="EBP"/>
<register name="ESI"/>
<register name="EDI"/>
<register name="EBX"/>
<register name="DF"/>
</unaffected>
<killedbycall>
<register name="ECX"/>
<register name="EDX"/>
<register name="EAX"/>
</killedbycall>
</prototype>
<prototype name="__cdecl" extrapop="4" stackshift="4">
<input>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="4" space="stack"/>
</pentry>
</input>
<output killedbycall="true">
<pentry minsize="1" maxsize="4">
<register name="EAX"/>
</pentry>
</output>
<unaffected>
<varnode space="ram" offset="0" size="4"/>
<register name="ESP"/>
<register name="EBP"/>
<register name="ESI"/>
<register name="EDI"/>
<register name="EBX"/>
<register name="DF"/>
</unaffected>
<killedbycall>
<register name="ECX"/>
<register name="EDX"/>
<register name="EAX"/>
</killedbycall>
</prototype>
<prototype name="__syscall" extrapop="4" stackshift="4">
<input>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="4" space="stack"/>
</pentry>
</input>
<output killedbycall="true">
<pentry minsize="4" maxsize="10" metatype="float" extension="float">
<register name="ST0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="EAX"/>
</pentry>
</output>
<unaffected>
<register name="EBX"/>
<register name="EBP"/>
<register name="EDI"/>
<register name="ESI"/>
<register name="ESP"/>
<register name="DF"/>
</unaffected>
<killedbycall>
<register name="EAX"/>
<register name="ECX"/>
<register name="EDX"/>
</killedbycall>
</prototype>
</compiler_spec>
7 changes: 7 additions & 0 deletions src/data/languages/x86openwatcom.ldefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="x86" endian="little" size="32" variant="default" version="1.0" slafile="x86.sla" processorspec="x86.pspec" manualindexfile="../manuals/x86.idx" id="x86:LE:32:openwatcom">
<description>Intel/AMD 32-bit x86</description>
<compiler name="Open Watcom C++" spec="x86openwatcom.cspec" id="openwatcomcpp"/>
</language>
</language_definitions>
7 changes: 7 additions & 0 deletions src/data/patterns/patternconstraints.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<patternconstraints>
<language id="x86:*:32:*">
<compiler id="openwatcomcpp">
<patternfile>x86openwatcomcpp_patterns.xml</patternfile>
</compiler>
</language>
</patternconstraints>
2 changes: 2 additions & 0 deletions src/data/patterns/x86openwatcomcpp_patterns.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<patternlist>
</patternlist>
4 changes: 4 additions & 0 deletions src/extension.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name=GhiOWat
description=Allows to simplify the handling of the Open Watcom compiler
createdOn=
version=9.2.2
133 changes: 133 additions & 0 deletions test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#include <stdio.h>
#include <stdlib.h>

typedef struct teststruct
{
int a;
int b;
float f;
} TestStruct;


int __watcall registerCallingConvention(int a, int b, int c, int d, int e, int f, int g);
int __watcall stackCallingConvention(int a, int b, int c, ...);
TestStruct * __watcall registerCallingConvention2(int a, int b, char * name, float f);

int __syscall sysCallConvention(int a, int b, int c , int d, int e, int f, int g);
int __stdcall standardCallConvention(int a, int b, int c, int d, int e, int f, int g, int h, int i);
int __pascal pascalCallConvention(int a, int b, int c, int d, int e);
int __cdecl cdeclCallConvention(int a, int b, int c, int d, int e, int f, int g, int h, int i);

void __watcall testStruct1(int a, int b, float f, TestStruct * str);
void __syscall testStruct2(int a, int b, float f, TestStruct * str);
void __stdcall testStruct3(int a, int b, float f, TestStruct * str);
void __pascal testStruct4(int a, int b, float f, TestStruct * str);
void __cdecl testStruct5(int a, int b, float f, TestStruct * str);
void __watcall PrintStruct(TestStruct * str);

void main( )
{
TestStruct * t;
printf("MainFunction");
registerCallingConvention(1,2,3,4,5,6,7);
stackCallingConvention(1,2,3,4,5,6,7,8,9,10);
t = registerCallingConvention2(10,20,"Test",1.23456);
sysCallConvention(10,20,30,40,50,60,70);
standardCallConvention(5,10,15,20,25,30,35,40,45);
pascalCallConvention(20,40,60,80,100);
cdeclCallConvention(-10, -15, -20, -25, -30, -35, -40, -45, -50);
testStruct1(10,20,1.2345,t);
PrintStruct(t);
testStruct2(30,40,2.3456,t);
PrintStruct(t);
testStruct3(50,60,3.4567,t);
PrintStruct(t);
testStruct4(70,80,4.5678,t);
PrintStruct(t);
testStruct5(90,100,5.6789,t);
PrintStruct(t);
}

void __watcall PrintStruct(TestStruct * str)
{
printf("%d %d %f \r\n",str->a, str->b, str->f);
}

int __watcall registerCallingConvention(int a, int b, int c, int d, int e, int f, int g)
{
return a + b + c + d + e + f + g;
}

int __watcall stackCallingConvention(int a, int b, int c, ...)
{
return 0;
}

TestStruct * __watcall registerCallingConvention2(int a, int b, char * name, float f)
{
TestStruct* t = malloc(sizeof(TestStruct));
t->a = a;
t->b = b;
t->f = f;
return t;
}

int __syscall sysCallConvention(int a, int b, int c , int d, int e, int f, int g)
{
return g + f + e + d + c + b + a;
}

int __stdcall standardCallConvention(int a, int b, int c, int d, int e, int f, int g, int h, int i)
{
int test;
int test2;

test = a + c + e + g;
test2 = b + d + f + h;

return test * test2;
}

int __pascal pascalCallConvention(int a, int b, int c, int d, int e)
{
return a + c + e;
}

int __cdecl cdeclCallConvention(int a, int b, int c, int d, int e, int f, int g, int h, int i)
{
return a + c + e + f + h;
}

void __watcall testStruct1(int a, int b, float f, TestStruct * str)
{
str->a = a;
str->b = b;
str->f = f;
}

void __syscall testStruct2(int a, int b, float f, TestStruct * str)
{
str->a = a;
str->b = b;
str->f = f;
}

void __stdcall testStruct3(int a, int b, float f, TestStruct * str)
{
str->a = a;
str->b = b;
str->f = f;
}

void __pascal testStruct4(int a, int b, float f, TestStruct * str)
{
str->a = a;
str->b = b;
str->f = f;
}
void __cdecl testStruct5(int a, int b, float f, TestStruct * str)
{
str->a = a;
str->b = b;
str->f = f;
}
Loading

0 comments on commit 14381dc

Please sign in to comment.