* harbour/common.mak
* updated for new files - please check
* harbour/harbour.spec
* added compiler library
* harbour/bin/pack_src.sh
* harbour/bin/hb-func.sh
* updated for new files and libraries
* harbour/config/w32/mingw32.cf
* harbour/config/w32/watcom.cf
* harbour/config/w32/xcc.cf
* added winsock libraries
* harbour/include/hbapicdp.h
* harbour/source/rtl/cdpapi.c
+ added hb_cdpicmp() - not case sensitive version of hb_cdpcmp()
* harbour/include/hbapiitm.h
* harbour/source/vm/itemapi.c
+ hb_itemStrICmp(), hb_itemCopyFromRef(), hb_itemMoveFromRef()
* harbour/include/hbapi.h
* harbour/include/hbcomp.h
* harbour/include/hbcompdf.h
* harbour/include/hbexpra.c
* harbour/include/hbexprb.c
* harbour/include/hbexprop.h
* harbour/include/hbmacro.h
* harbour/include/hbpcode.h
* harbour/include/hbvmpub.h
* harbour/include/hbxvm.h
* harbour/source/common/expropt1.c
* harbour/source/compiler/complex.c
* harbour/source/compiler/genc.c
* harbour/source/compiler/gencc.c
* harbour/source/compiler/gencli.c
* harbour/source/compiler/genhrb.c
* harbour/source/compiler/genobj32.c
* harbour/source/compiler/harbour.y
* harbour/source/compiler/harbour.yyc
* harbour/source/compiler/harbour.yyh
* harbour/source/compiler/hbdead.c
* harbour/source/compiler/hbfix.c
* harbour/source/compiler/hblbl.c
* harbour/source/compiler/hbmain.c
* harbour/source/compiler/hbopt.c
* harbour/source/compiler/hbpcode.c
* harbour/source/compiler/hbstripl.c
* harbour/source/macro/macro.y
* harbour/source/macro/macro.yyc
* harbour/source/macro/macro.yyh
* harbour/source/macro/macrolex.c
* harbour/source/vm/Makefile
* harbour/source/vm/arrays.c
* harbour/source/vm/asort.c
* harbour/source/vm/classes.c
* harbour/source/vm/eval.c
* harbour/source/vm/garbage.c
* harbour/source/vm/hvm.c
* harbour/source/vm/itemapi.c
* harbour/source/vm/macro.c
+ harbour/source/vm/hashes.c
+ harbour/source/vm/hashfunc.c
+ added hash items, f.e.:
local h1 := {=>}, h2 := { "a"=>1.234, "b"=>2.345 }
? h2[ "a" ], h2[ "b ]
+ added support for DYNAMIC function declaration - it allow to define
functions which are lately bound at runtime, f.e.:
/*** t01.prg ***/
dynamic func1
proc main()
local h:=__hrbload("t02.hrb")
? func1()
return
/*** t02.prg ***/
func func1
return "Hello!!!"
% use new FUNCALL structure to hold EXTERNAL and DYNAMIC functions,
it reduce memory usage, FUNCALL is much smaller then FUNCTION
% use symbol scope bits when possible instead of making some linear scan
+ added new enumarator message: __ENUMKEY - it allow to access
key value when hash item is base enumerator value, f.e.:
proc main()
local v, h:={"a"=>1.000,"b"=>2.000,"c"=>3.000}
heval( h, { |k,v,i| qout( k, v, i ) } ); ?
for each v in h
? v, "=>", v:__enumKey(), v:__enumValue(), v:__enumIndex(), ;
valtype(v:__enumBase())
v += 0.123
next
? ;heval( h, { |k,v,i| qout( k, v, i ) } )
return
+ added C level hb_hash*() functions
+ added support for full HASH item cloning and updated array cloning
to also clone nested hashes - please note that xHarbour does not do
that, in xHarbour ACLONE() clones _ONLY_ nested arrays and HCLONE()
_DOES_NOT_ clone _ANY_ nested items.
* harbour/include/hbextern.ch
+ added hash functions HB_H*()
* changed INET*() functions to HB_INET*()
+ added hash functions H*() and socket functions INET*() when
HB_COMPAT_XHB is set
* harbour/include/hbtypes.h
+ added missing HB_EXTERN_BEGIN / HB_EXTERN_END
* harbour/include/hbpp.h
* harbour/source/pp/ppcore.c
! added protection against automatic word concatenation in some cases
! fixed preprocessing expressions when match marker matches ';' token
* harbour/source/rtl/Makefile
+ harbour/source/rtl/itemseri.c
+ added functions for item serialization: HB_SERIALIZE() and
HB_DESERIALIZE() - these function are not binary compatible
with xHarbour functions with the same names but make very
similar job with the exception to serialization of codeblock
and object variables - Harbour does not allow to serialize
codeblocks and serialize objects as arrays.
In most cases these functions can replace the xHarbour ones
+ added HB_DESERIALBEGIN() and HB_DESERIALIZE() functions covered
by HB_COMPAT_XHB macro - this functions are only for compatibility
with existing xHarbour code, In Harbour HB_DESERIALBEGIN() is
dummy function which returns first parameter and HB_DESERIALNEXT()
is a simple wrapper to HB_DESERIALIZE() so it's not necessary to
use them.
* harbour/source/rtl/hbinet.c
* changed INET*() functions to HB_INET*() and enable them for default
build
+ added INET*() functions wrappers covered by HB_COMPAT_XHB macro
* harbour/source/rtl/hbrandom.c
+ added HB_RANDOMINT() - xHarbour compatible
* harbour/source/rtl/len.c
+ added support for HASHes
* harbour/source/rtl/valtype.c
+ added support for HASHes
+ added set of HB_IS*() functions - they are a little bit faster then
calling VALTYPE( v ) == <cVal>
- removed HB_ISBYREF() - this function cannot longer work, it was using
a Clipper incompatible anomalies in passing variables by reference I
fixed so it has to stop to work. If it will be realy necessary to
implement HB_ISBYREF() function then please inform me - it will have
to be done at compiler level or with some much deeper HVM stack
checking.
* harbour/source/vm/extend.c
! fixed hb_extIsArray() and hb_extIsObject() to work well with
parameters passed by reference.
Please note that now hb_extIsArray() return TRUE only for pure arrays
not object values.
* harbour/contrib/Makefile
+ harbour/contrib/tip/Changelog
+ harbour/contrib/tip/Makefile
+ harbour/contrib/tip/atokens.c
+ harbour/contrib/tip/base64x.c
+ harbour/contrib/tip/cgi.prg
+ harbour/contrib/tip/client.prg
+ harbour/contrib/tip/credent.prg
+ harbour/contrib/tip/cstr.prg
+ harbour/contrib/tip/encb64.prg
+ harbour/contrib/tip/encmthd.c
+ harbour/contrib/tip/encoder.prg
+ harbour/contrib/tip/encqp.prg
+ harbour/contrib/tip/encurl.prg
+ harbour/contrib/tip/ftpcln.prg
+ harbour/contrib/tip/hbhex2n.c
+ harbour/contrib/tip/httpcln.prg
+ harbour/contrib/tip/mail.prg
+ harbour/contrib/tip/popcln.prg
+ harbour/contrib/tip/smtpcln.prg
+ harbour/contrib/tip/tip.ch
+ harbour/contrib/tip/url.prg
+ harbour/contrib/tip/utils.c
+ added TIP library - code borrowed from xHarbour
Please test - a lot of above code is not well tested, also some peaces
were written over year ago for different things (f.e. serialization for
NETRDD) and now I collected them and committed.
The TIP library was not tested at all. It can be compiled but I cannot
say if it works - I hope that people familiar with it can make necessary
test and fixes.
It's also not the final version of low level HASH item code. I'm working
on more efficient structure which uses binary tries but I cannot say when
I'll finish it (maybe in this weekend or maybe in next year) so I committed
working version now even if I'm not happy with overall performance (BTW
not worser then in xHarbour)
665 lines
21 KiB
C
665 lines
21 KiB
C
/*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* Compiler Windows/DOS OBJ32 generation
|
|
*
|
|
* Copyright 1999 Antonio Linares <alinares@fivetech.com>
|
|
* www - http://www.harbour-project.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA (or visit
|
|
* their web site at http://www.gnu.org/).
|
|
*
|
|
*/
|
|
|
|
#include "hbcomp.h"
|
|
|
|
static ULONG GetSymbolsSize( HB_COMP_DECL );
|
|
static PCOMSYMBOL GetFirstSymbol( HB_COMP_DECL );
|
|
static char * GetSymbolName( HB_COMP_DECL, ULONG ulPos );
|
|
static ULONG GetPCodesSize( HB_COMP_DECL );
|
|
static ULONG GetSymbolsAmount( HB_COMP_DECL );
|
|
static BOOL IsExternal( HB_COMP_DECL, ULONG ulSymbol );
|
|
static USHORT GetExternalPos( char * szExternal );
|
|
static void GenerateLocalNames( FILE * hObjFile );
|
|
static void GenerateSymbolsSegment( HB_COMP_DECL, FILE * hObjFile );
|
|
static void GenerateDataSegment( HB_COMP_DECL, FILE * hObjFile );
|
|
static void GenerateCodeSegment( HB_COMP_DECL, FILE * hObjFile );
|
|
static void GenerateExternals( HB_COMP_DECL, FILE * hObjFile );
|
|
static void putbyte( BYTE b, FILE * hObjFile, BYTE * pbChecksum );
|
|
static void putword( USHORT w, FILE * hObjFile, BYTE * pbChecksum );
|
|
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 CodeSegment( HB_COMP_DECL, FILE * hObjFile, BYTE * prgCode, ULONG ulPrgLen, USHORT wFunctions );
|
|
static void DataSegment( HB_COMP_DECL, FILE * hObjFile, BYTE * symbol, ULONG wSymLen, ULONG wSymbols, ULONG ulTotalSize );
|
|
static void DefineSegment( FILE * hObjFile, BYTE bName, BYTE bClass, USHORT wLen );
|
|
static void PubDef( FILE * hObjFile, char * szName, USHORT wSegment, USHORT wOffset );
|
|
static void Fixup( FILE * hObjFile, BYTE bType, USHORT wOffset, BYTE bFlags, BYTE bSymbol );
|
|
static void EnumeratedData( FILE * hObjFile, BYTE bSegment, BYTE * pData, USHORT wLen, USHORT wOffset );
|
|
static void End( FILE * hObjFile );
|
|
static void GroupDef( FILE * hObjFile, BYTE bName, BYTE * aSegs );
|
|
|
|
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;
|
|
static USHORT wExternals = 1; /* _hb_vmExecute is always added */
|
|
static char * szPrefix = "_HB_FUN_";
|
|
|
|
void hb_compGenObj32( HB_COMP_DECL, PHB_FNAME pFileName )
|
|
{
|
|
char szFileName[ _POSIX_PATH_MAX + 1 ];
|
|
FILE * hObjFile; /* file handle for OBJ output */
|
|
char * szVer;
|
|
|
|
if( ! pFileName->szExtension )
|
|
pFileName->szExtension = ".obj";
|
|
hb_fsFNameMerge( szFileName, pFileName );
|
|
|
|
if( ( hObjFile = fopen( szFileName, "wb" ) ) == NULL )
|
|
{
|
|
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_CREATE_OUTPUT, szFileName, NULL );
|
|
return;
|
|
}
|
|
|
|
if( ! HB_COMP_PARAM->fQuiet )
|
|
{
|
|
printf( "Generating Windows/DOS OBJ32 output to \'%s\'... ", szFileName );
|
|
fflush( stdout );
|
|
}
|
|
|
|
CompiledFileName( hObjFile, szFileName );
|
|
szVer = hb_verHarbour();
|
|
CompilerVersion( hObjFile, szVer );
|
|
hb_xfree( szVer );
|
|
GenerateLocalNames( hObjFile );
|
|
GenerateExternals( HB_COMP_PARAM, hObjFile );
|
|
GenerateCodeSegment( HB_COMP_PARAM, hObjFile );
|
|
GenerateDataSegment( HB_COMP_PARAM, hObjFile );
|
|
GenerateSymbolsSegment( HB_COMP_PARAM, hObjFile );
|
|
End( hObjFile );
|
|
|
|
fclose( hObjFile );
|
|
|
|
if( ! HB_COMP_PARAM->fQuiet )
|
|
printf( "Done.\n" );
|
|
}
|
|
|
|
static ULONG GetSymbolsSize( HB_COMP_DECL )
|
|
{
|
|
return HB_COMP_PARAM->symbols.iCount * sizeof( HB_SYMB );
|
|
}
|
|
|
|
static PCOMSYMBOL GetFirstSymbol( HB_COMP_DECL )
|
|
{
|
|
PCOMSYMBOL pSymbol = HB_COMP_PARAM->symbols.pFirst;
|
|
return pSymbol;
|
|
}
|
|
|
|
static char * GetSymbolName( HB_COMP_DECL, ULONG ulPos )
|
|
{
|
|
PCOMSYMBOL pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
ULONG ul = 0;
|
|
|
|
while( pSymbol && ( ul++ < ulPos ) )
|
|
pSymbol = pSymbol->pNext;
|
|
|
|
return pSymbol->szName;
|
|
}
|
|
|
|
static ULONG GetPCodesSize( HB_COMP_DECL )
|
|
{
|
|
ULONG ulTotal = 0;
|
|
PFUNCTION pFunction = HB_COMP_PARAM->functions.pFirst;
|
|
|
|
if( ! HB_COMP_PARAM->fStartProc )
|
|
pFunction = pFunction->pNext;
|
|
|
|
while( pFunction )
|
|
{
|
|
ulTotal += pFunction->lPCodePos;
|
|
pFunction = pFunction->pNext;
|
|
}
|
|
return ulTotal;
|
|
}
|
|
|
|
static ULONG GetSymbolsAmount( HB_COMP_DECL )
|
|
{
|
|
PCOMSYMBOL pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
ULONG ulAmount = 1;
|
|
|
|
while( pSymbol->pNext )
|
|
{
|
|
ulAmount++;
|
|
pSymbol = pSymbol->pNext;
|
|
}
|
|
return ulAmount;
|
|
}
|
|
|
|
static BOOL IsExternal( HB_COMP_DECL, ULONG ulSymbol )
|
|
{
|
|
PCOMSYMBOL pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
ULONG ul = 0;
|
|
|
|
while( ul++ < ulSymbol )
|
|
pSymbol = pSymbol->pNext;
|
|
|
|
return ! hb_compFunctionFind( HB_COMP_PARAM, pSymbol->szName );
|
|
}
|
|
|
|
static USHORT GetExternalPos( char * szExternal )
|
|
{
|
|
USHORT w = 0;
|
|
|
|
while( w < wExternals )
|
|
{
|
|
if( ! strcmp( szExternal, externNames[ w ] ) )
|
|
break;
|
|
w++;
|
|
}
|
|
|
|
return w;
|
|
}
|
|
|
|
static void GenerateLocalNames( FILE * hObjFile )
|
|
{
|
|
char * localNames[] = { "_TEXT", "CODE",
|
|
"_NULL", "_DATA", "DATA",
|
|
"_BSS", "BSS", "DGROUP",
|
|
"HB_STARTSYMBOLS", "HB_SYMBOLS", "HB_ENDSYMBOLS", "HARBOUR",
|
|
"HB_STARTBORSYMBOLS", "_INIT_", "HB_ENDBORSYMBOLS", "INITDATA", "BORLAND",
|
|
0 };
|
|
|
|
LocalNames( hObjFile, localNames );
|
|
}
|
|
|
|
static void GenerateSymbolsSegment( HB_COMP_DECL, FILE * hObjFile )
|
|
{
|
|
BYTE symbolsData[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
BYTE groupDGroup[] = { 2, 3, 4, 0 }; /* segments defined order for DGROUP */
|
|
BYTE groupSymGroup[] = { 5, 6, 7, 0 }; /* segments defined order for SYMGROUP */
|
|
BYTE groupInitData[] = { 8, 9, 10, 0 }; /* segments defined order for INITDATA */
|
|
|
|
DefineSegment( hObjFile, 10, /* HB_STARTSYMBOLS position + 1 into localnames */
|
|
6, /* "DATA" position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
DefineSegment( hObjFile, 11, /* HB_SYMBOLS position + 1 into localNames */
|
|
6, /* "DATA" position + 1 into localNames */
|
|
8 ); /* segment length */
|
|
DefineSegment( hObjFile, 12, /* HB_ENDSYMBOLS position + 1 into localNames */
|
|
6, /* "DATA" position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
|
|
DefineSegment( hObjFile, 14, /* HB_STARTBORSYMBOLS position + 1 into localnames */
|
|
17, /* INITDATA position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
DefineSegment( hObjFile, 15, /* HB_STARTSYMBOLS position + 1 into localnames */
|
|
17, /* INITDATA position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
DefineSegment( hObjFile, 16, /* HB_ENDBORSYMBOLS position + 1 into localnames */
|
|
17, /* INITDATA position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
|
|
GroupDef( hObjFile, 8, groupDGroup ); /* "DGROUP" localNames position - 1 */
|
|
GroupDef( hObjFile, 12, groupSymGroup ); /* "SYMGROUP" localNames position - 1 */
|
|
GroupDef( hObjFile, 17, groupInitData ); /* "BORLAND" localNames position - 1 */
|
|
|
|
* ( USHORT * ) symbolsData = (USHORT) GetSymbolsAmount( HB_COMP_PARAM );
|
|
|
|
EnumeratedData( hObjFile, 6, symbolsData, sizeof( symbolsData ), 0 ); /* HB_SYMBOLS defined order segment */
|
|
|
|
Fixup( hObjFile, 0xE4, 4, /* offset into HB_SYMBOLS segment */
|
|
0x54,
|
|
4 ); /* DATA segment defined order */
|
|
}
|
|
|
|
static void GenerateDataSegment( HB_COMP_DECL, FILE * hObjFile )
|
|
{
|
|
HB_SYMB symbol;
|
|
ULONG ulSize = GetSymbolsSize( HB_COMP_PARAM );
|
|
PCOMSYMBOL pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
ULONG ulSymbols = GetSymbolsAmount( HB_COMP_PARAM ), ul;
|
|
|
|
while( pSymbol )
|
|
{
|
|
ulSize += strlen( pSymbol->szName ) + 1;
|
|
pSymbol = pSymbol->pNext;
|
|
}
|
|
|
|
ulSize += GetPCodesSize( HB_COMP_PARAM );
|
|
|
|
DefineSegment( hObjFile, 4, /* _NULL position + 1 into localnames */
|
|
6, /* "DATA" position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
DefineSegment( hObjFile, 7, /* _BSS position + 1 into localNames */
|
|
8, /* "BSS" position + 1 into localNames */
|
|
0 ); /* segment length */
|
|
DefineSegment( hObjFile, 5, /* "_DATA" position + 1 into localNames */
|
|
6, /* "DATA" position + 1 into localNames */
|
|
(USHORT) ulSize ); /* segment length */
|
|
|
|
memset( &symbol, 0, sizeof( symbol ) );
|
|
DataSegment( HB_COMP_PARAM, hObjFile, (BYTE *) &symbol,
|
|
sizeof( symbol ), GetSymbolsAmount( HB_COMP_PARAM ), ulSize );
|
|
|
|
pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
for( ul = 0; ul < ulSymbols; ul++ )
|
|
{
|
|
Fixup( hObjFile, 0xE4, (USHORT) ( ul * sizeof( HB_SYMB ) ), 0x54, 4 ); /* 4 = Data symbol name location */
|
|
|
|
if( IsExternal( HB_COMP_PARAM, ul ) )
|
|
{
|
|
if( ! ( pSymbol->cScope & HB_FS_MESSAGE ) )
|
|
Fixup( hObjFile, 0xE4, (USHORT) ( ul * sizeof( HB_SYMB ) ) + 8, 0x56,
|
|
GetExternalPos( GetSymbolName( HB_COMP_PARAM, ul ) ) + 1 );
|
|
}
|
|
else
|
|
{
|
|
/* if( ! ( pSymbol->cScope & HB_FS_MESSAGE ) ) */
|
|
Fixup( hObjFile, 0xE4, (USHORT) ( ul * sizeof( HB_SYMB ) ) + 8, 0x54, 1 ); /* function address location */
|
|
}
|
|
pSymbol = pSymbol->pNext;
|
|
}
|
|
}
|
|
|
|
static void GenerateCodeSegment( HB_COMP_DECL, FILE * hObjFile )
|
|
{
|
|
USHORT wFunctions = HB_COMP_PARAM->functions.iCount - ( HB_COMP_PARAM->fStartProc ? 0: 1 );
|
|
ULONG ulSize = wFunctions * sizeof( prgFunction );
|
|
PFUNCTION pFunc = ( HB_COMP_PARAM->fStartProc ? HB_COMP_PARAM->functions.pFirst: HB_COMP_PARAM->functions.pFirst->pNext );
|
|
USHORT w = 0;
|
|
|
|
DefineSegment( hObjFile, 2, /* "_TEXT" position + 1 into localNames */
|
|
3, /* "CODE" position + 1 into localNames */
|
|
(USHORT) ulSize ); /* segment length */
|
|
|
|
while( pFunc )
|
|
{
|
|
if( !( pFunc->cScope & ( HB_FS_STATIC | HB_FS_INIT | HB_FS_EXIT ) ) )
|
|
PubDef( hObjFile, pFunc->szName, 1, w * sizeof( prgFunction ) );
|
|
w++;
|
|
pFunc = pFunc->pNext;
|
|
}
|
|
|
|
CodeSegment( HB_COMP_PARAM, hObjFile, prgFunction, sizeof( prgFunction ), wFunctions );
|
|
|
|
for( w = 0; w < wFunctions; w++ )
|
|
{
|
|
/* prgFunction fixups */
|
|
Fixup( hObjFile, 0xE4, ( w * sizeof( prgFunction ) ) + 1,
|
|
0x54, 4 ); /* 4 = DATA segment defined order */
|
|
|
|
Fixup( hObjFile, 0xE4, ( w * sizeof( prgFunction ) ) + 6,
|
|
0x54, 4 ); /* DATA segment define order - pcode location */
|
|
|
|
Fixup( hObjFile, 0xA4, ( w * sizeof( prgFunction ) ) + 11,
|
|
0x56, 1 ); /* External: _hb_vmExecute */
|
|
}
|
|
}
|
|
|
|
static void GenerateExternals( HB_COMP_DECL, FILE * hObjFile )
|
|
{
|
|
USHORT w;
|
|
PFUNCALL pFunc;
|
|
PFUNCTION pFTemp;
|
|
|
|
/* calculate amount of externals */
|
|
pFunc = HB_COMP_PARAM->funcalls.pFirst;
|
|
while( pFunc )
|
|
{
|
|
if( ( pFTemp = hb_compFunctionFind( HB_COMP_PARAM, pFunc->szName ) ) == NULL || pFTemp == HB_COMP_PARAM->functions.pFirst )
|
|
wExternals++;
|
|
pFunc = pFunc->pNext;
|
|
}
|
|
if( wExternals )
|
|
{
|
|
externNames = ( char * * ) hb_xgrab( sizeof( char * ) * ( wExternals + 2 ) );
|
|
w = 1;
|
|
externNames[ 0 ] = "_hb_vmExecute";
|
|
|
|
pFunc = HB_COMP_PARAM->funcalls.pFirst;
|
|
while( pFunc )
|
|
{
|
|
if( ( pFTemp = hb_compFunctionFind( HB_COMP_PARAM, pFunc->szName ) ) == NULL || pFTemp == HB_COMP_PARAM->functions.pFirst )
|
|
externNames[ w++ ] = pFunc->szName;
|
|
pFunc = pFunc->pNext;
|
|
}
|
|
externNames[ w ] = 0;
|
|
ExternalNames( hObjFile, externNames );
|
|
}
|
|
}
|
|
|
|
static void putbyte( BYTE b, FILE * hObjFile, BYTE * pbChecksum )
|
|
{
|
|
fputc( b, hObjFile );
|
|
* pbChecksum += b;
|
|
}
|
|
|
|
static void putword( USHORT w, FILE * hObjFile, BYTE * pbChecksum )
|
|
{
|
|
putbyte( HB_LOBYTE( w ), hObjFile, pbChecksum );
|
|
putbyte( HB_HIBYTE( w ), hObjFile, pbChecksum );
|
|
}
|
|
|
|
static void CompiledFileName( FILE * hObjFile, char * szFileName )
|
|
{
|
|
USHORT wLen = strlen( szFileName );
|
|
BYTE bChk = 0; /* this is a checksum the linker will check to asure OBJ integrity */
|
|
BYTE bChar;
|
|
|
|
putbyte( 0x80, hObjFile, &bChk ); /* this tells the linker the kind of OBJ record this is */
|
|
putbyte( 1 + 1 + wLen, hObjFile, &bChk ); /* now it comes the total length of this OBJ record */
|
|
putbyte( 0, hObjFile, &bChk );
|
|
putbyte( (BYTE) wLen, hObjFile, &bChk ); /* szFileName length */
|
|
|
|
while( ( bChar = * szFileName++ ) != 0 )
|
|
putbyte( bChar, hObjFile, &bChk ); /* each of the szFileName characters */
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk ); /* a checksum that will be recalculated by the linker */
|
|
}
|
|
|
|
static void CompilerVersion( FILE * hObjFile, char * szVersion )
|
|
{
|
|
USHORT wLen = strlen( szVersion );
|
|
BYTE bChk = 0; /* this is a checksum the linker will check to asure OBJ integrity */
|
|
BYTE bChar;
|
|
|
|
putbyte( 0x88, hObjFile, &bChk ); /* this tells the linker the kind of OBJ record this is */
|
|
putword( 3 + wLen, hObjFile, &bChk ); /* now it comes the total length of this OBJ record */
|
|
putword( 0, hObjFile, &bChk );
|
|
|
|
while( ( bChar = * szVersion++ ) != 0 )
|
|
putbyte( bChar, hObjFile, &bChk ); /* each of the szFileName characters */
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk ); /* a checksum that will be recalculated by the linker */
|
|
}
|
|
|
|
static void LocalNames( FILE * hObjFile, char * szNames[] )
|
|
{
|
|
BYTE b = 0, c;
|
|
USHORT wTotalLen = 0;
|
|
BYTE bChk = 0;
|
|
|
|
while( szNames[ b ] )
|
|
wTotalLen += strlen( szNames[ b++ ] );
|
|
wTotalLen += 2 + b;
|
|
|
|
putbyte( 0x96, hObjFile, &bChk );
|
|
putword( wTotalLen, hObjFile, &bChk );
|
|
putbyte( 0, hObjFile, &bChk );
|
|
|
|
b = 0;
|
|
while( szNames[ b ] )
|
|
{
|
|
putbyte( strlen( szNames[ b ] ), hObjFile, &bChk );
|
|
|
|
c = 0;
|
|
while( szNames[ b ][ c ] )
|
|
putbyte( szNames[ b ][ c++ ], hObjFile, &bChk );
|
|
b++;
|
|
}
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void ExternalNames( FILE * hObjFile, char * szNames[] )
|
|
{
|
|
BYTE b = 0, c;
|
|
USHORT wTotalLen = 0;
|
|
BYTE bChk = 0;
|
|
|
|
while( szNames[ b ] )
|
|
{
|
|
if( b == 0 )
|
|
wTotalLen += strlen( szNames[ b++ ] ) + 1;
|
|
else
|
|
wTotalLen += strlen( szPrefix ) + strlen( szNames[ b++ ] ) + 1;
|
|
}
|
|
wTotalLen += 2 + b - 1;
|
|
|
|
putbyte( 0x8C, hObjFile, &bChk );
|
|
putword( wTotalLen, hObjFile, &bChk );
|
|
|
|
b = 0;
|
|
while( szNames[ b ] )
|
|
{
|
|
if( b == 0 )
|
|
putbyte( strlen( szNames[ b ] ), hObjFile, &bChk );
|
|
else
|
|
putbyte( strlen( szPrefix ) + strlen( szNames[ b ] ), hObjFile, &bChk );
|
|
|
|
c = 0;
|
|
|
|
if( b > 0 )
|
|
{
|
|
while( szPrefix[ c ] )
|
|
putbyte( szPrefix[ c++ ], hObjFile, &bChk );
|
|
c = 0;
|
|
}
|
|
|
|
while( szNames[ b ][ c ] )
|
|
putbyte( szNames[ b ][ c++ ], hObjFile, &bChk );
|
|
putbyte( 0, hObjFile, &bChk );
|
|
b++;
|
|
}
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void CodeSegment( HB_COMP_DECL, FILE * hObjFile, BYTE * prgCode, ULONG ulPrgLen, USHORT wFunctions )
|
|
{
|
|
BYTE bChk = 0;
|
|
USHORT y;
|
|
USHORT wTotalLen = (USHORT) ( ulPrgLen * wFunctions ) + 4;
|
|
ULONG ul;
|
|
PFUNCTION pFunction = HB_COMP_PARAM->functions.pFirst;
|
|
ULONG ulPCodeOffset = HB_COMP_PARAM->symbols.iCount * sizeof( HB_SYMB );
|
|
|
|
if( ! HB_COMP_PARAM->fStartProc )
|
|
pFunction = pFunction->pNext;
|
|
|
|
putbyte( 0xA0, hObjFile, &bChk );
|
|
putword( wTotalLen, hObjFile, &bChk );
|
|
putbyte( 1, hObjFile, &bChk ); /* 1 = _TEXT segment */
|
|
putword( 0, hObjFile, &bChk ); /* 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, &bChk );
|
|
ulPCodeOffset += pFunction->lPCodePos;
|
|
pFunction = pFunction->pNext;
|
|
}
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void DataSegment( HB_COMP_DECL, FILE * hObjFile, BYTE * symbol, ULONG wSymLen, ULONG wSymbols,
|
|
ULONG ulSize )
|
|
{
|
|
BYTE bChk = 0;
|
|
ULONG w, y;
|
|
USHORT wTotalLen = 4 + (USHORT) ulSize;
|
|
PCOMSYMBOL pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
PFUNCTION pFunction = HB_COMP_PARAM->functions.pFirst;
|
|
ULONG ulSymbolNameOffset = GetSymbolsSize( HB_COMP_PARAM ) + GetPCodesSize( HB_COMP_PARAM );
|
|
ULONG ulFunctionOffset;
|
|
|
|
if( ! HB_COMP_PARAM->fStartProc )
|
|
pFunction = pFunction->pNext;
|
|
|
|
putbyte( 0xA0, hObjFile, &bChk );
|
|
putword( wTotalLen, hObjFile, &bChk );
|
|
putbyte( 4, hObjFile, &bChk ); /* 2 = _DATA segment defined order */
|
|
putword( 0, hObjFile, &bChk ); /* 0 = offset */
|
|
|
|
for( y = 0; y < wSymbols; y++ )
|
|
{
|
|
* ( ULONG * ) symbol = ulSymbolNameOffset;
|
|
|
|
if( ! IsExternal( HB_COMP_PARAM, y ) )
|
|
{
|
|
ulFunctionOffset = ( hb_compFunctionGetPos( HB_COMP_PARAM, pSymbol->szName ) - 1 ) *
|
|
sizeof( prgFunction );
|
|
* ( ( ULONG * ) &symbol[ 8 ] ) = ulFunctionOffset; /* 8 offset of function pointer into symbol */
|
|
}
|
|
else
|
|
* ( ( ULONG * ) &symbol[ 8 ] ) = 0; /* 8 offset of function pointer into symbol */
|
|
|
|
if( pSymbol->cScope == HB_FS_MESSAGE )
|
|
symbol[ 4 ] = HB_FS_PUBLIC;
|
|
else
|
|
symbol[ 4 ] = pSymbol->cScope;
|
|
|
|
for( w = 0; w < wSymLen; w++ )
|
|
putbyte( * ( symbol + w ), hObjFile, &bChk );
|
|
|
|
ulSymbolNameOffset += strlen( pSymbol->szName ) + 1;
|
|
pSymbol = pSymbol->pNext;
|
|
}
|
|
|
|
while( pFunction )
|
|
{
|
|
w = 0;
|
|
while( w < pFunction->lPCodePos )
|
|
putbyte( pFunction->pCode[ w++ ], hObjFile, &bChk );
|
|
|
|
pFunction = pFunction->pNext;
|
|
}
|
|
|
|
pSymbol = GetFirstSymbol( HB_COMP_PARAM );
|
|
|
|
while( pSymbol )
|
|
{
|
|
for( w = 0; w < strlen( pSymbol->szName ); w++ )
|
|
putbyte( pSymbol->szName[ w ], hObjFile, &bChk );
|
|
|
|
putbyte( 0, hObjFile, &bChk );
|
|
pSymbol = pSymbol->pNext;
|
|
}
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void DefineSegment( FILE * hObjFile, BYTE bName, BYTE bClass, USHORT wLen )
|
|
{
|
|
BYTE bChk = 0;
|
|
|
|
putbyte( 0x98, hObjFile, &bChk );
|
|
putbyte( 7, hObjFile, &bChk ); /* SegDef records have always this length */
|
|
putbyte( 0, hObjFile, &bChk );
|
|
|
|
putbyte( 0xA9, hObjFile, &bChk );
|
|
putword( wLen, hObjFile, &bChk );
|
|
putbyte( bName, hObjFile, &bChk );
|
|
putbyte( bClass, hObjFile, &bChk );
|
|
putbyte( 0, hObjFile, &bChk );
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void PubDef( FILE * hObjFile, char * szName, USHORT wSegment, USHORT wOffset )
|
|
{
|
|
BYTE bChk = 0;
|
|
BYTE bChar;
|
|
USHORT wLen = 2 + 2 + strlen( szPrefix ) + strlen( szName ) + 2 + 1;
|
|
char * szTemp;
|
|
|
|
putbyte( 0x90, hObjFile, &bChk );
|
|
putword( wLen, hObjFile, &bChk );
|
|
putbyte( 0x00, hObjFile, &bChk );
|
|
putbyte( (BYTE) wSegment, hObjFile, &bChk );
|
|
putbyte( strlen( szPrefix ) + strlen( szName ), hObjFile, &bChk );
|
|
|
|
szTemp = szPrefix;
|
|
while( ( bChar = * szTemp++ ) != 0 )
|
|
putbyte( bChar, hObjFile, &bChk );
|
|
|
|
while( ( bChar = * szName++ ) != 0 )
|
|
putbyte( bChar, hObjFile, &bChk );
|
|
|
|
putword( wOffset, hObjFile, &bChk );
|
|
putbyte( 0x00, hObjFile, &bChk );
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void Fixup( FILE * hObjFile, BYTE bType, USHORT wOffset, BYTE bFlags, BYTE bSymbol )
|
|
{
|
|
BYTE bChk = 0;
|
|
|
|
putbyte( 0x9D, hObjFile, &bChk );
|
|
putword( 5, hObjFile, &bChk );
|
|
putbyte( bType + HB_HIBYTE( wOffset ), hObjFile, &bChk );
|
|
putbyte( HB_LOBYTE( wOffset ), hObjFile, &bChk );
|
|
putbyte( bFlags, hObjFile, &bChk );
|
|
putbyte( bSymbol, hObjFile, &bChk );
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void EnumeratedData( FILE * hObjFile, BYTE bSegment, BYTE * pData, USHORT wLen, USHORT wOffset )
|
|
{
|
|
BYTE bChk = 0;
|
|
USHORT w;
|
|
|
|
putbyte( 0xA0, hObjFile, &bChk );
|
|
putword( ( USHORT ) ( wLen + 4 ), hObjFile, &bChk );
|
|
putbyte( bSegment, hObjFile, &bChk );
|
|
putword( wOffset, hObjFile, &bChk );
|
|
|
|
for( w = 0; w < wLen; w++ )
|
|
putbyte( * ( pData + w ), hObjFile, &bChk );
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void End( FILE * hObjFile )
|
|
{
|
|
BYTE bChk = 0;
|
|
|
|
putbyte( 0x8A, hObjFile, &bChk );
|
|
putbyte( 0x02, hObjFile, &bChk );
|
|
putbyte( 0x00, hObjFile, &bChk );
|
|
putbyte( 0x00, hObjFile, &bChk );
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|
|
|
|
static void GroupDef( FILE * hObjFile, BYTE bName, BYTE * aSegs )
|
|
{
|
|
BYTE bChk = 0;
|
|
USHORT wRecLen = 2;
|
|
USHORT w = 0;
|
|
|
|
while( aSegs[ w++ ] )
|
|
wRecLen += 2;
|
|
|
|
putbyte( 0x9A, hObjFile, &bChk );
|
|
putword( wRecLen, hObjFile, &bChk );
|
|
putbyte( bName + 1, hObjFile, &bChk );
|
|
|
|
w = 0;
|
|
while( aSegs[ w ] )
|
|
{
|
|
putbyte( 0xFF, hObjFile, &bChk );
|
|
putbyte( aSegs[ w++ ], hObjFile, &bChk );
|
|
}
|
|
|
|
putbyte( 256 - bChk, hObjFile, &bChk );
|
|
}
|