mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[SPEC2DEF] Implement support for import symbol aliases
This commit is contained in:
parent
bc2621812f
commit
60f4493a68
2 changed files with 113 additions and 9 deletions
|
@ -317,11 +317,12 @@ function(generate_import_lib _libname _dllname _spec_file __version_arg)
|
||||||
|
|
||||||
set(_def_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def)
|
set(_def_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_implib.def)
|
||||||
set(_asm_stubs_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_stubs.asm)
|
set(_asm_stubs_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_stubs.asm)
|
||||||
|
set(_asm_impalias_file ${CMAKE_CURRENT_BINARY_DIR}/${_libname}_impalias.asm)
|
||||||
|
|
||||||
# Generate the def and asm stub files
|
# Generate the def, asm stub and alias files
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${_asm_stubs_file} ${_def_file}
|
OUTPUT ${_asm_stubs_file} ${_def_file} ${_asm_impalias_file}
|
||||||
COMMAND native-spec2def --ms ${__version_arg} -a=${SPEC2DEF_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
|
COMMAND native-spec2def --ms ${__version_arg} -a=${SPEC2DEF_ARCH} --implib -n=${_dllname} -d=${_def_file} -l=${_asm_stubs_file} -i=${_asm_impalias_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
|
||||||
|
|
||||||
# Compile the generated asm stub file
|
# Compile the generated asm stub file
|
||||||
|
@ -351,7 +352,7 @@ function(generate_import_lib _libname _dllname _spec_file __version_arg)
|
||||||
# By giving the import lib as an object input, LIB extracts the relevant object files and make a new library.
|
# By giving the import lib as an object input, LIB extracts the relevant object files and make a new library.
|
||||||
# This allows us to treat the implib as a regular static library
|
# This allows us to treat the implib as a regular static library
|
||||||
set_source_files_properties(${_libfile_tmp} PROPERTIES EXTERNAL_OBJECT TRUE)
|
set_source_files_properties(${_libfile_tmp} PROPERTIES EXTERNAL_OBJECT TRUE)
|
||||||
add_library(${_libname} STATIC ${_libfile_tmp})
|
add_library(${_libname} STATIC ${_libfile_tmp} ${_asm_impalias_file})
|
||||||
|
|
||||||
set_target_properties(${_libname} PROPERTIES LINKER_LANGUAGE "C")
|
set_target_properties(${_libname} PROPERTIES LINKER_LANGUAGE "C")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
|
@ -85,6 +85,7 @@ enum
|
||||||
FL_NORELAY = 16,
|
FL_NORELAY = 16,
|
||||||
FL_RET64 = 32,
|
FL_RET64 = 32,
|
||||||
FL_REGISTER = 64,
|
FL_REGISTER = 64,
|
||||||
|
FL_IMPSYM = 128,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -612,6 +613,11 @@ PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
|
||||||
fprintf(fileDest, "%.*s@%d", nNameLength, pcName, pexp->nStackBytes);
|
fprintf(fileDest, "%.*s@%d", nNameLength, pcName, pexp->nStackBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (fDeco && (pexp->nCallingConvention == CC_CDECL) && gbMSComp)
|
||||||
|
{
|
||||||
|
/* Print with cdecl decoration */
|
||||||
|
fprintf(fileDest, "_%.*s", nNameLength, pcName);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Print the undecorated function name */
|
/* Print the undecorated function name */
|
||||||
|
@ -685,7 +691,7 @@ OutputLine_def_GCC(FILE *fileDest, EXPORT *pexp)
|
||||||
DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
|
DbgPrint("Got redirect '%.*s'\n", pexp->strTarget.len, pexp->strTarget.buf);
|
||||||
|
|
||||||
/* print the target name, don't decorate if it is external */
|
/* print the target name, don't decorate if it is external */
|
||||||
fprintf(fileDest, "=");
|
fprintf(fileDest, pexp->uFlags & FL_IMPSYM ? "==" : "=");
|
||||||
PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
|
PrintName(fileDest, pexp, &pexp->strTarget, !fIsExternal);
|
||||||
}
|
}
|
||||||
else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
|
else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
|
||||||
|
@ -747,6 +753,17 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle import symbols */
|
||||||
|
if (pexp->uFlags & FL_IMPSYM)
|
||||||
|
{
|
||||||
|
/* Skip these, if we are not creating an import lib, or if this is MS */
|
||||||
|
if (!gbImportLib || gbMSComp)
|
||||||
|
{
|
||||||
|
DbgPrint("OutputLine_def: skipping import symbol '%.*s'...\n", pexp->strName.len, pexp->strName.buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* For MS linker, forwarded externs are managed via #pragma comment(linker,"/export:_data=org.data,DATA") */
|
/* For MS linker, forwarded externs are managed via #pragma comment(linker,"/export:_data=org.data,DATA") */
|
||||||
if (gbMSComp && !gbImportLib && (pexp->nCallingConvention == CC_EXTERN) &&
|
if (gbMSComp && !gbImportLib && (pexp->nCallingConvention == CC_EXTERN) &&
|
||||||
(pexp->strTarget.buf != NULL) && !!ScanToken(pexp->strTarget.buf, '.'))
|
(pexp->strTarget.buf != NULL) && !!ScanToken(pexp->strTarget.buf, '.'))
|
||||||
|
@ -790,6 +807,54 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PrintNameOrImpName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco, int fImp)
|
||||||
|
{
|
||||||
|
if (fImp)
|
||||||
|
{
|
||||||
|
fprintf(fileDest, "__imp_");
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintName(fileDest, pexp, pstr, fDeco);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OutputAlias(FILE *fileDest, EXPORT *pexp, int fImp)
|
||||||
|
{
|
||||||
|
if ((giArch == ARCH_ARM) || (giArch == ARCH_ARM64))
|
||||||
|
{
|
||||||
|
fprintf(fileDest, " IMPORT ");
|
||||||
|
PrintNameOrImpName(fileDest, pexp, &pexp->strName, 1, fImp);
|
||||||
|
fprintf(fileDest, ", WEAK ");
|
||||||
|
PrintNameOrImpName(fileDest, pexp, &pexp->strTarget, 1, fImp);
|
||||||
|
fprintf(fileDest, "\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(fileDest, " EXTERN ");
|
||||||
|
PrintNameOrImpName(fileDest, pexp, &pexp->strTarget, 1, fImp);
|
||||||
|
fprintf(fileDest, ":PROC\n ALIAS <");
|
||||||
|
PrintNameOrImpName(fileDest, pexp, &pexp->strName, 1, fImp);
|
||||||
|
fprintf(fileDest, "> = <");
|
||||||
|
PrintNameOrImpName(fileDest, pexp, &pexp->strTarget, 1, fImp);
|
||||||
|
fprintf(fileDest, ">\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
OutputLine_implib_asm(FILE *fileDest, EXPORT *pexp)
|
||||||
|
{
|
||||||
|
if ((pexp->uFlags & FL_IMPSYM) == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputAlias(fileDest, pexp, 0);
|
||||||
|
OutputAlias(fileDest, pexp, 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Fatalv(
|
Fatalv(
|
||||||
const char* filename,
|
const char* filename,
|
||||||
|
@ -1090,6 +1155,10 @@ ParseFile(char* pcStart, FILE *fileDest, unsigned *cExports)
|
||||||
{
|
{
|
||||||
exp.uFlags |= FL_ORDINAL | FL_NONAME;
|
exp.uFlags |= FL_ORDINAL | FL_NONAME;
|
||||||
}
|
}
|
||||||
|
else if (CompareToken(pc, "-impsym"))
|
||||||
|
{
|
||||||
|
exp.uFlags |= FL_IMPSYM;
|
||||||
|
}
|
||||||
else if (CompareToken(pc, "-ordinal"))
|
else if (CompareToken(pc, "-ordinal"))
|
||||||
{
|
{
|
||||||
exp.uFlags |= FL_ORDINAL;
|
exp.uFlags |= FL_ORDINAL;
|
||||||
|
@ -1298,6 +1367,12 @@ ParseFile(char* pcStart, FILE *fileDest, unsigned *cExports)
|
||||||
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 0, "Ordinal export without ordinal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for import symbol without target */
|
||||||
|
if ((exp.uFlags & FL_IMPSYM) && (exp.strTarget.buf == NULL))
|
||||||
|
{
|
||||||
|
Fatal(pszSourceFileName, nLine, pcLine, pc, 1, "Import symbol without target");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for special handling of OLE exports, only when MSVC
|
* Check for special handling of OLE exports, only when MSVC
|
||||||
* is not used, since otherwise this is handled by MS LINK.EXE.
|
* is not used, since otherwise this is handled by MS LINK.EXE.
|
||||||
|
@ -1395,6 +1470,7 @@ void usage(void)
|
||||||
" -l=<file> generate an asm lib stub\n"
|
" -l=<file> generate an asm lib stub\n"
|
||||||
" -d=<file> generate a def file\n"
|
" -d=<file> generate a def file\n"
|
||||||
" -s=<file> generate a stub file\n"
|
" -s=<file> generate a stub file\n"
|
||||||
|
" -i=<file> generate an import alias file\n"
|
||||||
" --ms MSVC compatibility\n"
|
" --ms MSVC compatibility\n"
|
||||||
" -n=<name> name of the dll\n"
|
" -n=<name> name of the dll\n"
|
||||||
" --version=<version> Sets the version to create exports for\n"
|
" --version=<version> Sets the version to create exports for\n"
|
||||||
|
@ -1408,6 +1484,7 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
size_t nFileSize;
|
size_t nFileSize;
|
||||||
char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
|
char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
|
||||||
|
char *pszImpLibAliasFileName = NULL;
|
||||||
const char* pszVersionOption = "--version=0x";
|
const char* pszVersionOption = "--version=0x";
|
||||||
char achDllName[40];
|
char achDllName[40];
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
@ -1441,6 +1518,10 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
pszStubFileName = argv[i] + 3;
|
pszStubFileName = argv[i] + 3;
|
||||||
}
|
}
|
||||||
|
else if (argv[i][1] == 'i' && argv[i][2] == '=')
|
||||||
|
{
|
||||||
|
pszImpLibAliasFileName = argv[i] + 3;
|
||||||
|
}
|
||||||
else if (argv[i][1] == 'n' && argv[i][2] == '=')
|
else if (argv[i][1] == 'n' && argv[i][2] == '=')
|
||||||
{
|
{
|
||||||
pszDllName = argv[i] + 3;
|
pszDllName = argv[i] + 3;
|
||||||
|
@ -1574,7 +1655,7 @@ int main(int argc, char *argv[])
|
||||||
file = fopen(pszDefFileName, "w");
|
file = fopen(pszDefFileName, "w");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
|
fprintf(stderr, "error: could not open output file %s\n", pszDefFileName);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1595,7 +1676,7 @@ int main(int argc, char *argv[])
|
||||||
file = fopen(pszStubFileName, "w");
|
file = fopen(pszStubFileName, "w");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
|
fprintf(stderr, "error: could not open output file %s\n", pszStubFileName);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1616,7 +1697,7 @@ int main(int argc, char *argv[])
|
||||||
file = fopen(pszLibStubName, "w");
|
file = fopen(pszLibStubName, "w");
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "error: could not open output file %s\n", argv[i + 1]);
|
fprintf(stderr, "error: could not open output file %s\n", pszLibStubName);
|
||||||
return -5;
|
return -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1632,6 +1713,28 @@ int main(int argc, char *argv[])
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pszImpLibAliasFileName)
|
||||||
|
{
|
||||||
|
/* Open output file */
|
||||||
|
file = fopen(pszImpLibAliasFileName, "w");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "error: could not open output file %s\n", pszImpLibAliasFileName);
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputHeader_asmstub(file, pszDllName);
|
||||||
|
|
||||||
|
for (i = 0; i < cExports; i++)
|
||||||
|
{
|
||||||
|
if (pexports[i].bVersionIncluded)
|
||||||
|
OutputLine_implib_asm(file, &pexports[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "\n END\n");
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
free(pexports);
|
free(pexports);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue