*** empty log message ***
This commit is contained in:
2
harbour/genbuild.bat
Normal file
2
harbour/genbuild.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
cd..
|
||||
pkzip -r -p harb21-2 -x*.exe -x*.bak -x*.sim -x*.out -xsave.bat -xlexyy.c -xy_tab.c -xy_tab.h -x*.obj -x*.lib -x*.zip
|
||||
@@ -1,5 +1,6 @@
|
||||
# makefile for Borland C/C++ 32 bits
|
||||
|
||||
.path.asm = source\compiler
|
||||
.path.c = source\compiler;source\vm;source\rtl;source\tools
|
||||
.path.h = include
|
||||
.path.l = source\compiler
|
||||
@@ -14,7 +15,8 @@ PROJECT: harbour.lib libs\b32\terminal.lib libs\win32\terminal.lib harbour.exe
|
||||
harbour.lib : arrays.obj classes.obj codebloc.obj dates.obj datesx.obj \
|
||||
debug.obj dynsym.obj environ.obj error.obj \
|
||||
errorapi.obj errorsys.obj extend.obj files.obj itemapi.obj math.obj \
|
||||
mathx.obj set.obj strings.obj stringsx.obj strcmp.obj tclass.obj transfrm.obj
|
||||
mathx.obj set.obj symbols.obj strings.obj stringsx.obj strcmp.obj \
|
||||
tclass.obj transfrm.obj
|
||||
|
||||
libs\b32\terminal.lib : console.obj
|
||||
|
||||
@@ -25,7 +27,9 @@ console.obj : console.c extend.h types.h
|
||||
tlib .\libs\b32\terminal.lib -+$@,,
|
||||
bcc32 -c -O2 -DWINDOWS -I.\include -o$@ source\rtl\console.c
|
||||
tlib .\libs\win32\terminal.lib -+$@,,
|
||||
|
||||
|
||||
symbols.obj : symbols.asm
|
||||
|
||||
arrays.obj : arrays.c extend.h types.h
|
||||
classes.obj : classes.c extend.h types.h
|
||||
codebloc.obj : codebloc.c extend.h types.h
|
||||
@@ -53,6 +57,10 @@ error.c : error.prg harbour.exe
|
||||
errorsys.c : errorsys.prg harbour.exe
|
||||
tclass.c : tclass.prg harbour.exe
|
||||
|
||||
.asm.obj:
|
||||
tasm $<, $@
|
||||
tlib .\libs\b32\harbour.lib -+$@,,
|
||||
|
||||
.prg.c:
|
||||
bin\harbour $< /n /osource\rtl
|
||||
|
||||
@@ -60,12 +68,12 @@ tclass.c : tclass.prg harbour.exe
|
||||
bcc32 -c -O2 -I.\include -o$@ $<
|
||||
tlib .\libs\b32\harbour.lib -+$@,,
|
||||
|
||||
harbour.exe : y_tab.c lexyy.c harbour.obj
|
||||
harbour.exe : y_tab.c lexyy.c genobj32.c compiler.h
|
||||
bcc32 -O2 -ebin\harbour.exe -Iinclude;source\compiler \
|
||||
source\compiler\y_tab.c source\compiler\lexyy.c \
|
||||
source\compiler\harbour.obj
|
||||
source\compiler\y_tab.c source\compiler\lexyy.c source\compiler\genobj32.c
|
||||
del y_tab.obj
|
||||
del lexyy.obj
|
||||
del compiler.obj
|
||||
|
||||
y_tab.c : harbour.y
|
||||
bison -d -v -y -osource\compiler\y_tab.c source\compiler\harbour.y
|
||||
|
||||
692
harbour/source/compiler/genobj32.c
Normal file
692
harbour/source/compiler/genobj32.c
Normal file
@@ -0,0 +1,692 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include <compiler.h>
|
||||
#include <extend.h>
|
||||
#include <pcode.h>
|
||||
|
||||
static void CompiledFileName( FILE * hObjFile, char * szFileName );
|
||||
static void CompilerVersion( FILE * hObjFile, char * szVersion );
|
||||
static void LocalNames( FILE * hObjFile, char * szNames[] );
|
||||
static void ExternalNames( FILE * hObjFile, char * szNames[] );
|
||||
static void Fixup( FILE * hObjFile, BYTE bType, WORD wOffset, BYTE bFlags, BYTE bSymbol );
|
||||
static void DefineSegment( FILE * hObjFile, BYTE bName, BYTE bClass, WORD wLen );
|
||||
static void PubDef( FILE * hObjFile, char * szName, WORD wSegment, WORD wOffset );
|
||||
static void EnumeratedData( FILE * hObjFile, BYTE bSegment, BYTE * pData, WORD wLen, WORD wOffset );
|
||||
static void GroupDef( FILE * hObjFile, BYTE bName, BYTE * aSegs );
|
||||
static void End( FILE * hObjFile );
|
||||
|
||||
static void CodeSegment( FILE * hObjFile, BYTE * prgCode, ULONG ulPrgLen,
|
||||
WORD wFunctions );
|
||||
static void DataSegment( FILE * hObjFile, BYTE * symbol, WORD wSymLen,
|
||||
WORD wSymbols, ULONG ulTotalSize );
|
||||
|
||||
static void GenerateLocalNames( FILE * hObjFile );
|
||||
static void GenerateExternals( FILE * hObjFile );
|
||||
static void GenerateCodeSegment( FILE * hObjFile );
|
||||
static void GenerateDataSegment( FILE * hObjFile );
|
||||
static void GenerateSymbolsSegment( FILE * hObjFile );
|
||||
|
||||
extern FUNCTIONS functions, funcalls;
|
||||
extern SYMBOLS symbols;
|
||||
extern int _iQuiet, _iStartProc;
|
||||
|
||||
static BYTE prgFunction[] = { 0x68, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
|
||||
0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC4, 0x08, 0xC3 };
|
||||
|
||||
static char * * externNames = 0;
|
||||
WORD wExternals = 1; /* _VirtualMachine is always added */
|
||||
|
||||
void GenObj32( char * szObjFileName, char * szFileName )
|
||||
{
|
||||
FILE * hObjFile; /* file handle for OBJ output */
|
||||
|
||||
if( ! ( hObjFile = fopen( szObjFileName, "wb" ) ) )
|
||||
{
|
||||
printf( "Error opening file %s\n", szObjFileName );
|
||||
return;
|
||||
}
|
||||
|
||||
if( ! _iQuiet )
|
||||
printf( "\ngenerating Windows/Dos OBJ 32 bits..." );
|
||||
|
||||
CompiledFileName( hObjFile, szFileName );
|
||||
CompilerVersion( hObjFile, "Harbour" );
|
||||
GenerateLocalNames( hObjFile );
|
||||
GenerateExternals( hObjFile );
|
||||
GenerateCodeSegment( hObjFile );
|
||||
GenerateDataSegment( hObjFile );
|
||||
GenerateSymbolsSegment( hObjFile );
|
||||
End( hObjFile );
|
||||
|
||||
fclose( hObjFile );
|
||||
|
||||
if( ! _iQuiet )
|
||||
printf( "\n%s -> done!\n", szObjFileName );
|
||||
}
|
||||
|
||||
static ULONG GetSymbolsSize( void )
|
||||
{
|
||||
return ( symbols.iCount - ( _iStartProc ? 0: 1 ) ) * sizeof( SYMBOL );
|
||||
}
|
||||
|
||||
static PCOMSYMBOL GetFirstSymbol( void )
|
||||
{
|
||||
PCOMSYMBOL pSymbol = symbols.pFirst;
|
||||
|
||||
if( ! _iStartProc )
|
||||
pSymbol = pSymbol->pNext;
|
||||
|
||||
return pSymbol;
|
||||
}
|
||||
|
||||
static char * GetSymbolName( ULONG ulPos )
|
||||
{
|
||||
PCOMSYMBOL pSymbol = GetFirstSymbol();
|
||||
ULONG ul = 0;
|
||||
|
||||
while( pSymbol && ( ul++ < ulPos ) )
|
||||
pSymbol = pSymbol->pNext;
|
||||
|
||||
return pSymbol->szName;
|
||||
}
|
||||
|
||||
static ULONG GetPCodesSize( void )
|
||||
{
|
||||
ULONG ulTotal = 0;
|
||||
PFUNCTION pFunction = functions.pFirst;
|
||||
|
||||
if( ! _iStartProc )
|
||||
pFunction = pFunction->pNext;
|
||||
|
||||
while( pFunction )
|
||||
{
|
||||
ulTotal += pFunction->lPCodePos + 1; /* _ENDPROC !!! */
|
||||
pFunction = pFunction->pNext;
|
||||
}
|
||||
return ulTotal;
|
||||
}
|
||||
|
||||
ULONG GetSymbolsAmount( void )
|
||||
{
|
||||
PCOMSYMBOL pSymbol = GetFirstSymbol();
|
||||
ULONG ulAmount = 1;
|
||||
|
||||
while( pSymbol->pNext )
|
||||
{
|
||||
ulAmount++;
|
||||
pSymbol = pSymbol->pNext;
|
||||
}
|
||||
return ulAmount;
|
||||
}
|
||||
|
||||
BOOL IsExternal( ULONG ulSymbol )
|
||||
{
|
||||
PCOMSYMBOL pSymbol = GetFirstSymbol();
|
||||
ULONG ul = 0;
|
||||
|
||||
while( ul++ < ulSymbol )
|
||||
pSymbol = pSymbol->pNext;
|
||||
|
||||
return ! GetFunction( pSymbol->szName );
|
||||
}
|
||||
|
||||
WORD GetExternalPos( char * szExternal )
|
||||
{
|
||||
WORD w = 0;
|
||||
|
||||
while( w < wExternals )
|
||||
{
|
||||
if( ! strcmp( szExternal, externNames[ w ] ) )
|
||||
break;
|
||||
w++;
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static void GenerateLocalNames( FILE * hObjFile )
|
||||
{
|
||||
char * localNames[] = { "_TEXT", "CODE", "_DATA", "DATA",
|
||||
"HB_SYMBOLS", "HB_STARTSYMBOLS", "HB_ENDSYMBOLS", "SYMGROUP", 0 };
|
||||
|
||||
LocalNames( hObjFile, localNames );
|
||||
}
|
||||
|
||||
static void GenerateSymbolsSegment( FILE * hObjFile )
|
||||
{
|
||||
BYTE symbolsData[] = { 0, 0, 0, 0, 0, 0 };
|
||||
BYTE groupSegments[] = { 3, 4, 5, 0 }; /* segments order for HB_... */
|
||||
|
||||
DefineSegment( hObjFile, 7, 5, 0 ); /* 7 = HB_STARTSYMBOLS, 5 = DATA */
|
||||
DefineSegment( hObjFile, 6, /* "HB_SYMBOLS" position + 1 into localNames */
|
||||
5, /* "DATA" position + 1 into localNames */
|
||||
6 ); /* segment length */
|
||||
DefineSegment( hObjFile, 8, 5, 0 ); /* 8 = HB_ENDSYMBOLS, 5 = DATA */
|
||||
|
||||
GroupDef( hObjFile, 8, groupSegments ); /* 8 = "SYMGROUP" localNames position */
|
||||
|
||||
* ( WORD * ) symbolsData = GetSymbolsAmount();
|
||||
|
||||
EnumeratedData( hObjFile, 4, symbolsData, sizeof( symbolsData ), 0 ); /* 4 = HB_SYMBOLS defined segment */
|
||||
|
||||
Fixup( hObjFile, 0xE4, 2, 0x54, 2 ); /* Data: symbols location */
|
||||
}
|
||||
|
||||
static void GenerateDataSegment( FILE * hObjFile )
|
||||
{
|
||||
SYMBOL symbol;
|
||||
ULONG ulSize = GetSymbolsSize();
|
||||
PCOMSYMBOL pSymbol = GetFirstSymbol();
|
||||
ULONG ulSymbols = GetSymbolsAmount(), ul;
|
||||
|
||||
while( pSymbol )
|
||||
{
|
||||
ulSize += strlen( pSymbol->szName ) + 1;
|
||||
pSymbol = pSymbol->pNext;
|
||||
}
|
||||
|
||||
ulSize += GetPCodesSize();
|
||||
|
||||
DefineSegment( hObjFile, 4, /* "_DATA" position + 1 into localNames */
|
||||
5, /* "DATA" position + 1 into localNames */
|
||||
ulSize ); /* segment length */
|
||||
|
||||
memset( &symbol, 0, sizeof( symbol ) );
|
||||
DataSegment( hObjFile, &symbol, sizeof( symbol ), GetSymbolsAmount(), ulSize );
|
||||
|
||||
pSymbol = GetFirstSymbol();
|
||||
for( ul = 0; ul < ulSymbols; ul++ )
|
||||
{
|
||||
Fixup( hObjFile, 0xE4, ( ul * sizeof( SYMBOL ) ), 0x54, 2 ); /* Data symbol name location */
|
||||
|
||||
if( IsExternal( ul ) )
|
||||
{
|
||||
if( ! ( pSymbol->cScope & FS_MESSAGE ) )
|
||||
Fixup( hObjFile, 0xE4, ( ul * sizeof( SYMBOL ) ) + 5, 0x56,
|
||||
GetExternalPos( GetSymbolName( ul ) ) + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if( ! ( pSymbol->cScope & FS_MESSAGE ) ) */
|
||||
Fixup( hObjFile, 0xE4, ( ul * sizeof( SYMBOL ) ) + 5, 0x54, 1 ); /* function address location */
|
||||
}
|
||||
pSymbol = pSymbol->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateCodeSegment( FILE * hObjFile )
|
||||
{
|
||||
WORD wFunctions = functions.iCount - ( _iStartProc ? 0: 1 );
|
||||
ULONG ulSize = wFunctions * sizeof( prgFunction );
|
||||
PFUNCTION pFunc = ( _iStartProc ? functions.pFirst: functions.pFirst->pNext );
|
||||
WORD w = 0;
|
||||
|
||||
DefineSegment( hObjFile, 2, /* "_TEXT" position + 1 into localNames */
|
||||
3, /* "CODE" position + 1 into localNames */
|
||||
ulSize ); /* segment length */
|
||||
|
||||
while( pFunc )
|
||||
{
|
||||
if( !( pFunc->cScope & ( FS_STATIC | FS_INIT | FS_EXIT ) ) )
|
||||
PubDef( hObjFile, pFunc->szName, 1, w * sizeof( prgFunction ) );
|
||||
w++;
|
||||
pFunc = pFunc->pNext;
|
||||
}
|
||||
|
||||
CodeSegment( hObjFile, prgFunction, sizeof( prgFunction ), wFunctions );
|
||||
|
||||
for( w = 0; w < wFunctions; w++ )
|
||||
{
|
||||
/* prgFunction fixups */
|
||||
Fixup( hObjFile, 0xE4, ( w * sizeof( prgFunction ) ) + 1,
|
||||
0x54, 2 ); /* Data: symbols location */
|
||||
|
||||
Fixup( hObjFile, 0xE4, ( w * sizeof( prgFunction ) ) + 6,
|
||||
0x54, 2 ); /* Data pcode location */
|
||||
|
||||
Fixup( hObjFile, 0xA4, ( w * sizeof( prgFunction ) ) + 11,
|
||||
0x56, 1 ); /* External: _VirtualMachine */
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateExternals( FILE * hObjFile )
|
||||
{
|
||||
WORD w;
|
||||
PFUNCTION pFunc, pFTemp;
|
||||
|
||||
/* calculate amount of externals */
|
||||
pFunc = funcalls.pFirst;
|
||||
while( pFunc )
|
||||
{
|
||||
if( ! ( pFTemp = GetFunction( pFunc->szName ) ) || pFTemp == functions.pFirst )
|
||||
wExternals++;
|
||||
pFunc = pFunc->pNext;
|
||||
}
|
||||
if( wExternals )
|
||||
{
|
||||
externNames = ( char * * ) OurMalloc( sizeof( char * ) * ( wExternals + 2 ) );
|
||||
w = 1;
|
||||
externNames[ 0 ] = "_VirtualMachine";
|
||||
|
||||
pFunc = funcalls.pFirst;
|
||||
while( pFunc )
|
||||
{
|
||||
if( ! ( pFTemp = GetFunction( pFunc->szName ) ) || pFTemp == functions.pFirst )
|
||||
externNames[ w++ ] = pFunc->szName;
|
||||
pFunc = pFunc->pNext;
|
||||
}
|
||||
externNames[ w ] = 0;
|
||||
ExternalNames( hObjFile, externNames );
|
||||
}
|
||||
}
|
||||
|
||||
static void putbyte( BYTE b, FILE * hObjFile )
|
||||
{
|
||||
fputc( b, hObjFile );
|
||||
}
|
||||
|
||||
void putword( WORD w, FILE * hObjFile )
|
||||
{
|
||||
putbyte( LOBYTE( w ), hObjFile );
|
||||
putbyte( HIBYTE( w ), hObjFile );
|
||||
}
|
||||
|
||||
static void CompiledFileName( FILE * hObjFile, char * szFileName )
|
||||
{
|
||||
WORD wLen = strlen( szFileName );
|
||||
BYTE bChk = 0; /* this is a checksum the linker will check to asure OBJ integrity */
|
||||
BYTE bChar;
|
||||
|
||||
putbyte( 0x80, hObjFile ); /* this tells the linker the kind of OBJ record this is */
|
||||
bChk += 0x80;
|
||||
|
||||
putbyte( 1 + 1 + wLen, hObjFile ); /* now it comes the total length of this OBJ record */
|
||||
bChk += ( 1 + 1 + wLen );
|
||||
putbyte( 0, hObjFile );
|
||||
|
||||
putbyte( wLen, hObjFile ); /* szFileName length */
|
||||
bChk += wLen;
|
||||
|
||||
while( bChar = * szFileName++ )
|
||||
{
|
||||
putbyte( bChar, hObjFile ); /* each of the szFileName characters */
|
||||
bChk += bChar;
|
||||
}
|
||||
|
||||
putbyte( 256 - bChk, hObjFile ); /* a checksum that will be recalculated by the linker */
|
||||
}
|
||||
|
||||
static void CompilerVersion( FILE * hObjFile, char * szVersion )
|
||||
{
|
||||
WORD wLen = strlen( szVersion );
|
||||
BYTE bChk = 0; /* this is a checksum the linker will check to asure OBJ integrity */
|
||||
BYTE bChar;
|
||||
|
||||
putbyte( 0x88, hObjFile ); /* this tells the linker the kind of OBJ record this is */
|
||||
bChk += 0x88;
|
||||
|
||||
putword( 3 + wLen, hObjFile ); /* now it comes the total length of this OBJ record */
|
||||
bChk += LOBYTE( 3 + wLen );
|
||||
bChk += HIBYTE( 3 + wLen );
|
||||
|
||||
putword( 0, hObjFile );
|
||||
|
||||
while( bChar = * szVersion++ )
|
||||
{
|
||||
putbyte( bChar, hObjFile ); /* each of the szFileName characters */
|
||||
bChk += bChar;
|
||||
}
|
||||
|
||||
putbyte( 256 - bChk, hObjFile ); /* a checksum that will be recalculated by the linker */
|
||||
}
|
||||
|
||||
static void LocalNames( FILE * hObjFile, char * szNames[] )
|
||||
{
|
||||
BYTE b = 0, c;
|
||||
WORD wTotalLen = 0;
|
||||
BYTE bChk = 0;
|
||||
BYTE bChar;
|
||||
|
||||
while( szNames[ b ] )
|
||||
wTotalLen += strlen( szNames[ b++ ] );
|
||||
wTotalLen += 2 + b;
|
||||
|
||||
putbyte( 0x96, hObjFile );
|
||||
bChk += 0x96;
|
||||
|
||||
putbyte( LOBYTE( wTotalLen ), hObjFile );
|
||||
bChk += LOBYTE( wTotalLen );
|
||||
putbyte( HIBYTE( wTotalLen ), hObjFile );
|
||||
bChk += HIBYTE( wTotalLen );
|
||||
|
||||
putbyte( 0, hObjFile );
|
||||
|
||||
b = 0;
|
||||
while( szNames[ b ] )
|
||||
{
|
||||
putbyte( strlen( szNames[ b ] ), hObjFile );
|
||||
bChk += strlen( szNames[ b ] );
|
||||
|
||||
c = 0;
|
||||
while( szNames[ b ][ c ] )
|
||||
{
|
||||
putbyte( szNames[ b ][ c ], hObjFile );
|
||||
bChk += szNames[ b ][ c++ ];
|
||||
}
|
||||
b++;
|
||||
}
|
||||
putbyte( 256 - bChk, hObjFile );
|
||||
}
|
||||
|
||||
static void ExternalNames( FILE * hObjFile, char * szNames[] )
|
||||
{
|
||||
BYTE b = 0, c;
|
||||
WORD wTotalLen = 0;
|
||||
BYTE bChk = 0;
|
||||
BYTE bChar;
|
||||
|
||||
while( szNames[ b ] )
|
||||
wTotalLen += strlen( szNames[ b++ ] ) + 1;
|
||||
wTotalLen += 2 + b - 1;
|
||||
|
||||
putbyte( 0x8C, hObjFile );
|
||||
bChk += 0x8C;
|
||||
|
||||
putword( wTotalLen, hObjFile );
|
||||
bChk += LOBYTE( wTotalLen );
|
||||
bChk += HIBYTE( wTotalLen );
|
||||
|
||||
b = 0;
|
||||
while( szNames[ b ] )
|
||||
{
|
||||
putbyte( strlen( szNames[ b ] ), hObjFile );
|
||||
bChk += strlen( szNames[ b ] );
|
||||
|
||||
c = 0;
|
||||
|
||||
while( szNames[ b ][ c ] )
|
||||
{
|
||||
putbyte( szNames[ b ][ c ], hObjFile );
|
||||
bChk += szNames[ b ][ c++ ];
|
||||
}
|
||||
putbyte( 0, hObjFile );
|
||||
b++;
|
||||
}
|
||||
putbyte( 256 - bChk, hObjFile );
|
||||
}
|
||||
|
||||
static void CodeSegment( FILE * hObjFile, BYTE * prgCode, ULONG ulPrgLen, WORD wFunctions )
|
||||
{
|
||||
BYTE bCheckSum = 0;
|
||||
WORD y;
|
||||
WORD wTotalLen = ( ulPrgLen * wFunctions ) + 4;
|
||||
ULONG ul;
|
||||
PFUNCTION pFunction = functions.pFirst;
|
||||
ULONG ulPCodeOffset = ( symbols.iCount - ( _iStartProc ? 0: 1 ) ) * sizeof( SYMBOL );
|
||||
|
||||
if( ! _iStartProc )
|
||||
pFunction = pFunction->pNext;
|
||||
|
||||
putbyte( 0xA0, hObjFile );
|
||||
bCheckSum += 0xA0;
|
||||
|
||||
putword( wTotalLen, hObjFile );
|
||||
bCheckSum += LOBYTE( wTotalLen );
|
||||
bCheckSum += HIBYTE( wTotalLen );
|
||||
|
||||
putbyte( 1, hObjFile ); /* 1 = _TEXT segment */
|
||||
bCheckSum += 1;
|
||||
|
||||
putword( 0, hObjFile ); /* 0 = offset */
|
||||
|
||||
for( y = 0; y < wFunctions; y++ )
|
||||
{
|
||||
* ( ULONG * ) &prgCode[ 6 ] = ulPCodeOffset; /* function pcode offset */
|
||||
for( ul = 0; ul < ulPrgLen; ul++ )
|
||||
{
|
||||
putbyte( * ( prgCode + ul ), hObjFile );
|
||||
bCheckSum += * ( prgCode + ul );
|
||||
}
|
||||
ulPCodeOffset += pFunction->lPCodePos + 1; /* _ENDPROC !!! */
|
||||
pFunction = pFunction->pNext;
|
||||
}
|
||||
|
||||
putbyte( 256 - bCheckSum, hObjFile );
|
||||
}
|
||||
|
||||
static void DataSegment( FILE * hObjFile, BYTE * symbol, WORD wSymLen, WORD wSymbols,
|
||||
ULONG ulSize )
|
||||
{
|
||||
BYTE bCheckSum = 0;
|
||||
WORD w, y;
|
||||
WORD wTotalLen = 4 + ulSize;
|
||||
PCOMSYMBOL pSymbol = GetFirstSymbol();
|
||||
PFUNCTION pFunction = functions.pFirst;
|
||||
ULONG ulSymbolNameOffset = GetSymbolsSize() + GetPCodesSize();
|
||||
ULONG ulFunctionOffset;
|
||||
|
||||
if( ! _iStartProc )
|
||||
pFunction = pFunction->pNext;
|
||||
|
||||
putbyte( 0xA0, hObjFile );
|
||||
bCheckSum += 0xA0;
|
||||
|
||||
putword( wTotalLen, hObjFile );
|
||||
bCheckSum += LOBYTE( wTotalLen );
|
||||
bCheckSum += HIBYTE( wTotalLen );
|
||||
|
||||
putbyte( 2, hObjFile ); /* 2 = _DATA segment */
|
||||
bCheckSum += 2;
|
||||
|
||||
putword( 0, hObjFile ); /* 0 = offset */
|
||||
|
||||
for( y = 0; y < wSymbols; y++ )
|
||||
{
|
||||
* ( ULONG * ) symbol = ulSymbolNameOffset;
|
||||
|
||||
if( ! IsExternal( y ) )
|
||||
{
|
||||
ulFunctionOffset = ( GetFunctionPos( pSymbol->szName ) - 1 ) *
|
||||
sizeof( prgFunction );
|
||||
* ( ( ULONG * ) &symbol[ 5 ] ) = ulFunctionOffset;
|
||||
}
|
||||
else
|
||||
* ( ( ULONG * ) &symbol[ 5 ] ) = 0;
|
||||
|
||||
if( pSymbol->cScope == FS_MESSAGE )
|
||||
symbol[ 4 ] = FS_PUBLIC;
|
||||
else
|
||||
symbol[ 4 ] = pSymbol->cScope;
|
||||
|
||||
for( w = 0; w < wSymLen; w++ )
|
||||
{
|
||||
putbyte( * ( symbol + w ), hObjFile );
|
||||
bCheckSum += * ( symbol + w );
|
||||
}
|
||||
|
||||
ulSymbolNameOffset += strlen( pSymbol->szName ) + 1;
|
||||
pSymbol = pSymbol->pNext;
|
||||
}
|
||||
|
||||
while( pFunction )
|
||||
{
|
||||
for( w = 0; w < pFunction->lPCodePos; w++ )
|
||||
{
|
||||
putbyte( pFunction->pCode[ w ], hObjFile );
|
||||
bCheckSum += pFunction->pCode[ w ];
|
||||
}
|
||||
putbyte( _ENDPROC, hObjFile );
|
||||
bCheckSum += _ENDPROC;
|
||||
pFunction = pFunction->pNext;
|
||||
}
|
||||
|
||||
pSymbol = GetFirstSymbol();
|
||||
|
||||
while( pSymbol )
|
||||
{
|
||||
for( w = 0; w < strlen( pSymbol->szName ); w++ )
|
||||
{
|
||||
putbyte( pSymbol->szName[ w ], hObjFile );
|
||||
bCheckSum += pSymbol->szName[ w ];
|
||||
}
|
||||
putbyte( 0, hObjFile );
|
||||
pSymbol = pSymbol->pNext;
|
||||
}
|
||||
|
||||
putbyte( 256 - bCheckSum, hObjFile );
|
||||
}
|
||||
|
||||
static void DefineSegment( FILE * hObjFile, BYTE bName, BYTE bClass, WORD wLen )
|
||||
{
|
||||
BYTE bCheckSum = 0;
|
||||
|
||||
putbyte( 0x98, hObjFile );
|
||||
bCheckSum += 0x98;
|
||||
putbyte( 7, hObjFile ); /* SegDef records have always this length */
|
||||
bCheckSum += 7;
|
||||
putbyte( 0, hObjFile );
|
||||
|
||||
putbyte( 0xA9, hObjFile );
|
||||
bCheckSum += 0xA9;
|
||||
|
||||
putword( wLen, hObjFile );
|
||||
bCheckSum += LOBYTE( wLen );
|
||||
bCheckSum += HIBYTE( wLen );
|
||||
|
||||
putbyte( bName, hObjFile );
|
||||
bCheckSum += bName;
|
||||
putbyte( bClass, hObjFile );
|
||||
bCheckSum += bClass;
|
||||
putbyte( 0, hObjFile );
|
||||
|
||||
putbyte( 256 - bCheckSum, hObjFile );
|
||||
}
|
||||
|
||||
static void PubDef( FILE * hObjFile, char * szName, WORD wSegment, WORD wOffset )
|
||||
{
|
||||
BYTE bChk = 0;
|
||||
BYTE bChar;
|
||||
WORD wLen = 2 + 2 + strlen( szName ) + 2 + 1;
|
||||
|
||||
putbyte( 0x90, hObjFile );
|
||||
bChk += 0x90;
|
||||
|
||||
putword( wLen, hObjFile );
|
||||
bChk += LOBYTE( wLen );
|
||||
bChk += HIBYTE( wLen );
|
||||
|
||||
putbyte( 0x00, hObjFile );
|
||||
putbyte( wSegment, hObjFile );
|
||||
bChk += wSegment;
|
||||
|
||||
putbyte( strlen( szName ), hObjFile );
|
||||
bChk += strlen( szName );
|
||||
|
||||
while( bChar = * szName++ )
|
||||
{
|
||||
putbyte( bChar, hObjFile );
|
||||
bChk += bChar;
|
||||
}
|
||||
|
||||
putword( wOffset, hObjFile);
|
||||
bChk += LOBYTE( wOffset );
|
||||
bChk += HIBYTE( wOffset );
|
||||
putbyte( 0x00, hObjFile );
|
||||
|
||||
putbyte( 256 - bChk, hObjFile );
|
||||
}
|
||||
|
||||
static void Fixup( FILE * hObjFile, BYTE bType, WORD wOffset, BYTE bFlags, BYTE bSymbol )
|
||||
{
|
||||
BYTE bCheckSum = 0;
|
||||
|
||||
putbyte( 0x9D, hObjFile ); bCheckSum += 0x9D;
|
||||
|
||||
putword( 5, hObjFile ); bCheckSum += 5;
|
||||
|
||||
putbyte( bType + HIBYTE( wOffset ), hObjFile );
|
||||
bCheckSum += bType + HIBYTE( wOffset );
|
||||
|
||||
putbyte( LOBYTE( wOffset ), hObjFile );
|
||||
bCheckSum += LOBYTE( wOffset );
|
||||
|
||||
putbyte( bFlags, hObjFile ); bCheckSum += bFlags;
|
||||
putbyte( bSymbol, hObjFile ); bCheckSum += bSymbol;
|
||||
|
||||
putbyte( 256 - bCheckSum, hObjFile );
|
||||
}
|
||||
|
||||
static void EnumeratedData( FILE * hObjFile, BYTE bSegment, BYTE * pData, WORD wLen, WORD wOffset )
|
||||
{
|
||||
BYTE bCheckSum = 0;
|
||||
WORD w;
|
||||
|
||||
putbyte( 0xA0, hObjFile );
|
||||
bCheckSum += 0xA0;
|
||||
|
||||
putword( ( WORD ) ( wLen + 4 ), hObjFile );
|
||||
bCheckSum += LOBYTE( wLen + 4 );
|
||||
bCheckSum += HIBYTE( wLen + 4 );
|
||||
|
||||
putbyte( bSegment, hObjFile );
|
||||
bCheckSum += bSegment;
|
||||
|
||||
putword( wOffset, hObjFile );
|
||||
bCheckSum += wOffset;
|
||||
|
||||
for( w = 0; w < wLen; w++ )
|
||||
{
|
||||
putbyte( * ( pData + w ), hObjFile );
|
||||
bCheckSum += * ( pData + w );
|
||||
}
|
||||
|
||||
putbyte( 256 - bCheckSum, hObjFile );
|
||||
}
|
||||
|
||||
static void End( FILE * hObjFile )
|
||||
{
|
||||
BYTE bChk = 0;
|
||||
BYTE bChar;
|
||||
|
||||
putbyte( 0x8A, hObjFile ); bChk += 0x8A;
|
||||
|
||||
putbyte( 0x02, hObjFile ); bChk += 0x02;
|
||||
putbyte( 0x00, hObjFile );
|
||||
|
||||
putbyte( 0x00, hObjFile ); bChk += 0x00;
|
||||
|
||||
putbyte( 256 - bChk, hObjFile );
|
||||
}
|
||||
|
||||
static void GroupDef( FILE * hObjFile, BYTE bName, BYTE * aSegs )
|
||||
{
|
||||
BYTE bCheckSum = 0;
|
||||
WORD wRecLen = 2;
|
||||
WORD w = 0;
|
||||
|
||||
while( aSegs[ w++ ] )
|
||||
wRecLen += 2;
|
||||
|
||||
putbyte( 0x9A, hObjFile );
|
||||
bCheckSum += 0x9A;
|
||||
|
||||
putword( wRecLen, hObjFile );
|
||||
bCheckSum += LOBYTE( wRecLen );
|
||||
bCheckSum += HIBYTE( wRecLen );
|
||||
|
||||
putbyte( bName + 1, hObjFile );
|
||||
bCheckSum += bName + 1;
|
||||
|
||||
w = 0;
|
||||
while( aSegs[ w ] )
|
||||
{
|
||||
putbyte( 0xFF, hObjFile );
|
||||
bCheckSum += 0xFF;
|
||||
putbyte( aSegs[ w ], hObjFile );
|
||||
bCheckSum += aSegs[ w ];
|
||||
w++;
|
||||
}
|
||||
|
||||
putbyte( 256 - bCheckSum, hObjFile );
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <malloc.h> /* required for allocating and freeing memory */
|
||||
#include "pcode.h" /* pcode values */
|
||||
#include "types.h" /* our defined types */
|
||||
#include "compiler.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#define HAVE_STRUPR
|
||||
@@ -27,7 +28,7 @@
|
||||
#endif
|
||||
|
||||
/* TODO: #define this for various platforms */
|
||||
#define PATH_DELIMITER "/\\"
|
||||
#define PATH_DELIMITER "\\"
|
||||
#define IS_PATH_SEP( c ) (strchr(PATH_DELIMITER, (c))!=NULL)
|
||||
|
||||
extern FILE * yyin; /* currently yacc parsed file */
|
||||
@@ -51,30 +52,6 @@ typedef struct
|
||||
|
||||
int Include( char * szFileName ); /* end #include support */
|
||||
|
||||
typedef struct _VAR /* locals, static, public variables support */
|
||||
{
|
||||
char *szName; /* variable name */
|
||||
char *szAlias; /* variable alias namespace */
|
||||
struct _VAR * pNext; /* pointer to next defined variable */
|
||||
} VAR, * PVAR;
|
||||
|
||||
typedef struct __FUNC /* functions definition support */
|
||||
{
|
||||
char * szName; /* name of a defined Clipper function */
|
||||
char cScope; /* scope of a defined Clipper function */
|
||||
BYTE bFlags; /* some flags we may need */
|
||||
WORD wParamCount; /* number of declared parameters */
|
||||
PVAR pLocals; /* pointer to local variables list */
|
||||
PVAR pStatics; /* pointer to static variables list */
|
||||
PVAR pFields; /* pointer to fields variables list */
|
||||
BYTE * pCode; /* pointer to a memory block where pcode is stored */
|
||||
LONG lPCodeSize; /* total memory size for pcode */
|
||||
LONG lPCodePos; /* actual pcode offset */
|
||||
WORD wStaticsBase; /* base for this function statics */
|
||||
struct __FUNC * pOwner; /* pointer to the function/procedure that owns the codeblock */
|
||||
struct __FUNC * pNext; /* pointer to the next defined function */
|
||||
} _FUNC, * PFUNCTION; /* structure to hold a Clipper defined function */
|
||||
|
||||
/*
|
||||
* flags for bFlags member
|
||||
*/
|
||||
@@ -83,30 +60,9 @@ typedef struct __FUNC /* functions definition support */
|
||||
#define FUN_PROCEDURE 4 /* This is a procedure that shouldn't return value */
|
||||
#define FUN_ILLEGAL_INIT 8 /* Attempt to initialize static variable with a function call */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PFUNCTION pFirst; /* pointer to the first defined funtion */
|
||||
PFUNCTION pLast; /* pointer to the last defined function */
|
||||
int iCount; /* number of defined functions */
|
||||
} FUNCTIONS; /* structure to control all Clipper defined functions */
|
||||
|
||||
/* pcode chunks bytes size */
|
||||
#define PCODE_CHUNK 100
|
||||
|
||||
typedef struct _COMSYMBOL /* compiler symbol support structure */
|
||||
{
|
||||
char * szName; /* the name of the symbol */
|
||||
char cScope; /* the scope of the symbol */
|
||||
struct _COMSYMBOL * pNext; /* pointer to the next defined symbol */
|
||||
} COMSYMBOL, * PCOMSYMBOL;
|
||||
|
||||
typedef struct /* symbol table support structures */
|
||||
{
|
||||
PCOMSYMBOL pFirst; /* pointer to the first defined symbol */
|
||||
PCOMSYMBOL pLast; /* pointer to the last defined symbol */
|
||||
int iCount; /* number of defined symbols */
|
||||
} SYMBOLS;
|
||||
|
||||
typedef struct __ELSEIF
|
||||
{
|
||||
WORD wOffset;
|
||||
@@ -181,7 +137,6 @@ void GenError( int, char*, char * ); /* generic parsing error management fu
|
||||
void GenExterns( void ); /* generates the symbols for the EXTERN names */
|
||||
void GenReturn( WORD wOffset ); /* generates a return offset to later on fill it with the proper exiting pcode address */
|
||||
PFUNCTION GetFuncall( char * szFunName ); /* locates a previously defined called function */
|
||||
PFUNCTION GetFunction( char * szFunName ); /* locates a previously defined function */
|
||||
PVAR GetVar( PVAR pVars, WORD wOrder ); /* returns a variable if defined or zero */
|
||||
WORD GetVarPos( PVAR pVars, char * szVarName ); /* returns the order + 1 of a variable if defined or zero */
|
||||
int GetLocalVarPos( char * szVarName ); /* returns the order + 1 of a local variable */
|
||||
@@ -226,15 +181,12 @@ void StaticDefStart( void );
|
||||
void StaticDefEnd( WORD );
|
||||
void StaticAssign( void ); /* checks if static variable is initialized with function call */
|
||||
|
||||
void * OurMalloc( LONG lSize ); /* our malloc with error control */
|
||||
void * OurRealloc( void * p, LONG lSize ); /* our malloc with error control */
|
||||
#define OurFree( p ) free( (p) ); /* just for symetry -we can expand it later */
|
||||
|
||||
/* output related functions */
|
||||
void GenCCode( char *, char * ); /* generates the C language output */
|
||||
void GenJava( char *, char * ); /* generates the Java language output */
|
||||
void GenPascal( char *, char * ); /* generates the Pascal language output */
|
||||
void GenRC( char *, char * ); /* generates the RC language output */
|
||||
void GenObj32( char *, char * ); /* generates OBJ 32 bits */
|
||||
|
||||
void PrintUsage( char * );
|
||||
|
||||
@@ -384,6 +336,7 @@ int _iSyntaxCheckOnly = 0; /* syntax check only */
|
||||
int _iLanguage = LANG_C; /* default Harbour generated output language */
|
||||
int _iRestrictSymbolLength = 0; /* generate 10 chars max symbols length */
|
||||
int _iShortCuts = 1; /* .and. & .or. expressions shortcuts */
|
||||
int _iObj32 = 0; /* generate OBJ 32 bits */
|
||||
WORD _wStatics = 0; /* number of defined statics variables on the PRG */
|
||||
PRETURN pReturns = 0; /* list of multiple returns from a function */
|
||||
PEXTERN pExterns = 0;
|
||||
@@ -989,7 +942,7 @@ void EXTERNAL_LINKAGE close_on_exit( void )
|
||||
}
|
||||
}
|
||||
|
||||
int harbour_main( int argc, char * argv[] )
|
||||
int main( int argc, char * argv[] )
|
||||
{
|
||||
int iStatus = 0, iArg = 1;
|
||||
char szFileName[ _POSIX_PATH_MAX ]; /* filename to parse */
|
||||
@@ -1031,6 +984,16 @@ int harbour_main( int argc, char * argv[] )
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case 'F':
|
||||
{
|
||||
char * szUpper = strupr( strdup( &argv[ iArg ][ 2 ] ) );
|
||||
if( ! strcmp( szUpper, "OBJ32" ) )
|
||||
_iObj32 = 1;
|
||||
free( szUpper );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
switch( argv[ iArg ][ 2 ] )
|
||||
@@ -1143,7 +1106,7 @@ int harbour_main( int argc, char * argv[] )
|
||||
fclose( yyin );
|
||||
files.pLast =NULL;
|
||||
|
||||
if( ! _iSyntaxCheckOnly )
|
||||
if( ! _iSyntaxCheckOnly && ! _iObj32 )
|
||||
{
|
||||
if( _pInitFunc )
|
||||
{
|
||||
@@ -1189,6 +1152,12 @@ int harbour_main( int argc, char * argv[] )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( _iObj32 )
|
||||
{
|
||||
pFileName->extension = ".obj";
|
||||
MakeFilename( szFileName, pFileName );
|
||||
GenObj32( szFileName, pFileName->name );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1211,6 +1180,8 @@ void PrintUsage( char * szSelf )
|
||||
printf( "Syntax: %s <file.prg> [options]\n"
|
||||
"\nOptions: \n"
|
||||
"\t/d<id>[=<val>]\t#define <id>\n"
|
||||
"\t/f\t\tgenerated object file\n"
|
||||
"\t\t\t /fobj32 --> Windows/Dos 32 bits OBJ\n"
|
||||
"\t/g\t\tgenerated output language\n"
|
||||
"\t\t\t /gc (C default) --> <file.c>\n"
|
||||
"\t\t\t /gj (Java) --> <file.java>\n"
|
||||
@@ -1523,11 +1494,11 @@ int Include( char * szFileName )
|
||||
pFile->pPrev = files.pLast;
|
||||
files.pLast = pFile;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
yy_switch_to_buffer( (YY_BUFFER_STATE) pFile->pBuffer = yy_create_buffer( yyin, 8192 * 2 ) );
|
||||
#else
|
||||
#else
|
||||
yy_switch_to_buffer( pFile->pBuffer = yy_create_buffer( yyin, 8192 * 2 ) );
|
||||
#endif
|
||||
#endif
|
||||
files.iFiles++;
|
||||
return 1;
|
||||
}
|
||||
@@ -1545,19 +1516,19 @@ int yywrap( void ) /* handles the EOF of the currently processed file */
|
||||
files.pLast = ( PFILE ) ( ( PFILE ) files.pLast )->pPrev;
|
||||
iLine = files.pLast->iLine;
|
||||
printf( "\nparsing file %s\n", files.pLast->szFileName );
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
yy_delete_buffer( (YY_BUFFER_STATE) ( ( PFILE ) pLast )->pBuffer );
|
||||
#else
|
||||
yy_delete_buffer( ( ( PFILE ) pLast )->pBuffer );
|
||||
#endif
|
||||
#endif
|
||||
free( pLast );
|
||||
files.iFiles--;
|
||||
yyin = files.pLast->handle;
|
||||
#ifdef __cplusplus
|
||||
#ifdef __cplusplus
|
||||
yy_switch_to_buffer( (YY_BUFFER_STATE) files.pLast->pBuffer );
|
||||
#else
|
||||
yy_switch_to_buffer( files.pLast->pBuffer );
|
||||
#endif
|
||||
#endif
|
||||
return 0; /* we close the currently include file and continue */
|
||||
}
|
||||
}
|
||||
@@ -1779,7 +1750,8 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
|
||||
{
|
||||
if( pFunc->cScope != FS_PUBLIC )
|
||||
fprintf( yyc, "static " );
|
||||
fprintf( yyc, "HARBOUR %s( void )\n{\n static BYTE pcode[]={\n", pFunc->szName );
|
||||
|
||||
fprintf( yyc, "HARBOUR %s( void )\n{\n static BYTE pcode[] = { \n", pFunc->szName );
|
||||
|
||||
lPCodePos = 0;
|
||||
while( lPCodePos < pFunc->lPCodePos )
|
||||
@@ -2605,6 +2577,29 @@ WORD GetSymbolPos( char * szSymbolName ) /* return 0 if not found or order + 1 *
|
||||
return 0;
|
||||
}
|
||||
|
||||
WORD GetFunctionPos( char * szFunctionName ) /* return 0 if not found or order + 1 */
|
||||
{
|
||||
PFUNCTION pFunc = functions.pFirst;
|
||||
WORD wFunction = _iStartProc;
|
||||
|
||||
while( pFunc )
|
||||
{
|
||||
if( ! strcmp( pFunc->szName, szFunctionName ) && pFunc != functions.pFirst )
|
||||
return wFunction;
|
||||
else
|
||||
{
|
||||
if( pFunc->pNext )
|
||||
{
|
||||
pFunc = pFunc->pNext;
|
||||
wFunction++;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Inc( void )
|
||||
{
|
||||
GenPCode1( _INC );
|
||||
@@ -3012,9 +3007,8 @@ void SetFrame( void ) /* generates the proper _FRAME values */
|
||||
*/
|
||||
void CodeBlockStart()
|
||||
{
|
||||
PFUNCTION pFunc;
|
||||
PFUNCTION pFunc = FunctionNew( NULL, FS_STATIC );
|
||||
|
||||
pFunc =FunctionNew( NULL, FS_STATIC );
|
||||
pFunc->pOwner = functions.pLast;
|
||||
pFunc->wStaticsBase = functions.pLast->wStaticsBase;
|
||||
|
||||
|
||||
24
harbour/source/compiler/symbols.asm
Normal file
24
harbour/source/compiler/symbols.asm
Normal file
@@ -0,0 +1,24 @@
|
||||
.386
|
||||
|
||||
HB_STARTSYMBOLS segment dword use32 public 'DATA'
|
||||
HB_STARTSYMBOLS ends
|
||||
|
||||
HB_SYMBOLS segment dword use32 public 'DATA'
|
||||
HB_SYMBOLS ends
|
||||
|
||||
HB_ENDSYMBOLS segment dword use32 public 'DATA'
|
||||
HB_ENDSYMBOLS ends
|
||||
|
||||
DGROUP group HB_STARTSYMBOLS, HB_SYMBOLS, HB_ENDSYMBOLS
|
||||
|
||||
public _hb_firstsymbol, _hb_lastsymbol
|
||||
|
||||
HB_STARTSYMBOLS segment
|
||||
_hb_firstsymbol label byte
|
||||
HB_STARTSYMBOLS ends
|
||||
|
||||
HB_ENDSYMBOLS segment
|
||||
_hb_lastsymbol label byte
|
||||
HB_ENDSYMBOLS ends
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user