static TString EmitExports(const std::vector<TString> &escaped_args) { auto uuid_lib_file = TempFile::Create(TEXT(".lib"), true); auto uuid_exp_file = uuid_lib_file; uuid_exp_file.replace(uuid_exp_file.length() - 4, 4, TEXT(".exp")); TempFile::AutoDeleteFile(uuid_exp_file); // Call link.exe -lib -def <rest of linker arguments> -out:<uuid_lib_file> auto linker_exe = LocateMSVCLinker(); auto linker_exe_esc = QuoteSpaces(linker_exe.data()); std::vector<const _TCHAR*> export_args; export_args.push_back(linker_exe_esc.data()); export_args.push_back(TEXT("-lib")); export_args.push_back(TEXT("-def")); // If the original includes "/DEF" or "-DEF", it should override this one // FIXME: this passes many link.exe args to lib.exe which generates warnings for (auto &escaped_arg : escaped_args) export_args.push_back(escaped_arg.data()); TString out_arg(TEXT("-out:")); out_arg += uuid_lib_file; export_args.push_back(out_arg.data()); export_args.push_back(NULL); //PrintArgs(export_args); auto errnum = _tspawnvp(_P_WAIT, linker_exe.data(), export_args.data()); if (errnum) { perror("LinkWrapper:EmitExports"); exit(errnum); } // Convert the exports file to the trampoline object file auto exports_obj_file = TempFile::Create(TEXT(".obj"), true); bool converted = ConvertExports(uuid_exp_file.data(), exports_obj_file.data()); return converted ? exports_obj_file : TString(); }
int _tmain(int argc, _TCHAR* argv[]) { // FIXME: MSDN says that the linker also parses arguments from the LINK environment variable std::vector<const _TCHAR*> linker_args; std::vector<TString> escaped_args; auto linker_exe = LocateMSVCLinker(); auto linker_exe_esc = QuoteSpaces(linker_exe.data()); linker_args.push_back(linker_exe_esc.data()); // Needed by _tspawnvp for (int i = 1; i < argc; i++) { auto trap_file = ProcessArg(argv[i]); escaped_args.push_back(QuoteSpaces(trap_file.data())); } for (auto &escaped_arg : escaped_args) linker_args.push_back(escaped_arg.data()); // Make a new linker arguments containing the following: // 1) The linker program name as argv[0] (required by _texecvp) // 2) The original arguments passed to the linker // 3) All additional arguments we add in (such as the path to RandoLib.lib) // 4) Terminating NULL pointer // When producing an executable/DLL, add in RandoLib.lib TString rando_lib_path, exports_file; if (!lib_mode) { exports_file = EmitExports(escaped_args); linker_args.push_back(exports_file.data()); linker_args.push_back(kLinkerExtraArg1); linker_args.push_back(kLinkerExtraArg2); linker_args.push_back(kRandoLib); // We need to disable incremental linking because it breaks our stuff // (for some reason, the linker adds an extra 0 byte to the end of each .txtrp entry) linker_args.push_back(kLinkerNoIncrementalArg); } linker_args.push_back(NULL); //PrintArgs(linker_args); auto errnum = _tspawnvp(_P_WAIT, linker_exe.data(), linker_args.data()); if (errnum) { perror("LinkWrapper:_tmain"); exit(errnum); } if (!lib_mode) CallPatchEntry(); return errnum; }
CString CFilePath::GetStr(DWORD dwPacking) const { CString sTemp = msPath; if (dwPacking & eppAutoQuote) sTemp = QuoteSpaces(sTemp); if (dwPacking & eppBackslashToSlash) sTemp.Replace('\\', '/'); return sTemp; }