mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
598 lines
23 KiB
598 lines
23 KiB
/*
|
|
* Thunk Compiler - Routines for Code Generator (32->16).
|
|
* GDI-specific hacks
|
|
*
|
|
* This is a Win32 specific file
|
|
* Microsoft Confidential
|
|
*
|
|
* Copyright (c) Microsoft Corporation 1987, 1988, 1989, 1990
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* Created by Kevin Ruddell 11/06/90
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include "error.h"
|
|
#include "thunk.h"
|
|
#include "types.h"
|
|
#include "symtab.h"
|
|
#include "codegen.h"
|
|
#include "cod3216.h"
|
|
|
|
extern BOOL fGDIAllocUsed;
|
|
extern BOOL fMapTo16Used;
|
|
extern BOOL fLocalHeapUsed;
|
|
extern unsigned int fgOutputFlag;
|
|
|
|
/*** cod32_HandlePointerGDI(ptnFrom,ptnTo)
|
|
*
|
|
* This function will act on the two pointers accordingly.
|
|
* Structures will be repacked if needed.
|
|
*
|
|
* Entry: ptnFrom - Parameter input to thunk.
|
|
* ptnTo - Parameter output from thunk.
|
|
*
|
|
* Exit: pointers are handled and code is generated.
|
|
*
|
|
*
|
|
* This is a GDI-specific hack. It assumes that there is
|
|
* only 1 thread at a time in the thunk layer and it does not
|
|
* handle any embedded pointers.
|
|
*/
|
|
|
|
void cod32_HandlePointerGDI(PTYPENODE ptnFrom, //Parameter input to thunk
|
|
PTYPENODE ptnTo) //Parameter output from thunk
|
|
{
|
|
int iNullLabel, iStoreLabel;
|
|
BOOL fSameType, fEmbeddedPtr;
|
|
BOOL fOutputOK = FALSE;
|
|
ULONG ulObjectSize;
|
|
|
|
printf("\n;Pointer %s --> %s\n",
|
|
typ_NonNull( ptnFrom->pchIdent), typ_NonNull( ptnTo->pchIdent));
|
|
|
|
/*
|
|
* If structures and (not identical or contain pointers), call
|
|
* structure repacking routine.
|
|
*/
|
|
fSameType = typ_TypeIdentical( ptnFrom, ptnTo);
|
|
fEmbeddedPtr = cod_CountPointerParameters( ptnFrom->pStructElems, FALSE);
|
|
|
|
if( (ptnFrom->fSemantics & SEMANTIC_OUTPUT) && fSameType &&
|
|
(ptnFrom->pSizeParam) && (ptnFrom->iBaseType == TYPE_CHAR)) {
|
|
fOutputOK = TRUE;
|
|
fMapTo16Used = TRUE;
|
|
}
|
|
|
|
if( !(ptnFrom->fSemantics & SEMANTIC_INPUT) && !fOutputOK) {
|
|
cod_NotHandled( "unsupported non-input pointer");
|
|
return;
|
|
}
|
|
|
|
printf( "\n\n\tmov\teax,[ebp+%u]\t\t;%s base address\n",
|
|
ptnFrom->iOffset, typ_NonNull( ptnFrom->pchIdent));
|
|
printf( "\tor\teax,eax\n");
|
|
printf( "\tjz\tL%u\n\n", iNullLabel = gen_LabelCount++);
|
|
|
|
if( ptnFrom->fSemantics & SEMANTIC_PASSIFHINULL) {
|
|
printf( ";special case of polymorphic parameter\n");
|
|
printf( ";do no conversion if the high word is null\n");
|
|
printf( "\trol\teax,16\n");
|
|
printf( "\tor\tax,ax\n");
|
|
printf( "\trol\teax,16\t\t\t;return eax to original state\n");
|
|
printf( "\tjz\tL%u\t\t\t;skip if hi word null\n\n",
|
|
iStoreLabel = gen_LabelCount++);
|
|
}
|
|
|
|
if( ptnFrom->iBaseType == TYPE_STRUCT) {
|
|
printf("\n;Structures are%s identical\n", fSameType ? "" : " not");
|
|
printf(";Structures %shave pointers\n\n", fEmbeddedPtr ? "" : "don't ");
|
|
|
|
if( fEmbeddedPtr) {
|
|
cod_NotHandled( "embedded pointer");
|
|
} else if( ptnFrom->pSizeParam) {
|
|
cod_NotHandled( "structure buffer");
|
|
} else if( !fSameType) {
|
|
cod32_StructureRepackGDI( ptnFrom, ptnTo);
|
|
} else {
|
|
printf( "\tmov\tecx,%u\t\t\t;struct size\n", ptnFrom->iBaseDataSize);
|
|
fMapTo16Used = TRUE;
|
|
}
|
|
} else if( fSameType) {
|
|
if( !ptnFrom->pSizeParam) {
|
|
if( ptnFrom->iBaseType == TYPE_NULLTYPE) {
|
|
printf( "\t.err *** NULLTYPE ***\n");
|
|
} else if( ptnFrom->iBaseType == TYPE_STRING) {
|
|
printf( "\tmov\tecx,%u\t\t;default string size\n",
|
|
DEFAULT_STRING_SIZE);
|
|
fMapTo16Used = TRUE;
|
|
} else {
|
|
printf( "\tmov\tecx,%u\t\t;default buffer size\n",
|
|
DEFAULT_BUFFER_SIZE);
|
|
fMapTo16Used = TRUE;
|
|
//cod_NotHandled( "non-string, non-struct, non-sized pointer");
|
|
}
|
|
} else {
|
|
if( ptnFrom->iBaseType == TYPE_CHAR) {
|
|
printf( "\tmov\tecx,[ebp+%u]\t\t;buffer size\n",
|
|
ptnFrom->pSizeParam->iOffset);
|
|
fMapTo16Used = TRUE;
|
|
} else {
|
|
cod_NotHandled( "non-char buffer");
|
|
}
|
|
}
|
|
} else {
|
|
cod_NotHandled( "pointer to different non-structs");
|
|
}
|
|
|
|
if( fMapTo16Used) {
|
|
printf( "\tpush\teax\t\t\t;base address\n", ptnFrom->iOffset);
|
|
printf( "\tpush\tecx\t\t\t;object size\n", ulObjectSize);
|
|
printf( "\tpush\tdword ptr [ebp-%u]\t;thunk ID\n", iPtrThunkIDOffset);
|
|
printf( "\tcall\tMapLS32\t\t\t;exit: (eax)==16:16 address\n");
|
|
if( ptnFrom->fSemantics & SEMANTIC_PASSIFHINULL)
|
|
printf( "L%u:\n", iStoreLabel);
|
|
printf( "\tmov\tDWORD PTR [ebp-%u],eax\t;value to push\n",
|
|
ptnFrom->iTempOffset);
|
|
}
|
|
|
|
printf( "\nL%u:\n", iNullLabel);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** cod32_PushParametersGDI
|
|
*
|
|
* This function generates the code that pushes the 32-bit parameters
|
|
* onto the stack.
|
|
*
|
|
* Entry: pFromNode - pointer to the 32-bit function's parameter list.
|
|
* pToNode - pointer to the 16-bit function's parameter list.
|
|
*
|
|
* Exit: generates the code that pushes the 32-bit parameters.
|
|
*
|
|
* History:
|
|
* 29-Nov-1988 JulieB Created it.
|
|
*/
|
|
|
|
cod32_PushParametersGDI(TypeNode *pFromNode,
|
|
TypeNode *pToNode)
|
|
|
|
{
|
|
int iStackOffset = DWORD_SIZE; /* offset to temp storage on stack */
|
|
unsigned int AllowLabel;
|
|
int fRestricted;
|
|
BOOL fSameType, fEmbeddedPtr;
|
|
BOOL fOutputOK = FALSE;
|
|
|
|
|
|
/*
|
|
* For each parameter, convert and push as needed.
|
|
*/
|
|
while (pFromNode) {
|
|
fRestricted = (pFromNode->fSemantics & SEMANTIC_RESTRICT);
|
|
|
|
printf("\n\n\t;From Name: %s Type: %s\n",
|
|
typ_NonNull(pFromNode->pchIdent),
|
|
typ_NonNull(pFromNode->pchBaseTypeName));
|
|
if (pFromNode->iBaseType == TYPE_NULLTYPE)
|
|
printf("\n\t.err **** NULLTYPE ****\n\n");
|
|
|
|
else if (pFromNode->iDeleted) {
|
|
|
|
/* If the iDeleted flag is set in the pFromNode, then this
|
|
* parameter does not exist in the original call frame.
|
|
* Therefore, we need to push a zero of the appropriate length.
|
|
*/
|
|
printf("\n;Extra parameter needed: Push a zero\n");
|
|
|
|
switch (pToNode->iBaseType)
|
|
{
|
|
case TYPE_UCHAR:
|
|
printf("\tpush\tBYTE PTR %u\t\t;Push u/byte\n",
|
|
pFromNode->iFillValue);
|
|
break;
|
|
|
|
case TYPE_SHORT:
|
|
case TYPE_USHORT:
|
|
printf("\tpush\tWORD PTR %u\t\t;Push u/short\n",
|
|
pFromNode->iFillValue);
|
|
break;
|
|
|
|
case TYPE_LONG:
|
|
case TYPE_ULONG:
|
|
printf("\tpush\t%u\t\t;Push U/LONG\n",
|
|
pFromNode->iFillValue);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "\nInvalid type for DELETED\n");
|
|
printf("\n.err Invalid type for DELETED\n");
|
|
}
|
|
}
|
|
else if (pToNode->iDeleted) {
|
|
printf("\t;Parameter not needed in callee\n");
|
|
|
|
if (fRestricted)
|
|
cod32_HandleRestricted(pFromNode);
|
|
}
|
|
else {
|
|
switch (pFromNode->iPointerType)
|
|
{
|
|
case TYPE_NEAR32:
|
|
fSameType = typ_TypeIdentical( pFromNode, pToNode);
|
|
fEmbeddedPtr = cod_CountPointerParameters(
|
|
pFromNode->pStructElems, FALSE);
|
|
|
|
if( pFromNode->iBaseType == TYPE_STRUCT) {
|
|
if( (pFromNode->pSizeParam) || fEmbeddedPtr) {
|
|
printf( "\t.err\t\t\t;struct buffer or embedded ptrs\n");
|
|
} else if( fSameType) {
|
|
printf( "\tpush\tDWORD PTR [ebp-%u]\n",
|
|
pFromNode->iTempOffset);
|
|
} else {
|
|
printf( ";compute 16:16 address on stack\n");
|
|
printf( "\tmov\teax,[ebp-%u]\n",
|
|
pFromNode->iTempOffset);
|
|
printf( "\tsub\teax,esp\n");
|
|
printf( "\tadd\teax,DWORD PTR STACK16INITIALOFFSET\n");
|
|
printf( "\tadd\teax,%u\n",
|
|
DWORD_SIZE + pToNode->iOffset);
|
|
printf( "\tpush\teax\n");
|
|
}
|
|
} else {
|
|
printf( "\tpush\tDWORD PTR [ebp-%u]\n",
|
|
pFromNode->iTempOffset);
|
|
}
|
|
break;
|
|
|
|
#if 0
|
|
if( pFromNode->iBaseType == TYPE_STRING) {
|
|
printf( "\tpush\tDWORD PTR [ebp-%u]\n",
|
|
pFromNode->iTempOffset);
|
|
} else {
|
|
printf( "\tmov\teax,[ebp-%u]\n",
|
|
pFromNode->iTempOffset);
|
|
printf( "\tsub\teax,esp\n");
|
|
printf( "\tadd\teax,DWORD PTR STACK16INITIALOFFSET\n");
|
|
printf( "\tadd\teax,%u\n",
|
|
DWORD_SIZE + pToNode->iOffset);
|
|
printf( "\tpush\teax\n");
|
|
}
|
|
break;
|
|
#endif
|
|
case TYPE_FAR16:
|
|
printf( "\tpush\tDWORD PTR [ebp-%u]\n",
|
|
pFromNode->iTempOffset);
|
|
break;
|
|
|
|
/* If it wasn't one of the pointer types above, then it must
|
|
* be a non pointer parameter. Thus, it will be a long,
|
|
* short, ulong, ushort, or char.
|
|
*/
|
|
default:
|
|
|
|
/* If types are equal, then no conversion needed.
|
|
* If no conversion is needed, then just push the item
|
|
* onto new call frame. If conversion is needed, then
|
|
* use switch statement to emit the correct conversion.
|
|
*/
|
|
if (pToNode->iBaseType == pFromNode->iBaseType) {
|
|
if (pFromNode->iBaseDataSize <= WORD_SIZE) {
|
|
if (fRestricted) {
|
|
printf("\tmovzx\teax,WORD PTR [ebp+%u]\t; To: %s\n",
|
|
pFromNode->iOffset, pToNode->pchBaseTypeName);
|
|
cod32_HandleRestricted(pFromNode);
|
|
printf("\n\tpush\tax\n");
|
|
} else {
|
|
printf("\tpush\tWORD PTR [ebp+%u]\t; To: %s\n",
|
|
pFromNode->iOffset, pToNode->pchBaseTypeName);
|
|
}
|
|
}
|
|
else {
|
|
if (fRestricted) {
|
|
printf("\tmov\teax,[ebp+%u]\t; To: %s\n",
|
|
pFromNode->iOffset, pToNode->pchBaseTypeName);
|
|
cod32_HandleRestricted(pFromNode);
|
|
printf("\n\tpush\teax\n");
|
|
}
|
|
else {
|
|
printf("\tpush\tDWORD PTR [ebp+%u]\t; To: %s\n",
|
|
pFromNode->iOffset, pToNode->pchBaseTypeName);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
switch (pFromNode->iBaseType)
|
|
{
|
|
case TYPE_UCHAR: /* UCHAR --> ULONG */
|
|
printf("\tmovzx\teax,BYTE PTR[ebp+%u]\t;",
|
|
pFromNode->iOffset);
|
|
cod32_HandleRestricted(pFromNode);
|
|
printf("To: %s\n", pToNode->pchBaseTypeName);
|
|
printf("\tpush\teax\n");
|
|
break;
|
|
case TYPE_SHORT: /* SHORT --> LONG */
|
|
printf("\tmovsx\teax,WORD PTR[ebp+%u]\t;",
|
|
pFromNode->iOffset);
|
|
cod32_HandleRestricted(pFromNode);
|
|
printf("To: %s\n", pToNode->pchBaseTypeName);
|
|
printf("\tpush\teax\n");
|
|
break;
|
|
case TYPE_USHORT: /* USHORT --> ULONG */
|
|
printf("\tmovzx\teax,WORD PTR[ebp+%u]\t;",
|
|
pFromNode->iOffset);
|
|
cod32_HandleRestricted(pFromNode);
|
|
printf("To: %s\n", pToNode->pchBaseTypeName);
|
|
printf("\tpush\teax\n");
|
|
break;
|
|
case TYPE_LONG: /* LONG --> SHORT */
|
|
printf("\tmov\teax,[ebp+%u]\n", pFromNode->iOffset);
|
|
|
|
if (fRestricted) {
|
|
cod32_HandleRestricted(pFromNode);
|
|
}
|
|
else {
|
|
if (pGlobal_From->fSemantics & SEMANTIC_TRUNC) {
|
|
if (pFromNode->AllowList) {
|
|
AllowLabel = gen_LabelCount++;
|
|
cod32_HandleAllowList(pFromNode->AllowList,
|
|
AllowLabel);
|
|
}
|
|
printf("\tmovsx\tecx,ax\n");
|
|
printf("\tcmp\teax,ecx\n");
|
|
printf("\tjne\tINVP_%s\t\t;\n\n",
|
|
pGlobal_From->pchFunctionName);
|
|
pGlobal_From->fInvalidParam = 1;
|
|
if (pFromNode->AllowList)
|
|
printf("L%u:",AllowLabel);
|
|
}
|
|
}
|
|
printf("\tpush\tax\t;To:%s\n",pToNode->pchBaseTypeName);
|
|
break;
|
|
|
|
case TYPE_ULONG: /* ULONG --> USHORT */
|
|
printf("\tmov\teax,[ebp+%u]\n", pFromNode->iOffset);
|
|
|
|
if( (pFromNode->fSemantics & SEMANTIC_LOCALHEAP) &&
|
|
(pFromNode->fSemantics & SEMANTIC_INPUT)) {
|
|
printf( "\tsub\teax,DS16LOCALHEAPBASE\t\t;local heap\n");
|
|
printf( "\tcmp\teax,0ffffh\n");
|
|
printf( "\tja\tINVP_%s\n\n",
|
|
pGlobal_From->pchFunctionName);
|
|
pGlobal_From->fInvalidParam = 1;
|
|
} else if( fRestricted) {
|
|
cod32_HandleRestricted(pFromNode);
|
|
}
|
|
else {
|
|
if (pGlobal_From->fSemantics & SEMANTIC_TRUNC) {
|
|
if (pFromNode->AllowList) {
|
|
AllowLabel = gen_LabelCount++;
|
|
cod32_HandleAllowList(pFromNode->AllowList,
|
|
AllowLabel);
|
|
}
|
|
|
|
printf("\tcmp\teax,0ffffh\n");
|
|
printf("\tja\tINVP_%s\n\n",
|
|
pGlobal_From->pchFunctionName);
|
|
pGlobal_From->fInvalidParam = 1;
|
|
if (pFromNode->AllowList)
|
|
printf("L%u:",AllowLabel);
|
|
}
|
|
}
|
|
printf("\tpush\tax\t\t;To:%s\n",pToNode->pchBaseTypeName);
|
|
break;
|
|
default:
|
|
fatal("cod_PushParameters32: Tried converted %d to %d",
|
|
pFromNode->iBaseType, pToNode->iBaseType);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pToNode = pToNode->pNextNode;
|
|
pFromNode = pFromNode->pNextNode;
|
|
}
|
|
}
|
|
|
|
|
|
/*** cod32_StructureRepackGDI( ptnBaseFrom, ptnBaseTo)
|
|
*
|
|
* This function generates the code that converts one structure
|
|
* to another structure.
|
|
*
|
|
* Entry: pBaseFrom - pointer to the 32-bit structure.
|
|
* pBaseTo - pointer to the 16-bit structure.
|
|
*
|
|
* Exit: structure repack code is generated.
|
|
*
|
|
* History:
|
|
* 06-Nov-1990 KevinR Wrote it
|
|
*/
|
|
|
|
void
|
|
cod32_StructureRepackGDI(PTYPENODE ptnBaseFrom,
|
|
PTYPENODE ptnBaseTo)
|
|
|
|
{
|
|
FixupRec *pFixupList = NULL, *pCurrent;
|
|
PTYPENODE ptnFrom, ptnTo;
|
|
|
|
|
|
ptnFrom = ptnBaseFrom->pStructElems;
|
|
ptnTo = ptnBaseTo->pStructElems;
|
|
|
|
cod32_AllocFixedSize(typ_FullSize(ptnBaseTo), ptnBaseFrom);
|
|
|
|
gEDI = 0;
|
|
gESI = 0;
|
|
|
|
/*
|
|
* If the structure is not marked with the input semantic, then the
|
|
* structure does not contain any useful information. Therefore,
|
|
* we will assume that any substructures to this structure are
|
|
* not interesting, and may not actually exist.
|
|
*/
|
|
if (!(ptnBaseFrom->fSemantics & SEMANTIC_INPUT))
|
|
return;
|
|
|
|
printf(";Copy structure to new area\n\n");
|
|
cod32_RepackElements(ptnBaseFrom, ptnBaseTo, ptnFrom, ptnTo, &pFixupList);
|
|
|
|
/*
|
|
* Now, handle the fixups.
|
|
*/
|
|
while (pCurrent = cod_GetFixupRecord(&pFixupList)) {
|
|
printf("\n\n;Fixup imbedded pointer %s\n\n",
|
|
typ_NonNull(pCurrent->pFrom->pchIdent));
|
|
printf("\tmov\tesi,[ebp-%u]\t\t;Get parents pointer\n",
|
|
pCurrent->pParentFrom->iTempOffset);
|
|
printf("\tmov\tesi,[esi+%u]\t\t;Get Fixups pointer\n",
|
|
pCurrent->pTo->iStructOffset);
|
|
|
|
cod32_HandlePointer(pCurrent->pFrom, pCurrent->pTo);
|
|
|
|
printf("\n;Patch in new pointer value\n");
|
|
printf("\tmov\tedi,[ebp-%u]\t\t;Get parents pointer\n",
|
|
pCurrent->pParentFrom->iTempOffset);
|
|
printf("\tmov\tesi,[ebp-%u]\t\t;Get Fixups new pointer\n",
|
|
pCurrent->pFrom->iTempOffset);
|
|
|
|
if (pCurrent->pFrom->iPointerType != pCurrent->pTo->iPointerType) {
|
|
switch (pCurrent->pFrom->iPointerType)
|
|
{
|
|
case TYPE_FAR16:
|
|
printf(";Convert 16:16 --> 0:32\n");
|
|
printf("\tor\tesi,esi\n");
|
|
printf("\tjz\tshort L%u\n",gen_LabelCount);
|
|
printf("\tror\tesi,16\n");
|
|
printf("\tshr\tsi,3\n");
|
|
printf("\trol\tesi,16\n");
|
|
printf("L%u:\n",gen_LabelCount++);
|
|
break;
|
|
case TYPE_NEAR32:
|
|
printf(";Convert 0:32 --> 16:16\n");
|
|
printf("\tor\tesi,esi\n");
|
|
printf("\tjz\tshort L%u\n",gen_LabelCount);
|
|
printf("\tror\tesi,16\n");
|
|
printf("\tshl\tsi,3\n");
|
|
printf("\tmov\teax,ss\n");
|
|
printf("\tand\teax,3\n");
|
|
printf("\tor\tal,4\n");
|
|
printf("\tor\tsi,ax\n");
|
|
printf("\trol\tesi,16\n");
|
|
printf("L%u:\n",gen_LabelCount++);
|
|
break;
|
|
default:
|
|
fatal("Structure Repack: Unknown pointer type");
|
|
}
|
|
}
|
|
printf("\tmov\t[edi+%u],esi\t\t;Put Fixups pointer\n",
|
|
pCurrent->pTo->iStructOffset);
|
|
free(pCurrent);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*** cod32_UnpackStructGDI( pMNode)
|
|
*
|
|
* This function will unwind any pointer manipulation done to make
|
|
* the call.
|
|
*
|
|
* Entry: pMNode - pointer to a MapNode.
|
|
*
|
|
* Exit: generates code to unpack structures.
|
|
*
|
|
* History:
|
|
* 28-Nov-1988 JulieB Created it.
|
|
* 06-Nov-1990 KevinR GDI hacks
|
|
*/
|
|
|
|
cod32_UnpackStructGDI( MapNode *pMNode)
|
|
|
|
{
|
|
int iNullLabel;
|
|
PTYPENODE ptnFrom, ptnTo;
|
|
|
|
|
|
printf("\n; ****> BEGIN Pointer/Structure Unpack Section\n\n");
|
|
|
|
printf( "\tpush\teax\t\t\t; save return code\n");
|
|
|
|
if( fMapTo16Used) {
|
|
printf( "\tpush\tdword ptr [ebp-%u]\t\t; ptr thunk id\n",
|
|
iPtrThunkIDOffset);
|
|
printf( "\tcall\tUnmapLS32\n");
|
|
}
|
|
|
|
printf( "\tpush\tdword ptr [ebp-%u]\t\t;stack thunk id\n",
|
|
iStackThunkIDOffset);
|
|
printf( "\tcall\tReleaseStack32\n");
|
|
|
|
printf( "\tpop\teax\t\t\t; restore return code\n");
|
|
|
|
#if 0
|
|
ptnFrom = pMNode->pFromNode->ParamList;
|
|
ptnTo = pMNode->pToNode->ParamList;
|
|
|
|
while (ptnFrom && ptnTo) {
|
|
if( (ptnFrom->fSemantics & SEMANTIC_OUTPUT) &&
|
|
typ_TypeIdentical( ptnFrom, ptnTo) &&
|
|
(ptnFrom->pSizeParam) && (ptnFrom->iBaseType == TYPE_CHAR)) {
|
|
|
|
printf( "\n;output buffer %s --> %s\n",
|
|
typ_NonNull( ptnFrom->pchIdent),
|
|
typ_NonNull( ptnTo->pchIdent));
|
|
printf( "\tmov\tecx,DWORD PTR [ebp+%u]\t\t;get size param\n",
|
|
ptnFrom->pSizeParam->iOffset);
|
|
printf( "\tmov\tesi,DWORD PTR [ebp-%u]\t\t;32-bit buffer address\n",
|
|
ptnFrom->iTempOffset);
|
|
printf( "\tmov\tedi,DWORD PTR [ebp+%u]\n", ptnFrom->iOffset);
|
|
printf( "\trep\tmovsb\n");
|
|
}
|
|
ptnFrom = ptnFrom->pNextNode;
|
|
ptnTo = ptnTo->pNextNode;
|
|
}
|
|
|
|
if( fGDIAllocUsed)
|
|
printf( "\tcall\tReleaseBuff\n");
|
|
#endif
|
|
|
|
#if 0
|
|
pFromList = pMNode->pFromNode->ParamList;
|
|
pToList = pMNode->pToNode->ParamList;
|
|
|
|
while (pFromList && pToList) {
|
|
if (pFromList->iPointerType) {
|
|
fgOutputFlag = pFromList->fSemantics & SEMANTIC_OUTPUT;
|
|
|
|
printf("\n;Undo Pointer %s --> %s\n",
|
|
typ_NonNull(pFromList->pchIdent),typ_NonNull(pToList->pchIdent));
|
|
|
|
/*
|
|
* Load source address into esi.
|
|
*/
|
|
printf("\n\n\tmov\tesi,[ebp-%u]\t\t;%s temp address\n",
|
|
pFromList->iTempOffset,typ_NonNull(pFromList->pchIdent));
|
|
printf("\tor\tesi,esi\n");
|
|
printf("\tjz\tL%u\n\n",NullLabel=gen_LabelCount++);
|
|
|
|
/*
|
|
* Load destination address into edi.
|
|
*/
|
|
printf("\n\n\tmov\tedi,[ebp+%u]\t\t;%s original address\n",
|
|
pFromList->iOffset,typ_NonNull(pFromList->pchIdent));
|
|
|
|
cod32_UnHandlePointer(pFromList,pToList);
|
|
printf("\nL%u:\t\t;No action required\n",NullLabel);
|
|
}
|
|
pFromList = pFromList->pNextNode;
|
|
pToList = pToList->pNextNode;
|
|
}
|
|
#endif
|
|
printf("\n; ****> END Pointer/Structure Unpack Section\n\n");
|
|
}
|