typedef struct
{
char *pcName;
- size_t nNameLength;
+ int nNameLength;
char *pcRedirection;
int nRedirectionLength;
int nCallingConvention;
int nArgCount;
int anArgs[30];
unsigned int uFlags;
+ int nNumber;
} EXPORT;
enum _ARCH
typedef int (*PFNOUTLINE)(FILE *, EXPORT *);
int gbKillAt = 0;
-int gbUseDeco = 0;
int gbMSComp = 0;
+int gbImportLib = 0;
int no_redirections = 0;
int giArch = ARCH_X86;
char *pszArchString = "i386";
char *pszArchString2;
char *pszDllName = 0;
+char *gpszUnderscore = "";
enum
{
CC_STDCALL,
CC_CDECL,
CC_FASTCALL,
+ CC_THISCALL,
CC_EXTERN,
CC_STUB,
};
ARG_STR,
ARG_WSTR,
ARG_DBL,
- ARG_INT64
+ ARG_INT64,
+ ARG_INT128,
+ ARG_FLOAT
};
char* astrCallingConventions[] =
"STDCALL",
"CDECL",
"FASTCALL",
+ "THISCALL",
"EXTERN"
};
fprintf(file, "__stdcall ");
}
- fprintf(file, "%.*s(", pexp->nNameLength, pexp->pcName);
+ /* Check for C++ */
+ if (pexp->pcName[0] == '?')
+ {
+ fprintf(file, "stub_function%d(", pexp->nNumber);
+ }
+ else
+ {
+ fprintf(file, "%.*s(", pexp->nNameLength, pexp->pcName);
+ }
for (i = 0; i < pexp->nArgCount; i++)
{
case ARG_PTR: fprintf(file, "void*"); break;
case ARG_STR: fprintf(file, "char*"); break;
case ARG_WSTR: fprintf(file, "wchar_t*"); break;
- case ARG_DBL: case ARG_INT64 : fprintf(file, "__int64"); break;
+ case ARG_DBL:
+ case ARG_INT64 : fprintf(file, "__int64"); break;
+ case ARG_INT128 : fprintf(file, "__int128"); break;
+ case ARG_FLOAT: fprintf(file, "float"); break;
}
fprintf(file, " a%d", i);
}
case ARG_WSTR: fprintf(file, "'%%ws'"); break;
case ARG_DBL: fprintf(file, "%%f"); break;
case ARG_INT64: fprintf(file, "%%\"PRix64\""); break;
+ case ARG_INT128: fprintf(file, "%%\"PRix128\""); break;
+ case ARG_FLOAT: fprintf(file, "%%f"); break;
}
}
fprintf(file, ")\\n\"");
case ARG_WSTR: fprintf(file, "(wchar_t*)a%d", i); break;
case ARG_DBL: fprintf(file, "(double)a%d", i); break;
case ARG_INT64: fprintf(file, "(__int64)a%d", i); break;
+ case ARG_INT128: fprintf(file, "(__int128)a%d", i); break;
+ case ARG_FLOAT: fprintf(file, "(float)a%d", i); break;
}
}
fprintf(file, ");\n");
/* Handle autoname */
if (pexp->nNameLength == 1 && pexp->pcName[0] == '@')
{
- fprintf(fileDest, "PUBLIC ordinal%d\nordinal%d: nop\n",
- pexp->nOrdinal, pexp->nOrdinal);
+ fprintf(fileDest, "PUBLIC %sordinal%d\n%sordinal%d: nop\n",
+ gpszUnderscore, pexp->nOrdinal, gpszUnderscore, pexp->nOrdinal);
}
- else if (giArch == ARCH_AMD64)
+ else if (giArch != ARCH_X86)
{
- fprintf(fileDest, "PUBLIC %.*s\n%.*s: nop\n",
+ fprintf(fileDest, "PUBLIC _stub_%.*s\n_stub_%.*s: nop\n",
pexp->nNameLength, pexp->pcName,
pexp->nNameLength, pexp->pcName);
}
else if (pexp->nCallingConvention == CC_STDCALL)
{
- fprintf(fileDest, "PUBLIC _%.*s@%d\n_%.*s@%d: nop\n",
+ fprintf(fileDest, "PUBLIC __stub_%.*s@%d\n__stub_%.*s@%d: nop\n",
pexp->nNameLength, pexp->pcName, pexp->nStackBytes,
pexp->nNameLength, pexp->pcName, pexp->nStackBytes);
}
else if (pexp->nCallingConvention == CC_FASTCALL)
{
- fprintf(fileDest, "PUBLIC @%.*s@%d\n@%.*s@%d: nop\n",
+ fprintf(fileDest, "PUBLIC @_stub_%.*s@%d\n@_stub_%.*s@%d: nop\n",
pexp->nNameLength, pexp->pcName, pexp->nStackBytes,
pexp->nNameLength, pexp->pcName, pexp->nStackBytes);
}
else if (pexp->nCallingConvention == CC_CDECL ||
pexp->nCallingConvention == CC_STUB)
{
- fprintf(fileDest, "PUBLIC _%.*s\n_%.*s: nop\n",
+ fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s: nop\n",
pexp->nNameLength, pexp->pcName,
pexp->nNameLength, pexp->pcName);
}
else if (pexp->nCallingConvention == CC_EXTERN)
{
- fprintf(fileDest, "PUBLIC _%.*s\n_%.*s:\n",
+ fprintf(fileDest, "PUBLIC __stub_%.*s\n__stub_%.*s:\n",
pexp->nNameLength, pexp->pcName,
pexp->nNameLength, pexp->pcName);
}
}
void
-PrintName(FILE *fileDest, EXPORT *pexp, int fRedir, int fDeco)
+PrintName(FILE *fileDest, EXPORT *pexp, char *pszPrefix, int fRedir, int fDeco)
{
char *pcName = fRedir ? pexp->pcRedirection : pexp->pcName;
- size_t nNameLength = fRedir ? pexp->nRedirectionLength : pexp->nNameLength;
+ int nNameLength = fRedir ? pexp->nRedirectionLength : pexp->nNameLength;
- if (fDeco && pexp->nCallingConvention == CC_FASTCALL)
- fprintf(fileDest, "@");
- fprintf(fileDest, "%.*s", nNameLength, pcName);
- if ((pexp->nCallingConvention == CC_STDCALL ||
- pexp->nCallingConvention == CC_FASTCALL) && fDeco)
+ /* Handle autoname */
+ if (nNameLength == 1 && pcName[0] == '@')
{
- fprintf(fileDest, "@%d", pexp->nStackBytes);
+ fprintf(fileDest, "ordinal%d", pexp->nOrdinal);
+ }
+ else
+ {
+ if (fDeco && pexp->nCallingConvention == CC_FASTCALL)
+ fprintf(fileDest, "@");
+ fprintf(fileDest, "%s%.*s", pszPrefix, nNameLength, pcName);
+ if ((pexp->nCallingConvention == CC_STDCALL ||
+ pexp->nCallingConvention == CC_FASTCALL) && fDeco)
+ {
+ fprintf(fileDest, "@%d", pexp->nStackBytes);
+ }
}
}
{
fprintf(fileDest, " ");
- /* Handle autoname */
- if (pexp->nNameLength == 1 && pexp->pcName[0] == '@')
+ PrintName(fileDest, pexp, "", 0, (giArch == ARCH_X86) && !gbKillAt);
+
+ if (gbImportLib)
{
- fprintf(fileDest, "ordinal%d", pexp->nOrdinal);
+ fprintf(fileDest, "=");
+ PrintName(fileDest, pexp, "_stub_", 0, 0);
}
- else
+ else if (pexp->pcRedirection)
{
- PrintName(fileDest, pexp, 0, gbUseDeco && !gbKillAt);
- }
+ if (gbMSComp && (pexp->pcName[0] == '?'))
+ {
+ /* ignore c++ redirection, since link doesn't like that! */
+ }
+ else
+ {
+ int fDeco;
- if (pexp->pcRedirection && !no_redirections)
+ fDeco = ((giArch == ARCH_X86) && !ScanToken(pexp->pcRedirection, '.'));
+ fprintf(fileDest, "=");
+ PrintName(fileDest, pexp, "", 1, fDeco && !gbMSComp);
+ }
+ }
+ else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
+ (pexp->pcName[0] == '?'))
{
- int fDeco = (gbUseDeco && !ScanToken(pexp->pcRedirection, '.'));
-
+ /* C++ stubs are forwarded to C stubs */
fprintf(fileDest, "=");
- PrintName(fileDest, pexp, 1, fDeco && !gbMSComp);
+ fprintf(fileDest, "stub_function%d", pexp->nNumber);
}
- else if (gbUseDeco && gbKillAt && !gbMSComp &&
+ else if ((giArch == ARCH_X86) && gbKillAt && !gbMSComp &&
(pexp->nCallingConvention == CC_STDCALL ||
pexp->nCallingConvention == CC_FASTCALL))
{
fprintf(fileDest, "=");
- PrintName(fileDest, pexp, 0, 1);
+ PrintName(fileDest, pexp, "", 0, 1);
}
if (pexp->nOrdinal != -1)
/* Loop all lines */
nLine = 1;
+ exp.nNumber = 0;
for (pcLine = pcStart; *pcLine; pcLine = NextLine(pcLine), nLine++)
{
pc = pcLine;
exp.nArgCount = 0;
exp.uFlags = 0;
+ exp.nNumber++;
//fprintf(stderr, "info: line %d, token:'%d, %.20s'\n",
// nLine, TokenLength(pcLine), pcLine);
{
exp.nCallingConvention = CC_FASTCALL;
}
+ else if (CompareToken(pc, "thiscall"))
+ {
+ exp.nCallingConvention = CC_THISCALL;
+ }
else if (CompareToken(pc, "extern"))
{
exp.nCallingConvention = CC_EXTERN;
exp.nStackBytes += 8;
exp.anArgs[exp.nArgCount] = ARG_INT64;
}
+ else if (CompareToken(pc, "int128"))
+ {
+ exp.nStackBytes += 16;
+ exp.anArgs[exp.nArgCount] = ARG_INT128;
+ }
+ else if (CompareToken(pc, "float"))
+ {
+ exp.nStackBytes += 4;
+ exp.anArgs[exp.nArgCount] = ARG_FLOAT;
+ }
else
fprintf(stderr, "error: line %d, expected type, got: %.10s\n", nLine, pc);
/* Check for c++ mangled name */
if (pc[0] == '?')
{
- printf("Found c++ mangled name...\n");
+ //printf("Found c++ mangled name...\n");
//
}
else
{
/* Check for stdcall name */
char *p = strchr(pc, '@');
- if (p && ((size_t)(p - pc) < exp.nNameLength))
+ if (p && (p - pc < exp.nNameLength))
{
int i;
- exp.nNameLength = p - pc;
+ exp.nNameLength = (int)(p - pc);
if (exp.nNameLength < 1)
{
fprintf(stderr, "error, @ in line %d\n", nLine);
}
/* Get optional redirection */
- if ((pc = NextToken(pc)))
+ pc = NextToken(pc);
+ if (pc)
{
exp.pcRedirection = pc;
exp.nRedirectionLength = TokenLength(pc);
char *pszSource, *pszDefFileName = 0, *pszStubFileName = 0, *pszLibStubName = 0;
char achDllName[40];
FILE *file;
- int result, i;
+ int result = 0, i;
if (argc < 2)
{
{
pszDllName = argv[i] + 3;
}
+ else if ((strcasecmp(argv[i], "--implib") == 0))
+ {
+ no_redirections = 1;
+ gbImportLib = 1;
+ }
else if ((strcasecmp(argv[i], "--kill-at") == 0))
{
gbKillAt = 1;
}
}
- if (strcasecmp(pszArchString, "i386") == 0) giArch = ARCH_X86;
+ if (strcasecmp(pszArchString, "i386") == 0)
+ {
+ giArch = ARCH_X86;
+ gpszUnderscore = "_";
+ }
else if (strcasecmp(pszArchString, "x86_64") == 0) giArch = ARCH_AMD64;
else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64;
else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM;
else
pszArchString2 = "win32";
- if (giArch == ARCH_X86)
- {
- gbUseDeco = 1;
- }
-
/* Set a default dll name */
if (!pszDllName)
{
/* Allocate memory buffer */
pszSource = malloc(nFileSize + 1);
- if (!pszSource) return -4;
+ if (!pszSource)
+ {
+ fclose(file);
+ return -4;
+ }
/* Load input file into memory */
nFileSize = fread(pszSource, 1, nFileSize, file);