mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +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(_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(
|
||||
OUTPUT ${_asm_stubs_file} ${_def_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}
|
||||
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} -i=${_asm_impalias_file} ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file} native-spec2def)
|
||||
|
||||
# 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.
|
||||
# This allows us to treat the implib as a regular static library
|
||||
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")
|
||||
endfunction()
|
||||
|
@ -364,7 +365,7 @@ if(ARCH STREQUAL "amd64")
|
|||
elseif(ARCH STREQUAL "arm")
|
||||
set(SPEC2DEF_ARCH arm)
|
||||
elseif(ARCH STREQUAL "arm64")
|
||||
add_definitions(/D__arm64__)
|
||||
add_definitions(/D__arm64__)
|
||||
set(SPEC2DEF_ARCH arm64)
|
||||
else()
|
||||
set(SPEC2DEF_ARCH i386)
|
||||
|
|
|
@ -85,6 +85,7 @@ enum
|
|||
FL_NORELAY = 16,
|
||||
FL_RET64 = 32,
|
||||
FL_REGISTER = 64,
|
||||
FL_IMPSYM = 128,
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -612,6 +613,11 @@ PrintName(FILE *fileDest, EXPORT *pexp, PSTRING pstr, int fDeco)
|
|||
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
|
||||
{
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
else if (((pexp->uFlags & FL_STUB) || (pexp->nCallingConvention == CC_STUB)) &&
|
||||
|
@ -747,6 +753,17 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
|
|||
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") */
|
||||
if (gbMSComp && !gbImportLib && (pexp->nCallingConvention == CC_EXTERN) &&
|
||||
(pexp->strTarget.buf != NULL) && !!ScanToken(pexp->strTarget.buf, '.'))
|
||||
|
@ -790,6 +807,54 @@ OutputLine_def(FILE *fileDest, EXPORT *pexp)
|
|||
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
|
||||
Fatalv(
|
||||
const char* filename,
|
||||
|
@ -1090,6 +1155,10 @@ ParseFile(char* pcStart, FILE *fileDest, unsigned *cExports)
|
|||
{
|
||||
exp.uFlags |= FL_ORDINAL | FL_NONAME;
|
||||
}
|
||||
else if (CompareToken(pc, "-impsym"))
|
||||
{
|
||||
exp.uFlags |= FL_IMPSYM;
|
||||
}
|
||||
else if (CompareToken(pc, "-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");
|
||||
}
|
||||
|
||||
/* 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
|
||||
* 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"
|
||||
" -d=<file> generate a def file\n"
|
||||
" -s=<file> generate a stub file\n"
|
||||
" -i=<file> generate an import alias file\n"
|
||||
" --ms MSVC compatibility\n"
|
||||
" -n=<name> name of the dll\n"
|
||||
" --version=<version> Sets the version to create exports for\n"
|
||||
|
@ -1408,6 +1484,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
size_t nFileSize;
|
||||
char *pszSource, *pszDefFileName = NULL, *pszStubFileName = NULL, *pszLibStubName = NULL;
|
||||
char *pszImpLibAliasFileName = NULL;
|
||||
const char* pszVersionOption = "--version=0x";
|
||||
char achDllName[40];
|
||||
FILE *file;
|
||||
|
@ -1441,6 +1518,10 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
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] == '=')
|
||||
{
|
||||
pszDllName = argv[i] + 3;
|
||||
|
@ -1574,7 +1655,7 @@ int main(int argc, char *argv[])
|
|||
file = fopen(pszDefFileName, "w");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1595,7 +1676,7 @@ int main(int argc, char *argv[])
|
|||
file = fopen(pszStubFileName, "w");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1616,7 +1697,7 @@ int main(int argc, char *argv[])
|
|||
file = fopen(pszLibStubName, "w");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1632,6 +1713,28 @@ int main(int argc, char *argv[])
|
|||
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);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue