[SPEC2DEF]

change the way import libs are created for MSVC. Since we don't use underscores in symbols on other architectures than x86, its not possible to create labels like "div", since it conflicts with the opcode. Therefore add a prefix and redirect all exports to the prefixed version when building an importlib

svn path=/trunk/; revision=52476
This commit is contained in:
Timo Kreuzer 2011-06-26 22:23:08 +00:00
parent b32da944f7
commit 5074cf8d1e
2 changed files with 47 additions and 37 deletions

View file

@ -141,7 +141,7 @@ macro(add_importlib_target _exports_file)
# Generate the asm stub file and the export def file # Generate the asm stub file and the export def file
add_custom_command( add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def OUTPUT ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm ${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def
COMMAND native-spec2def --ms --kill-at -a=${SPEC2DEF_ARCH} -r -n=${_name}${_suffix} -d=${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def -l=${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file} COMMAND native-spec2def --ms --kill-at -a=${SPEC2DEF_ARCH} --implib -n=${_name}${_suffix} -d=${CMAKE_BINARY_DIR}/importlibs/lib${_name}_exp.def -l=${CMAKE_BINARY_DIR}/importlibs/lib${_name}_stubs.asm ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file}) DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file})
# Assemble the stub file # Assemble the stub file

View file

@ -32,13 +32,14 @@ enum _ARCH
typedef int (*PFNOUTLINE)(FILE *, EXPORT *); typedef int (*PFNOUTLINE)(FILE *, EXPORT *);
int gbKillAt = 0; int gbKillAt = 0;
int gbUseDeco = 0;
int gbMSComp = 0; int gbMSComp = 0;
int gbImportLib = 0;
int no_redirections = 0; int no_redirections = 0;
int giArch = ARCH_X86; int giArch = ARCH_X86;
char *pszArchString = "i386"; char *pszArchString = "i386";
char *pszArchString2; char *pszArchString2;
char *pszDllName = 0; char *pszDllName = 0;
char *gpszUnderscore = "";
enum enum
{ {
@ -242,37 +243,37 @@ OutputLine_asmstub(FILE *fileDest, EXPORT *pexp)
/* Handle autoname */ /* Handle autoname */
if (pexp->nNameLength == 1 && pexp->pcName[0] == '@') if (pexp->nNameLength == 1 && pexp->pcName[0] == '@')
{ {
fprintf(fileDest, "PUBLIC ordinal%d\nordinal%d: nop\n", fprintf(fileDest, "PUBLIC %sordinal%d\n%sordinal%d: nop\n",
pexp->nOrdinal, pexp->nOrdinal); 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,
pexp->nNameLength, pexp->pcName); pexp->nNameLength, pexp->pcName);
} }
else if (pexp->nCallingConvention == CC_STDCALL) 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,
pexp->nNameLength, pexp->pcName, pexp->nStackBytes); pexp->nNameLength, pexp->pcName, pexp->nStackBytes);
} }
else if (pexp->nCallingConvention == CC_FASTCALL) 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,
pexp->nNameLength, pexp->pcName, pexp->nStackBytes); pexp->nNameLength, pexp->pcName, pexp->nStackBytes);
} }
else if (pexp->nCallingConvention == CC_CDECL || else if (pexp->nCallingConvention == CC_CDECL ||
pexp->nCallingConvention == CC_STUB) 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,
pexp->nNameLength, pexp->pcName); pexp->nNameLength, pexp->pcName);
} }
else if (pexp->nCallingConvention == CC_EXTERN) 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,
pexp->nNameLength, pexp->pcName); pexp->nNameLength, pexp->pcName);
} }
@ -291,18 +292,26 @@ OutputHeader_def(FILE *file, char *libname)
} }
void 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; char *pcName = fRedir ? pexp->pcRedirection : pexp->pcName;
size_t nNameLength = fRedir ? pexp->nRedirectionLength : pexp->nNameLength; size_t nNameLength = fRedir ? pexp->nRedirectionLength : pexp->nNameLength;
if (fDeco && pexp->nCallingConvention == CC_FASTCALL) /* Handle autoname */
fprintf(fileDest, "@"); if (nNameLength == 1 && pcName[0] == '@')
fprintf(fileDest, "%.*s", nNameLength, pcName);
if ((pexp->nCallingConvention == CC_STDCALL ||
pexp->nCallingConvention == CC_FASTCALL) && fDeco)
{ {
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);
}
} }
} }
@ -311,29 +320,26 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
{ {
fprintf(fileDest, " "); fprintf(fileDest, " ");
/* Handle autoname */ PrintName(fileDest, pexp, "", 0, (giArch == ARCH_X86) && !gbKillAt);
if (pexp->nNameLength == 1 && pexp->pcName[0] == '@')
{
fprintf(fileDest, "ordinal%d", pexp->nOrdinal);
}
else
{
PrintName(fileDest, pexp, 0, gbUseDeco && !gbKillAt);
}
if (pexp->pcRedirection && !no_redirections) if (gbImportLib)
{ {
int fDeco = (gbUseDeco && !ScanToken(pexp->pcRedirection, '.')); fprintf(fileDest, "=");
PrintName(fileDest, pexp, "_stub_", 0, 0);
}
else if (pexp->pcRedirection)
{
int fDeco = ((giArch == ARCH_X86) && !ScanToken(pexp->pcRedirection, '.'));
fprintf(fileDest, "="); fprintf(fileDest, "=");
PrintName(fileDest, pexp, 1, fDeco && !gbMSComp); PrintName(fileDest, pexp, "", 1, fDeco && !gbMSComp);
} }
else if (gbUseDeco && gbKillAt && !gbMSComp && else if ((giArch == ARCH_X86) && gbKillAt && !gbMSComp &&
(pexp->nCallingConvention == CC_STDCALL || (pexp->nCallingConvention == CC_STDCALL ||
pexp->nCallingConvention == CC_FASTCALL)) pexp->nCallingConvention == CC_FASTCALL))
{ {
fprintf(fileDest, "="); fprintf(fileDest, "=");
PrintName(fileDest, pexp, 0, 1); PrintName(fileDest, pexp, "", 0, 1);
} }
if (pexp->nOrdinal != -1) if (pexp->nOrdinal != -1)
@ -691,6 +697,11 @@ int main(int argc, char *argv[])
{ {
pszDllName = argv[i] + 3; pszDllName = argv[i] + 3;
} }
else if ((strcasecmp(argv[i], "--implib") == 0))
{
no_redirections = 1;
gbImportLib = 1;
}
else if ((strcasecmp(argv[i], "--kill-at") == 0)) else if ((strcasecmp(argv[i], "--kill-at") == 0))
{ {
gbKillAt = 1; gbKillAt = 1;
@ -714,7 +725,11 @@ int main(int argc, char *argv[])
} }
} }
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, "x86_64") == 0) giArch = ARCH_AMD64;
else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64; else if (strcasecmp(pszArchString, "ia64") == 0) giArch = ARCH_IA64;
else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM; else if (strcasecmp(pszArchString, "arm") == 0) giArch = ARCH_ARM;
@ -727,11 +742,6 @@ int main(int argc, char *argv[])
else else
pszArchString2 = "win32"; pszArchString2 = "win32";
if (giArch == ARCH_X86)
{
gbUseDeco = 1;
}
/* Set a default dll name */ /* Set a default dll name */
if (!pszDllName) if (!pszDllName)
{ {